From 479b1b83891105c382cacdf71aeb35c14e994219 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 28 Nov 2023 11:23:49 +0100 Subject: [PATCH] Import OpenSSL 3.2.0 --- Crypto-config-host.mk | 1 + Crypto-config-target.mk | 1 + apps/CA.pl.in | 14 +- apps/asn1parse.c | 19 +- apps/ca.c | 146 +- apps/ciphers.c | 5 +- apps/cmp.c | 774 +- apps/cms.c | 68 +- apps/crl.c | 12 +- apps/crl2pkcs7.c | 3 +- apps/dgst.c | 5 +- apps/dhparam.c | 36 +- apps/dsa.c | 16 +- apps/dsaparam.c | 55 +- apps/ec.c | 16 +- apps/ecparam.c | 15 +- apps/enc.c | 137 +- apps/engine.c | 2 +- apps/fipsinstall.c | 12 +- apps/gendsa.c | 18 +- apps/genpkey.c | 121 +- apps/genrsa.c | 42 +- apps/include/apps.h | 54 +- apps/include/cmp_mock_srv.h | 4 + apps/include/engine_loader.h | 2 +- apps/include/function.h | 2 +- apps/include/http_server.h | 38 +- apps/include/log.h | 50 + apps/include/opt.h | 87 +- apps/include/s_apps.h | 10 +- apps/info.c | 2 +- apps/lib/app_libctx.c | 2 +- apps/lib/app_rand.c | 10 +- apps/lib/apps.c | 592 +- apps/lib/apps_opt_printf.c | 25 + apps/lib/build.info | 4 +- apps/lib/cmp_mock_srv.c | 151 +- apps/lib/engine_loader.c | 4 +- apps/lib/http_server.c | 323 +- apps/lib/log.c | 108 + apps/lib/names.c | 2 +- apps/lib/opt.c | 215 +- apps/lib/s_cb.c | 108 +- apps/lib/s_socket.c | 75 +- apps/lib/tlssrp_depr.c | 4 +- apps/lib/vms_term_sock.c | 14 +- apps/list.c | 138 +- apps/mac.c | 9 +- apps/nseq.c | 3 +- apps/ocsp.c | 58 +- apps/openssl.c | 38 +- apps/openssl.cnf | 4 +- apps/passwd.c | 2 +- apps/pkcs12.c | 123 +- apps/pkcs7.c | 18 +- apps/pkcs8.c | 23 +- apps/pkey.c | 10 +- apps/pkeyparam.c | 5 +- apps/pkeyutl.c | 11 +- apps/prime.c | 35 +- apps/progs.pl | 10 +- apps/rand.c | 19 +- apps/rehash.c | 33 +- apps/req.c | 321 +- apps/rsa.c | 14 +- apps/rsautl.c | 9 +- apps/s_client.c | 624 +- apps/s_server.c | 158 +- apps/s_time.c | 3 +- apps/sess_id.c | 3 +- apps/smime.c | 59 +- apps/speed.c | 1582 +- apps/spkac.c | 12 +- apps/storeutl.c | 15 +- apps/tsget.in | 2 +- apps/verify.c | 6 +- apps/version.c | 3 +- apps/x509.c | 131 +- crypto/aes/aes_x86core.c | 5 +- crypto/aes/asm/aes-riscv32-zkn.pl | 36 +- crypto/aes/asm/aes-riscv64-zkn.pl | 237 +- crypto/aes/asm/aesni-x86.pl | 2 +- crypto/aes/asm/aesp8-ppc.pl | 147 +- crypto/aes/asm/bsaes-armv8.S | 4 +- crypto/aes/asm/bsaes-armv8.pl | 4 +- crypto/aes/asm/vpaes-armv8.pl | 2 +- crypto/aria/aria.c | 2 +- crypto/arm_arch.h | 19 + crypto/armcap.c | 15 + crypto/asn1/a_bitstr.c | 17 +- crypto/asn1/a_d2i_fp.c | 6 +- crypto/asn1/a_digest.c | 4 +- crypto/asn1/a_dup.c | 6 +- crypto/asn1/a_i2d_fp.c | 6 +- crypto/asn1/a_int.c | 20 +- crypto/asn1/a_mbstr.c | 9 +- crypto/asn1/a_object.c | 20 +- crypto/asn1/a_sign.c | 40 +- crypto/asn1/a_strex.c | 4 +- crypto/asn1/a_strnid.c | 16 +- crypto/asn1/a_time.c | 83 +- crypto/asn1/a_verify.c | 15 +- crypto/asn1/ameth_lib.c | 5 +- crypto/asn1/asn1_gen.c | 34 +- crypto/asn1/asn1_item_list.h | 1 + crypto/asn1/asn1_lib.c | 11 +- crypto/asn1/asn1_local.h | 2 + crypto/asn1/asn_mime.c | 25 +- crypto/asn1/asn_moid.c | 4 +- crypto/asn1/asn_mstbl.c | 2 +- crypto/asn1/asn_pack.c | 22 +- crypto/asn1/bio_asn1.c | 10 +- crypto/asn1/bio_ndef.c | 8 +- crypto/asn1/f_int.c | 1 - crypto/asn1/f_string.c | 1 - crypto/asn1/i2d_evp.c | 5 +- crypto/asn1/p5_pbe.c | 18 +- crypto/asn1/p5_pbev2.c | 116 +- crypto/asn1/p5_scrypt.c | 99 +- crypto/asn1/standard_methods.h | 6 +- crypto/asn1/tasn_dec.c | 16 +- crypto/asn1/tasn_enc.c | 12 +- crypto/asn1/tasn_new.c | 30 +- crypto/asn1/tasn_prn.c | 4 +- crypto/asn1/tasn_scn.c | 4 +- crypto/asn1/tasn_utl.c | 24 +- crypto/asn1/x_algor.c | 59 +- crypto/asn1/x_info.c | 4 +- crypto/asn1/x_int64.c | 10 +- crypto/asn1/x_pkey.c | 13 +- crypto/async/arch/async_null.c | 17 +- crypto/async/arch/async_null.h | 4 +- crypto/async/arch/async_posix.c | 82 +- crypto/async/arch/async_posix.h | 3 + crypto/async/arch/async_win.c | 17 +- crypto/async/arch/async_win.h | 4 +- crypto/async/async.c | 20 +- crypto/async/async_wait.c | 4 +- crypto/bf/bf_local.h | 2 +- crypto/bio/bf_buff.c | 13 +- crypto/bio/bf_lbuf.c | 14 +- crypto/bio/bf_nbio.c | 4 +- crypto/bio/bio_addr.c | 71 +- crypto/bio/bio_cb.c | 22 +- crypto/bio/bio_err.c | 30 +- crypto/bio/bio_lib.c | 132 +- crypto/bio/bio_local.h | 23 +- crypto/bio/bio_meth.c | 36 +- crypto/bio/bio_print.c | 14 +- crypto/bio/bio_sock.c | 49 +- crypto/bio/bio_sock2.c | 113 + crypto/bio/bss_acpt.c | 8 +- crypto/bio/bss_bio.c | 10 +- crypto/bio/bss_conn.c | 283 +- crypto/bio/bss_dgram.c | 1238 +- crypto/bio/bss_dgram_pair.c | 1328 ++ crypto/bio/bss_fd.c | 2 +- crypto/bio/bss_file.c | 2 +- crypto/bio/bss_log.c | 8 +- crypto/bio/bss_mem.c | 2 +- crypto/bio/bss_sock.c | 82 +- crypto/bio/build.info | 2 +- crypto/bio/ossl_core_bio.c | 12 +- crypto/bn/asm/armv8-mont.pl | 2 +- crypto/bn/asm/mips.pl | 2 +- crypto/bn/asm/rsaz-2k-avx512.pl | 2 +- crypto/bn/asm/sparcv8.S | 8 +- crypto/bn/asm/sparcv8plus.S | 6 +- crypto/bn/asm/x86_64-mont5.pl | 2 +- crypto/bn/bn_blind.c | 6 +- crypto/bn/bn_const.c | 2 +- crypto/bn/bn_conv.c | 8 +- crypto/bn/bn_ctx.c | 12 +- crypto/bn/bn_exp.c | 39 +- crypto/bn/bn_gcd.c | 2 +- crypto/bn/bn_gf2m.c | 20 +- crypto/bn/bn_intern.c | 10 +- crypto/bn/bn_lib.c | 272 +- crypto/bn/bn_local.h | 7 +- crypto/bn/bn_mod.c | 16 +- crypto/bn/bn_mont.c | 4 +- crypto/bn/bn_mul.c | 2 +- crypto/bn/bn_nist.c | 2 +- crypto/bn/bn_prime.c | 6 +- crypto/bn/bn_rand.c | 4 +- crypto/bn/bn_recp.c | 4 +- crypto/bn/bn_rsa_fips186_4.c | 2 +- crypto/bn/bn_s390x.c | 143 + crypto/bn/build.info | 2 +- crypto/bn/rsaz_exp.c | 13 +- crypto/bn/rsaz_exp.h | 2 +- crypto/bn/rsaz_exp_x2.c | 9 +- crypto/buffer/buffer.c | 10 +- crypto/build.info | 8 +- crypto/buildinf.h | 2 +- crypto/chacha/asm/chacha-loongarch64.pl | 1413 ++ crypto/chacha/build.info | 4 + crypto/chacha/chacha_enc.c | 2 +- crypto/cmac/cmac.c | 43 +- crypto/cmp/build.info | 11 +- crypto/cmp/cmp_asn.c | 139 +- crypto/cmp/cmp_client.c | 24 +- crypto/cmp/cmp_ctx.c | 459 +- crypto/cmp/cmp_err.c | 5 + crypto/cmp/cmp_genm.c | 346 + crypto/cmp/cmp_hdr.c | 8 +- crypto/cmp/cmp_http.c | 7 +- crypto/cmp/cmp_local.h | 43 +- crypto/cmp/cmp_msg.c | 64 +- crypto/cmp/cmp_protect.c | 77 +- crypto/cmp/cmp_server.c | 13 +- crypto/cmp/cmp_status.c | 10 +- crypto/cmp/cmp_util.c | 8 +- crypto/cmp/cmp_vfy.c | 121 +- crypto/cms/cms_asn1.c | 3 +- crypto/cms/cms_cd.c | 9 +- crypto/cms/cms_dd.c | 2 +- crypto/cms/cms_dh.c | 16 +- crypto/cms/cms_ec.c | 10 +- crypto/cms/cms_enc.c | 14 +- crypto/cms/cms_env.c | 145 +- crypto/cms/cms_err.c | 2 + crypto/cms/cms_ess.c | 34 +- crypto/cms/cms_io.c | 3 +- crypto/cms/cms_lib.c | 63 +- crypto/cms/cms_local.h | 9 +- crypto/cms/cms_pwri.c | 58 +- crypto/cms/cms_rsa.c | 44 +- crypto/cms/cms_sd.c | 205 +- crypto/cms/cms_smime.c | 82 +- crypto/comp/build.info | 2 + crypto/comp/c_brotli.c | 800 + crypto/comp/c_zlib.c | 160 +- crypto/comp/c_zstd.c | 845 + crypto/comp/comp_err.c | 13 + crypto/comp/comp_lib.c | 11 +- crypto/comp/comp_local.h | 12 +- crypto/conf/conf_def.c | 49 +- crypto/conf/conf_lib.c | 16 +- crypto/conf/conf_mod.c | 10 +- crypto/context.c | 42 +- crypto/core_algorithm.c | 4 +- crypto/core_fetch.c | 2 +- crypto/cpuid.c | 12 +- crypto/crmf/crmf_asn.c | 25 +- crypto/crmf/crmf_lib.c | 84 +- crypto/crmf/crmf_local.h | 4 +- crypto/crmf/crmf_pbm.c | 7 +- crypto/cryptlib.c | 6 +- crypto/ct/ct_b64.c | 6 +- crypto/ct/ct_log.c | 38 +- crypto/ct/ct_oct.c | 12 +- crypto/ct/ct_policy.c | 14 +- crypto/ct/ct_sct.c | 16 +- crypto/ct/ct_sct_ctx.c | 5 +- crypto/ctype.c | 4 +- crypto/der_writer.c | 2 +- crypto/des/des_local.h | 17 +- crypto/des/set_key.c | 2 +- crypto/deterministic_nonce.c | 198 + crypto/dh/dh_ameth.c | 12 +- crypto/dh/dh_backend.c | 10 +- crypto/dh/dh_check.c | 12 + crypto/dh/dh_err.c | 4 +- crypto/dh/dh_gen.c | 2 +- crypto/dh/dh_key.c | 23 +- crypto/dh/dh_lib.c | 18 +- crypto/dh/dh_meth.c | 6 +- crypto/dh/dh_pmeth.c | 10 +- crypto/dsa/dsa_ameth.c | 16 +- crypto/dsa/dsa_backend.c | 4 +- crypto/dsa/dsa_key.c | 91 +- crypto/dsa/dsa_lib.c | 26 +- crypto/dsa/dsa_local.h | 6 +- crypto/dsa/dsa_meth.c | 6 +- crypto/dsa/dsa_ossl.c | 47 +- crypto/dsa/dsa_sign.c | 13 +- crypto/dso/dso_dl.c | 12 +- crypto/dso/dso_dlfcn.c | 12 +- crypto/dso/dso_lib.c | 29 +- crypto/dso/dso_local.h | 3 +- crypto/ec/asm/ecp_nistp384-ppc64.pl | 306 + crypto/ec/asm/ecp_nistz256-armv8.pl | 2 +- crypto/ec/asm/ecp_sm2p256-armv8.S | 826 + crypto/ec/asm/ecp_sm2p256-armv8.pl | 823 + crypto/ec/build.info | 72 +- crypto/ec/curve25519.c | 88 +- crypto/ec/curve448/arch_32/f_impl32.c | 10 +- crypto/ec/curve448/arch_64/f_impl64.c | 8 +- crypto/ec/curve448/curve448.c | 160 +- crypto/ec/curve448/curve448_local.h | 13 +- crypto/ec/curve448/eddsa.c | 52 +- crypto/ec/curve448/f_generic.c | 40 +- crypto/ec/curve448/field.h | 24 +- crypto/ec/curve448/point_448.h | 4 +- crypto/ec/ec2_smpl.c | 10 +- crypto/ec/ec_ameth.c | 6 +- crypto/ec/ec_asn1.c | 54 +- crypto/ec/ec_backend.c | 18 +- crypto/ec/ec_check.c | 4 +- crypto/ec/ec_curve.c | 17 +- crypto/ec/ec_deprecated.c | 6 +- crypto/ec/ec_key.c | 50 +- crypto/ec/ec_kmeth.c | 21 +- crypto/ec/ec_lib.c | 70 +- crypto/ec/ec_local.h | 39 +- crypto/ec/ec_mult.c | 39 +- crypto/ec/ec_oct.c | 4 +- crypto/ec/ec_pmeth.c | 8 +- crypto/ec/ecdh_ossl.c | 17 +- crypto/ec/ecdsa_ossl.c | 89 +- crypto/ec/eck_prn.c | 4 +- crypto/ec/ecp_mont.c | 2 +- crypto/ec/ecp_nistp256.c | 25 +- crypto/ec/ecp_nistp384.c | 1997 ++ crypto/ec/ecp_nistz256.c | 46 +- crypto/ec/ecp_s390x_nistp.c | 12 +- crypto/ec/ecp_sm2p256.c | 790 + crypto/ec/ecp_sm2p256_table.c | 16387 ++++++++++++++++ crypto/ec/ecp_smpl.c | 8 +- crypto/ec/ecx_backend.c | 26 +- crypto/ec/ecx_key.c | 85 +- crypto/ec/ecx_meth.c | 67 +- crypto/encode_decode/decoder_lib.c | 41 +- crypto/encode_decode/decoder_meth.c | 20 +- crypto/encode_decode/decoder_pkey.c | 425 +- crypto/encode_decode/encoder_lib.c | 6 +- crypto/encode_decode/encoder_local.h | 3 +- crypto/encode_decode/encoder_meth.c | 20 +- crypto/encode_decode/encoder_pkey.c | 10 +- crypto/engine/eng_ctrl.c | 15 +- crypto/engine/eng_dyn.c | 12 +- crypto/engine/eng_init.c | 12 +- crypto/engine/eng_lib.c | 24 +- crypto/engine/eng_list.c | 68 +- crypto/engine/eng_local.h | 12 +- crypto/engine/eng_openssl.c | 4 +- crypto/engine/tb_asnmth.c | 17 +- crypto/err/build.info | 2 +- crypto/err/err.c | 81 +- crypto/err/err_all.c | 4 +- crypto/err/err_local.h | 15 +- crypto/err/err_mark.c | 88 + crypto/err/err_save.c | 156 + crypto/err/openssl.ec | 2 - crypto/err/openssl.txt | 95 +- crypto/ess/ess_lib.c | 119 +- crypto/evp/asymcipher.c | 39 +- crypto/evp/bio_b64.c | 89 +- crypto/evp/bio_enc.c | 7 +- crypto/evp/bio_ok.c | 7 +- crypto/evp/c_allc.c | 5 +- crypto/evp/cmeth_lib.c | 6 +- crypto/evp/ctrl_params_translate.c | 78 +- crypto/evp/digest.c | 58 +- crypto/evp/e_aes.c | 50 +- crypto/evp/e_aria.c | 54 +- crypto/evp/e_camellia.c | 16 +- crypto/evp/e_chacha20_poly1305.c | 33 +- crypto/evp/e_des.c | 3 +- crypto/evp/e_des3.c | 3 +- crypto/evp/e_idea.c | 6 +- crypto/evp/e_seed.c | 2 +- crypto/evp/evp_enc.c | 53 +- crypto/evp/evp_err.c | 6 +- crypto/evp/evp_fetch.c | 18 +- crypto/evp/evp_lib.c | 6 +- crypto/evp/evp_local.h | 11 +- crypto/evp/evp_pbe.c | 15 +- crypto/evp/evp_pkey.c | 4 +- crypto/evp/evp_rand.c | 34 +- crypto/evp/exchange.c | 25 +- crypto/evp/kdf_lib.c | 10 +- crypto/evp/kdf_meth.c | 13 +- crypto/evp/kem.c | 110 +- crypto/evp/keymgmt_lib.c | 12 +- crypto/evp/keymgmt_meth.c | 52 +- crypto/evp/legacy_blake2.c | 30 +- crypto/evp/m_sigver.c | 100 +- crypto/evp/mac_lib.c | 25 +- crypto/evp/mac_meth.c | 15 +- crypto/evp/p_dec.c | 2 +- crypto/evp/p_enc.c | 2 +- crypto/evp/p_lib.c | 50 +- crypto/evp/p_open.c | 8 +- crypto/evp/p_seal.c | 4 +- crypto/evp/p_sign.c | 6 +- crypto/evp/p_verify.c | 6 +- crypto/evp/pmeth_gn.c | 8 +- crypto/evp/pmeth_lib.c | 99 +- crypto/evp/signature.c | 20 +- crypto/ex_data.c | 20 +- crypto/ffc/ffc_backend.c | 12 +- crypto/ffc/ffc_key_generate.c | 2 +- crypto/ffc/ffc_params.c | 9 +- crypto/ffc/ffc_params_generate.c | 8 +- crypto/hpke/build.info | 5 + crypto/hpke/hpke.c | 1463 ++ crypto/hpke/hpke_util.c | 528 + crypto/http/http_client.c | 136 +- crypto/init.c | 17 +- crypto/lhash/lh_stats.c | 2 +- crypto/lhash/lhash.c | 10 +- crypto/mem.c | 25 +- crypto/mem_sec.c | 30 +- crypto/modes/aes-gcm-armv8-unroll8_64.S | 84 +- crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl | 156 +- crypto/modes/asm/aes-gcm-armv8_64.pl | 60 +- crypto/modes/asm/aes-gcm-avx512.S | 13102 ++++++------ crypto/modes/asm/aes-gcm-avx512.pl | 326 +- crypto/modes/asm/ghash-riscv64.pl | 636 +- crypto/modes/asm/ghash-s390x.pl | 2 +- crypto/modes/build.info | 2 +- crypto/modes/gcm128.c | 96 +- crypto/modes/ocb128.c | 8 +- crypto/modes/xts128gb.c | 199 + crypto/o_fopen.c | 4 +- crypto/o_str.c | 22 +- crypto/objects/o_names.c | 3 +- crypto/objects/obj_dat.c | 80 +- crypto/objects/obj_dat.h | 362 +- crypto/objects/obj_lib.c | 1 - crypto/objects/obj_local.h | 2 +- crypto/objects/obj_mac.num | 72 + crypto/objects/obj_xref.c | 4 +- crypto/objects/obj_xref.h | 12 +- crypto/objects/obj_xref.txt | 4 + crypto/objects/objects.txt | 149 +- crypto/ocsp/ocsp_prn.c | 6 +- crypto/ocsp/ocsp_vfy.c | 4 +- crypto/ocsp/v3_ocsp.c | 2 +- crypto/packet.c | 100 +- crypto/param_build.c | 52 +- crypto/params.c | 167 +- crypto/params_dup.c | 9 +- crypto/params_from_text.c | 11 +- crypto/params_idx.c | 2710 +++ crypto/params_idx.c.in | 21 + crypto/passphrase.c | 19 +- crypto/pem/pem_info.c | 2 +- crypto/pem/pem_lib.c | 148 +- crypto/pem/pem_sign.c | 4 +- crypto/pem/pvkfmt.c | 141 +- crypto/perlasm/arm-xlate.pl | 10 + crypto/perlasm/riscv.pm | 259 + crypto/perlasm/x86asm.pl | 2 +- crypto/pkcs12/p12_add.c | 28 +- crypto/pkcs12/p12_asn.c | 19 +- crypto/pkcs12/p12_attr.c | 18 +- crypto/pkcs12/p12_crt.c | 78 +- crypto/pkcs12/p12_decr.c | 10 +- crypto/pkcs12/p12_init.c | 14 +- crypto/pkcs12/p12_key.c | 4 +- crypto/pkcs12/p12_kiss.c | 73 +- crypto/pkcs12/p12_local.h | 4 +- crypto/pkcs12/p12_mutl.c | 10 +- crypto/pkcs12/p12_npas.c | 147 +- crypto/pkcs12/p12_p8e.c | 1 - crypto/pkcs12/p12_sbag.c | 55 +- crypto/pkcs12/p12_utl.c | 46 +- crypto/pkcs12/pk12err.c | 5 +- crypto/pkcs7/pk7_asn1.c | 3 +- crypto/pkcs7/pk7_attr.c | 33 +- crypto/pkcs7/pk7_doit.c | 91 +- crypto/pkcs7/pk7_lib.c | 36 +- crypto/pkcs7/pk7_smime.c | 69 +- crypto/poly1305/poly1305_ieee754.c | 4 +- crypto/property/property.c | 2 +- crypto/property/property_local.h | 2 +- crypto/provider.c | 27 +- crypto/provider_child.c | 2 +- crypto/provider_conf.c | 12 +- crypto/provider_core.c | 212 +- crypto/punycode.c | 26 +- crypto/quic_vlint.c | 81 + crypto/rand/build.info | 3 +- crypto/rand/prov_seed.c | 4 +- crypto/rand/rand_egd.c | 6 +- crypto/rand/rand_lib.c | 43 +- crypto/rand/rand_pool.c | 16 +- crypto/rand/rand_uniform.c | 109 + crypto/rand/randfile.c | 4 +- crypto/rc2/rc2_local.h | 68 +- crypto/rc4/asm/rc4-x86_64.pl | 4 +- crypto/rsa/rsa_ameth.c | 8 +- crypto/rsa/rsa_backend.c | 8 +- crypto/rsa/rsa_chk.c | 2 +- crypto/rsa/rsa_crpt.c | 4 +- crypto/rsa/rsa_gen.c | 15 +- crypto/rsa/rsa_lib.c | 22 +- crypto/rsa/rsa_meth.c | 6 +- crypto/rsa/rsa_mp.c | 6 +- crypto/rsa/rsa_oaep.c | 12 +- crypto/rsa/rsa_ossl.c | 201 +- crypto/rsa/rsa_pk1.c | 258 +- crypto/rsa/rsa_pmeth.c | 28 +- crypto/rsa/rsa_pss.c | 19 +- crypto/rsa/rsa_saos.c | 8 +- crypto/rsa/rsa_sign.c | 10 +- crypto/rsa/rsa_sp800_56b_check.c | 7 +- crypto/rsa/rsa_sp800_56b_gen.c | 4 +- crypto/rsa/rsa_x931g.c | 9 +- crypto/s390x_arch.h | 16 +- crypto/s390xcap.c | 87 +- crypto/sha/asm/keccak1600-ppc64.pl | 2 +- crypto/sha/asm/sha1-armv8.pl | 2 +- crypto/sha/asm/sha256-armv8.S | 2 +- crypto/sha/asm/sha512-armv8.S | 2 +- crypto/sha/asm/sha512-armv8.pl | 2 +- crypto/sha/asm/sha512-ia64.pl | 2 +- crypto/sha/keccak1600.c | 10 +- crypto/sha/sha1dgst.c | 4 +- crypto/sha/sha256.c | 16 +- crypto/sha/sha512.c | 2 +- crypto/sleep.c | 95 + crypto/sm2/sm2_crypt.c | 28 +- crypto/sm2/sm2_key.c | 2 +- crypto/sm2/sm2_sign.c | 43 +- crypto/sm3/sm3_local.h | 4 +- crypto/sm4/asm/vpsm4-armv8.S | 2283 +++ crypto/sm4/asm/vpsm4-armv8.pl | 460 + crypto/sm4/asm/vpsm4_ex-armv8.S | 4504 +++++ crypto/sm4/asm/vpsm4_ex-armv8.pl | 1553 ++ crypto/sm4/build.info | 4 +- crypto/srp/srp_vfy.c | 11 +- crypto/stack/stack.c | 87 +- crypto/store/store_lib.c | 145 +- crypto/store/store_local.h | 5 +- crypto/store/store_meth.c | 21 +- crypto/store/store_register.c | 13 +- crypto/store/store_result.c | 2 +- crypto/thread/api.c | 73 + crypto/thread/arch.c | 132 + crypto/thread/arch/thread_none.c | 82 + crypto/thread/arch/thread_posix.c | 233 + crypto/thread/arch/thread_win.c | 599 + crypto/thread/build.info | 21 + crypto/thread/internal.c | 157 + crypto/threads_lib.c | 2 +- crypto/threads_none.c | 12 +- crypto/threads_pthread.c | 30 +- crypto/threads_win.c | 23 +- crypto/time.c | 48 + crypto/trace.c | 27 +- crypto/ts/ts_local.h | 2 +- crypto/txt_db/txt_db.c | 3 +- crypto/ui/ui_lib.c | 55 +- crypto/uid.c | 4 +- crypto/x509/build.info | 3 +- crypto/x509/by_dir.c | 33 +- crypto/x509/by_file.c | 96 +- crypto/x509/by_store.c | 3 +- crypto/x509/ext_dat.h | 8 +- crypto/x509/pcy_cache.c | 16 +- crypto/x509/pcy_data.c | 3 +- crypto/x509/pcy_map.c | 2 +- crypto/x509/pcy_node.c | 14 +- crypto/x509/pcy_tree.c | 6 +- crypto/x509/standard_exts.h | 10 +- crypto/x509/t_req.c | 10 +- crypto/x509/t_x509.c | 15 +- crypto/x509/v3_addr.c | 85 +- crypto/x509/v3_admis.c | 6 +- crypto/x509/v3_akid.c | 65 +- crypto/x509/v3_asid.c | 26 +- crypto/x509/v3_bcons.c | 2 +- crypto/x509/v3_bitst.c | 4 +- crypto/x509/v3_conf.c | 58 +- crypto/x509/v3_cpols.c | 118 +- crypto/x509/v3_crld.c | 42 +- crypto/x509/v3_extku.c | 2 +- crypto/x509/v3_group_ac.c | 53 + crypto/x509/v3_ia5.c | 13 +- crypto/x509/v3_ind_iss.c | 53 + crypto/x509/v3_info.c | 13 +- crypto/x509/v3_ist.c | 10 +- crypto/x509/v3_lib.c | 15 +- crypto/x509/v3_ncons.c | 39 +- crypto/x509/v3_no_ass.c | 53 + crypto/x509/v3_no_rev_avail.c | 53 + crypto/x509/v3_pci.c | 21 +- crypto/x509/v3_pcia.c | 14 +- crypto/x509/v3_pcons.c | 2 +- crypto/x509/v3_pmaps.c | 4 +- crypto/x509/v3_purp.c | 255 +- crypto/x509/v3_san.c | 16 +- crypto/x509/v3_single_use.c | 53 + crypto/x509/v3_skid.c | 2 +- crypto/x509/v3_soa_id.c | 53 + crypto/x509/v3_sxnet.c | 25 +- crypto/x509/v3_tlsf.c | 4 +- crypto/x509/v3_utf8.c | 8 +- crypto/x509/v3_utl.c | 30 +- crypto/x509/v3err.c | 5 +- crypto/x509/x509_att.c | 127 +- crypto/x509/x509_cmp.c | 32 +- crypto/x509/x509_d2.c | 2 +- crypto/x509/x509_def.c | 2 +- crypto/x509/x509_err.c | 2 +- crypto/x509/x509_lu.c | 321 +- crypto/x509/x509_meth.c | 4 +- crypto/x509/x509_obj.c | 10 +- crypto/x509/x509_r2x.c | 2 +- crypto/x509/x509_req.c | 35 +- crypto/x509/x509_set.c | 89 +- crypto/x509/x509_trust.c | 25 +- crypto/x509/x509_txt.c | 2 + crypto/x509/x509_v3.c | 22 +- crypto/x509/x509_vfy.c | 414 +- crypto/x509/x509_vpm.c | 33 +- crypto/x509/x509cset.c | 40 +- crypto/x509/x509name.c | 4 +- crypto/x509/x509spki.c | 5 +- crypto/x509/x_all.c | 60 +- crypto/x509/x_crl.c | 28 +- crypto/x509/x_name.c | 52 +- crypto/x509/x_pubkey.c | 85 +- crypto/x509/x_req.c | 4 +- crypto/x509/x_x509.c | 6 +- import_openssl.sh | 11 +- include/crypto/aes_platform.h | 33 +- include/crypto/asn1.h | 12 +- include/crypto/bioerr.h | 2 +- include/crypto/bn.h | 9 + include/crypto/cmserr.h | 2 +- include/crypto/context.h | 6 + include/crypto/decoder.h | 12 +- include/crypto/dherr.h | 2 +- include/crypto/dsa.h | 4 +- include/crypto/ec.h | 8 +- include/crypto/ecx.h | 34 +- include/crypto/encoder.h | 2 +- include/crypto/evp.h | 28 +- include/crypto/evperr.h | 2 +- include/crypto/md32_common.h | 96 +- include/crypto/modes.h | 12 + include/crypto/pkcs12err.h | 2 +- include/crypto/punycode.h | 4 +- include/crypto/rand.h | 11 + include/crypto/riscv_arch.h | 7 +- include/crypto/rsa.h | 8 +- include/crypto/sha.h | 3 +- include/crypto/sm4_platform.h | 40 +- include/crypto/store.h | 2 +- include/crypto/x509.h | 8 +- include/crypto/x509err.h | 2 +- include/internal/asn1.h | 2 + include/internal/bio.h | 10 + include/internal/bio_addr.h | 29 + include/internal/bio_tfo.h | 151 + include/internal/common.h | 217 + include/internal/comp.h | 2 + include/internal/cryptlib.h | 93 +- include/internal/der.h | 76 +- include/internal/deterministic_nonce.h | 24 + include/internal/e_os.h | 58 +- include/internal/endian.h | 4 +- include/internal/event_queue.h | 163 + include/internal/ffc.h | 11 +- include/internal/hpke_util.h | 100 + include/internal/ktls.h | 26 +- include/internal/list.h | 169 + include/internal/namemap.h | 2 +- include/internal/numbers.h | 27 +- include/internal/packet.h | 4 +- include/internal/packet_quic.h | 150 + include/internal/param_build_set.h | 7 +- include/internal/param_names.h | 376 + include/internal/param_names.h.in | 18 + include/internal/params.h | 38 + include/internal/priority_queue.h | 88 + include/internal/property.h | 2 +- include/internal/provider.h | 4 +- include/internal/quic_ackm.h | 297 + include/internal/quic_cc.h | 219 + include/internal/quic_cfq.h | 154 + include/internal/quic_channel.h | 429 + include/internal/quic_demux.h | 364 + include/internal/quic_error.h | 56 + include/internal/quic_fc.h | 277 + include/internal/quic_fifd.h | 80 + include/internal/quic_reactor.h | 188 + include/internal/quic_record_rx.h | 569 + include/internal/quic_record_tx.h | 383 + include/internal/quic_record_util.h | 116 + include/internal/quic_rx_depack.h | 21 + include/internal/quic_sf_list.h | 151 + include/internal/quic_ssl.h | 132 + include/internal/quic_statm.h | 40 + include/internal/quic_stream.h | 429 + include/internal/quic_stream_map.h | 878 + include/internal/quic_thread_assist.h | 102 + include/internal/quic_tls.h | 106 + include/internal/quic_tserver.h | 220 + include/internal/quic_txp.h | 209 + include/internal/quic_txpim.h | 133 + include/internal/quic_types.h | 116 + include/internal/quic_vlint.h | 127 + include/internal/quic_wire.h | 784 + include/internal/quic_wire_pkt.h | 629 + include/internal/recordmethod.h | 339 + include/internal/refcount.h | 187 +- include/internal/ring_buf.h | 277 + include/internal/safe_math.h | 443 + include/internal/sockets.h | 33 +- include/internal/ssl.h | 24 + include/internal/ssl3_cbc.h | 40 + {ssl/statem => include/internal}/statem.h | 78 +- include/internal/thread.h | 39 + include/internal/thread_arch.h | 127 + include/internal/time.h | 242 + include/internal/tlsgroups.h | 10 + include/internal/tsan_assist.h | 129 +- include/internal/uint_set.h | 63 + include/openssl/asn1.h | 6 +- include/openssl/asn1.h.in | 6 +- include/openssl/async.h | 10 +- include/openssl/bio.h | 143 +- include/openssl/bio.h.in | 143 +- include/openssl/bioerr.h | 9 +- include/openssl/bn.h | 6 + include/openssl/cmp.h | 42 +- include/openssl/cmp.h.in | 42 +- include/openssl/cmperr.h | 4 + include/openssl/cms.h | 35 +- include/openssl/cms.h.in | 35 +- include/openssl/cmserr.h | 1 + include/openssl/comp.h | 9 +- include/openssl/comperr.h | 7 + include/openssl/conf.h | 2 +- include/openssl/conf.h.in | 2 +- include/openssl/configuration-32.h | 32 +- include/openssl/configuration-64.h | 32 +- include/openssl/configuration-static-32.h | 32 +- include/openssl/configuration-static-64.h | 32 +- include/openssl/configuration.h.in | 6 + include/openssl/core.h | 5 +- include/openssl/core_dispatch.h | 24 + include/openssl/core_names.h | 952 +- include/openssl/core_names.h.in | 119 + include/openssl/crmf.h | 10 +- include/openssl/crmf.h.in | 10 +- include/openssl/crypto.h | 5 +- include/openssl/crypto.h.in | 5 +- include/openssl/ct.h | 2 +- include/openssl/ct.h.in | 2 +- include/openssl/dh.h | 6 +- include/openssl/dherr.h | 4 +- include/openssl/dsa.h | 2 +- include/openssl/e_os2.h | 4 +- include/openssl/e_ostime.h | 30 + include/openssl/ec.h | 22 +- include/openssl/err.h | 9 +- include/openssl/err.h.in | 9 +- include/openssl/evp.h | 36 +- include/openssl/evperr.h | 5 +- include/openssl/hpke.h | 169 + include/openssl/http.h | 6 +- include/openssl/lhash.h | 2 +- include/openssl/lhash.h.in | 2 +- include/openssl/macros.h | 3 +- include/openssl/obj_mac.h | 349 +- include/openssl/opensslv.h | 12 +- include/openssl/pem.h | 3 +- include/openssl/pkcs12.h | 12 +- include/openssl/pkcs12.h.in | 12 +- include/openssl/pkcs12err.h | 3 +- include/openssl/pkcs7.h | 16 +- include/openssl/pkcs7.h.in | 16 +- include/openssl/prov_ssl.h | 6 +- include/openssl/proverr.h | 4 + include/openssl/provider.h | 10 +- include/openssl/quic.h | 37 + include/openssl/rand.h | 2 +- include/openssl/rsa.h | 7 +- include/openssl/sha.h | 3 +- include/openssl/srtp.h | 28 +- include/openssl/ssl.h | 195 +- include/openssl/ssl.h.in | 195 +- include/openssl/ssl3.h | 12 +- include/openssl/sslerr.h | 26 +- include/openssl/store.h | 12 +- include/openssl/thread.h | 31 + include/openssl/tls1.h | 34 +- include/openssl/trace.h | 10 +- include/openssl/ts.h | 2 +- include/openssl/types.h | 2 +- include/openssl/x509.h | 15 +- include/openssl/x509.h.in | 15 +- include/openssl/x509_vfy.h | 119 +- include/openssl/x509_vfy.h.in | 119 +- include/openssl/x509err.h | 2 +- include/openssl/x509v3.h | 3 +- include/openssl/x509v3.h.in | 3 +- include/openssl/x509v3err.h | 5 +- openssl.cmake | 116 +- openssl.config | 1 + openssl.version | 2 +- providers/baseprov.c | 2 +- providers/common/capabilities.c | 20 +- providers/common/der/build.info | 6 +- providers/common/der/der_rsa_key.c | 2 +- providers/common/der/oids_to_c.pm | 2 +- providers/common/provider_err.c | 6 + providers/common/provider_seeding.c | 2 +- providers/common/provider_util.c | 4 +- providers/decoders.inc | 5 +- providers/defltprov.c | 34 +- providers/encoders.inc | 6 +- providers/fips-sources.checksums | 498 +- providers/fips.checksum | 2 +- providers/fips.module.sources | 32 +- providers/fips/fipsprov.c | 10 +- .../implementations/asymciphers/rsa_enc.c | 36 +- .../implementations/asymciphers/sm2_enc.c | 4 +- providers/implementations/ciphers/build.info | 56 +- .../implementations/ciphers/cipher_aes.c | 4 +- .../ciphers/cipher_aes_cbc_hmac_sha.c | 24 +- .../implementations/ciphers/cipher_aes_ccm.c | 22 +- .../ciphers/cipher_aes_ccm_hw.c | 10 +- ...d_zkne.inc => cipher_aes_ccm_hw_rv32i.inc} | 6 +- ...d_zkne.inc => cipher_aes_ccm_hw_rv64i.inc} | 4 +- .../implementations/ciphers/cipher_aes_gcm.c | 17 +- .../ciphers/cipher_aes_gcm_hw.c | 9 +- ...d_zkne.inc => cipher_aes_gcm_hw_rv32i.inc} | 6 +- ...d_zkne.inc => cipher_aes_gcm_hw_rv64i.inc} | 4 +- .../ciphers/cipher_aes_gcm_hw_vaes_avx512.inc | 9 +- .../ciphers/cipher_aes_gcm_siv.c | 323 + .../ciphers/cipher_aes_gcm_siv.h | 76 + .../ciphers/cipher_aes_gcm_siv_hw.c | 373 + .../ciphers/cipher_aes_gcm_siv_polyval.c | 95 + .../implementations/ciphers/cipher_aes_hw.c | 10 +- ..._zknd_zkne.inc => cipher_aes_hw_rv32i.inc} | 6 +- ..._zknd_zkne.inc => cipher_aes_hw_rv64i.inc} | 4 +- .../implementations/ciphers/cipher_aes_ocb.c | 13 +- .../ciphers/cipher_aes_ocb_hw.c | 14 +- .../implementations/ciphers/cipher_aes_siv.c | 8 +- .../implementations/ciphers/cipher_aes_wrp.c | 25 +- .../implementations/ciphers/cipher_aes_xts.c | 8 +- .../ciphers/cipher_aes_xts_hw.c | 14 +- .../implementations/ciphers/cipher_aria.c | 4 +- .../implementations/ciphers/cipher_aria_ccm.c | 17 +- .../implementations/ciphers/cipher_aria_gcm.c | 17 +- .../implementations/ciphers/cipher_blowfish.c | 6 +- .../implementations/ciphers/cipher_camellia.c | 4 +- .../implementations/ciphers/cipher_cast5.c | 4 +- .../implementations/ciphers/cipher_chacha20.c | 4 +- .../ciphers/cipher_chacha20_poly1305.c | 23 +- .../implementations/ciphers/cipher_cts.h | 4 +- .../implementations/ciphers/cipher_des.c | 9 +- .../implementations/ciphers/cipher_des_hw.c | 3 +- .../implementations/ciphers/cipher_idea.c | 4 +- .../implementations/ciphers/cipher_null.c | 4 +- .../implementations/ciphers/cipher_rc2.c | 14 +- .../implementations/ciphers/cipher_rc4.c | 10 +- .../ciphers/cipher_rc4_hmac_md5.c | 15 +- .../implementations/ciphers/cipher_rc5.c | 10 +- .../implementations/ciphers/cipher_rc5.h | 2 +- .../implementations/ciphers/cipher_seed.c | 4 +- .../implementations/ciphers/cipher_sm4.c | 4 +- .../implementations/ciphers/cipher_sm4_ccm.c | 17 +- .../implementations/ciphers/cipher_sm4_ccm.h | 2 +- .../ciphers/cipher_sm4_ccm_hw.c | 38 +- .../implementations/ciphers/cipher_sm4_gcm.c | 17 +- .../implementations/ciphers/cipher_sm4_gcm.h | 2 +- .../ciphers/cipher_sm4_gcm_hw.c | 34 +- .../implementations/ciphers/cipher_sm4_hw.c | 28 +- .../implementations/ciphers/cipher_sm4_xts.c | 281 + .../implementations/ciphers/cipher_sm4_xts.h | 46 + .../ciphers/cipher_sm4_xts_hw.c | 94 + .../implementations/ciphers/cipher_tdes.h | 4 +- .../ciphers/cipher_tdes_common.c | 5 +- .../ciphers/cipher_tdes_default_hw.c | 3 +- .../ciphers/cipher_tdes_wrap.c | 4 +- .../implementations/ciphers/ciphercommon.c | 35 +- .../ciphers/ciphercommon_block.c | 23 +- .../ciphers/ciphercommon_ccm.c | 7 +- .../ciphers/ciphercommon_gcm.c | 295 +- .../implementations/digests/blake2_prov.c | 109 +- .../implementations/digests/blake2b_prov.c | 74 +- providers/implementations/digests/sha2_prov.c | 9 +- providers/implementations/digests/sha3_prov.c | 72 +- .../encode_decode/decode_der2key.c | 116 +- .../encode_decode/decode_epki2pki.c | 36 +- .../encode_decode/decode_msblob2key.c | 6 +- .../encode_decode/decode_pem2der.c | 5 +- .../encode_decode/decode_pvk2key.c | 35 +- .../encode_decode/decode_spki2typespki.c | 37 +- .../encode_decode/encode_key2any.c | 32 +- .../encode_decode/encode_key2blob.c | 4 +- .../encode_decode/encode_key2ms.c | 4 +- .../encode_decode/encode_key2text.c | 18 +- providers/implementations/exchange/build.info | 6 +- providers/implementations/exchange/dh_exch.c | 10 +- .../implementations/exchange/ecdh_exch.c | 14 +- providers/implementations/exchange/ecx_exch.c | 78 +- providers/implementations/exchange/kdf_exch.c | 4 +- .../implementations/include/prov/blake2.h | 14 +- .../include/prov/ciphercommon.h | 85 +- .../include/prov/ciphercommon_aead.h | 21 +- .../include/prov/ciphercommon_ccm.h | 14 +- .../include/prov/ciphercommon_gcm.h | 26 +- providers/implementations/include/prov/ecx.h | 31 + .../implementations/include/prov/hmac_drbg.h | 33 + .../include/prov/implementations.h | 24 +- .../include/prov/kdfexchange.h | 3 +- .../include/prov/macsignature.h | 3 +- .../implementations/include/prov/names.h | 17 +- .../implementations/include/prov/seeding.h | 2 +- providers/implementations/kdfs/argon2.c | 1560 ++ providers/implementations/kdfs/build.info | 8 + providers/implementations/kdfs/hkdf.c | 71 +- providers/implementations/kdfs/hmacdrbg_kdf.c | 259 + providers/implementations/kdfs/kbkdf.c | 41 +- providers/implementations/kdfs/krb5kdf.c | 8 +- providers/implementations/kdfs/pbkdf1.c | 16 +- providers/implementations/kdfs/pbkdf2.c | 14 +- providers/implementations/kdfs/pkcs12kdf.c | 20 +- providers/implementations/kdfs/pvkkdf.c | 248 + providers/implementations/kdfs/scrypt.c | 20 +- providers/implementations/kdfs/sshkdf.c | 8 +- providers/implementations/kdfs/sskdf.c | 66 +- providers/implementations/kdfs/tls1_prf.c | 13 +- providers/implementations/kdfs/x942kdf.c | 10 +- providers/implementations/kem/build.info | 8 + providers/implementations/kem/ec_kem.c | 814 + providers/implementations/kem/eckem.h | 13 + providers/implementations/kem/ecx_kem.c | 704 + providers/implementations/kem/kem_util.c | 37 + providers/implementations/kem/rsa_kem.c | 4 +- providers/implementations/keymgmt/build.info | 6 +- providers/implementations/keymgmt/dh_kmgmt.c | 14 +- providers/implementations/keymgmt/dsa_kmgmt.c | 9 +- providers/implementations/keymgmt/ec_kmgmt.c | 28 +- providers/implementations/keymgmt/ecx_kmgmt.c | 88 +- .../keymgmt/kdf_legacy_kmgmt.c | 14 +- .../keymgmt/mac_legacy_kmgmt.c | 28 +- providers/implementations/keymgmt/rsa_kmgmt.c | 4 +- .../implementations/macs/blake2_mac_impl.c | 4 +- providers/implementations/macs/cmac_prov.c | 4 +- providers/implementations/macs/gmac_prov.c | 4 +- providers/implementations/macs/hmac_prov.c | 17 +- providers/implementations/macs/kmac_prov.c | 8 +- .../implementations/macs/poly1305_prov.c | 4 +- providers/implementations/macs/siphash_prov.c | 4 +- providers/implementations/rands/drbg.c | 149 +- providers/implementations/rands/drbg_ctr.c | 106 +- providers/implementations/rands/drbg_hash.c | 96 +- providers/implementations/rands/drbg_hmac.c | 152 +- providers/implementations/rands/drbg_local.h | 8 +- providers/implementations/rands/seed_src.c | 8 +- .../rands/seeding/rand_cpu_arm64.c | 2 +- .../implementations/rands/seeding/rand_unix.c | 18 +- .../implementations/rands/seeding/rand_vms.c | 2 +- .../rands/seeding/rand_vxworks.c | 4 +- .../implementations/rands/seeding/rand_win.c | 2 +- providers/implementations/rands/test_rng.c | 2 +- .../implementations/signature/build.info | 5 +- providers/implementations/signature/dsa_sig.c | 22 +- .../implementations/signature/ecdsa_sig.c | 28 +- .../implementations/signature/eddsa_sig.c | 323 +- .../signature/mac_legacy_sig.c | 8 +- providers/implementations/signature/rsa_sig.c | 19 +- providers/implementations/signature/sm2_sig.c | 5 +- .../implementations/storemgmt/build.info | 3 + .../implementations/storemgmt/file_store.c | 36 +- .../storemgmt/file_store_any2obj.c | 12 +- .../storemgmt/winstore_store.c | 329 + providers/legacyprov.c | 107 +- providers/nullprov.c | 4 +- providers/stores.inc | 3 + ssl/bio_ssl.c | 62 +- ssl/build.info | 46 +- ssl/d1_lib.c | 404 +- ssl/d1_msg.c | 36 +- ssl/d1_srtp.c | 60 +- ssl/event_queue.c | 196 + ssl/ktls.c | 247 - ssl/pqueue.c | 7 +- ssl/priority_queue.c | 376 + ssl/quic/build.info | 16 + ssl/quic/cc_newreno.c | 485 + ssl/quic/quic_ackm.c | 1725 ++ ssl/quic/quic_cfq.c | 363 + ssl/quic/quic_channel.c | 3803 ++++ ssl/quic/quic_channel_local.h | 477 + ssl/quic/quic_demux.c | 677 + ssl/quic/quic_fc.c | 406 + ssl/quic/quic_fifd.c | 290 + ssl/quic/quic_impl.c | 3657 ++++ ssl/quic/quic_local.h | 338 + ssl/quic/quic_method.c | 22 + ssl/quic/quic_reactor.c | 386 + ssl/quic/quic_record_rx.c | 1375 ++ ssl/quic/quic_record_shared.c | 489 + ssl/quic/quic_record_shared.h | 150 + ssl/quic/quic_record_tx.c | 1061 + ssl/quic/quic_record_util.c | 277 + ssl/quic/quic_rstream.c | 295 + ssl/quic/quic_rx_depack.c | 1467 ++ ssl/quic/quic_sf_list.c | 334 + ssl/quic/quic_sstream.c | 424 + ssl/quic/quic_statm.c | 76 + ssl/quic/quic_stream_map.c | 848 + ssl/quic/quic_thread_assist.c | 157 + ssl/quic/quic_tls.c | 879 + ssl/quic/quic_trace.c | 641 + ssl/quic/quic_tserver.c | 566 + ssl/quic/quic_txp.c | 3134 +++ ssl/quic/quic_txpim.c | 229 + ssl/quic/quic_wire.c | 1078 + ssl/quic/quic_wire_pkt.c | 945 + ssl/quic/uint_set.c | 332 + ssl/record/README.md | 73 - ssl/record/build.info | 17 + ssl/record/dtls1_bitmap.c | 78 - ssl/record/methods/build.info | 23 + ssl/record/methods/dtls_meth.c | 802 + ssl/record/methods/ktls_meth.c | 611 + ssl/record/methods/recmethod_local.h | 539 + ssl/{s3_cbc.c => record/methods/ssl3_cbc.c} | 77 +- ssl/record/methods/ssl3_meth.c | 327 + ssl/record/methods/tls13_meth.c | 325 + ssl/record/methods/tls1_meth.c | 688 + ssl/record/methods/tls_common.c | 2152 ++ ssl/record/methods/tls_multib.c | 187 + ssl/record/{ => methods}/tls_pad.c | 21 +- ssl/record/methods/tlsany_meth.c | 197 + ssl/record/rec_layer_d1.c | 804 +- ssl/record/rec_layer_s3.c | 1910 +- ssl/record/record.h | 262 +- ssl/record/record_local.h | 106 - ssl/record/ssl3_buffer.c | 195 - ssl/record/ssl3_record.c | 1933 -- ssl/record/ssl3_record_tls13.c | 193 - ssl/s3_enc.c | 205 +- ssl/s3_lib.c | 586 +- ssl/s3_msg.c | 93 +- ssl/ssl_asn1.c | 53 +- ssl/ssl_cert.c | 334 +- ssl/ssl_cert_comp.c | 465 + ssl/ssl_cert_table.h | 4 +- ssl/ssl_ciph.c | 111 +- ssl/ssl_conf.c | 79 +- ssl/ssl_err.c | 62 +- ssl/ssl_init.c | 6 +- ssl/ssl_lib.c | 3413 +++- ssl/ssl_local.h | 970 +- ssl/ssl_rsa.c | 138 +- ssl/ssl_sess.c | 269 +- ssl/ssl_stat.c | 24 +- ssl/ssl_txt.c | 10 +- ssl/ssl_utst.c | 1 - ssl/sslerr.h | 2 +- ssl/statem/extensions.c | 437 +- ssl/statem/extensions_clnt.c | 308 +- ssl/statem/extensions_cust.c | 85 +- ssl/statem/extensions_srvr.c | 427 +- ssl/statem/statem.c | 209 +- ssl/statem/statem_clnt.c | 916 +- ssl/statem/statem_dtls.c | 234 +- ssl/statem/statem_lib.c | 900 +- ssl/statem/statem_local.h | 530 +- ssl/statem/statem_srvr.c | 825 +- ssl/t1_enc.c | 446 +- ssl/t1_lib.c | 932 +- ssl/t1_trce.c | 269 +- ssl/tls13_enc.c | 296 +- ssl/tls_depr.c | 10 +- ssl/tls_srp.c | 192 +- 1070 files changed, 132050 insertions(+), 27138 deletions(-) create mode 100644 apps/include/log.h create mode 100644 apps/lib/apps_opt_printf.c create mode 100644 apps/lib/log.c create mode 100644 crypto/bio/bss_dgram_pair.c create mode 100644 crypto/bn/bn_s390x.c create mode 100644 crypto/chacha/asm/chacha-loongarch64.pl create mode 100644 crypto/cmp/cmp_genm.c create mode 100644 crypto/comp/c_brotli.c create mode 100644 crypto/comp/c_zstd.c create mode 100644 crypto/deterministic_nonce.c create mode 100755 crypto/ec/asm/ecp_nistp384-ppc64.pl create mode 100644 crypto/ec/asm/ecp_sm2p256-armv8.S create mode 100644 crypto/ec/asm/ecp_sm2p256-armv8.pl create mode 100644 crypto/ec/ecp_nistp384.c create mode 100644 crypto/ec/ecp_sm2p256.c create mode 100644 crypto/ec/ecp_sm2p256_table.c create mode 100644 crypto/err/err_mark.c create mode 100644 crypto/err/err_save.c create mode 100644 crypto/hpke/build.info create mode 100644 crypto/hpke/hpke.c create mode 100644 crypto/hpke/hpke_util.c create mode 100644 crypto/modes/xts128gb.c create mode 100644 crypto/params_idx.c create mode 100644 crypto/params_idx.c.in create mode 100644 crypto/perlasm/riscv.pm create mode 100644 crypto/quic_vlint.c create mode 100644 crypto/rand/rand_uniform.c create mode 100644 crypto/sleep.c create mode 100644 crypto/sm4/asm/vpsm4_ex-armv8.S create mode 100644 crypto/sm4/asm/vpsm4_ex-armv8.pl create mode 100644 crypto/thread/api.c create mode 100644 crypto/thread/arch.c create mode 100644 crypto/thread/arch/thread_none.c create mode 100644 crypto/thread/arch/thread_posix.c create mode 100644 crypto/thread/arch/thread_win.c create mode 100644 crypto/thread/build.info create mode 100644 crypto/thread/internal.c create mode 100644 crypto/time.c create mode 100644 crypto/x509/v3_group_ac.c create mode 100644 crypto/x509/v3_ind_iss.c create mode 100644 crypto/x509/v3_no_ass.c create mode 100644 crypto/x509/v3_no_rev_avail.c create mode 100644 crypto/x509/v3_single_use.c create mode 100644 crypto/x509/v3_soa_id.c create mode 100644 include/internal/bio_addr.h create mode 100644 include/internal/bio_tfo.h create mode 100644 include/internal/common.h create mode 100644 include/internal/deterministic_nonce.h create mode 100644 include/internal/event_queue.h create mode 100644 include/internal/hpke_util.h create mode 100644 include/internal/list.h create mode 100644 include/internal/packet_quic.h create mode 100644 include/internal/param_names.h create mode 100644 include/internal/param_names.h.in create mode 100644 include/internal/params.h create mode 100644 include/internal/priority_queue.h create mode 100644 include/internal/quic_ackm.h create mode 100644 include/internal/quic_cc.h create mode 100644 include/internal/quic_cfq.h create mode 100644 include/internal/quic_channel.h create mode 100644 include/internal/quic_demux.h create mode 100644 include/internal/quic_error.h create mode 100644 include/internal/quic_fc.h create mode 100644 include/internal/quic_fifd.h create mode 100644 include/internal/quic_reactor.h create mode 100644 include/internal/quic_record_rx.h create mode 100644 include/internal/quic_record_tx.h create mode 100644 include/internal/quic_record_util.h create mode 100644 include/internal/quic_rx_depack.h create mode 100644 include/internal/quic_sf_list.h create mode 100644 include/internal/quic_ssl.h create mode 100644 include/internal/quic_statm.h create mode 100644 include/internal/quic_stream.h create mode 100644 include/internal/quic_stream_map.h create mode 100644 include/internal/quic_thread_assist.h create mode 100644 include/internal/quic_tls.h create mode 100644 include/internal/quic_tserver.h create mode 100644 include/internal/quic_txp.h create mode 100644 include/internal/quic_txpim.h create mode 100644 include/internal/quic_types.h create mode 100644 include/internal/quic_vlint.h create mode 100644 include/internal/quic_wire.h create mode 100644 include/internal/quic_wire_pkt.h create mode 100644 include/internal/recordmethod.h create mode 100644 include/internal/ring_buf.h create mode 100644 include/internal/safe_math.h create mode 100644 include/internal/ssl.h create mode 100644 include/internal/ssl3_cbc.h rename {ssl/statem => include/internal}/statem.h (67%) create mode 100644 include/internal/thread.h create mode 100644 include/internal/thread_arch.h create mode 100644 include/internal/time.h create mode 100644 include/internal/uint_set.h create mode 100644 include/openssl/core_names.h.in create mode 100644 include/openssl/e_ostime.h create mode 100644 include/openssl/hpke.h create mode 100644 include/openssl/quic.h create mode 100644 include/openssl/thread.h rename providers/implementations/ciphers/{cipher_aes_ccm_hw_rv32i_zknd_zkne.inc => cipher_aes_ccm_hw_rv32i.inc} (91%) rename providers/implementations/ciphers/{cipher_aes_ccm_hw_rv64i_zknd_zkne.inc => cipher_aes_ccm_hw_rv64i.inc} (87%) rename providers/implementations/ciphers/{cipher_aes_gcm_hw_rv32i_zknd_zkne.inc => cipher_aes_gcm_hw_rv32i.inc} (91%) rename providers/implementations/ciphers/{cipher_aes_gcm_hw_rv64i_zknd_zkne.inc => cipher_aes_gcm_hw_rv64i.inc} (90%) create mode 100644 providers/implementations/ciphers/cipher_aes_gcm_siv.c create mode 100644 providers/implementations/ciphers/cipher_aes_gcm_siv.h create mode 100644 providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c create mode 100644 providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c rename providers/implementations/ciphers/{cipher_aes_hw_rv32i_zknd_zkne.inc => cipher_aes_hw_rv32i.inc} (95%) rename providers/implementations/ciphers/{cipher_aes_hw_rv64i_zknd_zkne.inc => cipher_aes_hw_rv64i.inc} (94%) create mode 100644 providers/implementations/ciphers/cipher_sm4_xts.c create mode 100644 providers/implementations/ciphers/cipher_sm4_xts.h create mode 100644 providers/implementations/ciphers/cipher_sm4_xts_hw.c create mode 100644 providers/implementations/include/prov/ecx.h create mode 100644 providers/implementations/include/prov/hmac_drbg.h create mode 100644 providers/implementations/kdfs/argon2.c create mode 100644 providers/implementations/kdfs/hmacdrbg_kdf.c create mode 100644 providers/implementations/kdfs/pvkkdf.c create mode 100644 providers/implementations/kem/ec_kem.c create mode 100644 providers/implementations/kem/eckem.h create mode 100644 providers/implementations/kem/ecx_kem.c create mode 100644 providers/implementations/kem/kem_util.c create mode 100644 providers/implementations/storemgmt/winstore_store.c create mode 100644 ssl/event_queue.c delete mode 100644 ssl/ktls.c create mode 100644 ssl/priority_queue.c create mode 100644 ssl/quic/build.info create mode 100644 ssl/quic/cc_newreno.c create mode 100644 ssl/quic/quic_ackm.c create mode 100644 ssl/quic/quic_cfq.c create mode 100644 ssl/quic/quic_channel.c create mode 100644 ssl/quic/quic_channel_local.h create mode 100644 ssl/quic/quic_demux.c create mode 100644 ssl/quic/quic_fc.c create mode 100644 ssl/quic/quic_fifd.c create mode 100644 ssl/quic/quic_impl.c create mode 100644 ssl/quic/quic_local.h create mode 100644 ssl/quic/quic_method.c create mode 100644 ssl/quic/quic_reactor.c create mode 100644 ssl/quic/quic_record_rx.c create mode 100644 ssl/quic/quic_record_shared.c create mode 100644 ssl/quic/quic_record_shared.h create mode 100644 ssl/quic/quic_record_tx.c create mode 100644 ssl/quic/quic_record_util.c create mode 100644 ssl/quic/quic_rstream.c create mode 100644 ssl/quic/quic_rx_depack.c create mode 100644 ssl/quic/quic_sf_list.c create mode 100644 ssl/quic/quic_sstream.c create mode 100644 ssl/quic/quic_statm.c create mode 100644 ssl/quic/quic_stream_map.c create mode 100644 ssl/quic/quic_thread_assist.c create mode 100644 ssl/quic/quic_tls.c create mode 100644 ssl/quic/quic_trace.c create mode 100644 ssl/quic/quic_tserver.c create mode 100644 ssl/quic/quic_txp.c create mode 100644 ssl/quic/quic_txpim.c create mode 100644 ssl/quic/quic_wire.c create mode 100644 ssl/quic/quic_wire_pkt.c create mode 100644 ssl/quic/uint_set.c delete mode 100644 ssl/record/README.md create mode 100644 ssl/record/build.info delete mode 100644 ssl/record/dtls1_bitmap.c create mode 100644 ssl/record/methods/build.info create mode 100644 ssl/record/methods/dtls_meth.c create mode 100644 ssl/record/methods/ktls_meth.c create mode 100644 ssl/record/methods/recmethod_local.h rename ssl/{s3_cbc.c => record/methods/ssl3_cbc.c} (86%) create mode 100644 ssl/record/methods/ssl3_meth.c create mode 100644 ssl/record/methods/tls13_meth.c create mode 100644 ssl/record/methods/tls1_meth.c create mode 100644 ssl/record/methods/tls_common.c create mode 100644 ssl/record/methods/tls_multib.c rename ssl/record/{ => methods}/tls_pad.c (92%) create mode 100644 ssl/record/methods/tlsany_meth.c delete mode 100644 ssl/record/ssl3_buffer.c delete mode 100644 ssl/record/ssl3_record.c delete mode 100644 ssl/record/ssl3_record_tls13.c create mode 100644 ssl/ssl_cert_comp.c diff --git a/Crypto-config-host.mk b/Crypto-config-host.mk index f468f334ea..46d181fdec 100644 --- a/Crypto-config-host.mk +++ b/Crypto-config-host.mk @@ -613,6 +613,7 @@ arm64_clang_asflags := \ arm64_cflags := \ -DBSAES_ASM \ -DECP_NISTZ256_ASM \ + -DECP_SM2P256_ASM \ -DKECCAK1600_ASM \ -DMD5_ASM \ -DOPENSSL_BN_ASM_MONT \ diff --git a/Crypto-config-target.mk b/Crypto-config-target.mk index 495f89c4c5..f234b74ea3 100644 --- a/Crypto-config-target.mk +++ b/Crypto-config-target.mk @@ -613,6 +613,7 @@ arm64_clang_asflags := \ arm64_cflags := \ -DBSAES_ASM \ -DECP_NISTZ256_ASM \ + -DECP_SM2P256_ASM \ -DKECCAK1600_ASM \ -DMD5_ASM \ -DOPENSSL_BN_ASM_MONT \ diff --git a/apps/CA.pl.in b/apps/CA.pl.in index f029470005..2c31ee6c8d 100644 --- a/apps/CA.pl.in +++ b/apps/CA.pl.in @@ -36,6 +36,8 @@ my $CACERT = "cacert.pem"; my $CACRL = "crl.pem"; my $DAYS = "-days 365"; my $CADAYS = "-days 1095"; # 3 years +my $EXTENSIONS = "-extensions v3_ca"; +my $POLICY = "-policy policy_anything"; my $NEWKEY = "newkey.pem"; my $NEWREQ = "newreq.pem"; my $NEWCERT = "newcert.pem"; @@ -179,7 +181,7 @@ if ($WHAT eq '-newcert' ) { $RET = run("$CA -create_serial" . " -out ${CATOP}/$CACERT $CADAYS -batch" . " -keyfile ${CATOP}/private/$CAKEY -selfsign" - . " -extensions v3_ca" + . " $EXTENSIONS" . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0; print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0; } @@ -191,19 +193,19 @@ if ($WHAT eq '-newcert' ) { . " -export -name \"$cname\" $EXTRA{pkcs12}"); print "PKCS #12 file is in $NEWP12\n" if $RET == 0; } elsif ($WHAT eq '-xsign' ) { - $RET = run("$CA -policy policy_anything -infiles $NEWREQ $EXTRA{ca}"); + $RET = run("$CA $POLICY -infiles $NEWREQ $EXTRA{ca}"); } elsif ($WHAT eq '-sign' ) { - $RET = run("$CA -policy policy_anything -out $NEWCERT" + $RET = run("$CA $POLICY -out $NEWCERT" . " -infiles $NEWREQ $EXTRA{ca}"); print "Signed certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-signCA' ) { - $RET = run("$CA -policy policy_anything -out $NEWCERT" - . " -extensions v3_ca -infiles $NEWREQ $EXTRA{ca}"); + $RET = run("$CA $POLICY -out $NEWCERT" + . " $EXTENSIONS -infiles $NEWREQ $EXTRA{ca}"); print "Signed CA certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-signcert' ) { $RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ" . " -out tmp.pem $EXTRA{x509}"); - $RET = run("$CA -policy policy_anything -out $NEWCERT" + $RET = run("$CA $POLICY -out $NEWCERT" . "-infiles tmp.pem $EXTRA{ca}") if $RET == 0; print "Signed certificate is in $NEWCERT\n" if $RET == 0; } elsif ($WHAT eq '-verify' ) { diff --git a/apps/asn1parse.c b/apps/asn1parse.c index f0bfd1d45f..097b0cc1ed 100644 --- a/apps/asn1parse.c +++ b/apps/asn1parse.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,7 +32,7 @@ const OPTIONS asn1parse_options[] = { {"oid", OPT_OID, '<', "file of extra oid definitions"}, OPT_SECTION("I/O"), - {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"}, + {"inform", OPT_INFORM, 'A', "input format - one of DER PEM B64"}, {"in", OPT_IN, '<', "input file"}, {"out", OPT_OUT, '>', "output file (output format is always DER)"}, {"noout", OPT_NOOUT, 0, "do not produce any output"}, @@ -44,7 +44,7 @@ const OPTIONS asn1parse_options[] = { {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, {"strictpem", OPT_STRICTPEM, 0, - "do not attempt base64 decode outside PEM markers"}, + "equivalent to '-inform pem' (obsolete)"}, {"item", OPT_ITEM, 's', "item to parse and print"}, {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, @@ -69,7 +69,7 @@ int asn1parse_main(int argc, char **argv) unsigned char *str = NULL; char *name = NULL, *header = NULL, *prog; const unsigned char *ctmpbuf; - int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM; + int indent = 0, noout = 0, dump = 0, informat = FORMAT_PEM; int offset = 0, ret = 1, i, j; long num, tmplen; unsigned char *tmpbuf; @@ -96,7 +96,7 @@ int asn1parse_main(int argc, char **argv) ret = 0; goto end; case OPT_INFORM: - if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + if (!opt_format(opt_arg(), OPT_FMT_ASN1, &informat)) goto opthelp; break; case OPT_IN: @@ -136,7 +136,7 @@ int asn1parse_main(int argc, char **argv) genconf = opt_arg(); break; case OPT_STRICTPEM: - strictpem = 1; + /* accepted for backward compatibility */ informat = FORMAT_PEM; break; case OPT_ITEM: @@ -159,8 +159,7 @@ int asn1parse_main(int argc, char **argv) } /* No extra args. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (oidfile != NULL) { @@ -179,7 +178,7 @@ int asn1parse_main(int argc, char **argv) if ((buf = BUF_MEM_new()) == NULL) goto end; - if (strictpem) { + if (informat == FORMAT_PEM) { if (PEM_read_bio(in, &name, &header, &str, &num) != 1) { BIO_printf(bio_err, "Error reading PEM file\n"); ERR_print_errors(bio_err); @@ -199,7 +198,7 @@ int asn1parse_main(int argc, char **argv) } } else { - if (informat == FORMAT_PEM) { + if (informat == FORMAT_BASE64) { BIO *tmp; if ((b64 = BIO_new(BIO_f_base64())) == NULL) diff --git a/apps/ca.c b/apps/ca.c index a7a5ab1ece..e12a8c2370 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -129,7 +129,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, CONF *conf, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, int selfsign, unsigned long dateopt); static int get_certificate_status(const char *ser_status, CA_DB *db); -static int do_updatedb(CA_DB *db); static int check_time_format(const char *str); static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type, const char *extval); @@ -154,7 +153,7 @@ typedef enum OPTION_choice { OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, - OPT_RAND_SERIAL, + OPT_RAND_SERIAL, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM, /* Do not change the order here; see related case statements below */ OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE @@ -166,9 +165,11 @@ const OPTIONS ca_options[] = { OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"}, + {"quiet", OPT_QUIET, '-', "Terse output during processing"}, {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, {"in", OPT_IN, '<', "The input cert request(s)"}, - {"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"}, + {"inform", OPT_INFORM, 'F', + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, {"out", OPT_OUT, '>', "Where to put the output file(s)"}, {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, @@ -332,6 +333,9 @@ int ca_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_QUIET: + verbose = 0; + break; case OPT_CONFIG: configfile = opt_arg(); break; @@ -510,9 +514,7 @@ int ca_main(int argc, char **argv) && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL) goto end; - p = NCONF_get_string(conf, NULL, "oid_file"); - if (p == NULL) - ERR_clear_error(); + p = app_conf_try_string(conf, NULL, "oid_file"); if (p != NULL) { BIO *oid_bio = BIO_new_file(p, "r"); @@ -530,29 +532,22 @@ int ca_main(int argc, char **argv) if (!app_RAND_load()) goto end; - f = NCONF_get_string(conf, section, STRING_MASK); - if (f == NULL) - ERR_clear_error(); - + f = app_conf_try_string(conf, section, STRING_MASK); if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) { BIO_printf(bio_err, "Invalid global string mask setting %s\n", f); goto end; } if (chtype != MBSTRING_UTF8) { - f = NCONF_get_string(conf, section, UTF8_IN); - if (f == NULL) - ERR_clear_error(); - else if (strcmp(f, "yes") == 0) + f = app_conf_try_string(conf, section, UTF8_IN); + if (f != NULL && strcmp(f, "yes") == 0) chtype = MBSTRING_UTF8; } db_attr.unique_subject = 1; - p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT); + p = app_conf_try_string(conf, section, ENV_UNIQUE_SUBJECT); if (p != NULL) db_attr.unique_subject = parse_yesno(p, 1); - else - ERR_clear_error(); /*****************************************************************/ /* report status of cert with serial number given on command line */ @@ -615,21 +610,14 @@ int ca_main(int argc, char **argv) if (!selfsign) x509p = x509; - f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE); - if (f == NULL) - ERR_clear_error(); - if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) + f = app_conf_try_string(conf, BASE_SECTION, ENV_PRESERVE); + if (f != NULL && (*f == 'y' || *f == 'Y')) preserve = 1; - f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK); - if (f == NULL) - ERR_clear_error(); - if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) + f = app_conf_try_string(conf, BASE_SECTION, ENV_MSIE_HACK); + if (f != NULL && (*f == 'y' || *f == 'Y')) msie_hack = 1; - f = NCONF_get_string(conf, section, ENV_NAMEOPT); - - if (f == NULL) - ERR_clear_error(); + f = app_conf_try_string(conf, section, ENV_NAMEOPT); if (f != NULL) { if (!set_nameopt(f)) { BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f); @@ -638,27 +626,21 @@ int ca_main(int argc, char **argv) default_op = 0; } - f = NCONF_get_string(conf, section, ENV_CERTOPT); - + f = app_conf_try_string(conf, section, ENV_CERTOPT); if (f != NULL) { if (!set_cert_ex(&certopt, f)) { BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f); goto end; } default_op = 0; - } else { - ERR_clear_error(); } - f = NCONF_get_string(conf, section, ENV_EXTCOPY); - + f = app_conf_try_string(conf, section, ENV_EXTCOPY); if (f != NULL) { if (!set_ext_copy(&ext_copy, f)) { BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f); goto end; } - } else { - ERR_clear_error(); } /*****************************************************************/ @@ -753,7 +735,7 @@ int ca_main(int argc, char **argv) if (verbose) BIO_printf(bio_err, "Updating %s ...\n", dbfile); - i = do_updatedb(db); + i = do_updatedb(db, NULL); if (i == -1) { BIO_printf(bio_err, "Malloc failure\n"); goto end; @@ -786,11 +768,10 @@ int ca_main(int argc, char **argv) /* We can have sections in the ext file */ if (extensions == NULL) { - extensions = NCONF_get_string(extfile_conf, "default", "extensions"); - if (extensions == NULL) { - ERR_clear_error(); + extensions = + app_conf_try_string(extfile_conf, "default", "extensions"); + if (extensions == NULL) extensions = "default"; - } } } @@ -832,9 +813,8 @@ int ca_main(int argc, char **argv) if (email_dn == 1) { char *tmp_email_dn = NULL; - tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN); - if (tmp_email_dn == NULL) - ERR_clear_error(); + tmp_email_dn = + app_conf_try_string(conf, section, ENV_DEFAULT_EMAIL_DN); if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0) email_dn = 0; } @@ -847,10 +827,9 @@ int ca_main(int argc, char **argv) if (verbose) BIO_printf(bio_err, "policy is %s\n", policy); - if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) { + if (app_conf_try_string(conf, section, ENV_RAND_SERIAL) != NULL) { rand_ser = 1; } else { - ERR_clear_error(); serialfile = lookup_conf(conf, section, ENV_SERIAL); if (serialfile == NULL) goto end; @@ -874,11 +853,8 @@ int ca_main(int argc, char **argv) * no '-extfile' option, so we look for extensions in the main * configuration file */ - if (extensions == NULL) { - extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS); - if (extensions == NULL) - ERR_clear_error(); - } + if (extensions == NULL) + extensions = app_conf_try_string(conf, section, ENV_EXTENSIONS); if (extensions != NULL) { /* Check syntax of config file section */ X509V3_CTX ctx; @@ -895,11 +871,9 @@ int ca_main(int argc, char **argv) } } - if (startdate == NULL) { - startdate = NCONF_get_string(conf, section, ENV_DEFAULT_STARTDATE); - if (startdate == NULL) - ERR_clear_error(); - } + if (startdate == NULL) + startdate = + app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE); if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) { BIO_printf(bio_err, "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); @@ -908,11 +882,8 @@ int ca_main(int argc, char **argv) if (startdate == NULL) startdate = "today"; - if (enddate == NULL) { - enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE); - if (enddate == NULL) - ERR_clear_error(); - } + if (enddate == NULL) + enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE); if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) { BIO_printf(bio_err, "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); @@ -920,10 +891,8 @@ int ca_main(int argc, char **argv) } if (days == 0) { - if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days)) { - ERR_clear_error(); + if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days)) days = 0; - } } if (enddate == NULL && days == 0) { BIO_printf(bio_err, "cannot lookup how many days to certify for\n"); @@ -1156,11 +1125,9 @@ int ca_main(int argc, char **argv) /*****************************************************************/ if (gencrl) { int crl_v2 = 0; - if (crl_ext == NULL) { - crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT); - if (crl_ext == NULL) - ERR_clear_error(); - } + + if (crl_ext == NULL) + crl_ext = app_conf_try_string(conf, section, ENV_CRLEXT); if (crl_ext != NULL) { /* Check syntax of file */ X509V3_CTX ctx; @@ -1175,28 +1142,22 @@ int ca_main(int argc, char **argv) } } - crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER); + crlnumberfile = app_conf_try_string(conf, section, ENV_CRLNUMBER); if (crlnumberfile != NULL) { if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL)) == NULL) { BIO_printf(bio_err, "error while loading CRL number\n"); goto end; } - } else { - ERR_clear_error(); } if (!crldays && !crlhours && !crlsec) { - if (!NCONF_get_number(conf, section, - ENV_DEFAULT_CRL_DAYS, &crldays)) { - ERR_clear_error(); + if (!app_conf_try_number(conf, section, + ENV_DEFAULT_CRL_DAYS, &crldays)) crldays = 0; - } - if (!NCONF_get_number(conf, section, - ENV_DEFAULT_CRL_HOURS, &crlhours)) { - ERR_clear_error(); + if (!app_conf_try_number(conf, section, + ENV_DEFAULT_CRL_HOURS, &crlhours)) crlhours = 0; - } } if ((crl_nextupdate == NULL) && (crldays == 0) && (crlhours == 0) && (crlsec == 0)) { @@ -1347,7 +1308,7 @@ int ca_main(int argc, char **argv) BIO_free_all(Sout); BIO_free_all(out); BIO_free_all(in); - sk_X509_pop_free(cert_sk, X509_free); + OSSL_STACK_OF_X509_free(cert_sk); cleanse(passin); if (free_passin) @@ -1391,7 +1352,7 @@ static int certify(X509 **xret, const char *infile, int informat, EVP_PKEY *pktmp = NULL; int ok = -1, i; - req = load_csr(infile, informat, "certificate request"); + req = load_csr_autofmt(infile, informat, vfyopts, "certificate request"); if (req == NULL) goto end; if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) { @@ -1731,7 +1692,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* Initialize the context structure */ X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509, - ret, req, NULL, X509V3_CTX_REPLACE); + ret, NULL /* no need to give req, needed info is in ret */, + NULL, X509V3_CTX_REPLACE); + /* prepare fallback for AKID, but only if issuer cert equals subject cert */ + if (selfsign) { + if (!X509V3_set_issuer_pkey(&ext_ctx, pkey)) + goto end; + if (!cert_matches_key(ret, pkey)) + BIO_printf(bio_err, + "Warning: Signature key and public key of cert do not match\n"); + } /* Lets add the extensions, if there are any */ if (ext_sect) { @@ -1868,7 +1838,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, p = "Valid"; else p = "\ninvalid type, Database error\n"; - BIO_printf(bio_err, "Type :%s\n", p);; + BIO_printf(bio_err, "Type :%s\n", p); if (rrow[DB_type][0] == DB_TYPE_REV) { p = rrow[DB_exp_date]; if (p == NULL) @@ -1933,7 +1903,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, !EVP_PKEY_missing_parameters(pkey)) EVP_PKEY_copy_parameters(pktmp, pkey); - if (!do_X509_sign(ret, pkey, dgst, sigopts, &ext_ctx)) + if (!do_X509_sign(ret, 0, pkey, dgst, sigopts, &ext_ctx)) goto end; /* We now just add it to the database as DB_TYPE_VAL('V') */ @@ -2299,7 +2269,7 @@ static int get_certificate_status(const char *serial, CA_DB *db) return ok; } -static int do_updatedb(CA_DB *db) +int do_updatedb(CA_DB *db, time_t *now) { ASN1_TIME *a_tm = NULL; int i, cnt = 0; @@ -2310,7 +2280,7 @@ static int do_updatedb(CA_DB *db) return -1; /* get actual time */ - if (X509_gmtime_adj(a_tm, 0) == NULL) { + if (X509_time_adj(a_tm, 0, now) == NULL) { ASN1_TIME_free(a_tm); return -1; } diff --git a/apps/ciphers.c b/apps/ciphers.c index 42a0bb79f6..c33685d8ce 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -174,10 +174,9 @@ int ciphers_main(int argc, char **argv) /* Optional arg is cipher name. */ argv = opt_rest(); - argc = opt_num_rest(); - if (argc == 1) + if (opt_num_rest() == 1) ciphers = argv[0]; - else if (argc != 0) + else if (!opt_check_rest_arg(NULL)) goto opthelp; if (convert != NULL) { diff --git a/apps/cmp.c b/apps/cmp.c index ffcd86dba8..dd5a69af7c 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -68,7 +68,7 @@ typedef enum { } cmp_cmd_t; /* message transfer */ -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) static char *opt_server = NULL; static char *opt_proxy = NULL; static char *opt_no_proxy = NULL; @@ -86,8 +86,13 @@ static char *opt_srvcert = NULL; static char *opt_expect_sender = NULL; static int opt_ignore_keyusage = 0; static int opt_unprotected_errors = 0; +static char *opt_srvcertout = NULL; static char *opt_extracertsout = NULL; static char *opt_cacertsout = NULL; +static char *opt_oldwithold = NULL; +static char *opt_newwithnew = NULL; +static char *opt_newwithold = NULL; +static char *opt_oldwithnew = NULL; /* client authentication */ static char *opt_ref = NULL; @@ -112,7 +117,6 @@ static int opt_infotype = NID_undef; static char *opt_newkey = NULL; static char *opt_newkeypass = NULL; static char *opt_subject = NULL; -static char *opt_issuer = NULL; static int opt_days = 0; static char *opt_reqexts = NULL; static char *opt_sans = NULL; @@ -130,6 +134,8 @@ static char *opt_chainout = NULL; /* certificate enrollment and revocation */ static char *opt_oldcert = NULL; +static char *opt_issuer = NULL; +static char *opt_serial = NULL; static int opt_revreason = CRL_REASON_NONE; /* credentials format */ @@ -140,7 +146,7 @@ static int opt_keyform = FORMAT_UNDEF; static char *opt_otherpass = NULL; static char *opt_engine = NULL; -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) /* TLS connection */ static int opt_tls_used = 0; static char *opt_tls_cert = NULL; @@ -163,7 +169,7 @@ static char *opt_rspout = NULL; static int opt_use_mock_srv = 0; /* mock server */ -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) static char *opt_port = NULL; static int opt_max_msgs = 0; #endif @@ -175,9 +181,14 @@ static char *opt_srv_keypass = NULL; static char *opt_srv_trusted = NULL; static char *opt_srv_untrusted = NULL; +static char *opt_ref_cert = NULL; static char *opt_rsp_cert = NULL; static char *opt_rsp_extracerts = NULL; static char *opt_rsp_capubs = NULL; +static char *opt_rsp_newwithnew = NULL; +static char *opt_rsp_newwithold = NULL; +static char *opt_rsp_oldwithnew = NULL; + static int opt_poll_count = 0; static int opt_check_after = 1; static int opt_grant_implicitconf = 0; @@ -201,7 +212,7 @@ typedef enum OPTION_choice { OPT_CMD, OPT_INFOTYPE, OPT_GENINFO, - OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT, OPT_ISSUER, + OPT_NEWKEY, OPT_NEWKEYPASS, OPT_SUBJECT, OPT_DAYS, OPT_REQEXTS, OPT_SANS, OPT_SAN_NODEFAULT, OPT_POLICIES, OPT_POLICY_OIDS, OPT_POLICY_OIDS_CRITICAL, @@ -209,9 +220,9 @@ typedef enum OPTION_choice { OPT_OUT_TRUSTED, OPT_IMPLICIT_CONFIRM, OPT_DISABLE_CONFIRM, OPT_CERTOUT, OPT_CHAINOUT, - OPT_OLDCERT, OPT_REVREASON, + OPT_OLDCERT, OPT_ISSUER, OPT_SERIAL, OPT_REVREASON, -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) OPT_SERVER, OPT_PROXY, OPT_NO_PROXY, #endif OPT_RECIPIENT, OPT_PATH, @@ -220,7 +231,8 @@ typedef enum OPTION_choice { OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT, OPT_EXPECT_SENDER, OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, - OPT_EXTRACERTSOUT, OPT_CACERTSOUT, + OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, + OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, @@ -234,7 +246,7 @@ typedef enum OPTION_choice { OPT_PROV_ENUM, OPT_R_ENUM, -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) OPT_TLS_USED, OPT_TLS_CERT, OPT_TLS_KEY, OPT_TLS_KEYPASS, OPT_TLS_EXTRA, OPT_TLS_TRUSTED, OPT_TLS_HOST, @@ -244,13 +256,14 @@ typedef enum OPTION_choice { OPT_REQIN, OPT_REQIN_NEW_TID, OPT_REQOUT, OPT_RSPIN, OPT_RSPOUT, OPT_USE_MOCK_SRV, -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) OPT_PORT, OPT_MAX_MSGS, #endif OPT_SRV_REF, OPT_SRV_SECRET, OPT_SRV_CERT, OPT_SRV_KEY, OPT_SRV_KEYPASS, OPT_SRV_TRUSTED, OPT_SRV_UNTRUSTED, - OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS, + OPT_REF_CERT, OPT_RSP_CERT, OPT_RSP_EXTRACERTS, OPT_RSP_CAPUBS, + OPT_RSP_NEWWITHNEW, OPT_RSP_NEWWITHOLD, OPT_RSP_OLDWITHNEW, OPT_POLL_COUNT, OPT_CHECK_AFTER, OPT_GRANT_IMPLICITCONF, OPT_PKISTATUS, OPT_FAILURE, @@ -275,7 +288,9 @@ const OPTIONS cmp_options[] = { OPT_SECTION("Generic message"), {"cmd", OPT_CMD, 's', "CMP request to send: ir/cr/kur/p10cr/rr/genm"}, {"infotype", OPT_INFOTYPE, 's', - "InfoType name for requesting specific info in genm, e.g. 'signKeyPairTypes'"}, + "InfoType name for requesting specific info in genm, with specific support"}, + {OPT_MORE_STR, 0, 0, + "for 'caCerts' and 'rootCaCert'"}, {"geninfo", OPT_GENINFO, 's', "generalInfo integer values to place in request PKIHeader with given OID"}, {OPT_MORE_STR, 0, 0, @@ -291,10 +306,6 @@ const OPTIONS cmp_options[] = { "For kur, default is subject of -csr arg or reference cert (see -oldcert)"}, {OPT_MORE_STR, 0, 0, "this default is used for ir and cr only if no Subject Alt Names are set"}, - {"issuer", OPT_ISSUER, 's', - "DN of the issuer to place in the requested certificate template"}, - {OPT_MORE_STR, 0, 0, - "also used as recipient if neither -recipient nor -srvcert are given"}, {"days", OPT_DAYS, 'N', "Requested validity time of the new certificate in number of days"}, {"reqexts", OPT_REQEXTS, 's', @@ -338,15 +349,21 @@ const OPTIONS cmp_options[] = { "also used as reference (defaulting to -cert) for subject DN and SANs."}, {OPT_MORE_STR, 0, 0, "Issuer is used as recipient unless -recipient, -srvcert, or -issuer given"}, + {"issuer", OPT_ISSUER, 's', + "DN of the issuer to place in the certificate template of ir/cr/kur/rr;"}, + {OPT_MORE_STR, 0, 0, + "also used as recipient if neither -recipient nor -srvcert are given"}, + {"serial", OPT_SERIAL, 's', + "Serial number of certificate to be revoked in revocation request (rr)"}, {"revreason", OPT_REVREASON, 'n', "Reason code to include in revocation request (rr); possible values:"}, {OPT_MORE_STR, 0, 0, "0..6, 8..10 (see RFC5280, 5.3.1) or -1. Default -1 = none included"}, OPT_SECTION("Message transfer"), -#ifdef OPENSSL_NO_SOCK +#if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP) {OPT_MORE_STR, 0, 0, - "NOTE: -server, -proxy, and -no_proxy not supported due to no-sock build"}, + "NOTE: -server, -proxy, and -no_proxy not supported due to no-sock/no-http build"}, #else {"server", OPT_SERVER, 's', "[http[s]://]address[:port][/path] of CMP server. Default port 80 or 443."}, @@ -388,10 +405,20 @@ const OPTIONS cmp_options[] = { "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"}, {OPT_MORE_STR, 0, 0, "WARNING: This setting leads to behavior allowing violation of RFC 4210"}, + { "srvcertout", OPT_SRVCERTOUT, 's', + "File to save the server cert used and validated for CMP response protection"}, {"extracertsout", OPT_EXTRACERTSOUT, 's', "File to save extra certificates received in the extraCerts field"}, {"cacertsout", OPT_CACERTSOUT, 's', - "File to save CA certificates received in the caPubs field of 'ip' messages"}, + "File to save CA certs received in caPubs field or genp with id-it-caCerts"}, + { "oldwithold", OPT_OLDWITHOLD, 's', + "Root CA certificate to request update for in genm of type rootCaCert"}, + { "newwithnew", OPT_NEWWITHNEW, 's', + "File to save NewWithNew cert received in genp of type rootCaKeyUpdate"}, + { "newwithold", OPT_NEWWITHOLD, 's', + "File to save NewWithOld cert received in genp of type rootCaKeyUpdate"}, + { "oldwithnew", OPT_OLDWITHNEW, 's', + "File to save OldWithNew cert received in genp of type rootCaKeyUpdate"}, OPT_SECTION("Client authentication"), {"ref", OPT_REF, 's', @@ -437,9 +464,9 @@ const OPTIONS cmp_options[] = { OPT_R_OPTIONS, OPT_SECTION("TLS connection"), -#ifdef OPENSSL_NO_SOCK +#if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP) {OPT_MORE_STR, 0, 0, - "NOTE: -tls_used and all other TLS options not supported due to no-sock build"}, + "NOTE: -tls_used and all other TLS options not supported due to no-sock/no-http build"}, #else {"tls_used", OPT_TLS_USED, '-', "Enable using TLS (also when other TLS options are not set)"}, @@ -453,9 +480,9 @@ const OPTIONS cmp_options[] = { "Extra certificates to provide to TLS server during TLS handshake"}, {"tls_trusted", OPT_TLS_TRUSTED, 's', "Trusted certificates to use for verifying the TLS server certificate;"}, - {OPT_MORE_STR, 0, 0, "this implies host name validation"}, + {OPT_MORE_STR, 0, 0, "this implies hostname validation"}, {"tls_host", OPT_TLS_HOST, 's', - "Address to be checked (rather than -server) during TLS host name validation"}, + "Address to be checked (rather than -server) during TLS hostname validation"}, #endif OPT_SECTION("Client-side debugging"), @@ -478,9 +505,9 @@ const OPTIONS cmp_options[] = { "Use internal mock server at API level, bypassing socket-based HTTP"}, OPT_SECTION("Mock server"), -#ifdef OPENSSL_NO_SOCK +#if defined(OPENSSL_NO_SOCK) || defined(OPENSSL_NO_HTTP) {OPT_MORE_STR, 0, 0, - "NOTE: -port and -max_msgs not supported due to no-sock build"}, + "NOTE: -port and -max_msgs not supported due to no-sock/no-http build"}, #else {"port", OPT_PORT, 's', "Act as HTTP-based mock server listening on given port"}, @@ -502,12 +529,20 @@ const OPTIONS cmp_options[] = { "Trusted certificates for client authentication"}, {"srv_untrusted", OPT_SRV_UNTRUSTED, 's', "Intermediate certs that may be useful for verifying CMP protection"}, + {"ref_cert", OPT_RSP_CERT, 's', + "Certificate to be expected for rr and any oldCertID in kur messages"}, {"rsp_cert", OPT_RSP_CERT, 's', "Certificate to be returned as mock enrollment result"}, {"rsp_extracerts", OPT_RSP_EXTRACERTS, 's', "Extra certificates to be included in mock certification responses"}, {"rsp_capubs", OPT_RSP_CAPUBS, 's', "CA certificates to be included in mock ip response"}, + {"rsp_newwithnew", OPT_RSP_NEWWITHNEW, 's', + "New root CA certificate to include in genp of type rootCaKeyUpdate"}, + {"rsp_newwithold", OPT_RSP_NEWWITHOLD, 's', + "NewWithOld transition cert to include in genp of type rootCaKeyUpdate"}, + {"rsp_oldwithnew", OPT_RSP_OLDWITHNEW, 's', + "OldWithNew transition cert to include in genp of type rootCaKeyUpdate"}, {"poll_count", OPT_POLL_COUNT, 'N', "Number of times the client must poll before receiving a certificate"}, {"check_after", OPT_CHECK_AFTER, 'N', @@ -554,7 +589,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_cmd_s}, {&opt_infotype_s}, {&opt_geninfo}, - {&opt_newkey}, {&opt_newkeypass}, {&opt_subject}, {&opt_issuer}, + {&opt_newkey}, {&opt_newkeypass}, {&opt_subject}, {(char **)&opt_days}, {&opt_reqexts}, {&opt_sans}, {(char **)&opt_san_nodefault}, {&opt_policies}, {&opt_policy_oids}, {(char **)&opt_policy_oids_critical}, @@ -563,9 +598,9 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_implicit_confirm}, {(char **)&opt_disable_confirm}, {&opt_certout}, {&opt_chainout}, - {&opt_oldcert}, {(char **)&opt_revreason}, + {&opt_oldcert}, {&opt_issuer}, {&opt_serial}, {(char **)&opt_revreason}, -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) {&opt_server}, {&opt_proxy}, {&opt_no_proxy}, #endif {&opt_recipient}, {&opt_path}, {(char **)&opt_keep_alive}, @@ -574,7 +609,8 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert}, {&opt_expect_sender}, {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, - {&opt_extracertsout}, {&opt_cacertsout}, + {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, + {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, {&opt_ref}, {&opt_secret}, {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, @@ -587,7 +623,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_engine}, #endif -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) {(char **)&opt_tls_used}, {&opt_tls_cert}, {&opt_tls_key}, {&opt_tls_keypass}, {&opt_tls_extra}, {&opt_tls_trusted}, {&opt_tls_host}, @@ -598,13 +634,15 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {&opt_reqout}, {&opt_rspin}, {&opt_rspout}, {(char **)&opt_use_mock_srv}, -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) {&opt_port}, {(char **)&opt_max_msgs}, #endif {&opt_srv_ref}, {&opt_srv_secret}, {&opt_srv_cert}, {&opt_srv_key}, {&opt_srv_keypass}, {&opt_srv_trusted}, {&opt_srv_untrusted}, - {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs}, + {&opt_ref_cert}, {&opt_rsp_cert}, {&opt_rsp_extracerts}, {&opt_rsp_capubs}, + {&opt_rsp_newwithnew}, {&opt_rsp_newwithold}, {&opt_rsp_oldwithnew}, + {(char **)&opt_poll_count}, {(char **)&opt_check_after}, {(char **)&opt_grant_implicitconf}, {(char **)&opt_pkistatus}, {(char **)&opt_failure}, @@ -689,40 +727,12 @@ static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc) return cert; } -static X509_REQ *load_csr_autofmt(const char *infile, const char *desc) -{ - X509_REQ *csr; - BIO *bio_bak = bio_err; - - bio_err = NULL; /* do not show errors on more than one try */ - csr = load_csr(infile, FORMAT_PEM, desc); - bio_err = bio_bak; - if (csr == NULL) { - ERR_clear_error(); - csr = load_csr(infile, FORMAT_ASN1, desc); - } - if (csr == NULL) { - ERR_print_errors(bio_err); - BIO_printf(bio_err, "error: unable to load %s from file '%s'\n", desc, - infile); - } else { - EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr); - int ret = do_X509_REQ_verify(csr, pkey, NULL /* vfyopts */); - - if (pkey == NULL || ret < 0) - CMP_warn("error while verifying CSR self-signature"); - else if (ret == 0) - CMP_warn("CSR self-signature does not match the contents"); - } - return csr; -} - -/* set expected host name/IP addr and clears the email addr in the given ts */ +/* set expected hostname/IP addr and clears the email addr in the given ts */ static int truststore_set_host_etc(X509_STORE *ts, const char *host) { X509_VERIFY_PARAM *ts_vpm = X509_STORE_get0_param(ts); - /* first clear any host names, IP, and email addresses */ + /* first clear any hostnames, IP, and email addresses */ if (!X509_VERIFY_PARAM_set1_host(ts_vpm, NULL, 0) || !X509_VERIFY_PARAM_set1_ip(ts_vpm, NULL, 0) || !X509_VERIFY_PARAM_set1_email(ts_vpm, NULL, 0)) @@ -797,8 +807,7 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr; const char *prev_opt_rspin = opt_rspin; - if (req != NULL && opt_reqout != NULL - && !write_PKIMESSAGE(req, &opt_reqout)) + if (opt_reqout != NULL && !write_PKIMESSAGE(req, &opt_reqout)) goto err; if (opt_reqin != NULL && opt_rspin == NULL) { if ((req_new = read_PKIMESSAGE("actually sending", &opt_reqin)) == NULL) @@ -830,7 +839,7 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, CMP_warn("too few -rspin filename arguments; resorting to using mock server"); res = OSSL_CMP_CTX_server_perform(ctx, actual_req); } else { -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_server == NULL) { CMP_err("missing -server or -use_mock_srv option, or too few -rspin filename arguments"); goto err; @@ -839,7 +848,7 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, CMP_warn("too few -rspin filename arguments; resorting to contacting server"); res = OSSL_CMP_MSG_http_perform(ctx, actual_req); #else - CMP_err("-server not supported on no-sock build; missing -use_mock_srv option or too few -rspin filename arguments"); + CMP_err("-server not supported on no-sock/no-http build; missing -use_mock_srv option or too few -rspin filename arguments"); #endif } rspin_in_use = 0; @@ -907,11 +916,12 @@ static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc) continue; } - /* try IP address first, then URI or domain name */ + /* try IP address first, then email/URI/domain name */ (void)ERR_set_mark(); n = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_IPADD, names, 0); if (n == NULL) n = a2i_GENERAL_NAME(NULL, NULL, NULL, + strchr(names, '@') != NULL ? GEN_EMAIL : strchr(names, ':') != NULL ? GEN_URI : GEN_DNS, names, 0); (void)ERR_pop_to_mark(); @@ -948,8 +958,23 @@ static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc) return NULL; } -typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); +typedef int (*add_X509_fn_t)(void *ctx, const X509 *cert); +static int setup_cert(void *ctx, const char *file, const char *pass, + const char *desc, add_X509_fn_t set1_fn) +{ + X509 *cert; + int ok; + if (file == NULL) + return 1; + if ((cert = load_cert_pwd(file, pass, desc)) == NULL) + return 0; + ok = (*set1_fn)(ctx, cert); + X509_free(cert); + return ok; +} + +typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); static int setup_certs(char *files, const char *desc, void *ctx, add_X509_stack_fn_t set1_fn) { @@ -961,11 +986,10 @@ static int setup_certs(char *files, const char *desc, void *ctx, if ((certs = load_certs_multifile(files, opt_otherpass, desc, vpm)) == NULL) return 0; ok = (*set1_fn)(ctx, certs); - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); return ok; } - /* * parse and transform some options, checking their syntax. * Returns 1 on success, 0 on error @@ -1063,16 +1087,10 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) CMP_err("must give both -srv_cert and -srv_key options or neither"); goto err; } - if (opt_srv_cert != NULL) { - X509 *srv_cert = load_cert_pwd(opt_srv_cert, opt_srv_keypass, - "certificate of the mock server"); - - if (srv_cert == NULL || !OSSL_CMP_CTX_set1_cert(ctx, srv_cert)) { - X509_free(srv_cert); - goto err; - } - X509_free(srv_cert); - } + if (!setup_cert(ctx, opt_srv_cert, opt_srv_keypass, + "signer certificate of the mock server", + (add_X509_fn_t)OSSL_CMP_CTX_set1_cert)) + goto err; if (opt_srv_key != NULL) { EVP_PKEY *pkey = load_key_pwd(opt_srv_key, opt_keyform, opt_srv_keypass, @@ -1090,7 +1108,7 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) X509_STORE *ts = load_trusted(opt_srv_trusted, 0, "certs trusted by mock server"); - if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + if (ts == NULL || !OSSL_CMP_CTX_set0_trusted(ctx, ts)) { X509_STORE_free(ts); goto err; } @@ -1102,20 +1120,17 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) goto err; + if (!setup_cert(srv_ctx, opt_ref_cert, opt_otherpass, + "reference cert to be expected by the mock server", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_refCert)) + goto err; if (opt_rsp_cert == NULL) { CMP_warn("no -rsp_cert given for mock server"); } else { - X509 *cert = load_cert_pwd(opt_rsp_cert, opt_keypass, - "cert to be returned by the mock server"); - - if (cert == NULL) - goto err; - /* from server perspective the server is the client */ - if (!ossl_cmp_mock_srv_set1_certOut(srv_ctx, cert)) { - X509_free(cert); + if (!setup_cert(srv_ctx, opt_rsp_cert, opt_keypass, + "cert the mock server returns on certificate requests", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_certOut)) goto err; - } - X509_free(cert); } if (!setup_certs(opt_rsp_extracerts, "CMP extra certificates for mock server", srv_ctx, @@ -1124,6 +1139,16 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) if (!setup_certs(opt_rsp_capubs, "caPubs for mock server", srv_ctx, (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut)) goto err; + if (!setup_cert(srv_ctx, opt_rsp_newwithnew, opt_otherpass, + "NewWithNew cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithNew) + || !setup_cert(srv_ctx, opt_rsp_newwithold, opt_otherpass, + "NewWithOld cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_newWithOld) + || !setup_cert(srv_ctx, opt_rsp_oldwithnew, opt_otherpass, + "OldWithNew cert the mock server returns in rootCaKeyUpdate", + (add_X509_fn_t)ossl_cmp_mock_srv_set1_oldWithNew)) + goto err; (void)ossl_cmp_mock_srv_set_pollCount(srv_ctx, opt_poll_count); (void)ossl_cmp_mock_srv_set_checkAfterTime(srv_ctx, opt_check_after); if (opt_grant_implicitconf) @@ -1180,10 +1205,6 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) return 0; if (opt_srvcert != NULL || opt_trusted != NULL) { - X509 *srvcert; - X509_STORE *ts; - int ok; - if (opt_srvcert != NULL) { if (opt_trusted != NULL) { CMP_warn("-trusted option is ignored since -srvcert option is present"); @@ -1193,21 +1214,21 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) CMP_warn("-recipient option is ignored since -srvcert option is present"); opt_recipient = NULL; } - srvcert = load_cert_pwd(opt_srvcert, opt_otherpass, - "directly trusted CMP server certificate"); - ok = srvcert != NULL && OSSL_CMP_CTX_set1_srvCert(ctx, srvcert); - X509_free(srvcert); - if (!ok) + if (!setup_cert(ctx, opt_srvcert, opt_otherpass, + "directly trusted CMP server certificate", + (add_X509_fn_t)OSSL_CMP_CTX_set1_srvCert)) return 0; } if (opt_trusted != NULL) { + X509_STORE *ts; + /* * the 0 arg below clears any expected host/ip/email address; * opt_expect_sender is used instead */ ts = load_trusted(opt_trusted, 0, "certs trusted by client"); - if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + if (ts == NULL || !OSSL_CMP_CTX_set0_trusted(ctx, ts)) { X509_STORE_free(ts); return 0; } @@ -1244,7 +1265,7 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) return 1; } -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) /* * set up ssl_ctx for the OSSL_CMP_CTX based on options from config file/CLI. * Returns pointer on success, NULL on error @@ -1267,6 +1288,9 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host, if (trust_store == NULL) goto err; SSL_CTX_set_cert_store(ssl_ctx, trust_store); + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + } else { + CMP_warn("-tls_used given without -tls_trusted; will not authenticate the TLS server"); } if (opt_tls_cert != NULL && opt_tls_key != NULL) { @@ -1290,7 +1314,7 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host, if (!ok || !SSL_CTX_set0_chain(ssl_ctx, certs)) { CMP_err1("unable to use client TLS certificate file '%s'", opt_tls_cert); - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); goto err; } for (i = 0; i < sk_X509_num(untrusted); i++) { @@ -1377,13 +1401,18 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host, goto err; } EVP_PKEY_free(pkey); /* we do not need the handle any more */ + } else { + CMP_warn("-tls_used given without -tls_key; cannot authenticate to the TLS server"); } - if (opt_tls_trusted != NULL) { - /* enable and parameterize server hostname/IP address check */ + if (trust_store != NULL) { + /* + * Enable and parameterize server hostname/IP address check. + * If we did this before checking our own TLS cert + * the expected hostname would mislead the check. + */ if (!truststore_set_host_etc(trust_store, opt_tls_host != NULL ? opt_tls_host : host)) goto err; - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); } return ssl_ctx; err: @@ -1409,7 +1438,7 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) CMP_err("must give -ref if no -cert and no -subject given"); return 0; } - if (!opt_secret && ((opt_cert == NULL) != (opt_key == NULL))) { + if (opt_secret == NULL && ((opt_cert == NULL) != (opt_key == NULL))) { CMP_err("must give both -cert and -key options or neither"); return 0; } @@ -1471,7 +1500,7 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) ok = ok && OSSL_CMP_CTX_build_cert_chain(ctx, own_trusted, certs); } X509_STORE_free(own_trusted); - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); if (!ok) return 0; } else if (opt_own_trusted != NULL) { @@ -1502,6 +1531,7 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_mac != NULL) { int mac = OBJ_ln2nid(opt_mac); + if (mac == NID_undef) { CMP_err1("MAC algorithm name not recognized: '%s'", opt_mac); return 0; @@ -1512,9 +1542,9 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) } /* - * set up IR/CR/KUR/CertConf/RR specific parts of the OSSL_CMP_CTX - * based on options from config file/CLI. - * Returns pointer on success, NULL on error + * Set up IR/CR/P10CR/KUR/CertConf/RR/GENM specific parts of the OSSL_CMP_CTX + * based on options from CLI and/or config file. + * Returns 1 on success, 0 on error */ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { @@ -1527,6 +1557,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) && opt_cmd != CMP_RR && opt_cmd != CMP_GENM) CMP_warn("no -subject given; no -csr or -oldcert or -cert available for fallback"); + if (!set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer")) + return 0; if (opt_cmd == CMP_IR || opt_cmd == CMP_CR || opt_cmd == CMP_KUR) { if (opt_newkey == NULL && opt_key == NULL && opt_csr == NULL && opt_oldcert == NULL) { @@ -1539,7 +1571,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_csr != NULL) { CMP_err1("no -newkey option given with private key for POPO, -csr option only provides public key%s", opt_key == NULL ? "" : - ", and -key option superseded by by -csr"); + ", and -key option superseded by -csr"); return 0; } if (opt_key == NULL) { @@ -1551,23 +1583,22 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) CMP_err("-certout not given, nowhere to save newly enrolled certificate"); return 0; } - if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject") - || !set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer")) + if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject")) return 0; } else { const char *msg = "option is ignored for commands other than 'ir', 'cr', and 'kur'"; if (opt_subject != NULL) { if (opt_ref == NULL && opt_cert == NULL) { - /* use subject as default sender unless oldcert subject is used */ + /* will use subject as sender unless oldcert subject is used */ if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject")) return 0; } else { - CMP_warn1("-subject %s since -ref or -cert is given", msg); + CMP_warn1("-subject %s since sender is taken from -ref or -cert", msg); } } - if (opt_issuer != NULL) - CMP_warn1("-issuer %s", msg); + if (opt_issuer != NULL && opt_cmd != CMP_RR) + CMP_warn1("-issuer %s and 'rr'", msg); if (opt_reqexts != NULL) CMP_warn1("-reqexts %s", msg); if (opt_san_nodefault) @@ -1578,6 +1609,16 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) CMP_warn1("-policies %s", msg); if (opt_policy_oids != NULL) CMP_warn1("-policy_oids %s", msg); + if (opt_cmd != CMP_P10CR) { + if (opt_implicit_confirm) + CMP_warn1("-implicit_confirm %s, and 'p10cr'", msg); + if (opt_disable_confirm) + CMP_warn1("-disable_confirm %s, and 'p10cr'", msg); + if (opt_certout != NULL) + CMP_warn1("-certout %s, and 'p10cr'", msg); + if (opt_chainout != NULL) + CMP_warn1("-chainout %s, and 'p10cr'", msg); + } } if (opt_cmd == CMP_KUR) { char *ref_cert = opt_oldcert != NULL ? opt_oldcert : opt_cert; @@ -1591,12 +1632,44 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) opt_subject, ref_cert != NULL ? ref_cert : opt_csr); } if (opt_cmd == CMP_RR) { - if (opt_oldcert == NULL && opt_csr == NULL) { - CMP_err("missing -oldcert for certificate to be revoked and no -csr given"); - return 0; + if (opt_issuer == NULL && opt_serial == NULL) { + if (opt_oldcert == NULL && opt_csr == NULL) { + CMP_err("missing -oldcert or -issuer and -serial for certificate to be revoked and no -csr given"); + return 0; + } + if (opt_oldcert != NULL && opt_csr != NULL) + CMP_warn("ignoring -csr since certificate to be revoked is given"); + } else { +#define OSSL_CMP_RR_MSG "since -issuer and -serial is given for command 'rr'" + if (opt_issuer == NULL || opt_serial == NULL) { + CMP_err("Must give both -issuer and -serial options or neither"); + return 0; + } + if (opt_oldcert != NULL) + CMP_warn("Ignoring -oldcert " OSSL_CMP_RR_MSG); + if (opt_csr != NULL) + CMP_warn("Ignoring -csr " OSSL_CMP_RR_MSG); } - if (opt_oldcert != NULL && opt_csr != NULL) - CMP_warn("ignoring -csr since certificate to be revoked is given"); + if (opt_serial != NULL) { + ASN1_INTEGER *sno; + + if ((sno = s2i_ASN1_INTEGER(NULL, opt_serial)) == NULL) { + CMP_err1("cannot read serial number: '%s'", opt_serial); + return 0; + } + if (!OSSL_CMP_CTX_set1_serialNumber(ctx, sno)) { + ASN1_INTEGER_free(sno); + CMP_err("out of memory"); + return 0; + } + ASN1_INTEGER_free(sno); + } + if (opt_revreason > CRL_REASON_NONE) + (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_REVOCATION_REASON, + opt_revreason); + } else { + if (opt_serial != NULL) + CMP_warn("Ignoring -serial for command other than 'rr'"); } if (opt_cmd == CMP_P10CR && opt_csr == NULL) { CMP_err("missing PKCS#10 CSR for p10cr"); @@ -1607,17 +1680,19 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) && opt_oldcert == NULL && opt_cert == NULL) CMP_warn("missing -recipient, -srvcert, -issuer, -oldcert or -cert; recipient will be set to \"NULL-DN\""); - if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR) { - const char *msg = "option is ignored for 'p10cr' and 'rr' commands"; + if (opt_cmd == CMP_P10CR || opt_cmd == CMP_RR || opt_cmd == CMP_GENM) { + const char *msg = "option is ignored for 'p10cr', 'rr', and 'genm' commands"; if (opt_newkeypass != NULL) - CMP_warn1("-newkeytype %s", msg); + CMP_warn1("-newkeypass %s", msg); if (opt_newkey != NULL) CMP_warn1("-newkey %s", msg); if (opt_days != 0) CMP_warn1("-days %s", msg); if (opt_popo != OSSL_CRMF_POPO_NONE - 1) CMP_warn1("-popo %s", msg); + if (opt_out_trusted != NULL) + CMP_warn1("-out_trusted %s", msg); } else if (opt_newkey != NULL) { const char *file = opt_newkey; const int format = opt_keyform; @@ -1633,8 +1708,8 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (pkey == NULL) { ERR_clear_error(); desc = opt_csr == NULL - ? "fallback public key for cert to be enrolled" - : "public key for checking cert resulting from p10cr"; + ? "fallback public key for cert to be enrolled" + : "public key for checking cert resulting from p10cr"; pkey = load_pubkey(file, format, 0, pass, engine, desc); priv = 0; } @@ -1659,9 +1734,10 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_csr != NULL) { if (opt_cmd == CMP_GENM) { - CMP_warn("-csr option is ignored for command 'genm'"); + CMP_warn("-csr option is ignored for 'genm' command"); } else { - if ((csr = load_csr_autofmt(opt_csr, "PKCS#10 CSR")) == NULL) + csr = load_csr_autofmt(opt_csr, FORMAT_UNDEF, NULL, "PKCS#10 CSR"); + if (csr == NULL) return 0; if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) goto oom; @@ -1738,30 +1814,18 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_oldcert != NULL) { if (opt_cmd == CMP_GENM) { - CMP_warn("-oldcert option is ignored for command 'genm'"); + CMP_warn("-oldcert option is ignored for 'genm' command"); } else { - X509 *oldcert = load_cert_pwd(opt_oldcert, opt_keypass, - opt_cmd == CMP_KUR ? - "certificate to be updated" : - opt_cmd == CMP_RR ? - "certificate to be revoked" : - "reference certificate (oldcert)"); - /* opt_keypass needed if opt_oldcert is an encrypted PKCS#12 file */ - - if (oldcert == NULL) + if (!setup_cert(ctx, opt_oldcert, opt_keypass, + /* needed if opt_oldcert is encrypted PKCS12 file */ + opt_cmd == CMP_KUR ? "certificate to be updated" : + opt_cmd == CMP_RR ? "certificate to be revoked" : + "reference certificate (oldcert)", + (add_X509_fn_t)OSSL_CMP_CTX_set1_oldCert)) return 0; - if (!OSSL_CMP_CTX_set1_oldCert(ctx, oldcert)) { - X509_free(oldcert); - CMP_err("out of memory"); - return 0; - } - X509_free(oldcert); } } cleanse(opt_keypass); - if (opt_revreason > CRL_REASON_NONE) - (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_REVOCATION_REASON, - opt_revreason); return 1; @@ -1790,11 +1854,10 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) valptr[0] = '\0'; valptr++; - if (OPENSSL_strncasecmp(valptr, "int:", 4) != 0) { + if (!CHECK_AND_SKIP_CASE_PREFIX(valptr, "int:")) { CMP_err("missing 'int:' in -geninfo option"); return 0; } - valptr += 4; value = strtol(valptr, &endstr, 10); if (endstr == valptr || *endstr != '\0') { @@ -1835,7 +1898,6 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) return 0; } - /* * set up the client-side OSSL_CMP_CTX based on options from config file/CLI * while parsing options and checking their consistency. @@ -1846,8 +1908,8 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { int ret = 0; char *host = NULL, *port = NULL, *path = NULL, *used_path = opt_path; -#ifndef OPENSSL_NO_SOCK - int portnum, ssl; +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) + int portnum, use_ssl; static char server_port[32] = { '\0' }; const char *proxy_host = NULL; #endif @@ -1855,7 +1917,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) char proxy_buf[200] = ""; if (!opt_use_mock_srv && opt_rspin == NULL) { /* note: -port is not given */ -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_server == NULL) { CMP_err("missing -server or -use_mock_srv or -rspin option"); goto err; @@ -1865,27 +1927,26 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) goto err; #endif } -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_server == NULL) { if (opt_proxy != NULL) CMP_warn("ignoring -proxy option since -server is not given"); if (opt_no_proxy != NULL) CMP_warn("ignoring -no_proxy option since -server is not given"); - if (opt_tls_used) { - CMP_warn("ignoring -tls_used option since -server is not given"); - opt_tls_used = 0; - } goto set_path; } - if (!OSSL_HTTP_parse_url(opt_server, &ssl, NULL /* user */, &host, &port, - &portnum, &path, NULL /* q */, NULL /* frag */)) { + if (!OSSL_HTTP_parse_url(opt_server, &use_ssl, NULL /* user */, + &host, &port, &portnum, + &path, NULL /* q */, NULL /* frag */)) { CMP_err1("cannot parse -server URL: %s", opt_server); goto err; } - if (ssl && !opt_tls_used) { - CMP_err("missing -tls_used option since -server URL indicates https"); - goto err; + if (use_ssl && !opt_tls_used) { + CMP_warn("assuming -tls_used since -server URL indicates HTTPS"); + opt_tls_used = 1; } + if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_USE_TLS, opt_tls_used)) + goto err; BIO_snprintf(server_port, sizeof(server_port), "%s", port); if (opt_path == NULL) @@ -1901,7 +1962,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) opt_tls_used ? "s" : "", host, port, *used_path == '/' ? used_path + 1 : used_path); - proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, ssl); + proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, use_ssl); if (proxy_host != NULL) (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host); @@ -1913,7 +1974,12 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (!transform_opts()) goto err; - if (opt_infotype_s != NULL) { + if (opt_infotype_s == NULL) { + if (opt_cmd == CMP_GENM) + CMP_warn("no -infotype option given for genm"); + } else if (opt_cmd != CMP_GENM) { + CMP_warn("-infotype option is ignored for commands other than 'genm'"); + } else { char id_buf[100] = "id-it-"; strncat(id_buf, opt_infotype_s, sizeof(id_buf) - strlen(id_buf) - 1); @@ -1922,6 +1988,18 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) goto err; } } + if (opt_cmd != CMP_GENM || opt_infotype != NID_id_it_rootCaCert) { + const char *msg = "option is ignored unless -cmd 'genm' and -infotype rootCaCert is given"; + + if (opt_oldwithold != NULL) + CMP_warn1("-oldwithold %s", msg); + if (opt_newwithnew != NULL) + CMP_warn1("-newwithnew %s", msg); + if (opt_newwithold != NULL) + CMP_warn1("-newwithold %s", msg); + if (opt_oldwithnew != NULL) + CMP_warn1("-oldwithnew %s", msg); + } if (!setup_verification_ctx(ctx)) goto err; @@ -1953,7 +2031,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) || opt_rspin != NULL || opt_rspout != NULL || opt_use_mock_srv) (void)OSSL_CMP_CTX_set_transfer_cb(ctx, read_write_req_resp); -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_tls_used) { APP_HTTP_TLS_INFO *info; @@ -1970,6 +2048,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if ((info = OPENSSL_zalloc(sizeof(*info))) == NULL) goto err; + APP_HTTP_TLS_INFO_free(OSSL_CMP_CTX_get_http_cb_arg(ctx)); (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info); info->ssl_ctx = setup_ssl_ctx(ctx, host, engine); info->server = host; @@ -2038,36 +2117,41 @@ static int write_cert(BIO *bio, X509 *cert) } /* - * If destFile != NULL writes out a stack of certs to the given file. - * In any case frees the certs. + * If file != NULL writes out a stack of certs to the given file. + * If certs is NULL, the file is emptied. + * Frees the certs if present. * Depending on options use either PEM or DER format, * where DER does not make much sense for writing more than one cert! * Returns number of written certificates on success, -1 on error. */ -static int save_free_certs(OSSL_CMP_CTX *ctx, - STACK_OF(X509) *certs, char *destFile, char *desc) +static int save_free_certs(STACK_OF(X509) *certs, + const char *file, const char *desc) { BIO *bio = NULL; int i; - int n = sk_X509_num(certs); + int n = sk_X509_num(certs /* may be NULL */); - if (destFile == NULL) + if (n < 0) + n = 0; + if (file == NULL) goto end; - CMP_info3("received %d %s certificate(s), saving to file '%s'", - n, desc, destFile); + if (certs != NULL) + CMP_info3("received %d %s certificate(s), saving to file '%s'", + n, desc, file); if (n > 1 && opt_certform != FORMAT_PEM) CMP_warn("saving more than one certificate in non-PEM format"); - if (destFile == NULL || (bio = BIO_new(BIO_s_file())) == NULL - || !BIO_write_filename(bio, (char *)destFile)) { - CMP_err1("could not open file '%s' for writing", destFile); + if ((bio = BIO_new(BIO_s_file())) == NULL + || !BIO_write_filename(bio, (char *)file)) { + CMP_err3("could not open file '%s' for %s %s certificate(s)", + file, certs == NULL ? "deleting" : "writing", desc); n = -1; goto end; } for (i = 0; i < n; i++) { if (!write_cert(bio, sk_X509_value(certs, i))) { - CMP_err1("cannot write certificate to file '%s'", destFile); + CMP_err2("cannot write %s certificate to file '%s'", desc, file); n = -1; goto end; } @@ -2075,32 +2159,71 @@ static int save_free_certs(OSSL_CMP_CTX *ctx, end: BIO_free(bio); - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); return n; } -static void print_itavs(STACK_OF(OSSL_CMP_ITAV) *itavs) +static int delete_file(const char *file, const char *desc) { - OSSL_CMP_ITAV *itav = NULL; - char buf[128]; - int i, r; - int n = sk_OSSL_CMP_ITAV_num(itavs); /* itavs == NULL leads to 0 */ + if (file == NULL) + return 1; - if (n == 0) { - CMP_info("genp contains no ITAV"); - return; + if (unlink(file) != 0 && errno != ENOENT) { + CMP_err2("Failed to delete %s, which should be done to indicate there is no %s", + file, desc); + return 0; } + return 1; +} - for (i = 0; i < n; i++) { - itav = sk_OSSL_CMP_ITAV_value(itavs, i); - r = OBJ_obj2txt(buf, 128, OSSL_CMP_ITAV_get0_type(itav), 0); - if (r < 0) - CMP_err("could not get ITAV details"); - else if (r == 0) - CMP_info("genp contains empty ITAV"); - else - CMP_info1("genp contains ITAV of type: %s", buf); +static int save_cert_or_delete(X509 *cert, const char *file, const char *desc) +{ + if (file == NULL) + return 1; + if (cert == NULL) { + char desc_cert[80]; + + BIO_snprintf(desc_cert, sizeof(desc_cert), "%s certificate", desc); + return delete_file(file, desc_cert); + } else { + STACK_OF(X509) *certs = sk_X509_new_null(); + + if (!X509_add_cert(certs, cert, X509_ADD_FLAG_UP_REF)) { + sk_X509_free(certs); + return 0; + } + return save_free_certs(certs, file, desc) >= 0; + } +} + +static int print_itavs(const STACK_OF(OSSL_CMP_ITAV) *itavs) +{ + int i, ret = 1; + int n = sk_OSSL_CMP_ITAV_num(itavs); + + if (n <= 0) { /* also in case itavs == NULL */ + CMP_info("genp does not contain any ITAV"); + return ret; } + + for (i = 1; i <= n; i++) { + OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i - 1); + ASN1_OBJECT *type = OSSL_CMP_ITAV_get0_type(itav); + char name[80]; + + if (itav == NULL) { + CMP_err1("could not get ITAV #%d from genp", i); + ret = 0; + continue; + } + if (i2t_ASN1_OBJECT(name, sizeof(name), type) <= 0) { + CMP_err1("error parsing type of ITAV #%d from genp", i); + ret = 0; + } else { + CMP_info2("ITAV #%d from genp infoType=%s", i, name); + } + } + return ret; } static char opt_item[SECTION_NAME_MAX + 1]; @@ -2146,9 +2269,8 @@ static char *conf_get_string(const CONF *src_conf, const char *groups, const char *end = groups + strlen(groups); while ((end = prev_item(groups, end)) != NULL) { - if ((res = NCONF_get_string(src_conf, opt_item, name)) != NULL) + if ((res = app_conf_try_string(src_conf, opt_item, name)) != NULL) return res; - ERR_clear_error(); } return res; } @@ -2197,9 +2319,9 @@ static int read_config(void) || !strcmp(opt->name, OPT_MORE_STR)) n_options--; OPENSSL_assert(OSSL_NELEM(cmp_vars) == n_options - + OPT_PROV__FIRST + 1 - OPT_PROV__LAST - + OPT_R__FIRST + 1 - OPT_R__LAST - + OPT_V__FIRST + 1 - OPT_V__LAST); + + OPT_PROV__FIRST + 1 - OPT_PROV__LAST + + OPT_R__FIRST + 1 - OPT_R__LAST + + OPT_V__FIRST + 1 - OPT_V__LAST); for (opt = &cmp_options[start_opt], i = start_idx; opt->name != NULL; i++, opt++) { int provider_option = (OPT_PROV__FIRST <= opt->retval @@ -2346,7 +2468,7 @@ static int get_opts(int argc, char **argv) if (!set_verbosity(opt_int_arg())) goto opthelp; break; -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) case OPT_SERVER: opt_server = opt_str(); break; @@ -2376,7 +2498,7 @@ static int get_opts(int argc, char **argv) case OPT_TOTAL_TIMEOUT: opt_total_timeout = opt_int_arg(); break; -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) case OPT_TLS_USED: opt_tls_used = 1; break; @@ -2449,12 +2571,27 @@ static int get_opts(int argc, char **argv) case OPT_UNPROTECTED_ERRORS: opt_unprotected_errors = 1; break; + case OPT_SRVCERTOUT: + opt_srvcertout = opt_str(); + break; case OPT_EXTRACERTSOUT: opt_extracertsout = opt_str(); break; case OPT_CACERTSOUT: opt_cacertsout = opt_str(); break; + case OPT_OLDWITHOLD: + opt_oldwithold = opt_str(); + break; + case OPT_NEWWITHNEW: + opt_newwithnew = opt_str(); + break; + case OPT_NEWWITHOLD: + opt_newwithold = opt_str(); + break; + case OPT_OLDWITHNEW: + opt_oldwithnew = opt_str(); + break; case OPT_V_CASES: if (!opt_verify(o, vpm)) @@ -2479,9 +2616,6 @@ static int get_opts(int argc, char **argv) case OPT_SUBJECT: opt_subject = opt_str(); break; - case OPT_ISSUER: - opt_issuer = opt_str(); - break; case OPT_DAYS: opt_days = opt_int_arg(); break; @@ -2534,13 +2668,19 @@ static int get_opts(int argc, char **argv) break; case OPT_REVREASON: opt_revreason = opt_int_arg(); - if (opt_revreason < CRL_REASON_NONE + if (opt_revreason < CRL_REASON_NONE || opt_revreason > CRL_REASON_AA_COMPROMISE || opt_revreason == 7) { CMP_err("invalid revreason. Valid values are -1 .. 6, 8 .. 10"); goto opthelp; } break; + case OPT_ISSUER: + opt_issuer = opt_str(); + break; + case OPT_SERIAL: + opt_serial = opt_str(); + break; case OPT_CERTFORM: opt_certform_s = opt_str(); break; @@ -2589,7 +2729,7 @@ static int get_opts(int argc, char **argv) opt_use_mock_srv = 1; break; -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) case OPT_PORT: opt_port = opt_str(); break; @@ -2618,6 +2758,9 @@ static int get_opts(int argc, char **argv) case OPT_SRV_UNTRUSTED: opt_srv_untrusted = opt_str(); break; + case OPT_REF_CERT: + opt_ref_cert = opt_str(); + break; case OPT_RSP_CERT: opt_rsp_cert = opt_str(); break; @@ -2627,6 +2770,15 @@ static int get_opts(int argc, char **argv) case OPT_RSP_CAPUBS: opt_rsp_capubs = opt_str(); break; + case OPT_RSP_NEWWITHNEW: + opt_rsp_newwithnew = opt_str(); + break; + case OPT_RSP_NEWWITHOLD: + opt_rsp_newwithold = opt_str(); + break; + case OPT_RSP_OLDWITHNEW: + opt_rsp_oldwithnew = opt_str(); + break; case OPT_POLL_COUNT: opt_poll_count = opt_int_arg(); break; @@ -2670,15 +2822,14 @@ static int get_opts(int argc, char **argv) } /* No extra args. */ - argc = opt_num_rest(); - argv = opt_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; return 1; } -#ifndef OPENSSL_NO_SOCK -static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) +static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) +{ BIO *acbio; BIO *cbio = NULL; int keep_alive = 0; @@ -2686,7 +2837,7 @@ static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { int retry = 1; int ret = 1; - if ((acbio = http_server_init_bio(prog, opt_port)) == NULL) + if ((acbio = http_server_init(prog, opt_port, opt_verbosity)) == NULL) return 0; while (opt_max_msgs <= 0 || msgs < opt_max_msgs) { char *path = NULL; @@ -2696,10 +2847,10 @@ static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG), (ASN1_VALUE **)&req, &path, &cbio, acbio, &keep_alive, - prog, opt_port, 0, 0); + prog, 0, 0); if (ret == 0) { /* no request yet */ if (retry) { - ossl_sleep(1000); + OSSL_sleep(1000); retry = 0; continue; } @@ -2713,7 +2864,7 @@ static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { msgs++; if (req != NULL) { if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) { - (void)http_server_send_status(cbio, 404, "Not Found"); + (void)http_server_send_status(prog, cbio, 404, "Not Found"); CMP_err1("expecting empty path or 'pkix/' but got '%s'", path); OPENSSL_free(path); @@ -2724,11 +2875,11 @@ static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) { resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req); OSSL_CMP_MSG_free(req); if (resp == NULL) { - (void)http_server_send_status(cbio, + (void)http_server_send_status(prog, cbio, 500, "Internal Server Error"); break; /* treated as fatal error */ } - ret = http_server_send_asn1_resp(cbio, keep_alive, + ret = http_server_send_asn1_resp(prog, cbio, keep_alive, "application/pkixcmp", ASN1_ITEM_rptr(OSSL_CMP_MSG), (const ASN1_VALUE *)resp); @@ -2764,7 +2915,7 @@ static void print_status(void) OSSL_CMP_CTX_snprint_PKIStatus(cmp_ctx, buf, OSSL_CMP_PKISI_BUFLEN); const char *from = "", *server = ""; -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_server != NULL) { from = " from "; server = opt_server; @@ -2784,6 +2935,99 @@ static void print_status(void) OPENSSL_free(buf); } +static int do_genm(OSSL_CMP_CTX *ctx) +{ + if (opt_infotype == NID_id_it_caCerts) { + STACK_OF(X509) *cacerts = NULL; + + if (opt_cacertsout == NULL) { + CMP_err("Missing -cacertsout option for -infotype caCerts"); + return 0; + } + + if (!OSSL_CMP_get1_caCerts(ctx, &cacerts)) + return 0; + + /* could check authorization of sender/origin at this point */ + if (cacerts == NULL) { + CMP_warn("no CA certificates provided by server"); + } else if (save_free_certs(cacerts, opt_cacertsout, "CA") < 0) { + CMP_err1("Failed to store CA certificates from genp in %s", + opt_cacertsout); + return 0; + } + return 1; + } else if (opt_infotype == NID_id_it_rootCaCert) { + X509 *oldwithold = NULL; + X509 *newwithnew = NULL; + X509 *newwithold = NULL; + X509 *oldwithnew = NULL; + int res = 0; + + if (opt_newwithnew == NULL) { + CMP_err("Missing -newwithnew option for -infotype rootCaCert"); + return 0; + } + if (opt_oldwithold == NULL) { + CMP_warn("No -oldwithold given, will use all certs given with -trusted as trust anchors for verifying the newWithNew cert"); + } else { + oldwithold = load_cert_pwd(opt_oldwithold, opt_otherpass, + "OldWithOld cert for genm with -infotype rootCaCert"); + if (oldwithold == NULL) + goto end_upd; + } + if (!OSSL_CMP_get1_rootCaKeyUpdate(ctx, oldwithold, &newwithnew, + &newwithold, &oldwithnew)) + goto end_upd; + /* At this point might check authorization of response sender/origin */ + + if (newwithnew == NULL) + CMP_info("no root CA certificate update available"); + else if (oldwithold == NULL && oldwithnew != NULL) + CMP_warn("oldWithNew certificate received in genp for verifying oldWithOld, but oldWithOld was not provided"); + + if (save_cert_or_delete(newwithnew, opt_newwithnew, + "NewWithNew cert from genp") + && save_cert_or_delete(newwithold, opt_newwithold, + "NewWithOld cert from genp") + && save_cert_or_delete(oldwithnew, opt_oldwithnew, + "OldWithNew cert from genp")) + res = 1; + + X509_free(newwithnew); + X509_free(newwithold); + X509_free(oldwithnew); + end_upd: + X509_free(oldwithold); + return res; + } else { + OSSL_CMP_ITAV *req; + STACK_OF(OSSL_CMP_ITAV) *itavs; + + if (opt_infotype != NID_undef) { + CMP_warn1("No specific support for -infotype %s available", + opt_infotype_s); + + req = OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL); + if (req == NULL || !OSSL_CMP_CTX_push0_genm_ITAV(ctx, req)) { + CMP_err1("Failed to create genm for -infotype %s", + opt_infotype_s); + return 0; + } + } + + if ((itavs = OSSL_CMP_exec_GENM_ses(ctx)) != NULL) { + int res = print_itavs(itavs); + + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + return res; + } + if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request) + CMP_err("Did not receive response on genm or genp is not valid"); + return 0; + } +} + int cmp_main(int argc, char **argv) { char *configfile = NULL; @@ -2828,7 +3072,8 @@ int cmp_main(int argc, char **argv) /* read default values for options from config file */ configfile = opt_config != NULL ? opt_config : default_config_file; if (configfile != NULL && configfile[0] != '\0' /* non-empty string */ - && (configfile != default_config_file || access(configfile, F_OK) != -1)) { + && (configfile != default_config_file + || access(configfile, F_OK) != -1)) { CMP_info2("using section(s) '%s' of OpenSSL configuration file '%s'", opt_section, configfile); conf = app_load_config(configfile); @@ -2842,6 +3087,7 @@ int cmp_main(int argc, char **argv) opt_section, configfile); } else { const char *end = opt_section + strlen(opt_section); + while ((end = prev_item(opt_section, end)) != NULL) { if (!NCONF_get_section(conf, opt_item)) { CMP_err2("no [%s] section found in config file '%s'", @@ -2865,6 +3111,7 @@ int cmp_main(int argc, char **argv) ret = get_opts(argc, argv); if (ret <= 0) goto err; + ret = 0; if (!app_RAND_load()) goto err; @@ -2873,7 +3120,8 @@ int cmp_main(int argc, char **argv) set_base_ui_method(UI_null()); if (opt_engine != NULL) { - engine = setup_engine_methods(opt_engine, 0 /* not: ENGINE_METHOD_ALL */, 0); + engine = setup_engine_methods(opt_engine, + 0 /* not: ENGINE_METHOD_ALL */, 0); if (engine == NULL) { CMP_err1("cannot load engine %s", opt_engine); goto err; @@ -2889,12 +3137,15 @@ int cmp_main(int argc, char **argv) goto err; } -#ifndef OPENSSL_NO_SOCK - if ((opt_tls_cert != NULL || opt_tls_key != NULL - || opt_tls_keypass != NULL || opt_tls_extra != NULL - || opt_tls_trusted != NULL || opt_tls_host != NULL) - && !opt_tls_used) - CMP_warn("Ingnoring TLS options(s) since -tls_used is not given"); +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) + if (opt_tls_cert == NULL && opt_tls_key == NULL && opt_tls_keypass == NULL + && opt_tls_extra == NULL && opt_tls_trusted == NULL + && opt_tls_host == NULL) { + if (opt_tls_used) + CMP_warn("-tls_used given without any other TLS options"); + } else if (!opt_tls_used) { + CMP_warn("ignoring TLS options(s) since -tls_used is not given"); + } if (opt_port != NULL) { if (opt_tls_used) { CMP_err("-tls_used option not supported with -port option"); @@ -2920,7 +3171,7 @@ int cmp_main(int argc, char **argv) #endif if (opt_use_mock_srv -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) || opt_port != NULL #endif ) { @@ -2937,7 +3188,7 @@ int cmp_main(int argc, char **argv) OSSL_CMP_CTX_set_log_verbosity(srv_cmp_ctx, opt_verbosity); } -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (opt_tls_used && (opt_use_mock_srv || opt_server == NULL)) { CMP_warn("ignoring -tls_used option since -use_mock_srv is given or -server is not given"); opt_tls_used = 0; @@ -2989,54 +3240,32 @@ int cmp_main(int argc, char **argv) ret = OSSL_CMP_exec_RR_ses(cmp_ctx); break; case CMP_GENM: - { - STACK_OF(OSSL_CMP_ITAV) *itavs; - - if (opt_infotype != NID_undef) { - OSSL_CMP_ITAV *itav = - OSSL_CMP_ITAV_create(OBJ_nid2obj(opt_infotype), NULL); - if (itav == NULL) - goto err; - OSSL_CMP_CTX_push0_genm_ITAV(cmp_ctx, itav); - } - - if ((itavs = OSSL_CMP_exec_GENM_ses(cmp_ctx)) != NULL) { - print_itavs(itavs); - sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); - ret = 1; - } - break; - } + ret = do_genm(cmp_ctx); default: break; } - if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) + if (OSSL_CMP_CTX_get_status(cmp_ctx) < OSSL_CMP_PKISTATUS_accepted) { + ret = 0; goto err; /* we got no response, maybe even did not send request */ - + } print_status(); - if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx), - opt_extracertsout, "extra") < 0) + if (!save_cert_or_delete(OSSL_CMP_CTX_get0_validatedSrvCert(cmp_ctx), + opt_srvcertout, "validated server")) ret = 0; if (!ret) goto err; ret = 0; - if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_caPubs(cmp_ctx), - opt_cacertsout, "CA") < 0) + if (save_free_certs(OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx), + opt_extracertsout, "extra") < 0) goto err; - if (newcert != NULL) { - STACK_OF(X509) *certs = sk_X509_new_null(); - - if (!X509_add_cert(certs, newcert, X509_ADD_FLAG_UP_REF)) { - sk_X509_free(certs); + if (newcert != NULL && (opt_cmd == CMP_IR || opt_cmd == CMP_CR + || opt_cmd == CMP_KUR || opt_cmd == CMP_P10CR)) + if (!save_cert_or_delete(newcert, opt_certout, "newly enrolled") + || save_free_certs(OSSL_CMP_CTX_get1_newChain(cmp_ctx), + opt_chainout, "chain") < 0 + || save_free_certs(OSSL_CMP_CTX_get1_caPubs(cmp_ctx), + opt_cacertsout, "CA") < 0) goto err; - } - if (save_free_certs(cmp_ctx, certs, opt_certout, "enrolled") < 0) - goto err; - } - if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_newChain(cmp_ctx), - opt_chainout, "chain") < 0) - goto err; - if (!OSSL_CMP_CTX_reinit(cmp_ctx)) goto err; } @@ -3047,7 +3276,7 @@ int cmp_main(int argc, char **argv) cleanse(opt_keypass); cleanse(opt_newkeypass); cleanse(opt_otherpass); -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) cleanse(opt_tls_keypass); #endif cleanse(opt_secret); @@ -3058,15 +3287,16 @@ int cmp_main(int argc, char **argv) OSSL_CMP_CTX_print_errors(cmp_ctx); if (cmp_ctx != NULL) { -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) APP_HTTP_TLS_INFO *info = OSSL_CMP_CTX_get_http_cb_arg(cmp_ctx); + (void)OSSL_CMP_CTX_set_http_cb_arg(cmp_ctx, NULL); #endif ossl_cmp_mock_srv_free(OSSL_CMP_CTX_get_transfer_cb_arg(cmp_ctx)); X509_STORE_free(OSSL_CMP_CTX_get_certConf_cb_arg(cmp_ctx)); /* cannot free info already here, as it may be used indirectly by: */ OSSL_CMP_CTX_free(cmp_ctx); -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) if (info != NULL) { OPENSSL_free((char *)info->server); OPENSSL_free((char *)info->port); diff --git a/apps/cms.c b/apps/cms.c index 0d1730c56f..9c4e4ee5e0 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -66,7 +66,7 @@ typedef enum OPTION_choice { OPT_DECRYPT, OPT_SIGN, OPT_CADES, OPT_SIGN_RECEIPT, OPT_RESIGN, OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT, OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY, - OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS, + OPT_DIGEST, OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS, OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT, OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID, @@ -106,6 +106,7 @@ const OPTIONS cms_options[] = { "Generate a signed receipt for a message"}, {"verify_receipt", OPT_VERIFY_RECEIPT, '<', "Verify receipts; exit if receipt signatures do not verify"}, + {"digest", OPT_DIGEST, 's', "Sign a pre-computed digest in hex notation"}, {"digest_create", OPT_DIGEST_CREATE, '-', "Create a CMS \"DigestedData\" object"}, {"digest_verify", OPT_DIGEST_VERIFY, '-', @@ -293,6 +294,9 @@ int cms_main(int argc, char **argv) const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL; char *certsoutfile = NULL, *digestname = NULL, *wrapname = NULL; int noCAfile = 0, noCApath = 0, noCAstore = 0; + char *digesthex = NULL; + unsigned char *digestbin = NULL; + long digestlen = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *passinarg = NULL, *passin = NULL, *signerfile = NULL; char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL; @@ -314,6 +318,7 @@ int cms_main(int argc, char **argv) if (encerts == NULL || vpm == NULL) goto end; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, cms_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -366,6 +371,9 @@ int cms_main(int argc, char **argv) case OPT_DIGEST_CREATE: operation = SMIME_DIGEST_CREATE; break; + case OPT_DIGEST: + digesthex = opt_arg(); + break; case OPT_DIGEST_VERIFY: operation = SMIME_DIGEST_VERIFY; break; @@ -697,10 +705,8 @@ int cms_main(int argc, char **argv) if (!opt_md(digestname, &sign_md)) goto end; } - if (ciphername != NULL) { - if (!opt_cipher_any(ciphername, &cipher)) - goto end; - } + if (!opt_cipher_any(ciphername, &cipher)) + goto end; if (wrapname != NULL) { if (!opt_cipher_any(wrapname, &wrap_cipher)) goto end; @@ -883,10 +889,31 @@ int cms_main(int argc, char **argv) goto end; } - in = bio_open_default(infile, 'r', - binary_files ? FORMAT_BINARY : informat); - if (in == NULL) - goto end; + if (digesthex != NULL) { + if (operation != SMIME_SIGN) { + BIO_printf(bio_err, + "Cannot use -digest for non-signing operation\n"); + goto end; + } + if (infile != NULL + || (flags & CMS_DETACHED) == 0 + || (flags & CMS_STREAM) != 0) { + BIO_printf(bio_err, + "Cannot use -digest when -in, -nodetach or streaming is used\n"); + goto end; + } + digestbin = OPENSSL_hexstr2buf(digesthex, &digestlen); + if (digestbin == NULL) { + BIO_printf(bio_err, + "Invalid hex value after -digest\n"); + goto end; + } + } else { + in = bio_open_default(infile, 'r', + binary_files ? FORMAT_BINARY : informat); + if (in == NULL) + goto end; + } if (operation & SMIME_IP) { cms = load_content_info(informat, in, flags, &indata, "SMIME"); @@ -908,7 +935,7 @@ int cms_main(int argc, char **argv) ret = 5; goto end; } - sk_X509_pop_free(allcerts, X509_free); + OSSL_STACK_OF_X509_free(allcerts); } } @@ -987,7 +1014,8 @@ int cms_main(int argc, char **argv) && wrap_cipher != NULL) { EVP_CIPHER_CTX *wctx; wctx = CMS_RecipientInfo_kari_get0_ctx(ri); - EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL); + if (EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL) != 1) + goto end; } } @@ -1035,12 +1063,12 @@ int cms_main(int argc, char **argv) } else if (operation & SMIME_SIGNERS) { int i; /* - * If detached data content we enable streaming if S/MIME output - * format. + * If detached data content and not signing pre-computed digest, we + * enable streaming if S/MIME output format. */ if (operation == SMIME_SIGN) { - if (flags & CMS_DETACHED) { + if ((flags & CMS_DETACHED) != 0 && digestbin == NULL) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } @@ -1101,7 +1129,12 @@ int cms_main(int argc, char **argv) key = NULL; } /* If not streaming or resigning finalize structure */ - if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { + if (operation == SMIME_SIGN && digestbin != NULL + && (flags & CMS_STREAM) == 0) { + /* Use pre-computed digest instead of content */ + if (!CMS_final_digest(cms, digestbin, digestlen, NULL, flags)) + goto end; + } else if (operation == SMIME_SIGN && (flags & CMS_STREAM) == 0) { if (!CMS_final(cms, in, NULL, flags)) goto end; } @@ -1236,8 +1269,8 @@ int cms_main(int argc, char **argv) end: if (ret) ERR_print_errors(bio_err); - sk_X509_pop_free(encerts, X509_free); - sk_X509_pop_free(other, X509_free); + OSSL_STACK_OF_X509_free(encerts); + OSSL_STACK_OF_X509_free(other); X509_VERIFY_PARAM_free(vpm); sk_OPENSSL_STRING_free(sksigners); sk_OPENSSL_STRING_free(skkeys); @@ -1270,6 +1303,7 @@ int cms_main(int argc, char **argv) BIO_free(in); BIO_free(indata); BIO_free_all(out); + OPENSSL_free(digestbin); OPENSSL_free(passin); NCONF_free(conf); return ret; diff --git a/apps/crl.c b/apps/crl.c index 2158a107e5..09aec81cf7 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -98,6 +98,7 @@ int crl_main(int argc, char **argv) int hash_old = 0; #endif + opt_set_unknown_name("digest"); prog = opt_init(argc, argv, crl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -209,14 +210,11 @@ int crl_main(int argc, char **argv) } /* No remaining args. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; - if (digestname != NULL) { - if (!opt_md(digestname, &digest)) - goto opthelp; - } + if (!opt_md(digestname, &digest)) + goto opthelp; x = load_crl(infile, informat, 1, "CRL"); if (x == NULL) goto end; diff --git a/apps/crl2pkcs7.c b/apps/crl2pkcs7.c index fe59e65427..681c60285f 100644 --- a/apps/crl2pkcs7.c +++ b/apps/crl2pkcs7.c @@ -104,8 +104,7 @@ int crl2pkcs7_main(int argc, char **argv) } /* No remaining args. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!nocrl) { diff --git a/apps/dgst.c b/apps/dgst.c index 3f02af0d57..28123f813f 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -117,6 +117,7 @@ int dgst_main(int argc, char **argv) if (md != NULL) digestname = argv[0]; + opt_set_unknown_name("digest"); prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -514,7 +515,7 @@ static void show_digests(const OBJ_NAME *name, void *arg) * in the '*sum' checksum programs. This aims to preserve backward * compatibility. */ -static const char *newline_escape_filename(const char *file, int * backslash) +static const char *newline_escape_filename(const char *file, int *backslash) { size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0; char *file_cpy = NULL; @@ -527,7 +528,7 @@ static const char *newline_escape_filename(const char *file, int * backslash) file_cpy = app_malloc(mem_len, file); i = 0; - while(e < length) { + while (e < length) { const char c = file[e]; if (c == '\n') { file_cpy[i++] = '\\'; diff --git a/apps/dhparam.c b/apps/dhparam.c index 754ad8a96e..ffe6e6cb88 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -31,13 +31,14 @@ #define DEFBITS 2048 static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh); -static int gendh_cb(EVP_PKEY_CTX *ctx); + +static int verbose = 1; typedef enum OPTION_choice { OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, - OPT_DSAPARAM, OPT_2, OPT_3, OPT_5, + OPT_DSAPARAM, OPT_2, OPT_3, OPT_5, OPT_VERBOSE, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -67,6 +68,8 @@ const OPTIONS dhparam_options[] = { {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"}, {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"quiet", OPT_QUIET, '-', "Terse output"}, OPT_R_OPTIONS, OPT_PROV_OPTIONS, @@ -138,6 +141,12 @@ int dhparam_main(int argc, char **argv) case OPT_NOOUT: noout = 1; break; + case OPT_VERBOSE: + verbose = 1; + break; + case OPT_QUIET: + verbose = 0; + break; case OPT_R_CASES: if (!opt_rand(o)) goto end; @@ -155,7 +164,7 @@ int dhparam_main(int argc, char **argv) if (argc == 1) { if (!opt_int(argv[0], &num) || num <= 0) goto opthelp; - } else if (argc != 0) { + } else if (!opt_check_rest_arg(NULL)) { goto opthelp; } if (!app_RAND_load()) @@ -192,11 +201,13 @@ int dhparam_main(int argc, char **argv) alg); goto end; } - EVP_PKEY_CTX_set_cb(ctx, gendh_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); - BIO_printf(bio_err, - "Generating %s parameters, %d bit long %sprime\n", - alg, num, dsaparam ? "" : "safe "); + if (verbose) { + EVP_PKEY_CTX_set_cb(ctx, progress_cb); + BIO_printf(bio_err, + "Generating %s parameters, %d bit long %sprime\n", + alg, num, dsaparam ? "" : "safe "); + } if (EVP_PKEY_paramgen_init(ctx) <= 0) { BIO_printf(bio_err, @@ -405,14 +416,3 @@ static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh) return pkey; } -static int gendh_cb(EVP_PKEY_CTX *ctx) -{ - int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - static const char symbols[] = ".+*\n"; - char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; - - BIO_write(b, &c, 1); - (void)BIO_flush(b); - return 1; -} diff --git a/apps/dsa.c b/apps/dsa.c index 51c0284353..9ba8c252da 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -92,6 +92,7 @@ int dsa_main(int argc, char **argv) int selection = 0; OSSL_ENCODER_CTX *ectx = NULL; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, dsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -161,17 +162,12 @@ int dsa_main(int argc, char **argv) } /* No extra args. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &enc)) - goto end; - } - private = pubin || pubout ? 0 : 1; - if (text && !pubin) - private = 1; + if (!opt_cipher(ciphername, &enc)) + goto end; + private = !pubin && (!pubout || text); if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); diff --git a/apps/dsaparam.c b/apps/dsaparam.c index ca91beb5b8..8bd2e1361b 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -11,7 +11,6 @@ #include #include -#include "apps.h" #include #include #include "apps.h" @@ -25,17 +24,15 @@ static int verbose = 0; -static int gendsa_cb(EVP_PKEY_CTX *ctx); - typedef enum OPTION_choice { OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, - OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE, + OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS dsaparam_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"}, + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits] [numqbits]\n"}, OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, @@ -53,13 +50,15 @@ const OPTIONS dsaparam_options[] = { {"text", OPT_TEXT, '-', "Print as text"}, {"noout", OPT_NOOUT, '-', "No output"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"quiet", OPT_QUIET, '-', "Terse output"}, {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, OPT_R_OPTIONS, OPT_PROV_OPTIONS, OPT_PARAMETERS(), - {"numbits", 0, 0, "Number of bits if generating parameters (optional)"}, + {"numbits", 0, 0, "Number of bits if generating parameters or key (optional)"}, + {"numqbits", 0, 0, "Number of bits in the subprime parameter q if generating parameters or key (optional)"}, {NULL} }; @@ -69,7 +68,7 @@ int dsaparam_main(int argc, char **argv) BIO *out = NULL; EVP_PKEY *params = NULL, *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; - int numbits = -1, num = 0, genkey = 0; + int numbits = -1, numqbits = -1, num = 0, genkey = 0; int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, noout = 0; int ret = 1, i, text = 0, private = 0; char *infile = NULL, *outfile = NULL, *prog; @@ -124,16 +123,24 @@ int dsaparam_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_QUIET: + verbose = 0; + break; } } - /* Optional arg is bitsize. */ + /* Optional args are bitsize and q bitsize. */ argc = opt_num_rest(); argv = opt_rest(); - if (argc == 1) { + if (argc == 2) { if (!opt_int(argv[0], &num) || num < 0) goto opthelp; - } else if (argc != 0) { + if (!opt_int(argv[1], &numqbits) || numqbits < 0) + goto opthelp; + } else if (argc == 1) { + if (!opt_int(argv[0], &num) || num < 0) + goto opthelp; + } else if (!opt_check_rest_arg(NULL)) { goto opthelp; } if (!app_RAND_load()) @@ -160,9 +167,9 @@ int dsaparam_main(int argc, char **argv) " Your key size is %d! Larger key size may behave not as expected.\n", OPENSSL_DSA_MAX_MODULUS_BITS, numbits); - EVP_PKEY_CTX_set_cb(ctx, gendsa_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); if (verbose) { + EVP_PKEY_CTX_set_cb(ctx, progress_cb); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); BIO_printf(bio_err, "This could take some time\n"); @@ -177,6 +184,13 @@ int dsaparam_main(int argc, char **argv) "Error, DSA key generation setting bit length failed\n"); goto end; } + if (numqbits > 0) { + if (EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, numqbits) <= 0) { + BIO_printf(bio_err, + "Error, DSA key generation setting subprime bit length failed\n"); + goto end; + } + } params = app_paramgen(ctx, "DSA"); } else { params = load_keyparams(infile, informat, 1, "DSA", "DSA parameters"); @@ -237,22 +251,3 @@ int dsaparam_main(int argc, char **argv) release_engine(e); return ret; } - -static int gendsa_cb(EVP_PKEY_CTX *ctx) -{ - static const char symbols[] = ".+*\n"; - int p; - char c; - BIO *b; - - if (!verbose) - return 1; - - b = EVP_PKEY_CTX_get_app_data(ctx); - p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; - - BIO_write(b, &c, 1); - (void)BIO_flush(b); - return 1; -} diff --git a/apps/ec.c b/apps/ec.c index e2dd6f2b48..677876ccc9 100644 --- a/apps/ec.c +++ b/apps/ec.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -80,6 +80,7 @@ int ec_main(int argc, char **argv) char *point_format = NULL; int no_public = 0; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, ec_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -157,17 +158,12 @@ int ec_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &enc)) - goto opthelp; - } - private = param_out || pubin || pubout ? 0 : 1; - if (text && !pubin) - private = 1; + if (!opt_cipher(ciphername, &enc)) + goto opthelp; + private = !pubin && (text || (!param_out && !pubout)); if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); diff --git a/apps/ecparam.c b/apps/ecparam.c index 9e9ad13683..71f93c4ca5 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -186,8 +186,7 @@ int ecparam_main(int argc, char **argv) } /* No extra args. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) @@ -243,9 +242,17 @@ int ecparam_main(int argc, char **argv) goto end; } } else { - params_key = load_keyparams(infile, informat, 1, "EC", "EC parameters"); - if (params_key == NULL || !EVP_PKEY_is_a(params_key, "EC")) + params_key = load_keyparams_suppress(infile, informat, 1, "EC", + "EC parameters", 1); + if (params_key == NULL) + params_key = load_keyparams_suppress(infile, informat, 1, "SM2", + "SM2 parameters", 1); + + if (params_key == NULL) { + BIO_printf(bio_err, "Unable to load parameters from %s\n", infile); goto end; + } + if (point_format && !EVP_PKEY_set_utf8_string_param( params_key, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, diff --git a/apps/enc.c b/apps/enc.c index c275046cf5..d94f5236d7 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -49,7 +49,7 @@ typedef enum OPTION_choice { OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A, OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE, OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER, - OPT_R_ENUM, OPT_PROV_ENUM + OPT_SALTLEN, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS enc_options[] = { @@ -100,7 +100,9 @@ const OPTIONS enc_options[] = { {OPT_MORE_STR, 0, 0, "Use -iter to change the iteration count from " STR(PBKDF2_ITER_DEFAULT)}, {"none", OPT_NONE, '-', "Don't encrypt"}, -#ifdef ZLIB + {"saltlen", OPT_SALTLEN, 'p', "Specify the PBKDF2 salt length (in bytes)"}, + {OPT_MORE_STR, 0, 0, "Default: 16"}, +#ifndef OPENSSL_NO_ZLIB {"z", OPT_Z, '-', "Compress or decompress encrypted data using zlib"}, #endif {"", OPT_CIPHER, '-', "Any supported cipher"}, @@ -132,26 +134,42 @@ int enc_main(int argc, char **argv) int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY; int ret = 1, inl, nopad = 0; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - unsigned char *buff = NULL, salt[PKCS5_SALT_LEN]; + unsigned char *buff = NULL, salt[EVP_MAX_IV_LENGTH]; + int saltlen = 0; int pbkdf2 = 0; int iter = 0; long n; + int streamable = 1; + int wrap = 0; struct doall_enc_ciphers dec; -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB int do_zlib = 0; BIO *bzl = NULL; #endif + int do_brotli = 0; + BIO *bbrot = NULL; + int do_zstd = 0; + BIO *bzstd = NULL; /* first check the command name */ if (strcmp(argv[0], "base64") == 0) base64 = 1; -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB else if (strcmp(argv[0], "zlib") == 0) do_zlib = 1; +#endif +#ifndef OPENSSL_NO_BROTLI + else if (strcmp(argv[0], "brotli") == 0) + do_brotli = 1; +#endif +#ifndef OPENSSL_NO_ZSTD + else if (strcmp(argv[0], "zstd") == 0) + do_zstd = 1; #endif else if (strcmp(argv[0], "enc") != 0) ciphername = argv[0]; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, enc_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -219,7 +237,7 @@ int enc_main(int argc, char **argv) base64 = 1; break; case OPT_Z: -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB do_zlib = 1; #endif break; @@ -278,6 +296,12 @@ int enc_main(int argc, char **argv) iter = opt_int_arg(); pbkdf2 = 1; break; + case OPT_SALTLEN: + if (!opt_int(opt_arg(), &saltlen)) + goto opthelp; + if (saltlen > (int)sizeof(salt)) + saltlen = (int)sizeof(salt); + break; case OPT_PBKDF2: pbkdf2 = 1; if (iter == 0) /* do not overwrite a chosen value */ @@ -298,16 +322,19 @@ int enc_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) goto end; + if (saltlen == 0 || pbkdf2 == 0) + saltlen = PKCS5_SALT_LEN; /* Get the cipher name, either from progname (if set) or flag. */ - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &cipher)) - goto opthelp; + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; + if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_WRAP_MODE)) { + wrap = 1; + streamable = 0; } if (digestname != NULL) { if (!opt_md(digestname, &dgst)) @@ -325,20 +352,30 @@ int enc_main(int argc, char **argv) if (verbose) BIO_printf(bio_err, "bufsize=%d\n", bsize); -#ifdef ZLIB - if (!do_zlib) +#ifndef OPENSSL_NO_ZLIB + if (do_zlib) + base64 = 0; #endif - if (base64) { - if (enc) - outformat = FORMAT_BASE64; - else - informat = FORMAT_BASE64; - } + if (do_brotli) + base64 = 0; + if (do_zstd) + base64 = 0; + + if (base64) { + if (enc) + outformat = FORMAT_BASE64; + else + informat = FORMAT_BASE64; + } strbuf = app_malloc(SIZE, "strbuf"); buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer"); if (infile == NULL) { + if (!streamable && printkey != 2) { /* if just print key and exit, it's ok */ + BIO_printf(bio_err, "Unstreamable cipher mode\n"); + goto end; + } in = dup_bio_in(informat); } else { in = bio_open_default(infile, 'r', informat); @@ -399,7 +436,8 @@ int enc_main(int argc, char **argv) rbio = in; wbio = out; -#ifdef ZLIB +#ifndef OPENSSL_NO_COMP +# ifndef OPENSSL_NO_ZLIB if (do_zlib) { if ((bzl = BIO_new(BIO_f_zlib())) == NULL) goto end; @@ -412,6 +450,33 @@ int enc_main(int argc, char **argv) else rbio = BIO_push(bzl, rbio); } +# endif + + if (do_brotli) { + if ((bbrot = BIO_new(BIO_f_brotli())) == NULL) + goto end; + if (debug) { + BIO_set_callback_ex(bbrot, BIO_debug_callback_ex); + BIO_set_callback_arg(bbrot, (char *)bio_err); + } + if (enc) + wbio = BIO_push(bbrot, wbio); + else + rbio = BIO_push(bbrot, rbio); + } + + if (do_zstd) { + if ((bzstd = BIO_new(BIO_f_zstd())) == NULL) + goto end; + if (debug) { + BIO_set_callback_ex(bzstd, BIO_debug_callback_ex); + BIO_set_callback_arg(bzstd, (char *)bio_err); + } + if (enc) + wbio = BIO_push(bzstd, wbio); + else + rbio = BIO_push(bzstd, rbio); + } #endif if (base64) { @@ -442,13 +507,13 @@ int enc_main(int argc, char **argv) if (nosalt) { sptr = NULL; } else { - if (hsalt != NULL && !set_hex(hsalt, salt, sizeof(salt))) { + if (hsalt != NULL && !set_hex(hsalt, salt, saltlen)) { BIO_printf(bio_err, "invalid hex salt value\n"); goto end; } if (enc) { /* encryption */ if (hsalt == NULL) { - if (RAND_bytes(salt, sizeof(salt)) <= 0) { + if (RAND_bytes(salt, saltlen) <= 0) { BIO_printf(bio_err, "RAND_bytes failed\n"); goto end; } @@ -461,7 +526,7 @@ int enc_main(int argc, char **argv) sizeof(magic) - 1) != sizeof(magic) - 1 || BIO_write(wbio, (char *)salt, - sizeof(salt)) != sizeof(salt))) { + saltlen) != saltlen)) { BIO_printf(bio_err, "error writing output file\n"); goto end; } @@ -474,7 +539,7 @@ int enc_main(int argc, char **argv) } if (memcmp(mbuf, magic, sizeof(mbuf)) == 0) { /* file IS salted */ if (BIO_read(rbio, salt, - sizeof(salt)) != sizeof(salt)) { + saltlen) != saltlen) { BIO_printf(bio_err, "error reading input file\n"); goto end; } @@ -496,7 +561,8 @@ int enc_main(int argc, char **argv) int iklen = EVP_CIPHER_get_key_length(cipher); int ivlen = EVP_CIPHER_get_iv_length(cipher); /* not needed if HASH_UPDATE() is fixed : */ - int islen = (sptr != NULL ? sizeof(salt) : 0); + int islen = (sptr != NULL ? saltlen : 0); + if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen, iter, dgst, iklen+ivlen, tmpkeyiv)) { BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n"); @@ -535,7 +601,8 @@ int enc_main(int argc, char **argv) } } if ((hiv == NULL) && (str == NULL) - && EVP_CIPHER_get_iv_length(cipher) != 0) { + && EVP_CIPHER_get_iv_length(cipher) != 0 + && wrap == 0) { /* * No IV was explicitly set and no IV was generated. * Hence the IV is undefined, making correct decryption impossible. @@ -562,6 +629,9 @@ int enc_main(int argc, char **argv) BIO_get_cipher_ctx(benc, &ctx); + if (wrap == 1) + EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (!EVP_CipherInit_ex(ctx, cipher, e, NULL, NULL, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_get0_name(cipher)); @@ -572,7 +642,8 @@ int enc_main(int argc, char **argv) if (nopad) EVP_CIPHER_CTX_set_padding(ctx, 0); - if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, + (hiv == NULL && wrap == 1 ? NULL : iv), enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_get0_name(cipher)); ERR_print_errors(bio_err); @@ -587,7 +658,7 @@ int enc_main(int argc, char **argv) if (printkey) { if (!nosalt) { printf("salt="); - for (i = 0; i < (int)sizeof(salt); i++) + for (i = 0; i < (int)saltlen; i++) printf("%02X", salt[i]); printf("\n"); } @@ -618,10 +689,16 @@ int enc_main(int argc, char **argv) inl = BIO_read(rbio, (char *)buff, bsize); if (inl <= 0) break; + if (!streamable && !BIO_eof(rbio)) { /* do not output data */ + BIO_printf(bio_err, "Unstreamable cipher mode\n"); + goto end; + } if (BIO_write(wbio, (char *)buff, inl) != inl) { BIO_printf(bio_err, "error writing output file\n"); goto end; } + if (!streamable) + break; } if (!BIO_flush(wbio)) { if (enc) @@ -646,9 +723,11 @@ int enc_main(int argc, char **argv) BIO_free(b64); EVP_MD_free(dgst); EVP_CIPHER_free(cipher); -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB BIO_free(bzl); #endif + BIO_free(bbrot); + BIO_free(bzstd); release_engine(e); OPENSSL_free(pass); return ret; diff --git a/apps/engine.c b/apps/engine.c index f9dce6e4b4..dc57dc7465 100644 --- a/apps/engine.c +++ b/apps/engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index e1ef645b60..6d86bb44e2 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -7,7 +7,6 @@ * https://www.openssl.org/source/license.html */ -#include #include #include #include @@ -446,9 +445,9 @@ int fipsinstall_main(int argc, char **argv) case OPT_MACOPT: if (!sk_OPENSSL_STRING_push(opts, opt_arg())) goto opthelp; - if (strncmp(opt_arg(), "hexkey:", 7) == 0) + if (HAS_PREFIX(opt_arg(), "hexkey:")) gotkey = 1; - else if (strncmp(opt_arg(), "digest:", 7) == 0) + else if (HAS_PREFIX(opt_arg(), "digest:")) gotdigest = 1; break; case OPT_VERIFY: @@ -466,9 +465,12 @@ int fipsinstall_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0 || (verify && in_fname == NULL)) + if (!opt_check_rest_arg(NULL)) goto opthelp; + if (verify && in_fname == NULL) { + BIO_printf(bio_err, "Missing -in option for -verify\n"); + goto opthelp; + } if (parent_config != NULL) { /* Test that a parent config can load the module */ diff --git a/apps/gendsa.c b/apps/gendsa.c index 8aefca6556..a655c6ea02 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -24,7 +24,7 @@ typedef enum OPTION_choice { OPT_COMMON, - OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE, + OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -44,6 +44,7 @@ const OPTIONS gendsa_options[] = { OPT_PROV_OPTIONS, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"quiet", OPT_QUIET, '-', "Terse output"}, OPT_PARAMETERS(), {"dsaparam-file", 0, 0, "File containing DSA parameters"}, @@ -62,6 +63,7 @@ int gendsa_main(int argc, char **argv) OPTION_CHOICE o; int ret = 1, private = 0, verbose = 0, nbits; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, gendsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -97,23 +99,23 @@ int gendsa_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_QUIET: + verbose = 0; + break; } } /* One argument, the params file. */ - argc = opt_num_rest(); - argv = opt_rest(); - if (argc != 1) + if (!opt_check_rest_arg("params file")) goto opthelp; + argv = opt_rest(); dsaparams = argv[0]; if (!app_RAND_load()) goto end; - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &enc)) - goto end; - } + if (!opt_cipher(ciphername, &enc)) + goto end; private = 1; if (!app_passwd(NULL, passoutarg, NULL, &passout)) { diff --git a/apps/genpkey.c b/apps/genpkey.c index 705e5c76b4..66f0e1eaf0 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -15,17 +15,15 @@ #include #include -static int quiet; +static int verbose = 1; static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e, OSSL_LIB_CTX *libctx, const char *propq); -static int genpkey_cb(EVP_PKEY_CTX *ctx); - typedef enum OPTION_choice { OPT_COMMON, OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER, - OPT_QUIET, OPT_CONFIG, + OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY, OPT_PROV_ENUM } OPTION_CHOICE; @@ -37,17 +35,19 @@ const OPTIONS genpkey_options[] = { #endif {"paramfile", OPT_PARAMFILE, '<', "Parameters file"}, {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, + {"verbose", OPT_VERBOSE, '-', "Output status while generating keys"}, {"quiet", OPT_QUIET, '-', "Do not output status while generating keys"}, {"pkeyopt", OPT_PKEYOPT, 's', "Set the public key algorithm option as opt:value"}, OPT_CONFIG_OPTION, OPT_SECTION("Output"), - {"out", OPT_OUT, '>', "Output file"}, + {"out", OPT_OUT, '>', "Output (private key) file"}, + {"outpubkey", OPT_OUTPUBKEY, '>', "Output public key file"}, {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, {"pass", OPT_PASS, 's', "Output file pass phrase source"}, {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, - {"text", OPT_TEXT, '-', "Print the in text"}, + {"text", OPT_TEXT, '-', "Print the private key in text"}, {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, OPT_PROV_OPTIONS, @@ -58,14 +58,59 @@ const OPTIONS genpkey_options[] = { {NULL} }; +static const char *param_datatype_2name(unsigned int type, int *ishex) +{ + *ishex = 0; + + switch (type) { + case OSSL_PARAM_INTEGER: return "int"; + case OSSL_PARAM_UNSIGNED_INTEGER: return "uint"; + case OSSL_PARAM_REAL: return "float"; + case OSSL_PARAM_OCTET_STRING: *ishex = 1; return "string"; + case OSSL_PARAM_UTF8_STRING: return "string"; + default: + return NULL; + } +} + +static void show_gen_pkeyopt(const char *algname, OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY_CTX *ctx = NULL; + const OSSL_PARAM *params; + int i, ishex = 0; + + if (algname == NULL) + return; + ctx = EVP_PKEY_CTX_new_from_name(libctx, algname, propq); + if (ctx == NULL) + return; + + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto cleanup; + params = EVP_PKEY_CTX_settable_params(ctx); + if (params == NULL) + goto cleanup; + + BIO_printf(bio_err, "\nThe possible -pkeyopt arguments are:\n"); + for (i = 0; params[i].key != NULL; ++i) { + const char *name = param_datatype_2name(params[i].data_type, &ishex); + + if (name != NULL) + BIO_printf(bio_err, " %s%s:%s\n", ishex ? "hex" : "", params[i].key, name); + } +cleanup: + EVP_PKEY_CTX_free(ctx); +} + int genpkey_main(int argc, char **argv) { CONF *conf = NULL; - BIO *in = NULL, *out = NULL; + BIO *in = NULL, *out = NULL, *outpubkey = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog, *p; + char *outpubkeyfile = NULL; const char *ciphername = NULL, *paramfile = NULL, *algname = NULL; EVP_CIPHER *cipher = NULL; OPTION_CHOICE o; @@ -74,6 +119,7 @@ int genpkey_main(int argc, char **argv) OSSL_LIB_CTX *libctx = app_get0_libctx(); STACK_OF(OPENSSL_STRING) *keyopt = NULL; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, genpkey_options); keyopt = sk_OPENSSL_STRING_new_null(); if (keyopt == NULL) @@ -88,6 +134,7 @@ int genpkey_main(int argc, char **argv) case OPT_HELP: ret = 0; opt_help(genpkey_options); + show_gen_pkeyopt(algname, libctx, app_get0_propq()); goto end; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) @@ -96,6 +143,9 @@ int genpkey_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; + case OPT_OUTPUBKEY: + outpubkeyfile = opt_arg(); + break; case OPT_PASS: passarg = opt_arg(); break; @@ -115,7 +165,10 @@ int genpkey_main(int argc, char **argv) goto end; break; case OPT_QUIET: - quiet = 1; + verbose = 0; + break; + case OPT_VERBOSE: + verbose = 1; break; case OPT_GENPARAM: do_param = 1; @@ -139,8 +192,7 @@ int genpkey_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; /* Fetch cipher, etc. */ @@ -163,9 +215,12 @@ int genpkey_main(int argc, char **argv) goto end; } } - if (ciphername != NULL) - if (!opt_cipher(ciphername, &cipher) || do_param == 1) - goto opthelp; + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; + if (ciphername != NULL && do_param == 1) { + BIO_printf(bio_err, "Cannot use cipher with -genparam option\n"); + goto opthelp; + } private = do_param ? 0 : 1; @@ -178,7 +233,14 @@ int genpkey_main(int argc, char **argv) if (out == NULL) goto end; - EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); + if (outpubkeyfile != NULL) { + outpubkey = bio_open_owner(outpubkeyfile, outformat, private); + if (outpubkey == NULL) + goto end; + } + + if (verbose) + EVP_PKEY_CTX_set_cb(ctx, progress_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); pkey = do_param ? app_paramgen(ctx, algname) @@ -191,9 +253,13 @@ int genpkey_main(int argc, char **argv) } else if (outformat == FORMAT_PEM) { assert(private); rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); + if (rv > 0 && outpubkey != NULL) + rv = PEM_write_bio_PUBKEY(outpubkey, pkey); } else if (outformat == FORMAT_ASN1) { assert(private); rv = i2d_PrivateKey_bio(out, pkey); + if (rv > 0 && outpubkey != NULL) + rv = i2d_PUBKEY_bio(outpubkey, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; @@ -202,7 +268,7 @@ int genpkey_main(int argc, char **argv) ret = 0; if (rv <= 0) { - BIO_puts(bio_err, "Error writing key\n"); + BIO_puts(bio_err, "Error writing key(s)\n"); ret = 1; } @@ -226,6 +292,7 @@ int genpkey_main(int argc, char **argv) EVP_PKEY_CTX_free(ctx); EVP_CIPHER_free(cipher); BIO_free_all(out); + BIO_free_all(outpubkey); BIO_free(in); release_engine(e); OPENSSL_free(pass); @@ -318,27 +385,3 @@ int init_gen_str(EVP_PKEY_CTX **pctx, } -static int genpkey_cb(EVP_PKEY_CTX *ctx) -{ - char c = '*'; - BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - - if (quiet) - return 1; - - switch (EVP_PKEY_CTX_get_keygen_info(ctx, 0)) { - case 0: - c = '.'; - break; - case 1: - c = '+'; - break; - case 3: - c = '\n'; - break; - } - - BIO_write(b, &c, 1); - (void)BIO_flush(b); - return 1; -} diff --git a/apps/genrsa.c b/apps/genrsa.c index 6a683517a1..54d025e24c 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -29,15 +29,13 @@ static int verbose = 0; -static int genrsa_cb(EVP_PKEY_CTX *ctx); - typedef enum OPTION_choice { OPT_COMMON, #ifndef OPENSSL_NO_DEPRECATED_3_0 OPT_3, #endif OPT_F4, OPT_ENGINE, - OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, + OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM, OPT_TRADITIONAL } OPTION_CHOICE; @@ -62,6 +60,7 @@ const OPTIONS genrsa_options[] = { {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"quiet", OPT_QUIET, '-', "Terse output"}, {"traditional", OPT_TRADITIONAL, '-', "Use traditional format for private keys"}, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, @@ -93,6 +92,7 @@ int genrsa_main(int argc, char **argv) if (bn == NULL || cb == NULL) goto end; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, genrsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -139,6 +139,9 @@ int genrsa_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_QUIET: + verbose = 0; + break; case OPT_TRADITIONAL: traditional = 1; break; @@ -157,8 +160,7 @@ int genrsa_main(int argc, char **argv) "Warning: It is not recommended to use more than %d bit for RSA keys.\n" " Your key size is %d! Larger key size may behave not as expected.\n", OPENSSL_RSA_MAX_MODULUS_BITS, num); - } else if (argc > 0) { - BIO_printf(bio_err, "Extra arguments given.\n"); + } else if (!opt_check_rest_arg(NULL)) { goto opthelp; } @@ -166,10 +168,8 @@ int genrsa_main(int argc, char **argv) goto end; private = 1; - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &enc)) - goto end; - } + if (!opt_cipher(ciphername, &enc)) + goto end; if (!app_passwd(NULL, passoutarg, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto end; @@ -183,7 +183,8 @@ int genrsa_main(int argc, char **argv) app_get0_propq())) goto end; - EVP_PKEY_CTX_set_cb(ctx, genrsa_cb); + if (verbose) + EVP_PKEY_CTX_set_cb(ctx, progress_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, num) <= 0) { @@ -248,24 +249,3 @@ int genrsa_main(int argc, char **argv) return ret; } -static int genrsa_cb(EVP_PKEY_CTX *ctx) -{ - char c = '*'; - BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - - if (!verbose) - return 1; - - if (p == 0) - c = '.'; - if (p == 1) - c = '+'; - if (p == 2) - c = '*'; - if (p == 3) - c = '\n'; - BIO_write(b, &c, 1); - (void)BIO_flush(b); - return 1; -} diff --git a/apps/include/apps.h b/apps/include/apps.h index 8b96fa7235..a1b2cbbdc3 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,9 @@ # define OSSL_APPS_H # include "internal/e_os.h" /* struct timeval for DTLS */ +# include "internal/common.h" /* for HAS_PREFIX */ # include "internal/nelem.h" # include "internal/sockets.h" /* for openssl_fdset() */ -# include "internal/cryptlib.h" /* ossl_assert() */ # include # include @@ -65,9 +65,12 @@ BIO *dup_bio_err(int format); BIO *bio_open_owner(const char *filename, int format, int private); BIO *bio_open_default(const char *filename, char mode, int format); BIO *bio_open_default_quiet(const char *filename, char mode, int format); +char *app_conf_try_string(const CONF *cnf, const char *group, const char *name); +int app_conf_try_number(const CONF *conf, const char *group, const char *name, + long *result); CONF *app_load_config_bio(BIO *in, const char *filename); -#define app_load_config(filename) app_load_config_internal(filename, 0) -#define app_load_config_quiet(filename) app_load_config_internal(filename, 1) +# define app_load_config(filename) app_load_config_internal(filename, 0) +# define app_load_config_quiet(filename) app_load_config_internal(filename, 1) CONF *app_load_config_internal(const char *filename, int quiet); CONF *app_load_config_verbose(const char *filename, int verbose); int app_load_modules(const CONF *config); @@ -94,10 +97,13 @@ typedef struct args_st { /* We need both wrap and the "real" function because libcrypto uses both. */ int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); +/* progress callback for dsaparam, dhparam, req, genpkey, etc. */ +int progress_cb(EVP_PKEY_CTX *ctx); + int chopup_args(ARGS *arg, char *buf); void dump_cert_text(BIO *out, X509 *x); void print_name(BIO *out, const char *title, const X509_NAME *nm); -void print_bignum_var(BIO *, const BIGNUM *, const char*, +void print_bignum_var(BIO *, const BIGNUM *, const char *, int, unsigned char *); void print_array(BIO *, const char *, int, const unsigned char *); int set_nameopt(const char *arg); @@ -111,15 +117,18 @@ char *get_passwd(const char *pass, const char *desc); int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2); int add_oid_section(CONF *conf); X509_REQ *load_csr(const char *file, int format, const char *desc); +X509_REQ *load_csr_autofmt(const char *infile, int format, + STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc); X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, const char *pass, const char *desc); -#define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc) +# define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc) X509_CRL *load_crl(const char *uri, int format, int maybe_stdin, const char *desc); void cleanse(char *str); void clear_free(char *str); EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *desc); +/* first try reading public key, on failure resort to loading private key */ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *desc); EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin, @@ -141,15 +150,11 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs, int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, const char *pass, const char *desc); int load_key_certs_crls(const char *uri, int format, int maybe_stdin, - const char *pass, const char *desc, + const char *pass, const char *desc, int quiet, EVP_PKEY **ppkey, EVP_PKEY **ppubkey, EVP_PKEY **pparams, X509 **pcert, STACK_OF(X509) **pcerts, X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls); -int load_key_cert_crl(const char *uri, int format, int maybe_stdin, - const char *pass, const char *desc, - EVP_PKEY **ppkey, EVP_PKEY **ppubkey, - X509 **pcert, X509_CRL **pcrl); X509_STORE *setup_verify(const char *CAfile, int noCAfile, const char *CApath, int noCApath, const char *CAstore, int noCAstore); @@ -195,10 +200,9 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, # define DB_type 0 # define DB_exp_date 1 # define DB_rev_date 2 -# define DB_serial 3 /* index - unique */ +# define DB_serial 3 /* index - unique */ # define DB_file 4 -# define DB_name 5 /* index - unique when active and not - * disabled */ +# define DB_name 5 /* index - unique when active and not disabled */ # define DB_NUMBER 6 # define DB_TYPE_REV 'R' /* Revoked */ @@ -218,6 +222,8 @@ typedef struct ca_db_st { # endif } CA_DB; +extern int do_updatedb(CA_DB *db, time_t *now); + void app_bail_out(char *fmt, ...); void *app_malloc(size_t sz, const char *what); @@ -237,8 +243,8 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix); void free_index(CA_DB *db); # define index_name_cmp_noconst(a, b) \ - index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ - (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) + index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ + (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); int parse_yesno(const char *str, int def); @@ -252,7 +258,8 @@ int x509_req_ctrl_string(X509_REQ *x, const char *value); int init_gen_str(EVP_PKEY_CTX **pctx, const char *algname, ENGINE *e, int do_param, OSSL_LIB_CTX *libctx, const char *propq); -int do_X509_sign(X509 *x, EVP_PKEY *pkey, const char *md, +int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey); +int do_X509_sign(X509 *x, int force_v1, EVP_PKEY *pkey, const char *md, STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx); int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts); int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md, @@ -264,12 +271,11 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md, extern char *psk_key; - unsigned char *next_protos_parse(size_t *outlen, const char *in); -void print_cert_checks(BIO *bio, X509 *x, - const char *checkhost, - const char *checkemail, const char *checkip); +int check_cert_attributes(BIO *bio, X509 *x, + const char *checkhost, const char *checkemail, + const char *checkip, int print); void store_setup_crl_download(X509_STORE *st); @@ -303,16 +309,16 @@ ASN1_VALUE *app_http_post_asn1(const char *host, const char *port, # define EXT_COPY_ADD 1 # define EXT_COPY_ALL 2 -# define NETSCAPE_CERT_HDR "certificate" +# define NETSCAPE_CERT_HDR "certificate" -# define APP_PASS_LEN 1024 +# define APP_PASS_LEN 1024 /* * IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits * so that the first bit will never be one, so that the DER encoding * rules won't force a leading octet. */ -# define SERIAL_RAND_BITS 159 +# define SERIAL_RAND_BITS 159 int app_isdir(const char *); int app_access(const char *, int flag); diff --git a/apps/include/cmp_mock_srv.h b/apps/include/cmp_mock_srv.h index 18c141c563..fcc1ef7bb4 100644 --- a/apps/include/cmp_mock_srv.h +++ b/apps/include/cmp_mock_srv.h @@ -20,11 +20,15 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq); void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx); +int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *chain); int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *caPubs); +int ossl_cmp_mock_srv_set1_newWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_newWithOld(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); +int ossl_cmp_mock_srv_set1_oldWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, int fail_info, const char *text); int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype); diff --git a/apps/include/engine_loader.h b/apps/include/engine_loader.h index fa80fc9656..30fdb9e551 100644 --- a/apps/include/engine_loader.h +++ b/apps/include/engine_loader.h @@ -13,7 +13,7 @@ /* this is a private URI scheme */ # define ENGINE_SCHEME "org.openssl.engine" -# define ENGINE_SCHEME_COLON (ENGINE_SCHEME ":") +# define ENGINE_SCHEME_COLON ENGINE_SCHEME ":" int setup_engine_loader(void); void destroy_engine_loader(void); diff --git a/apps/include/function.h b/apps/include/function.h index c45a8f21f1..e796ff4045 100644 --- a/apps/include/function.h +++ b/apps/include/function.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/include/http_server.h b/apps/include/http_server.h index 3a259038b0..4811e6be40 100644 --- a/apps/include/http_server.h +++ b/apps/include/http_server.h @@ -11,6 +11,7 @@ # define OSSL_HTTP_SERVER_H # include "apps.h" +# include "log.h" # ifndef HAVE_FORK # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) @@ -31,37 +32,19 @@ # define HTTP_DAEMON # include # include -# include # include # define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */ -# else -# undef LOG_DEBUG -# undef LOG_INFO -# undef LOG_WARNING -# undef LOG_ERR -# define LOG_DEBUG 7 -# define LOG_INFO 6 -# define LOG_WARNING 4 -# define LOG_ERR 3 # endif -/*- - * Log a message to syslog if multi-threaded HTTP_DAEMON, else to bio_err - * prog: the name of the current app - * level: the severity of the message, e.g., LOG_ERR - * fmt: message with potential extra parameters like with printf() - * returns nothing - */ -void log_message(const char *prog, int level, const char *fmt, ...); - # ifndef OPENSSL_NO_SOCK /*- - * Initialize an HTTP server by setting up its listening BIO + * Initialize an HTTP server, setting up its listening BIO * prog: the name of the current app * port: the port to listen on + * verbosity: the level of verbosity to use, or -1 for default: LOG_INFO * returns a BIO for accepting requests, NULL on error */ -BIO *http_server_init_bio(const char *prog, const char *port); +BIO *http_server_init(const char *prog, const char *port, int verbosity); /*- * Accept an ASN.1-formatted HTTP request @@ -72,7 +55,6 @@ BIO *http_server_init_bio(const char *prog, const char *port); * acbio: the listening bio (typically as returned by http_server_init_bio()) * found_keep_alive: for returning flag if client requests persistent connection * prog: the name of the current app, for diagnostics only - * port: the local port listening to, for diagnostics only * accept_get: whether to accept GET requests (in addition to POST requests) * timeout: connection timeout (in seconds), or 0 for none/infinite * returns 0 in case caller should retry, then *preq == *ppath == *pcbio == NULL @@ -86,11 +68,11 @@ BIO *http_server_init_bio(const char *prog, const char *port); int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, char **ppath, BIO **pcbio, BIO *acbio, int *found_keep_alive, - const char *prog, const char *port, - int accept_get, int timeout); + const char *prog, int accept_get, int timeout); /*- * Send an ASN.1-formatted HTTP response + * prog: the name of the current app, for diagnostics only * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) * note: cbio should not do an encoding that changes the output length * keep_alive: grant persistent connection @@ -99,23 +81,25 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, * resp: the response to send * returns 1 on success, 0 on failure */ -int http_server_send_asn1_resp(BIO *cbio, int keep_alive, +int http_server_send_asn1_resp(const char *prog, BIO *cbio, int keep_alive, const char *content_type, const ASN1_ITEM *it, const ASN1_VALUE *resp); /*- * Send a trivial HTTP response, typically to report an error or OK + * prog: the name of the current app, for diagnostics only * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) * status: the status code to send * reason: the corresponding human-readable string * returns 1 on success, 0 on failure */ -int http_server_send_status(BIO *cbio, int status, const char *reason); +int http_server_send_status(const char *prog, BIO *cbio, + int status, const char *reason); # endif # ifdef HTTP_DAEMON -extern int multi; +extern int n_responders; extern int acfd; void socket_timeout(int signum); diff --git a/apps/include/log.h b/apps/include/log.h new file mode 100644 index 0000000000..1b8b58d41a --- /dev/null +++ b/apps/include/log.h @@ -0,0 +1,50 @@ +/* + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_APPS_LOG_H +# define OSSL_APPS_LOG_H + +# include +# if !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS) \ + && !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_POSIX_IO) +# include +# else +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 +# endif + +# undef LOG_TRACE +# define LOG_TRACE (LOG_DEBUG + 1) + +int log_set_verbosity(const char *prog, int level); +int log_get_verbosity(void); + +/*- + * Output a message using the trace API with the given category + * if the category is >= 0 and tracing is enabled. + * Log the message to syslog if multi-threaded HTTP_DAEMON, else to bio_err + * if the verbosity is sufficient for the given level of severity. + * Yet cannot do both types of output in strict ANSI mode. + * category: trace category as defined in trace.h, or -1 + * prog: the name of the current app, or NULL + * level: the severity of the message, e.g., LOG_ERR + * fmt: message format, which should not include a trailing newline + * ...: potential extra parameters like with printf() + * returns nothing + */ +void trace_log_message(int category, + const char *prog, int level, const char *fmt, ...); + +#endif /* OSSL_APPS_LOG_H */ diff --git a/apps/include/opt.h b/apps/include/opt.h index 4f83a0ed53..5a2faa150b 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -163,7 +163,11 @@ OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \ OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \ OPT_S_MINPROTO, OPT_S_MAXPROTO, \ - OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, OPT_S__LAST + OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, \ + OPT_S_NO_EMS, \ + OPT_S_NO_TX_CERT_COMP, \ + OPT_S_NO_RX_CERT_COMP, \ + OPT_S__LAST # define OPT_S_OPTIONS \ OPT_SECTION("TLS/SSL"), \ @@ -175,6 +179,8 @@ {"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \ {"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \ {"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \ + {"no_tx_cert_comp", OPT_S_NO_TX_CERT_COMP, '-', "Disable sending TLSv1.3 compressed certificates" }, \ + {"no_rx_cert_comp", OPT_S_NO_RX_CERT_COMP, '-', "Disable receiving TLSv1.3 compressed certificates" }, \ {"no_ticket", OPT_S_NOTICKET, '-', \ "Disable use of TLS session tickets"}, \ {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \ @@ -218,7 +224,9 @@ {"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \ "Disable TLSv1.3 middlebox compat mode" }, \ {"no_etm", OPT_S_NO_ETM, '-', \ - "Disable Encrypt-then-Mac extension"} + "Disable Encrypt-then-Mac extension"}, \ + {"no_ems", OPT_S_NO_EMS, '-', \ + "Disable Extended master secret extension"} # define OPT_S_CASES \ OPT_S__FIRST: case OPT_S__LAST: break; \ @@ -230,6 +238,8 @@ case OPT_S_BUGS: \ case OPT_S_NO_COMP: \ case OPT_S_COMP: \ + case OPT_S_NO_TX_CERT_COMP: \ + case OPT_S_NO_RX_CERT_COMP: \ case OPT_S_NOTICKET: \ case OPT_S_SERVERPREF: \ case OPT_S_LEGACYRENEG: \ @@ -253,7 +263,8 @@ case OPT_S_MAXPROTO: \ case OPT_S_DEBUGBROKE: \ case OPT_S_NO_MIDDLEBOX: \ - case OPT_S_NO_ETM + case OPT_S_NO_ETM: \ + case OPT_S_NO_EMS #define IS_NO_PROT_FLAG(o) \ (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \ @@ -308,11 +319,28 @@ extern const char OPT_PARAM_STR[]; typedef struct options_st { const char *name; int retval; - /* - * value type: - no value (also the value zero), n number, p positive - * number, u unsigned, l long, s string, < input file, > output file, - * f any format, F der/pem format, E der/pem/engine format identifier. - * l, n and u include zero; p does not. + /*- + * value type: + * + * '-' no value (also the value zero) + * 'n' number (type 'int') + * 'p' positive number (type 'int') + * 'u' unsigned number (type 'unsigned long') + * 'l' number (type 'unsigned long') + * 'M' number (type 'intmax_t') + * 'U' unsigned number (type 'uintmax_t') + * 's' string + * '<' input file + * '>' output file + * '/' directory + * 'f' any format [OPT_FMT_ANY] + * 'F' der/pem format [OPT_FMT_PEMDER] + * 'A' any ASN1, der/pem/b64 format [OPT_FMT_ASN1] + * 'E' der/pem/engine format [OPT_FMT_PDE] + * 'c' pem/der/smime format [OPT_FMT_PDS] + * + * The 'l', 'n' and 'u' value types include the values zero, + * the 'p' value type does not. */ int valtype; const char *helpstr; @@ -332,46 +360,54 @@ typedef struct string_int_pair_st { } OPT_PAIR, STRINT_PAIR; /* Flags to pass into opt_format; see FORMAT_xxx, below. */ -# define OPT_FMT_PEMDER (1L << 1) -# define OPT_FMT_PKCS12 (1L << 2) -# define OPT_FMT_SMIME (1L << 3) -# define OPT_FMT_ENGINE (1L << 4) -# define OPT_FMT_MSBLOB (1L << 5) -/* (1L << 6) was OPT_FMT_NETSCAPE, but wasn't used */ -# define OPT_FMT_NSS (1L << 7) -# define OPT_FMT_TEXT (1L << 8) -# define OPT_FMT_HTTP (1L << 9) -# define OPT_FMT_PVK (1L << 10) +# define OPT_FMT_PEM (1L << 1) +# define OPT_FMT_DER (1L << 2) +# define OPT_FMT_B64 (1L << 3) +# define OPT_FMT_PKCS12 (1L << 4) +# define OPT_FMT_SMIME (1L << 5) +# define OPT_FMT_ENGINE (1L << 6) +# define OPT_FMT_MSBLOB (1L << 7) +# define OPT_FMT_NSS (1L << 8) +# define OPT_FMT_TEXT (1L << 9) +# define OPT_FMT_HTTP (1L << 10) +# define OPT_FMT_PVK (1L << 11) + +# define OPT_FMT_PEMDER (OPT_FMT_PEM | OPT_FMT_DER) +# define OPT_FMT_ASN1 (OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64) # define OPT_FMT_PDE (OPT_FMT_PEMDER | OPT_FMT_ENGINE) # define OPT_FMT_PDS (OPT_FMT_PEMDER | OPT_FMT_SMIME) # define OPT_FMT_ANY ( \ - OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \ - OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ - OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) + OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64 | \ + OPT_FMT_PKCS12 | OPT_FMT_SMIME | \ + OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ + OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) /* Divide options into sections when displaying usage */ #define OPT_SECTION(sec) { OPT_SECTION_STR, 1, '-', sec " options:\n" } #define OPT_PARAMETERS() { OPT_PARAM_STR, 1, '-', "Parameters:\n" } const char *opt_path_end(const char *filename); -char *opt_init(int ac, char **av, const OPTIONS * o); +char *opt_init(int ac, char **av, const OPTIONS *o); char *opt_progname(const char *argv0); char *opt_appname(const char *argv0); char *opt_getprog(void); -void opt_help(const OPTIONS * list); +void opt_help(const OPTIONS *list); void opt_begin(void); int opt_next(void); char *opt_flag(void); char *opt_arg(void); char *opt_unknown(void); +void reset_unknown(void); int opt_cipher(const char *name, EVP_CIPHER **cipherp); int opt_cipher_any(const char *name, EVP_CIPHER **cipherp); int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp); +int opt_check_md(const char *name); int opt_md(const char *name, EVP_MD **mdp); int opt_md_silent(const char *name, EVP_MD **mdp); int opt_int(const char *arg, int *result); +void opt_set_unknown_name(const char *name); int opt_int_arg(void); int opt_long(const char *arg, long *result); int opt_ulong(const char *arg, unsigned long *result); @@ -383,7 +419,7 @@ int opt_format(const char *s, unsigned long flags, int *result); void print_format_error(int format, unsigned long flags); int opt_printf_stderr(const char *fmt, ...); int opt_string(const char *name, const char **options); -int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); +int opt_pair(const char *arg, const OPT_PAIR *pairs, int *result); int opt_verify(int i, X509_VERIFY_PARAM *vpm); int opt_rand(int i); @@ -392,6 +428,7 @@ int opt_provider_option_given(void); char **opt_rest(void); int opt_num_rest(void); +int opt_check_rest_arg(const char *expected); /* Returns non-zero if legacy paths are still available */ int opt_legacy_okay(void); diff --git a/apps/include/s_apps.h b/apps/include/s_apps.h index a86106ce29..33c3b6278c 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,11 +19,12 @@ (SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION)) typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context); +void get_sock_info_address(int asock, char **hostname, char **service); int report_server_accept(BIO *out, int asock, int with_address, int with_pid); int do_server(int *accept_sock, const char *host, const char *port, int family, int type, int protocol, do_server_cb cb, - unsigned char *context, int naccept, BIO *bio_s_out); - + unsigned char *context, int naccept, BIO *bio_s_out, + int tfo); int verify_callback(int ok, X509_STORE_CTX *ctx); int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); @@ -35,7 +36,8 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared); int ssl_print_tmp_key(BIO *out, SSL *s); int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, - int family, int type, int protocol); + int family, int type, int protocol, int tfo, int doconn, + BIO_ADDR **ba_ret); int should_retry(int i); void do_ssl_shutdown(SSL *ssl); diff --git a/apps/info.c b/apps/info.c index c68603652f..befc62dac1 100644 --- a/apps/info.c +++ b/apps/info.c @@ -86,7 +86,7 @@ int info_main(int argc, char **argv) break; } } - if (opt_num_rest() != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (dirty > 1) { BIO_printf(bio_err, "%s: Only one item allowed\n", prog); diff --git a/apps/lib/app_libctx.c b/apps/lib/app_libctx.c index 4b9ec40e85..2f68cb0a75 100644 --- a/apps/lib/app_libctx.c +++ b/apps/lib/app_libctx.c @@ -36,7 +36,7 @@ OSSL_LIB_CTX *app_create_libctx(void) */ if (app_libctx == NULL) { if (!app_provider_load(NULL, "null")) { - opt_printf_stderr( "Failed to create null provider\n"); + opt_printf_stderr("Failed to create null provider\n"); return NULL; } app_libctx = OSSL_LIB_CTX_new(); diff --git a/apps/lib/app_rand.c b/apps/lib/app_rand.c index 713792ead4..9ca6056563 100644 --- a/apps/lib/app_rand.c +++ b/apps/lib/app_rand.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,12 +18,10 @@ static STACK_OF(OPENSSL_STRING) *randfiles; void app_RAND_load_conf(CONF *c, const char *section) { - const char *randfile = NCONF_get_string(c, section, "RANDFILE"); + const char *randfile = app_conf_try_string(c, section, "RANDFILE"); - if (randfile == NULL) { - ERR_clear_error(); + if (randfile == NULL) return; - } if (RAND_load_file(randfile, -1) < 0) { BIO_printf(bio_err, "Can't load %s into RNG\n", randfile); ERR_print_errors(bio_err); @@ -43,7 +41,7 @@ static int loadfiles(char *name) char *p; int last, ret = 1; - for ( ; ; ) { + for (;;) { last = 0; for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++) continue; diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 1554364aac..47d994b9c2 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -50,7 +50,7 @@ #ifdef _WIN32 static int WIN32_rename(const char *from, const char *to); -# define rename(from,to) WIN32_rename((from),(to)) +# define rename(from, to) WIN32_rename((from), (to)) #endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) @@ -75,9 +75,9 @@ typedef struct { } NAME_EX_TBL; static int set_table_opts(unsigned long *flags, const char *arg, - const NAME_EX_TBL * in_tbl); + const NAME_EX_TBL *in_tbl); static int set_multi_opts(unsigned long *flags, const char *arg, - const NAME_EX_TBL * in_tbl); + const NAME_EX_TBL *in_tbl); int app_init(long mesgwin); int chopup_args(ARGS *arg, char *buf) @@ -101,6 +101,7 @@ int chopup_args(ARGS *arg, char *buf) /* The start of something good :-) */ if (arg->argc >= arg->size) { char **tmp; + arg->size += 20; tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size); if (tmp == NULL) @@ -187,7 +188,8 @@ int set_nameopt(const char *arg) unsigned long get_nameopt(void) { - return (nmflag_set) ? nmflag : XN_FLAG_ONELINE; + return + nmflag_set ? nmflag : XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_UTF8_CONVERT; } void dump_cert_text(BIO *out, X509 *x) @@ -201,7 +203,6 @@ int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata) return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata); } - static char *app_get_pass(const char *arg, int keepbio); char *get_passwd(const char *pass, const char *desc) @@ -217,7 +218,8 @@ char *get_passwd(const char *pass, const char *desc) "Trying plain input string (better precede with 'pass:')\n"); result = OPENSSL_strdup(pass); if (result == NULL) - BIO_printf(bio_err, "Out of memory getting password for %s\n", desc); + BIO_printf(bio_err, + "Out of memory getting password for %s\n", desc); } return result; } @@ -250,21 +252,21 @@ static char *app_get_pass(const char *arg, int keepbio) int i; /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */ - if (strncmp(arg, "pass:", 5) == 0) - return OPENSSL_strdup(arg + 5); - if (strncmp(arg, "env:", 4) == 0) { - tmp = getenv(arg + 4); + if (CHECK_AND_SKIP_PREFIX(arg, "pass:")) + return OPENSSL_strdup(arg); + if (CHECK_AND_SKIP_PREFIX(arg, "env:")) { + tmp = getenv(arg); if (tmp == NULL) { - BIO_printf(bio_err, "No environment variable %s\n", arg + 4); + BIO_printf(bio_err, "No environment variable %s\n", arg); return NULL; } return OPENSSL_strdup(tmp); } if (!keepbio || pwdbio == NULL) { - if (strncmp(arg, "file:", 5) == 0) { - pwdbio = BIO_new_file(arg + 5, "r"); + if (CHECK_AND_SKIP_PREFIX(arg, "file:")) { + pwdbio = BIO_new_file(arg, "r"); if (pwdbio == NULL) { - BIO_printf(bio_err, "Can't open file %s\n", arg + 5); + BIO_printf(bio_err, "Can't open file %s\n", arg); return NULL; } #if !defined(_WIN32) @@ -276,13 +278,14 @@ static char *app_get_pass(const char *arg, int keepbio) * on real Windows descriptors, such as those obtained * with CreateFile. */ - } else if (strncmp(arg, "fd:", 3) == 0) { + } else if (CHECK_AND_SKIP_PREFIX(arg, "fd:")) { BIO *btmp; - i = atoi(arg + 3); + + i = atoi(arg); if (i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); if ((i < 0) || pwdbio == NULL) { - BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3); + BIO_printf(bio_err, "Can't access file descriptor %s\n", arg); return NULL; } /* @@ -333,6 +336,33 @@ static char *app_get_pass(const char *arg, int keepbio) return OPENSSL_strdup(tpass); } +char *app_conf_try_string(const CONF *conf, const char *group, const char *name) +{ + char *res; + + ERR_set_mark(); + res = NCONF_get_string(conf, group, name); + if (res == NULL) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); + return res; +} + +int app_conf_try_number(const CONF *conf, const char *group, const char *name, + long *result) +{ + int ok; + + ERR_set_mark(); + ok = NCONF_get_number(conf, group, name, result); + if (!ok) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); + return ok; +} + CONF *app_load_config_bio(BIO *in, const char *filename) { long errorline = -1; @@ -413,10 +443,8 @@ int add_oid_section(CONF *conf) CONF_VALUE *cnf; int i; - if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) { - ERR_clear_error(); + if ((p = app_conf_try_string(conf, NULL, "oid_section")) == NULL) return 1; - } if ((sktmp = NCONF_get_section(conf, p)) == NULL) { BIO_printf(bio_err, "problem loading oid section %s\n", p); return 0; @@ -447,10 +475,8 @@ CONF *app_load_config_modules(const char *configfile) return conf; } -#define IS_HTTP(uri) ((uri) != NULL \ - && strncmp(uri, OSSL_HTTP_PREFIX, strlen(OSSL_HTTP_PREFIX)) == 0) -#define IS_HTTPS(uri) ((uri) != NULL \ - && strncmp(uri, OSSL_HTTPS_PREFIX, strlen(OSSL_HTTPS_PREFIX)) == 0) +#define IS_HTTP(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTP_PREFIX)) +#define IS_HTTPS(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTPS_PREFIX)) X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, const char *pass, const char *desc) @@ -468,7 +494,7 @@ X509 *load_cert_pass(const char *uri, int format, int maybe_stdin, BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri); } } else { - (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, + (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0, NULL, NULL, NULL, &cert, NULL, NULL, NULL); } return cert; @@ -490,12 +516,13 @@ X509_CRL *load_crl(const char *uri, int format, int maybe_stdin, BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri); } } else { - (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, + (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, 0, NULL, NULL, NULL, NULL, NULL, &crl, NULL); } return crl; } +/* Could be simplified if OSSL_STORE supported CSRs, see FR #15725 */ X509_REQ *load_csr(const char *file, int format, const char *desc) { X509_REQ *req = NULL; @@ -503,8 +530,6 @@ X509_REQ *load_csr(const char *file, int format, const char *desc) if (format == FORMAT_UNDEF) format = FORMAT_PEM; - if (desc == NULL) - desc = "CSR"; in = bio_open_default(file, 'r', format); if (in == NULL) goto end; @@ -519,12 +544,49 @@ X509_REQ *load_csr(const char *file, int format, const char *desc) end: if (req == NULL) { ERR_print_errors(bio_err); - BIO_printf(bio_err, "Unable to load %s\n", desc); + if (desc != NULL) + BIO_printf(bio_err, "Unable to load %s\n", desc); } BIO_free(in); return req; } +/* Better extend OSSL_STORE to support CSRs, see FR #15725 */ +X509_REQ *load_csr_autofmt(const char *infile, int format, + STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc) +{ + X509_REQ *csr; + + if (format != FORMAT_UNDEF) { + csr = load_csr(infile, format, desc); + } else { /* try PEM, then DER */ + BIO *bio_bak = bio_err; + + bio_err = NULL; /* do not show errors on more than one try */ + csr = load_csr(infile, FORMAT_PEM, NULL /* desc */); + bio_err = bio_bak; + if (csr == NULL) { + ERR_clear_error(); + csr = load_csr(infile, FORMAT_ASN1, NULL /* desc */); + } + if (csr == NULL) { + BIO_printf(bio_err, "error: unable to load %s from file '%s'\n", + desc, infile); + } + } + if (csr != NULL) { + EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr); + int ret = do_X509_REQ_verify(csr, pkey, vfyopts); + + if (pkey == NULL || ret < 0) + BIO_puts(bio_err, "Warning: error while verifying CSR self-signature\n"); + else if (ret == 0) + BIO_puts(bio_err, "Warning: CSR self-signature does not match the contents\n"); + return csr; + } + return csr; +} + void cleanse(char *str) { if (str != NULL) @@ -546,16 +608,16 @@ EVP_PKEY *load_key(const char *uri, int format, int may_stdin, if (desc == NULL) desc = "private key"; - if (format == FORMAT_ENGINE) { + if (format == FORMAT_ENGINE) uri = allocated_uri = make_engine_uri(e, uri, desc); - } - (void)load_key_certs_crls(uri, format, may_stdin, pass, desc, + (void)load_key_certs_crls(uri, format, may_stdin, pass, desc, 0, &pkey, NULL, NULL, NULL, NULL, NULL, NULL); OPENSSL_free(allocated_uri); return pkey; } +/* first try reading public key, on failure resort to loading private key */ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *desc) { @@ -565,28 +627,27 @@ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, if (desc == NULL) desc = "public key"; - if (format == FORMAT_ENGINE) { + if (format == FORMAT_ENGINE) uri = allocated_uri = make_engine_uri(e, uri, desc); - } - (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, + (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 1, NULL, &pkey, NULL, NULL, NULL, NULL, NULL); - + if (pkey == NULL) + (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0, + &pkey, NULL, NULL, NULL, NULL, NULL, NULL); OPENSSL_free(allocated_uri); return pkey; } EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin, - const char *keytype, const char *desc, - int suppress_decode_errors) + const char *keytype, const char *desc, + int suppress_decode_errors) { EVP_PKEY *params = NULL; - BIO *bio_bak = bio_err; if (desc == NULL) desc = "key parameters"; - if (suppress_decode_errors) - bio_err = NULL; (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, + suppress_decode_errors, NULL, NULL, ¶ms, NULL, NULL, NULL, NULL); if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) { ERR_print_errors(bio_err); @@ -596,7 +657,6 @@ EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin, EVP_PKEY_free(params); params = NULL; } - bio_err = bio_bak; return params; } @@ -683,13 +743,13 @@ int load_cert_certs(const char *uri, if (desc == NULL) desc = pcerts == NULL ? "certificate" : "certificates"; - if (exclude_http && (OPENSSL_strncasecmp(uri, "http://", 7) == 0 - || OPENSSL_strncasecmp(uri, "https://", 8) == 0)) { + if (exclude_http && (HAS_CASE_PREFIX(uri, "http://") + || HAS_CASE_PREFIX(uri, "https://"))) { BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc); return ret; } pass_string = get_passwd(pass, desc); - ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, + ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, 0, NULL, NULL, NULL, pcert, pcerts, NULL, NULL); clear_free(pass_string); @@ -700,7 +760,7 @@ int load_cert_certs(const char *uri, warn_certs(uri, *pcerts, 1, vpm); } else { if (pcerts != NULL) { - sk_X509_pop_free(*pcerts, X509_free); + OSSL_STACK_OF_X509_free(*pcerts); *pcerts = NULL; } } @@ -726,7 +786,7 @@ STACK_OF(X509) *load_certs_multifile(char *files, const char *pass, if (!X509_add_certs(result, certs, X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) goto oom; - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); certs = NULL; files = next; } @@ -735,8 +795,8 @@ STACK_OF(X509) *load_certs_multifile(char *files, const char *pass, oom: BIO_printf(bio_err, "out of memory\n"); err: - sk_X509_pop_free(certs, X509_free); - sk_X509_pop_free(result, X509_free); + OSSL_STACK_OF_X509_free(certs); + OSSL_STACK_OF_X509_free(result); return NULL; } @@ -777,7 +837,7 @@ X509_STORE *load_certstore(char *input, const char *pass, const char *desc, return NULL; } ok = (store = sk_X509_to_store(store, certs)) != NULL; - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); certs = NULL; if (!ok) return NULL; @@ -797,11 +857,11 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs, if (desc == NULL) desc = "certificates"; - ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc, + ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc, 0, NULL, NULL, NULL, NULL, certs, NULL, NULL); if (!ret && was_NULL) { - sk_X509_pop_free(*certs, X509_free); + OSSL_STACK_OF_X509_free(*certs); *certs = NULL; } return ret; @@ -818,7 +878,7 @@ int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, if (desc == NULL) desc = "CRLs"; - ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, + ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, 0, NULL, NULL, NULL, NULL, NULL, NULL, crls); if (!ret && was_NULL) { @@ -830,7 +890,7 @@ int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, static const char *format2string(int format) { - switch(format) { + switch (format) { case FORMAT_PEM: return "PEM"; case FORMAT_ASN1: @@ -840,7 +900,18 @@ static const char *format2string(int format) } /* Set type expectation, but clear it if objects of different types expected. */ -#define SET_EXPECT(expect, val) ((expect) = (expect) < 0 ? (val) : ((expect) == (val) ? (val) : 0)) +#define SET_EXPECT(val) \ + (expect = expect < 0 ? (val) : (expect == (val) ? (val) : 0)) +#define SET_EXPECT1(pvar, val) \ + if ((pvar) != NULL) { \ + *(pvar) = NULL; \ + SET_EXPECT(val); \ + } +#define FAIL_NAME \ + (ppkey != NULL ? "private key" : ppubkey != NULL ? "public key" : \ + pparams != NULL ? "key parameters" : \ + pcert != NULL ? "certificate" : pcerts != NULL ? "certificates" : \ + pcrl != NULL ? "CRL" : pcrls != NULL ? "CRLs" : NULL) /* * Load those types of credentials for which the result pointer is not NULL. * Reads from stdio if uri is NULL and maybe_stdin is nonzero. @@ -855,7 +926,7 @@ static const char *format2string(int format) * of *pcerts and *pcrls (as far as they are not NULL). */ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, - const char *pass, const char *desc, + const char *pass, const char *desc, int quiet, EVP_PKEY **ppkey, EVP_PKEY **ppubkey, EVP_PKEY **pparams, X509 **pcert, STACK_OF(X509) **pcerts, @@ -865,82 +936,58 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, OSSL_STORE_CTX *ctx = NULL; OSSL_LIB_CTX *libctx = app_get0_libctx(); const char *propq = app_get0_propq(); - int ncerts = 0; - int ncrls = 0; - const char *failed = - ppkey != NULL ? "key" : ppubkey != NULL ? "public key" : - pparams != NULL ? "params" : pcert != NULL ? "cert" : - pcrl != NULL ? "CRL" : pcerts != NULL ? "certs" : - pcrls != NULL ? "CRLs" : NULL; - int cnt_expectations = 0; - int expect = -1; + int ncerts = 0, ncrls = 0, expect = -1; + const char *failed = FAIL_NAME; const char *input_type; OSSL_PARAM itp[2]; const OSSL_PARAM *params = NULL; - ERR_set_mark(); - if (ppkey != NULL) { - *ppkey = NULL; - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_PKEY); - } - if (ppubkey != NULL) { - *ppubkey = NULL; - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_PUBKEY); - } - if (pparams != NULL) { - *pparams = NULL; - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_PARAMS); - } - if (pcert != NULL) { - *pcert = NULL; - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_CERT); + if (failed == NULL) { + if (!quiet) + BIO_printf(bio_err, "Internal error: nothing to load from %s\n", + uri != NULL ? uri : ""); + return 0; } + ERR_set_mark(); + + SET_EXPECT1(ppkey, OSSL_STORE_INFO_PKEY); + SET_EXPECT1(ppubkey, OSSL_STORE_INFO_PUBKEY); + SET_EXPECT1(pparams, OSSL_STORE_INFO_PARAMS); + SET_EXPECT1(pcert, OSSL_STORE_INFO_CERT); if (pcerts != NULL) { if (*pcerts == NULL && (*pcerts = sk_X509_new_null()) == NULL) { - BIO_printf(bio_err, "Out of memory loading"); + if (!quiet) + BIO_printf(bio_err, "Out of memory loading"); goto end; } - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_CERT); - } - if (pcrl != NULL) { - *pcrl = NULL; - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_CRL); + SET_EXPECT(OSSL_STORE_INFO_CERT); } + SET_EXPECT1(pcrl, OSSL_STORE_INFO_CRL); if (pcrls != NULL) { if (*pcrls == NULL && (*pcrls = sk_X509_CRL_new_null()) == NULL) { - BIO_printf(bio_err, "Out of memory loading"); + if (!quiet) + BIO_printf(bio_err, "Out of memory loading"); goto end; } - cnt_expectations++; - SET_EXPECT(expect, OSSL_STORE_INFO_CRL); - } - if (cnt_expectations == 0) { - BIO_printf(bio_err, "Internal error: no expectation to load"); - failed = "anything"; - goto end; + SET_EXPECT(OSSL_STORE_INFO_CRL); } uidata.password = pass; uidata.prompt_info = uri; if ((input_type = format2string(format)) != NULL) { - itp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE, - (char *)input_type, 0); - itp[1] = OSSL_PARAM_construct_end(); - params = itp; + itp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE, + (char *)input_type, 0); + itp[1] = OSSL_PARAM_construct_end(); + params = itp; } if (uri == NULL) { BIO *bio; if (!maybe_stdin) { - BIO_printf(bio_err, "No filename or uri specified for loading\n"); + if (!quiet) + BIO_printf(bio_err, "No filename or uri specified for loading\n"); goto end; } uri = ""; @@ -957,16 +1004,20 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, params, NULL, NULL); } if (ctx == NULL) { - BIO_printf(bio_err, "Could not open file or uri for loading"); + if (!quiet) + BIO_printf(bio_err, "Could not open file or uri for loading"); goto end; } if (expect > 0 && !OSSL_STORE_expect(ctx, expect)) { - BIO_printf(bio_err, "Internal error trying to load"); + if (!quiet) + BIO_printf(bio_err, "Internal error trying to load"); goto end; } failed = NULL; - while (cnt_expectations > 0 && !OSSL_STORE_eof(ctx)) { + while ((ppkey != NULL || ppubkey != NULL || pparams != NULL + || pcert != NULL || pcerts != NULL || pcrl != NULL || pcrls != NULL) + && !OSSL_STORE_eof(ctx)) { OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); int type, ok = 1; @@ -984,50 +1035,52 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, type = OSSL_STORE_INFO_get_type(info); switch (type) { case OSSL_STORE_INFO_PKEY: - if (ppkey != NULL && *ppkey == NULL) { + if (ppkey != NULL) { ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL; - cnt_expectations -= ok; + if (ok) + ppkey = NULL; + break; } /* * An EVP_PKEY with private parts also holds the public parts, * so if the caller asked for a public key, and we got a private * key, we can still pass it back. */ - if (ok && ppubkey != NULL && *ppubkey == NULL) { - ok = ((*ppubkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL); - cnt_expectations -= ok; - } - break; + /* fall through */ case OSSL_STORE_INFO_PUBKEY: - if (ppubkey != NULL && *ppubkey == NULL) { - ok = ((*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL); - cnt_expectations -= ok; + if (ppubkey != NULL) { + ok = (*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL; + if (ok) + ppubkey = NULL; } break; case OSSL_STORE_INFO_PARAMS: - if (pparams != NULL && *pparams == NULL) { - ok = ((*pparams = OSSL_STORE_INFO_get1_PARAMS(info)) != NULL); - cnt_expectations -= ok; + if (pparams != NULL) { + ok = (*pparams = OSSL_STORE_INFO_get1_PARAMS(info)) != NULL; + if (ok) + pparams = NULL; } break; case OSSL_STORE_INFO_CERT: - if (pcert != NULL && *pcert == NULL) { + if (pcert != NULL) { ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL; - cnt_expectations -= ok; - } - else if (pcerts != NULL) + if (ok) + pcert = NULL; + } else if (pcerts != NULL) { ok = X509_add_cert(*pcerts, OSSL_STORE_INFO_get1_CERT(info), X509_ADD_FLAG_DEFAULT); + } ncerts += ok; break; case OSSL_STORE_INFO_CRL: - if (pcrl != NULL && *pcrl == NULL) { + if (pcrl != NULL) { ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL; - cnt_expectations -= ok; - } - else if (pcrls != NULL) + if (ok) + pcrl = NULL; + } else if (pcrls != NULL) { ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info)); + } ncrls += ok; break; default: @@ -1036,37 +1089,25 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, } OSSL_STORE_INFO_free(info); if (!ok) { - failed = info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); - BIO_printf(bio_err, "Error reading"); + failed = OSSL_STORE_INFO_type_string(type); + if (!quiet) + BIO_printf(bio_err, "Error reading"); break; } } end: OSSL_STORE_close(ctx); + if (ncerts > 0) + pcerts = NULL; + if (ncrls > 0) + pcrls = NULL; if (failed == NULL) { - int any = 0; - - if ((ppkey != NULL && *ppkey == NULL) - || (ppubkey != NULL && *ppubkey == NULL)) { - failed = "key"; - } else if (pparams != NULL && *pparams == NULL) { - failed = "params"; - } else if ((pcert != NULL || pcerts != NULL) && ncerts == 0) { - if (pcert == NULL) - any = 1; - failed = "cert"; - } else if ((pcrl != NULL || pcrls != NULL) && ncrls == 0) { - if (pcrl == NULL) - any = 1; - failed = "CRL"; - } - if (failed != NULL) - BIO_printf(bio_err, "Could not read"); - if (any) - BIO_printf(bio_err, " any"); + failed = FAIL_NAME; + if (failed != NULL && !quiet) + BIO_printf(bio_err, "Could not find"); } - if (failed != NULL) { + if (failed != NULL && !quiet) { unsigned long err = ERR_peek_last_error(); if (desc != NULL && strstr(desc, failed) != NULL) { @@ -1087,7 +1128,7 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, BIO_printf(bio_err, "\n"); ERR_print_errors(bio_err); } - if (bio_err == NULL || failed == NULL) + if (quiet || failed == NULL) /* clear any suppressed or spurious errors */ ERR_pop_to_mark(); else @@ -1095,18 +1136,14 @@ int load_key_certs_crls(const char *uri, int format, int maybe_stdin, return failed == NULL; } -#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) -/* Return error for unknown extensions */ -#define X509V3_EXT_DEFAULT 0 -/* Print error for unknown extensions */ -#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) -/* ASN1 parse unknown extensions */ -#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) -/* BIO_dump unknown extensions */ -#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +#define X509V3_EXT_DEFAULT 0 /* Return error for unknown exts */ +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) /* Print error for unknown exts */ +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) /* ASN1 parse unknown extensions */ +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) /* BIO_dump unknown extensions */ #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ - X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) + X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) int set_cert_ex(unsigned long *flags, const char *arg) { @@ -1237,11 +1274,12 @@ int copy_extensions(X509 *x, X509_REQ *req, int copy_type) } static int set_multi_opts(unsigned long *flags, const char *arg, - const NAME_EX_TBL * in_tbl) + const NAME_EX_TBL *in_tbl) { STACK_OF(CONF_VALUE) *vals; CONF_VALUE *val; int i, ret = 1; + if (!arg) return 0; vals = X509V3_parse_list(arg); @@ -1255,12 +1293,12 @@ static int set_multi_opts(unsigned long *flags, const char *arg, } static int set_table_opts(unsigned long *flags, const char *arg, - const NAME_EX_TBL * in_tbl) + const NAME_EX_TBL *in_tbl) { char c; const NAME_EX_TBL *ptbl; - c = arg[0]; + c = arg[0]; if (c == '-') { c = 0; arg++; @@ -1333,7 +1371,7 @@ void print_bignum_var(BIO *out, const BIGNUM *in, const char *var, BIO_printf(out, "\n };\n"); } -void print_array(BIO *out, const char* title, int len, const unsigned char* d) +void print_array(BIO *out, const char *title, int len, const unsigned char *d) { int i; @@ -1367,9 +1405,13 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile, goto end; if (CAfile != NULL) { if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM, - libctx, propq) <= 0) { - BIO_printf(bio_err, "Error loading file %s\n", CAfile); - goto end; + libctx, propq) <= 0) { + ERR_clear_error(); + if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_ASN1, + libctx, propq) <= 0) { + BIO_printf(bio_err, "Error loading file %s\n", CAfile); + goto end; + } } } else { X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, @@ -1506,8 +1548,8 @@ BIGNUM *load_serial(const char *serialfile, int *exists, int create, return ret; } -int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, - ASN1_INTEGER **retai) +int save_serial(const char *serialfile, const char *suffix, + const BIGNUM *serial, ASN1_INTEGER **retai) { char buf[1][BSIZE]; BIO *out = NULL; @@ -1524,9 +1566,9 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial goto err; } - if (suffix == NULL) + if (suffix == NULL) { OPENSSL_strlcpy(buf[0], serialfile, BSIZE); - else { + } else { #ifndef OPENSSL_SYS_VMS j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix); #else @@ -1665,18 +1707,14 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) tmpdb = NULL; if (db_attr) retdb->attributes = *db_attr; - else { + else retdb->attributes.unique_subject = 1; - } - if (dbattr_conf) { - char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject"); - if (p) { - retdb->attributes.unique_subject = parse_yesno(p, 1); - } else { - ERR_clear_error(); - } + if (dbattr_conf != NULL) { + char *p = app_conf_try_string(dbattr_conf, NULL, "unique_subject"); + if (p != NULL) + retdb->attributes.unique_subject = parse_yesno(p, 1); } retdb->dbfname = OPENSSL_strdup(dbfile); @@ -1903,6 +1941,7 @@ X509_NAME *parse_name(const char *cp, int chtype, int canmulti, unsigned char *valstr; int nid; int ismulti = nextismulti; + nextismulti = 0; /* Collect the type */ @@ -1962,7 +2001,7 @@ X509_NAME *parse_name(const char *cp, int chtype, int canmulti, ERR_print_errors(bio_err); BIO_printf(bio_err, "%s: Error adding %s name attribute \"/%s=%s\"\n", - opt_getprog(), desc, typestr ,valstr); + opt_getprog(), desc, typestr, valstr); goto err; } } @@ -2060,6 +2099,7 @@ void policies_print(X509_STORE_CTX *ctx) { X509_POLICY_TREE *tree; int explicit_policy; + tree = X509_STORE_CTX_get0_policy_tree(ctx); explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); @@ -2111,7 +2151,7 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in) OPENSSL_free(out); return NULL; } - out[start-skipped] = (unsigned char)(i - start); + out[start - skipped] = (unsigned char)(i - start); start = i + 1; } else { out[i + 1 - skipped] = in[i]; @@ -2127,29 +2167,43 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in) return out; } -void print_cert_checks(BIO *bio, X509 *x, - const char *checkhost, - const char *checkemail, const char *checkip) +int check_cert_attributes(BIO *bio, X509 *x, const char *checkhost, + const char *checkemail, const char *checkip, + int print) { + int valid_host = 0; + int valid_mail = 0; + int valid_ip = 0; + int ret = 1; + if (x == NULL) - return; - if (checkhost) { - BIO_printf(bio, "Hostname %s does%s match certificate\n", - checkhost, - X509_check_host(x, checkhost, 0, 0, NULL) == 1 - ? "" : " NOT"); + return 0; + + if (checkhost != NULL) { + valid_host = X509_check_host(x, checkhost, 0, 0, NULL); + if (print) + BIO_printf(bio, "Hostname %s does%s match certificate\n", + checkhost, valid_host == 1 ? "" : " NOT"); + ret = ret && valid_host; } - if (checkemail) { - BIO_printf(bio, "Email %s does%s match certificate\n", - checkemail, X509_check_email(x, checkemail, 0, 0) - ? "" : " NOT"); + if (checkemail != NULL) { + valid_mail = X509_check_email(x, checkemail, 0, 0); + if (print) + BIO_printf(bio, "Email %s does%s match certificate\n", + checkemail, valid_mail ? "" : " NOT"); + ret = ret && valid_mail; } - if (checkip) { - BIO_printf(bio, "IP %s does%s match certificate\n", - checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT"); + if (checkip != NULL) { + valid_ip = X509_check_ip_asc(x, checkip, 0); + if (print) + BIO_printf(bio, "IP %s does%s match certificate\n", + checkip, valid_ip ? "" : " NOT"); + ret = ret && valid_ip; } + + return ret; } static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts) @@ -2161,6 +2215,7 @@ static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts) for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { char *opt = sk_OPENSSL_STRING_value(opts, i); + if (pkey_ctrl_string(pkctx, opt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", opt); ERR_print_errors(bio_err); @@ -2180,6 +2235,7 @@ static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts) for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_ctrl_string(x, opt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", opt); ERR_print_errors(bio_err); @@ -2199,6 +2255,7 @@ static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts) for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) { char *opt = sk_OPENSSL_STRING_value(opts, i); + if (x509_req_ctrl_string(x, opt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", opt); ERR_print_errors(bio_err); @@ -2245,50 +2302,57 @@ static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx, idx = X509v3_get_ext_by_OBJ(exts, X509_EXTENSION_get_object(new_ext), -1); if (idx >= 0) { X509_EXTENSION *found_ext = X509v3_get_ext(exts, idx); - ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(found_ext); - int disabled = ASN1_STRING_length(data) <= 2; /* config said "none" */ + ASN1_OCTET_STRING *encoded = X509_EXTENSION_get_data(found_ext); + int disabled = ASN1_STRING_length(encoded) <= 2; /* indicating "none" */ if (disabled) { X509_delete_ext(cert, idx); X509_EXTENSION_free(found_ext); } /* else keep existing key identifier, which might be outdated */ rv = 1; - } else { + } else { rv = !add_default || X509_add_ext(cert, new_ext, -1); } X509_EXTENSION_free(new_ext); return rv; } +int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey) +{ + int match; + + ERR_set_mark(); + match = X509_check_private_key(cert, pkey); + ERR_pop_to_mark(); + return match; +} + /* Ensure RFC 5280 compliance, adapt keyIDs as needed, and sign the cert info */ -int do_X509_sign(X509 *cert, EVP_PKEY *pkey, const char *md, +int do_X509_sign(X509 *cert, int force_v1, EVP_PKEY *pkey, const char *md, STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx) { - const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert); EVP_MD_CTX *mctx = EVP_MD_CTX_new(); int self_sign; int rv = 0; - if (sk_X509_EXTENSION_num(exts /* may be NULL */) > 0) { - /* Prevent X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 */ + if (!force_v1) { if (!X509_set_version(cert, X509_VERSION_3)) goto end; /* - * Add default SKID before such that default AKID can make use of it + * Add default SKID before AKID such that AKID can make use of it * in case the certificate is self-signed */ /* Prevent X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER */ if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1)) goto end; /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */ - ERR_set_mark(); - self_sign = X509_check_private_key(cert, pkey); - ERR_pop_to_mark(); + self_sign = cert_matches_key(cert, pkey); if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier", "keyid, issuer", !self_sign)) goto end; } + /* May add further measures for ensuring RFC 5280 compliance, see #19805 */ if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0) rv = (X509_sign_ctx(cert, mctx) > 0); @@ -2348,8 +2412,7 @@ int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, int rv = 0; if (do_x509_req_init(x, vfyopts) > 0) - rv = X509_REQ_verify_ex(x, pkey, - app_get0_libctx(), app_get0_propq()); + rv = X509_REQ_verify_ex(x, pkey, app_get0_libctx(), app_get0_propq()); else rv = -1; return rv; @@ -2363,6 +2426,7 @@ static const char *get_dp_url(DIST_POINT *dp) GENERAL_NAME *gen; int i, gtype; ASN1_STRING *uri; + if (!dp->distpoint || dp->distpoint->type != 0) return NULL; gens = dp->distpoint->name.fullname; @@ -2388,8 +2452,10 @@ static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp) { int i; const char *urlptr = NULL; + for (i = 0; i < sk_DIST_POINT_num(crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); + urlptr = get_dp_url(dp); if (urlptr != NULL) return load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP"); @@ -2436,7 +2502,7 @@ void store_setup_crl_download(X509_STORE *st) X509_STORE_set_lookup_crls_cb(st, crls_http_cb); } -#ifndef OPENSSL_NO_SOCK +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP) static const char *tls_error_hint(void) { unsigned long err = ERR_peek_error(); @@ -2444,7 +2510,7 @@ static const char *tls_error_hint(void) if (ERR_GET_LIB(err) != ERR_LIB_SSL) err = ERR_peek_last_error(); if (ERR_GET_LIB(err) != ERR_LIB_SSL) - return NULL; + return NULL; /* likely no TLS error */ switch (ERR_GET_REASON(err)) { case SSL_R_WRONG_VERSION_NUMBER: @@ -2457,9 +2523,27 @@ static const char *tls_error_hint(void) return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status"; case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE: return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it"; - default: /* no error or no hint available for error */ - return NULL; + default: + return NULL; /* no hint available for TLS error */ + } +} + +static BIO *http_tls_shutdown(BIO *bio) +{ + if (bio != NULL) { + BIO *cbio; + const char *hint = tls_error_hint(); + + if (hint != NULL) + BIO_printf(bio_err, "%s\n", hint); + (void)ERR_set_mark(); + BIO_ssl_shutdown(bio); + cbio = BIO_pop(bio); /* connect+HTTP BIO */ + BIO_free(bio); /* SSL BIO */ + (void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */ + bio = cbio; } + return bio; } /* HTTP callback function that supports TLS connection also via HTTPS proxy */ @@ -2486,7 +2570,7 @@ BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail) || (sbio = BIO_new(BIO_f_ssl())) == NULL) { return NULL; } - if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) { + if ((ssl = SSL_new(ssl_ctx)) == NULL) { BIO_free(sbio); return NULL; } @@ -2498,24 +2582,8 @@ BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail) BIO_set_ssl(sbio, ssl, BIO_CLOSE); bio = BIO_push(sbio, bio); - } - if (!connect) { - const char *hint; - BIO *cbio; - - if (!detail) { /* disconnecting after error */ - hint = tls_error_hint(); - if (hint != NULL) - ERR_add_error_data(2, " : ", hint); - } - if (ssl_ctx != NULL) { - (void)ERR_set_mark(); - BIO_ssl_shutdown(bio); - cbio = BIO_pop(bio); /* connect+HTTP BIO */ - BIO_free(bio); /* SSL BIO */ - (void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */ - bio = cbio; - } + } else { /* disconnect from TLS */ + bio = http_tls_shutdown(bio); } return bio; } @@ -2640,18 +2708,18 @@ static int WIN32_rename(const char *from, const char *to) tfrom = (TCHAR *)from; tto = (TCHAR *)to; } else { /* UNICODE path */ - size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1; + tfrom = malloc(sizeof(*tfrom) * (flen + tlen)); if (tfrom == NULL) goto err; tto = tfrom + flen; -# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 +# if !defined(_WIN32_WCE) || _WIN32_WCE >= 101 if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen)) # endif for (i = 0; i < flen; i++) tfrom[i] = (TCHAR)from[i]; -# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 +# if !defined(_WIN32_WCE) || _WIN32_WCE >= 101 if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen)) # endif for (i = 0; i < tlen; i++) @@ -2689,6 +2757,7 @@ double app_tminterval(int stop, int usertime) double ret = 0; static ULARGE_INTEGER tmstart; static int warning = 1; + int use_GetSystemTime = 1; # ifdef _WIN32_WINNT static HANDLE proc = NULL; @@ -2702,10 +2771,12 @@ double app_tminterval(int stop, int usertime) if (usertime && proc != (HANDLE) - 1) { FILETIME junk; + GetProcessTimes(proc, &junk, &junk, &junk, &now); - } else + use_GetSystemTime = 0; + } # endif - { + if (use_GetSystemTime) { SYSTEMTIME systime; if (usertime && warning) { @@ -2785,6 +2856,7 @@ double app_tminterval(int stop, int usertime) tmstart = now; } else { long int tck = sysconf(_SC_CLK_TCK); + ret = (now - tmstart) / (double)tck; } @@ -2817,7 +2889,7 @@ double app_tminterval(int stop, int usertime) } #endif -int app_access(const char* name, int flag) +int app_access(const char *name, int flag) { #ifdef _WIN32 return _access(name, flag); @@ -2838,7 +2910,7 @@ static int stdin_sock = -1; static void close_stdin_sock(void) { - TerminalSocket (TERM_SOCK_DELETE, &stdin_sock); + TerminalSocket(TERM_SOCK_DELETE, &stdin_sock); } int fileno_stdin(void) @@ -2866,6 +2938,7 @@ int fileno_stdout(void) int raw_read_stdin(void *buf, int siz) { DWORD n; + if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL)) return n; else @@ -2894,20 +2967,22 @@ int raw_read_stdin(void *buf, int siz) int raw_write_stdout(const void *buf, int siz) { DWORD n; + if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL)) return n; else return -1; } -#elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) && defined(_SPT_MODEL_) +#elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) \ + && defined(_SPT_MODEL_) # if defined(__TANDEM) # if defined(OPENSSL_TANDEM_FLOSS) # include # endif # endif -int raw_write_stdout(const void *buf,int siz) +int raw_write_stdout(const void *buf, int siz) { - return write(fileno(stdout),(void*)buf,siz); + return write(fileno(stdout), (void *)buf, siz); } #else # if defined(__TANDEM) @@ -2961,6 +3036,7 @@ BIO *dup_bio_err(int format) { BIO *b = BIO_new_fp(stderr, BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); + #ifdef OPENSSL_SYS_VMS if (b != NULL && FMT_istext(format)) b = BIO_push(BIO_new(BIO_f_linebuffer()), b); @@ -3049,7 +3125,8 @@ BIO *bio_open_owner(const char *filename, int format, int private) } # ifdef OPENSSL_SYS_VMS - /* VMS doesn't have O_BINARY, it just doesn't make sense. But, + /* + * VMS doesn't have O_BINARY, it just doesn't make sense. But, * it still needs to know that we're going binary, or fdopen() * will fail with "invalid argument"... so we tell VMS what the * context is. @@ -3193,8 +3270,9 @@ int has_stdin_waiting(void) /* Corrupt a signature by modifying final byte */ void corrupt_signature(const ASN1_STRING *signature) { - unsigned char *s = signature->data; - s[signature->length - 1] ^= 0x1; + unsigned char *s = signature->data; + + s[signature->length - 1] ^= 0x1; } int set_cert_times(X509 *x, const char *startdate, const char *enddate, @@ -3276,18 +3354,6 @@ void make_uppercase(char *string) string[i] = toupper((unsigned char)string[i]); } -/* This function is defined here due to visibility of bio_err */ -int opt_printf_stderr(const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = BIO_vprintf(bio_err, fmt, ap); - va_end(ap); - return ret; -} - OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, const OSSL_PARAM *paramdefs) { diff --git a/apps/lib/apps_opt_printf.c b/apps/lib/apps_opt_printf.c new file mode 100644 index 0000000000..e15f4b795e --- /dev/null +++ b/apps/lib/apps_opt_printf.c @@ -0,0 +1,25 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "opt.h" +#include +#include "apps_ui.h" + +/* This function is defined here due to visibility of bio_err */ +int opt_printf_stderr(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = BIO_vprintf(bio_err, fmt, ap); + va_end(ap); + return ret; +} + diff --git a/apps/lib/build.info b/apps/lib/build.info index 923ef5d92b..f0df608734 100644 --- a/apps/lib/build.info +++ b/apps/lib/build.info @@ -8,9 +8,9 @@ IF[{- $config{target} =~ /^vms-/ -}] ENDIF # Source for libapps -$LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \ +$LIBAPPSSRC=apps.c apps_ui.c log.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \ columns.c app_params.c names.c app_provider.c app_x509.c http_server.c \ - engine.c engine_loader.c app_libctx.c + engine.c engine_loader.c app_libctx.c apps_opt_printf.c IF[{- !$disabled{apps} -}] LIBS{noinst}=../libapps.a diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index 637bd1d0b7..a0450446c1 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -18,9 +18,13 @@ /* the context for the CMP mock server */ typedef struct { + X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */ X509 *certOut; /* certificate to be returned in cp/ip/kup msg */ STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */ - STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */ + STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */ + X509 *newWithNew; /* to return in newWithNew of rootKeyUpdate */ + X509 *newWithOld; /* to return in newWithOld of rootKeyUpdate */ + X509 *oldWithNew; /* to return in oldWithNew of rootKeyUpdate */ OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */ int sendError; /* send error response on given request type */ OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */ @@ -29,16 +33,16 @@ typedef struct int checkAfterTime; /* time the client should wait between polling */ } mock_srv_ctx; - static void mock_srv_ctx_free(mock_srv_ctx *ctx) { if (ctx == NULL) return; OSSL_CMP_PKISI_free(ctx->statusOut); + X509_free(ctx->refCert); X509_free(ctx->certOut); - sk_X509_pop_free(ctx->chainOut, X509_free); - sk_X509_pop_free(ctx->caPubsOut, X509_free); + OSSL_STACK_OF_X509_free(ctx->chainOut); + OSSL_STACK_OF_X509_free(ctx->caPubsOut); OSSL_CMP_MSG_free(ctx->certReq); OPENSSL_free(ctx); } @@ -62,21 +66,26 @@ static mock_srv_ctx *mock_srv_ctx_new(void) return NULL; } -int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert) -{ - mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); - - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; +#define DEFINE_OSSL_SET1_CERT(FIELD) \ + int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \ + X509 *cert) \ + { \ + mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \ + \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + if (cert == NULL || X509_up_ref(cert)) { \ + X509_free(ctx->FIELD); \ + ctx->FIELD = cert; \ + return 1; \ + } \ + return 0; \ } - if (cert == NULL || X509_up_ref(cert)) { - X509_free(ctx->certOut); - ctx->certOut = cert; - return 1; - } - return 0; -} + +DEFINE_OSSL_SET1_CERT(refCert) +DEFINE_OSSL_SET1_CERT(certOut) int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) *chain) @@ -90,7 +99,7 @@ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx, } if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL) return 0; - sk_X509_pop_free(ctx->chainOut, X509_free); + OSSL_STACK_OF_X509_free(ctx->chainOut); ctx->chainOut = chain_copy; return 1; } @@ -107,11 +116,15 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx, } if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL) return 0; - sk_X509_pop_free(ctx->caPubsOut, X509_free); + OSSL_STACK_OF_X509_free(ctx->caPubsOut); ctx->caPubsOut = caPubs_copy; return 1; } +DEFINE_OSSL_SET1_CERT(newWithNew) +DEFINE_OSSL_SET1_CERT(newWithOld) +DEFINE_OSSL_SET1_CERT(oldWithNew) + int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status, int fail_info, const char *text) { @@ -170,6 +183,21 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec) return 1; } +/* check for matching reference cert components, as far as given */ +static int refcert_cmp(const X509 *refcert, + const X509_NAME *issuer, const ASN1_INTEGER *serial) +{ + const X509_NAME *ref_issuer; + const ASN1_INTEGER *ref_serial; + + if (refcert == NULL) + return 1; + ref_issuer = X509_get_issuer_name(refcert); + ref_serial = X509_get0_serialNumber(refcert); + return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0) + && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0); +} + static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *cert_req, ossl_unused int certReqId, @@ -180,6 +208,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(X509) **caPubs) { mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); + int bodytype; OSSL_CMP_PKISI *si = NULL; if (ctx == NULL || cert_req == NULL @@ -187,8 +216,8 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return NULL; } - if (ctx->sendError == 1 - || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) { + bodytype = OSSL_CMP_MSG_get_bodytype(cert_req); + if (ctx->sendError == 1 || ctx->sendError == bodytype) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); return NULL; } @@ -212,24 +241,18 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, /* give final response after polling */ ctx->curr_pollCount = 0; - if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR - && crm != NULL && ctx->certOut != NULL) { + /* accept cert update request only for the reference cert, if given */ + if (bodytype == OSSL_CMP_KUR + && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) { const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm); - const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut); - const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut); if (cid == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID); return NULL; } - if (issuer != NULL - && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) { - ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); - return NULL; - } - if (serial != NULL - && ASN1_INTEGER_cmp(serial, - OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) { + if (!refcert_cmp(ctx->refCert, + OSSL_CRMF_CERTID_get0_issuer(cid), + OSSL_CRMF_CERTID_get0_serialNumber(cid))) { ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID); return NULL; } @@ -237,11 +260,12 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, if (ctx->certOut != NULL && (*certOut = X509_dup(ctx->certOut)) == NULL) + /* Should return a cert produced from request template, see FR #16054 */ goto err; if (ctx->chainOut != NULL && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) goto err; - if (ctx->caPubsOut != NULL + if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */ && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL) goto err; if (ctx->statusOut != NULL @@ -252,9 +276,9 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, err: X509_free(*certOut); *certOut = NULL; - sk_X509_pop_free(*chainOut, X509_free); + OSSL_STACK_OF_X509_free(*chainOut); *chainOut = NULL; - sk_X509_pop_free(*caPubs, X509_free); + OSSL_STACK_OF_X509_free(*caPubs); *caPubs = NULL; return NULL; } @@ -270,20 +294,16 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return NULL; } - if (ctx->certOut == NULL || ctx->sendError == 1 + if (ctx->sendError == 1 || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); return NULL; } - /* Allow any RR derived from CSR, which may include subject and serial */ - if (issuer == NULL || serial == NULL) - return OSSL_CMP_PKISI_dup(ctx->statusOut); - - /* accept revocation only for the certificate we sent in ir/cr/kur */ - if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0 - || ASN1_INTEGER_cmp(serial, - X509_get0_serialNumber(ctx->certOut)) != 0) { + /* allow any RR derived from CSR which does not include issuer and serial */ + if ((issuer != NULL || serial != NULL) + /* accept revocation only for the reference cert, if given */ + && !refcert_cmp(ctx->refCert, issuer, serial)) { ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED, "wrong certificate to revoke"); return NULL; @@ -291,6 +311,26 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx, return OSSL_CMP_PKISI_dup(ctx->statusOut); } +static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid, + const OSSL_CMP_ITAV *req) +{ + OSSL_CMP_ITAV *rsp; + + switch (req_nid) { + case NID_id_it_caCerts: + rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut); + break; + case NID_id_it_rootCaCert: + rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew, + ctx->newWithOld, + ctx->oldWithNew); + break; + default: + rsp = OSSL_CMP_ITAV_dup(req); + } + return rsp; +} + static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *genm, const STACK_OF(OSSL_CMP_ITAV) *in, @@ -308,6 +348,18 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); return 0; } + if (sk_OSSL_CMP_ITAV_num(in) == 1) { + OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp; + ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req); + + if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL) + return 0; + rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req); + if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp)) + return 1; + sk_OSSL_CMP_ITAV_free(*out); + return 0; + } *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup, OSSL_CMP_ITAV_free); @@ -351,10 +403,9 @@ static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error, for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) { if (i > 0) BIO_printf(bio_err, ", "); - BIO_printf(bio_err, "\""); - ASN1_STRING_print(bio_err, - sk_ASN1_UTF8STRING_value(errorDetails, i)); - BIO_printf(bio_err, "\""); + ASN1_STRING_print_ex(bio_err, + sk_ASN1_UTF8STRING_value(errorDetails, i), + ASN1_STRFLGS_ESC_QUOTE); } BIO_printf(bio_err, "\n"); } diff --git a/apps/lib/engine_loader.c b/apps/lib/engine_loader.c index 42775a89f3..b3ed120ea0 100644 --- a/apps/lib/engine_loader.c +++ b/apps/lib/engine_loader.c @@ -71,10 +71,8 @@ static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader, char *keyid = NULL; OSSL_STORE_LOADER_CTX *ctx = NULL; - if (OPENSSL_strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1) - != 0) + if (!CHECK_AND_SKIP_CASE_PREFIX(p, ENGINE_SCHEME_COLON)) return NULL; - p += sizeof(ENGINE_SCHEME_COLON) - 1; /* Look for engine ID */ q = strchr(p, ':'); diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index a7fe5e1a58..bca2e7110d 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,13 +17,14 @@ # define _POSIX_C_SOURCE 2 #endif -#include #include #include "http_server.h" #include "internal/sockets.h" #include +#include #include #include "s_apps.h" +#include "log.h" #if defined(__TANDEM) # if defined(OPENSSL_TANDEM_FLOSS) @@ -31,57 +32,25 @@ # endif #endif -static int verbosity = LOG_INFO; - #define HTTP_PREFIX "HTTP/" #define HTTP_VERSION_PATT "1." /* allow 1.x */ #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT #define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */ +#define HTTP_VERSION_STR " "HTTP_PREFIX_VERSION -#ifdef HTTP_DAEMON - -int multi = 0; /* run multiple responder processes */ -int acfd = (int) INVALID_SOCKET; - -static int print_syslog(const char *str, size_t len, void *levPtr) -{ - int level = *(int *)levPtr; - int ilen = len > MAXERRLEN ? MAXERRLEN : len; - - syslog(level, "%.*s", ilen, str); +#define log_HTTP(prog, level, text) \ + trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, "%s", text) +#define log_HTTP1(prog, level, fmt, arg) \ + trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, arg) +#define log_HTTP2(prog, level, fmt, arg1, arg2) \ + trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, arg1, arg2) +#define log_HTTP3(prog, level, fmt, a1, a2, a3) \ + trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, a1, a2, a3) - return ilen; -} -#endif - -void log_message(const char *prog, int level, const char *fmt, ...) -{ - va_list ap; - - if (verbosity < level) - return; - - va_start(ap, fmt); #ifdef HTTP_DAEMON - if (multi) { - char buf[1024]; - - if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) - syslog(level, "%s", buf); - if (level <= LOG_ERR) - ERR_print_errors_cb(print_syslog, &level); - } else -#endif - { - BIO_printf(bio_err, "%s: ", prog); - BIO_vprintf(bio_err, fmt, ap); - BIO_printf(bio_err, "\n"); - (void)BIO_flush(bio_err); - } - va_end(ap); -} +int n_responders = 0; /* run multiple responder processes, set by ocsp.c */ +int acfd = (int)INVALID_SOCKET; -#ifdef HTTP_DAEMON void socket_timeout(int signum) { if (acfd != (int)INVALID_SOCKET) @@ -92,11 +61,11 @@ static void killall(int ret, pid_t *kidpids) { int i; - for (i = 0; i < multi; ++i) + for (i = 0; i < n_responders; ++i) if (kidpids[i] != 0) (void)kill(kidpids[i], SIGTERM); OPENSSL_free(kidpids); - ossl_sleep(1000); + OSSL_sleep(1000); exit(ret); } @@ -122,12 +91,13 @@ void spawn_loop(const char *prog) openlog(prog, LOG_PID, LOG_DAEMON); if (setpgid(0, 0)) { - syslog(LOG_ERR, "fatal: error detaching from parent process group: %s", - strerror(errno)); + log_HTTP1(prog, LOG_CRIT, + "error detaching from parent process group: %s", + strerror(errno)); exit(1); } - kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array"); - for (i = 0; i < multi; ++i) + kidpids = app_malloc(n_responders * sizeof(*kidpids), "child PID array"); + for (i = 0; i < n_responders; ++i) kidpids[i] = 0; signal(SIGINT, noteterm); @@ -140,7 +110,7 @@ void spawn_loop(const char *prog) * Wait for a child to replace when we're at the limit. * Slow down if a child exited abnormally or waitpid() < 0 */ - while (termsig == 0 && procs >= multi) { + while (termsig == 0 && procs >= n_responders) { if ((fpid = waitpid(-1, &status, 0)) > 0) { for (i = 0; i < procs; ++i) { if (kidpids[i] == fpid) { @@ -149,28 +119,34 @@ void spawn_loop(const char *prog) break; } } - if (i >= multi) { - syslog(LOG_ERR, "fatal: internal error: " - "no matching child slot for pid: %ld", - (long) fpid); + if (i >= n_responders) { + log_HTTP1(prog, LOG_CRIT, + "internal error: no matching child slot for pid: %ld", + (long)fpid); killall(1, kidpids); } if (status != 0) { - if (WIFEXITED(status)) - syslog(LOG_WARNING, "child process: %ld, exit status: %d", - (long)fpid, WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - syslog(LOG_WARNING, "child process: %ld, term signal %d%s", - (long)fpid, WTERMSIG(status), + if (WIFEXITED(status)) { + log_HTTP2(prog, LOG_WARNING, + "child process: %ld, exit status: %d", + (long)fpid, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + char *dumped = ""; + # ifdef WCOREDUMP - WCOREDUMP(status) ? " (core dumped)" : + if (WCOREDUMP(status)) + dumped = " (core dumped)"; # endif - ""); - ossl_sleep(1000); + log_HTTP3(prog, LOG_WARNING, + "child process: %ld, term signal %d%s", + (long)fpid, WTERMSIG(status), dumped); + } + OSSL_sleep(1000); } break; } else if (errno != EINTR) { - syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno)); + log_HTTP1(prog, LOG_CRIT, + "waitpid() failed: %s", strerror(errno)); killall(1, kidpids); } } @@ -180,7 +156,7 @@ void spawn_loop(const char *prog) switch (fpid = fork()) { case -1: /* error */ /* System critically low on memory, pause and try again later */ - ossl_sleep(30000); + OSSL_sleep(30000); break; case 0: /* child */ OPENSSL_free(kidpids); @@ -189,20 +165,21 @@ void spawn_loop(const char *prog) if (termsig) _exit(0); if (RAND_poll() <= 0) { - syslog(LOG_ERR, "fatal: RAND_poll() failed"); + log_HTTP(prog, LOG_CRIT, "RAND_poll() failed"); _exit(1); } return; default: /* parent */ - for (i = 0; i < multi; ++i) { + for (i = 0; i < n_responders; ++i) { if (kidpids[i] == 0) { kidpids[i] = fpid; procs++; break; } } - if (i >= multi) { - syslog(LOG_ERR, "fatal: internal error: no free child slots"); + if (i >= n_responders) { + log_HTTP(prog, LOG_CRIT, + "internal error: no free child slots"); killall(1, kidpids); } break; @@ -210,45 +187,52 @@ void spawn_loop(const char *prog) } /* The loop above can only break on termsig */ - syslog(LOG_INFO, "terminating on signal: %d", termsig); + log_HTTP1(prog, LOG_INFO, "terminating on signal: %d", termsig); killall(0, kidpids); } #endif #ifndef OPENSSL_NO_SOCK -BIO *http_server_init_bio(const char *prog, const char *port) +BIO *http_server_init(const char *prog, const char *port, int verb) { BIO *acbio = NULL, *bufbio; int asock; + int port_num; + char name[40]; + snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */ + if (verb >= 0 && !log_set_verbosity(prog, verb)) + return NULL; bufbio = BIO_new(BIO_f_buffer()); if (bufbio == NULL) goto err; acbio = BIO_new(BIO_s_accept()); if (acbio == NULL || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0 - || BIO_set_accept_port(acbio, port) < 0) { - log_message(prog, LOG_ERR, "Error setting up accept BIO"); + || BIO_set_accept_name(acbio, name) < 0) { + log_HTTP(prog, LOG_ERR, "error setting up accept BIO"); goto err; } BIO_set_accept_bios(acbio, bufbio); bufbio = NULL; if (BIO_do_accept(acbio) <= 0) { - log_message(prog, LOG_ERR, "Error starting accept"); + log_HTTP1(prog, LOG_ERR, "error setting accept on port %s", port); goto err; } /* Report back what address and port are used */ BIO_get_fd(acbio, &asock); - if (!report_server_accept(bio_out, asock, 1, 1)) { - log_message(prog, LOG_ERR, "Error printing ACCEPT string"); + port_num = report_server_accept(bio_out, asock, 1, 1); + if (port_num == 0) { + log_HTTP(prog, LOG_ERR, "error printing ACCEPT string"); goto err; } return acbio; err: + ERR_print_errors(bio_err); BIO_free_all(acbio); BIO_free(bufbio); return NULL; @@ -283,8 +267,7 @@ static int urldecode(char *p) int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, char **ppath, BIO **pcbio, BIO *acbio, int *found_keep_alive, - const char *prog, const char *port, - int accept_get, int timeout) + const char *prog, int accept_get, int timeout) { BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL; int len; @@ -298,18 +281,27 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, *ppath = NULL; if (cbio == NULL) { - log_message(prog, LOG_DEBUG, - "Awaiting new connection on port %s...", port); + char *port; + + get_sock_info_address(BIO_get_fd(acbio, NULL), NULL, &port); + if (port == NULL) { + log_HTTP(prog, LOG_ERR, "cannot get port listening on"); + goto fatal; + } + log_HTTP1(prog, LOG_DEBUG, + "awaiting new connection on port %s ...", port); + OPENSSL_free(port); + if (BIO_do_accept(acbio) <= 0) /* Connection loss before accept() is routine, ignore silently */ return ret; *pcbio = cbio = BIO_pop(acbio); } else { - log_message(prog, LOG_DEBUG, "Awaiting next request..."); + log_HTTP(prog, LOG_DEBUG, "awaiting next request ..."); } if (cbio == NULL) { - /* Cannot call http_server_send_status(cbio, ...) */ + /* Cannot call http_server_send_status(..., cbio, ...) */ ret = -1; goto out; } @@ -327,31 +319,39 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, return ret; ret = 1; if (len < 0) { - log_message(prog, LOG_WARNING, "Request line read error"); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP(prog, LOG_WARNING, "request line read error"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } - if ((end = strchr(reqbuf, '\r')) != NULL + + if (((end = strchr(reqbuf, '\r')) != NULL && end[1] == '\n') || (end = strchr(reqbuf, '\n')) != NULL) *end = '\0'; - log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf); + if (log_get_verbosity() < LOG_TRACE) + trace_log_message(-1, prog, LOG_INFO, + "received request, 1st line: %s", reqbuf); + log_HTTP(prog, LOG_TRACE, "received request header:"); + log_HTTP1(prog, LOG_TRACE, "%s", reqbuf); + if (end == NULL) { + log_HTTP(prog, LOG_WARNING, + "cannot parse HTTP header: missing end of line"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); + goto out; + } - meth = reqbuf; - url = meth + 3; - if ((accept_get && strncmp(meth, "GET ", 4) == 0) - || (url++, strncmp(meth, "POST ", 5) == 0)) { - static const char http_version_str[] = " "HTTP_PREFIX_VERSION; - static const size_t http_version_str_len = sizeof(http_version_str) - 1; + url = meth = reqbuf; + if ((accept_get && CHECK_AND_SKIP_PREFIX(url, "GET ")) + || CHECK_AND_SKIP_PREFIX(url, "POST ")) { /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */ - *(url++) = '\0'; + url[-1] = '\0'; while (*url == ' ') url++; if (*url != '/') { - log_message(prog, LOG_WARNING, - "Invalid %s -- URL does not begin with '/': %s", - meth, url); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP2(prog, LOG_WARNING, + "invalid %s -- URL does not begin with '/': %s", + meth, url); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } url++; @@ -360,17 +360,17 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, for (end = url; *end != '\0'; end++) if (*end == ' ') break; - if (strncmp(end, http_version_str, http_version_str_len) != 0) { - log_message(prog, LOG_WARNING, - "Invalid %s -- bad HTTP/version string: %s", - meth, end + 1); - (void)http_server_send_status(cbio, 400, "Bad Request"); + if (!HAS_PREFIX(end, HTTP_VERSION_STR)) { + log_HTTP2(prog, LOG_WARNING, + "invalid %s -- bad HTTP/version string: %s", + meth, end + 1); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } *end = '\0'; /* above HTTP 1.0, connection persistence is the default */ if (found_keep_alive != NULL) - *found_keep_alive = end[http_version_str_len] > '0'; + *found_keep_alive = end[sizeof(HTTP_VERSION_STR) - 1] > '0'; /*- * Skip "GET / HTTP..." requests often used by load-balancers. @@ -378,34 +378,32 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, * the leading slash, so in case 'GET / ' it is now an empty string. */ if (strlen(meth) == 3 && url[0] == '\0') { - (void)http_server_send_status(cbio, 200, "OK"); + (void)http_server_send_status(prog, cbio, 200, "OK"); goto out; } len = urldecode(url); if (len < 0) { - log_message(prog, LOG_WARNING, - "Invalid %s request -- bad URL encoding: %s", - meth, url); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP2(prog, LOG_WARNING, + "invalid %s request -- bad URL encoding: %s", meth, url); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } if (strlen(meth) == 3) { /* GET */ if ((getbio = BIO_new_mem_buf(url, len)) == NULL || (b64 = BIO_new(BIO_f_base64())) == NULL) { - log_message(prog, LOG_ERR, - "Could not allocate base64 bio with size = %d", - len); + log_HTTP1(prog, LOG_ERR, + "could not allocate base64 bio with size = %d", len); goto fatal; } BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); getbio = BIO_push(b64, getbio); } } else { - log_message(prog, LOG_WARNING, - "HTTP request does not begin with %sPOST: %s", - accept_get ? "GET or " : "", reqbuf); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP2(prog, LOG_WARNING, + "HTTP request does not begin with %sPOST: %s", + accept_get ? "GET or " : "", reqbuf); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } @@ -418,40 +416,41 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, /* Read and skip past the headers. */ for (;;) { - char *key, *value, *line_end = NULL; + char *key, *value; len = BIO_gets(cbio, inbuf, sizeof(inbuf)); if (len <= 0) { - log_message(prog, LOG_WARNING, "Error reading HTTP header"); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP(prog, LOG_WARNING, "error reading HTTP header"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); + goto out; + } + + if (((end = strchr(inbuf, '\r')) != NULL && end[1] == '\n') + || (end = strchr(inbuf, '\n')) != NULL) + *end = '\0'; + log_HTTP1(prog, LOG_TRACE, "%s", *inbuf == '\0' ? + " " /* workaround for "" getting ignored */ : inbuf); + if (end == NULL) { + log_HTTP(prog, LOG_WARNING, + "error parsing HTTP header: missing end of line"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } - if (inbuf[0] == '\r' || inbuf[0] == '\n') + if (inbuf[0] == '\0') break; key = inbuf; value = strchr(key, ':'); if (value == NULL) { - log_message(prog, LOG_WARNING, - "Error parsing HTTP header: missing ':'"); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP(prog, LOG_WARNING, + "error parsing HTTP header: missing ':'"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); goto out; } *(value++) = '\0'; while (*value == ' ') value++; - line_end = strchr(value, '\r'); - if (line_end == NULL) { - line_end = strchr(value, '\n'); - if (line_end == NULL) { - log_message(prog, LOG_WARNING, - "Error parsing HTTP header: missing end of line"); - (void)http_server_send_status(cbio, 400, "Bad Request"); - goto out; - } - } - *line_end = '\0'; /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */ if (found_keep_alive != NULL && OPENSSL_strcasecmp(key, "Connection") == 0) { @@ -471,12 +470,12 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, /* Try to read and parse request */ req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL); if (req == NULL) { - log_message(prog, LOG_WARNING, - "Error parsing DER-encoded request content"); - (void)http_server_send_status(cbio, 400, "Bad Request"); + log_HTTP(prog, LOG_WARNING, + "error parsing DER-encoded request content"); + (void)http_server_send_status(prog, cbio, 400, "Bad Request"); } else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) { - log_message(prog, LOG_ERR, - "Out of memory allocating %zu bytes", strlen(url) + 1); + log_HTTP1(prog, LOG_ERR, + "out of memory allocating %zu bytes", strlen(url) + 1); ASN1_item_free(req, it); goto fatal; } @@ -493,7 +492,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, return ret; fatal: - (void)http_server_send_status(cbio, 500, "Internal Server Error"); + (void)http_server_send_status(prog, cbio, 500, "Internal Server Error"); if (ppath != NULL) { OPENSSL_free(*ppath); *ppath = NULL; @@ -505,28 +504,46 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, } /* assumes that cbio does not do an encoding that changes the output length */ -int http_server_send_asn1_resp(BIO *cbio, int keep_alive, +int http_server_send_asn1_resp(const char *prog, BIO *cbio, int keep_alive, const char *content_type, const ASN1_ITEM *it, const ASN1_VALUE *resp) { - int ret = BIO_printf(cbio, HTTP_1_0" 200 OK\r\n%s" - "Content-type: %s\r\n" - "Content-Length: %d\r\n\r\n", - keep_alive ? "Connection: keep-alive\r\n" : "", - content_type, - ASN1_item_i2d(resp, NULL, it)) > 0 - && ASN1_item_i2d_bio(it, cbio, resp) > 0; + char buf[200], *p; + int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0" 200 OK\r\n%s" + "Content-type: %s\r\n" + "Content-Length: %d\r\n", + keep_alive ? "Connection: keep-alive\r\n" : "", + content_type, + ASN1_item_i2d(resp, NULL, it)); + + if (ret < 0 || (size_t)ret >= sizeof(buf)) + return 0; + if (log_get_verbosity() < LOG_TRACE && (p = strchr(buf, '\r')) != NULL) + trace_log_message(-1, prog, LOG_INFO, + "sending response, 1st line: %.*s", (int)(p - buf), + buf); + log_HTTP1(prog, LOG_TRACE, "sending response header:\n%s", buf); + + ret = BIO_printf(cbio, "%s\r\n", buf) > 0 + && ASN1_item_i2d_bio(it, cbio, resp) > 0; (void)BIO_flush(cbio); return ret; } -int http_server_send_status(BIO *cbio, int status, const char *reason) +int http_server_send_status(const char *prog, BIO *cbio, + int status, const char *reason) { - int ret = BIO_printf(cbio, HTTP_1_0" %d %s\r\n\r\n", - /* This implicitly cancels keep-alive */ - status, reason) > 0; + char buf[200]; + int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0" %d %s\r\n\r\n", + /* This implicitly cancels keep-alive */ + status, reason); + + if (ret < 0 || (size_t)ret >= sizeof(buf)) + return 0; + log_HTTP1(prog, LOG_TRACE, "sending response header:\n%s", buf); + ret = BIO_printf(cbio, "%s\r\n", buf) > 0; (void)BIO_flush(cbio); return ret; } diff --git a/apps/lib/log.c b/apps/lib/log.c new file mode 100644 index 0000000000..a5e2f5507a --- /dev/null +++ b/apps/lib/log.c @@ -0,0 +1,108 @@ +/* + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "apps.h" +#include "log.h" + +static int verbosity = LOG_INFO; + +int log_set_verbosity(const char *prog, int level) +{ + if (level < LOG_EMERG || level > LOG_TRACE) { + trace_log_message(-1, prog, LOG_ERR, + "Invalid verbosity level %d", level); + return 0; + } + verbosity = level; + return 1; +} + +int log_get_verbosity(void) +{ + return verbosity; +} + +#ifdef HTTP_DAEMON +static int print_syslog(const char *str, size_t len, void *levPtr) +{ + int level = *(int *)levPtr; + int ilen = len > MAXERRLEN ? MAXERRLEN : len; + + syslog(level, "%.*s", ilen, str); + + return ilen; +} +#endif + +static void log_with_prefix(const char *prog, const char *fmt, va_list ap) +{ + char prefix[80]; + BIO *bio, *pre = BIO_new(BIO_f_prefix()); + + (void)BIO_snprintf(prefix, sizeof(prefix), "%s: ", prog); + (void)BIO_set_prefix(pre, prefix); + bio = BIO_push(pre, bio_err); + (void)BIO_vprintf(bio, fmt, ap); + (void)BIO_printf(bio, "\n"); + (void)BIO_flush(bio); + (void)BIO_pop(pre); + BIO_free(pre); +} + +/* + * Unfortunately, C before C99 does not define va_copy, so we must + * check if it can be assumed to be present. We do that with an internal + * antifeature macro. + * C versions since C94 define __STDC_VERSION__, so it's enough to + * check its existence and value. + */ +#undef OSSL_NO_C99 +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ + 0 < 199900L +# define OSSL_NO_C99 +#endif + +void trace_log_message(int category, + const char *prog, int level, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + +#ifdef OSSL_NO_C99 + if (verbosity >= level) + category = -1; /* disabling trace output in addition to logging */ +#endif + if (category >= 0 && OSSL_trace_enabled(category)) { + BIO *out = OSSL_trace_begin(category); +#ifndef OSSL_NO_C99 + va_list ap_copy; + + va_copy(ap_copy, ap); + (void)BIO_vprintf(out, fmt, ap_copy); + va_end(ap_copy); +#else + (void)BIO_vprintf(out, fmt, ap); +#endif + (void)BIO_printf(out, "\n"); + OSSL_trace_end(category, out); + } + if (verbosity < level) { + va_end(ap); + return; + } +#ifdef HTTP_DAEMON + if (n_responders != 0) { + vsyslog(level, fmt, ap); + if (level <= LOG_ERR) + ERR_print_errors_cb(print_syslog, &level); + } else +#endif + log_with_prefix(prog, fmt, ap); + va_end(ap); +} diff --git a/apps/lib/names.c b/apps/lib/names.c index 4788ae84b9..716130c71e 100644 --- a/apps/lib/names.c +++ b/apps/lib/names.c @@ -11,7 +11,7 @@ #include #include #include "names.h" -#include "openssl/crypto.h" +#include "internal/e_os.h" int name_cmp(const char * const *a, const char * const *b) { diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 157367982d..2d61ac9a78 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,6 +41,7 @@ static int opt_index; static char *arg; static char *flag; static char *dunno; +static const char *unknown_name; static const OPTIONS *unknown; static const OPTIONS *opts; static char prog[40]; @@ -166,7 +167,6 @@ char *opt_init(int ac, char **av, const OPTIONS *o) opt_begin(); opts = o; unknown = NULL; - /* Make sure prog name is set for usage output */ (void)opt_progname(argv[0]); @@ -194,7 +194,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o) case 0: case '-': case '.': case '/': case '<': case '>': case 'E': case 'F': case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's': - case 'u': case 'c': case ':': case 'N': + case 'u': case 'c': case ':': case 'N': case 'A': break; default: OPENSSL_assert(0); @@ -215,6 +215,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o) } #endif if (o->name[0] == '\0') { + OPENSSL_assert(unknown_name != NULL); OPENSSL_assert(unknown == NULL); unknown = o; OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-'); @@ -224,7 +225,9 @@ char *opt_init(int ac, char **av, const OPTIONS *o) } static OPT_PAIR formats[] = { - {"PEM/DER", OPT_FMT_PEMDER}, + {"pem", OPT_FMT_PEM}, + {"der", OPT_FMT_DER}, + {"b64", OPT_FMT_B64}, {"pkcs12", OPT_FMT_PKCS12}, {"smime", OPT_FMT_SMIME}, {"engine", OPT_FMT_ENGINE}, @@ -236,21 +239,22 @@ static OPT_PAIR formats[] = { {NULL} }; +void opt_set_unknown_name(const char *name) +{ + unknown_name = name; +} + /* Print an error message about a failed format parse. */ static int opt_format_error(const char *s, unsigned long flags) { OPT_PAIR *ap; - if (flags == OPT_FMT_PEMDER) { - opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n", - prog, s); - } else { - opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n", - prog, s); - for (ap = formats; ap->name; ap++) - if (flags & ap->retval) - opt_printf_stderr(" %s\n", ap->name); - } + opt_printf_stderr("%s: Bad format \"%s\"; must be one of: ", prog, s); + for (ap = formats; ap->name; ap++) + if (flags & ap->retval) + opt_printf_stderr(" %s", ap->name); + opt_printf_stderr("\n"); + return 0; } @@ -261,9 +265,21 @@ int opt_format(const char *s, unsigned long flags, int *result) default: opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s); return 0; + case 'B': + case 'b': + if (s[1] == '\0' + || strcmp(s, "B64") == 0 || strcmp(s, "b64") == 0 + || strcmp(s, "BASE64") == 0 || strcmp(s, "base64") == 0 ) { + if ((flags & OPT_FMT_B64) == 0) + return opt_format_error(s, flags); + *result = FORMAT_BASE64; + } else { + return 0; + } + break; case 'D': case 'd': - if ((flags & OPT_FMT_PEMDER) == 0) + if ((flags & OPT_FMT_DER) == 0) return opt_format_error(s, flags); *result = FORMAT_ASN1; break; @@ -313,7 +329,7 @@ int opt_format(const char *s, unsigned long flags, int *result) case 'P': case 'p': if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) { - if ((flags & OPT_FMT_PEMDER) == 0) + if ((flags & OPT_FMT_PEM) == 0) return opt_format_error(s, flags); *result = FORMAT_PEM; } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) { @@ -399,8 +415,10 @@ int opt_cipher_any(const char *name, EVP_CIPHER **cipherp) { int ret; + if (name == NULL) + return 1; if ((ret = opt_cipher_silent(name, cipherp)) == 0) - opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); + opt_printf_stderr("%s: Unknown option or cipher: %s\n", prog, name); return ret; } @@ -410,6 +428,8 @@ int opt_cipher(const char *name, EVP_CIPHER **cipherp) unsigned long int flags; EVP_CIPHER *c = NULL; + if (name == NULL) + return 1; if (opt_cipher_any(name, &c)) { mode = EVP_CIPHER_get_mode(c); flags = EVP_CIPHER_get_flags(c); @@ -454,12 +474,22 @@ int opt_md(const char *name, EVP_MD **mdp) { int ret; + if (name == NULL) + return 1; if ((ret = opt_md_silent(name, mdp)) == 0) - opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog, - name != NULL ? name : "\"\""); + opt_printf_stderr("%s: Unknown option or message digest: %s\n", + prog, name); return ret; } +int opt_check_md(const char *name) +{ + if (opt_md(name, NULL)) + return 1; + ERR_clear_error(); + return 0; +} + /* Look through a list of name/value pairs. */ int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) { @@ -956,11 +986,14 @@ int opt_next(void) case 'E': case 'F': case 'f': + case 'A': + case 'a': if (opt_format(arg, o->valtype == 'c' ? OPT_FMT_PDS : o->valtype == 'E' ? OPT_FMT_PDE : - o->valtype == 'F' ? OPT_FMT_PEMDER - : OPT_FMT_ANY, &ival)) + o->valtype == 'F' ? OPT_FMT_PEMDER : + o->valtype == 'A' ? OPT_FMT_ASN1 : + OPT_FMT_ANY, &ival)) break; opt_printf_stderr("%s: Invalid format \"%s\" for option -%s\n", prog, arg, o->name); @@ -971,6 +1004,11 @@ int opt_next(void) return o->retval; } if (unknown != NULL) { + if (dunno != NULL) { + opt_printf_stderr("%s: Multiple %s or unknown options: -%s and -%s\n", + prog, unknown_name, dunno, p); + return -1; + } dunno = p; return unknown->retval; } @@ -996,6 +1034,12 @@ char *opt_unknown(void) return dunno; } +/* Reset the unknown option; needed by ocsp to allow multiple digest options. */ +void reset_unknown(void) +{ + dunno = NULL; +} + /* Return the rest of the arguments after parsing flags. */ char **opt_rest(void) { @@ -1013,6 +1057,31 @@ int opt_num_rest(void) return i; } +int opt_check_rest_arg(const char *expected) +{ + char *opt = *opt_rest(); + + if (opt == NULL || *opt == '\0') { + if (expected == NULL) + return 1; + opt_printf_stderr("%s: Missing argument: %s\n", prog, expected); + return 0; + } + if (expected != NULL) { + opt = argv[opt_index + 1]; + if (opt == NULL || *opt == '\0') + return 1; + opt_printf_stderr("%s: Extra argument after %s: \"%s\"\n", prog, expected, opt); + return 0; + } + if (opt_unknown() == NULL) + opt_printf_stderr("%s: Extra option: \"%s\"\n", prog, opt); + else + opt_printf_stderr("%s: Extra (unknown) options: \"%s\" \"%s\"\n", + prog, opt_unknown(), opt); + return 0; +} + /* Return a string describing the parameter type. */ static const char *valtype2param(const OPTIONS *o) { @@ -1058,55 +1127,60 @@ static void opt_print(const OPTIONS *o, int doingparams, int width) { const char* help; char start[80 + 1]; - char *p; - - help = o->helpstr ? o->helpstr : "(No additional info)"; - if (o->name == OPT_HELP_STR) { - opt_printf_stderr(help, prog); - return; - } - if (o->name == OPT_SECTION_STR) { - opt_printf_stderr("\n"); - opt_printf_stderr(help, prog); - return; - } - if (o->name == OPT_PARAM_STR) { - opt_printf_stderr("\nParameters:\n"); - return; - } - - /* Pad out prefix */ - memset(start, ' ', sizeof(start) - 1); - start[sizeof(start) - 1] = '\0'; + int linelen, printlen; + + /* Avoid OOB if width is beyond the buffer size of start */ + if (width >= (int)sizeof(start)) + width = (int)sizeof(start) - 1; + + help = o->helpstr ? o->helpstr : "(No additional info)"; + if (o->name == OPT_HELP_STR) { + opt_printf_stderr(help, prog); + return; + } else if (o->name == OPT_SECTION_STR) { + opt_printf_stderr("\n"); + opt_printf_stderr(help, prog); + return; + } else if (o->name == OPT_PARAM_STR) { + opt_printf_stderr("\nParameters:\n"); + return; + } - if (o->name == OPT_MORE_STR) { - /* Continuation of previous line; pad and print. */ - start[width] = '\0'; - opt_printf_stderr("%s %s\n", start, help); - return; - } + /* Pad out prefix */ + memset(start, ' ', sizeof(start) - 1); + start[sizeof(start) - 1] = '\0'; - /* Build up the "-flag [param]" part. */ - p = start; - *p++ = ' '; - if (!doingparams) - *p++ = '-'; - if (o->name[0]) - p += strlen(strcpy(p, o->name)); - else - *p++ = '*'; - if (o->valtype != '-') { - *p++ = ' '; - p += strlen(strcpy(p, valtype2param(o))); - } - *p = ' '; - if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) { - *p = '\0'; - opt_printf_stderr("%s\n", start); - memset(start, ' ', sizeof(start)); - } + if (o->name == OPT_MORE_STR) { + /* Continuation of previous line; pad and print. */ start[width] = '\0'; opt_printf_stderr("%s %s\n", start, help); + return; + } + + /* Build up the "-flag [param]" part. */ + linelen = 0; + + printlen = opt_printf_stderr(" %s", !doingparams ? "-" : ""); + linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH; + + printlen = opt_printf_stderr("%s" , o->name[0] ? o->name : "*"); + linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH; + + if (o->valtype != '-') { + printlen = opt_printf_stderr(" %s" , valtype2param(o)); + linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH; + } + + if (linelen >= MAX_OPT_HELP_WIDTH || linelen > width) { + opt_printf_stderr("%s", "\n"); + memset(start, ' ', sizeof(start)); + linelen = 0; + } + + width -= linelen; + + start[width] = '\0'; + opt_printf_stderr("%s %s\n", start, help); } void opt_help(const OPTIONS *list) @@ -1114,7 +1188,6 @@ void opt_help(const OPTIONS *list) const OPTIONS *o; int i, sawparams = 0, width = 5; int standard_prolog; - char start[80 + 1]; /* Starts with its own help message? */ standard_prolog = list[0].name != OPT_HELP_STR; @@ -1123,14 +1196,18 @@ void opt_help(const OPTIONS *list) for (o = list; o->name; o++) { if (o->name == OPT_MORE_STR) continue; + i = 2 + (int)strlen(o->name); if (o->valtype != '-') i += 1 + strlen(valtype2param(o)); - if (i < MAX_OPT_HELP_WIDTH && i > width) + + if (i > width) width = i; - OPENSSL_assert(i < (int)sizeof(start)); } + if (width > MAX_OPT_HELP_WIDTH) + width = MAX_OPT_HELP_WIDTH; + if (standard_prolog) { opt_printf_stderr("Usage: %s [options]\n", prog); if (list[0].name != OPT_SECTION_STR) diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index b27518c763..743d88993f 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -258,7 +258,8 @@ static const char *get_sigtype(int nid) return "gost2012_512"; default: - return NULL; + /* Try to output provider-registered sig alg name */ + return OBJ_nid2sn(nid); } } @@ -433,12 +434,15 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len, int argi, long argl, int ret, size_t *processed) { BIO *out; + BIO_MMSG_CB_ARGS *mmsgargs; + size_t i; out = (BIO *)BIO_get_callback_arg(bio); if (out == NULL) return ret; - if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { + switch (cmd) { + case (BIO_CB_READ | BIO_CB_RETURN): if (ret > 0 && processed != NULL) { BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n", (void *)bio, (void *)argp, len, *processed, *processed); @@ -447,7 +451,9 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len, BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n", (void *)bio, (void *)argp, len, ret); } - } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { + break; + + case (BIO_CB_WRITE | BIO_CB_RETURN): if (ret > 0 && processed != NULL) { BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n", (void *)bio, (void *)argp, len, *processed, *processed); @@ -456,6 +462,51 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len, BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n", (void *)bio, (void *)argp, len, ret); } + break; + + case (BIO_CB_RECVMMSG | BIO_CB_RETURN): + mmsgargs = (BIO_MMSG_CB_ARGS *)argp; + if (ret > 0) { + for (i = 0; i < *(mmsgargs->msgs_processed); i++) { + BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg + + (i * mmsgargs->stride)); + + BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n", + (void *)bio, (void *)msg->data, msg->data_len, + msg->data_len, msg->data_len); + BIO_dump(out, msg->data, msg->data_len); + } + } else if (mmsgargs->num_msg > 0) { + BIO_MSG *msg = mmsgargs->msg; + + BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n", + (void *)bio, (void *)msg->data, msg->data_len, ret); + } + break; + + case (BIO_CB_SENDMMSG | BIO_CB_RETURN): + mmsgargs = (BIO_MMSG_CB_ARGS *)argp; + if (ret > 0) { + for (i = 0; i < *(mmsgargs->msgs_processed); i++) { + BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg + + (i * mmsgargs->stride)); + + BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n", + (void *)bio, (void *)msg->data, msg->data_len, + msg->data_len, msg->data_len); + BIO_dump(out, msg->data, msg->data_len); + } + } else if (mmsgargs->num_msg > 0) { + BIO_MSG *msg = mmsgargs->msg; + + BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n", + (void *)bio, (void *)msg->data, msg->data_len, ret); + } + break; + + default: + /* do nothing */ + break; } return ret; } @@ -559,6 +610,7 @@ static STRINT_PAIR handshakes[] = { {", CertificateStatus", SSL3_MT_CERTIFICATE_STATUS}, {", SupplementalData", SSL3_MT_SUPPLEMENTAL_DATA}, {", KeyUpdate", SSL3_MT_KEY_UPDATE}, + {", CompressedCertificate", SSL3_MT_COMPRESSED_CERTIFICATE}, #ifndef OPENSSL_NO_NEXTPROTONEG {", NextProto", SSL3_MT_NEXT_PROTO}, #endif @@ -671,6 +723,8 @@ static STRINT_PAIR tlsext_types[] = { {"session ticket", TLSEXT_TYPE_session_ticket}, {"renegotiation info", TLSEXT_TYPE_renegotiate}, {"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp}, + {"client cert type", TLSEXT_TYPE_client_cert_type}, + {"server cert type", TLSEXT_TYPE_server_cert_type}, {"TLS padding", TLSEXT_TYPE_padding}, #ifdef TLSEXT_TYPE_next_proto_neg {"next protocol", TLSEXT_TYPE_next_proto_neg}, @@ -685,6 +739,7 @@ static STRINT_PAIR tlsext_types[] = { #ifdef TLSEXT_TYPE_extended_master_secret {"extended master secret", TLSEXT_TYPE_extended_master_secret}, #endif + {"compress certificate", TLSEXT_TYPE_compress_certificate}, {"key share", TLSEXT_TYPE_key_share}, {"supported versions", TLSEXT_TYPE_supported_versions}, {"psk", TLSEXT_TYPE_psk}, @@ -998,7 +1053,7 @@ void ssl_excert_free(SSL_EXCERT *exc) while (exc) { X509_free(exc->cert); EVP_PKEY_free(exc->key); - sk_X509_pop_free(exc->chain, X509_free); + OSSL_STACK_OF_X509_free(exc->chain); curr = exc; exc = exc->next; OPENSSL_free(curr); @@ -1168,7 +1223,7 @@ static char *hexencode(const unsigned char *data, size_t len) void print_verify_detail(SSL *s, BIO *bio) { int mdpth; - EVP_PKEY *mspki; + EVP_PKEY *mspki = NULL; long verify_err = SSL_get_verify_result(s); if (verify_err == X509_V_OK) { @@ -1203,12 +1258,15 @@ void print_verify_detail(SSL *s, BIO *bio) hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE); else hexdata = hexencode(data, dlen); - BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n", + BIO_printf(bio, "DANE TLSA %d %d %d %s%s ", usage, selector, mtype, - (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata, - (mspki != NULL) ? "signed the certificate" : - mdpth ? "matched TA certificate" : "matched EE certificate", - mdpth); + (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata); + if (SSL_get0_peer_rpk(s) == NULL) + BIO_printf(bio, "%s certificate at depth %d\n", + (mspki != NULL) ? "signed the peer" : + mdpth ? "matched the TA" : "matched the EE", mdpth); + else + BIO_printf(bio, "matched the peer raw public key\n"); OPENSSL_free(hexdata); } } @@ -1216,17 +1274,16 @@ void print_verify_detail(SSL *s, BIO *bio) void print_ssl_summary(SSL *s) { const SSL_CIPHER *c; - X509 *peer; + X509 *peer = SSL_get0_peer_certificate(s); + EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s); + int nid; BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s)); print_raw_cipherlist(s); c = SSL_get_current_cipher(s); BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c)); do_print_sigalgs(bio_err, s, 0); - peer = SSL_get0_peer_certificate(s); if (peer != NULL) { - int nid; - BIO_puts(bio_err, "Peer certificate: "); X509_NAME_print_ex(bio_err, X509_get_subject_name(peer), 0, get_nameopt()); @@ -1236,8 +1293,13 @@ void print_ssl_summary(SSL *s) if (SSL_get_peer_signature_type_nid(s, &nid)) BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid)); print_verify_detail(s, bio_err); + } else if (peer_rpk != NULL) { + BIO_printf(bio_err, "Peer used raw public key\n"); + if (SSL_get_peer_signature_type_nid(s, &nid)) + BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid)); + print_verify_detail(s, bio_err); } else { - BIO_puts(bio_err, "No peer certificate\n"); + BIO_puts(bio_err, "No peer certificate or raw public key\n"); } #ifndef OPENSSL_NO_EC ssl_print_point_formats(bio_err, s); @@ -1564,7 +1626,7 @@ void print_ca_names(BIO *bio, SSL *s) return; } - BIO_printf(bio, "---\nAcceptable %s certificate CA names\n",cs); + BIO_printf(bio, "---\nAcceptable %s certificate CA names\n", cs); for (i = 0; i < sk_X509_NAME_num(sk); i++) { X509_NAME_print_ex(bio, sk_X509_NAME_value(sk, i), 0, get_nameopt()); BIO_write(bio, "\n", 1); @@ -1580,3 +1642,15 @@ void ssl_print_secure_renegotiation_notes(BIO *bio, SSL *s) BIO_printf(bio, "This TLS version forbids renegotiation.\n"); } } + +int progress_cb(EVP_PKEY_CTX *ctx) +{ + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + static const char symbols[] = ".+*\n"; + char c = (p >= 0 && (size_t)p <= sizeof(symbols) - 1) ? symbols[p] : '?'; + + BIO_write(b, &c, 1); + (void)BIO_flush(b); + return 1; +} diff --git a/apps/lib/s_socket.c b/apps/lib/s_socket.c index 452714ea07..014c1c0bc0 100644 --- a/apps/lib/s_socket.c +++ b/apps/lib/s_socket.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,6 +64,9 @@ BIO_ADDR *ourpeer = NULL; * AF_UNSPEC * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM * @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any) + * @tfo: flag to enable TCP Fast Open + * @doconn: whether we should call BIO_connect() on the socket + * @ba_ret: BIO_ADDR for the remote peer, to be freed by caller * * This will create a socket and use it to connect to a host:port, or if * family == AF_UNIX, to the path found in host. @@ -76,7 +79,8 @@ BIO_ADDR *ourpeer = NULL; */ int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, - int family, int type, int protocol) + int family, int type, int protocol, int tfo, int doconn, + BIO_ADDR **ba_ret) { BIO_ADDRINFO *res = NULL; BIO_ADDRINFO *bindaddr = NULL; @@ -84,6 +88,10 @@ int init_client(int *sock, const char *host, const char *port, const BIO_ADDRINFO *bi = NULL; int found = 0; int ret; + int options = 0; + + if (tfo && ba_ret != NULL) + *ba_ret = NULL; if (BIO_sock_init() != 1) return 0; @@ -160,14 +168,22 @@ int init_client(int *sock, const char *host, const char *port, BIO_free(tmpbio); } #endif + if (BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP) { + options |= BIO_SOCK_NODELAY; + if (tfo) + options |= BIO_SOCK_TFO; + } - if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), - BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) { + if (doconn && !BIO_connect(*sock, BIO_ADDRINFO_address(ai), options)) { BIO_closesocket(*sock); *sock = INVALID_SOCKET; continue; } + /* Save the address */ + if (tfo || !doconn) + *ba_ret = BIO_ADDR_dup(BIO_ADDRINFO_address(ai)); + /* Success, don't try any more addresses */ break; } @@ -188,6 +204,13 @@ int init_client(int *sock, const char *host, const char *port, } ERR_print_errors(bio_err); } else { + char *hostname = NULL; + + hostname = BIO_ADDR_hostname_string(BIO_ADDRINFO_address(ai), 1); + if (hostname != NULL) { + BIO_printf(bio_out, "Connecting to %s\n", hostname); + OPENSSL_free(hostname); + } /* Remove any stale errors from previous connection attempts */ ERR_clear_error(); ret = 1; @@ -200,6 +223,25 @@ int init_client(int *sock, const char *host, const char *port, return ret; } +void get_sock_info_address(int asock, char **hostname, char **service) +{ + union BIO_sock_info_u info; + + if (hostname != NULL) + *hostname = NULL; + if (service != NULL) + *service = NULL; + + if ((info.addr = BIO_ADDR_new()) != NULL + && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)) { + if (hostname != NULL) + *hostname = BIO_ADDR_hostname_string(info.addr, 1); + if (service != NULL) + *service = BIO_ADDR_service_string(info.addr, 1); + } + BIO_ADDR_free(info.addr); +} + int report_server_accept(BIO *out, int asock, int with_address, int with_pid) { int success = 1; @@ -207,30 +249,24 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid) if (BIO_printf(out, "ACCEPT") <= 0) return 0; if (with_address) { - union BIO_sock_info_u info; - char *hostname = NULL; - char *service = NULL; + char *hostname, *service; - if ((info.addr = BIO_ADDR_new()) != NULL - && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info) - && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL - && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) { + get_sock_info_address(asock, &hostname, &service); + success = hostname != NULL && service != NULL; + if (success) success = BIO_printf(out, strchr(hostname, ':') == NULL ? /* IPv4 */ " %s:%s" : /* IPv6 */ " [%s]:%s", hostname, service) > 0; - } else { + else (void)BIO_printf(out, "unknown:error\n"); - success = 0; - } OPENSSL_free(hostname); OPENSSL_free(service); - BIO_ADDR_free(info.addr); } if (with_pid) - success = success && BIO_printf(out, " PID=%d", getpid()) > 0; - success = success && BIO_printf(out, "\n") > 0; + success *= BIO_printf(out, " PID=%d", getpid()) > 0; + success *= BIO_printf(out, "\n") > 0; (void)BIO_flush(out); return success; @@ -258,7 +294,8 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid) */ int do_server(int *accept_sock, const char *host, const char *port, int family, int type, int protocol, do_server_cb cb, - unsigned char *context, int naccept, BIO *bio_s_out) + unsigned char *context, int naccept, BIO *bio_s_out, + int tfo) { int asock = 0; int sock; @@ -292,6 +329,8 @@ int do_server(int *accept_sock, const char *host, const char *port, sock_protocol = BIO_ADDRINFO_protocol(res); sock_address = BIO_ADDRINFO_address(res); next = BIO_ADDRINFO_next(res); + if (tfo && sock_type == SOCK_STREAM) + sock_options |= BIO_SOCK_TFO; #ifdef AF_INET6 if (sock_family == AF_INET6) sock_options |= BIO_SOCK_V6_ONLY; diff --git a/apps/lib/tlssrp_depr.c b/apps/lib/tlssrp_depr.c index 91c19b096e..f03b013428 100644 --- a/apps/lib/tlssrp_depr.c +++ b/apps/lib/tlssrp_depr.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -87,7 +87,7 @@ static int ssl_srp_verify_param_cb(SSL *s, void *arg) "SRP param N and g are not known params, going to check deeper.\n"); /* - * The srp_moregroups is a real debugging feature. Implementors + * The srp_moregroups is a real debugging feature. Implementers * should rather add the value to the known ones. The minimal size * has already been tested. */ diff --git a/apps/lib/vms_term_sock.c b/apps/lib/vms_term_sock.c index 97fb394326..86f50c3d9a 100644 --- a/apps/lib/vms_term_sock.c +++ b/apps/lib/vms_term_sock.c @@ -120,7 +120,7 @@ typedef struct _SocketPairTimeoutBlock { } SPTB; # ifdef TERM_SOCK_TEST - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ @@ -160,7 +160,7 @@ int main (int argc, char *argv[], char *envp[]) } # endif - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ @@ -275,7 +275,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket) return TERM_SOCK_SUCCESS; } - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ @@ -441,7 +441,7 @@ static int CreateSocketPair (int SocketFamily, sin.sin_port = LocalHostPort ; status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof(sin)); - if (status < 0 ) { + if (status < 0) { LogMessage ("CreateSocketPair: connect () - %d", errno); sys$cantim (&sptb, 0); sys$cancel (TcpAcceptChan); @@ -485,7 +485,7 @@ static int CreateSocketPair (int SocketFamily, return (0) ; } - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ @@ -499,7 +499,7 @@ static void SocketPairTimeoutAst (int astparm) return; } - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ @@ -538,7 +538,7 @@ static int TerminalDeviceAst (int astparm) return status; } - + /*----------------------------------------------------------------------------*/ /* */ /*----------------------------------------------------------------------------*/ diff --git a/apps/list.c b/apps/list.c index 514abacfc8..8649598df7 100644 --- a/apps/list.c +++ b/apps/list.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -102,7 +102,7 @@ static void collect_ciphers(EVP_CIPHER *cipher, void *stack) EVP_CIPHER_up_ref(cipher); } -static void list_ciphers(void) +static void list_ciphers(const char *prefix) { STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp); int i; @@ -113,12 +113,12 @@ static void list_ciphers(void) } #ifndef OPENSSL_NO_DEPRECATED_3_0 if (include_legacy()) { - BIO_printf(bio_out, "Legacy:\n"); + BIO_printf(bio_out, "%sLegacy:\n", prefix); EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out); } #endif - BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, "%sProvided:\n", prefix); EVP_CIPHER_do_all_provided(app_get0_libctx(), collect_ciphers, ciphers); sk_EVP_CIPHER_sort(ciphers); for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) { @@ -186,7 +186,7 @@ static void collect_digests(EVP_MD *digest, void *stack) EVP_MD_up_ref(digest); } -static void list_digests(void) +static void list_digests(const char *prefix) { STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp); int i; @@ -197,12 +197,12 @@ static void list_digests(void) } #ifndef OPENSSL_NO_DEPRECATED_3_0 if (include_legacy()) { - BIO_printf(bio_out, "Legacy:\n"); + BIO_printf(bio_out, "%sLegacy:\n", prefix); EVP_MD_do_all_sorted(legacy_md_fn, bio_out); } #endif - BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, "%sProvided:\n", prefix); EVP_MD_do_all_provided(app_get0_libctx(), collect_digests, digests); sk_EVP_MD_sort(digests); for (i = 0; i < sk_EVP_MD_num(digests); i++) { @@ -1209,9 +1209,11 @@ static int provider_cmp(const OSSL_PROVIDER * const *a, static int collect_providers(OSSL_PROVIDER *provider, void *stack) { STACK_OF(OSSL_PROVIDER) *provider_stack = stack; - - sk_OSSL_PROVIDER_push(provider_stack, provider); - return 1; + /* + * If OK - result is the index of inserted data + * Error - result is -1 or 0 + */ + return sk_OSSL_PROVIDER_push(provider_stack, provider) > 0 ? 1 : 0; } static void list_provider_info(void) @@ -1226,8 +1228,13 @@ static void list_provider_info(void) BIO_printf(bio_err, "ERROR: Memory allocation\n"); return; } + + if (OSSL_PROVIDER_do_all(NULL, &collect_providers, providers) != 1) { + BIO_printf(bio_err, "ERROR: Memory allocation\n"); + return; + } + BIO_printf(bio_out, "Providers:\n"); - OSSL_PROVIDER_do_all(NULL, &collect_providers, providers); sk_OSSL_PROVIDER_sort(providers); for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) { const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i); @@ -1286,6 +1293,9 @@ static void list_engines(void) static void list_disabled(void) { BIO_puts(bio_out, "Disabled algorithms:\n"); +#ifdef OPENSSL_NO_ARGON2 + BIO_puts(bio_out, "ARGON2\n"); +#endif #ifdef OPENSSL_NO_ARIA BIO_puts(bio_out, "ARIA\n"); #endif @@ -1334,6 +1344,9 @@ static void list_disabled(void) #ifdef OPENSSL_NO_EC BIO_puts(bio_out, "EC\n"); #endif +#ifdef OPENSSL_NO_ECX + BIO_puts(bio_out, "ECX\n"); +#endif #ifdef OPENSSL_NO_EC2M BIO_puts(bio_out, "EC2M\n"); #endif @@ -1421,15 +1434,22 @@ static void list_disabled(void) #ifdef OPENSSL_NO_WHIRLPOOL BIO_puts(bio_out, "WHIRLPOOL\n"); #endif -#ifndef ZLIB +#ifdef OPENSSL_NO_ZLIB BIO_puts(bio_out, "ZLIB\n"); #endif +#ifdef OPENSSL_NO_BROTLI + BIO_puts(bio_out, "BROTLI\n"); +#endif +#ifdef OPENSSL_NO_ZSTD + BIO_puts(bio_out, "ZSTD\n"); +#endif } /* Unified enum for help and list commands. */ typedef enum HELPLIST_CHOICE { OPT_COMMON, OPT_ONE, OPT_VERBOSE, + OPT_ALL_ARGORITHMS, OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, @@ -1455,6 +1475,7 @@ const OPTIONS list_options[] = { {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"}, {"commands", OPT_COMMANDS, '-', "List of standard commands"}, {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"}, + {"all-algorithms", OPT_ALL_ARGORITHMS, '-', "List of all algorithms"}, #ifndef OPENSSL_NO_DEPRECATED_3_0 {"digest-commands", OPT_DIGEST_COMMANDS, '-', "List of message digest commands (deprecated)"}, @@ -1513,8 +1534,10 @@ int list_main(int argc, char **argv) char *prog; HELPLIST_CHOICE o; int one = 0, done = 0; + int print_newline = 0; struct { unsigned int commands:1; + unsigned int all_algorithms:1; unsigned int random_instances:1; unsigned int random_generators:1; unsigned int digest_commands:1; @@ -1558,6 +1581,9 @@ int list_main(int argc, char **argv) case OPT_ONE: one = 1; break; + case OPT_ALL_ARGORITHMS: + todo.all_algorithms = 1; + break; case OPT_COMMANDS: todo.commands = 1; break; @@ -1647,57 +1673,97 @@ int list_main(int argc, char **argv) } /* No extra arguments. */ - if (opt_num_rest() != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; +#define MAYBE_ADD_NL(cmd) \ + do { \ + if (print_newline++) { \ + BIO_printf(bio_out, "\n"); \ + } \ + cmd; \ + } while(0) + if (todo.commands) - list_type(FT_general, one); + MAYBE_ADD_NL(list_type(FT_general, one)); + if (todo.all_algorithms) { + MAYBE_ADD_NL({}); + + BIO_printf(bio_out, "Digests:\n"); + list_digests(" "); + BIO_printf(bio_out, "\nSymmetric Ciphers:\n"); + list_ciphers(" "); + BIO_printf(bio_out, "\n"); + list_kdfs(); + BIO_printf(bio_out, "\n"); + list_macs(); + + BIO_printf(bio_out, "\nProvided Asymmetric Encryption:\n"); + list_asymciphers(); + BIO_printf(bio_out, "\nProvided Key Exchange:\n"); + list_keyexchanges(); + BIO_printf(bio_out, "\nProvided Signatures:\n"); + list_signatures(); + BIO_printf(bio_out, "\nProvided Key encapsulation:\n"); + list_kems(); + BIO_printf(bio_out, "\nProvided Key managers:\n"); + list_keymanagers(); + + BIO_printf(bio_out, "\n"); + list_encoders(); + BIO_printf(bio_out, "\n"); + list_decoders(); + BIO_printf(bio_out, "\n"); + list_store_loaders(); + } if (todo.random_instances) - list_random_instances(); + MAYBE_ADD_NL(list_random_instances()); if (todo.random_generators) - list_random_generators(); + MAYBE_ADD_NL(list_random_generators()); if (todo.digest_commands) - list_type(FT_md, one); + MAYBE_ADD_NL(list_type(FT_md, one)); if (todo.digest_algorithms) - list_digests(); + MAYBE_ADD_NL(list_digests("")); if (todo.kdf_algorithms) - list_kdfs(); + MAYBE_ADD_NL(list_kdfs()); if (todo.mac_algorithms) - list_macs(); + MAYBE_ADD_NL(list_macs()); if (todo.cipher_commands) - list_type(FT_cipher, one); + MAYBE_ADD_NL(list_type(FT_cipher, one)); if (todo.cipher_algorithms) - list_ciphers(); + MAYBE_ADD_NL(list_ciphers("")); if (todo.encoder_algorithms) - list_encoders(); + MAYBE_ADD_NL(list_encoders()); if (todo.decoder_algorithms) - list_decoders(); + MAYBE_ADD_NL(list_decoders()); if (todo.keymanager_algorithms) - list_keymanagers(); + MAYBE_ADD_NL(list_keymanagers()); if (todo.signature_algorithms) - list_signatures(); + MAYBE_ADD_NL(list_signatures()); if (todo.asym_cipher_algorithms) - list_asymciphers(); + MAYBE_ADD_NL(list_asymciphers()); if (todo.keyexchange_algorithms) - list_keyexchanges(); + MAYBE_ADD_NL(list_keyexchanges()); if (todo.kem_algorithms) - list_kems(); + MAYBE_ADD_NL(list_kems()); if (todo.pk_algorithms) - list_pkey(); + MAYBE_ADD_NL(list_pkey()); if (todo.pk_method) - list_pkey_meth(); + MAYBE_ADD_NL(list_pkey_meth()); if (todo.store_loaders) - list_store_loaders(); + MAYBE_ADD_NL(list_store_loaders()); if (todo.provider_info) - list_provider_info(); + MAYBE_ADD_NL(list_provider_info()); #ifndef OPENSSL_NO_DEPRECATED_3_0 if (todo.engines) - list_engines(); + MAYBE_ADD_NL(list_engines()); #endif if (todo.disabled) - list_disabled(); + MAYBE_ADD_NL(list_disabled()); if (todo.objects) - list_objects(); + MAYBE_ADD_NL(list_objects()); + +#undef MAYBE_ADD_NL if (!done) goto opthelp; diff --git a/apps/mac.c b/apps/mac.c index a9b6a265f4..0a07b2ea43 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -137,10 +137,9 @@ int mac_main(int argc, char **argv) } /* One argument, the MAC name. */ - argc = opt_num_rest(); - argv = opt_rest(); - if (argc != 1) + if (!opt_check_rest_arg("MAC name")) goto opthelp; + argv = opt_rest(); mac = EVP_MAC_fetch(app_get0_libctx(), argv[0], app_get0_propq()); if (mac == NULL) { @@ -218,7 +217,7 @@ int mac_main(int argc, char **argv) for (i = 0; i < (int)len; ++i) BIO_printf(out, "%02X", buf[i]); if (outfile == NULL) - BIO_printf(out,"\n"); + BIO_printf(out, "\n"); } ret = 0; diff --git a/apps/nseq.c b/apps/nseq.c index d5524370f2..e66b58d957 100644 --- a/apps/nseq.c +++ b/apps/nseq.c @@ -73,8 +73,7 @@ int nseq_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; in = bio_open_default(infile, 'r', FORMAT_PEM); diff --git a/apps/ocsp.c b/apps/ocsp.c index 821e224c6c..17313520cf 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -76,7 +76,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, - const char *port, int timeout); + int timeout); static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp); static char *prog; @@ -136,7 +136,7 @@ const OPTIONS ocsp_options[] = { "Don't include any certificates in signed request"}, {"badsig", OPT_BADSIG, '-', "Corrupt last byte of loaded OCSP response signature (for test)"}, - {"CA", OPT_CA, '<', "CA certificate"}, + {"CA", OPT_CA, '<', "CA certificates"}, {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, {"nrequest", OPT_REQUEST, 'p', "Number of requests to accept (default unlimited)"}, @@ -196,8 +196,10 @@ const OPTIONS ocsp_options[] = { {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, {"verify_other", OPT_VERIFY_OTHER, '<', "Additional certificates to search for signer"}, - {"cert", OPT_CERT, '<', "Certificate to check"}, - {"serial", OPT_SERIAL, 's', "Serial number to check"}, + {"cert", OPT_CERT, '<', + "Certificate to check; may be given multiple times"}, + {"serial", OPT_SERIAL, 's', + "Serial number to check; may be given multiple times"}, {"validity_period", OPT_VALIDITY_PERIOD, 'u', "Maximum validity discrepancy in seconds"}, {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, @@ -228,7 +230,7 @@ int ocsp_main(int argc, char **argv) STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; STACK_OF(X509) *issuers = NULL; X509 *issuer = NULL, *cert = NULL; - STACK_OF(X509) *rca_cert = NULL; + STACK_OF(X509) *rca_certs = NULL; EVP_MD *resp_certid_md = NULL; X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; @@ -261,6 +263,7 @@ int ocsp_main(int argc, char **argv) || (vpm = X509_VERIFY_PARAM_new()) == NULL) goto end; + opt_set_unknown_name("digest"); prog = opt_init(argc, argv, ocsp_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -436,6 +439,7 @@ int ocsp_main(int argc, char **argv) goto end; break; case OPT_CERT: + reset_unknown(); X509_free(cert); cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate"); if (cert == NULL) @@ -449,6 +453,7 @@ int ocsp_main(int argc, char **argv) trailing_md = 0; break; case OPT_SERIAL: + reset_unknown(); if (cert_id_md == NULL) cert_id_md = (EVP_MD *)EVP_sha1(); if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) @@ -524,7 +529,7 @@ int ocsp_main(int argc, char **argv) break; case OPT_MULTI: #ifdef HTTP_DAEMON - multi = atoi(opt_arg()); + n_responders = atoi(opt_arg()); #endif break; case OPT_PROV_CASES: @@ -535,8 +540,7 @@ int ocsp_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (trailing_md) { @@ -576,7 +580,7 @@ int ocsp_main(int argc, char **argv) if (req == NULL && port != NULL) { #ifndef OPENSSL_NO_SOCK - acbio = http_server_init_bio(prog, port); + acbio = http_server_init(prog, port, -1); if (acbio == NULL) goto end; #else @@ -593,7 +597,7 @@ int ocsp_main(int argc, char **argv) BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - if (!load_certs(rca_filename, 0, &rca_cert, NULL, "CA certificates")) + if (!load_certs(rca_filename, 0, &rca_certs, NULL, "CA certificates")) goto end; if (rcertfile != NULL) { if (!load_certs(rcertfile, 0, &rother, NULL, @@ -611,7 +615,7 @@ int ocsp_main(int argc, char **argv) } if (ridx_filename != NULL - && (rkey == NULL || rsigner == NULL || rca_cert == NULL)) { + && (rkey == NULL || rsigner == NULL || rca_certs == NULL)) { BIO_printf(bio_err, "Responder mode requires certificate, key, and CA.\n"); goto end; @@ -629,14 +633,15 @@ int ocsp_main(int argc, char **argv) } #ifdef HTTP_DAEMON - if (multi && acbio != NULL) + if (n_responders != 0 && acbio != NULL) spawn_loop(prog); if (acbio != NULL && req_timeout > 0) signal(SIGALRM, socket_timeout); #endif if (acbio != NULL) - log_message(prog, LOG_INFO, "waiting for OCSP client connections..."); + trace_log_message(-1, prog, + LOG_INFO, "waiting for OCSP client connections..."); redo_accept: @@ -650,14 +655,15 @@ int ocsp_main(int argc, char **argv) rdb = newrdb; } else { free_index(newrdb); - log_message(prog, LOG_ERR, "error reloading updated index: %s", - ridx_filename); + trace_log_message(-1, prog, + LOG_ERR, "error reloading updated index: %s", + ridx_filename); } } #endif req = NULL; - res = do_responder(&req, &cbio, acbio, port, req_timeout); + res = do_responder(&req, &cbio, acbio, req_timeout); if (res == 0) goto redo_accept; @@ -721,7 +727,7 @@ int ocsp_main(int argc, char **argv) } if (rdb != NULL) { - make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey, + make_ocsp_response(bio_err, &resp, req, rdb, rca_certs, rsigner, rkey, rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig, resp_certid_md); if (resp == NULL) @@ -858,9 +864,9 @@ int ocsp_main(int argc, char **argv) EVP_MD_free(rsign_md); EVP_MD_free(resp_certid_md); X509_free(cert); - sk_X509_pop_free(issuers, X509_free); + OSSL_STACK_OF_X509_free(issuers); X509_free(rsigner); - sk_X509_pop_free(rca_cert, X509_free); + OSSL_STACK_OF_X509_free(rca_certs); free_index(rdb); BIO_free_all(cbio); BIO_free_all(acbio); @@ -870,8 +876,8 @@ int ocsp_main(int argc, char **argv) OCSP_BASICRESP_free(bs); sk_OPENSSL_STRING_free(reqnames); sk_OCSP_CERTID_free(ids); - sk_X509_pop_free(sign_other, X509_free); - sk_X509_pop_free(verify_other, X509_free); + OSSL_STACK_OF_X509_free(sign_other); + OSSL_STACK_OF_X509_free(verify_other); sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); OPENSSL_free(thost); OPENSSL_free(tport); @@ -1139,7 +1145,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req OCSP_copy_nonce(bs, req); mctx = EVP_MD_CTX_new(); - if ( mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) { + if (mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) { *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, NULL); goto end; } @@ -1197,13 +1203,13 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) } static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, - const char *port, int timeout) + int timeout) { #ifndef OPENSSL_NO_SOCK return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_REQUEST), (ASN1_VALUE **)preq, NULL, pcbio, acbio, NULL /* found_keep_alive */, - prog, port, 1 /* accept_get */, timeout); + prog, 1 /* accept_get */, timeout); #else BIO_printf(bio_err, "Error getting OCSP request - sockets not supported\n"); @@ -1215,7 +1221,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp) { #ifndef OPENSSL_NO_SOCK - return http_server_send_asn1_resp(cbio, + return http_server_send_asn1_resp(prog, cbio, 0 /* no keep-alive */, "application/ocsp-response", ASN1_ITEM_rptr(OCSP_RESPONSE), diff --git a/apps/openssl.c b/apps/openssl.c index a3056c799f..adf77096c7 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,8 +8,8 @@ */ #include -#include #include +#include "internal/common.h" #include #include #include @@ -157,8 +157,6 @@ static void tracedata_free(tracedata *data) OPENSSL_free(data); } -static STACK_OF(tracedata) *trace_data_stack; - static void cleanup_trace(void) { sk_tracedata_pop_free(trace_data_stack, tracedata_free); @@ -232,6 +230,7 @@ static void setup_trace(const char *str) #endif /* OPENSSL_NO_TRACE */ static char *help_argv[] = { "help", NULL }; +static char *version_argv[] = { "version", NULL }; int main(int argc, char *argv[]) { @@ -241,6 +240,7 @@ int main(int argc, char *argv[]) const char *fname; ARGS arg; int global_help = 0; + int global_version = 0; int ret = 0; arg.argv = NULL; @@ -285,17 +285,26 @@ int main(int argc, char *argv[]) global_help = argc > 1 && (strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0); + global_version = argc > 1 + && (strcmp(argv[1], "-version") == 0 || strcmp(argv[1], "--version") == 0 + || strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--v") == 0); + argc--; argv++; - opt_appname(argc == 1 || global_help ? "help" : argv[0]); + opt_appname(argc == 1 || global_help ? "help" : global_version ? "version" : argv[0]); } else { argv[0] = pname; } - /* If there's a command, run with that, otherwise "help". */ - ret = argc == 0 || global_help - ? do_cmd(prog, 1, help_argv) - : do_cmd(prog, argc, argv); + /* + * If there's no command, assume "help". If there's an override for help + * or version run those, otherwise run the command given. + */ + ret = (argc == 0) || global_help + ? do_cmd(prog, 1, help_argv) + : global_version + ? do_cmd(prog, 1, version_argv) + : do_cmd(prog, argc, argv); end: OPENSSL_free(default_config_file); @@ -326,7 +335,6 @@ const OPTIONS help_options[] = { {NULL} }; - int help_main(int argc, char **argv) { FUNCTION *fp; @@ -357,7 +365,7 @@ int help_main(int argc, char **argv) new_argv[2] = NULL; return do_cmd(prog_init(), 2, new_argv); } - if (opt_num_rest() != 0) { + if (!opt_check_rest_arg(NULL)) { BIO_printf(bio_err, "Usage: %s\n", prog); return 1; } @@ -417,12 +425,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) warn_deprecated(fp); return fp->func(argc, argv); } - if ((strncmp(argv[0], "no-", 3)) == 0) { + f.name = argv[0]; + if (CHECK_AND_SKIP_PREFIX(f.name, "no-")) { /* * User is asking if foo is unsupported, by trying to "run" the * no-foo command. Strange. */ - f.name = argv[0] + 3; if (lh_FUNCTION_retrieve(prog, &f) == NULL) { BIO_printf(bio_out, "%s\n", argv[0]); return 0; @@ -436,12 +444,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) return 1; } -static int function_cmp(const FUNCTION * a, const FUNCTION * b) +static int function_cmp(const FUNCTION *a, const FUNCTION *b) { return strncmp(a->name, b->name, 8); } -static unsigned long function_hash(const FUNCTION * a) +static unsigned long function_hash(const FUNCTION *a) { return OPENSSL_LH_strhash(a->name); } diff --git a/apps/openssl.cnf b/apps/openssl.cnf index bd25e0c622..2833b6f30b 100644 --- a/apps/openssl.cnf +++ b/apps/openssl.cnf @@ -330,8 +330,8 @@ tsa_name = yes # Must the TSA name be included in the reply? # (optional, default: no) ess_cert_id_chain = no # Must the ESS cert id chain be included? # (optional, default: no) -ess_cert_id_alg = sha1 # algorithm to compute certificate - # identifier (optional, default: sha1) +ess_cert_id_alg = sha256 # algorithm to compute certificate + # identifier (optional, default: sha256) [insta] # CMP using Insta Demo CA # Message transfer diff --git a/apps/passwd.c b/apps/passwd.c index 64b2e76c14..379928563c 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -601,7 +601,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf)); /* assert "$5$rounds=999999999$......salt......" */ - if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len ) + if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len) goto err; md = EVP_MD_CTX_new(); diff --git a/apps/pkcs12.c b/apps/pkcs12.c index b442d358f8..1fa0abd3d4 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,12 +14,15 @@ #include #include "apps.h" #include "progs.h" +#include +#include #include #include #include #include #include #include +#include #define NOKEYS 0x1 #define NOCERTS 0x2 @@ -53,6 +56,7 @@ void hex_prin(BIO *out, unsigned char *buf, int len); static int alg_print(const X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); static int set_pbe(int *ppbe, const char *str); +static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg); typedef enum OPTION_choice { OPT_COMMON, @@ -61,13 +65,13 @@ typedef enum OPTION_choice { #ifndef OPENSSL_NO_DES OPT_DESCERT, #endif - OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, + OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, OPT_MACSALTLEN, OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS, OPT_NAME, OPT_CSP, OPT_CANAME, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, - OPT_R_ENUM, OPT_PROV_ENUM, + OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST, #ifndef OPENSSL_NO_DES OPT_LEGACY_ALG #endif @@ -148,23 +152,27 @@ const OPTIONS pkcs12_options[] = { {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"}, {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"}, + {"macsaltlen", OPT_MACSALTLEN, 'p', "Specify the salt len for MAC"}, {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, + {"jdktrust", OPT_JDKTRUST, 's', "Mark certificate in PKCS#12 store as trusted for JDK compatibility"}, {NULL} }; int pkcs12_main(int argc, char **argv) { char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; - char *untrusted = NULL, *ciphername = NULL, *enc_flag = NULL; + char *untrusted = NULL, *ciphername = NULL, *enc_name = NULL; char *passcertsarg = NULL, *passcerts = NULL; char *name = NULL, *csp_name = NULL; char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = ""; int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0; + char *jdktrust = NULL; #ifndef OPENSSL_NO_DES int use_legacy = 0; #endif /* use library defaults for the iter, maciter, cert, and key PBE */ int iter = 0, maciter = 0; + int macsaltlen = PKCS12_SALT_LEN; int cert_pbe = NID_undef; int key_pbe = NID_undef; int ret = 1, macver = 1, add_lmk = 0, private = 0; @@ -182,6 +190,7 @@ int pkcs12_main(int argc, char **argv) EVP_CIPHER *enc = (EVP_CIPHER *)default_enc; OPTION_CHOICE o; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, pkcs12_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -215,6 +224,11 @@ int pkcs12_main(int argc, char **argv) case OPT_NOOUT: options |= (NOKEYS | NOCERTS); break; + case OPT_JDKTRUST: + jdktrust = opt_arg(); + /* Adding jdk trust implies nokeys */ + options |= NOKEYS; + break; case OPT_INFO: options |= INFO; break; @@ -238,16 +252,15 @@ int pkcs12_main(int argc, char **argv) case OPT_NODES: case OPT_NOENC: /* - * |enc_flag| stores the name of the option used so it + * |enc_name| stores the name of the option used so it * can be printed if an error message is output. */ - enc_flag = opt_flag() + 1; + enc_name = opt_flag() + 1; enc = NULL; ciphername = NULL; break; case OPT_CIPHER: - ciphername = opt_unknown(); - enc_flag = opt_unknown(); + enc_name = ciphername = opt_unknown(); break; case OPT_ITER: maciter = iter = opt_int_arg(); @@ -261,6 +274,9 @@ int pkcs12_main(int argc, char **argv) case OPT_NOMACITER: maciter = 1; break; + case OPT_MACSALTLEN: + macsaltlen = opt_int_arg(); + break; case OPT_NOMAC: cert_pbe = -1; maciter = -1; @@ -356,17 +372,14 @@ int pkcs12_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) goto end; - if (ciphername != NULL) { - if (!opt_cipher_any(ciphername, &enc)) - goto opthelp; - } + if (!opt_cipher_any(ciphername, &enc)) + goto opthelp; if (export_pkcs12) { if ((options & INFO) != 0) WARN_EXPORT("info"); @@ -378,7 +391,7 @@ int pkcs12_main(int argc, char **argv) WARN_EXPORT("cacerts"); if (enc != default_enc) BIO_printf(bio_err, - "Warning: output encryption option -%s ignored with -export\n", enc_flag); + "Warning: output encryption option -%s ignored with -export\n", enc_name); } else { if (keyname != NULL) WARN_NO_EXPORT("inkey"); @@ -426,6 +439,8 @@ int pkcs12_main(int argc, char **argv) WARN_NO_EXPORT("nomaciter"); if (cert_pbe == -1 && maciter == -1) WARN_NO_EXPORT("nomac"); + if (macsaltlen != PKCS12_SALT_LEN) + WARN_NO_EXPORT("macsaltlen"); } #ifndef OPENSSL_NO_DES if (use_legacy) { @@ -520,6 +535,8 @@ int pkcs12_main(int argc, char **argv) EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; + CONF *conf = NULL; + ASN1_OBJECT *obj = NULL; if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n"); @@ -555,7 +572,7 @@ int pkcs12_main(int argc, char **argv) /* Look for matching private key */ for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); - if (X509_check_private_key(x, key)) { + if (cert_matches_key(x, key)) { ee_cert = x; /* Zero keyid and alias */ X509_keyid_set1(ee_cert, NULL, 0); @@ -613,7 +630,7 @@ int pkcs12_main(int argc, char **argv) /* Add the remaining certs (except for duplicates) */ add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP); - sk_X509_pop_free(chain2, X509_free); + OSSL_STACK_OF_X509_free(chain2); if (!add_certs) goto export_end; } else { @@ -664,9 +681,20 @@ int pkcs12_main(int argc, char **argv) if (!twopass) OPENSSL_strlcpy(macpass, pass, sizeof(macpass)); - p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs, - key_pbe, cert_pbe, iter, -1, keytype, - app_get0_libctx(), app_get0_propq()); + /* Load the config file */ + if ((conf = app_load_config(default_config_file)) == NULL) + goto export_end; + if (!app_load_modules(conf)) + goto export_end; + + if (jdktrust != NULL) { + obj = OBJ_txt2obj(jdktrust, 0); + } + + p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs, + key_pbe, cert_pbe, iter, -1, keytype, + app_get0_libctx(), app_get0_propq(), + jdk_trust, (void*)obj); if (p12 == NULL) { BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n", @@ -679,13 +707,13 @@ int pkcs12_main(int argc, char **argv) goto opthelp; } - if (maciter != -1) - if (!PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd)) { + if (maciter != -1) { + if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) { BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n"); BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n"); goto export_end; } - + } assert(private); out = bio_open_owner(outfile, FORMAT_PKCS12, private); @@ -700,10 +728,11 @@ int pkcs12_main(int argc, char **argv) EVP_PKEY_free(key); EVP_MD_free(macmd); - sk_X509_pop_free(certs, X509_free); - sk_X509_pop_free(untrusted_certs, X509_free); + OSSL_STACK_OF_X509_free(certs); + OSSL_STACK_OF_X509_free(untrusted_certs); X509_free(ee_cert); - + NCONF_free(conf); + ASN1_OBJECT_free(obj); ERR_print_errors(bio_err); goto end; @@ -833,12 +862,36 @@ int pkcs12_main(int argc, char **argv) return ret; } +static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg) +{ + STACK_OF(X509_ATTRIBUTE) *attrs = NULL; + X509_ATTRIBUTE *attr = NULL; + + /* Nothing to do */ + if (cbarg == NULL) + return 1; + + /* Get the current attrs */ + attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag); + + /* Create a new attr for the JDK Trusted Usage and add it */ + attr = X509_ATTRIBUTE_create(NID_oracle_jdk_trustedkeyusage, V_ASN1_OBJECT, (ASN1_OBJECT*)cbarg); + + /* Add the new attr, if attrs is NULL, it'll be initialised */ + X509at_add1_attr(&attrs, attr); + + /* Set the bag attrs */ + PKCS12_SAFEBAG_set0_attrs(bag, attrs); + + X509_ATTRIBUTE_free(attr); + return 1; +} + int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, int passlen, int options, char *pempass, const EVP_CIPHER *enc) { STACK_OF(PKCS7) *asafes = NULL; - STACK_OF(PKCS12_SAFEBAG) *bags; int i, bagnid; int ret = 0; PKCS7 *p7; @@ -846,6 +899,8 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) return 0; for (i = 0; i < sk_PKCS7_num(asafes); i++) { + STACK_OF(PKCS12_SAFEBAG) *bags; + p7 = sk_PKCS7_value(asafes, i); bagnid = OBJ_obj2nid(p7->type); if (bagnid == NID_pkcs7_data) { @@ -861,7 +916,7 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, } else { continue; } - if (!bags) + if (bags == NULL) goto err; if (!dump_certs_pkeys_bags(out, bags, pass, passlen, options, pempass, enc)) { @@ -869,7 +924,6 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, goto err; } sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; } ret = 1; @@ -1132,6 +1186,8 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) void print_attribute(BIO *out, const ASN1_TYPE *av) { char *value; + const char *ln; + char objbuf[80]; switch (av->type) { case V_ASN1_BMPSTRING: @@ -1158,6 +1214,15 @@ void print_attribute(BIO *out, const ASN1_TYPE *av) BIO_printf(out, "\n"); break; + case V_ASN1_OBJECT: + ln = OBJ_nid2ln(OBJ_obj2nid(av->value.object)); + if (!ln) + ln = ""; + OBJ_obj2txt(objbuf, sizeof(objbuf), av->value.object, 1); + BIO_printf(out, "%s (%s)", ln, objbuf); + BIO_printf(out, "\n"); + break; + default: BIO_printf(out, "\n", av->type); break; diff --git a/apps/pkcs7.c b/apps/pkcs7.c index ba11e8151a..57cb517b17 100644 --- a/apps/pkcs7.c +++ b/apps/pkcs7.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,8 +23,8 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT, - OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE, - OPT_PROV_ENUM + OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_QUIET, + OPT_ENGINE, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS pkcs7_options[] = { @@ -46,6 +46,8 @@ const OPTIONS pkcs7_options[] = { {"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"}, {"print_certs", OPT_PRINT_CERTS, '-', "Print_certs print any certs or crl in the input"}, + {"quiet", OPT_QUIET, '-', + "When used with -print_certs, it produces a cleaner output"}, OPT_PROV_OPTIONS, {NULL} @@ -58,7 +60,7 @@ int pkcs7_main(int argc, char **argv) BIO *in = NULL, *out = NULL; int informat = FORMAT_PEM, outformat = FORMAT_PEM; char *infile = NULL, *outfile = NULL, *prog; - int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; + int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, quiet = 0, ret = 1; OPTION_CHOICE o; OSSL_LIB_CTX *libctx = app_get0_libctx(); @@ -100,6 +102,9 @@ int pkcs7_main(int argc, char **argv) case OPT_PRINT_CERTS: print_certs = 1; break; + case OPT_QUIET: + quiet = 1; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -111,8 +116,7 @@ int pkcs7_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; in = bio_open_default(infile, 'r', informat); @@ -172,7 +176,7 @@ int pkcs7_main(int argc, char **argv) x = sk_X509_value(certs, i); if (text) X509_print(out, x); - else + else if (!quiet) dump_cert_text(out, x); if (!noout) diff --git a/apps/pkcs8.c b/apps/pkcs8.c index 6b09b909eb..7b5e79966b 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,9 @@ #include #include +#define STR(a) XSTR(a) +#define XSTR(a) #a + typedef enum OPTION_choice { OPT_COMMON, OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, @@ -26,6 +29,7 @@ typedef enum OPTION_choice { #endif OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT, OPT_TRADITIONAL, + OPT_SALTLEN, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -53,7 +57,8 @@ const OPTIONS pkcs8_options[] = { {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, {"iter", OPT_ITER, 'p', "Specify the iteration count"}, {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, - + {"saltlen", OPT_SALTLEN, 'p', "Specify the salt length (in bytes)"}, + {OPT_MORE_STR, 0, 0, "Default: 8 (For PBE1) or 16 (for PBE2)"}, #ifndef OPENSSL_NO_SCRYPT OPT_SECTION("Scrypt"), {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"}, @@ -88,6 +93,7 @@ int pkcs8_main(int argc, char **argv) #ifndef OPENSSL_NO_SCRYPT long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0; #endif + int saltlen = 0; /* A value of zero chooses the default */ prog = opt_init(argc, argv, pkcs8_options); while ((o = opt_next()) != OPT_EOF) { @@ -189,12 +195,15 @@ int pkcs8_main(int argc, char **argv) goto opthelp; break; #endif + case OPT_SALTLEN: + if (!opt_int(opt_arg(), &saltlen)) + goto opthelp; + break; } } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; private = 1; @@ -246,14 +255,14 @@ int pkcs8_main(int argc, char **argv) if (cipher) { #ifndef OPENSSL_NO_SCRYPT if (scrypt_N && scrypt_r && scrypt_p) - pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL, + pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, saltlen, NULL, scrypt_N, scrypt_r, scrypt_p); else #endif - pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, + pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, saltlen, NULL, pbe_nid); } else { - pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0); + pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, saltlen); } if (pbe == NULL) { BIO_printf(bio_err, "Error setting PBE algorithm\n"); diff --git a/apps/pkey.c b/apps/pkey.c index 196678533c..3e4c09b362 100644 --- a/apps/pkey.c +++ b/apps/pkey.c @@ -83,6 +83,7 @@ int pkey_main(int argc, char **argv) char *point_format = NULL; #endif + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, pkey_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -171,8 +172,7 @@ int pkey_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (text && text_pub) @@ -190,10 +190,8 @@ int pkey_main(int argc, char **argv) private = (!noout && !pubout) || (text && !text_pub); - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &cipher)) - goto opthelp; - } + if (!opt_cipher(ciphername, &cipher)) + goto opthelp; if (cipher == NULL) { if (passoutarg != NULL) BIO_printf(bio_err, diff --git a/apps/pkeyparam.c b/apps/pkeyparam.c index b02882ccc2..4fefe69e6b 100644 --- a/apps/pkeyparam.c +++ b/apps/pkeyparam.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -91,8 +91,7 @@ int pkeyparam_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; in = bio_open_default(infile, 'r', FORMAT_PEM); diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 3c9f9025a1..b5390c64c2 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -69,8 +69,8 @@ const OPTIONS pkeyutl_options[] = { OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file - default stdin"}, {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, - {"pubin", OPT_PUBIN, '-', "Input is a public key"}, - {"inkey", OPT_INKEY, 's', "Input private key file"}, + {"inkey", OPT_INKEY, 's', "Input key, by default private key"}, + {"pubin", OPT_PUBIN, '-', "Input key is a public key"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"}, @@ -253,8 +253,7 @@ int pkeyutl_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) @@ -729,7 +728,7 @@ static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, goto end; } mbuf = app_malloc(filesize, "oneshot sign/verify buffer"); - switch(pkey_op) { + switch (pkey_op) { case EVP_PKEY_OP_VERIFY: buf_len = BIO_read(in, mbuf, filesize); if (buf_len != filesize) { @@ -754,7 +753,7 @@ static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, goto end; } - switch(pkey_op) { + switch (pkey_op) { case EVP_PKEY_OP_VERIFY: for (;;) { buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); diff --git a/apps/prime.c b/apps/prime.c index e269493d5c..a03909c411 100644 --- a/apps/prime.c +++ b/apps/prime.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,6 +19,23 @@ typedef enum OPTION_choice { OPT_PROV_ENUM } OPTION_CHOICE; +static int check_num(const char *s, const int is_hex) +{ + int i; + /* + * It would make sense to use ossl_isxdigit and ossl_isdigit here, + * but ossl_ctype_check is a local symbol in libcrypto.so. + */ + if (is_hex) { + for (i = 0; ('0' <= s[i] && s[i] <= '9') + || ('A' <= s[i] && s[i] <= 'F') + || ('a' <= s[i] && s[i] <= 'f'); i++); + } else { + for (i = 0; '0' <= s[i] && s[i] <= '9'; i++); + } + return s[i] == 0; +} + const OPTIONS prime_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, @@ -83,12 +100,12 @@ int prime_main(int argc, char **argv) } /* Optional arguments are numbers to check. */ + if (generate && !opt_check_rest_arg(NULL)) + goto opthelp; argc = opt_num_rest(); argv = opt_rest(); - if (generate) { - if (argc != 0) - goto opthelp; - } else if (argc == 0) { + if (!generate && argc == 0) { + BIO_printf(bio_err, "Missing number (s) to check\n"); goto opthelp; } @@ -117,12 +134,10 @@ int prime_main(int argc, char **argv) OPENSSL_free(s); } else { for ( ; *argv; argv++) { - int r; + int r = check_num(argv[0], hex); - if (hex) - r = BN_hex2bn(&bn, argv[0]); - else - r = BN_dec2bn(&bn, argv[0]); + if (r) + r = hex ? BN_hex2bn(&bn, argv[0]) : BN_dec2bn(&bn, argv[0]); if (!r) { BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); diff --git a/apps/progs.pl b/apps/progs.pl index 29f9be13ca..4a1e4be47c 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -104,7 +104,7 @@ # The format of this table is: # [0] = alternative command to use instead # [1] = deprecented in this version -# [2] = preprocessor conditional for exclusing irrespective of deprecation +# [2] = preprocessor conditional for excluding irrespective of deprecation # rsa => [ "pkey", "3_0", "rsa" ], # genrsa => [ "genpkey", "3_0", "rsa" ], rsautl => [ "pkeyutl", "3_0", "rsa" ], @@ -188,7 +188,7 @@ "camellia-128-cbc", "camellia-128-ecb", "camellia-192-cbc", "camellia-192-ecb", "camellia-256-cbc", "camellia-256-ecb", - "base64", "zlib", + "base64", "zlib", "brotli", "zstd", "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", "rc2", "bf", "cast", "rc5", "des-ecb", "des-ede", "des-ede3", @@ -205,9 +205,7 @@ ) { my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options, NULL},\n"; (my $algo = $cmd) =~ s/-.*//g; - if ($cmd eq "zlib") { - print "#ifdef ZLIB\n${str}#endif\n"; - } elsif (grep { $algo eq $_ } @disablables) { + if (grep { $algo eq $_ } @disablables) { print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n"; } elsif (my $disabler = $cipher_disabler{$algo}) { print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n"; diff --git a/apps/rand.c b/apps/rand.c index cbf495d5bc..c0ab51dd83 100644 --- a/apps/rand.c +++ b/apps/rand.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -52,7 +52,9 @@ int rand_main(int argc, char **argv) BIO *out = NULL; char *outfile = NULL, *prog; OPTION_CHOICE o; - int format = FORMAT_BINARY, i, num = -1, r, ret = 1; + int format = FORMAT_BINARY, r, i, ret = 1, buflen = 131072; + long num = -1; + uint8_t *buf = NULL; prog = opt_init(argc, argv, rand_options); while ((o = opt_next()) != OPT_EOF) { @@ -93,9 +95,9 @@ int rand_main(int argc, char **argv) argc = opt_num_rest(); argv = opt_rest(); if (argc == 1) { - if (!opt_int(argv[0], &num) || num <= 0) + if (!opt_long(argv[0], &num) || num <= 0) goto opthelp; - } else if (argc != 0) { + } else if (!opt_check_rest_arg(NULL)) { goto opthelp; } @@ -113,13 +115,11 @@ int rand_main(int argc, char **argv) out = BIO_push(b64, out); } + buf = app_malloc(buflen, "buffer for output file"); while (num > 0) { - unsigned char buf[4096]; - int chunk; + long chunk; - chunk = num; - if (chunk > (int)sizeof(buf)) - chunk = sizeof(buf); + chunk = (num > buflen) ? buflen : num; r = RAND_bytes(buf, chunk); if (r <= 0) goto end; @@ -143,6 +143,7 @@ int rand_main(int argc, char **argv) end: if (ret != 0) ERR_print_errors(bio_err); + OPENSSL_free(buf); release_engine(e); BIO_free_all(out); return ret; diff --git a/apps/rehash.c b/apps/rehash.c index 5c6d5340be..1e5cf38a7f 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -212,11 +212,11 @@ static int handle_symlink(const char *filename, const char *fullpath) } if (filename[i++] != '.') return -1; - for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) { - const char *suffix = suffixes[type]; - if (OPENSSL_strncasecmp(suffix, &filename[i], strlen(suffix)) == 0) + for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) + if (OPENSSL_strncasecmp(&filename[i], + suffixes[type], strlen(suffixes[type])) == 0) break; - } + i += strlen(suffixes[type]); id = strtoul(&filename[i], &endptr, 10); @@ -355,9 +355,9 @@ static int do_dir(const char *dirname, enum Hash h) OPENSSL_DIR_CTX *d = NULL; struct stat st; unsigned char idmask[MAX_COLLISIONS / 8]; - int n, numfiles, nextid, buflen, errs = 0; + int n, numfiles, nextid, dirlen, buflen, errs = 0; size_t i; - const char *pathsep; + const char *pathsep = ""; const char *filename; char *buf, *copy = NULL; STACK_OF(OPENSSL_STRING) *files = NULL; @@ -366,9 +366,12 @@ static int do_dir(const char *dirname, enum Hash h) BIO_printf(bio_err, "Skipping %s, can't write\n", dirname); return 1; } - buflen = strlen(dirname); - pathsep = (buflen && !ends_with_dirsep(dirname)) ? "/": ""; - buflen += NAME_MAX + 1 + 1; + dirlen = strlen(dirname); + if (dirlen != 0 && !ends_with_dirsep(dirname)) { + pathsep = "/"; + dirlen++; + } + buflen = dirlen + NAME_MAX + 1; buf = app_malloc(buflen, "filename buffer"); if (verbose) @@ -427,12 +430,12 @@ static int do_dir(const char *dirname, enum Hash h) while (bit_isset(idmask, nextid)) nextid++; - BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d", - dirname, pathsep, &n, bp->hash, + BIO_snprintf(buf, buflen, "%s%s%08x.%s%d", + dirname, pathsep, bp->hash, suffixes[bp->type], nextid); if (verbose) BIO_printf(bio_out, "link %s -> %s\n", - ep->filename, &buf[n]); + ep->filename, &buf[dirlen]); if (unlink(buf) < 0 && errno != ENOENT) { BIO_printf(bio_err, "%s: Can't unlink %s, %s\n", @@ -449,12 +452,12 @@ static int do_dir(const char *dirname, enum Hash h) bit_set(idmask, nextid); } else if (remove_links) { /* Link to be deleted */ - BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d", - dirname, pathsep, &n, bp->hash, + BIO_snprintf(buf, buflen, "%s%s%08x.%s%d", + dirname, pathsep, bp->hash, suffixes[bp->type], ep->old_id); if (verbose) BIO_printf(bio_out, "unlink %s\n", - &buf[n]); + &buf[dirlen]); if (unlink(buf) < 0 && errno != ENOENT) { BIO_printf(bio_err, "%s: Can't unlink %s, %s\n", diff --git a/apps/req.c b/apps/req.c index 41191803ae..3ce2b38496 100644 --- a/apps/req.c +++ b/apps/req.c @@ -62,7 +62,6 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def, static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, int nid, int n_min, int n_max, unsigned long chtype, int mval); -static int genpkey_cb(EVP_PKEY_CTX *ctx); static int build_data(char *text, const char *def, char *value, int n_min, int n_max, char *buf, const int buf_size, const char *desc1, const char *desc2); @@ -86,12 +85,12 @@ typedef enum OPTION_choice { OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY, OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, OPT_VERIFY, OPT_NOENC, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, - OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509, - OPT_CA, OPT_CAKEY, + OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, + OPT_X509, OPT_X509V1, OPT_CA, OPT_CAKEY, OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, - OPT_COPY_EXTENSIONS, OPT_ADDEXT, OPT_EXTENSIONS, - OPT_REQEXTS, OPT_PRECERT, OPT_MD, - OPT_SECTION, + OPT_COPY_EXTENSIONS, OPT_EXTENSIONS, OPT_REQEXTS, OPT_ADDEXT, + OPT_PRECERT, OPT_MD, + OPT_SECTION, OPT_QUIET, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -104,7 +103,8 @@ const OPTIONS req_options[] = { "Specify engine to be used for key generation operations"}, #endif {"in", OPT_IN, '<', "X.509 request input file (default stdin)"}, - {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"inform", OPT_INFORM, 'F', + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"verify", OPT_VERIFY, '-', "Verify self-signature on the request"}, OPT_SECTION("Certificate"), @@ -117,6 +117,7 @@ const OPTIONS req_options[] = { {"text", OPT_TEXT, '-', "Text form of request"}, {"x509", OPT_X509, '-', "Output an X.509 certificate structure instead of a cert request"}, + {"x509v1", OPT_X509V1, '-', "Request cert generation with X.509 version 1"}, {"CA", OPT_CA, '<', "Issuer cert to use for signing a cert, implies -x509"}, {"CAkey", OPT_CAKEY, 's', "Issuer private key to use with -CA; default is -CA arg"}, @@ -130,14 +131,12 @@ const OPTIONS req_options[] = { {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, {"copy_extensions", OPT_COPY_EXTENSIONS, 's', "copy extensions from request when using -x509"}, + {"extensions", OPT_EXTENSIONS, 's', + "Cert or request extension section (override value in config file)"}, + {"reqexts", OPT_REQEXTS, 's', "An alias for -extensions"}, {"addext", OPT_ADDEXT, 's', "Additional cert extension key=value pair (may be given more than once)"}, - {"extensions", OPT_EXTENSIONS, 's', - "Cert extension section (override value in config file)"}, - {"reqexts", OPT_REQEXTS, 's', - "Request extension section (override value in config file)"}, - {"precert", OPT_PRECERT, '-', - "Add a poison extension to the generated cert (implies -new)"}, + {"precert", OPT_PRECERT, '-', "Add a poison extension to generated cert (implies -new)"}, OPT_SECTION("Keys and Signing"), {"key", OPT_KEY, 's', "Key for signing, and to include unless -in given"}, @@ -159,6 +158,7 @@ const OPTIONS req_options[] = { {"batch", OPT_BATCH, '-', "Do not ask anything during request generation"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"quiet", OPT_QUIET, '-', "Terse output"}, {"noenc", OPT_NOENC, '-', "Don't encrypt private keys"}, {"nodes", OPT_NODES, '-', "Don't encrypt private keys; deprecated"}, {"noout", OPT_NOOUT, '-', "Do not output REQ"}, @@ -189,8 +189,8 @@ static void exts_cleanup(OPENSSL_STRING *x) } /* - * Is the |kv| key already duplicated? This is remarkably tricky to get right. - * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error. + * Is the |kv| key already duplicated? + * Return 0 if unique, -1 on runtime error, -2 on syntax error; 1 if found. */ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) { @@ -199,11 +199,12 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) /* Check syntax. */ /* Skip leading whitespace, make a copy. */ - while (*kv && isspace(_UC(*kv))) - if (*++kv == '\0') - return 1; - if ((p = strchr(kv, '=')) == NULL) - return 1; + while (isspace(_UC(*kv))) + kv++; + if ((p = strchr(kv, '=')) == NULL) { + BIO_printf(bio_err, "Parse error on -addext: missing '='\n"); + return -2; + } off = p - kv; if ((kv = OPENSSL_strdup(kv)) == NULL) return -1; @@ -213,14 +214,16 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) if (!isspace(_UC(p[-1]))) break; if (p == kv) { + BIO_printf(bio_err, "Parse error on -addext: missing key\n"); OPENSSL_free(kv); - return 1; + return -2; } *p = '\0'; /* Finally have a clean "key"; see if it's there [by attempt to add it]. */ p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING *)kv); if (p != NULL) { + BIO_printf(bio_err, "Duplicate extension name: %s\n", kv); OPENSSL_free(p); return 1; } else if (lh_OPENSSL_STRING_error(addexts)) { @@ -243,25 +246,24 @@ int req_main(int argc, char **argv) X509 *new_x509 = NULL, *CAcert = NULL; X509_REQ *req = NULL; EVP_CIPHER *cipher = NULL; - EVP_MD *md = NULL; int ext_copy = EXT_COPY_UNSET; BIO *addext_bio = NULL; - char *extensions = NULL; + char *extsect = NULL; const char *infile = NULL, *CAfile = NULL, *CAkeyfile = NULL; char *outfile = NULL, *keyfile = NULL, *digest = NULL; char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; char *nofree_passin = NULL, *nofree_passout = NULL; - char *req_exts = NULL, *subj = NULL; + char *subj = NULL; X509_NAME *fsubj = NULL; char *template = default_config_file, *keyout = NULL; const char *keyalg = NULL; OPTION_CHOICE o; int days = UNSET_DAYS; - int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0; + int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0, progress = 1; int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyform = FORMAT_UNDEF; int modulus = 0, multirdn = 1, verify = 0, noout = 0, text = 0; - int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0; + int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0, x509v1 = 0; long newkey_len = -1; unsigned long chtype = MBSTRING_ASC, reqflag = 0; @@ -269,6 +271,7 @@ int req_main(int argc, char **argv) cipher = (EVP_CIPHER *)EVP_des_ede3_cbc(); #endif + opt_set_unknown_name("digest"); prog = opt_init(argc, argv, req_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -387,6 +390,11 @@ int req_main(int argc, char **argv) break; case OPT_VERBOSE: verbose = 1; + progress = 1; + break; + case OPT_QUIET: + verbose = 0; + progress = 0; break; case OPT_UTF8: chtype = MBSTRING_UTF8; @@ -402,6 +410,9 @@ int req_main(int argc, char **argv) case OPT_TEXT: text = 1; break; + case OPT_X509V1: + x509v1 = 1; + /* fall thru */ case OPT_X509: gen_x509 = 1; break; @@ -445,6 +456,10 @@ int req_main(int argc, char **argv) goto end; } break; + case OPT_EXTENSIONS: + case OPT_REQEXTS: + extsect = opt_arg(); + break; case OPT_ADDEXT: p = opt_arg(); if (addexts == NULL) { @@ -454,19 +469,13 @@ int req_main(int argc, char **argv) goto end; } i = duplicated(addexts, p); - if (i == 1) { - BIO_printf(bio_err, "Duplicate extension: %s\n", p); + if (i == 1) goto opthelp; - } + if (i == -1) + BIO_printf(bio_err, "Internal error handling -addext %s\n", p); if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0) goto end; break; - case OPT_EXTENSIONS: - extensions = opt_arg(); - break; - case OPT_REQEXTS: - req_exts = opt_arg(); - break; case OPT_PRECERT: newreq = precert = 1; break; @@ -477,8 +486,7 @@ int req_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) @@ -490,8 +498,13 @@ int req_main(int argc, char **argv) if (ext_copy == EXT_COPY_NONE) BIO_printf(bio_err, "Ignoring -copy_extensions 'none' when -x509 is not given\n"); } - if (gen_x509 && infile == NULL) - newreq = 1; + if (infile == NULL) { + if (gen_x509) + newreq = 1; + else if (!newreq) + BIO_printf(bio_err, + "Warning: Will read cert request from stdin since no -in option is given\n"); + } if (!app_passwd(passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -511,9 +524,7 @@ int req_main(int argc, char **argv) goto end; if (req_conf != NULL) { - p = NCONF_get_string(req_conf, NULL, "oid_file"); - if (p == NULL) - ERR_clear_error(); + p = app_conf_try_string(req_conf, NULL, "oid_file"); if (p != NULL) { BIO *oid_bio = BIO_new_file(p, "r"); @@ -532,35 +543,28 @@ int req_main(int argc, char **argv) /* Check that any specified digest is fetchable */ if (digest != NULL) { - if (!opt_md(digest, &md)) { - ERR_clear_error(); + if (!opt_check_md(digest)) goto opthelp; - } - EVP_MD_free(md); } else { /* No digest specified, default to configuration */ - p = NCONF_get_string(req_conf, section, "default_md"); - if (p == NULL) - ERR_clear_error(); - else + p = app_conf_try_string(req_conf, section, "default_md"); + if (p != NULL) digest = p; } - if (extensions == NULL) { - extensions = NCONF_get_string(req_conf, section, V3_EXTENSIONS); - if (extensions == NULL) - ERR_clear_error(); - } - if (extensions != NULL) { - /* Check syntax of file */ + if (extsect == NULL) + extsect = app_conf_try_string(req_conf, section, + gen_x509 ? V3_EXTENSIONS : REQ_EXTENSIONS); + if (extsect != NULL) { + /* Check syntax of extension section in config file */ X509V3_CTX ctx; X509V3_set_ctx_test(&ctx); X509V3_set_nconf(&ctx, req_conf); - if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { + if (!X509V3_EXT_add_nconf(req_conf, &ctx, extsect, NULL)) { BIO_printf(bio_err, - "Error checking x509 extension section %s\n", - extensions); + "Error checking %s extension section %s\n", + gen_x509 ? "x509" : "request", extsect); goto end; } } @@ -576,69 +580,42 @@ int req_main(int argc, char **argv) } } - if (passin == NULL) { + if (passin == NULL) passin = nofree_passin = - NCONF_get_string(req_conf, section, "input_password"); - if (passin == NULL) - ERR_clear_error(); - } + app_conf_try_string(req_conf, section, "input_password"); - if (passout == NULL) { + if (passout == NULL) passout = nofree_passout = - NCONF_get_string(req_conf, section, "output_password"); - if (passout == NULL) - ERR_clear_error(); - } - - p = NCONF_get_string(req_conf, section, STRING_MASK); - if (p == NULL) - ERR_clear_error(); + app_conf_try_string(req_conf, section, "output_password"); + p = app_conf_try_string(req_conf, section, STRING_MASK); if (p != NULL && !ASN1_STRING_set_default_mask_asc(p)) { BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); goto end; } if (chtype != MBSTRING_UTF8) { - p = NCONF_get_string(req_conf, section, UTF8_IN); - if (p == NULL) - ERR_clear_error(); - else if (strcmp(p, "yes") == 0) + p = app_conf_try_string(req_conf, section, UTF8_IN); + if (p != NULL && strcmp(p, "yes") == 0) chtype = MBSTRING_UTF8; } - if (req_exts == NULL) { - req_exts = NCONF_get_string(req_conf, section, REQ_EXTENSIONS); - if (req_exts == NULL) - ERR_clear_error(); - } - if (req_exts != NULL) { - /* Check syntax of file */ - X509V3_CTX ctx; - - X509V3_set_ctx_test(&ctx); - X509V3_set_nconf(&ctx, req_conf); - if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { - BIO_printf(bio_err, - "Error checking request extension section %s\n", - req_exts); - goto end; - } - } - if (keyfile != NULL) { pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); if (pkey == NULL) goto end; app_RAND_load_conf(req_conf, section); } + if (keyalg != NULL && pkey != NULL) { + BIO_printf(bio_err, + "Warning: Not generating key via given -newkey option since -key is given\n"); + /* Better throw an error in this case */ + } if (newreq && pkey == NULL) { app_RAND_load_conf(req_conf, section); - if (!NCONF_get_number(req_conf, section, BITS, &newkey_len)) { - ERR_clear_error(); + if (!app_conf_try_number(req_conf, section, BITS, &newkey_len)) newkey_len = DEFAULT_KEY_LENGTH; - } genctx = set_keygen_ctx(keyalg, &keyalgstr, &newkey_len, gen_eng); if (genctx == NULL) @@ -681,8 +658,9 @@ int req_main(int argc, char **argv) } } - EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(genctx, bio_err); + if (progress) + EVP_PKEY_CTX_set_cb(genctx, progress_cb); pkey = app_keygen(genctx, keyalgstr, newkey_len, verbose); if (pkey == NULL) @@ -691,11 +669,8 @@ int req_main(int argc, char **argv) EVP_PKEY_CTX_free(genctx); genctx = NULL; } - if (keyout == NULL && keyfile == NULL) { - keyout = NCONF_get_string(req_conf, section, KEYFILE); - if (keyout == NULL) - ERR_clear_error(); - } + if (keyout == NULL && keyfile == NULL) + keyout = app_conf_try_string(req_conf, section, KEYFILE); if (pkey != NULL && (keyfile == NULL || keyout != NULL)) { if (verbose) { @@ -709,14 +684,10 @@ int req_main(int argc, char **argv) if (out == NULL) goto end; - p = NCONF_get_string(req_conf, section, "encrypt_rsa_key"); - if (p == NULL) { - ERR_clear_error(); - p = NCONF_get_string(req_conf, section, "encrypt_key"); - if (p == NULL) - ERR_clear_error(); - } - if ((p != NULL) && (strcmp(p, "no") == 0)) + p = app_conf_try_string(req_conf, section, "encrypt_rsa_key"); + if (p == NULL) + p = app_conf_try_string(req_conf, section, "encrypt_key"); + if (p != NULL && strcmp(p, "no") == 0) cipher = NULL; if (noenc) cipher = NULL; @@ -747,10 +718,17 @@ int req_main(int argc, char **argv) goto end; if (!newreq) { - req = load_csr(infile /* if NULL, reads from stdin */, - informat, "X509 request"); + if (keyfile != NULL) + BIO_printf(bio_err, + "Warning: Not placing -key in cert or request since request is used\n"); + req = load_csr_autofmt(infile /* if NULL, reads from stdin */, + informat, vfyopts, "X509 request"); if (req == NULL) goto end; + } else if (infile != NULL) { + BIO_printf(bio_err, + "Warning: Ignoring -in option since -new or -newkey or -precert is given\n"); + /* Better throw an error in this case, as done in the x509 app */ } if (CAkeyfile == NULL) @@ -791,7 +769,7 @@ int req_main(int argc, char **argv) goto end; } - if (!make_REQ(req, pkey, fsubj, multirdn, !gen_x509, chtype)){ + if (!make_REQ(req, pkey, fsubj, multirdn, !gen_x509, chtype)) { BIO_printf(bio_err, "Error making certificate request\n"); goto end; } @@ -806,6 +784,10 @@ int req_main(int argc, char **argv) X509_NAME *n_subj = fsubj != NULL ? fsubj : X509_REQ_get_subject_name(req); + if (CAcert != NULL && keyfile != NULL) + BIO_printf(bio_err, + "Warning: Not using -key or -newkey for signing since -CA option is given\n"); + if ((new_x509 = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; @@ -844,26 +826,23 @@ int req_main(int argc, char **argv) if (CAcert == NULL) { if (!X509V3_set_issuer_pkey(&ext_ctx, issuer_key)) goto end; - ERR_set_mark(); - if (!X509_check_private_key(new_x509, issuer_key)) + if (!cert_matches_key(new_x509, issuer_key)) BIO_printf(bio_err, "Warning: Signature key and public key of cert do not match\n"); - ERR_pop_to_mark(); } X509V3_set_nconf(&ext_ctx, req_conf); /* Add extensions */ - if (extensions != NULL - && !X509V3_EXT_add_nconf(req_conf, &ext_ctx, extensions, - new_x509)) { + if (extsect != NULL + && !X509V3_EXT_add_nconf(req_conf, &ext_ctx, extsect, new_x509)) { BIO_printf(bio_err, "Error adding x509 extensions from section %s\n", - extensions); + extsect); goto end; } if (addext_conf != NULL && !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, "default", new_x509)) { - BIO_printf(bio_err, "Error adding extensions defined via -addext\n"); + BIO_printf(bio_err, "Error adding x509 extensions defined via -addext\n"); goto end; } @@ -876,28 +855,32 @@ int req_main(int argc, char **argv) } } - i = do_X509_sign(new_x509, issuer_key, digest, sigopts, &ext_ctx); + i = do_X509_sign(new_x509, x509v1, issuer_key, digest, sigopts, + &ext_ctx); if (!i) goto end; } else { X509V3_CTX ext_ctx; + if (precert) { + BIO_printf(bio_err, + "Warning: Ignoring -precert flag since no cert is produced\n"); + } /* Set up V3 context struct */ - X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); + X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, X509V3_CTX_REPLACE); X509V3_set_nconf(&ext_ctx, req_conf); /* Add extensions */ - if (req_exts != NULL - && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx, - req_exts, req)) { + if (extsect != NULL + && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx, extsect, req)) { BIO_printf(bio_err, "Error adding request extensions from section %s\n", - req_exts); + extsect); goto end; } if (addext_conf != NULL && !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, "default", req)) { - BIO_printf(bio_err, "Error adding extensions defined via -addext\n"); + BIO_printf(bio_err, "Error adding request extensions defined via -addext\n"); goto end; } i = do_X509_REQ_sign(req, pkey, digest, sigopts); @@ -938,7 +921,7 @@ int req_main(int argc, char **argv) if (i == 0) BIO_printf(bio_err, "Certificate request self-signature verify failure\n"); else /* i > 0 */ - BIO_printf(bio_err, "Certificate request self-signature verify OK\n"); + BIO_printf(bio_out, "Certificate request self-signature verify OK\n"); } if (noout && !text && !modulus && !subject && !pubkey) { @@ -1073,16 +1056,12 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj, STACK_OF(CONF_VALUE) *dn_sk = NULL, *attr_sk = NULL; char *tmp, *dn_sect, *attr_sect; - tmp = NCONF_get_string(req_conf, section, PROMPT); - if (tmp == NULL) - ERR_clear_error(); - if ((tmp != NULL) && strcmp(tmp, "no") == 0) + tmp = app_conf_try_string(req_conf, section, PROMPT); + if (tmp != NULL && strcmp(tmp, "no") == 0) no_prompt = 1; - dn_sect = NCONF_get_string(req_conf, section, DISTINGUISHED_NAME); - if (dn_sect == NULL) { - ERR_clear_error(); - } else { + dn_sect = app_conf_try_string(req_conf, section, DISTINGUISHED_NAME); + if (dn_sect != NULL) { dn_sk = NCONF_get_section(req_conf, dn_sect); if (dn_sk == NULL) { BIO_printf(bio_err, "Unable to get '%s' section\n", dn_sect); @@ -1090,10 +1069,8 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj, } } - attr_sect = NCONF_get_string(req_conf, section, ATTRIBUTES); - if (attr_sect == NULL) { - ERR_clear_error(); - } else { + attr_sect = app_conf_try_string(req_conf, section, ATTRIBUTES); + if (attr_sect != NULL) { attr_sk = NCONF_get_section(req_conf, attr_sect); if (attr_sk == NULL) { BIO_printf(bio_err, "Unable to get '%s' section\n", attr_sect); @@ -1189,31 +1166,23 @@ static int prompt_info(X509_REQ *req, goto start; if (!join(buf, sizeof(buf), v->name, "_default", "Name")) return 0; - if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { - ERR_clear_error(); + if ((def = app_conf_try_string(req_conf, dn_sect, buf)) == NULL) def = ""; - } if (!join(buf, sizeof(buf), v->name, "_value", "Name")) return 0; - if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { - ERR_clear_error(); + if ((value = app_conf_try_string(req_conf, dn_sect, buf)) == NULL) value = NULL; - } if (!join(buf, sizeof(buf), v->name, "_min", "Name")) return 0; - if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { - ERR_clear_error(); + if (!app_conf_try_number(req_conf, dn_sect, buf, &n_min)) n_min = -1; - } if (!join(buf, sizeof(buf), v->name, "_max", "Name")) return 0; - if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { - ERR_clear_error(); + if (!app_conf_try_number(req_conf, dn_sect, buf, &n_max)) n_max = -1; - } if (!add_DN_object(subj, v->value, def, value, nid, n_min, n_max, chtype, mval)) @@ -1247,33 +1216,23 @@ static int prompt_info(X509_REQ *req, if (!join(buf, sizeof(buf), type, "_default", "Name")) return 0; - if ((def = NCONF_get_string(req_conf, attr_sect, buf)) - == NULL) { - ERR_clear_error(); + def = app_conf_try_string(req_conf, attr_sect, buf); + if (def == NULL) def = ""; - } if (!join(buf, sizeof(buf), type, "_value", "Name")) return 0; - if ((value = NCONF_get_string(req_conf, attr_sect, buf)) - == NULL) { - ERR_clear_error(); - value = NULL; - } + value = app_conf_try_string(req_conf, attr_sect, buf); if (!join(buf, sizeof(buf), type, "_min", "Name")) return 0; - if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { - ERR_clear_error(); + if (!app_conf_try_number(req_conf, attr_sect, buf, &n_min)) n_min = -1; - } if (!join(buf, sizeof(buf), type, "_max", "Name")) return 0; - if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { - ERR_clear_error(); + if (!app_conf_try_number(req_conf, attr_sect, buf, &n_max)) n_max = -1; - } if (!add_attribute_object(req, v->value, def, value, nid, n_min, @@ -1666,21 +1625,3 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, return gctx; } -static int genpkey_cb(EVP_PKEY_CTX *ctx) -{ - char c = '*'; - BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - int p; - p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); - if (p == 0) - c = '.'; - if (p == 1) - c = '+'; - if (p == 2) - c = '*'; - if (p == 3) - c = '\n'; - BIO_write(b, &c, 1); - (void)BIO_flush(b); - return 1; -} diff --git a/apps/rsa.c b/apps/rsa.c index 0da342c38f..9a4d16cbb0 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -139,6 +139,7 @@ int rsa_main(int argc, char **argv) int selection = 0; OSSL_ENCODER_CTX *ectx = NULL; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, rsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -217,15 +218,12 @@ int rsa_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; - if (ciphername != NULL) { - if (!opt_cipher(ciphername, &enc)) - goto opthelp; - } - private = (text && !pubin) || (!pubout && !noout) ? 1 : 0; + if (!opt_cipher(ciphername, &enc)) + goto opthelp; + private = (text && !pubin) || (!pubout && !noout); if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); diff --git a/apps/rsautl.c b/apps/rsautl.c index a61f21f864..3ee8224f48 100644 --- a/apps/rsautl.c +++ b/apps/rsautl.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -47,9 +47,9 @@ const OPTIONS rsautl_options[] = { OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input file"}, - {"inkey", OPT_INKEY, 's', "Input key"}, + {"inkey", OPT_INKEY, 's', "Input key, by default an RSA private key"}, {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, - {"pubin", OPT_PUBIN, '-', "Input is an RSA public"}, + {"pubin", OPT_PUBIN, '-', "Input key is an RSA public pkey"}, {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"}, {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, @@ -169,8 +169,7 @@ int rsautl_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) diff --git a/apps/s_client.c b/apps/s_client.c index 76ffbf36dc..78a44755cb 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -58,6 +58,46 @@ typedef unsigned int u_int; #define BUFSIZZ 1024*8 #define S_CLIENT_IRC_READ_TIMEOUT 8 +#define USER_DATA_MODE_NONE 0 +#define USER_DATA_MODE_BASIC 1 +#define USER_DATA_MODE_ADVANCED 2 + +#define USER_DATA_PROCESS_BAD_ARGUMENT 0 +#define USER_DATA_PROCESS_SHUT 1 +#define USER_DATA_PROCESS_RESTART 2 +#define USER_DATA_PROCESS_NO_DATA 3 +#define USER_DATA_PROCESS_CONTINUE 4 + +struct user_data_st { + /* SSL connection we are processing commands for */ + SSL *con; + + /* Buffer where we are storing data supplied by the user */ + char *buf; + + /* Allocated size of the buffer */ + size_t bufmax; + + /* Amount of the buffer actually used */ + size_t buflen; + + /* Current location in the buffer where we will read from next*/ + size_t bufoff; + + /* The mode we are using for processing commands */ + int mode; + + /* Whether FIN has ben sent on the stream */ + int isfin; +}; + +static void user_data_init(struct user_data_st *user_data, SSL *con, char *buf, + size_t bufmax, int mode); +static int user_data_add(struct user_data_st *user_data, size_t i); +static int user_data_process(struct user_data_st *user_data, size_t *len, + size_t *off); +static int user_data_has_data(struct user_data_st *user_data); + static char *prog; static int c_debug = 0; static int c_showcerts = 0; @@ -75,6 +115,9 @@ static int ocsp_resp_cb(SSL *s, void *arg); static int ldap_ExtendedResponse_parse(const char *buf, long rem); static int is_dNS_name(const char *host); +static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 }; +static int enable_server_rpk = 0; + static int saved_errno; static void save_errno(void) @@ -435,7 +478,7 @@ typedef enum OPTION_choice { OPT_XMPPHOST, OPT_VERIFY, OPT_NAMEOPT, OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, - OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO, + OPT_BRIEF, OPT_PREXIT, OPT_NO_INTERACTIVE, OPT_CRLF, OPT_QUIET, OPT_NBIO, OPT_SSL_CLIENT_ENGINE, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG, OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG, @@ -447,8 +490,8 @@ typedef enum OPTION_choice { #endif OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, - OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, - OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, + OPT_DTLS1_2, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, + OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_NEXTPROTONEG, OPT_ALPN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, @@ -457,17 +500,21 @@ typedef enum OPTION_choice { OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST, OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE, + OPT_TFO, OPT_V_ENUM, OPT_X_ENUM, OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF, - OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS, - OPT_DANE_TLSA_DOMAIN, + OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_ADV, OPT_PROXY, OPT_PROXY_USER, + OPT_PROXY_PASS, OPT_DANE_TLSA_DOMAIN, #ifndef OPENSSL_NO_CT OPT_CT, OPT_NOCT, OPT_CTLOG_FILE, #endif OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME, OPT_ENABLE_PHA, + OPT_ENABLE_SERVER_RPK, + OPT_ENABLE_CLIENT_RPK, OPT_SCTP_LABEL_BUG, + OPT_KTLS, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -539,6 +586,9 @@ const OPTIONS s_client_options[] = { "Do not load certificates from the default certificates store"}, {"requestCAfile", OPT_REQCAFILE, '<', "PEM format file of CA names to send to the server"}, +#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO) + {"tfo", OPT_TFO, '-', "Connect using TCP Fast Open"}, +#endif {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"}, {"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's', "DANE TLSA rrdata presentation form"}, @@ -569,6 +619,8 @@ const OPTIONS s_client_options[] = { "Restrict output to brief summary of connection parameters"}, {"prexit", OPT_PREXIT, '-', "Print session information when the program exits"}, + {"no-interactive", OPT_NO_INTERACTIVE, '-', + "Don't run the client in the interactive mode"}, OPT_SECTION("Debug"), {"showcerts", OPT_SHOWCERTS, '-', @@ -595,6 +647,7 @@ const OPTIONS s_client_options[] = { #endif {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, + {"adv", OPT_ADV, '-', "Advanced command mode"}, {"servername", OPT_SERVERNAME, 's', "Set TLS extension servername (SNI) in ClientHello (default)"}, {"noservername", OPT_NOSERVERNAME, '-', @@ -631,6 +684,7 @@ const OPTIONS s_client_options[] = { #endif #ifndef OPENSSL_NO_DTLS {"dtls", OPT_DTLS, '-', "Use any version of DTLS"}, + {"quic", OPT_QUIC, '-', "Use QUIC"}, {"timeout", OPT_TIMEOUT, '-', "Enable send/receive timeout on DTLS connections"}, {"mtu", OPT_MTU, 'p', "Set the link layer MTU"}, @@ -651,6 +705,8 @@ const OPTIONS s_client_options[] = { #endif {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, + {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"}, + {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"}, #ifndef OPENSSL_NO_SRTP {"use_srtp", OPT_USE_SRTP, 's', "Offer SRTP key management with a colon-separated profile list"}, @@ -665,6 +721,9 @@ const OPTIONS s_client_options[] = { {"srp_strength", OPT_SRP_STRENGTH, 'p', "(deprecated) Minimal length in bits for N"}, #endif +#ifndef OPENSSL_NO_KTLS + {"ktls", OPT_KTLS, '-', "Enable Kernel TLS for sending and receiving"}, +#endif OPT_R_OPTIONS, OPT_S_OPTIONS, @@ -737,7 +796,8 @@ static const OPT_PAIR services[] = { #define IS_PROT_FLAG(o) \ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ - || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) + || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \ + || o == OPT_QUIC) /* Free |*dest| and optionally set it to a copy of |source|. */ static void freeandcopy(char **dest, const char *source) @@ -815,16 +875,19 @@ int s_client_main(int argc, char **argv) struct timeval timeout, *timeoutp; fd_set readfds, writefds; int noCApath = 0, noCAfile = 0, noCAstore = 0; - int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_UNDEF; + int build_chain = 0, cert_format = FORMAT_UNDEF; + size_t cbuf_len, cbuf_off; int key_format = FORMAT_UNDEF, crlf = 0, full_log = 1, mbuf_len = 0; int prexit = 0; + int nointeractive = 0; int sdebug = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0; - int sbuf_len, sbuf_off, cmdletters = 1; + int sbuf_len, sbuf_off, cmdmode = USER_DATA_MODE_BASIC; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; int starttls_proto = PROTO_OFF, crl_format = FORMAT_UNDEF, crl_download = 0; int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + int first_loop; #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) int at_eof = 0; #endif @@ -880,15 +943,21 @@ int s_client_main(int argc, char **argv) #endif BIO *bio_c_msg = NULL; const char *keylog_file = NULL, *early_data_file = NULL; -#ifndef OPENSSL_NO_DTLS - int isdtls = 0; -#endif + int isdtls = 0, isquic = 0; char *psksessf = NULL; int enable_pha = 0; + int enable_client_rpk = 0; #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif int ignore_unexpected_eof = 0; +#ifndef OPENSSL_NO_KTLS + int enable_ktls = 0; +#endif + int tfo = 0; + int is_infinite; + BIO_ADDR *peer_addr = NULL; + struct user_data_st user_data; FD_ZERO(&readfds); FD_ZERO(&writefds); @@ -1073,6 +1142,9 @@ int s_client_main(int argc, char **argv) case OPT_PREXIT: prexit = 1; break; + case OPT_NO_INTERACTIVE: + nointeractive = 1; + break; case OPT_CRLF: crlf = 1; break; @@ -1083,7 +1155,10 @@ int s_client_main(int argc, char **argv) c_nbio = 1; break; case OPT_NOCMDS: - cmdletters = 0; + cmdmode = USER_DATA_MODE_NONE; + break; + case OPT_ADV: + cmdmode = USER_DATA_MODE_ADVANCED; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 1); @@ -1210,6 +1285,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_DTLS isdtls = 0; #endif + isquic = 0; break; case OPT_TLS1_3: min_version = TLS1_3_VERSION; @@ -1218,6 +1294,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_DTLS isdtls = 0; #endif + isquic = 0; break; case OPT_TLS1_2: min_version = TLS1_2_VERSION; @@ -1226,6 +1303,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_DTLS isdtls = 0; #endif + isquic = 0; break; case OPT_TLS1_1: min_version = TLS1_1_VERSION; @@ -1234,6 +1312,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_DTLS isdtls = 0; #endif + isquic = 0; break; case OPT_TLS1: min_version = TLS1_VERSION; @@ -1242,12 +1321,14 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_DTLS isdtls = 0; #endif + isquic = 0; break; case OPT_DTLS: #ifndef OPENSSL_NO_DTLS meth = DTLS_client_method(); socket_type = SOCK_DGRAM; isdtls = 1; + isquic = 0; #endif break; case OPT_DTLS1: @@ -1257,6 +1338,7 @@ int s_client_main(int argc, char **argv) max_version = DTLS1_VERSION; socket_type = SOCK_DGRAM; isdtls = 1; + isquic = 0; #endif break; case OPT_DTLS1_2: @@ -1266,6 +1348,19 @@ int s_client_main(int argc, char **argv) max_version = DTLS1_2_VERSION; socket_type = SOCK_DGRAM; isdtls = 1; + isquic = 0; +#endif + break; + case OPT_QUIC: +#ifndef OPENSSL_NO_QUIC + meth = OSSL_QUIC_client_method(); + min_version = 0; + max_version = 0; + socket_type = SOCK_DGRAM; +# ifndef OPENSSL_NO_DTLS + isdtls = 0; +# endif + isquic = 1; #endif break; case OPT_SCTP: @@ -1399,6 +1494,9 @@ int s_client_main(int argc, char **argv) if (!opt_pair(opt_arg(), services, &starttls_proto)) goto end; break; + case OPT_TFO: + tfo = 1; + break; case OPT_SERVERNAME: servername = opt_arg(); break; @@ -1462,12 +1560,22 @@ int s_client_main(int argc, char **argv) case OPT_ENABLE_PHA: enable_pha = 1; break; + case OPT_KTLS: +#ifndef OPENSSL_NO_KTLS + enable_ktls = 1; +#endif + break; + case OPT_ENABLE_SERVER_RPK: + enable_server_rpk = 1; + break; + case OPT_ENABLE_CLIENT_RPK: + enable_client_rpk = 1; + break; } } /* Optional argument is connect string if -connect not used. */ - argc = opt_num_rest(); - if (argc == 1) { + if (opt_num_rest() == 1) { /* Don't allow -connect and a separate argument. */ if (connectstr != NULL) { BIO_printf(bio_err, @@ -1477,12 +1585,15 @@ int s_client_main(int argc, char **argv) } connect_type = use_inet; freeandcopy(&connectstr, *opt_rest()); - } else if (argc != 0) { + } else if (!opt_check_rest_arg(NULL)) { goto opthelp; } if (!app_RAND_load()) goto end; + if (c_ign_eof) + cmdmode = USER_DATA_MODE_NONE; + if (count4or6 >= 2) { BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog); goto opthelp; @@ -1527,6 +1638,7 @@ int s_client_main(int argc, char **argv) } if (proxystr != NULL) { +#ifndef OPENSSL_NO_HTTP int res; char *tmp_host = host, *tmp_port = port; @@ -1561,8 +1673,14 @@ int s_client_main(int argc, char **argv) "%s: -proxy argument malformed or ambiguous\n", prog); goto end; } +#else + BIO_printf(bio_err, + "%s: -proxy not supported in no-http build\n", prog); + goto end; +#endif } + if (bindstr != NULL) { int res; res = BIO_parse_hostserv(bindstr, &bindhost, &bindport, @@ -1724,6 +1842,10 @@ int s_client_main(int argc, char **argv) if (ignore_unexpected_eof) SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); +#ifndef OPENSSL_NO_KTLS + if (enable_ktls) + SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS); +#endif if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { BIO_printf(bio_err, "Error setting verify params\n"); @@ -1933,7 +2055,7 @@ int s_client_main(int argc, char **argv) /* * In TLSv1.3 NewSessionTicket messages arrive after the handshake and can - * come at any time. Therefore we use a callback to write out the session + * come at any time. Therefore, we use a callback to write out the session * when we know about it. This approach works for < TLSv1.3 as well. */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT @@ -1950,6 +2072,18 @@ int s_client_main(int argc, char **argv) if (enable_pha) SSL_set_post_handshake_auth(con, 1); + if (enable_client_rpk) + if (!SSL_set1_client_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) { + BIO_printf(bio_err, "Error setting client certificate types\n"); + goto end; + } + if (enable_server_rpk) { + if (!SSL_set1_server_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) { + BIO_printf(bio_err, "Error setting server certificate types\n"); + goto end; + } + } + if (sess_in != NULL) { SSL_SESSION *sess; BIO *stmp = BIO_new_file(sess_in, "r"); @@ -1979,7 +2113,7 @@ int s_client_main(int argc, char **argv) if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) { if (servername == NULL) { - if(host == NULL || is_dNS_name(host)) + if (host == NULL || is_dNS_name(host)) servername = (host == NULL) ? "localhost" : host; } if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) { @@ -2013,22 +2147,48 @@ int s_client_main(int argc, char **argv) "-dane_tlsa_domain option.\n", prog); goto end; } +#ifndef OPENSSL_NO_DTLS + if (isdtls && tfo) { + BIO_printf(bio_err, "%s: DTLS does not support the -tfo option\n", prog); + goto end; + } +#endif +#ifndef OPENSSL_NO_QUIC + if (isquic && tfo) { + BIO_printf(bio_err, "%s: QUIC does not support the -tfo option\n", prog); + goto end; + } + if (isquic && alpn_in == NULL) { + BIO_printf(bio_err, "%s: QUIC requires ALPN to be specified (e.g. \"h3\" for HTTP/3) via the -alpn option\n", prog); + goto end; + } +#endif + if (tfo) + BIO_printf(bio_c_out, "Connecting via TFO\n"); re_start: if (init_client(&sock, host, port, bindhost, bindport, socket_family, - socket_type, protocol) == 0) { + socket_type, protocol, tfo, !isquic, &peer_addr) == 0) { BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); BIO_closesocket(sock); goto end; } BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock); - if (c_nbio) { + /* + * QUIC always uses a non-blocking socket - and we have to switch on + * non-blocking mode at the SSL level + */ + if (c_nbio || isquic) { if (!BIO_socket_nbio(sock, 1)) { ERR_print_errors(bio_err); goto end; } - BIO_printf(bio_c_out, "Turned on non blocking io\n"); + if (c_nbio) { + if (isquic && !SSL_set_blocking_mode(con, 0)) + goto end; + BIO_printf(bio_c_out, "Turned on non blocking io\n"); + } } #ifndef OPENSSL_NO_DTLS if (isdtls) { @@ -2089,6 +2249,15 @@ int s_client_main(int argc, char **argv) } } else #endif /* OPENSSL_NO_DTLS */ +#ifndef OPENSSL_NO_QUIC + if (isquic) { + sbio = BIO_new_dgram(sock, BIO_NOCLOSE); + if (!SSL_set1_initial_peer_addr(con, peer_addr)) { + BIO_printf(bio_err, "Failed to set the initial peer address\n"); + goto shut; + } + } else +#endif sbio = BIO_new_socket(sock, BIO_NOCLOSE); if (sbio == NULL) { @@ -2098,6 +2267,12 @@ int s_client_main(int argc, char **argv) goto end; } + /* Now that we're using a BIO... */ + if (tfo) { + (void)BIO_set_conn_address(sbio, peer_addr); + (void)BIO_set_tfo(sbio, 1); + } + if (nbio_test) { BIO *test; @@ -2150,18 +2325,21 @@ int s_client_main(int argc, char **argv) tty_on = 0; read_ssl = 1; write_ssl = 1; + first_loop = 1; cbuf_len = 0; cbuf_off = 0; sbuf_len = 0; sbuf_off = 0; +#ifndef OPENSSL_NO_HTTP if (proxystr != NULL) { /* Here we must use the connect string target host & port */ if (!OSSL_HTTP_proxy_connect(sbio, thost, tport, proxyuser, proxypass, 0 /* no timeout */, bio_err, prog)) goto shut; } +#endif switch ((PROTOCOL_CHOICE) starttls_proto) { case PROTO_OFF: @@ -2577,7 +2755,7 @@ int s_client_main(int argc, char **argv) */ if (mbuf_len > 1 && mbuf[0] == '"') { make_uppercase(mbuf); - if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0) + if (HAS_PREFIX(mbuf, "\"STARTTLS\"")) foundit = 1; } } while (mbuf_len > 1 && mbuf[0] == '"'); @@ -2605,7 +2783,7 @@ int s_client_main(int argc, char **argv) */ strncpy(sbuf, mbuf, 2); make_uppercase(sbuf); - if (strncmp(sbuf, "OK", 2) != 0) { + if (!HAS_PREFIX(sbuf, "OK")) { BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf); goto shut; } @@ -2720,11 +2898,14 @@ int s_client_main(int argc, char **argv) BIO_free(edfile); } + user_data_init(&user_data, con, cbuf, BUFSIZZ, cmdmode); for (;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); - if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout)) + if ((isdtls || isquic) + && SSL_get_event_timeout(con, &timeout, &is_infinite) + && !is_infinite) timeoutp = &timeout; else timeoutp = NULL; @@ -2765,6 +2946,38 @@ int s_client_main(int argc, char **argv) } } + if (!write_ssl) { + do { + switch (user_data_process(&user_data, &cbuf_len, &cbuf_off)) { + default: + BIO_printf(bio_err, "ERROR\n"); + /* fall through */ + case USER_DATA_PROCESS_SHUT: + ret = 0; + goto shut; + + case USER_DATA_PROCESS_RESTART: + goto re_start; + + case USER_DATA_PROCESS_NO_DATA: + break; + + case USER_DATA_PROCESS_CONTINUE: + write_ssl = 1; + break; + } + } while (!write_ssl + && cbuf_len == 0 + && user_data_has_data(&user_data)); + if (cbuf_len > 0) { + read_tty = 0; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + } else { + read_tty = 1; + } + } + ssl_pending = read_ssl && SSL_has_pending(con); if (!ssl_pending) { @@ -2782,15 +2995,26 @@ int s_client_main(int argc, char **argv) openssl_fdset(fileno_stdout(), &writefds); #endif } - if (read_ssl) + + /* + * Note that for QUIC we never actually check FD_ISSET() for the + * underlying network fds. We just rely on select waking up when + * they become readable/writeable and then SSL_handle_events() doing + * the right thing. + */ + if ((!isquic && read_ssl) + || (isquic && SSL_net_read_desired(con))) openssl_fdset(SSL_get_fd(con), &readfds); - if (write_ssl) + if ((!isquic && write_ssl) + || (isquic && (first_loop || SSL_net_write_desired(con)))) openssl_fdset(SSL_get_fd(con), &writefds); #else if (!tty_on || !write_tty) { - if (read_ssl) + if ((!isquic && read_ssl) + || (isquic && SSL_net_read_desired(con))) openssl_fdset(SSL_get_fd(con), &readfds); - if (write_ssl) + if ((!isquic && write_ssl) + || (isquic && (first_loop || SSL_net_write_desired(con)))) openssl_fdset(SSL_get_fd(con), &writefds); } #endif @@ -2805,7 +3029,7 @@ int s_client_main(int argc, char **argv) #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) /* * Under Windows/DOS we make the assumption that we can always - * write to the tty: therefore if we need to write to the tty we + * write to the tty: therefore, if we need to write to the tty we * just fall through. Otherwise we timeout the select every * second and see if there are any keypresses. Note: this is a * hack, in a proper Windows application we wouldn't do this. @@ -2834,10 +3058,17 @@ int s_client_main(int argc, char **argv) } } - if (SSL_is_dtls(con) && DTLSv1_handle_timeout(con) > 0) - BIO_printf(bio_err, "TIMEOUT occurred\n"); + if (timeoutp != NULL) { + SSL_handle_events(con); + if (isdtls + && !FD_ISSET(SSL_get_fd(con), &readfds) + && !FD_ISSET(SSL_get_fd(con), &writefds)) + BIO_printf(bio_err, "TIMEOUT occurred\n"); + } - if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) { + if (!ssl_pending + && ((!isquic && FD_ISSET(SSL_get_fd(con), &writefds)) + || (isquic && (cbuf_len > 0 || first_loop)))) { k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len); switch (SSL_get_error(con, k)) { case SSL_ERROR_NONE: @@ -2846,7 +3077,7 @@ int s_client_main(int argc, char **argv) if (k <= 0) goto end; /* we have done a write(con,NULL,0); */ - if (cbuf_len <= 0) { + if (cbuf_len == 0) { read_tty = 1; write_ssl = 0; } else { /* if (cbuf_len > 0) */ @@ -2888,9 +3119,12 @@ int s_client_main(int argc, char **argv) case SSL_ERROR_SYSCALL: if ((k != 0) || (cbuf_len != 0)) { - BIO_printf(bio_err, "write:errno=%d\n", - get_last_socket_error()); - goto shut; + int sockerr = get_last_socket_error(); + + if (!tfo || sockerr != EISCONN) { + BIO_printf(bio_err, "write:errno=%d\n", sockerr); + goto shut; + } } else { read_tty = 1; write_ssl = 0; @@ -2927,7 +3161,8 @@ int s_client_main(int argc, char **argv) read_ssl = 1; write_tty = 0; } - } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) { + } else if (ssl_pending + || (!isquic && FD_ISSET(SSL_get_fd(con), &readfds))) { #ifdef RENEG { static int iiii; @@ -2990,6 +3225,13 @@ int s_client_main(int argc, char **argv) goto shut; } } + + /* don't wait for client input in the non-interactive mode */ + else if (nointeractive) { + ret = 0; + goto shut; + } + /* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */ #if defined(OPENSSL_SYS_MSDOS) else if (has_stdin_waiting()) @@ -3022,34 +3264,19 @@ int s_client_main(int argc, char **argv) at_eof = 1; #endif - if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) { + if (!c_ign_eof && i <= 0) { BIO_printf(bio_err, "DONE\n"); ret = 0; goto shut; } - if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) { - BIO_printf(bio_err, "RENEGOTIATING\n"); - SSL_renegotiate(con); - cbuf_len = 0; - } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) - && cmdletters) { - BIO_printf(bio_err, "KEYUPDATE\n"); - SSL_key_update(con, - cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED - : SSL_KEY_UPDATE_NOT_REQUESTED); - cbuf_len = 0; - } else { - cbuf_len = i; - cbuf_off = 0; -#ifdef CHARSET_EBCDIC - ebcdic2ascii(cbuf, cbuf, i); -#endif + if (i > 0 && !user_data_add(&user_data, i)) { + ret = 0; + goto shut; } - - write_ssl = 1; read_tty = 0; } + first_loop = 0; } shut: @@ -3097,12 +3324,13 @@ int s_client_main(int argc, char **argv) X509_free(cert); sk_X509_CRL_pop_free(crls, X509_CRL_free); EVP_PKEY_free(key); - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); OPENSSL_free(pass); #ifndef OPENSSL_NO_SRP OPENSSL_free(srp_arg.srppassin); #endif OPENSSL_free(sname_alloc); + BIO_ADDR_free(peer_addr); OPENSSL_free(connectstr); OPENSSL_free(bindstr); OPENSSL_free(bindhost); @@ -3189,6 +3417,23 @@ static void print_stuff(BIO *bio, SSL *s, int full) } else { BIO_printf(bio, "no peer certificate available\n"); } + + /* Only display RPK information if configured */ + if (SSL_get_negotiated_client_cert_type(s) == TLSEXT_cert_type_rpk) + BIO_printf(bio, "Client-to-server raw public key negotiated\n"); + if (SSL_get_negotiated_server_cert_type(s) == TLSEXT_cert_type_rpk) + BIO_printf(bio, "Server-to-client raw public key negotiated\n"); + if (enable_server_rpk) { + EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s); + + if (peer_rpk != NULL) { + BIO_printf(bio, "Server raw public key\n"); + EVP_PKEY_print_public(bio, peer_rpk, 2, NULL); + } else { + BIO_printf(bio, "no peer rpk available\n"); + } + } + print_ca_names(bio, s); ssl_print_sigalgs(bio, s); @@ -3329,7 +3574,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) /* * We also print the verify results when we dump session information, * but in TLSv1.3 we may not get that right away (or at all) depending - * on when we get a NewSessionTicket. Therefore we print it now as well. + * on when we get a NewSessionTicket. Therefore, we print it now as well. */ verify_result = SSL_get_verify_result(s); BIO_printf(bio, "Verify return code: %ld (%s)\n", verify_result, @@ -3538,4 +3783,267 @@ static int is_dNS_name(const char *host) return isdnsname; } + +static void user_data_init(struct user_data_st *user_data, SSL *con, char *buf, + size_t bufmax, int mode) +{ + user_data->con = con; + user_data->buf = buf; + user_data->bufmax = bufmax; + user_data->buflen = 0; + user_data->bufoff = 0; + user_data->mode = mode; + user_data->isfin = 0; +} + +static int user_data_add(struct user_data_st *user_data, size_t i) +{ + if (user_data->buflen != 0 || i > user_data->bufmax) + return 0; + + user_data->buflen = i; + user_data->bufoff = 0; + + return 1; +} + +#define USER_COMMAND_HELP 0 +#define USER_COMMAND_QUIT 1 +#define USER_COMMAND_RECONNECT 2 +#define USER_COMMAND_RENEGOTIATE 3 +#define USER_COMMAND_KEY_UPDATE 4 +#define USER_COMMAND_FIN 5 + +static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg) +{ + switch (cmd) { + case USER_COMMAND_HELP: + /* This only ever occurs in advanced mode, so just emit advanced help */ + BIO_printf(bio_err, "Enter text to send to the peer followed by \n"); + BIO_printf(bio_err, "To issue a command insert {cmd} or {cmd:arg} anywhere in the text\n"); + BIO_printf(bio_err, "Entering {{ will send { to the peer\n"); + BIO_printf(bio_err, "The following commands are available\n"); + BIO_printf(bio_err, " {help}: Get this help text\n"); + BIO_printf(bio_err, " {quit}: Close the connection to the peer\n"); + BIO_printf(bio_err, " {reconnect}: Reconnect to the peer\n"); + if (SSL_is_quic(user_data->con)) { + BIO_printf(bio_err, " {fin}: Send FIN on the stream. No further writing is possible\n"); + } else if(SSL_version(user_data->con) == TLS1_3_VERSION) { + BIO_printf(bio_err, " {keyup:req|noreq}: Send a Key Update message\n"); + BIO_printf(bio_err, " Arguments:\n"); + BIO_printf(bio_err, " req = peer update requested (default)\n"); + BIO_printf(bio_err, " noreq = peer update not requested\n"); + } else { + BIO_printf(bio_err, " {reneg}: Attempt to renegotiate\n"); + } + BIO_printf(bio_err, "\n"); + return USER_DATA_PROCESS_NO_DATA; + + case USER_COMMAND_QUIT: + BIO_printf(bio_err, "DONE\n"); + return USER_DATA_PROCESS_SHUT; + + case USER_COMMAND_RECONNECT: + BIO_printf(bio_err, "RECONNECTING\n"); + do_ssl_shutdown(user_data->con); + SSL_set_connect_state(user_data->con); + BIO_closesocket(SSL_get_fd(user_data->con)); + return USER_DATA_PROCESS_RESTART; + + case USER_COMMAND_RENEGOTIATE: + BIO_printf(bio_err, "RENEGOTIATING\n"); + if (!SSL_renegotiate(user_data->con)) + break; + return USER_DATA_PROCESS_CONTINUE; + + case USER_COMMAND_KEY_UPDATE: { + int updatetype; + + if (OPENSSL_strcasecmp(arg, "req") == 0) + updatetype = SSL_KEY_UPDATE_REQUESTED; + else if (OPENSSL_strcasecmp(arg, "noreq") == 0) + updatetype = SSL_KEY_UPDATE_NOT_REQUESTED; + else + return USER_DATA_PROCESS_BAD_ARGUMENT; + BIO_printf(bio_err, "KEYUPDATE\n"); + if (!SSL_key_update(user_data->con, updatetype)) + break; + return USER_DATA_PROCESS_CONTINUE; + } + + case USER_COMMAND_FIN: + if (!SSL_stream_conclude(user_data->con, 0)) + break; + user_data->isfin = 1; + return USER_DATA_PROCESS_NO_DATA; + + default: + break; + } + + BIO_printf(bio_err, "ERROR\n"); + ERR_print_errors(bio_err); + + return USER_DATA_PROCESS_SHUT; +} + +static int user_data_process(struct user_data_st *user_data, size_t *len, + size_t *off) +{ + char *buf_start = user_data->buf + user_data->bufoff; + size_t outlen = user_data->buflen; + + if (user_data->buflen == 0) { + *len = 0; + *off = 0; + return USER_DATA_PROCESS_NO_DATA; + } + + if (user_data->mode == USER_DATA_MODE_BASIC) { + switch (buf_start[0]) { + case 'Q': + user_data->buflen = user_data->bufoff = *len = *off = 0; + return user_data_execute(user_data, USER_COMMAND_QUIT, NULL); + + case 'C': + user_data->buflen = user_data->bufoff = *len = *off = 0; + return user_data_execute(user_data, USER_COMMAND_RECONNECT, NULL); + + case 'R': + user_data->buflen = user_data->bufoff = *len = *off = 0; + return user_data_execute(user_data, USER_COMMAND_RENEGOTIATE, NULL); + + case 'K': + case 'k': + user_data->buflen = user_data->bufoff = *len = *off = 0; + return user_data_execute(user_data, USER_COMMAND_KEY_UPDATE, + buf_start[0] == 'K' ? "req" : "noreq"); + default: + break; + } + } else if (user_data->mode == USER_DATA_MODE_ADVANCED) { + char *cmd_start = buf_start; + + cmd_start[outlen] = '\0'; + for (;;) { + cmd_start = strchr(cmd_start, '{'); + if (cmd_start == buf_start && *(cmd_start + 1) == '{') { + /* The "{" is escaped, so skip it */ + cmd_start += 2; + buf_start++; + user_data->bufoff++; + user_data->buflen--; + outlen--; + continue; + } + break; + } + + if (cmd_start == buf_start) { + /* Command detected */ + char *cmd_end = strchr(cmd_start, '}'); + char *arg_start; + int cmd = -1, ret = USER_DATA_PROCESS_NO_DATA; + size_t oldoff; + + if (cmd_end == NULL) { + /* Malformed command */ + cmd_start[outlen - 1] = '\0'; + BIO_printf(bio_err, + "ERROR PROCESSING COMMAND. REST OF LINE IGNORED: %s\n", + cmd_start); + user_data->buflen = user_data->bufoff = *len = *off = 0; + return USER_DATA_PROCESS_NO_DATA; + } + *cmd_end = '\0'; + arg_start = strchr(cmd_start, ':'); + if (arg_start != NULL) { + *arg_start = '\0'; + arg_start++; + } + /* Skip over the { */ + cmd_start++; + /* + * Now we have cmd_start pointing to a NUL terminated string for + * the command, and arg_start either being NULL or pointing to a + * NUL terminated string for the argument. + */ + if (OPENSSL_strcasecmp(cmd_start, "help") == 0) { + cmd = USER_COMMAND_HELP; + } else if (OPENSSL_strcasecmp(cmd_start, "quit") == 0) { + cmd = USER_COMMAND_QUIT; + } else if (OPENSSL_strcasecmp(cmd_start, "reconnect") == 0) { + cmd = USER_COMMAND_RECONNECT; + } else if(SSL_is_quic(user_data->con)) { + if (OPENSSL_strcasecmp(cmd_start, "fin") == 0) + cmd = USER_COMMAND_FIN; + } if (SSL_version(user_data->con) == TLS1_3_VERSION) { + if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) { + cmd = USER_COMMAND_KEY_UPDATE; + if (arg_start == NULL) + arg_start = "req"; + } + } else { + /* (D)TLSv1.2 or below */ + if (OPENSSL_strcasecmp(cmd_start, "reneg") == 0) + cmd = USER_COMMAND_RENEGOTIATE; + } + if (cmd == -1) { + BIO_printf(bio_err, "UNRECOGNISED COMMAND (IGNORED): %s\n", + cmd_start); + } else { + ret = user_data_execute(user_data, cmd, arg_start); + if (ret == USER_DATA_PROCESS_BAD_ARGUMENT) { + BIO_printf(bio_err, "BAD ARGUMENT (COMMAND IGNORED): %s\n", + arg_start); + ret = USER_DATA_PROCESS_NO_DATA; + } + } + oldoff = user_data->bufoff; + user_data->bufoff = (cmd_end - user_data->buf) + 1; + user_data->buflen -= user_data->bufoff - oldoff; + if (user_data->buf + 1 == cmd_start + && user_data->buflen == 1 + && user_data->buf[user_data->bufoff] == '\n') { + /* + * This command was the only thing on the whole line. We + * suppress the final `\n` + */ + user_data->bufoff = 0; + user_data->buflen = 0; + } + *len = *off = 0; + return ret; + } else if (cmd_start != NULL) { + /* + * There is a command on this line, but its not at the start. Output + * the start of the line, and we'll process the command next time + * we call this function + */ + outlen = cmd_start - buf_start; + } + } + + if (user_data->isfin) { + user_data->buflen = user_data->bufoff = *len = *off = 0; + return USER_DATA_PROCESS_NO_DATA; + } + +#ifdef CHARSET_EBCDIC + ebcdic2ascii(buf_start, buf_start, outlen); +#endif + *len = outlen; + *off = user_data->bufoff; + user_data->buflen -= outlen; + if (user_data->buflen == 0) + user_data->bufoff = 0; + else + user_data->bufoff += outlen; + return USER_DATA_PROCESS_CONTINUE; +} + +static int user_data_has_data(struct user_data_st *user_data) +{ + return user_data->buflen > 0; +} #endif /* OPENSSL_NO_SOCK */ diff --git a/apps/s_server.c b/apps/s_server.c index 8daa58f9f6..93f6cb2983 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -96,9 +96,13 @@ static int keymatexportlen = 20; static int async = 0; static int use_sendfile = 0; +static int use_zc_sendfile = 0; static const char *session_id_prefix = NULL; +static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 }; +static int enable_client_rpk = 0; + #ifndef OPENSSL_NO_DTLS static int enable_timeouts = 0; static long socket_mtu; @@ -262,7 +266,7 @@ typedef struct { char buff[1]; } EBCDIC_OUTBUFF; -static const BIO_METHOD *BIO_f_ebcdic_filter() +static const BIO_METHOD *BIO_f_ebcdic_filter(void) { if (methods_ebcdic == NULL) { methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER, @@ -716,7 +720,11 @@ typedef enum OPTION_choice { OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, - OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, + OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_KTLS, + OPT_USE_ZC_SENDFILE, + OPT_TFO, OPT_CERT_COMP, + OPT_ENABLE_SERVER_RPK, + OPT_ENABLE_CLIENT_RPK, OPT_R_ENUM, OPT_S_ENUM, OPT_V_ENUM, @@ -747,6 +755,9 @@ const OPTIONS s_server_options[] = { #endif {"4", OPT_4, '-', "Use IPv4 only"}, {"6", OPT_6, '-', "Use IPv6 only"}, +#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO) + {"tfo", OPT_TFO, '-', "Listen for TCP Fast Open connections"}, +#endif OPT_SECTION("Identity"), {"context", OPT_CONTEXT, 's', "Set session ID context"}, @@ -840,6 +851,9 @@ const OPTIONS s_server_options[] = { "No verify output except verify errors"}, {"ign_eof", OPT_IGN_EOF, '-', "Ignore input EOF (default when -quiet)"}, {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input EOF"}, +#ifndef OPENSSL_NO_COMP_ALG + {"cert_comp", OPT_CERT_COMP, '-', "Pre-compress server certificates"}, +#endif #ifndef OPENSSL_NO_OCSP OPT_SECTION("OCSP"), @@ -958,9 +972,12 @@ const OPTIONS s_server_options[] = { {"alpn", OPT_ALPN, 's', "Set the advertised protocols for the ALPN extension (comma-separated list)"}, #ifndef OPENSSL_NO_KTLS + {"ktls", OPT_KTLS, '-', "Enable Kernel TLS for sending and receiving"}, {"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"}, + {"zerocopy_sendfile", OPT_USE_ZC_SENDFILE, '-', "Use zerocopy mode of KTLS sendfile"}, #endif - + {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"}, + {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"}, OPT_R_OPTIONS, OPT_S_OPTIONS, OPT_V_OPTIONS, @@ -1053,6 +1070,12 @@ int s_server_main(int argc, char *argv[]) int sctp_label_bug = 0; #endif int ignore_unexpected_eof = 0; +#ifndef OPENSSL_NO_KTLS + int enable_ktls = 0; +#endif + int tfo = 0; + int cert_comp = 0; + int enable_server_rpk = 0; /* Init of few remaining global variables */ local_argc = argc; @@ -1068,6 +1091,7 @@ int s_server_main(int argc, char *argv[]) s_brief = 0; async = 0; use_sendfile = 0; + use_zc_sendfile = 0; port = OPENSSL_strdup(PORT); cctx = SSL_CONF_CTX_new(); @@ -1634,20 +1658,41 @@ int s_server_main(int argc, char *argv[]) case OPT_NOCANAMES: no_ca_names = 1; break; + case OPT_KTLS: +#ifndef OPENSSL_NO_KTLS + enable_ktls = 1; +#endif + break; case OPT_SENDFILE: #ifndef OPENSSL_NO_KTLS use_sendfile = 1; +#endif + break; + case OPT_USE_ZC_SENDFILE: +#ifndef OPENSSL_NO_KTLS + use_zc_sendfile = 1; #endif break; case OPT_IGNORE_UNEXPECTED_EOF: ignore_unexpected_eof = 1; break; + case OPT_TFO: + tfo = 1; + break; + case OPT_CERT_COMP: + cert_comp = 1; + break; + case OPT_ENABLE_SERVER_RPK: + enable_server_rpk = 1; + break; + case OPT_ENABLE_CLIENT_RPK: + enable_client_rpk = 1; + break; } } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) @@ -1671,6 +1716,11 @@ int s_server_main(int argc, char *argv[]) } #endif + if (tfo && socket_type != SOCK_STREAM) { + BIO_printf(bio_err, "Can only use -tfo with TLS\n"); + goto end; + } + if (stateless && socket_type != SOCK_STREAM) { BIO_printf(bio_err, "Can only use --stateless with TLS\n"); goto end; @@ -1701,6 +1751,16 @@ int s_server_main(int argc, char *argv[]) #endif #ifndef OPENSSL_NO_KTLS + if (use_zc_sendfile && !use_sendfile) { + BIO_printf(bio_out, "Warning: -zerocopy_sendfile depends on -sendfile, enabling -sendfile now.\n"); + use_sendfile = 1; + } + + if (use_sendfile && enable_ktls == 0) { + BIO_printf(bio_out, "Warning: -sendfile depends on -ktls, enabling -ktls now.\n"); + enable_ktls = 1; + } + if (use_sendfile && www <= 1) { BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n"); goto end; @@ -1898,6 +1958,12 @@ int s_server_main(int argc, char *argv[]) if (ignore_unexpected_eof) SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); +#ifndef OPENSSL_NO_KTLS + if (enable_ktls) + SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS); + if (use_zc_sendfile) + SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE); +#endif if (max_send_fragment > 0 && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) { @@ -2214,6 +2280,24 @@ int s_server_main(int argc, char *argv[]) if (recv_max_early_data >= 0) SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data); + if (cert_comp) { + BIO_printf(bio_s_out, "Compressing certificates\n"); + if (!SSL_CTX_compress_certs(ctx, 0)) + BIO_printf(bio_s_out, "Error compressing certs on ctx\n"); + if (ctx2 != NULL && !SSL_CTX_compress_certs(ctx2, 0)) + BIO_printf(bio_s_out, "Error compressing certs on ctx2\n"); + } + if (enable_server_rpk) + if (!SSL_CTX_set1_server_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) { + BIO_printf(bio_s_out, "Error setting server certificate types\n"); + goto end; + } + if (enable_client_rpk) + if (!SSL_CTX_set1_client_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) { + BIO_printf(bio_s_out, "Error setting server certificate types\n"); + goto end; + } + if (rev) server_cb = rev_body; else if (www) @@ -2225,8 +2309,10 @@ int s_server_main(int argc, char *argv[]) && unlink_unix_path) unlink(host); #endif + if (tfo) + BIO_printf(bio_s_out, "Listening for TFO\n"); do_server(&accept_socket, host, port, socket_family, socket_type, protocol, - server_cb, context, naccept, bio_s_out); + server_cb, context, naccept, bio_s_out, tfo); print_stats(bio_s_out, ctx); ret = 0; end: @@ -2238,8 +2324,8 @@ int s_server_main(int argc, char *argv[]) X509_free(s_dcert); EVP_PKEY_free(s_key); EVP_PKEY_free(s_dkey); - sk_X509_pop_free(s_chain, X509_free); - sk_X509_pop_free(s_dchain, X509_free); + OSSL_STACK_OF_X509_free(s_chain); + OSSL_STACK_OF_X509_free(s_dchain); OPENSSL_free(pass); OPENSSL_free(dpass); OPENSSL_free(host); @@ -2327,7 +2413,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) char *buf = NULL; fd_set readfds; int ret = 1, width; - int k, i; + int k; unsigned long l; SSL *con = NULL; BIO *sbio; @@ -2443,7 +2529,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) BIO_free(sbio); goto err; } - sbio = BIO_push(test, sbio); } @@ -2515,6 +2600,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) else width = s + 1; for (;;) { + int i; int read_from_terminal; int read_from_sslcon; @@ -2614,7 +2700,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) SSL_renegotiate(con); i = SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n", i); - i = 0; /* 13; */ continue; } if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) { @@ -2624,7 +2709,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) SSL_renegotiate(con); i = SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n", i); - i = 0; /* 13; */ continue; } if ((buf[0] == 'K' || buf[0] == 'k') @@ -2634,7 +2718,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) : SSL_KEY_UPDATE_NOT_REQUESTED); i = SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n", i); - i = 0; continue; } if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) { @@ -2646,7 +2729,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) } else { i = SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n", i); - i = 0; } continue; } @@ -2963,6 +3045,19 @@ static void print_connection_info(SSL *con) dump_cert_text(bio_s_out, peer); peer = NULL; } + /* Only display RPK information if configured */ + if (SSL_get_negotiated_server_cert_type(con) == TLSEXT_cert_type_rpk) + BIO_printf(bio_s_out, "Server-to-client raw public key negotiated\n"); + if (SSL_get_negotiated_client_cert_type(con) == TLSEXT_cert_type_rpk) + BIO_printf(bio_s_out, "Client-to-server raw public key negotiated\n"); + if (enable_client_rpk) { + EVP_PKEY *client_rpk = SSL_get0_peer_rpk(con); + + if (client_rpk != NULL) { + BIO_printf(bio_s_out, "Client raw public key\n"); + EVP_PKEY_print_public(bio_s_out, client_rpk, 2, NULL); + } + } if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL) BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); @@ -3032,7 +3127,7 @@ static void print_connection_info(SSL *con) static int www_body(int s, int stype, int prot, unsigned char *context) { - char *buf = NULL; + char *buf = NULL, *p; int ret = 1; int i, j, k, dot; SSL *con; @@ -3056,7 +3151,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) /* as we use BIO_gets(), and it always null terminates data, we need * to allocate 1 byte longer buffer to fit the full 2^14 byte record */ - buf = app_malloc(bufsize + 1, "server www buffer"); + p = buf = app_malloc(bufsize + 1, "server www buffer"); io = BIO_new(BIO_f_buffer()); ssl_bio = BIO_new(BIO_f_ssl()); if ((io == NULL) || (ssl_bio == NULL)) @@ -3154,7 +3249,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) continue; } #endif - ossl_sleep(1000); + OSSL_sleep(1000); continue; } } else if (i == 0) { /* end of input */ @@ -3163,15 +3258,14 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } /* else we have data */ - if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || - ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { - char *p; + if ((www == 1 && HAS_PREFIX(buf, "GET ")) + || (www == 2 && HAS_PREFIX(buf, "GET /stats "))) { X509 *peer = NULL; STACK_OF(SSL_CIPHER) *sk; static const char *space = " "; - if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) { - if (strncmp("GET /renegcert", buf, 14) == 0) + if (www == 1 && HAS_PREFIX(buf, "GET /reneg")) { + if (HAS_PREFIX(buf, "GET /renegcert")) SSL_set_verify(con, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); @@ -3212,6 +3306,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) BIO_puts(io, "\n"); for (i = 0; i < local_argc; i++) { const char *myp; + for (myp = local_argv[i]; *myp; myp++) switch (*myp) { case '<': @@ -3291,16 +3386,12 @@ static int www_body(int s, int stype, int prot, unsigned char *context) } BIO_puts(io, "\r\n\r\n"); break; - } else if ((www == 2 || www == 3) - && (strncmp("GET /", buf, 5) == 0)) { + } else if ((www == 2 || www == 3) && CHECK_AND_SKIP_PREFIX(p, "GET /")) { BIO *file; - char *p, *e; + char *e; static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; - /* skip the '/' */ - p = &(buf[5]); - dot = 1; for (e = p; *e != '\0'; e++) { if (e[0] == ' ') @@ -3473,7 +3564,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) break; } end: - /* make sure we re-use sessions */ + /* make sure we reuse sessions */ do_ssl_shutdown(con); err: @@ -3599,7 +3690,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) continue; } #endif - ossl_sleep(1000); + OSSL_sleep(1000); continue; } } else if (i == 0) { /* end of input */ @@ -3612,7 +3703,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) p--; i--; } - if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) { + if (!s_ign_eof && i == 5 && HAS_PREFIX(buf, "CLOSE")) { ret = 1; BIO_printf(bio_err, "CONNECTION CLOSED\n"); goto end; @@ -3630,7 +3721,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) } } end: - /* make sure we re-use sessions */ + /* make sure we reuse sessions */ do_ssl_shutdown(con); err: @@ -3734,7 +3825,8 @@ static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen, if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) { const unsigned char *p = sess->der; BIO_printf(bio_err, "Lookup session: cache hit\n"); - return d2i_SSL_SESSION(NULL, &p, sess->derlen); + return d2i_SSL_SESSION_ex(NULL, &p, sess->derlen, app_get0_libctx(), + app_get0_propq()); } } BIO_printf(bio_err, "Lookup session: cache miss\n"); diff --git a/apps/s_time.c b/apps/s_time.c index 1a58e19de5..1c6ed78b2c 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -234,8 +234,7 @@ int s_time_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (cipher == NULL) diff --git a/apps/sess_id.c b/apps/sess_id.c index 714c0f7787..54b3d05563 100644 --- a/apps/sess_id.c +++ b/apps/sess_id.c @@ -98,8 +98,7 @@ int sess_id_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; x = load_sess_id(infile, informat); diff --git a/apps/smime.c b/apps/smime.c index a2ff0b5be7..88b0475d2d 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,9 +28,9 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx); #define SMIME_ENCRYPT (1 | SMIME_OP) #define SMIME_DECRYPT (2 | SMIME_IP) #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) #define SMIME_VERIFY (4 | SMIME_IP) #define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP) -#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) typedef enum OPTION_choice { OPT_COMMON, @@ -75,12 +75,12 @@ const OPTIONS smime_options[] = { {"sign", OPT_SIGN, '-', "Sign message"}, {"resign", OPT_RESIGN, '-', "Resign a signed message"}, {"verify", OPT_VERIFY, '-', "Verify signed message"}, + {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, OPT_SECTION("Signing/Encryption"), {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, - {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, {"nointern", OPT_NOINTERN, '-', "Don't search certificates in message for signer"}, {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, @@ -129,6 +129,32 @@ const OPTIONS smime_options[] = { {NULL} }; +static const char *operation_name(int operation) +{ + switch (operation) { + case SMIME_ENCRYPT: + return "encrypt"; + case SMIME_DECRYPT: + return "decrypt"; + case SMIME_SIGN: + return "sign"; + case SMIME_RESIGN: + return "resign"; + case SMIME_VERIFY: + return "verify"; + case SMIME_PK7OUT: + return "pk7out"; + default: + return "(invalid operation)"; + } +} + +#define SET_OPERATION(op) \ + ((operation != 0 && (operation != (op))) \ + ? 0 * BIO_printf(bio_err, "%s: Cannot use -%s together with -%s\n", \ + prog, operation_name(op), operation_name(operation)) \ + : (operation = (op))) + int smime_main(int argc, char **argv) { CONF *conf = NULL; @@ -160,6 +186,7 @@ int smime_main(int argc, char **argv) if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; + opt_set_unknown_name("cipher"); prog = opt_init(argc, argv, smime_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -187,22 +214,28 @@ int smime_main(int argc, char **argv) outfile = opt_arg(); break; case OPT_ENCRYPT: - operation = SMIME_ENCRYPT; + if (!SET_OPERATION(SMIME_ENCRYPT)) + goto end; break; case OPT_DECRYPT: - operation = SMIME_DECRYPT; + if (!SET_OPERATION(SMIME_DECRYPT)) + goto end; break; case OPT_SIGN: - operation = SMIME_SIGN; + if (!SET_OPERATION(SMIME_SIGN)) + goto end; break; case OPT_RESIGN: - operation = SMIME_RESIGN; + if (!SET_OPERATION(SMIME_RESIGN)) + goto end; break; case OPT_VERIFY: - operation = SMIME_VERIFY; + if (!SET_OPERATION(SMIME_VERIFY)) + goto end; break; case OPT_PK7OUT: - operation = SMIME_PK7OUT; + if (!SET_OPERATION(SMIME_PK7OUT)) + goto end; break; case OPT_TEXT: flags |= PKCS7_TEXT; @@ -366,10 +399,8 @@ int smime_main(int argc, char **argv) if (!opt_md(digestname, &sign_md)) goto opthelp; } - if (ciphername != NULL) { - if (!opt_cipher_any(ciphername, &cipher)) + if (!opt_cipher_any(ciphername, &cipher)) goto opthelp; - } if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto opthelp; @@ -653,8 +684,8 @@ int smime_main(int argc, char **argv) end: if (ret) ERR_print_errors(bio_err); - sk_X509_pop_free(encerts, X509_free); - sk_X509_pop_free(other, X509_free); + OSSL_STACK_OF_X509_free(encerts); + OSSL_STACK_OF_X509_free(other); X509_VERIFY_PARAM_free(vpm); sk_OPENSSL_STRING_free(sksigners); sk_OPENSSL_STRING_free(skkeys); diff --git a/apps/speed.c b/apps/speed.c index 90c210db32..57aeb67bf8 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -19,6 +19,10 @@ #define EdDSA_SECONDS PKEY_SECONDS #define SM2_SECONDS PKEY_SECONDS #define FFDH_SECONDS PKEY_SECONDS +#define KEM_SECONDS PKEY_SECONDS +#define SIG_SECONDS PKEY_SECONDS + +#define MAX_ALGNAME_SUFFIX 100 /* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED @@ -29,6 +33,7 @@ #include #include "apps.h" #include "progs.h" +#include "internal/nelem.h" #include "internal/numbers.h" #include #include @@ -37,6 +42,7 @@ #include #include #include +#include #if !defined(OPENSSL_SYS_MSDOS) # include #endif @@ -110,6 +116,8 @@ typedef struct openssl_speed_sec_st { int eddsa; int sm2; int ffdh; + int kem; + int sig; } openssl_speed_sec_t; static volatile int run = 0; @@ -118,9 +126,10 @@ static int mr = 0; /* machine-readeable output format to merge fork results */ static int usertime = 1; static double Time_F(int s); -static void print_message(const char *s, long num, int length, int tm); +static void print_message(const char *s, int length, int tm); static void pkey_print_message(const char *str, const char *str2, - long num, unsigned int bits, int sec); + unsigned int bits, int sec); +static void kskey_print_message(const char *str, const char *str2, int tm); static void print_result(int alg, int run_no, int count, double time_used); #ifndef NO_FORK static int do_multi(int multi, int size_num); @@ -143,7 +152,7 @@ static const int aead_lengths_list[] = { #ifdef SIGALRM -static void alarmed(int sig) +static void alarmed(ossl_unused int sig) { signal(SIGALRM, alarmed); run = 0; @@ -229,11 +238,15 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG, - OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK + OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK, OPT_KEM, OPT_SIG } OPTION_CHOICE; const OPTIONS speed_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"}, + {OPT_HELP_STR, 1, '-', + "Usage: %s [options] [algorithm...]\n" + "All +int options consider prefix '0' as base-8 input, " + "prefix '0x'/'0X' as base-16 input.\n" + }, OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, @@ -262,6 +275,10 @@ const OPTIONS speed_options[] = { "Time decryption instead of encryption (only EVP)"}, {"aead", OPT_AEAD, '-', "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, + {"kem-algorithms", OPT_KEM, '-', + "Benchmark KEM algorithms"}, + {"signature-algorithms", OPT_SIG, '-', + "Benchmark signature algorithms"}, OPT_SECTION("Timing"), {"elapsed", OPT_ELAPSED, '-', @@ -344,9 +361,8 @@ static const OPT_PAIR doit_choices[] = { static double results[ALGOR_NUM][SIZE_NUM]; -enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM }; +enum { R_DSA_1024, R_DSA_2048, DSA_NUM }; static const OPT_PAIR dsa_choices[DSA_NUM] = { - {"dsa512", R_DSA_512}, {"dsa1024", R_DSA_1024}, {"dsa2048", R_DSA_2048} }; @@ -366,7 +382,7 @@ static const OPT_PAIR rsa_choices[RSA_NUM] = { {"rsa15360", R_RSA_15360} }; -static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ +static double rsa_results[RSA_NUM][4]; /* 4 ops: sign, verify, encrypt, decrypt */ #ifndef OPENSSL_NO_DH enum ff_params_t { @@ -420,7 +436,13 @@ static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = { {"ecdsabrp512r1", R_EC_BRP512R1}, {"ecdsabrp512t1", R_EC_BRP512T1} }; -enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM }; +enum { +#ifndef OPENSSL_NO_ECX + R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM +#else + EC_NUM = ECDSA_NUM +#endif +}; /* list of ecdh curves, extension of |ecdsa_choices| list above */ static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhp160", R_EC_P160}, @@ -447,13 +469,16 @@ static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhbrp384t1", R_EC_BRP384T1}, {"ecdhbrp512r1", R_EC_BRP512R1}, {"ecdhbrp512t1", R_EC_BRP512T1}, +#ifndef OPENSSL_NO_ECX {"ecdhx25519", R_EC_X25519}, {"ecdhx448", R_EC_X448} +#endif }; static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ +#ifndef OPENSSL_NO_ECX enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM }; static const OPT_PAIR eddsa_choices[EdDSA_NUM] = { {"ed25519", R_EC_Ed25519}, @@ -461,6 +486,7 @@ static const OPT_PAIR eddsa_choices[EdDSA_NUM] = { }; static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */ +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 enum { R_EC_CURVESM2, SM2_NUM }; @@ -472,6 +498,16 @@ static const OPT_PAIR sm2_choices[SM2_NUM] = { static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */ #endif /* OPENSSL_NO_SM2 */ +#define MAX_KEM_NUM 111 +static size_t kems_algs_len = 0; +static char *kems_algname[MAX_KEM_NUM] = { NULL }; +static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */ + +#define MAX_SIG_NUM 111 +static size_t sigs_algs_len = 0; +static char *sigs_algname[MAX_SIG_NUM] = { NULL }; +static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */ + #define COND(unused_cond) (run && count < INT_MAX) #define COUNT(d) (count) @@ -485,15 +521,20 @@ typedef struct loopargs_st { unsigned char *key; size_t buflen; size_t sigsize; + size_t encsize; EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM]; EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM]; + EVP_PKEY_CTX *rsa_encrypt_ctx[RSA_NUM]; + EVP_PKEY_CTX *rsa_decrypt_ctx[RSA_NUM]; EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM]; EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM]; EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM]; EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM]; EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; +#ifndef OPENSSL_NO_ECX EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM]; +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 EVP_MD_CTX *sm2_ctx[SM2_NUM]; EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM]; @@ -509,15 +550,26 @@ typedef struct loopargs_st { #endif EVP_CIPHER_CTX *ctx; EVP_MAC_CTX *mctx; + EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM]; + EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM]; + EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM]; + size_t kem_out_len[MAX_KEM_NUM]; + size_t kem_secret_len[MAX_KEM_NUM]; + unsigned char *kem_out[MAX_KEM_NUM]; + unsigned char *kem_send_secret[MAX_KEM_NUM]; + unsigned char *kem_rcv_secret[MAX_KEM_NUM]; + EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM]; + EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM]; + EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM]; + size_t sig_max_sig_len[MAX_KEM_NUM]; + size_t sig_act_sig_len[MAX_KEM_NUM]; + unsigned char *sig_sig[MAX_KEM_NUM]; } loopargs_t; static int run_benchmark(int async_jobs, int (*loop_function) (void *), - loopargs_t * loopargs); + loopargs_t *loopargs); static unsigned int testnum; -/* Nb of iterations to do per algorithm and key-size */ -static long c[ALGOR_NUM][SIZE_NUM]; - static char *evp_mac_mdname = "md5"; static char *evp_hmac_name = NULL; static const char *evp_md_name = NULL; @@ -557,7 +609,7 @@ static int have_cipher(const char *name) return ret; } -static int EVP_Digest_loop(const char *mdname, int algindex, void *args) +static int EVP_Digest_loop(const char *mdname, ossl_unused int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; @@ -603,7 +655,7 @@ static int MD5_loop(void *args) return EVP_Digest_loop("md5", D_MD5, args); } -static int EVP_MAC_loop(int algindex, void *args) +static int EVP_MAC_loop(ossl_unused int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; @@ -752,7 +804,7 @@ static int EVP_Update_loop(void *args) rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ - EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); + rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); } } } else { @@ -760,14 +812,17 @@ static int EVP_Update_loop(void *args) rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); if (rc != 1) { /* reset iv in case of counter overflow */ - EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); + rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); } } } if (decrypt) - EVP_DecryptFinal_ex(ctx, buf, &outl); + rc = EVP_DecryptFinal_ex(ctx, buf, &outl); else - EVP_EncryptFinal_ex(ctx, buf, &outl); + rc = EVP_EncryptFinal_ex(ctx, buf, &outl); + + if (rc == 0) + BIO_printf(bio_err, "Error finalizing cipher loop\n"); return count; } @@ -781,31 +836,36 @@ static int EVP_Update_loop_ccm(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; EVP_CIPHER_CTX *ctx = tempargs->ctx; - int outl, count; + int outl, count, realcount = 0, final; unsigned char tag[12]; if (decrypt) { for (count = 0; COND(c[D_EVP][testnum]); count++) { - (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), - tag); - /* reset iv */ - (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); - /* counter is reset on every update */ - (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), + tag) > 0 + /* reset iv */ + && EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0 + /* counter is reset on every update */ + && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0) + realcount++; } } else { for (count = 0; COND(c[D_EVP][testnum]); count++) { /* restore iv length field */ - (void)EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); - /* counter is reset on every update */ - (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]) > 0 + /* counter is reset on every update */ + && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0) + realcount++; } } if (decrypt) - (void)EVP_DecryptFinal_ex(ctx, buf, &outl); + final = EVP_DecryptFinal_ex(ctx, buf, &outl); else - (void)EVP_EncryptFinal_ex(ctx, buf, &outl); - return count; + final = EVP_EncryptFinal_ex(ctx, buf, &outl); + + if (final == 0) + BIO_printf(bio_err, "Error finalizing ccm loop\n"); + return realcount; } /* @@ -818,32 +878,32 @@ static int EVP_Update_loop_aead(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; EVP_CIPHER_CTX *ctx = tempargs->ctx; - int outl, count; + int outl, count, realcount = 0; unsigned char aad[13] = { 0xcc }; unsigned char faketag[16] = { 0xcc }; if (decrypt) { for (count = 0; COND(c[D_EVP][testnum]); count++) { - (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); - (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, - sizeof(faketag), faketag); - (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); - (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl); + if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0 + && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + sizeof(faketag), faketag) > 0 + && EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0 + && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0 + && EVP_DecryptFinal_ex(ctx, buf + outl, &outl) >0) + realcount++; } } else { for (count = 0; COND(c[D_EVP][testnum]); count++) { - (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); - (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); - (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl); + if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0 + && EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0 + && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0 + && EVP_EncryptFinal_ex(ctx, buf + outl, &outl) > 0) + realcount++; } } - return count; + return realcount; } -static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */ - static int RSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -887,8 +947,51 @@ static int RSA_verify_loop(void *args) return count; } +static int RSA_encrypt_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + unsigned char *buf2 = tempargs->buf2; + size_t *rsa_num = &tempargs->encsize; + EVP_PKEY_CTX **rsa_encrypt_ctx = tempargs->rsa_encrypt_ctx; + int ret, count; + + for (count = 0; COND(rsa_c[testnum][2]); count++) { + *rsa_num = tempargs->buflen; + ret = EVP_PKEY_encrypt(rsa_encrypt_ctx[testnum], buf2, rsa_num, buf, 36); + if (ret <= 0) { + BIO_printf(bio_err, "RSA encrypt failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + return count; +} + +static int RSA_decrypt_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + unsigned char *buf2 = tempargs->buf2; + size_t rsa_num; + EVP_PKEY_CTX **rsa_decrypt_ctx = tempargs->rsa_decrypt_ctx; + int ret, count; + + for (count = 0; COND(rsa_c[testnum][3]); count++) { + rsa_num = tempargs->buflen; + ret = EVP_PKEY_decrypt(rsa_decrypt_ctx[testnum], buf, &rsa_num, buf2, tempargs->encsize); + if (ret <= 0) { + BIO_printf(bio_err, "RSA decrypt failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + return count; +} + #ifndef OPENSSL_NO_DH -static long ffdh_c[FFDH_NUM][1]; static int FFDH_derive_key_loop(void *args) { @@ -907,7 +1010,6 @@ static int FFDH_derive_key_loop(void *args) } #endif /* OPENSSL_NO_DH */ -static long dsa_c[DSA_NUM][2]; static int DSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -951,7 +1053,6 @@ static int DSA_verify_loop(void *args) return count; } -static long ecdsa_c[ECDSA_NUM][2]; static int ECDSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -997,7 +1098,6 @@ static int ECDSA_verify_loop(void *args) } /* ******************************************************************** */ -static long ecdh_c[EC_NUM][1]; static int ECDH_EVP_derive_key_loop(void *args) { @@ -1013,7 +1113,7 @@ static int ECDH_EVP_derive_key_loop(void *args) return count; } -static long eddsa_c[EdDSA_NUM][2]; +#ifndef OPENSSL_NO_ECX static int EdDSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -1069,9 +1169,9 @@ static int EdDSA_verify_loop(void *args) } return count; } +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 -static long sm2_c[SM2_NUM][2]; static int SM2_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -1139,8 +1239,131 @@ static int SM2_verify_loop(void *args) } #endif /* OPENSSL_NO_SM2 */ +static int KEM_keygen_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum]; + EVP_PKEY *pkey = NULL; + int count; + + for (count = 0; COND(kems_c[testnum][0]); count++) { + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + return -1; + /* + * runtime defined to quite some degree by randomness, + * so performance overhead of _free doesn't impact + * results significantly. In any case this test is + * meant to permit relative algorithm performance + * comparison. + */ + EVP_PKEY_free(pkey); + pkey = NULL; + } + return count; +} + +static int KEM_encaps_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum]; + size_t out_len = tempargs->kem_out_len[testnum]; + size_t secret_len = tempargs->kem_secret_len[testnum]; + unsigned char *out = tempargs->kem_out[testnum]; + unsigned char *secret = tempargs->kem_send_secret[testnum]; + int count; + + for (count = 0; COND(kems_c[testnum][1]); count++) { + if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0) + return -1; + } + return count; +} + +static int KEM_decaps_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum]; + size_t out_len = tempargs->kem_out_len[testnum]; + size_t secret_len = tempargs->kem_secret_len[testnum]; + unsigned char *out = tempargs->kem_out[testnum]; + unsigned char *secret = tempargs->kem_send_secret[testnum]; + int count; + + for (count = 0; COND(kems_c[testnum][2]); count++) { + if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0) + return -1; + } + return count; +} + +static int SIG_keygen_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum]; + EVP_PKEY *pkey = NULL; + int count; + + for (count = 0; COND(kems_c[testnum][0]); count++) { + EVP_PKEY_keygen(ctx, &pkey); + /* TBD: How much does free influence runtime? */ + EVP_PKEY_free(pkey); + pkey = NULL; + } + return count; +} + +static int SIG_sign_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum]; + /* be sure to not change stored sig: */ + unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum], + "sig sign loop"); + unsigned char md[SHA256_DIGEST_LENGTH] = { 0 }; + size_t md_len = SHA256_DIGEST_LENGTH; + int count; + + for (count = 0; COND(kems_c[testnum][1]); count++) { + size_t sig_len = tempargs->sig_max_sig_len[testnum]; + int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len); + + if (ret <= 0) { + BIO_printf(bio_err, "SIG sign failure at count %d\n", count); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + OPENSSL_free(sig); + return count; +} + +static int SIG_verify_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum]; + size_t sig_len = tempargs->sig_act_sig_len[testnum]; + unsigned char *sig = tempargs->sig_sig[testnum]; + unsigned char md[SHA256_DIGEST_LENGTH] = { 0 }; + size_t md_len = SHA256_DIGEST_LENGTH; + int count; + + for (count = 0; COND(kems_c[testnum][2]); count++) { + int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len); + + if (ret <= 0) { + BIO_printf(bio_err, "SIG verify failure at count %d\n", count); + ERR_print_errors(bio_err); + count = -1; + break; + } + + } + return count; +} + static int run_benchmark(int async_jobs, - int (*loop_function) (void *), loopargs_t * loopargs) + int (*loop_function) (void *), loopargs_t *loopargs) { int job_op_count = 0; int total_op_count = 0; @@ -1373,6 +1596,99 @@ static EVP_PKEY *get_ecdsa(const EC_CURVE *curve) #define stop_it(do_it, test_num)\ memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num); +/* Checks to see if algorithms are fetchable */ +#define IS_FETCHABLE(type, TYPE) \ + static int is_ ## type ## _fetchable(const TYPE *alg) \ + { \ + TYPE *impl; \ + const char *propq = app_get0_propq(); \ + OSSL_LIB_CTX *libctx = app_get0_libctx(); \ + const char *name = TYPE ## _get0_name(alg); \ + \ + ERR_set_mark(); \ + impl = TYPE ## _fetch(libctx, name, propq); \ + ERR_pop_to_mark(); \ + if (impl == NULL) \ + return 0; \ + TYPE ## _free(impl); \ + return 1; \ + } + +IS_FETCHABLE(signature, EVP_SIGNATURE) +IS_FETCHABLE(kem, EVP_KEM) + +DEFINE_STACK_OF(EVP_KEM) + +static int kems_cmp(const EVP_KEM * const *a, + const EVP_KEM * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b))); +} + +static void collect_kem(EVP_KEM *kem, void *stack) +{ + STACK_OF(EVP_KEM) *kem_stack = stack; + + if (is_kem_fetchable(kem) + && sk_EVP_KEM_push(kem_stack, kem) > 0) { + EVP_KEM_up_ref(kem); + } +} + +static int kem_locate(const char *algo, unsigned int *idx) +{ + unsigned int i; + + for (i = 0; i < kems_algs_len; i++) { + if (strcmp(kems_algname[i], algo) == 0) { + *idx = i; + return 1; + } + } + return 0; +} + +DEFINE_STACK_OF(EVP_SIGNATURE) + +static int signatures_cmp(const EVP_SIGNATURE * const *a, + const EVP_SIGNATURE * const *b) +{ + return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)), + OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b))); +} + +static void collect_signatures(EVP_SIGNATURE *sig, void *stack) +{ + STACK_OF(EVP_SIGNATURE) *sig_stack = stack; + + if (is_signature_fetchable(sig) + && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0) + EVP_SIGNATURE_up_ref(sig); +} + +static int sig_locate(const char *algo, unsigned int *idx) +{ + unsigned int i; + + for (i = 0; i < sigs_algs_len; i++) { + if (strcmp(sigs_algname[i], algo) == 0) { + *idx = i; + return 1; + } + } + return 0; +} + +static int get_max(const uint8_t doit[], size_t algs_len) { + size_t i = 0; + int maxcnt = 0; + + for (i = 0; i < algs_len; i++) + if (maxcnt < doit[i]) maxcnt = doit[i]; + return maxcnt; +} + int speed_main(int argc, char **argv) { CONF *conf = NULL; @@ -1387,11 +1703,15 @@ int speed_main(int argc, char **argv) int async_init = 0, multiblock = 0, pr_header = 0; uint8_t doit[ALGOR_NUM] = { 0 }; int ret = 1, misalign = 0, lengths_single = 0, aead = 0; + STACK_OF(EVP_KEM) *kem_stack = NULL; + STACK_OF(EVP_SIGNATURE) *sig_stack = NULL; long count = 0; unsigned int size_num = SIZE_NUM; unsigned int i, k, loopargs_len = 0, async_jobs = 0; + unsigned int idx; int keylen; int buflen; + size_t declen; BIGNUM *bn = NULL; EVP_PKEY_CTX *genctx = NULL; #ifndef NO_FORK @@ -1401,7 +1721,8 @@ int speed_main(int argc, char **argv) openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, ECDH_SECONDS, EdDSA_SECONDS, SM2_SECONDS, - FFDH_SECONDS }; + FFDH_SECONDS, KEM_SECONDS, + SIG_SECONDS }; static const unsigned char key32[32] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, @@ -1446,7 +1767,7 @@ int speed_main(int argc, char **argv) uint8_t ffdh_doit[FFDH_NUM] = { 0 }; #endif /* OPENSSL_NO_DH */ - static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; + static const unsigned int dsa_bits[DSA_NUM] = { 1024, 2048 }; uint8_t dsa_doit[DSA_NUM] = { 0 }; /* * We only test over the following curves as they are representative, To @@ -1481,15 +1802,19 @@ int speed_main(int argc, char **argv) {"brainpoolP384t1", NID_brainpoolP384t1, 384}, {"brainpoolP512r1", NID_brainpoolP512r1, 512}, {"brainpoolP512t1", NID_brainpoolP512t1, 512}, +#ifndef OPENSSL_NO_ECX /* Other and ECDH only ones */ {"X25519", NID_X25519, 253}, {"X448", NID_X448, 448} +#endif }; +#ifndef OPENSSL_NO_ECX static const EC_CURVE ed_curves[EdDSA_NUM] = { /* EdDSA */ {"Ed25519", NID_ED25519, 253, 64}, {"Ed448", NID_ED448, 456, 114} }; +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 static const EC_CURVE sm2_curves[SM2_NUM] = { /* SM2 */ @@ -1499,9 +1824,18 @@ int speed_main(int argc, char **argv) #endif uint8_t ecdsa_doit[ECDSA_NUM] = { 0 }; uint8_t ecdh_doit[EC_NUM] = { 0 }; +#ifndef OPENSSL_NO_ECX uint8_t eddsa_doit[EdDSA_NUM] = { 0 }; +#endif /* OPENSSL_NO_ECX */ + + uint8_t kems_doit[MAX_KEM_NUM] = { 0 }; + uint8_t sigs_doit[MAX_SIG_NUM] = { 0 }; + + uint8_t do_kems = 0; + uint8_t do_sigs = 0; /* checks declared curves against choices list. */ +#ifndef OPENSSL_NO_ECX OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448); OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0); @@ -1510,6 +1844,7 @@ int speed_main(int argc, char **argv) OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1); OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0); +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2); @@ -1582,7 +1917,7 @@ int speed_main(int argc, char **argv) break; case OPT_MULTI: #ifndef NO_FORK - multi = atoi(opt_arg()); + multi = opt_int_arg(); if ((size_t)multi >= SIZE_MAX / sizeof(int)) { BIO_printf(bio_err, "%s: multi argument too large\n", prog); return 0; @@ -1591,7 +1926,7 @@ int speed_main(int argc, char **argv) break; case OPT_ASYNCJOBS: #ifndef OPENSSL_NO_ASYNC - async_jobs = atoi(opt_arg()); + async_jobs = opt_int_arg(); if (!ASYNC_is_capable()) { BIO_printf(bio_err, "%s: async_jobs specified but async not supported\n", @@ -1643,16 +1978,23 @@ int speed_main(int argc, char **argv) case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa = seconds.ecdh = seconds.eddsa - = seconds.sm2 = seconds.ffdh = atoi(opt_arg()); + = seconds.sm2 = seconds.ffdh + = seconds.kem = seconds.sig = opt_int_arg(); break; case OPT_BYTES: - lengths_single = atoi(opt_arg()); + lengths_single = opt_int_arg(); lengths = &lengths_single; size_num = 1; break; case OPT_AEAD: aead = 1; break; + case OPT_KEM: + do_kems = 1; + break; + case OPT_SIG: + do_sigs = 1; + break; case OPT_MLOCK: domlock = 1; #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX) @@ -1665,6 +2007,104 @@ int speed_main(int argc, char **argv) } } + /* find all KEMs currently available */ + kem_stack = sk_EVP_KEM_new(kems_cmp); + EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack); + + kems_algs_len = 0; + + for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) { + EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx); + + if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) { + if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) { + BIO_printf(bio_err, + "Too many KEMs registered. Change MAX_KEM_NUM.\n"); + goto end; + } + for (i = 0; i < OSSL_NELEM(rsa_choices); i++) { + kems_doit[kems_algs_len] = 1; + kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name); + } + } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) { + if (kems_algs_len + 3 >= MAX_KEM_NUM) { + BIO_printf(bio_err, + "Too many KEMs registered. Change MAX_KEM_NUM.\n"); + goto end; + } + kems_doit[kems_algs_len] = 1; + kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256"); + kems_doit[kems_algs_len] = 1; + kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384"); + kems_doit[kems_algs_len] = 1; + kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521"); + } else { + if (kems_algs_len + 1 >= MAX_KEM_NUM) { + BIO_printf(bio_err, + "Too many KEMs registered. Change MAX_KEM_NUM.\n"); + goto end; + } + kems_doit[kems_algs_len] = 1; + kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem)); + } + } + sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free); + kem_stack = NULL; + + /* find all SIGNATUREs currently available */ + sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp); + EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack); + + sigs_algs_len = 0; + + for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) { + EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx); + const char *sig_name = EVP_SIGNATURE_get0_name(s); + + if (strcmp(sig_name, "RSA") == 0) { + if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) { + BIO_printf(bio_err, + "Too many signatures registered. Change MAX_SIG_NUM.\n"); + goto end; + } + for (i = 0; i < OSSL_NELEM(rsa_choices); i++) { + sigs_doit[sigs_algs_len] = 1; + sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name); + } + } + else if (strcmp(sig_name, "DSA") == 0) { + if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) { + BIO_printf(bio_err, + "Too many signatures registered. Change MAX_SIG_NUM.\n"); + goto end; + } + for (i = 0; i < DSA_NUM; i++) { + sigs_doit[sigs_algs_len] = 1; + sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name); + } + } + /* skipping these algs as tested elsewhere - and b/o setup is a pain */ + else if (strcmp(sig_name, "ED25519") && + strcmp(sig_name, "ED448") && + strcmp(sig_name, "ECDSA") && + strcmp(sig_name, "HMAC") && + strcmp(sig_name, "SIPHASH") && + strcmp(sig_name, "POLY1305") && + strcmp(sig_name, "CMAC") && + strcmp(sig_name, "SM2")) { /* skip alg */ + if (sigs_algs_len + 1 >= MAX_SIG_NUM) { + BIO_printf(bio_err, + "Too many signatures registered. Change MAX_SIG_NUM.\n"); + goto end; + } + /* activate this provider algorithm */ + sigs_doit[sigs_algs_len] = 1; + sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name); + } + } + sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free); + sig_stack = NULL; + /* Remaining arguments are algorithms. */ argc = opt_num_rest(); argv = opt_rest(); @@ -1674,103 +2114,119 @@ int speed_main(int argc, char **argv) for (; *argv; argv++) { const char *algo = *argv; + int algo_found = 0; if (opt_found(algo, doit_choices, &i)) { doit[i] = 1; - continue; + algo_found = 1; } if (strcmp(algo, "des") == 0) { doit[D_CBC_DES] = doit[D_EDE3_DES] = 1; - continue; + algo_found = 1; } if (strcmp(algo, "sha") == 0) { doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1; - continue; + algo_found = 1; } #ifndef OPENSSL_NO_DEPRECATED_3_0 if (strcmp(algo, "openssl") == 0) /* just for compatibility */ - continue; + algo_found = 1; #endif - if (strncmp(algo, "rsa", 3) == 0) { - if (algo[3] == '\0') { + if (HAS_PREFIX(algo, "rsa")) { + if (algo[sizeof("rsa") - 1] == '\0') { memset(rsa_doit, 1, sizeof(rsa_doit)); - continue; + algo_found = 1; } if (opt_found(algo, rsa_choices, &i)) { rsa_doit[i] = 1; - continue; + algo_found = 1; } } #ifndef OPENSSL_NO_DH - if (strncmp(algo, "ffdh", 4) == 0) { - if (algo[4] == '\0') { + if (HAS_PREFIX(algo, "ffdh")) { + if (algo[sizeof("ffdh") - 1] == '\0') { memset(ffdh_doit, 1, sizeof(ffdh_doit)); - continue; + algo_found = 1; } if (opt_found(algo, ffdh_choices, &i)) { ffdh_doit[i] = 2; - continue; + algo_found = 1; } } #endif - if (strncmp(algo, "dsa", 3) == 0) { - if (algo[3] == '\0') { + if (HAS_PREFIX(algo, "dsa")) { + if (algo[sizeof("dsa") - 1] == '\0') { memset(dsa_doit, 1, sizeof(dsa_doit)); - continue; + algo_found = 1; } if (opt_found(algo, dsa_choices, &i)) { dsa_doit[i] = 2; - continue; + algo_found = 1; } } if (strcmp(algo, "aes") == 0) { doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1; - continue; + algo_found = 1; } if (strcmp(algo, "camellia") == 0) { doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1; - continue; + algo_found = 1; } - if (strncmp(algo, "ecdsa", 5) == 0) { - if (algo[5] == '\0') { + if (HAS_PREFIX(algo, "ecdsa")) { + if (algo[sizeof("ecdsa") - 1] == '\0') { memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); - continue; + algo_found = 1; } if (opt_found(algo, ecdsa_choices, &i)) { ecdsa_doit[i] = 2; - continue; + algo_found = 1; } } - if (strncmp(algo, "ecdh", 4) == 0) { - if (algo[4] == '\0') { + if (HAS_PREFIX(algo, "ecdh")) { + if (algo[sizeof("ecdh") - 1] == '\0') { memset(ecdh_doit, 1, sizeof(ecdh_doit)); - continue; + algo_found = 1; } if (opt_found(algo, ecdh_choices, &i)) { ecdh_doit[i] = 2; - continue; + algo_found = 1; } } +#ifndef OPENSSL_NO_ECX if (strcmp(algo, "eddsa") == 0) { memset(eddsa_doit, 1, sizeof(eddsa_doit)); - continue; + algo_found = 1; } if (opt_found(algo, eddsa_choices, &i)) { eddsa_doit[i] = 2; - continue; + algo_found = 1; } +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 if (strcmp(algo, "sm2") == 0) { memset(sm2_doit, 1, sizeof(sm2_doit)); - continue; + algo_found = 1; } if (opt_found(algo, sm2_choices, &i)) { sm2_doit[i] = 2; - continue; + algo_found = 1; } #endif - BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo); - goto end; + if (kem_locate(algo, &idx)) { + kems_doit[idx]++; + do_kems = 1; + algo_found = 1; + } + if (sig_locate(algo, &idx)) { + sigs_doit[idx]++; + do_sigs = 1; + algo_found = 1; + } + + if (!algo_found) { + BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo); + goto end; + } } /* Sanity checks */ @@ -1785,6 +2241,28 @@ int speed_main(int argc, char **argv) goto end; } } + if (kems_algs_len > 0) { + int maxcnt = get_max(kems_doit, kems_algs_len); + + if (maxcnt > 1) { + /* some algs explicitly selected */ + for (i = 0; i < kems_algs_len; i++) { + /* disable the rest */ + kems_doit[i]--; + } + } + } + if (sigs_algs_len > 0) { + int maxcnt = get_max(sigs_doit, sigs_algs_len); + + if (maxcnt > 1) { + /* some algs explicitly selected */ + for (i = 0; i < sigs_algs_len; i++) { + /* disable the rest */ + sigs_doit[i]--; + } + } + } if (multiblock) { if (evp_cipher == NULL) { BIO_printf(bio_err, "-mb can be used only with a multi-block" @@ -1871,7 +2349,8 @@ int speed_main(int argc, char **argv) e = setup_engine(engine_id, 0); /* No parameters; turn on everything. */ - if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) { + if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] + && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) { memset(doit, 1, sizeof(doit)); doit[D_EVP] = doit[D_EVP_CMAC] = 0; ERR_set_mark(); @@ -1903,12 +2382,18 @@ int speed_main(int argc, char **argv) memset(ffdh_doit, 1, sizeof(ffdh_doit)); #endif memset(dsa_doit, 1, sizeof(dsa_doit)); +#ifndef OPENSSL_NO_ECX memset(ecdsa_doit, 1, sizeof(ecdsa_doit)); memset(ecdh_doit, 1, sizeof(ecdh_doit)); memset(eddsa_doit, 1, sizeof(eddsa_doit)); +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 memset(sm2_doit, 1, sizeof(sm2_doit)); #endif + memset(kems_doit, 1, sizeof(kems_doit)); + do_kems = 1; + memset(sigs_doit, 1, sizeof(sigs_doit)); + do_sigs = 1; } for (i = 0; i < ALGOR_NUM; i++) if (doit[i]) @@ -1925,8 +2410,7 @@ int speed_main(int argc, char **argv) if (doit[D_MD2]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_MD2], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs); d = Time_F(STOP); @@ -1938,8 +2422,7 @@ int speed_main(int argc, char **argv) if (doit[D_MDC2]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_MDC2], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs); d = Time_F(STOP); @@ -1951,8 +2434,7 @@ int speed_main(int argc, char **argv) if (doit[D_MD4]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_MD4], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs); d = Time_F(STOP); @@ -1964,8 +2446,7 @@ int speed_main(int argc, char **argv) if (doit[D_MD5]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_MD5], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, MD5_loop, loopargs); d = Time_F(STOP); @@ -1977,8 +2458,7 @@ int speed_main(int argc, char **argv) if (doit[D_SHA1]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_SHA1], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA1_loop, loopargs); d = Time_F(STOP); @@ -1990,8 +2470,7 @@ int speed_main(int argc, char **argv) if (doit[D_SHA256]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_SHA256], c[D_SHA256][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_SHA256], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA256_loop, loopargs); d = Time_F(STOP); @@ -2003,8 +2482,7 @@ int speed_main(int argc, char **argv) if (doit[D_SHA512]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_SHA512], c[D_SHA512][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_SHA512], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA512_loop, loopargs); d = Time_F(STOP); @@ -2016,8 +2494,7 @@ int speed_main(int argc, char **argv) if (doit[D_WHIRLPOOL]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_WHIRLPOOL], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs); d = Time_F(STOP); @@ -2029,8 +2506,7 @@ int speed_main(int argc, char **argv) if (doit[D_RMD160]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_RMD160], c[D_RMD160][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_RMD160], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs); d = Time_F(STOP); @@ -2071,8 +2547,7 @@ int speed_main(int argc, char **argv) goto skip_hmac; /* Digest not found */ } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_HMAC], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, HMAC_loop, loopargs); d = Time_F(STOP); @@ -2096,8 +2571,7 @@ int speed_main(int argc, char **argv) } algindex = D_CBC_DES; for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_CBC_DES], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); d = Time_F(STOP); @@ -2117,8 +2591,7 @@ int speed_main(int argc, char **argv) } algindex = D_EDE3_DES; for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); @@ -2142,8 +2615,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[algindex], c[algindex][testnum], - lengths[testnum], seconds.sym); + print_message(names[algindex], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); @@ -2168,8 +2640,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[algindex], c[algindex][testnum], - lengths[testnum], seconds.sym); + print_message(names[algindex], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); @@ -2193,8 +2664,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; st && testnum < size_num; testnum++) { - print_message(names[algindex], c[algindex][testnum], - lengths[testnum], seconds.sym); + print_message(names[algindex], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs); @@ -2229,8 +2699,7 @@ int speed_main(int argc, char **argv) goto end; } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_GHASH], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, GHASH_loop, loopargs); d = Time_F(STOP); @@ -2246,8 +2715,7 @@ int speed_main(int argc, char **argv) if (doit[D_RAND]) { for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_RAND], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs); d = Time_F(STOP); @@ -2280,8 +2748,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_EVP], lengths[testnum], seconds.sym); for (k = 0; k < loopargs_len; k++) { loopargs[k].ctx = EVP_CIPHER_CTX_new(); @@ -2309,8 +2776,9 @@ int speed_main(int argc, char **argv) } OPENSSL_clear_free(loopargs[k].key, keylen); - /* SIV mode only allows for a single Update operation */ - if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE) + /* GCM-SIV/SIV mode only allows for a single Update operation */ + if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE + || EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_GCM_SIV_MODE) (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_SET_SPEED, 1, NULL); } @@ -2326,8 +2794,7 @@ int speed_main(int argc, char **argv) names[D_EVP] = evp_md_name; for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum], - seconds.sym); + print_message(names[D_EVP], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs); d = Time_F(STOP); @@ -2375,8 +2842,7 @@ int speed_main(int argc, char **argv) } for (testnum = 0; testnum < size_num; testnum++) { - print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum], - lengths[testnum], seconds.sym); + print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, CMAC_loop, loopargs); d = Time_F(STOP); @@ -2439,16 +2905,15 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); op_count = 1; } else { - pkey_print_message("private", "rsa", - rsa_c[testnum][0], rsa_keys[testnum].bits, - seconds.rsa); + pkey_print_message("private", "rsa sign", + rsa_keys[testnum].bits, seconds.rsa); /* RSA_blinding_on(rsa_key[testnum],NULL); */ Time_F(START); count = run_benchmark(async_jobs, RSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n" - : "%ld %u bits private RSA's in %.2fs\n", + : "%ld %u bits private RSA sign ops in %.2fs\n", count, rsa_keys[testnum].bits, d); rsa_results[testnum][0] = (double)count / d; op_count = count; @@ -2471,19 +2936,81 @@ int speed_main(int argc, char **argv) ERR_print_errors(bio_err); rsa_doit[testnum] = 0; } else { - pkey_print_message("public", "rsa", - rsa_c[testnum][1], rsa_keys[testnum].bits, - seconds.rsa); + pkey_print_message("public", "rsa verify", + rsa_keys[testnum].bits, seconds.rsa); Time_F(START); count = run_benchmark(async_jobs, RSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n" - : "%ld %u bits public RSA's in %.2fs\n", + : "%ld %u bits public RSA verify ops in %.2fs\n", count, rsa_keys[testnum].bits, d); rsa_results[testnum][1] = (double)count / d; } + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL); + loopargs[i].encsize = loopargs[i].buflen; + if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL + || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0 + || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum], + loopargs[i].buf2, + &loopargs[i].encsize, + loopargs[i].buf, 36) <= 0) + st = 0; + } + if (!st) { + BIO_printf(bio_err, + "RSA encrypt setup failure. No RSA encrypt will be done.\n"); + ERR_print_errors(bio_err); + op_count = 1; + } else { + pkey_print_message("private", "rsa encrypt", + rsa_keys[testnum].bits, seconds.rsa); + /* RSA_blinding_on(rsa_key[testnum],NULL); */ + Time_F(START); + count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R3:%ld:%d:%.2f\n" + : "%ld %u bits public RSA encrypt ops in %.2fs\n", + count, rsa_keys[testnum].bits, d); + rsa_results[testnum][2] = (double)count / d; + op_count = count; + } + + for (i = 0; st && i < loopargs_len; i++) { + loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL); + declen = loopargs[i].buflen; + if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL + || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0 + || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum], + loopargs[i].buf, + &declen, + loopargs[i].buf2, + loopargs[i].encsize) <= 0) + st = 0; + } + if (!st) { + BIO_printf(bio_err, + "RSA decrypt setup failure. No RSA decrypt will be done.\n"); + ERR_print_errors(bio_err); + op_count = 1; + } else { + pkey_print_message("private", "rsa decrypt", + rsa_keys[testnum].bits, seconds.rsa); + /* RSA_blinding_on(rsa_key[testnum],NULL); */ + Time_F(START); + count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R4:%ld:%d:%.2f\n" + : "%ld %u bits private RSA decrypt ops in %.2fs\n", + count, rsa_keys[testnum].bits, d); + rsa_results[testnum][3] = (double)count / d; + op_count = count; + } + if (op_count <= 1) { /* if longer than 10s, don't do any more */ stop_it(rsa_doit, testnum); @@ -2520,14 +3047,13 @@ int speed_main(int argc, char **argv) op_count = 1; } else { pkey_print_message("sign", "dsa", - dsa_c[testnum][0], dsa_bits[testnum], - seconds.dsa); + dsa_bits[testnum], seconds.dsa); Time_F(START); count = run_benchmark(async_jobs, DSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R3:%ld:%u:%.2f\n" - : "%ld %u bits DSA signs in %.2fs\n", + mr ? "+R5:%ld:%u:%.2f\n" + : "%ld %u bits DSA sign ops in %.2fs\n", count, dsa_bits[testnum], d); dsa_results[testnum][0] = (double)count / d; op_count = count; @@ -2551,14 +3077,13 @@ int speed_main(int argc, char **argv) dsa_doit[testnum] = 0; } else { pkey_print_message("verify", "dsa", - dsa_c[testnum][1], dsa_bits[testnum], - seconds.dsa); + dsa_bits[testnum], seconds.dsa); Time_F(START); count = run_benchmark(async_jobs, DSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R4:%ld:%u:%.2f\n" - : "%ld %u bits DSA verify in %.2fs\n", + mr ? "+R6:%ld:%u:%.2f\n" + : "%ld %u bits DSA verify ops in %.2fs\n", count, dsa_bits[testnum], d); dsa_results[testnum][1] = (double)count / d; } @@ -2599,14 +3124,13 @@ int speed_main(int argc, char **argv) op_count = 1; } else { pkey_print_message("sign", "ecdsa", - ecdsa_c[testnum][0], ec_curves[testnum].bits, - seconds.ecdsa); + ec_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R5:%ld:%u:%.2f\n" - : "%ld %u bits ECDSA signs in %.2fs\n", + mr ? "+R7:%ld:%u:%.2f\n" + : "%ld %u bits ECDSA sign ops in %.2fs\n", count, ec_curves[testnum].bits, d); ecdsa_results[testnum][0] = (double)count / d; op_count = count; @@ -2630,14 +3154,13 @@ int speed_main(int argc, char **argv) ecdsa_doit[testnum] = 0; } else { pkey_print_message("verify", "ecdsa", - ecdsa_c[testnum][1], ec_curves[testnum].bits, - seconds.ecdsa); + ec_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R6:%ld:%u:%.2f\n" - : "%ld %u bits ECDSA verify in %.2fs\n", + mr ? "+R8:%ld:%u:%.2f\n" + : "%ld %u bits ECDSA verify ops in %.2fs\n", count, ec_curves[testnum].bits, d); ecdsa_results[testnum][1] = (double)count / d; } @@ -2717,14 +3240,13 @@ int speed_main(int argc, char **argv) } if (ecdh_checks != 0) { pkey_print_message("", "ecdh", - ecdh_c[testnum][0], ec_curves[testnum].bits, seconds.ecdh); Time_F(START); count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R7:%ld:%d:%.2f\n" : + mr ? "+R9:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count, ec_curves[testnum].bits, d); ecdh_results[testnum][0] = (double)count / d; @@ -2737,6 +3259,7 @@ int speed_main(int argc, char **argv) } } +#ifndef OPENSSL_NO_ECX for (testnum = 0; testnum < EdDSA_NUM; testnum++) { int st = 1; EVP_PKEY *ed_pkey = NULL; @@ -2803,15 +3326,14 @@ int speed_main(int argc, char **argv) op_count = 1; } else { pkey_print_message("sign", ed_curves[testnum].name, - eddsa_c[testnum][0], ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R8:%ld:%u:%s:%.2f\n" : - "%ld %u bits %s signs in %.2fs \n", + mr ? "+R10:%ld:%u:%s:%.2f\n" : + "%ld %u bits %s sign ops in %.2fs \n", count, ed_curves[testnum].bits, ed_curves[testnum].name, d); eddsa_results[testnum][0] = (double)count / d; @@ -2832,14 +3354,13 @@ int speed_main(int argc, char **argv) eddsa_doit[testnum] = 0; } else { pkey_print_message("verify", ed_curves[testnum].name, - eddsa_c[testnum][1], ed_curves[testnum].bits, seconds.eddsa); Time_F(START); count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R9:%ld:%u:%s:%.2f\n" - : "%ld %u bits %s verify in %.2fs\n", + mr ? "+R11:%ld:%u:%s:%.2f\n" + : "%ld %u bits %s verify ops in %.2fs\n", count, ed_curves[testnum].bits, ed_curves[testnum].name, d); eddsa_results[testnum][1] = (double)count / d; @@ -2851,6 +3372,7 @@ int speed_main(int argc, char **argv) } } } +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 for (testnum = 0; testnum < SM2_NUM; testnum++) { @@ -2935,15 +3457,14 @@ int speed_main(int argc, char **argv) op_count = 1; } else { pkey_print_message("sign", sm2_curves[testnum].name, - sm2_c[testnum][0], sm2_curves[testnum].bits, seconds.sm2); Time_F(START); count = run_benchmark(async_jobs, SM2_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R10:%ld:%u:%s:%.2f\n" : - "%ld %u bits %s signs in %.2fs \n", + mr ? "+R12:%ld:%u:%s:%.2f\n" : + "%ld %u bits %s sign ops in %.2fs \n", count, sm2_curves[testnum].bits, sm2_curves[testnum].name, d); sm2_results[testnum][0] = (double)count / d; @@ -2965,14 +3486,13 @@ int speed_main(int argc, char **argv) sm2_doit[testnum] = 0; } else { pkey_print_message("verify", sm2_curves[testnum].name, - sm2_c[testnum][1], sm2_curves[testnum].bits, seconds.sm2); Time_F(START); count = run_benchmark(async_jobs, SM2_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R11:%ld:%u:%s:%.2f\n" - : "%ld %u bits %s verify in %.2fs\n", + mr ? "+R13:%ld:%u:%s:%.2f\n" + : "%ld %u bits %s verify ops in %.2fs\n", count, sm2_curves[testnum].bits, sm2_curves[testnum].name, d); sm2_results[testnum][1] = (double)count / d; @@ -3150,14 +3670,14 @@ int speed_main(int argc, char **argv) test_ctx = NULL; } if (ffdh_checks != 0) { - pkey_print_message("", "ffdh", ffdh_c[testnum][0], + pkey_print_message("", "ffdh", ffdh_params[testnum].bits, seconds.ffdh); Time_F(START); count = run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R12:%ld:%d:%.2f\n" : + mr ? "+R14:%ld:%d:%.2f\n" : "%ld %u-bits FFDH ops in %.2fs\n", count, ffdh_params[testnum].bits, d); ffdh_results[testnum][0] = (double)count / d; @@ -3169,6 +3689,376 @@ int speed_main(int argc, char **argv) } } #endif /* OPENSSL_NO_DH */ + + for (testnum = 0; testnum < kems_algs_len; testnum++) { + int kem_checks = 1; + const char *kem_name = kems_algname[testnum]; + + if (!kems_doit[testnum] || !do_kems) + continue; + + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *kem_gen_ctx = NULL; + EVP_PKEY_CTX *kem_encaps_ctx = NULL; + EVP_PKEY_CTX *kem_decaps_ctx = NULL; + size_t send_secret_len, out_len; + size_t rcv_secret_len; + unsigned char *out = NULL, *send_secret = NULL, *rcv_secret; + unsigned int bits; + char *name; + char sfx[MAX_ALGNAME_SUFFIX]; + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int use_params = 0; + enum kem_type_t { KEM_RSA = 1, KEM_EC, KEM_X25519, KEM_X448 } kem_type; + + /* no string after rsa permitted: */ + if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */ + && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1) + kem_type = KEM_RSA; + else if (strncmp(kem_name, "EC", 2) == 0) + kem_type = KEM_EC; + else if (strcmp(kem_name, "X25519") == 0) + kem_type = KEM_X25519; + else if (strcmp(kem_name, "X448") == 0) + kem_type = KEM_X448; + else kem_type = 0; + + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + if (kem_type == KEM_RSA) { + params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS, + &bits); + use_params = 1; + } else if (kem_type == KEM_EC) { + name = (char *)(kem_name + 2); + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + name, 0); + use_params = 1; + } + + kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), + (kem_type == KEM_RSA) ? "RSA": + (kem_type == KEM_EC) ? "EC": + kem_name, + app_get0_propq()); + + if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0) + || (use_params + && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) { + BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n", + kem_name); + goto kem_err_break; + } + if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) { + BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n"); + goto kem_err_break; + } + /* Now prepare encaps data structs */ + kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), + pkey, + app_get0_propq()); + if (kem_encaps_ctx == NULL + || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0 + || (kem_type == KEM_RSA + && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0) + || ((kem_type == KEM_EC + || kem_type == KEM_X25519 + || kem_type == KEM_X448) + && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0) + || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len, + NULL, &send_secret_len) <= 0) { + BIO_printf(bio_err, + "Error while initializing encaps data structs for %s.\n", + kem_name); + goto kem_err_break; + } + out = app_malloc(out_len, "encaps result"); + send_secret = app_malloc(send_secret_len, "encaps secret"); + if (out == NULL || send_secret == NULL) { + BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name); + goto kem_err_break; + } + if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len, + send_secret, &send_secret_len) <= 0) { + BIO_printf(bio_err, "Encaps error for %s.\n", kem_name); + goto kem_err_break; + } + /* Now prepare decaps data structs */ + kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), + pkey, + app_get0_propq()); + if (kem_decaps_ctx == NULL + || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0 + || (kem_type == KEM_RSA + && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0) + || ((kem_type == KEM_EC + || kem_type == KEM_X25519 + || kem_type == KEM_X448) + && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0) + || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len, + out, out_len) <= 0) { + BIO_printf(bio_err, + "Error while initializing decaps data structs for %s.\n", + kem_name); + goto kem_err_break; + } + rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret"); + if (rcv_secret == NULL) { + BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n", + kem_name); + goto kem_err_break; + } + if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret, + &rcv_secret_len, out, out_len) <= 0 + || rcv_secret_len != send_secret_len + || memcmp(send_secret, rcv_secret, send_secret_len)) { + BIO_printf(bio_err, "Decaps error for %s.\n", kem_name); + goto kem_err_break; + } + loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx; + loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx; + loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx; + loopargs[i].kem_out_len[testnum] = out_len; + loopargs[i].kem_secret_len[testnum] = send_secret_len; + loopargs[i].kem_out[testnum] = out; + loopargs[i].kem_send_secret[testnum] = send_secret; + loopargs[i].kem_rcv_secret[testnum] = rcv_secret; + EVP_PKEY_free(pkey); + pkey = NULL; + continue; + + kem_err_break: + ERR_print_errors(bio_err); + EVP_PKEY_free(pkey); + op_count = 1; + kem_checks = 0; + break; + } + if (kem_checks != 0) { + kskey_print_message(kem_name, "keygen", seconds.kem); + Time_F(START); + count = + run_benchmark(async_jobs, KEM_keygen_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R15:%ld:%s:%.2f\n" : + "%ld %s KEM keygen ops in %.2fs\n", count, + kem_name, d); + kems_results[testnum][0] = (double)count / d; + op_count = count; + kskey_print_message(kem_name, "encaps", seconds.kem); + Time_F(START); + count = + run_benchmark(async_jobs, KEM_encaps_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R16:%ld:%s:%.2f\n" : + "%ld %s KEM encaps ops in %.2fs\n", count, + kem_name, d); + kems_results[testnum][1] = (double)count / d; + op_count = count; + kskey_print_message(kem_name, "decaps", seconds.kem); + Time_F(START); + count = + run_benchmark(async_jobs, KEM_decaps_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R17:%ld:%s:%.2f\n" : + "%ld %s KEM decaps ops in %.2fs\n", count, + kem_name, d); + kems_results[testnum][2] = (double)count / d; + op_count = count; + } + if (op_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(kems_doit, testnum); + } + } + + for (testnum = 0; testnum < sigs_algs_len; testnum++) { + int sig_checks = 1; + const char *sig_name = sigs_algname[testnum]; + + if (!sigs_doit[testnum] || !do_sigs) + continue; + + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx_params = NULL; + EVP_PKEY* pkey_params = NULL; + EVP_PKEY_CTX *sig_gen_ctx = NULL; + EVP_PKEY_CTX *sig_sign_ctx = NULL; + EVP_PKEY_CTX *sig_verify_ctx = NULL; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char *sig; + char sfx[MAX_ALGNAME_SUFFIX]; + size_t md_len = SHA256_DIGEST_LENGTH; + size_t max_sig_len, sig_len; + unsigned int bits; + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + int use_params = 0; + + /* only sign little data to avoid measuring digest performance */ + memset(md, 0, SHA256_DIGEST_LENGTH); + + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + /* no string after rsa permitted: */ + if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */ + && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) { + params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS, + &bits); + use_params = 1; + } + + if (strncmp(sig_name, "dsa", 3) == 0) { + ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if (ctx_params == NULL + || EVP_PKEY_paramgen_init(ctx_params) <= 0 + || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params, + atoi(sig_name + 3)) <= 0 + || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0 + || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL + || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) { + BIO_printf(bio_err, + "Error initializing classic keygen ctx for %s.\n", + sig_name); + goto sig_err_break; + } + } + + if (sig_gen_ctx == NULL) + sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), + use_params == 1 ? "RSA" : sig_name, + app_get0_propq()); + + if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0 + || (use_params && + EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) { + BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n", + sig_name); + goto sig_err_break; + } + if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) { + BIO_printf(bio_err, + "Error while generating signature EVP_PKEY for %s.\n", + sig_name); + goto sig_err_break; + } + /* Now prepare signature data structs */ + sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), + pkey, + app_get0_propq()); + if (sig_sign_ctx == NULL + || EVP_PKEY_sign_init(sig_sign_ctx) <= 0 + || (use_params == 1 + && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx, + RSA_PKCS1_PADDING) <= 0)) + || EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len, + md, md_len) <= 0) { + BIO_printf(bio_err, + "Error while initializing signing data structs for %s.\n", + sig_name); + goto sig_err_break; + } + sig = app_malloc(sig_len = max_sig_len, "signature buffer"); + if (sig == NULL) { + BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name); + goto sig_err_break; + } + if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) { + BIO_printf(bio_err, "Signing error for %s.\n", sig_name); + goto sig_err_break; + } + /* Now prepare verify data structs */ + memset(md, 0, SHA256_DIGEST_LENGTH); + sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), + pkey, + app_get0_propq()); + if (sig_verify_ctx == NULL + || EVP_PKEY_verify_init(sig_verify_ctx) <= 0 + || (use_params == 1 + && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx, + RSA_PKCS1_PADDING) <= 0))) { + BIO_printf(bio_err, + "Error while initializing verify data structs for %s.\n", + sig_name); + goto sig_err_break; + } + if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) { + BIO_printf(bio_err, "Verify error for %s.\n", sig_name); + goto sig_err_break; + } + if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) { + BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name); + goto sig_err_break; + } + loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx; + loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx; + loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx; + loopargs[i].sig_max_sig_len[testnum] = max_sig_len; + loopargs[i].sig_act_sig_len[testnum] = sig_len; + loopargs[i].sig_sig[testnum] = sig; + EVP_PKEY_free(pkey); + pkey = NULL; + continue; + + sig_err_break: + ERR_print_errors(bio_err); + EVP_PKEY_free(pkey); + op_count = 1; + sig_checks = 0; + break; + } + + if (sig_checks != 0) { + kskey_print_message(sig_name, "keygen", seconds.sig); + Time_F(START); + count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R18:%ld:%s:%.2f\n" : + "%ld %s signature keygen ops in %.2fs\n", count, + sig_name, d); + sigs_results[testnum][0] = (double)count / d; + op_count = count; + kskey_print_message(sig_name, "signs", seconds.sig); + Time_F(START); + count = + run_benchmark(async_jobs, SIG_sign_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R19:%ld:%s:%.2f\n" : + "%ld %s signature sign ops in %.2fs\n", count, + sig_name, d); + sigs_results[testnum][1] = (double)count / d; + op_count = count; + + kskey_print_message(sig_name, "verify", seconds.sig); + Time_F(START); + count = + run_benchmark(async_jobs, SIG_verify_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R20:%ld:%s:%.2f\n" : + "%ld %s signature verify ops in %.2fs\n", count, + sig_name, d); + sigs_results[testnum][2] = (double)count / d; + op_count = count; + } + if (op_count <= 1) + stop_it(sigs_doit, testnum); + } + #ifndef NO_FORK show_res: #endif @@ -3222,16 +4112,20 @@ int speed_main(int argc, char **argv) if (!rsa_doit[k]) continue; if (testnum && !mr) { - printf("%18ssign verify sign/s verify/s\n", " "); + printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " "); testnum = 0; } if (mr) - printf("+F2:%u:%u:%f:%f\n", - k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]); + printf("+F2:%u:%u:%f:%f:%f:%f\n", + k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1], + rsa_results[k][2], rsa_results[k][3]); else - printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", - rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1], - rsa_results[k][0], rsa_results[k][1]); + printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n", + rsa_keys[k].bits, 1.0 / rsa_results[k][0], + 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2], + 1.0 / rsa_results[k][3], + rsa_results[k][0], rsa_results[k][1], + rsa_results[k][2], rsa_results[k][3]); } testnum = 1; for (k = 0; k < DSA_NUM; k++) { @@ -3288,6 +4182,7 @@ int speed_main(int argc, char **argv) 1.0 / ecdh_results[k][0], ecdh_results[k][0]); } +#ifndef OPENSSL_NO_ECX testnum = 1; for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) { if (!eddsa_doit[k]) @@ -3307,6 +4202,7 @@ int speed_main(int argc, char **argv) 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1], eddsa_results[k][0], eddsa_results[k][1]); } +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 testnum = 1; @@ -3350,6 +4246,48 @@ int speed_main(int argc, char **argv) } #endif /* OPENSSL_NO_DH */ + testnum = 1; + for (k = 0; k < kems_algs_len; k++) { + const char *kem_name = kems_algname[k]; + + if (!kems_doit[k] || !do_kems) + continue; + if (testnum && !mr) { + printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " "); + testnum = 0; + } + if (mr) + printf("+F9:%u:%f:%f:%f\n", + k, kems_results[k][0], kems_results[k][1], + kems_results[k][2]); + else + printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name, + 1.0 / kems_results[k][0], + 1.0 / kems_results[k][1], 1.0 / kems_results[k][2], + kems_results[k][0], kems_results[k][1], kems_results[k][2]); + } + ret = 0; + + testnum = 1; + for (k = 0; k < sigs_algs_len; k++) { + const char *sig_name = sigs_algname[k]; + + if (!sigs_doit[k] || !do_sigs) + continue; + if (testnum && !mr) { + printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " "); + testnum = 0; + } + if (mr) + printf("+F10:%u:%f:%f:%f\n", + k, sigs_results[k][0], sigs_results[k][1], + sigs_results[k][2]); + else + printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name, + 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1], + 1.0 / sigs_results[k][2], sigs_results[k][0], + sigs_results[k][1], sigs_results[k][2]); + } ret = 0; end: @@ -3363,6 +4301,8 @@ int speed_main(int argc, char **argv) for (k = 0; k < RSA_NUM; k++) { EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]); EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]); } #ifndef OPENSSL_NO_DH OPENSSL_free(loopargs[i].secret_ff_a); @@ -3380,10 +4320,12 @@ int speed_main(int argc, char **argv) } for (k = 0; k < EC_NUM; k++) EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]); +#ifndef OPENSSL_NO_ECX for (k = 0; k < EdDSA_NUM; k++) { EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]); EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]); } +#endif /* OPENSSL_NO_ECX */ #ifndef OPENSSL_NO_SM2 for (k = 0; k < SM2_NUM; k++) { EVP_PKEY_CTX *pctx = NULL; @@ -3402,11 +4344,33 @@ int speed_main(int argc, char **argv) EVP_PKEY_free(loopargs[i].sm2_pkey[k]); } #endif + for (k = 0; k < kems_algs_len; k++) { + EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]); + OPENSSL_free(loopargs[i].kem_out[k]); + OPENSSL_free(loopargs[i].kem_send_secret[k]); + OPENSSL_free(loopargs[i].kem_rcv_secret[k]); + } + for (k = 0; k < sigs_algs_len; k++) { + EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]); + EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]); + OPENSSL_free(loopargs[i].sig_sig[k]); + } OPENSSL_free(loopargs[i].secret_a); OPENSSL_free(loopargs[i].secret_b); } OPENSSL_free(evp_hmac_name); OPENSSL_free(evp_cmac_name); + for (k = 0; k < kems_algs_len; k++) + OPENSSL_free(kems_algname[k]); + if (kem_stack != NULL) + sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free); + for (k = 0; k < sigs_algs_len; k++) + OPENSSL_free(sigs_algname[k]); + if (sig_stack != NULL) + sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free); if (async_jobs > 0) { for (i = 0; i < loopargs_len; i++) @@ -3424,22 +4388,32 @@ int speed_main(int argc, char **argv) return ret; } -static void print_message(const char *s, long num, int length, int tm) +static void print_message(const char *s, int length, int tm) { BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n" - : "Doing %s for %ds on %d size blocks: ", s, tm, length); + : "Doing %s ops for %ds on %d size blocks: ", s, tm, length); (void)BIO_flush(bio_err); run = 1; alarm(tm); } -static void pkey_print_message(const char *str, const char *str2, long num, - unsigned int bits, int tm) +static void pkey_print_message(const char *str, const char *str2, unsigned int bits, + int tm) { BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n" - : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm); + : "Doing %u bits %s %s ops for %ds: ", bits, str, str2, tm); + (void)BIO_flush(bio_err); + run = 1; + alarm(tm); +} + +static void kskey_print_message(const char *str, const char *str2, int tm) +{ + BIO_printf(bio_err, + mr ? "+DTP:%s:%s:%d\n" + : "Doing %s %s ops for %ds: ", str, str2, tm); (void)BIO_flush(bio_err); run = 1; alarm(tm); @@ -3454,7 +4428,7 @@ static void print_result(int alg, int run_no, int count, double time_used) } BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" - : "%d %s's in %.2fs\n", count, names[alg], time_used); + : "%d %s ops in %.2fs\n", count, names[alg], time_used); results[alg][run_no] = ((double)count) / time_used * lengths[run_no]; } @@ -3464,9 +4438,6 @@ static char *sstrsep(char **string, const char *delim) char isdelim[256]; char *token = *string; - if (**string == 0) - return NULL; - memset(isdelim, 0, sizeof(isdelim)); isdelim[0] = 1; @@ -3486,6 +4457,23 @@ static char *sstrsep(char **string, const char *delim) return token; } +static int strtoint(const char *str, const int min_val, const int upper_val, + int *res) +{ + char *end = NULL; + long int val = 0; + + errno = 0; + val = strtol(str, &end, 10); + if (errno == 0 && end != str && *end == 0 + && min_val <= val && val < upper_val) { + *res = (int)val; + return 1; + } else { + return 0; + } +} + static int do_multi(int multi, int size_num) { int n; @@ -3526,6 +4514,9 @@ static int do_multi(int multi, int size_num) FILE *f; char buf[1024]; char *p; + char *tk; + int k; + double d; if ((f = fdopen(fds[n], "r")) == NULL) { BIO_printf(bio_err, "fdopen failure with 0x%x\n", @@ -3544,109 +4535,126 @@ static int do_multi(int multi, int size_num) continue; } printf("Got: %s from %d\n", buf, n); - if (strncmp(buf, "+F:", 3) == 0) { + p = buf; + if (CHECK_AND_SKIP_PREFIX(p, "+F:")) { int alg; int j; - p = buf + 3; - alg = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - for (j = 0; j < size_num; ++j) - results[alg][j] += atof(sstrsep(&p, sep)); - } else if (strncmp(buf, "+F2:", 4) == 0) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - rsa_results[k][0] += d; - - d = atof(sstrsep(&p, sep)); - rsa_results[k][1] += d; - } else if (strncmp(buf, "+F3:", 4) == 0) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - dsa_results[k][0] += d; - - d = atof(sstrsep(&p, sep)); - dsa_results[k][1] += d; - } else if (strncmp(buf, "+F4:", 4) == 0) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - ecdsa_results[k][0] += d; - - d = atof(sstrsep(&p, sep)); - ecdsa_results[k][1] += d; - } else if (strncmp(buf, "+F5:", 4) == 0) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - ecdh_results[k][0] += d; - } else if (strncmp(buf, "+F6:", 4) == 0) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - eddsa_results[k][0] += d; - - d = atof(sstrsep(&p, sep)); - eddsa_results[k][1] += d; -# ifndef OPENSSL_NO_SM2 - } else if (strncmp(buf, "+F7:", 4) == 0) { - int k; - double d; + if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) { + sstrsep(&p, sep); + for (j = 0; j < size_num; ++j) + results[alg][j] += atof(sstrsep(&p, sep)); + } + } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) { + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + rsa_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + rsa_results[k][1] += d; + + d = atof(sstrsep(&p, sep)); + rsa_results[k][2] += d; + + d = atof(sstrsep(&p, sep)); + rsa_results[k][3] += d; + } + } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) { + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + dsa_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + dsa_results[k][1] += d; + } + } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) { + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + ecdsa_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + ecdsa_results[k][1] += d; + } + } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) { + sstrsep(&p, sep); - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - sstrsep(&p, sep); + d = atof(sstrsep(&p, sep)); + ecdh_results[k][0] += d; + } +# ifndef OPENSSL_NO_ECX + } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) { + sstrsep(&p, sep); + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + eddsa_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + eddsa_results[k][1] += d; + } +# endif /* OPENSSL_NO_ECX */ +# ifndef OPENSSL_NO_SM2 + } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) { + sstrsep(&p, sep); + sstrsep(&p, sep); - d = atof(sstrsep(&p, sep)); - sm2_results[k][0] += d; + d = atof(sstrsep(&p, sep)); + sm2_results[k][0] += d; - d = atof(sstrsep(&p, sep)); - sm2_results[k][1] += d; + d = atof(sstrsep(&p, sep)); + sm2_results[k][1] += d; + } # endif /* OPENSSL_NO_SM2 */ # ifndef OPENSSL_NO_DH - } else if (strncmp(buf, "+F8:", 4) == 0) { - int k; - double d; + } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) { + sstrsep(&p, sep); - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - - d = atof(sstrsep(&p, sep)); - ffdh_results[k][0] += d; + d = atof(sstrsep(&p, sep)); + ffdh_results[k][0] += d; + } # endif /* OPENSSL_NO_DH */ - } else if (strncmp(buf, "+H:", 3) == 0) { - ; - } else { + } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) { + d = atof(sstrsep(&p, sep)); + kems_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + kems_results[k][1] += d; + + d = atof(sstrsep(&p, sep)); + kems_results[k][2] += d; + } + } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) { + tk = sstrsep(&p, sep); + if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) { + d = atof(sstrsep(&p, sep)); + sigs_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + sigs_results[k][1] += d; + + d = atof(sstrsep(&p, sep)); + sigs_results[k][2] += d; + } + } else if (!HAS_PREFIX(buf, "+H:")) { BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf, n); } @@ -3679,7 +4687,7 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, static const int mblengths_list[] = { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 }; const int *mblengths = mblengths_list; - int j, count, keylen, num = OSSL_NELEM(mblengths_list); + int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1; const char *alg_name; unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16]; EVP_CIPHER_CTX *ctx = NULL; @@ -3715,7 +4723,7 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, app_bail_out("failed to get cipher name\n"); for (j = 0; j < num; j++) { - print_message(alg_name, 0, mblengths[j], seconds->sym); + print_message(alg_name, mblengths[j], seconds->sym); Time_F(START); for (count = 0; run && count < INT_MAX; count++) { unsigned char aad[EVP_AEAD_TLS1_AAD_LEN]; @@ -3754,12 +4762,14 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, aad[12] = (unsigned char)(len); pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, EVP_AEAD_TLS1_AAD_LEN, aad); - EVP_Cipher(ctx, out, inp, len + pad); + ciph_success = EVP_Cipher(ctx, out, inp, len + pad); } } d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" - : "%d %s's in %.2fs\n", count, "evp", d); + : "%d %s ops in %.2fs\n", count, "evp", d); + if ((ciph_success <= 0) && (mr == 0)) + BIO_printf(bio_err, "Error performing cipher op\n"); results[D_EVP][j] = ((double)count) / d * mblengths[j]; } diff --git a/apps/spkac.c b/apps/spkac.c index d92be7d645..5a129a7fa7 100644 --- a/apps/spkac.c +++ b/apps/spkac.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -133,8 +133,7 @@ int spkac_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_passwd(passinarg, NULL, &passin, NULL)) { @@ -153,9 +152,10 @@ int spkac_main(int argc, char **argv) spki = NETSCAPE_SPKI_new(); if (spki == NULL) goto end; - if (challenge != NULL) - ASN1_STRING_set(spki->spkac->challenge, - challenge, (int)strlen(challenge)); + if (challenge != NULL + && !ASN1_STRING_set(spki->spkac->challenge, + challenge, (int)strlen(challenge))) + goto end; if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) { BIO_printf(bio_err, "Error setting public key\n"); goto end; diff --git a/apps/storeutl.c b/apps/storeutl.c index cb237de0a1..249dc75c83 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -74,7 +74,7 @@ int storeutl_main(int argc, char *argv[]) BIO *out = NULL; ENGINE *e = NULL; OPTION_CHOICE o; - char *prog = opt_init(argc, argv, storeutl_options); + char *prog; PW_CB_DATA pw_cb_data; int expected = 0; int criterion = 0; @@ -87,6 +87,8 @@ int storeutl_main(int argc, char *argv[]) EVP_MD *digest = NULL; OSSL_LIB_CTX *libctx = app_get0_libctx(); + opt_set_unknown_name("digest"); + prog = opt_init(argc, argv, storeutl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: @@ -256,15 +258,12 @@ int storeutl_main(int argc, char *argv[]) } /* One argument, the URI */ - argc = opt_num_rest(); - argv = opt_rest(); - if (argc != 1) + if (!opt_check_rest_arg("URI")) goto opthelp; + argv = opt_rest(); - if (digestname != NULL) { - if (!opt_md(digestname, &digest)) - goto opthelp; - } + if (!opt_md(digestname, &digest)) + goto opthelp; if (criterion != 0) { switch (criterion) { diff --git a/apps/tsget.in b/apps/tsget.in index 3b5f83cf9b..8eab6a8f1f 100644 --- a/apps/tsget.in +++ b/apps/tsget.in @@ -1,5 +1,5 @@ #!{- $config{HASHBANGPERL} -} -# Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2002 The OpenTSA Project. All rights reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/apps/verify.c b/apps/verify.c index 22b8eb94b5..93b214281e 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -234,8 +234,8 @@ int verify_main(int argc, char **argv) end: X509_VERIFY_PARAM_free(vpm); X509_STORE_free(store); - sk_X509_pop_free(untrusted, X509_free); - sk_X509_pop_free(trusted, X509_free); + OSSL_STACK_OF_X509_free(untrusted); + OSSL_STACK_OF_X509_free(trusted); sk_X509_CRL_pop_free(crls, X509_CRL_free); sk_OPENSSL_STRING_free(vfyopts); release_engine(e); @@ -308,7 +308,7 @@ static int check(X509_STORE *ctx, const char *file, BIO_printf(bio_out, " (untrusted)"); BIO_printf(bio_out, "\n"); } - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); } } else { BIO_printf(bio_err, diff --git a/apps/version.c b/apps/version.c index cab17a46bf..7185e9edcd 100644 --- a/apps/version.c +++ b/apps/version.c @@ -99,8 +99,7 @@ int version_main(int argc, char **argv) } /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!dirty) diff --git a/apps/x509.c b/apps/x509.c index a919d78745..578af2364f 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -70,7 +70,7 @@ const OPTIONS x509_options[] = { {"copy_extensions", OPT_COPY_EXTENSIONS, 's', "copy extensions when converting from CSR to x509 or vice versa"}, {"inform", OPT_INFORM, 'f', - "CSR input file format (DER or PEM) - default PEM"}, + "CSR input format to use (PEM or DER; by default try PEM first)"}, {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, {"key", OPT_KEY, 's', "Key for signing, and to include unless using -force_pubkey"}, @@ -87,7 +87,8 @@ const OPTIONS x509_options[] = { OPT_SECTION("Certificate printing"), {"text", OPT_TEXT, '-', "Print the certificate in text form"}, - {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, + {"dateopt", OPT_DATEOPT, 's', + "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, {"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"}, {"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"}, {"alias", OPT_ALIAS, '-', "Print certificate alias"}, @@ -139,7 +140,7 @@ const OPTIONS x509_options[] = { "Preserve existing validity dates"}, {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, {"force_pubkey", OPT_FORCE_PUBKEY, '<', - "Place the given key in new certificate"}, + "Key to be placed in new certificate or certificate request"}, {"clrext", OPT_CLREXT, '-', "Do not take over any extensions from the source certificate or request"}, {"extfile", OPT_EXTFILE, '<', "Config file with X509V3 extensions to add"}, @@ -299,9 +300,10 @@ int x509_main(int argc, char **argv) ctx = X509_STORE_new(); if (ctx == NULL) - goto end; + goto err; X509_STORE_set_verify_cb(ctx, callb); + opt_set_unknown_name("digest"); prog = opt_init(argc, argv, x509_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -309,7 +311,7 @@ int x509_main(int argc, char **argv) case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); - goto end; + goto err; case OPT_HELP: opt_help(x509_options); ret = 0; @@ -348,14 +350,14 @@ int x509_main(int argc, char **argv) if (!set_dateopt(&dateopt, opt_arg())) { BIO_printf(bio_err, "Invalid date format: %s\n", opt_arg()); - goto end; + goto err; } break; case OPT_COPY_EXTENSIONS: if (!set_ext_copy(&ext_copy, opt_arg())) { BIO_printf(bio_err, "Invalid extension copy option: %s\n", opt_arg()); - goto end; + goto err; } break; @@ -376,7 +378,7 @@ int x509_main(int argc, char **argv) if (days < -1) { BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n", prog); - goto end; + goto err; } break; case OPT_PASSIN: @@ -592,25 +594,26 @@ int x509_main(int argc, char **argv) break; } } - /* No extra arguments. */ - argc = opt_num_rest(); - if (argc != 0) + if (!opt_check_rest_arg(NULL)) goto opthelp; if (!app_RAND_load()) goto end; + if (!opt_check_md(digest)) + goto opthelp; + if (preserve_dates && days != UNSET_DAYS) { BIO_printf(bio_err, "Cannot use -preserve_dates with -days option\n"); - goto end; + goto err; } if (days == UNSET_DAYS) days = DEFAULT_DAYS; if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); - goto end; + goto err; } if (!X509_STORE_set_default_paths_ex(ctx, app_get0_libctx(), @@ -619,12 +622,11 @@ int x509_main(int argc, char **argv) if (newcert && infile != NULL) { BIO_printf(bio_err, "The -in option cannot be used with -new\n"); - goto end; + goto err; } if (newcert && reqfile) { - BIO_printf(bio_err, - "The -req option cannot be used with -new\n"); - goto end; + BIO_printf(bio_err, "The -req option cannot be used with -new\n"); + goto err; } if (privkeyfile != NULL) { privkey = load_key(privkeyfile, keyformat, 0, passin, e, "private key"); @@ -641,12 +643,12 @@ int x509_main(int argc, char **argv) if (subj == NULL) { BIO_printf(bio_err, "The -new option requires a subject to be set using -subj\n"); - goto end; + goto err; } if (privkeyfile == NULL && pubkeyfile == NULL) { BIO_printf(bio_err, "The -new option requires using the -key or -force_pubkey option\n"); - goto end; + goto err; } } if (subj != NULL @@ -658,7 +660,7 @@ int x509_main(int argc, char **argv) if (CAfile != NULL) { if (privkeyfile != NULL) { BIO_printf(bio_err, "Cannot use both -key/-signkey and -CA option\n"); - goto end; + goto err; } } else { #define WARN_NO_CA(opt) BIO_printf(bio_err, \ @@ -685,36 +687,38 @@ int x509_main(int argc, char **argv) if ((extconf = app_load_config(extfile)) == NULL) goto end; if (extsect == NULL) { - extsect = NCONF_get_string(extconf, "default", "extensions"); - if (extsect == NULL) { - ERR_clear_error(); + extsect = app_conf_try_string(extconf, "default", "extensions"); + if (extsect == NULL) extsect = "default"; - } } X509V3_set_ctx_test(&ctx2); X509V3_set_nconf(&ctx2, extconf); if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error checking extension section %s\n", extsect); - goto end; + goto err; } } if (reqfile) { - req = load_csr(infile, informat, "certificate request input"); + if (infile == NULL) + BIO_printf(bio_err, + "Warning: Reading cert request from stdin since no -in option is given\n"); + req = load_csr_autofmt(infile, informat, vfyopts, + "certificate request input"); if (req == NULL) goto end; if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) { BIO_printf(bio_err, "Error unpacking public key from CSR\n"); - goto end; + goto err; } i = do_X509_REQ_verify(req, pkey, vfyopts); if (i <= 0) { BIO_printf(bio_err, i < 0 ? "Error while verifying certificate request self-signature\n" : "Certificate request self-signature did not match the contents\n"); - goto end; + goto err; } BIO_printf(bio_err, "Certificate request self-signature ok\n"); @@ -731,7 +735,7 @@ int x509_main(int argc, char **argv) if (privkeyfile == NULL && CAkeyfile == NULL) { BIO_printf(bio_err, "We need a private key to sign with, use -key or -CAkey or -CA with private key\n"); - goto end; + goto err; } if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; @@ -743,13 +747,16 @@ int x509_main(int argc, char **argv) if (req != NULL && ext_copy != EXT_COPY_UNSET) { if (clrext && ext_copy != EXT_COPY_NONE) { BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n"); - goto end; + goto err; } else if (!copy_extensions(x, req, ext_copy)) { BIO_printf(bio_err, "Error copying extensions from request\n"); - goto end; + goto err; } } } else { + if (infile == NULL) + BIO_printf(bio_err, + "Warning: Reading certificate from stdin since no -in or -new option is given\n"); x = load_cert_pass(infile, informat, 1, passin, "certificate"); if (x == NULL) goto end; @@ -774,9 +781,6 @@ int x509_main(int argc, char **argv) if (out == NULL) goto end; - if (!noout || text || next_serial) - OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); - if (alias) X509_alias_set1(x, (unsigned char *)alias, -1); @@ -814,6 +818,10 @@ int x509_main(int argc, char **argv) goto end; if (!x509toreq && !reqfile && !newcert && !self_signed(ctx, x)) goto end; + } else { + if (privkey != NULL && !cert_matches_key(x, privkey)) + BIO_printf(bio_err, + "Warning: Signature key and public key of cert do not match\n"); } if (sno != NULL && !X509_set_serialNumber(x, sno)) @@ -837,7 +845,7 @@ int x509_main(int argc, char **argv) if (!X509V3_EXT_add_nconf(extconf, &ext_ctx, extsect, x)) { BIO_printf(bio_err, "Error adding extensions from section %s\n", extsect); - goto end; + goto err; } } @@ -846,17 +854,17 @@ int x509_main(int argc, char **argv) pkey = X509_get0_pubkey(x); if ((print_pubkey != 0 || modulus != 0) && pkey == NULL) { BIO_printf(bio_err, "Error getting public key\n"); - goto end; + goto err; } if (x509toreq) { /* also works in conjunction with -req */ if (privkey == NULL) { BIO_printf(bio_err, "Must specify request signing key using -key\n"); - goto end; + goto err; } if (clrext && ext_copy != EXT_COPY_NONE) { BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n"); - goto end; + goto err; } if ((rq = x509_to_req(x, ext_copy, ext_names)) == NULL) goto end; @@ -865,7 +873,7 @@ int x509_main(int argc, char **argv) if (!X509V3_EXT_REQ_add_nconf(extconf, &ext_ctx, extsect, rq)) { BIO_printf(bio_err, "Error adding request extensions from section %s\n", extsect); - goto end; + goto err; } } if (!do_X509_REQ_sign(rq, privkey, digest, sigopts)) @@ -880,13 +888,10 @@ int x509_main(int argc, char **argv) if (!i) { BIO_printf(bio_err, "Unable to write certificate request\n"); - goto end; + goto err; } } noout = 1; - } else if (privkey != NULL) { - if (!do_X509_sign(x, privkey, digest, sigopts, &ext_ctx)) - goto end; } else if (CAfile != NULL) { if ((CAkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA private key")) == NULL) @@ -894,10 +899,13 @@ int x509_main(int argc, char **argv) if (!X509_check_private_key(xca, CAkey)) { BIO_printf(bio_err, "CA certificate and CA private key do not match\n"); - goto end; + goto err; } - if (!do_X509_sign(x, CAkey, digest, sigopts, &ext_ctx)) + if (!do_X509_sign(x, 0, CAkey, digest, sigopts, &ext_ctx)) + goto end; + } else if (privkey != NULL) { + if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx)) goto end; } if (badsig) { @@ -1007,13 +1015,13 @@ int x509_main(int argc, char **argv) if ((fdig = EVP_MD_fetch(app_get0_libctx(), fdigname, app_get0_propq())) == NULL) { BIO_printf(bio_err, "Unknown digest\n"); - goto end; + goto err; } digres = X509_digest(x, fdig, md, &n); EVP_MD_free(fdig); if (!digres) { BIO_printf(bio_err, "Out of memory\n"); - goto end; + goto err; } BIO_printf(out, "%s Fingerprint=", fdigname); @@ -1037,7 +1045,8 @@ int x509_main(int argc, char **argv) goto end; } - print_cert_checks(out, x, checkhost, checkemail, checkip); + if (!check_cert_attributes(out, x, checkhost, checkemail, checkip, 1)) + goto err; if (noout || nocert) { ret = 0; @@ -1053,17 +1062,20 @@ int x509_main(int argc, char **argv) i = PEM_write_bio_X509(out, x); } else { BIO_printf(bio_err, "Bad output format specified for outfile\n"); - goto end; + goto err; } if (!i) { BIO_printf(bio_err, "Unable to write certificate\n"); - goto end; + goto err; } + ret = 0; + goto end; + + err: + ERR_print_errors(bio_err); end: - if (ret != 0) - ERR_print_errors(bio_err); NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); @@ -1137,16 +1149,7 @@ static int callb(int ok, X509_STORE_CTX *ctx) if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) return 1; - /* - * BAD we should have gotten an error. Normally if everything worked - * X509_STORE_CTX_get_error(ctx) will still be set to - * DEPTH_ZERO_SELF_.... - */ - if (ok) { - BIO_printf(bio_err, - "Error with certificate to be certified - should be self-signed\n"); - return 0; - } else { + if (!ok) { err_cert = X509_STORE_CTX_get_current_cert(ctx); print_name(bio_err, "subject=", X509_get_subject_name(err_cert)); BIO_printf(bio_err, @@ -1155,6 +1158,8 @@ static int callb(int ok, X509_STORE_CTX *ctx) X509_verify_cert_error_string(err)); return 1; } + + return 1; } static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) diff --git a/crypto/aes/aes_x86core.c b/crypto/aes/aes_x86core.c index da525b6566..8e54e80a6c 100644 --- a/crypto/aes/aes_x86core.c +++ b/crypto/aes/aes_x86core.c @@ -63,12 +63,13 @@ #if 1 static void prefetch256(const void *table) { - volatile unsigned long *t=(void *)table,ret; + volatile unsigned long *t = (void *)table, ret; unsigned long sum; int i; /* 32 is common least cache-line size */ - for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0])) sum ^= t[i]; + for (sum = 0, i = 0; i < 256/sizeof(t[0]); i += 32/sizeof(t[0])) + sum ^= t[i]; ret = sum; } diff --git a/crypto/aes/asm/aes-riscv32-zkn.pl b/crypto/aes/asm/aes-riscv32-zkn.pl index 7a20f66e5c..6fac451846 100644 --- a/crypto/aes/asm/aes-riscv32-zkn.pl +++ b/crypto/aes/asm/aes-riscv32-zkn.pl @@ -1,10 +1,38 @@ #! /usr/bin/env perl -# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +# This file is dual-licensed, meaning that you can use it under your +# choice of either of the following two licenses: # -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at +# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You can obtain +# a copy in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html +# +# or +# +# Copyright (c) 2022, Hongren (Zenithal) Zheng +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # $output is the last argument if it looks like a file (it has an extension) # $flavour is the first argument if it doesn't look like a file diff --git a/crypto/aes/asm/aes-riscv64-zkn.pl b/crypto/aes/asm/aes-riscv64-zkn.pl index fe4d26eac5..0e8a1540c4 100644 --- a/crypto/aes/asm/aes-riscv64-zkn.pl +++ b/crypto/aes/asm/aes-riscv64-zkn.pl @@ -1,15 +1,51 @@ #! /usr/bin/env perl -# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +# This file is dual-licensed, meaning that you can use it under your +# choice of either of the following two licenses: # -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at +# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You can obtain +# a copy in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html +# +# or +# +# Copyright (c) 2022, Hongren (Zenithal) Zheng +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; + +use FindBin qw($Bin); +use lib "$Bin"; +use lib "$Bin/../../perlasm"; +use riscv; # $output is the last argument if it looks like a file (it has an extension) # $flavour is the first argument if it doesn't look like a file -$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; -$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $output and open STDOUT,">$output"; @@ -69,103 +105,6 @@ } } -################################################################################ -# util for encoding scalar crypto extension instructions -################################################################################ - -my @regs = map("x$_",(0..31)); -my %reglookup; -@reglookup{@regs} = @regs; - -# Takes a register name, possibly an alias, and converts it to a register index -# from 0 to 31 -sub read_reg { - my $reg = lc shift; - if (!exists($reglookup{$reg})) { - die("Unknown register ".$reg); - } - my $regstr = $reglookup{$reg}; - if (!($regstr =~ /^x([0-9]+)$/)) { - die("Could not process register ".$reg); - } - return $1; -} - -sub rv64_aes64ds { - # Encoding for aes64ds rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0011101_00000_00000_000_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; - - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64dsm { - # Encoding for aes64dsm rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0011111_00000_00000_000_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; - - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64es { - # Encoding for aes64es rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0011001_00000_00000_000_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; - - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64esm { - # Encoding for aes64esm rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0011011_00000_00000_000_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; - - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64im { - # Encoding for aes64im rd, rs1 instruction on RV64 - # XXXXXXXXXXXX_ rs1 _XXX_ rd _XXXXXXX - my $template = 0b001100000000_00000_001_00000_0010011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - - return ".word ".($template | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64ks1i { - # Encoding for aes64ks1i rd, rs1, rnum instruction on RV64 - # XXXXXXXX_rnum_ rs1 _XXX_ rd _XXXXXXX - my $template = 0b00110001_0000_00000_001_00000_0010011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rnum = shift; - - return ".word ".($template | ($rnum << 20) | ($rs1 << 15) | ($rd << 7)); -} - -sub rv64_aes64ks2 { - # Encoding for aes64ks2 rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0111111_00000_00000_000_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; - - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); -} ################################################################################ # Register assignment for rv64i_zkne_encrypt and rv64i_zknd_decrypt ################################################################################ @@ -219,8 +158,8 @@ sub rv64_aes64ks2 { # Do Nr - 1 rounds (final round is special) 1: - @{[rv64_aes64esm $Q2,$Q0,$Q1]} - @{[rv64_aes64esm $Q3,$Q1,$Q0]} + @{[aes64esm $Q2,$Q0,$Q1]} + @{[aes64esm $Q3,$Q1,$Q0]} # Update key ptr to point to next key in schedule add $KEYP,$KEYP,16 @@ -235,8 +174,8 @@ sub rv64_aes64ks2 { bgtz $loopcntr,1b # final round - @{[rv64_aes64es $Q2,$Q0,$Q1]} - @{[rv64_aes64es $Q3,$Q1,$Q0]} + @{[aes64es $Q2,$Q0,$Q1]} + @{[aes64es $Q3,$Q1,$Q0]} # since not added 16 before ld $T0,16($KEYP) @@ -293,8 +232,8 @@ sub rv64_aes64ks2 { # Do Nr - 1 rounds (final round is special) 1: - @{[rv64_aes64dsm $Q2,$Q0,$Q1]} - @{[rv64_aes64dsm $Q3,$Q1,$Q0]} + @{[aes64dsm $Q2,$Q0,$Q1]} + @{[aes64dsm $Q3,$Q1,$Q0]} # Update key ptr to point to next key in schedule add $KEYP,$KEYP,-16 @@ -309,8 +248,8 @@ sub rv64_aes64ks2 { bgtz $loopcntr,1b # final round - @{[rv64_aes64ds $Q2,$Q0,$Q1]} - @{[rv64_aes64ds $Q3,$Q1,$Q0]} + @{[aes64ds $Q2,$Q0,$Q1]} + @{[aes64ds $Q3,$Q1,$Q0]} add $KEYP,$KEYP,-16 ld $T0,0($KEYP) @@ -356,9 +295,9 @@ sub ke128enc { ___ while($rnum < 10) { $ret .= <<___; - @{[rv64_aes64ks1i $T2,$T1,$rnum]} - @{[rv64_aes64ks2 $T0,$T2,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T2,$T1,$rnum]} + @{[aes64ks2 $T0,$T2,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} add $KEYP,$KEYP,16 sd $T0,0($KEYP) sd $T1,8($KEYP) @@ -381,15 +320,15 @@ sub ke192enc { ___ while($rnum < 8) { $ret .= <<___; - @{[rv64_aes64ks1i $T3,$T2,$rnum]} - @{[rv64_aes64ks2 $T0,$T3,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T3,$T2,$rnum]} + @{[aes64ks2 $T0,$T3,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} ___ if ($rnum != 7) { # note that (8+1)*24 = 216, (12+1)*16 = 208 # thus the last 8 bytes can be dropped $ret .= <<___; - @{[rv64_aes64ks2 $T2,$T1,$T2]} + @{[aes64ks2 $T2,$T1,$T2]} ___ } $ret .= <<___; @@ -422,9 +361,9 @@ sub ke256enc { ___ while($rnum < 7) { $ret .= <<___; - @{[rv64_aes64ks1i $T4,$T3,$rnum]} - @{[rv64_aes64ks2 $T0,$T4,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T4,$T3,$rnum]} + @{[aes64ks2 $T0,$T4,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} add $KEYP,$KEYP,32 sd $T0,0($KEYP) sd $T1,8($KEYP) @@ -433,9 +372,9 @@ sub ke256enc { # note that (7+1)*32 = 256, (14+1)*16 = 240 # thus the last 16 bytes can be dropped $ret .= <<___; - @{[rv64_aes64ks1i $T4,$T1,0xA]} - @{[rv64_aes64ks2 $T2,$T4,$T2]} - @{[rv64_aes64ks2 $T3,$T2,$T3]} + @{[aes64ks1i $T4,$T1,0xA]} + @{[aes64ks2 $T2,$T4,$T2]} + @{[aes64ks2 $T3,$T2,$T3]} sd $T2,16($KEYP) sd $T3,24($KEYP) ___ @@ -515,9 +454,9 @@ sub ke128dec { ___ while($rnum < 10) { $ret .= <<___; - @{[rv64_aes64ks1i $T2,$T1,$rnum]} - @{[rv64_aes64ks2 $T0,$T2,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T2,$T1,$rnum]} + @{[aes64ks2 $T0,$T2,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} add $KEYP,$KEYP,16 ___ # need to aes64im for [1:N-1] round keys @@ -528,9 +467,9 @@ sub ke128dec { # transform should then be done on the round key if ($rnum < 9) { $ret .= <<___; - @{[rv64_aes64im $T2,$T0]} + @{[aes64im $T2,$T0]} sd $T2,0($KEYP) - @{[rv64_aes64im $T2,$T1]} + @{[aes64im $T2,$T1]} sd $T2,8($KEYP) ___ } else { @@ -553,25 +492,25 @@ sub ke192dec { ld $T2,16($UKEY) sd $T0,0($KEYP) sd $T1,8($KEYP) - @{[rv64_aes64im $T3,$T2]} + @{[aes64im $T3,$T2]} sd $T3,16($KEYP) ___ while($rnum < 8) { $ret .= <<___; - @{[rv64_aes64ks1i $T3,$T2,$rnum]} - @{[rv64_aes64ks2 $T0,$T3,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T3,$T2,$rnum]} + @{[aes64ks2 $T0,$T3,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} add $KEYP,$KEYP,24 ___ if ($rnum < 7) { $ret .= <<___; - @{[rv64_aes64im $T3,$T0]} + @{[aes64im $T3,$T0]} sd $T3,0($KEYP) - @{[rv64_aes64im $T3,$T1]} + @{[aes64im $T3,$T1]} sd $T3,8($KEYP) # the reason is in ke192enc - @{[rv64_aes64ks2 $T2,$T1,$T2]} - @{[rv64_aes64im $T3,$T2]} + @{[aes64ks2 $T2,$T1,$T2]} + @{[aes64im $T3,$T2]} sd $T3,16($KEYP) ___ } else { # rnum == 7 @@ -595,30 +534,30 @@ sub ke256dec { ld $T3,24($UKEY) sd $T0,0($KEYP) sd $T1,8($KEYP) - @{[rv64_aes64im $T4,$T2]} + @{[aes64im $T4,$T2]} sd $T4,16($KEYP) - @{[rv64_aes64im $T4,$T3]} + @{[aes64im $T4,$T3]} sd $T4,24($KEYP) ___ while($rnum < 7) { $ret .= <<___; - @{[rv64_aes64ks1i $T4,$T3,$rnum]} - @{[rv64_aes64ks2 $T0,$T4,$T0]} - @{[rv64_aes64ks2 $T1,$T0,$T1]} + @{[aes64ks1i $T4,$T3,$rnum]} + @{[aes64ks2 $T0,$T4,$T0]} + @{[aes64ks2 $T1,$T0,$T1]} add $KEYP,$KEYP,32 ___ if ($rnum < 6) { $ret .= <<___; - @{[rv64_aes64ks1i $T4,$T1,0xA]} - @{[rv64_aes64ks2 $T2,$T4,$T2]} - @{[rv64_aes64ks2 $T3,$T2,$T3]} - @{[rv64_aes64im $T4,$T0]} + @{[aes64ks1i $T4,$T1,0xA]} + @{[aes64ks2 $T2,$T4,$T2]} + @{[aes64ks2 $T3,$T2,$T3]} + @{[aes64im $T4,$T0]} sd $T4,0($KEYP) - @{[rv64_aes64im $T4,$T1]} + @{[aes64im $T4,$T1]} sd $T4,8($KEYP) - @{[rv64_aes64im $T4,$T2]} + @{[aes64im $T4,$T2]} sd $T4,16($KEYP) - @{[rv64_aes64im $T4,$T3]} + @{[aes64im $T4,$T3]} sd $T4,24($KEYP) ___ } else { diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl index d8cc378b5f..7cf838db17 100644 --- a/crypto/aes/asm/aesni-x86.pl +++ b/crypto/aes/asm/aesni-x86.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aesp8-ppc.pl b/crypto/aes/asm/aesp8-ppc.pl index 60cf86f52a..ce176c605b 100755 --- a/crypto/aes/asm/aesp8-ppc.pl +++ b/crypto/aes/asm/aesp8-ppc.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -99,11 +99,12 @@ .long 0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000 ?rev .long 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c ?rev .long 0,0,0,0 ?asis +.long 0x0f102132, 0x43546576, 0x8798a9ba, 0xcbdcedfe Lconsts: mflr r0 bcl 20,31,\$+4 mflr $ptr #vvvvv "distance between . and rcon - addi $ptr,$ptr,-0x48 + addi $ptr,$ptr,-0x58 mtlr r0 blr .long 0 @@ -2405,7 +2406,7 @@ () my $key_=$key2; my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31)); $x00=0 if ($flavour =~ /osx/); -my ($in0, $in1, $in2, $in3, $in4, $in5 )=map("v$_",(0..5)); +my ($in0, $in1, $in2, $in3, $in4, $in5)=map("v$_",(0..5)); my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16)); my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22)); my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys @@ -2460,6 +2461,18 @@ () li $x70,0x70 mtspr 256,r0 + # Reverse eighty7 to 0x010101..87 + xxlor 2, 32+$eighty7, 32+$eighty7 + vsldoi $eighty7,$tmp,$eighty7,1 # 0x010101..87 + xxlor 1, 32+$eighty7, 32+$eighty7 + + # Load XOR contents. 0xf102132435465768798a9bacbdcedfe + mr $x70, r6 + bl Lconsts + lxvw4x 0, $x40, r6 # load XOR contents + mr r6, $x70 + li $x70,0x70 + subi $rounds,$rounds,3 # -4 in total lvx $rndkey0,$x00,$key1 # load key schedule @@ -2502,69 +2515,77 @@ () ?vperm v31,v31,$twk5,$keyperm lvx v25,$x10,$key_ # pre-load round[2] + # Switch to use the following codes with 0x010101..87 to generate tweak. + # eighty7 = 0x010101..87 + # vsrab tmp, tweak, seven # next tweak value, right shift 7 bits + # vand tmp, tmp, eighty7 # last byte with carry + # vaddubm tweak, tweak, tweak # left shift 1 bit (x2) + # xxlor vsx, 0, 0 + # vpermxor tweak, tweak, tmp, vsx + vperm $in0,$inout,$inptail,$inpperm subi $inp,$inp,31 # undo "caller" vxor $twk0,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vand $tmp,$tmp,$eighty7 vxor $out0,$in0,$twk0 - vxor $tweak,$tweak,$tmp + xxlor 32+$in1, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in1 lvx_u $in1,$x10,$inp vxor $twk1,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in1,$in1,$in1,$leperm vand $tmp,$tmp,$eighty7 vxor $out1,$in1,$twk1 - vxor $tweak,$tweak,$tmp + xxlor 32+$in2, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in2 lvx_u $in2,$x20,$inp andi. $taillen,$len,15 vxor $twk2,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in2,$in2,$in2,$leperm vand $tmp,$tmp,$eighty7 vxor $out2,$in2,$twk2 - vxor $tweak,$tweak,$tmp + xxlor 32+$in3, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in3 lvx_u $in3,$x30,$inp sub $len,$len,$taillen vxor $twk3,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in3,$in3,$in3,$leperm vand $tmp,$tmp,$eighty7 vxor $out3,$in3,$twk3 - vxor $tweak,$tweak,$tmp + xxlor 32+$in4, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in4 lvx_u $in4,$x40,$inp subi $len,$len,0x60 vxor $twk4,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in4,$in4,$in4,$leperm vand $tmp,$tmp,$eighty7 vxor $out4,$in4,$twk4 - vxor $tweak,$tweak,$tmp + xxlor 32+$in5, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in5 lvx_u $in5,$x50,$inp addi $inp,$inp,0x60 vxor $twk5,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in5,$in5,$in5,$leperm vand $tmp,$tmp,$eighty7 vxor $out5,$in5,$twk5 - vxor $tweak,$tweak,$tmp + xxlor 32+$in0, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in0 vxor v31,v31,$rndkey0 mtctr $rounds @@ -2590,6 +2611,8 @@ () lvx v25,$x10,$key_ # round[4] bdnz Loop_xts_enc6x + xxlor 32+$eighty7, 1, 1 # 0x010101..87 + subic $len,$len,96 # $len-=96 vxor $in0,$twk0,v31 # xor with last round key vcipher $out0,$out0,v24 @@ -2599,7 +2622,6 @@ () vaddubm $tweak,$tweak,$tweak vcipher $out2,$out2,v24 vcipher $out3,$out3,v24 - vsldoi $tmp,$tmp,$tmp,15 vcipher $out4,$out4,v24 vcipher $out5,$out5,v24 @@ -2607,7 +2629,8 @@ () vand $tmp,$tmp,$eighty7 vcipher $out0,$out0,v25 vcipher $out1,$out1,v25 - vxor $tweak,$tweak,$tmp + xxlor 32+$in1, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in1 vcipher $out2,$out2,v25 vcipher $out3,$out3,v25 vxor $in1,$twk1,v31 @@ -2618,13 +2641,13 @@ () and r0,r0,$len vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vcipher $out0,$out0,v26 vcipher $out1,$out1,v26 vand $tmp,$tmp,$eighty7 vcipher $out2,$out2,v26 vcipher $out3,$out3,v26 - vxor $tweak,$tweak,$tmp + xxlor 32+$in2, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in2 vcipher $out4,$out4,v26 vcipher $out5,$out5,v26 @@ -2638,7 +2661,6 @@ () vaddubm $tweak,$tweak,$tweak vcipher $out0,$out0,v27 vcipher $out1,$out1,v27 - vsldoi $tmp,$tmp,$tmp,15 vcipher $out2,$out2,v27 vcipher $out3,$out3,v27 vand $tmp,$tmp,$eighty7 @@ -2646,7 +2668,8 @@ () vcipher $out5,$out5,v27 addi $key_,$sp,$FRAME+15 # rewind $key_ - vxor $tweak,$tweak,$tmp + xxlor 32+$in3, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in3 vcipher $out0,$out0,v28 vcipher $out1,$out1,v28 vxor $in3,$twk3,v31 @@ -2655,7 +2678,6 @@ () vcipher $out2,$out2,v28 vcipher $out3,$out3,v28 vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vcipher $out4,$out4,v28 vcipher $out5,$out5,v28 lvx v24,$x00,$key_ # re-pre-load round[1] @@ -2663,7 +2685,8 @@ () vcipher $out0,$out0,v29 vcipher $out1,$out1,v29 - vxor $tweak,$tweak,$tmp + xxlor 32+$in4, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in4 vcipher $out2,$out2,v29 vcipher $out3,$out3,v29 vxor $in4,$twk4,v31 @@ -2673,14 +2696,14 @@ () vcipher $out5,$out5,v29 lvx v25,$x10,$key_ # re-pre-load round[2] vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vcipher $out0,$out0,v30 vcipher $out1,$out1,v30 vand $tmp,$tmp,$eighty7 vcipher $out2,$out2,v30 vcipher $out3,$out3,v30 - vxor $tweak,$tweak,$tmp + xxlor 32+$in5, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in5 vcipher $out4,$out4,v30 vcipher $out5,$out5,v30 vxor $in5,$twk5,v31 @@ -2690,7 +2713,6 @@ () vcipherlast $out0,$out0,$in0 lvx_u $in0,$x00,$inp # load next input block vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vcipherlast $out1,$out1,$in1 lvx_u $in1,$x10,$inp vcipherlast $out2,$out2,$in2 @@ -2703,7 +2725,10 @@ () vcipherlast $out4,$out4,$in4 le?vperm $in2,$in2,$in2,$leperm lvx_u $in4,$x40,$inp - vxor $tweak,$tweak,$tmp + xxlor 10, 32+$in0, 32+$in0 + xxlor 32+$in0, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in0 + xxlor 32+$in0, 10, 10 vcipherlast $tmp,$out5,$in5 # last block might be needed # in stealing mode le?vperm $in3,$in3,$in3,$leperm @@ -2736,6 +2761,8 @@ () mtctr $rounds beq Loop_xts_enc6x # did $len-=96 borrow? + xxlor 32+$eighty7, 2, 2 # 0x870101..01 + addic. $len,$len,0x60 beq Lxts_enc6x_zero cmpwi $len,0x20 @@ -3112,6 +3139,18 @@ () li $x70,0x70 mtspr 256,r0 + # Reverse eighty7 to 0x010101..87 + xxlor 2, 32+$eighty7, 32+$eighty7 + vsldoi $eighty7,$tmp,$eighty7,1 # 0x010101..87 + xxlor 1, 32+$eighty7, 32+$eighty7 + + # Load XOR contents. 0xf102132435465768798a9bacbdcedfe + mr $x70, r6 + bl Lconsts + lxvw4x 0, $x40, r6 # load XOR contents + mr r6, $x70 + li $x70,0x70 + subi $rounds,$rounds,3 # -4 in total lvx $rndkey0,$x00,$key1 # load key schedule @@ -3159,64 +3198,64 @@ () vxor $twk0,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vand $tmp,$tmp,$eighty7 vxor $out0,$in0,$twk0 - vxor $tweak,$tweak,$tmp + xxlor 32+$in1, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in1 lvx_u $in1,$x10,$inp vxor $twk1,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in1,$in1,$in1,$leperm vand $tmp,$tmp,$eighty7 vxor $out1,$in1,$twk1 - vxor $tweak,$tweak,$tmp + xxlor 32+$in2, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in2 lvx_u $in2,$x20,$inp andi. $taillen,$len,15 vxor $twk2,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in2,$in2,$in2,$leperm vand $tmp,$tmp,$eighty7 vxor $out2,$in2,$twk2 - vxor $tweak,$tweak,$tmp + xxlor 32+$in3, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in3 lvx_u $in3,$x30,$inp sub $len,$len,$taillen vxor $twk3,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in3,$in3,$in3,$leperm vand $tmp,$tmp,$eighty7 vxor $out3,$in3,$twk3 - vxor $tweak,$tweak,$tmp + xxlor 32+$in4, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in4 lvx_u $in4,$x40,$inp subi $len,$len,0x60 vxor $twk4,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in4,$in4,$in4,$leperm vand $tmp,$tmp,$eighty7 vxor $out4,$in4,$twk4 - vxor $tweak,$tweak,$tmp + xxlor 32+$in5, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in5 lvx_u $in5,$x50,$inp addi $inp,$inp,0x60 vxor $twk5,$tweak,$rndkey0 vsrab $tmp,$tweak,$seven # next tweak value vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 le?vperm $in5,$in5,$in5,$leperm vand $tmp,$tmp,$eighty7 vxor $out5,$in5,$twk5 - vxor $tweak,$tweak,$tmp + xxlor 32+$in0, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in0 vxor v31,v31,$rndkey0 mtctr $rounds @@ -3242,6 +3281,8 @@ () lvx v25,$x10,$key_ # round[4] bdnz Loop_xts_dec6x + xxlor 32+$eighty7, 1, 1 + subic $len,$len,96 # $len-=96 vxor $in0,$twk0,v31 # xor with last round key vncipher $out0,$out0,v24 @@ -3251,7 +3292,6 @@ () vaddubm $tweak,$tweak,$tweak vncipher $out2,$out2,v24 vncipher $out3,$out3,v24 - vsldoi $tmp,$tmp,$tmp,15 vncipher $out4,$out4,v24 vncipher $out5,$out5,v24 @@ -3259,7 +3299,8 @@ () vand $tmp,$tmp,$eighty7 vncipher $out0,$out0,v25 vncipher $out1,$out1,v25 - vxor $tweak,$tweak,$tmp + xxlor 32+$in1, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in1 vncipher $out2,$out2,v25 vncipher $out3,$out3,v25 vxor $in1,$twk1,v31 @@ -3270,13 +3311,13 @@ () and r0,r0,$len vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vncipher $out0,$out0,v26 vncipher $out1,$out1,v26 vand $tmp,$tmp,$eighty7 vncipher $out2,$out2,v26 vncipher $out3,$out3,v26 - vxor $tweak,$tweak,$tmp + xxlor 32+$in2, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in2 vncipher $out4,$out4,v26 vncipher $out5,$out5,v26 @@ -3290,7 +3331,6 @@ () vaddubm $tweak,$tweak,$tweak vncipher $out0,$out0,v27 vncipher $out1,$out1,v27 - vsldoi $tmp,$tmp,$tmp,15 vncipher $out2,$out2,v27 vncipher $out3,$out3,v27 vand $tmp,$tmp,$eighty7 @@ -3298,7 +3338,8 @@ () vncipher $out5,$out5,v27 addi $key_,$sp,$FRAME+15 # rewind $key_ - vxor $tweak,$tweak,$tmp + xxlor 32+$in3, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in3 vncipher $out0,$out0,v28 vncipher $out1,$out1,v28 vxor $in3,$twk3,v31 @@ -3307,7 +3348,6 @@ () vncipher $out2,$out2,v28 vncipher $out3,$out3,v28 vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vncipher $out4,$out4,v28 vncipher $out5,$out5,v28 lvx v24,$x00,$key_ # re-pre-load round[1] @@ -3315,7 +3355,8 @@ () vncipher $out0,$out0,v29 vncipher $out1,$out1,v29 - vxor $tweak,$tweak,$tmp + xxlor 32+$in4, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in4 vncipher $out2,$out2,v29 vncipher $out3,$out3,v29 vxor $in4,$twk4,v31 @@ -3325,14 +3366,14 @@ () vncipher $out5,$out5,v29 lvx v25,$x10,$key_ # re-pre-load round[2] vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vncipher $out0,$out0,v30 vncipher $out1,$out1,v30 vand $tmp,$tmp,$eighty7 vncipher $out2,$out2,v30 vncipher $out3,$out3,v30 - vxor $tweak,$tweak,$tmp + xxlor 32+$in5, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in5 vncipher $out4,$out4,v30 vncipher $out5,$out5,v30 vxor $in5,$twk5,v31 @@ -3342,7 +3383,6 @@ () vncipherlast $out0,$out0,$in0 lvx_u $in0,$x00,$inp # load next input block vaddubm $tweak,$tweak,$tweak - vsldoi $tmp,$tmp,$tmp,15 vncipherlast $out1,$out1,$in1 lvx_u $in1,$x10,$inp vncipherlast $out2,$out2,$in2 @@ -3355,7 +3395,10 @@ () vncipherlast $out4,$out4,$in4 le?vperm $in2,$in2,$in2,$leperm lvx_u $in4,$x40,$inp - vxor $tweak,$tweak,$tmp + xxlor 10, 32+$in0, 32+$in0 + xxlor 32+$in0, 0, 0 + vpermxor $tweak, $tweak, $tmp, $in0 + xxlor 32+$in0, 10, 10 vncipherlast $out5,$out5,$in5 le?vperm $in3,$in3,$in3,$leperm lvx_u $in5,$x50,$inp @@ -3386,6 +3429,8 @@ () mtctr $rounds beq Loop_xts_dec6x # did $len-=96 borrow? + xxlor 32+$eighty7, 2, 2 + addic. $len,$len,0x60 beq Lxts_dec6x_zero cmpwi $len,0x20 diff --git a/crypto/aes/asm/bsaes-armv8.S b/crypto/aes/asm/bsaes-armv8.S index c5cf4796d3..905d524761 100644 --- a/crypto/aes/asm/bsaes-armv8.S +++ b/crypto/aes/asm/bsaes-armv8.S @@ -1818,7 +1818,7 @@ ossl_bsaes_xts_encrypt: sub x6, x21, #0x10 // Penultimate plaintext block produces final ciphertext part-block // plus remaining part of final plaintext block. Move ciphertext part - // to final position and re-use penultimate ciphertext block buffer to + // to final position and reuse penultimate ciphertext block buffer to // construct final plaintext block .Lxts_enc_steal: ldrb w0, [x20], #1 @@ -2295,7 +2295,7 @@ ossl_bsaes_xts_decrypt: mov x6, x21 // Penultimate ciphertext block produces final plaintext part-block // plus remaining part of final ciphertext block. Move plaintext part - // to final position and re-use penultimate plaintext block buffer to + // to final position and reuse penultimate plaintext block buffer to // construct final ciphertext block .Lxts_dec_steal: ldrb w1, [x21] diff --git a/crypto/aes/asm/bsaes-armv8.pl b/crypto/aes/asm/bsaes-armv8.pl index 3c2e8bdc95..b3c97e439f 100644 --- a/crypto/aes/asm/bsaes-armv8.pl +++ b/crypto/aes/asm/bsaes-armv8.pl @@ -1852,7 +1852,7 @@ sub data sub x6, x21, #0x10 // Penultimate plaintext block produces final ciphertext part-block // plus remaining part of final plaintext block. Move ciphertext part - // to final position and re-use penultimate ciphertext block buffer to + // to final position and reuse penultimate ciphertext block buffer to // construct final plaintext block .Lxts_enc_steal: ldrb w0, [x20], #1 @@ -2329,7 +2329,7 @@ sub data mov x6, x21 // Penultimate ciphertext block produces final plaintext part-block // plus remaining part of final ciphertext block. Move plaintext part - // to final position and re-use penultimate plaintext block buffer to + // to final position and reuse penultimate plaintext block buffer to // construct final ciphertext block .Lxts_dec_steal: ldrb w1, [x21] diff --git a/crypto/aes/asm/vpaes-armv8.pl b/crypto/aes/asm/vpaes-armv8.pl index 6b85324f89..49988e9c2b 100755 --- a/crypto/aes/asm/vpaes-armv8.pl +++ b/crypto/aes/asm/vpaes-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aria/aria.c b/crypto/aria/aria.c index 5e60bc5210..84ddd00cd8 100644 --- a/crypto/aria/aria.c +++ b/crypto/aria/aria.c @@ -498,7 +498,7 @@ void ossl_aria_encrypt(const unsigned char *in, unsigned char *out, ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3); rk++; - while(Nr -= 2){ + while ((Nr -= 2) > 0) { ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3); ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3); rk++; diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h index 7d35a19d1d..83acbe0126 100644 --- a/crypto/arm_arch.h +++ b/crypto/arm_arch.h @@ -49,6 +49,8 @@ # else # error "unsupported ARM architecture" # endif +# elif defined(__ARM_ARCH) +# define __ARM_ARCH__ __ARM_ARCH # endif # endif @@ -85,6 +87,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; # define ARMV8_UNROLL8_EOR3 (1<<12) # define ARMV8_SVE (1<<13) # define ARMV8_SVE2 (1<<14) +# define ARMV8_HAVE_SHA3_AND_WORTH_USING (1<<15) /* * MIDR_EL1 system register @@ -97,13 +100,29 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; */ # define ARM_CPU_IMP_ARM 0x41 +# define HISI_CPU_IMP 0x48 +# define ARM_CPU_IMP_APPLE 0x61 # define ARM_CPU_PART_CORTEX_A72 0xD08 # define ARM_CPU_PART_N1 0xD0C # define ARM_CPU_PART_V1 0xD40 # define ARM_CPU_PART_N2 0xD49 +# define HISI_CPU_PART_KP920 0xD01 # define ARM_CPU_PART_V2 0xD4F +# define APPLE_CPU_PART_M1_ICESTORM 0x022 +# define APPLE_CPU_PART_M1_FIRESTORM 0x023 +# define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024 +# define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 +# define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 +# define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 +# define APPLE_CPU_PART_M2_BLIZZARD 0x032 +# define APPLE_CPU_PART_M2_AVALANCHE 0x033 +# define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034 +# define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035 +# define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 +# define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 + # define MIDR_PARTNUM_SHIFT 4 # define MIDR_PARTNUM_MASK (0xfffU << MIDR_PARTNUM_SHIFT) # define MIDR_PARTNUM(midr) \ diff --git a/crypto/armcap.c b/crypto/armcap.c index 03bc659bdb..3b1447456d 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -300,6 +300,7 @@ void OPENSSL_cpuid_setup(void) ((strncmp(uarch, "Apple M1", 8) == 0) || (strncmp(uarch, "Apple M2", 8) == 0))) { OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; + OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING; } } } @@ -419,6 +420,20 @@ void OPENSSL_cpuid_setup(void) MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) && (OPENSSL_armcap_P & ARMV8_SHA3)) OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; + if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)) && + (OPENSSL_armcap_P & ARMV8_SHA3)) + OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING; # endif } #endif /* _WIN32, __ARM_MAX_ARCH__ >= 7 */ diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 4930d5022e..d394070632 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -82,7 +82,7 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, ASN1_BIT_STRING *ret = NULL; const unsigned char *p; unsigned char *s; - int i; + int i = 0; if (len < 1) { i = ASN1_R_STRING_TOO_SHORT; @@ -110,13 +110,11 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, * We do this to preserve the settings. If we modify the settings, via * the _set_bit function, we will recalculate on output */ - ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ - ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ + ossl_asn1_string_set_bits_left(ret, i); if (len-- > 1) { /* using one because of the bits left byte */ s = OPENSSL_malloc((int)len); if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; goto err; } memcpy(s, p, (int)len); @@ -125,16 +123,15 @@ ASN1_BIT_STRING *ossl_c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, } else s = NULL; - ret->length = (int)len; - OPENSSL_free(ret->data); - ret->data = s; + ASN1_STRING_set0(ret, s, (int)len); ret->type = V_ASN1_BIT_STRING; if (a != NULL) (*a) = ret; *pp = p; return ret; err: - ERR_raise(ERR_LIB_ASN1, i); + if (i != 0) + ERR_raise(ERR_LIB_ASN1, i); if ((a == NULL) || (*a != ret)) ASN1_BIT_STRING_free(ret); return NULL; @@ -166,10 +163,8 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) if (!value) return 1; /* Don't need to set */ c = OPENSSL_clear_realloc(a->data, a->length, w + 1); - if (c == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (c == NULL) return 0; - } if (w + 1 - a->length > 0) memset(c + a->length, 0, w + 1 - a->length); a->data = c; diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c index e8602053f9..4af2276a8d 100644 --- a/crypto/asn1/a_d2i_fp.c +++ b/crypto/asn1/a_d2i_fp.c @@ -123,7 +123,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) b = BUF_MEM_new(); if (b == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return -1; } @@ -134,7 +134,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) want -= diff; if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); goto err; } i = BIO_read(in, &(b->data[len]), want); @@ -206,7 +206,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) size_t chunk = want > chunk_max ? chunk_max : want; if (!BUF_MEM_grow_clean(b, len + chunk)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); goto err; } want -= chunk; diff --git a/crypto/asn1/a_digest.c b/crypto/asn1/a_digest.c index 72cc880779..67e8a96ba1 100644 --- a/crypto/asn1/a_digest.c +++ b/crypto/asn1/a_digest.c @@ -36,10 +36,8 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR); return 0; } - if ((str = OPENSSL_malloc(inl)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((str = OPENSSL_malloc(inl)) == NULL) return 0; - } p = str; i2d(data, &p); diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c index 93e8b2aa8d..23d1d63808 100644 --- a/crypto/asn1/a_dup.c +++ b/crypto/asn1/a_dup.c @@ -28,10 +28,8 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x) return NULL; b = OPENSSL_malloc(i + 10); - if (b == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (b == NULL) return NULL; - } p = b; i = i2d(x, &p); p2 = b; @@ -78,7 +76,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) i = ASN1_item_i2d(x, &b, it); if (b == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return NULL; } p = b; diff --git a/crypto/asn1/a_i2d_fp.c b/crypto/asn1/a_i2d_fp.c index 4cc4773666..e30f1f2a17 100644 --- a/crypto/asn1/a_i2d_fp.c +++ b/crypto/asn1/a_i2d_fp.c @@ -42,10 +42,8 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x) return 0; b = OPENSSL_malloc(n); - if (b == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (b == NULL) return 0; - } p = (unsigned char *)b; i2d(x, &p); @@ -91,7 +89,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x) n = ASN1_item_i2d(x, &b, it); if (b == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return 0; } diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index 19e41ec73e..dc962290dd 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -303,8 +303,10 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, } else ret = *a; - if (ASN1_STRING_set(ret, NULL, r) == 0) + if (ASN1_STRING_set(ret, NULL, r) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; + } c2i_ibuf(ret->data, &neg, *pp, len); @@ -318,7 +320,6 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, (*a) = ret; return ret; err: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); if (a == NULL || *a != ret) ASN1_INTEGER_free(ret); return NULL; @@ -400,7 +401,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, unsigned char *s; long len = 0; int inf, tag, xclass; - int i; + int i = 0; if ((a == NULL) || ((*a) == NULL)) { if ((ret = ASN1_INTEGER_new()) == NULL) @@ -430,10 +431,8 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, * a missing NULL parameter. */ s = OPENSSL_malloc((int)len + 1); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; + if (s == NULL) goto err; - } ret->type = V_ASN1_INTEGER; if (len) { if ((*p == 0) && (len != 1)) { @@ -444,15 +443,14 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, p += len; } - OPENSSL_free(ret->data); - ret->data = s; - ret->length = (int)len; + ASN1_STRING_set0(ret, s, (int)len); if (a != NULL) (*a) = ret; *pp = p; return ret; err: - ERR_raise(ERR_LIB_ASN1, i); + if (i != 0) + ERR_raise(ERR_LIB_ASN1, i); if ((a == NULL) || (*a != ret)) ASN1_INTEGER_free(ret); return NULL; @@ -485,7 +483,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, len = 1; if (ASN1_STRING_set(ret, NULL, len) == 0) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c index 22dea873ee..7d80798655 100644 --- a/crypto/asn1/a_mbstr.c +++ b/crypto/asn1/a_mbstr.c @@ -139,15 +139,13 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, if (*out) { free_out = 0; dest = *out; - OPENSSL_free(dest->data); - dest->data = NULL; - dest->length = 0; + ASN1_STRING_set0(dest, NULL, 0); dest->type = str_type; } else { free_out = 1; dest = ASN1_STRING_type_new(str_type); if (dest == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return -1; } *out = dest; @@ -155,7 +153,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, /* If both the same type just copy across */ if (inform == outform) { if (!ASN1_STRING_set(dest, in, len)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return -1; } return str_type; @@ -187,7 +185,6 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, if ((p = OPENSSL_malloc(outlen + 1)) == NULL) { if (free_out) ASN1_STRING_free(dest); - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } dest->length = outlen; diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index c96c36e730..73c69eacd2 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -31,10 +31,8 @@ int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp) return objsize; if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) return 0; - } } else { p = *pp; } @@ -135,10 +133,8 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) OPENSSL_free(tmp); tmpsize = blsize + 32; tmp = OPENSSL_malloc(tmpsize); - if (tmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (tmp == NULL) goto err; - } } while (blsize--) { BN_ULONG t = BN_div_word(bl, 0x80L); @@ -196,10 +192,8 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) ERR_raise(ERR_LIB_ASN1, ASN1_R_LENGTH_TOO_LONG); return -1; } - if ((p = OPENSSL_malloc(i + 1)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((p = OPENSSL_malloc(i + 1)) == NULL) return -1; - } i2t_ASN1_OBJECT(p, i + 1, a); } if (i <= 0) { @@ -308,10 +302,8 @@ ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, ret->length = 0; OPENSSL_free(data); data = OPENSSL_malloc(length); - if (data == NULL) { - i = ERR_R_MALLOC_FAILURE; + if (data == NULL) goto err; - } ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; } memcpy(data, p, length); @@ -345,10 +337,8 @@ ASN1_OBJECT *ASN1_OBJECT_new(void) ASN1_OBJECT *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; return ret; } diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 302045cfcd..8507fc3668 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -35,7 +35,7 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, X509_ALGOR *a; if (ctx == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } for (i = 0; i < 2; i++) { @@ -82,7 +82,6 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, buf_out = OPENSSL_malloc(outll); if (buf_in == NULL || buf_out == NULL) { outl = 0; - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; @@ -96,16 +95,13 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } - OPENSSL_free(signature->data); - signature->data = buf_out; + ASN1_STRING_set0(signature, buf_out, outl); buf_out = NULL; - signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(signature, 0); err: EVP_MD_CTX_free(ctx); OPENSSL_clear_free((char *)buf_in, inll); @@ -133,7 +129,7 @@ int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1, EVP_MD_CTX *ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq); if (ctx == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return 0; } /* We can use the non _ex variant here since the pkey is already setup */ @@ -247,16 +243,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, goto err; } - if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) - paramtype = V_ASN1_NULL; - else - paramtype = V_ASN1_UNDEF; - - if (algor1) - X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); - if (algor2) - X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); - + paramtype = pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL ? + V_ASN1_NULL : V_ASN1_UNDEF; + if (algor1 != NULL + && !X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL)) + goto err; + if (algor2 != NULL + && !X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL)) + goto err; } buf_len = ASN1_item_i2d(data, &buf_in, it); @@ -275,7 +269,6 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, buf_out = OPENSSL_malloc(outll); if (buf_in == NULL || buf_out == NULL) { outl = 0; - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); goto err; } @@ -284,16 +277,13 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } - OPENSSL_free(signature->data); - signature->data = buf_out; + ASN1_STRING_set0(signature, buf_out, outl); buf_out = NULL; - signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(signature, 0); err: OPENSSL_clear_free((char *)buf_in, inl); OPENSSL_clear_free((char *)buf_out, outll); diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index b31761aae6..29ea60596e 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -282,10 +282,8 @@ static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, der_len = i2d_ASN1_TYPE(&t, NULL); if (der_len <= 0) return -1; - if ((der_buf = OPENSSL_malloc(der_len)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((der_buf = OPENSSL_malloc(der_len)) == NULL) return -1; - } p = der_buf; i2d_ASN1_TYPE(&t, &p); outlen = do_hex_dump(io_ch, arg, der_buf, der_len); diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c index d052935661..99ac2aed11 100644 --- a/crypto/asn1/a_strnid.c +++ b/crypto/asn1/a_strnid.c @@ -50,10 +50,10 @@ int ASN1_STRING_set_default_mask_asc(const char *p) unsigned long mask; char *end; - if (strncmp(p, "MASK:", 5) == 0) { - if (p[5] == '\0') + if (CHECK_AND_SKIP_PREFIX(p, "MASK:")) { + if (*p == '\0') return 0; - mask = strtoul(p + 5, &end, 0); + mask = strtoul(p, &end, 0); if (*end) return 0; } else if (strcmp(p, "nombstr") == 0) @@ -135,7 +135,9 @@ ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) #endif fnd.nid = nid; - if (stable) { + if (stable != NULL) { + /* Ideally, this would be done under lock */ + sk_ASN1_STRING_TABLE_sort(stable); idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); if (idx >= 0) return sk_ASN1_STRING_TABLE_value(stable, idx); @@ -161,10 +163,8 @@ static ASN1_STRING_TABLE *stable_get(int nid) tmp = ASN1_STRING_TABLE_get(nid); if (tmp != NULL && tmp->flags & STABLE_FLAGS_MALLOC) return tmp; - if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((rv = OPENSSL_zalloc(sizeof(*rv))) == NULL) return NULL; - } if (!sk_ASN1_STRING_TABLE_push(stable, rv)) { OPENSSL_free(rv); return NULL; @@ -192,7 +192,7 @@ int ASN1_STRING_TABLE_add(int nid, tmp = stable_get(nid); if (tmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return 0; } if (minsize >= 0) diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 5d63dbbc26..f1702f262e 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -420,10 +420,8 @@ int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str) * new t.data would be freed after ASN1_STRING_copy is done. */ t.data = OPENSSL_zalloc(t.length + 1); - if (t.data == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (t.data == NULL) goto out; - } memcpy(t.data, str + 2, t.length); t.type = V_ASN1_UTCTIME; } @@ -571,7 +569,7 @@ int ASN1_TIME_normalize(ASN1_TIME *t) { struct tm tm; - if (!ASN1_TIME_to_tm(t, &tm)) + if (t == NULL || !ASN1_TIME_to_tm(t, &tm)) return 0; return ossl_asn1_time_from_tm(t, &tm, V_ASN1_UNDEF) != NULL; @@ -589,3 +587,78 @@ int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b) return -1; return 0; } + +/* + * tweak for Windows + */ +#ifdef WIN32 +# define timezone _timezone +#endif + +#if defined(__FreeBSD__) || defined(__wasi__) +# define USE_TIMEGM +#endif + +time_t ossl_asn1_string_to_time_t(const char *asn1_string) +{ + ASN1_TIME *timestamp_asn1 = NULL; + struct tm *timestamp_tm = NULL; +#if defined(__DJGPP__) + char *tz = NULL; +#elif !defined(USE_TIMEGM) + time_t timestamp_local; +#endif + time_t timestamp_utc; + + timestamp_asn1 = ASN1_TIME_new(); + if (!ASN1_TIME_set_string(timestamp_asn1, asn1_string)) + { + ASN1_TIME_free(timestamp_asn1); + return -1; + } + + timestamp_tm = OPENSSL_malloc(sizeof(*timestamp_tm)); + if (timestamp_tm == NULL) { + ASN1_TIME_free(timestamp_asn1); + return -1; + } + if (!(ASN1_TIME_to_tm(timestamp_asn1, timestamp_tm))) { + OPENSSL_free(timestamp_tm); + ASN1_TIME_free(timestamp_asn1); + return -1; + } + ASN1_TIME_free(timestamp_asn1); + +#if defined(__DJGPP__) + /* + * This is NOT thread-safe. Do not use this method for platforms other + * than djgpp. + */ + tz = getenv("TZ"); + if (tz != NULL) { + tz = OPENSSL_strdup(tz); + if (tz == NULL) { + OPENSSL_free(timestamp_tm); + return -1; + } + } + setenv("TZ", "UTC", 1); + + timestamp_utc = mktime(timestamp_tm); + + if (tz != NULL) { + setenv("TZ", tz, 1); + OPENSSL_free(tz); + } else { + unsetenv("TZ"); + } +#elif defined(USE_TIMEGM) + timestamp_utc = timegm(timestamp_tm); +#else + timestamp_local = mktime(timestamp_tm); + timestamp_utc = timestamp_local - timezone; +#endif + OPENSSL_free(timestamp_tm); + + return timestamp_utc; +} diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c index 9bf9bdd14e..94d29e7c27 100644 --- a/crypto/asn1/a_verify.c +++ b/crypto/asn1/a_verify.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,7 +33,7 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, int ret = -1, i, inl; if (ctx == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } i = OBJ_obj2nid(a->algorithm); @@ -54,10 +54,8 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, goto err; } buf_in = OPENSSL_malloc((unsigned int)inl); - if (buf_in == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (buf_in == NULL) goto err; - } p = buf_in; i2d(data, &p); @@ -182,8 +180,9 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, if (mdnid != NID_undef) { type = EVP_get_digestbynid(mdnid); if (type == NULL) { - ERR_raise(ERR_LIB_ASN1, - ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + ERR_raise_data(ERR_LIB_ASN1, + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM, + "nid=0x%x", mdnid); goto err; } } @@ -206,7 +205,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, goto err; } if (buf_in == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } inll = inl; diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index 8b15da3bee..6ba13dd7f2 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -222,10 +222,8 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, { EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth)); - if (ameth == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ameth == NULL) return NULL; - } ameth->pkey_id = id; ameth->pkey_base_id = id; @@ -247,7 +245,6 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, err: EVP_PKEY_asn1_free(ameth); - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c index 402ab34e6a..6f73449cf4 100644 --- a/crypto/asn1/asn1_gen.c +++ b/crypto/asn1/asn1_gen.c @@ -7,9 +7,10 @@ * https://www.openssl.org/source/license.html */ -#include "internal/cryptlib.h" #include #include +#include "internal/cryptlib.h" +#include "crypto/asn1.h" #define ASN1_GEN_FLAG 0x10000 #define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) @@ -324,13 +325,13 @@ static int asn1_cb(const char *elem, int len, void *bitstr) ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); return -1; } - if (strncmp(vstart, "ASCII", 5) == 0) + if (HAS_PREFIX(vstart, "ASCII")) arg->format = ASN1_GEN_FORMAT_ASCII; - else if (strncmp(vstart, "UTF8", 4) == 0) + else if (HAS_PREFIX(vstart, "UTF8")) arg->format = ASN1_GEN_FORMAT_UTF8; - else if (strncmp(vstart, "HEX", 3) == 0) + else if (HAS_PREFIX(vstart, "HEX")) arg->format = ASN1_GEN_FORMAT_HEX; - else if (strncmp(vstart, "BITLIST", 7) == 0) + else if (HAS_PREFIX(vstart, "BITLIST")) arg->format = ASN1_GEN_FORMAT_BITLIST; else { ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); @@ -581,7 +582,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) int no_unused = 1; if ((atmp = ASN1_TYPE_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return NULL; } @@ -642,11 +643,11 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) goto bad_form; } if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } atmp->value.asn1_string->type = utype; @@ -677,7 +678,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, -1, format, ASN1_tag2bit(utype)) <= 0) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } @@ -686,7 +687,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_BIT_STRING: case V_ASN1_OCTET_STRING: if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_form; } @@ -700,7 +701,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) atmp->value.asn1_string->type = utype; } else if (format == ASN1_GEN_FORMAT_ASCII) { if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } } else if ((format == ASN1_GEN_FORMAT_BITLIST) @@ -717,11 +718,8 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 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 ((utype == V_ASN1_BIT_STRING) && no_unused) + ossl_asn1_string_set_bits_left(atmp->value.asn1_string, 0); break; @@ -756,7 +754,7 @@ static int bitstr_cb(const char *elem, int len, void *bitstr) return 0; } if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return 0; } return 1; @@ -768,7 +766,7 @@ static int mask_cb(const char *elem, int len, void *arg) int tag; if (elem == NULL) return 0; - if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) { + if (len == 3 && HAS_PREFIX(elem, "DIR")) { *pmask |= B_ASN1_DIRECTORYSTRING; return 1; } diff --git a/crypto/asn1/asn1_item_list.h b/crypto/asn1/asn1_item_list.h index 1432012b7c..72299a7b6b 100644 --- a/crypto/asn1/asn1_item_list.h +++ b/crypto/asn1/asn1_item_list.h @@ -52,6 +52,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = { ASN1_ITEM_ref(CERTIFICATEPOLICIES), #ifndef OPENSSL_NO_CMS ASN1_ITEM_ref(CMS_ContentInfo), + ASN1_ITEM_ref(CMS_EnvelopedData), ASN1_ITEM_ref(CMS_ReceiptRequest), #endif ASN1_ITEM_ref(CRL_DIST_POINTS), diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 5359cbc117..e3a8480eef 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -248,6 +248,12 @@ int ASN1_object_size(int constructed, int length, int tag) return ret + length; } +void ossl_asn1_string_set_bits_left(ASN1_STRING *str, unsigned int num) +{ + str->flags &= ~0x07; + str->flags |= ASN1_STRING_FLAG_BITS_LEFT | (num & 0x07); +} + int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) { if (str == NULL) @@ -308,7 +314,6 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) str->data = OPENSSL_realloc(c, len + 1); #endif if (str->data == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); str->data = c; return 0; } @@ -348,10 +353,8 @@ ASN1_STRING *ASN1_STRING_type_new(int type) ASN1_STRING *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->type = type; return ret; } diff --git a/crypto/asn1/asn1_local.h b/crypto/asn1/asn1_local.h index f73bd8fc6a..10e9fcb7de 100644 --- a/crypto/asn1/asn1_local.h +++ b/crypto/asn1/asn1_local.h @@ -9,6 +9,8 @@ /* Internal ASN1 structures and functions: not for application use */ +#include "crypto/asn1.h" + typedef const ASN1_VALUE const_ASN1_VALUE; SKM_DEFINE_STACK_OF(const_ASN1_VALUE, const ASN1_VALUE, ASN1_VALUE) diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index 9fc52d0476..3a7386f163 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -76,7 +76,7 @@ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, BIO *bio, *tbio; bio = BIO_new_NDEF(out, val, it); if (!bio) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return 0; } if (!SMIME_crlf_copy(in, bio, flags)) { @@ -109,7 +109,7 @@ static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, int r; b64 = BIO_new(BIO_f_base64()); if (b64 == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB); return 0; } /* @@ -142,7 +142,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x, ASN1_VALUE *val; if ((b64 = BIO_new(BIO_f_base64())) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB); return 0; } bio = BIO_push(b64, bio); @@ -528,7 +528,7 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) */ bf = BIO_new(BIO_f_buffer()); if (bf == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BIO_LIB); return 0; } out = BIO_push(bf, out); @@ -685,7 +685,7 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) char linebuf[MAX_SMLEN]; MIME_HEADER *mhdr = NULL, *new_hdr = NULL; STACK_OF(MIME_HEADER) *headers; - int len, state, save_state = 0; + int i, len, state, save_state = 0; headers = sk_MIME_HEADER_new(mime_hdr_cmp); if (headers == NULL) @@ -791,6 +791,12 @@ static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) break; /* Blank line means end of headers */ } + /* Sort the headers and their params for faster searching */ + sk_MIME_HEADER_sort(headers); + for (i = 0; i < sk_MIME_HEADER_num(headers); i++) + if ((mhdr = sk_MIME_HEADER_value(headers, i)) != NULL + && mhdr->params != NULL) + sk_MIME_PARAM_sort(mhdr->params); return headers; err: @@ -989,13 +995,8 @@ static int mime_bound_check(char *line, int linelen, const char *bound, int blen if (blen + 2 > linelen) return 0; /* Check for part boundary */ - if ((strncmp(line, "--", 2) == 0) - && strncmp(line + 2, bound, blen) == 0) { - if (strncmp(line + blen + 2, "--", 2) == 0) - return 2; - else - return 1; - } + if ((CHECK_AND_SKIP_PREFIX(line, "--")) && strncmp(line, bound, blen) == 0) + return HAS_PREFIX(line + blen, "--") ? 2 : 1; return 0; } diff --git a/crypto/asn1/asn_moid.c b/crypto/asn1/asn_moid.c index 526219c1a7..6f816307af 100644 --- a/crypto/asn1/asn_moid.c +++ b/crypto/asn1/asn_moid.c @@ -83,10 +83,8 @@ static int do_create(const char *value, const char *name) p--; } p++; - if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((lntmp = OPENSSL_malloc((p - ln) + 1)) == NULL) return 0; - } memcpy(lntmp, ln, p - ln); lntmp[p - ln] = '\0'; ln = lntmp; diff --git a/crypto/asn1/asn_mstbl.c b/crypto/asn1/asn_mstbl.c index 3543cd2256..515d8181b6 100644 --- a/crypto/asn1/asn_mstbl.c +++ b/crypto/asn1/asn_mstbl.c @@ -106,7 +106,7 @@ static int do_tcreate(const char *value, const char *name) rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max, tbl_mask, tbl_flags); if (!rv) - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); } sk_CONF_VALUE_pop_free(lst, X509V3_conf_free); return rv; diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c index 2389264f17..54f4ae3a67 100644 --- a/crypto/asn1/asn_pack.c +++ b/crypto/asn1/asn_pack.c @@ -17,24 +17,23 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) { ASN1_STRING *octmp; - if (oct == NULL || *oct == NULL) { + if (oct == NULL || *oct == NULL) { if ((octmp = ASN1_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return NULL; } } else { octmp = *oct; } - OPENSSL_free(octmp->data); - octmp->data = NULL; + ASN1_STRING_set0(octmp, NULL, 0); if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) <= 0) { ERR_raise(ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR); goto err; } if (octmp->data == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } @@ -60,3 +59,16 @@ void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it) ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR); return ret; } + +void *ASN1_item_unpack_ex(const ASN1_STRING *oct, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p; + void *ret; + + p = oct->data; + if ((ret = ASN1_item_d2i_ex(NULL, &p, oct->length, it,\ + libctx, propq)) == NULL) + ERR_raise(ERR_LIB_ASN1, ASN1_R_DECODE_ERROR); + return ret; +} diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c index 0ff2391204..f149942501 100644 --- a/crypto/asn1/bio_asn1.c +++ b/crypto/asn1/bio_asn1.c @@ -100,10 +100,8 @@ static int asn1_bio_new(BIO *b) { BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return 0; - } if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { OPENSSL_free(ctx); return 0; @@ -116,10 +114,12 @@ static int asn1_bio_new(BIO *b) static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) { - if (size <= 0 || (ctx->buf = OPENSSL_malloc(size)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (size <= 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } + if ((ctx->buf = OPENSSL_malloc(size)) == NULL) + return 0; ctx->bufsize = size; ctx->asn1_class = V_ASN1_UNIVERSAL; ctx->asn1_tag = V_ASN1_OCTET_STRING; diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index e5b5319d7f..279609e603 100644 --- a/crypto/asn1/bio_ndef.c +++ b/crypto/asn1/bio_ndef.c @@ -140,10 +140,8 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); if (derlen < 0) return 0; - if ((p = OPENSSL_malloc(derlen)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((p = OPENSSL_malloc(derlen)) == NULL) return 0; - } ndef_aux->derbuf = p; *pbuf = p; @@ -215,10 +213,8 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); if (derlen < 0) return 0; - if ((p = OPENSSL_malloc(derlen)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((p = OPENSSL_malloc(derlen)) == NULL) return 0; - } ndef_aux->derbuf = p; *pbuf = p; diff --git a/crypto/asn1/f_int.c b/crypto/asn1/f_int.c index d41e0069af..20192b577b 100644 --- a/crypto/asn1/f_int.c +++ b/crypto/asn1/f_int.c @@ -108,7 +108,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) if (num + i > slen) { sp = OPENSSL_clear_realloc(s, slen, num + i * 2); if (sp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } diff --git a/crypto/asn1/f_string.c b/crypto/asn1/f_string.c index 4b65110d98..1da442a457 100644 --- a/crypto/asn1/f_string.c +++ b/crypto/asn1/f_string.c @@ -99,7 +99,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) if (num + i > slen) { sp = OPENSSL_realloc(s, (unsigned int)num + i * 2); if (sp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } diff --git a/crypto/asn1/i2d_evp.c b/crypto/asn1/i2d_evp.c index 0d66411be8..106ea15273 100644 --- a/crypto/asn1/i2d_evp.c +++ b/crypto/asn1/i2d_evp.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,6 @@ static int i2d_provided(const EVP_PKEY *a, int selection, const struct type_and_structure_st *output_info, unsigned char **pp) { - OSSL_ENCODER_CTX *ctx = NULL; int ret; for (ret = -1; @@ -49,6 +48,7 @@ static int i2d_provided(const EVP_PKEY *a, int selection, */ size_t len = INT_MAX; int pp_was_NULL = (pp == NULL || *pp == NULL); + OSSL_ENCODER_CTX *ctx; ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, output_info->output_type, @@ -63,7 +63,6 @@ static int i2d_provided(const EVP_PKEY *a, int selection, ret = INT_MAX - (int)len; } OSSL_ENCODER_CTX_free(ctx); - ctx = NULL; } if (ret == -1) diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c index 9bc8aaa7a3..a90c200d42 100644 --- a/crypto/asn1/p5_pbe.c +++ b/crypto/asn1/p5_pbe.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ #include #include #include +#include "crypto/evp.h" /* PKCS#5 password based encryption structure */ @@ -34,25 +35,24 @@ int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter, pbe = PBEPARAM_new(); if (pbe == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + /* ERR_R_ASN1_LIB, because PBEPARAM_new() is defined in crypto/asn1 */ + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } if (!saltlen) - saltlen = PKCS5_SALT_LEN; + saltlen = PKCS5_DEFAULT_PBE1_SALT_LEN; if (saltlen < 0) goto err; sstr = OPENSSL_malloc(saltlen); - if (sstr == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (sstr == NULL) goto err; - } if (salt) memcpy(sstr, salt, saltlen); else if (RAND_bytes_ex(ctx, sstr, saltlen, 0) <= 0) @@ -62,7 +62,7 @@ int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter, sstr = NULL; if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } @@ -94,7 +94,7 @@ X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter, X509_ALGOR *ret; ret = X509_ALGOR_new(); if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); return NULL; } diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c index 711743a77b..8575d05bf6 100644 --- a/crypto/asn1/p5_pbev2.c +++ b/crypto/asn1/p5_pbev2.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,6 +9,8 @@ #include #include "internal/cryptlib.h" +#include "crypto/asn1.h" +#include "crypto/evp.h" #include #include #include @@ -56,14 +58,18 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter, goto err; } - if ((pbe2 = PBE2PARAM_new()) == NULL) - goto merr; + if ((pbe2 = PBE2PARAM_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = OBJ_nid2obj(alg_nid); - if ((scheme->parameter = ASN1_TYPE_new()) == NULL) - goto merr; + if ((scheme->parameter = ASN1_TYPE_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Create random IV */ ivlen = EVP_CIPHER_get_iv_length(cipher); @@ -75,8 +81,10 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter, } ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) - goto merr; + if (ctx == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); + goto err; + } /* Dummy cipherinit to just setup the IV, and PRF */ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0)) @@ -112,30 +120,33 @@ X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter, pbe2->keyfunc = PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, libctx); - if (pbe2->keyfunc == NULL) - goto merr; + if (pbe2->keyfunc == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Now set up top level AlgorithmIdentifier */ - if ((ret = X509_ALGOR_new()) == NULL) - goto merr; + if ((ret = X509_ALGOR_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); + goto err; + } ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, - &ret->parameter)) - goto merr; + &ret->parameter)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; - merr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); - err: EVP_CIPHER_CTX_free(ctx); PBE2PARAM_free(pbe2); @@ -169,70 +180,89 @@ X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen, PBKDF2PARAM *kdf = NULL; ASN1_OCTET_STRING *osalt = NULL; - if ((kdf = PBKDF2PARAM_new()) == NULL) - goto merr; - if ((osalt = ASN1_OCTET_STRING_new()) == NULL) - goto merr; + if ((kdf = PBKDF2PARAM_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } + if ((osalt = ASN1_OCTET_STRING_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; - if (saltlen < 0) - goto merr; + if (saltlen < 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } if (saltlen == 0) - saltlen = PKCS5_SALT_LEN; + saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN; if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL) - goto merr; + goto err; + osalt->length = saltlen; - if (salt) + if (salt) { memcpy(osalt->data, salt, saltlen); - else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0) - goto merr; + } else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_RAND_LIB); + goto err; + } if (iter <= 0) iter = PKCS5_DEFAULT_ITER; - if (!ASN1_INTEGER_set(kdf->iter, iter)) - goto merr; + if (!ASN1_INTEGER_set(kdf->iter, iter)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* If have a key len set it up */ if (keylen > 0) { - if ((kdf->keylength = ASN1_INTEGER_new()) == NULL) - goto merr; - if (!ASN1_INTEGER_set(kdf->keylength, keylen)) - goto merr; + if ((kdf->keylength = ASN1_INTEGER_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } + if (!ASN1_INTEGER_set(kdf->keylength, keylen)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } } /* prf can stay NULL if we are using hmacWithSHA1 */ if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { - kdf->prf = X509_ALGOR_new(); - if (kdf->prf == NULL) - goto merr; - X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); + kdf->prf = ossl_X509_ALGOR_from_nid(prf_nid, V_ASN1_NULL, NULL); + if (kdf->prf == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); + goto err; + } } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); - if (keyfunc == NULL) - goto merr; + if (keyfunc == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); + goto err; + } keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); /* Encode PBKDF2PARAM into parameter of pbe2 */ if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf, - &keyfunc->parameter)) - goto merr; + &keyfunc->parameter)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } PBKDF2PARAM_free(kdf); return keyfunc; - merr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + err: PBKDF2PARAM_free(kdf); X509_ALGOR_free(keyfunc); return NULL; diff --git a/crypto/asn1/p5_scrypt.c b/crypto/asn1/p5_scrypt.c index a02190d0dc..4f3dcecd41 100644 --- a/crypto/asn1/p5_scrypt.c +++ b/crypto/asn1/p5_scrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -67,16 +67,20 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, } pbe2 = PBE2PARAM_new(); - if (pbe2 == NULL) - goto merr; + if (pbe2 == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = OBJ_nid2obj(alg_nid); scheme->parameter = ASN1_TYPE_new(); - if (scheme->parameter == NULL) - goto merr; + if (scheme->parameter == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Create random IV */ if (EVP_CIPHER_get_iv_length(cipher)) { @@ -87,8 +91,10 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, } ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) - goto merr; + if (ctx == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); + goto err; + } /* Dummy cipherinit to just setup the IV */ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0) @@ -111,31 +117,34 @@ X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); - if (pbe2->keyfunc == NULL) - goto merr; + if (pbe2->keyfunc == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* Now set up top level AlgorithmIdentifier */ ret = X509_ALGOR_new(); - if (ret == NULL) - goto merr; + if (ret == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, - &ret->parameter) == NULL) - goto merr; + &ret->parameter) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; - merr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); - err: PBE2PARAM_free(pbe2); X509_ALGOR_free(ret); @@ -151,57 +160,73 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, X509_ALGOR *keyfunc = NULL; SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new(); - if (sparam == NULL) - goto merr; + if (sparam == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } if (!saltlen) - saltlen = PKCS5_SALT_LEN; + saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN; /* This will either copy salt or grow the buffer */ - if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) - goto merr; + if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0) goto err; - if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) - goto merr; + if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } - if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) - goto merr; + if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } - if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) - goto merr; + if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } /* If have a key len set it up */ if (keylen > 0) { sparam->keyLength = ASN1_INTEGER_new(); - if (sparam->keyLength == NULL) - goto merr; - if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) - goto merr; + if (sparam->keyLength == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } + if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); - if (keyfunc == NULL) - goto merr; + if (keyfunc == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); /* Encode SCRYPT_PARAMS into parameter of pbe2 */ if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam, - &keyfunc->parameter) == NULL) - goto merr; + &keyfunc->parameter) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } SCRYPT_PARAMS_free(sparam); return keyfunc; - merr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); err: SCRYPT_PARAMS_free(sparam); X509_ALGOR_free(keyfunc); diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h index 0b0c7ef686..6b73d9a771 100644 --- a/crypto/asn1/standard_methods.h +++ b/crypto/asn1/standard_methods.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,11 +32,9 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { #ifndef OPENSSL_NO_DH &ossl_dhx_asn1_meth, #endif -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECX &ossl_ecx25519_asn1_meth, &ossl_ecx448_asn1_meth, -#endif -#ifndef OPENSSL_NO_EC &ossl_ed25519_asn1_meth, &ossl_ed448_asn1_meth, #endif diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 11198087a5..5c65d542c5 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -629,7 +629,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } if (*val == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); goto err; } @@ -658,7 +658,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } len -= p - q; if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item)); goto err; } @@ -802,7 +802,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, len = buf.length; /* Append a final null to string */ if (!BUF_MEM_grow_clean(&buf, len + 1)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); goto err; } buf.data[len] = 0; @@ -925,7 +925,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, if (*pval == NULL) { stmp = ASN1_STRING_type_new(utype); if (stmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } *pval = (ASN1_VALUE *)stmp; @@ -935,13 +935,11 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } /* If we've already allocated a buffer use it */ if (*free_cont) { - OPENSSL_free(stmp->data); - stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ - stmp->length = len; + ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, len); *free_cont = 0; } else { if (!ASN1_STRING_set(stmp, cont, len)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); ASN1_STRING_free(stmp); *pval = NULL; goto err; @@ -1100,7 +1098,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) if (buf) { len = buf->length; if (!BUF_MEM_grow_clean(buf, len + plen)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); return 0; } memcpy(buf->data + len, *p, plen); diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index 3ea18b0280..dab5f9f278 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c @@ -62,10 +62,8 @@ static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out, len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); if (len <= 0) return len; - if ((buf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(len)) == NULL) return -1; - } p = buf; ASN1_item_ex_i2d(&val, &p, it, -1, flags); *out = buf; @@ -415,15 +413,11 @@ static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk, else { derlst = OPENSSL_malloc(sk_const_ASN1_VALUE_num(sk) * sizeof(*derlst)); - if (derlst == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (derlst == NULL) return 0; - } tmpdat = OPENSSL_malloc(skcontlen); - if (tmpdat == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (tmpdat == NULL) goto err; - } } } /* If not sorting just output each item */ diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index 4b624bbdd4..00a5397a5e 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -78,10 +78,10 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, if (ef != NULL) { if (ef->asn1_ex_new_ex != NULL) { if (!ef->asn1_ex_new_ex(pval, it, libctx, propq)) - goto memerr; + goto asn1err; } else if (ef->asn1_ex_new != NULL) { if (!ef->asn1_ex_new(pval, it)) - goto memerr; + goto asn1err; } } break; @@ -89,14 +89,14 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, case ASN1_ITYPE_PRIMITIVE: if (it->templates) { if (!asn1_template_new(pval, it->templates, libctx, propq)) - goto memerr; + goto asn1err; } else if (!asn1_primitive_new(pval, it, embed)) - goto memerr; + goto asn1err; break; case ASN1_ITYPE_MSTRING: if (!asn1_primitive_new(pval, it, embed)) - goto memerr; + goto asn1err; break; case ASN1_ITYPE_CHOICE: @@ -113,7 +113,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, } else { *pval = OPENSSL_zalloc(it->size); if (*pval == NULL) - goto memerr; + return 0; } ossl_asn1_set_choice_selector(pval, -1, it); if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) @@ -135,7 +135,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, } else { *pval = OPENSSL_zalloc(it->size); if (*pval == NULL) - goto memerr; + return 0; } /* 0 : init. lock */ if (ossl_asn1_do_lock(pval, 0, it) < 0) { @@ -143,13 +143,13 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, OPENSSL_free(*pval); *pval = NULL; } - goto memerr; + goto asn1err; } ossl_asn1_enc_init(pval, it); for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { pseqval = ossl_asn1_get_field_ptr(pval, tt); if (!asn1_template_new(pseqval, tt, libctx, propq)) - goto memerr2; + goto asn1err2; } if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) goto auxerr2; @@ -157,10 +157,10 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, } return 1; - memerr2: + asn1err2: ossl_asn1_item_embed_free(pval, it, embed); - memerr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + asn1err: + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return 0; auxerr2: @@ -230,7 +230,7 @@ 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) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); ret = 0; goto done; } @@ -298,10 +298,8 @@ static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; case V_ASN1_ANY: - if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) return 0; - } typ->value.ptr = NULL; typ->type = -1; *pval = (ASN1_VALUE *)typ; diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c index 7d8618e26c..73eadc5fd4 100644 --- a/crypto/asn1/tasn_prn.c +++ b/crypto/asn1/tasn_prn.c @@ -37,10 +37,8 @@ ASN1_PCTX *ASN1_PCTX_new(void) ASN1_PCTX *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } return ret; } diff --git a/crypto/asn1/tasn_scn.c b/crypto/asn1/tasn_scn.c index bde697ee99..7ada313b94 100644 --- a/crypto/asn1/tasn_scn.c +++ b/crypto/asn1/tasn_scn.c @@ -26,10 +26,8 @@ ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)) { ASN1_SCTX *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->scan_cb = scan_cb; return ret; } diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c index e5f25d88df..67a9ccde62 100644 --- a/crypto/asn1/tasn_utl.c +++ b/crypto/asn1/tasn_utl.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -59,7 +59,7 @@ int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value, /* * Do atomic reference counting. The value 'op' decides what to do. * If it is +1 then the count is incremented. - * If |op| is 0, lock is initialised and count is set to 1. + * If |op| is 0, count is initialised and set to 1. * If |op| is -1, count is decremented and the return value is the current * reference count or 0 if no reference count is active. * It returns -1 on initialisation error. @@ -68,8 +68,8 @@ int ossl_asn1_set_choice_selector(ASN1_VALUE **pval, int value, int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) { const ASN1_AUX *aux; - CRYPTO_REF_COUNT *lck; CRYPTO_RWLOCK **lock; + CRYPTO_REF_COUNT *refcnt; int ret = -1; if ((it->itype != ASN1_ITYPE_SEQUENCE) @@ -78,30 +78,34 @@ int ossl_asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) aux = it->funcs; if (aux == NULL || (aux->flags & ASN1_AFLG_REFCOUNT) == 0) return 0; - lck = offset2ptr(*pval, aux->ref_offset); lock = offset2ptr(*pval, aux->ref_lock); + refcnt = offset2ptr(*pval, aux->ref_offset); switch (op) { case 0: - *lck = ret = 1; + if (!CRYPTO_NEW_REF(refcnt, 1)) + return -1; *lock = CRYPTO_THREAD_lock_new(); if (*lock == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + CRYPTO_FREE_REF(refcnt); + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); return -1; } + ret = 1; break; case 1: - if (!CRYPTO_UP_REF(lck, &ret, *lock)) + if (!CRYPTO_UP_REF(refcnt, &ret)) return -1; break; case -1: - if (!CRYPTO_DOWN_REF(lck, &ret, *lock)) + if (!CRYPTO_DOWN_REF(refcnt, &ret)) return -1; /* failed */ REF_PRINT_EX(it->sname, ret, (void *)it); REF_ASSERT_ISNT(ret < 0); if (ret == 0) { CRYPTO_THREAD_lock_free(*lock); *lock = NULL; + CRYPTO_FREE_REF(refcnt); } break; } @@ -168,10 +172,8 @@ int ossl_asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, OPENSSL_free(enc->enc); if (inlen <= 0) return 0; - if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) return 0; - } memcpy(enc->enc, in, inlen); enc->len = inlen; enc->modified = 0; diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c index c0a5f76803..db9dd06e49 100644 --- a/crypto/asn1/x_algor.c +++ b/crypto/asn1/x_algor.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,17 +33,14 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) if (alg == NULL) return 0; - if (ptype != V_ASN1_UNDEF) { - if (alg->parameter == NULL) - alg->parameter = ASN1_TYPE_new(); - if (alg->parameter == NULL) - return 0; - } + if (ptype != V_ASN1_UNDEF && alg->parameter == NULL + && (alg->parameter = ASN1_TYPE_new()) == NULL) + return 0; ASN1_OBJECT_free(alg->algorithm); alg->algorithm = aobj; - if (ptype == 0) + if (ptype == V_ASN1_EOC) return 1; if (ptype == V_ASN1_UNDEF) { ASN1_TYPE_free(alg->parameter); @@ -53,6 +50,25 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) return 1; } +X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval) +{ + ASN1_OBJECT *algo = OBJ_nid2obj(nid); + X509_ALGOR *alg = NULL; + + if (algo == NULL) + return NULL; + if ((alg = X509_ALGOR_new()) == NULL) + goto err; + if (X509_ALGOR_set0(alg, algo, ptype, pval)) + return alg; + alg->algorithm = NULL; /* precaution to prevent double free */ + + err: + X509_ALGOR_free(alg); + /* ASN1_OBJECT_free(algo) is not needed due to OBJ_nid2obj() */ + return NULL; +} + void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, const X509_ALGOR *algor) { @@ -70,18 +86,12 @@ void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, } /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ - void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) { - int param_type; - - if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) - param_type = V_ASN1_UNDEF; - else - param_type = V_ASN1_NULL; - - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), param_type, NULL); + int type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF + : V_ASN1_NULL; + (void)X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), type, NULL); } int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) @@ -131,13 +141,15 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) /* allocate and set algorithm ID from EVP_MD, default SHA1 */ int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md) { + X509_ALGOR *alg; + /* Default is SHA1 so no need to create it - still success */ if (md == NULL || EVP_MD_is_a(md, "SHA1")) return 1; - *palg = X509_ALGOR_new(); - if (*palg == NULL) + if ((alg = X509_ALGOR_new()) == NULL) return 0; - X509_ALGOR_set_md(*palg, md); + X509_ALGOR_set_md(alg, md); + *palg = alg; return 1; } @@ -176,15 +188,12 @@ int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) goto err; if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) goto err; - *palg = X509_ALGOR_new(); + *palg = ossl_X509_ALGOR_from_nid(NID_mgf1, V_ASN1_SEQUENCE, stmp); if (*palg == NULL) goto err; - X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); stmp = NULL; err: ASN1_STRING_free(stmp); X509_ALGOR_free(algtmp); - if (*palg != NULL) - return 1; - return 0; + return *palg != NULL; } diff --git a/crypto/asn1/x_info.c b/crypto/asn1/x_info.c index f8bc478988..8a4d2dba0a 100644 --- a/crypto/asn1/x_info.c +++ b/crypto/asn1/x_info.c @@ -18,10 +18,8 @@ X509_INFO *X509_INFO_new(void) X509_INFO *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } return ret; } diff --git a/crypto/asn1/x_int64.c b/crypto/asn1/x_int64.c index 0cf8c76cde..b7251b8ad8 100644 --- a/crypto/asn1/x_int64.c +++ b/crypto/asn1/x_int64.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,10 +28,8 @@ static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { - if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) return 0; - } return 1; } @@ -123,10 +121,8 @@ static int uint64_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it) { - if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) return 0; - } return 1; } diff --git a/crypto/asn1/x_pkey.c b/crypto/asn1/x_pkey.c index b63c7c6489..34b7286d7e 100644 --- a/crypto/asn1/x_pkey.c +++ b/crypto/asn1/x_pkey.c @@ -19,18 +19,17 @@ X509_PKEY *X509_PKEY_new(void) ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) - goto err; + return NULL; ret->enc_algor = X509_ALGOR_new(); ret->enc_pkey = ASN1_OCTET_STRING_new(); - if (ret->enc_algor == NULL || ret->enc_pkey == NULL) - goto err; + if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { + X509_PKEY_free(ret); + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + return NULL; + } return ret; -err: - X509_PKEY_free(ret); - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); - return NULL; } void X509_PKEY_free(X509_PKEY *x) diff --git a/crypto/async/arch/async_null.c b/crypto/async/arch/async_null.c index 675c1d35bf..306c43df41 100644 --- a/crypto/async/arch/async_null.c +++ b/crypto/async/arch/async_null.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,6 +16,21 @@ int ASYNC_is_capable(void) return 0; } +int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn, + ASYNC_stack_free_fn free_fn) +{ + return 0; +} + +void ASYNC_get_mem_functions(ASYNC_stack_alloc_fn *alloc_fn, + ASYNC_stack_free_fn *free_fn) +{ + if (alloc_fn != NULL) + *alloc_fn = NULL; + if (free_fn != NULL) + *free_fn = NULL; +} + void async_local_cleanup(void) { } diff --git a/crypto/async/arch/async_null.h b/crypto/async/arch/async_null.h index c62aba69a8..536c9829cd 100644 --- a/crypto/async/arch/async_null.h +++ b/crypto/async/arch/async_null.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,5 +26,7 @@ typedef struct async_fibre_st { # define async_fibre_makecontext(c) 0 # define async_fibre_free(f) # define async_fibre_init_dispatcher(f) +# define async_local_init() 1 +# define async_local_deinit() #endif diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index e107e09a35..f2b507c7d0 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,9 +14,31 @@ # include # include +# include +# include #define STACKSIZE 32768 +static CRYPTO_RWLOCK *async_mem_lock; + +static void *async_stack_alloc(size_t *num); +static void async_stack_free(void *addr); + +int async_local_init(void) +{ + async_mem_lock = CRYPTO_THREAD_lock_new(); + return async_mem_lock != NULL; +} + +void async_local_deinit(void) +{ + CRYPTO_THREAD_lock_free(async_mem_lock); +} + +static int allow_customize = 1; +static ASYNC_stack_alloc_fn stack_alloc_impl = async_stack_alloc; +static ASYNC_stack_free_fn stack_free_impl = async_stack_free; + int ASYNC_is_capable(void) { ucontext_t ctx; @@ -28,6 +50,45 @@ int ASYNC_is_capable(void) return getcontext(&ctx) == 0; } +int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn, + ASYNC_stack_free_fn free_fn) +{ + OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL); + + if (!CRYPTO_THREAD_write_lock(async_mem_lock)) + return 0; + if (!allow_customize) { + CRYPTO_THREAD_unlock(async_mem_lock); + return 0; + } + CRYPTO_THREAD_unlock(async_mem_lock); + + if (alloc_fn != NULL) + stack_alloc_impl = alloc_fn; + if (free_fn != NULL) + stack_free_impl = free_fn; + return 1; +} + +void ASYNC_get_mem_functions(ASYNC_stack_alloc_fn *alloc_fn, + ASYNC_stack_free_fn *free_fn) +{ + if (alloc_fn != NULL) + *alloc_fn = stack_alloc_impl; + if (free_fn != NULL) + *free_fn = stack_free_impl; +} + +static void *async_stack_alloc(size_t *num) +{ + return OPENSSL_malloc(*num); +} + +static void async_stack_free(void *addr) +{ + OPENSSL_free(addr); +} + void async_local_cleanup(void) { } @@ -38,9 +99,22 @@ int async_fibre_makecontext(async_fibre *fibre) fibre->env_init = 0; #endif if (getcontext(&fibre->fibre) == 0) { - fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE); + size_t num = STACKSIZE; + + /* + * Disallow customisation after the first + * stack is allocated. + */ + if (allow_customize) { + if (!CRYPTO_THREAD_write_lock(async_mem_lock)) + return 0; + allow_customize = 0; + CRYPTO_THREAD_unlock(async_mem_lock); + } + + fibre->fibre.uc_stack.ss_sp = stack_alloc_impl(&num); if (fibre->fibre.uc_stack.ss_sp != NULL) { - fibre->fibre.uc_stack.ss_size = STACKSIZE; + fibre->fibre.uc_stack.ss_size = num; fibre->fibre.uc_link = NULL; makecontext(&fibre->fibre, async_start_func, 0); return 1; @@ -53,7 +127,7 @@ int async_fibre_makecontext(async_fibre *fibre) void async_fibre_free(async_fibre *fibre) { - OPENSSL_free(fibre->fibre.uc_stack.ss_sp); + stack_free_impl(fibre->fibre.uc_stack.ss_sp); fibre->fibre.uc_stack.ss_sp = NULL; } diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h index a17c6b8e68..603965310d 100644 --- a/crypto/async/arch/async_posix.h +++ b/crypto/async/arch/async_posix.h @@ -61,6 +61,9 @@ typedef struct async_fibre_st { # endif } async_fibre; +int async_local_init(void); +void async_local_deinit(void); + static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) { # ifdef USE_SWAPCONTEXT diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c index 0b276fd504..cbb8ef24ed 100644 --- a/crypto/async/arch/async_win.c +++ b/crypto/async/arch/async_win.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,21 @@ int ASYNC_is_capable(void) return 1; } +int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn, + ASYNC_stack_free_fn free_fn) +{ + return 0; +} + +void ASYNC_get_mem_functions(ASYNC_stack_alloc_fn *alloc_fn, + ASYNC_stack_free_fn *free_fn) +{ + if (alloc_fn != NULL) + *alloc_fn = NULL; + if (free_fn != NULL) + *free_fn = NULL; +} + void async_local_cleanup(void) { async_ctx *ctx = async_get_ctx(); diff --git a/crypto/async/arch/async_win.h b/crypto/async/arch/async_win.h index 0fab95996e..6a61a9a380 100644 --- a/crypto/async/arch/async_win.h +++ b/crypto/async/arch/async_win.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -37,6 +37,8 @@ typedef struct async_fibre_st { # endif # define async_fibre_free(f) (DeleteFiber((f)->fibre)) +# define async_local_init() 1 +# define async_local_deinit() int async_fibre_init_dispatcher(async_fibre *fibre); VOID CALLBACK async_start_func_win(PVOID unused); diff --git a/crypto/async/async.c b/crypto/async/async.c index a320d455b7..46c87d6a5a 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,10 +40,8 @@ static async_ctx *async_ctx_new(void) return NULL; nctx = OPENSSL_malloc(sizeof(*nctx)); - if (nctx == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); + if (nctx == NULL) goto err; - } async_fibre_init_dispatcher(&nctx->dispatcher); nctx->currjob = NULL; @@ -82,10 +80,8 @@ static ASYNC_JOB *async_job_new(void) ASYNC_JOB *job = NULL; job = OPENSSL_zalloc(sizeof(*job)); - if (job == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); + if (job == NULL) return NULL; - } job->status = ASYNC_JOB_RUNNING; @@ -256,7 +252,6 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, if (args != NULL) { ctx->currjob->funcargs = OPENSSL_malloc(size); if (ctx->currjob->funcargs == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); async_release_job(ctx->currjob); ctx->currjob = NULL; return ASYNC_ERR; @@ -340,13 +335,14 @@ int async_init(void) return 0; } - return 1; + return async_local_init(); } void async_deinit(void) { CRYPTO_THREAD_cleanup_local(&ctxkey); CRYPTO_THREAD_cleanup_local(&poolkey); + async_local_deinit(); } int ASYNC_init_thread(size_t max_size, size_t init_size) @@ -366,14 +362,12 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) return 0; pool = OPENSSL_zalloc(sizeof(*pool)); - if (pool == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); + if (pool == NULL) return 0; - } pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); if (pool->jobs == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASYNC, ERR_R_CRYPTO_LIB); OPENSSL_free(pool); return 0; } diff --git a/crypto/async/async_wait.c b/crypto/async/async_wait.c index df7d293021..c5d000a03b 100644 --- a/crypto/async/async_wait.c +++ b/crypto/async/async_wait.c @@ -47,10 +47,8 @@ int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, { struct fd_lookup_st *fdlookup; - if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) { - ERR_raise(ERR_LIB_ASYNC, ERR_R_MALLOC_FAILURE); + if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) return 0; - } fdlookup->key = key; fdlookup->fd = fd; diff --git a/crypto/bf/bf_local.h b/crypto/bf/bf_local.h index a7ea4acc0d..53c6963e6b 100644 --- a/crypto/bf/bf_local.h +++ b/crypto/bf/bf_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c index e9f03ed451..737910cc75 100644 --- a/crypto/bio/bf_buff.c +++ b/crypto/bio/bf_buff.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -291,7 +291,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) return 0; p1 = OPENSSL_malloc((size_t)num); if (p1 == NULL) - goto malloc_error; + return 0; OPENSSL_free(ctx->ibuf); ctx->ibuf = p1; } @@ -322,14 +322,14 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) return 0; p1 = OPENSSL_malloc((size_t)num); if (p1 == NULL) - goto malloc_error; + return 0; } if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { p2 = OPENSSL_malloc((size_t)num); if (p2 == NULL) { if (p1 != ctx->ibuf) OPENSSL_free(p1); - goto malloc_error; + return 0; } } if (ctx->ibuf != p1) { @@ -360,6 +360,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) return 0; if (ctx->obuf_len <= 0) { ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); break; } @@ -380,6 +381,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) } } ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; @@ -405,9 +407,6 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) break; } return ret; - malloc_error: - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); - return 0; } static long buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c index 30220b0a08..eed3dc4633 100644 --- a/crypto/bio/bf_lbuf.c +++ b/crypto/bio/bf_lbuf.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -57,13 +57,10 @@ static int linebuffer_new(BIO *bi) { BIO_LINEBUFFER_CTX *ctx; - if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) return 0; - } ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); if (ctx->obuf == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); OPENSSL_free(ctx); return 0; } @@ -237,7 +234,7 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { p = OPENSSL_malloc((size_t)obs); if (p == NULL) - goto malloc_error; + return 0; } if (ctx->obuf != p) { if (ctx->obuf_len > obs) { @@ -262,6 +259,7 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) return 0; if (ctx->obuf_len <= 0) { ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); break; } @@ -281,6 +279,7 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) } } ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; @@ -294,9 +293,6 @@ static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) break; } return ret; - malloc_error: - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); - return 0; } static long linebuffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) diff --git a/crypto/bio/bf_nbio.c b/crypto/bio/bf_nbio.c index f9ea1730ba..01138729b0 100644 --- a/crypto/bio/bf_nbio.c +++ b/crypto/bio/bf_nbio.c @@ -55,10 +55,8 @@ static int nbiof_new(BIO *bi) { NBIO_TEST *nt; - if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL) return 0; - } nt->lrn = -1; nt->lwn = -1; bi->ptr = (char *)nt; diff --git a/crypto/bio/bio_addr.c b/crypto/bio/bio_addr.c index 20c2895b50..0a64d0749a 100644 --- a/crypto/bio/bio_addr.c +++ b/crypto/bio/bio_addr.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -53,10 +53,8 @@ BIO_ADDR *BIO_ADDR_new(void) { BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->sa.sa_family = AF_UNSPEC; return ret; @@ -67,6 +65,33 @@ void BIO_ADDR_free(BIO_ADDR *ap) OPENSSL_free(ap); } +int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src) +{ + if (dst == NULL || src == NULL) + return 0; + + if (src->sa.sa_family == AF_UNSPEC) { + BIO_ADDR_clear(dst); + return 1; + } + + return BIO_ADDR_make(dst, &src->sa); +} + +BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap) +{ + BIO_ADDR *ret = NULL; + + if (ap != NULL) { + ret = BIO_ADDR_new(); + if (ret != NULL && !BIO_ADDR_copy(ret, ap)) { + BIO_ADDR_free(ret); + ret = NULL; + } + } + return ret; +} + void BIO_ADDR_clear(BIO_ADDR *ap) { memset(ap, 0, sizeof(*ap)); @@ -267,7 +292,6 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, OPENSSL_free(*service); *service = NULL; } - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } @@ -538,7 +562,7 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service, } else { *host = OPENSSL_strndup(h, hl); if (*host == NULL) - goto memerr; + return 0; } } if (p != NULL && service != NULL) { @@ -548,7 +572,7 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service, } else { *service = OPENSSL_strndup(p, pl); if (*service == NULL) - goto memerr; + return 0; } } @@ -559,9 +583,6 @@ int BIO_parse_hostserv(const char *hostserv, char **host, char **service, spec_err: ERR_raise(ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE); return 0; - memerr: - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); - return 0; } /* addrinfo_wrap is used to build our own addrinfo "chain". @@ -578,10 +599,8 @@ static int addrinfo_wrap(int family, int socktype, unsigned short port, BIO_ADDRINFO **bai) { - if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((*bai = OPENSSL_zalloc(sizeof(**bai))) == NULL) return 0; - } (*bai)->bai_family = family; (*bai)->bai_socktype = socktype; @@ -654,7 +673,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, { int ret = 0; /* Assume failure */ - switch(family) { + switch (family) { case AF_INET: #if OPENSSL_USE_IPV6 case AF_INET6: @@ -676,7 +695,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res)) return 1; else - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); return 0; } #endif @@ -720,7 +739,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, # endif # ifdef EAI_MEMORY case EAI_MEMORY: - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise_data(ERR_LIB_BIO, ERR_R_SYS_LIB, + gai_strerror(old_ret ? old_ret : gai_ret)); break; # endif case 0: @@ -777,7 +797,8 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, #endif if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + /* Should this be raised inside do_bio_lookup_init()? */ + ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB); ret = 0; goto err; } @@ -789,7 +810,7 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, he_fallback_address = INADDR_ANY; if (host == NULL) { he = &he_fallback; - switch(lookup_type) { + switch (lookup_type) { case BIO_LOOKUP_CLIENT: he_fallback_address = INADDR_LOOPBACK; break; @@ -906,23 +927,23 @@ int BIO_lookup_ex(const char *host, const char *service, int lookup_type, /* The easiest way to create a linked list from an array is to start from the back */ - for(addrlistp = he->h_addr_list; *addrlistp != NULL; - addrlistp++) + for (addrlistp = he->h_addr_list; *addrlistp != NULL; + addrlistp++) ; - for(addresses = addrlistp - he->h_addr_list; - addrlistp--, addresses-- > 0; ) { + for (addresses = addrlistp - he->h_addr_list; + addrlistp--, addresses-- > 0; ) { if (!addrinfo_wrap(he->h_addrtype, socktype, *addrlistp, he->h_length, se->s_port, &tmp_bai)) - goto addrinfo_malloc_err; + goto addrinfo_wrap_err; tmp_bai->bai_next = *res; *res = tmp_bai; continue; - addrinfo_malloc_err: + addrinfo_wrap_err: BIO_ADDRINFO_free(*res); *res = NULL; - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); ret = 0; goto err; } diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c index 522a05369d..8e4f79ea3c 100644 --- a/crypto/bio/bio_cb.c +++ b/crypto/bio/bio_cb.c @@ -24,6 +24,8 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, char *p; int left; size_t l = 0; + BIO_MMSG_CB_ARGS *args; + long ret_ = ret; if (processed != NULL) l = *processed; @@ -69,6 +71,16 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi, bio->method->name); break; + case BIO_CB_RECVMMSG: + args = (BIO_MMSG_CB_ARGS *)argp; + BIO_snprintf(p, left, "recvmmsg(%zu) - %s", + args->num_msg, bio->method->name); + break; + case BIO_CB_SENDMMSG: + args = (BIO_MMSG_CB_ARGS *)argp; + BIO_snprintf(p, left, "sendmmsg(%zu) - %s", + args->num_msg, bio->method->name); + break; case BIO_CB_RETURN | BIO_CB_READ: BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l); break; @@ -84,6 +96,14 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, case BIO_CB_RETURN | BIO_CB_CTRL: BIO_snprintf(p, left, "ctrl return %d\n", ret); break; + case BIO_CB_RETURN | BIO_CB_RECVMMSG: + BIO_snprintf(p, left, "recvmmsg processed: %zu\n", len); + ret_ = (long)len; + break; + case BIO_CB_RETURN | BIO_CB_SENDMMSG: + BIO_snprintf(p, left, "sendmmsg processed: %zu\n", len); + ret_ = (long)len; + break; default: BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd); break; @@ -96,7 +116,7 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, else fputs(buf, stderr); #endif - return ret; + return ret_; } #ifndef OPENSSL_NO_DEPRECATED_3_0 diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index 7a36c61148..6fe295ee52 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -46,6 +46,10 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { "no hostname or service specified"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), "port mismatch"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_DISABLED), "tfo disabled"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_NO_KERNEL_SUPPORT), + "tfo no kernel support"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET), @@ -59,6 +63,7 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_REUSEADDR), "unable to reuseaddr"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_TFO), "unable to tfo"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNAVAILABLE_IP_FAMILY), "unavailable ip family"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "uninitialized"}, @@ -71,6 +76,14 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOCAL_ADDR_NOT_AVAILABLE), + "local address not available"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PEER_ADDR_NOT_AVAILABLE), + "peer address not available"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NON_FATAL), + "non-fatal or transient error"}, + {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), + "port mismatch"}, {0, NULL} }; @@ -84,3 +97,18 @@ int ossl_err_load_BIO_strings(void) #endif return 1; } + +#ifndef OPENSSL_NO_SOCK + +int BIO_err_is_non_fatal(unsigned int errcode) +{ + if (ERR_SYSTEM_ERROR(errcode)) + return BIO_sock_non_fatal_error(ERR_GET_REASON(errcode)); + else if (ERR_GET_LIB(errcode) == ERR_LIB_BIO + && ERR_GET_REASON(errcode) == BIO_R_NON_FATAL) + return 1; + else + return 0; +} + +#endif diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index faea9a63ef..e4f72bcd1b 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -82,30 +82,22 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method) { BIO *bio = OPENSSL_zalloc(sizeof(*bio)); - if (bio == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (bio == NULL) return NULL; - } bio->libctx = libctx; bio->method = method; bio->shutdown = 1; - bio->references = 1; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) + if (!CRYPTO_NEW_REF(&bio->references, 1)) goto err; - bio->lock = CRYPTO_THREAD_lock_new(); - if (bio->lock == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data)) goto err; - } if (method->create != NULL && !method->create(bio)) { ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); - CRYPTO_THREAD_lock_free(bio->lock); goto err; } if (method->create == NULL) @@ -114,6 +106,7 @@ BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method) return bio; err: + CRYPTO_FREE_REF(&bio->references); OPENSSL_free(bio); return NULL; } @@ -130,7 +123,7 @@ int BIO_free(BIO *a) if (a == NULL) return 0; - if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0) + if (CRYPTO_DOWN_REF(&a->references, &ret) <= 0) return 0; REF_PRINT_COUNT("BIO", a); @@ -149,7 +142,7 @@ int BIO_free(BIO *a) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); - CRYPTO_THREAD_lock_free(a->lock); + CRYPTO_FREE_REF(&a->references); OPENSSL_free(a); @@ -195,7 +188,7 @@ int BIO_up_ref(BIO *a) { int i; - if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0) + if (CRYPTO_UP_REF(&a->references, &i) <= 0) return 0; REF_PRINT_COUNT("BIO", a); @@ -398,6 +391,110 @@ int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written) || (b != NULL && dlen == 0); /* order is important for *written */ } +int BIO_sendmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + size_t ret; + BIO_MMSG_CB_ARGS args; + + if (b == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (b->method == NULL || b->method->bsendmmsg == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + if (HAS_CALLBACK(b)) { + args.msg = msg; + args.stride = stride; + args.num_msg = num_msg; + args.flags = flags; + args.msgs_processed = msgs_processed; + + ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG, (void *)&args, + 0, 0, 0, 1, NULL); + if (ret <= 0) + return 0; + } + + if (!b->init) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + ret = b->method->bsendmmsg(b, msg, stride, num_msg, flags, msgs_processed); + + if (HAS_CALLBACK(b)) + ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG | BIO_CB_RETURN, + (void *)&args, ret, 0, 0, ret, NULL); + + return ret; +} + +int BIO_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + size_t ret; + BIO_MMSG_CB_ARGS args; + + if (b == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (b->method == NULL || b->method->brecvmmsg == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + if (HAS_CALLBACK(b)) { + args.msg = msg; + args.stride = stride; + args.num_msg = num_msg; + args.flags = flags; + args.msgs_processed = msgs_processed; + + ret = bio_call_callback(b, BIO_CB_RECVMMSG, (void *)&args, + 0, 0, 0, 1, NULL); + if (ret <= 0) + return 0; + } + + if (!b->init) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + ret = b->method->brecvmmsg(b, msg, stride, num_msg, flags, msgs_processed); + + if (HAS_CALLBACK(b)) + ret = (size_t)bio_call_callback(b, BIO_CB_RECVMMSG | BIO_CB_RETURN, + (void *)&args, ret, 0, 0, ret, NULL); + + return ret; +} + +int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc) +{ + return BIO_ctrl(b, BIO_CTRL_GET_RPOLL_DESCRIPTOR, 0, desc); +} + +int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc) +{ + return BIO_ctrl(b, BIO_CTRL_GET_WPOLL_DESCRIPTOR, 0, desc); +} + int BIO_puts(BIO *b, const char *buf) { int ret; @@ -756,7 +853,7 @@ void BIO_free_all(BIO *bio) while (bio != NULL) { b = bio; - ref = b->references; + CRYPTO_GET_REF(&b->references, &ref); bio = bio->next_bio; BIO_free(b); /* Since ref count > 1, don't free anyone else. */ @@ -853,8 +950,7 @@ void bio_cleanup(void) CRYPTO_THREAD_lock_free(bio_lookup_lock); bio_lookup_lock = NULL; #endif - CRYPTO_THREAD_lock_free(bio_type_lock); - bio_type_lock = NULL; + CRYPTO_FREE_REF(&bio_type_count); } /* Internal variant of the below BIO_wait() not calling ERR_raise(...) */ @@ -886,7 +982,7 @@ static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds) if ((unsigned long)sec_diff * 1000 < nap_milliseconds) nap_milliseconds = (unsigned int)sec_diff * 1000; } - ossl_sleep(nap_milliseconds); + OSSL_sleep(nap_milliseconds); return 1; } diff --git a/crypto/bio/bio_local.h b/crypto/bio/bio_local.h index 87779c8e02..05954f85bb 100644 --- a/crypto/bio/bio_local.h +++ b/crypto/bio/bio_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,6 +9,7 @@ #include "internal/e_os.h" #include "internal/sockets.h" +#include "internal/bio_addr.h" /* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */ @@ -63,17 +64,6 @@ struct bio_addrinfo_st { struct bio_addrinfo_st *bai_next; }; # endif - -union bio_addr_st { - struct sockaddr sa; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 s_in6; -# endif - struct sockaddr_in s_in; -# ifndef OPENSSL_NO_UNIX_SOCK - struct sockaddr_un s_un; -# endif -}; #endif /* END BIO_ADDRINFO/BIO_ADDR stuff. */ @@ -126,7 +116,6 @@ struct bio_st { uint64_t num_read; uint64_t num_write; CRYPTO_EX_DATA ex_data; - CRYPTO_RWLOCK *lock; }; #ifndef OPENSSL_NO_SOCK @@ -142,9 +131,15 @@ struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap); socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap); socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai); const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai); + +# if defined(OPENSSL_SYS_WINDOWS) && defined(WSAID_WSARECVMSG) +# define BIO_HAVE_WSAMSG +extern LPFN_WSARECVMSG bio_WSARecvMsg; +extern LPFN_WSASENDMSG bio_WSASendMsg; +# endif #endif -extern CRYPTO_RWLOCK *bio_type_lock; +extern CRYPTO_REF_COUNT bio_type_count; void bio_sock_cleanup_int(void); diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c index 469715ba09..30b1db5aa8 100644 --- a/crypto/bio/bio_meth.c +++ b/crypto/bio/bio_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,25 +10,24 @@ #include "bio_local.h" #include "internal/thread_once.h" -CRYPTO_RWLOCK *bio_type_lock = NULL; +CRYPTO_REF_COUNT bio_type_count; static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_bio_type_init) { - bio_type_lock = CRYPTO_THREAD_lock_new(); - return bio_type_lock != NULL; + return CRYPTO_NEW_REF(&bio_type_count, BIO_TYPE_START); } int BIO_get_new_index(void) { - static CRYPTO_REF_COUNT bio_count = BIO_TYPE_START; int newval; if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + /* Perhaps the error should be raised in do_bio_type_init()? */ + ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB); return -1; } - if (!CRYPTO_UP_REF(&bio_count, &newval, bio_type_lock)) + if (!CRYPTO_UP_REF(&bio_type_count, &newval)) return -1; return newval; } @@ -40,7 +39,6 @@ BIO_METHOD *BIO_meth_new(int type, const char *name) if (biom == NULL || (biom->name = OPENSSL_strdup(name)) == NULL) { OPENSSL_free(biom); - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return NULL; } biom->type = type; @@ -218,3 +216,25 @@ int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, biom->callback_ctrl = callback_ctrl; return 1; } + +int BIO_meth_set_sendmmsg(BIO_METHOD *biom, + int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *)) +{ + biom->bsendmmsg = bsendmmsg; + return 1; +} + +int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) { + return biom->bsendmmsg; +} + +int BIO_meth_set_recvmmsg(BIO_METHOD *biom, + int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *)) +{ + biom->brecvmmsg = brecvmmsg; + return 1; +} + +int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) { + return biom->brecvmmsg; +} diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c index eb192e8240..5f2543030e 100644 --- a/crypto/bio/bio_print.c +++ b/crypto/bio/bio_print.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,7 +62,7 @@ static int _dopr(char **sbuffer, char **buffer, #define DP_F_NUM (1 << 3) /* print leading zeroes */ #define DP_F_ZERO (1 << 4) -/* print HEX in UPPPERcase */ +/* print HEX in UPPERcase */ #define DP_F_UP (1 << 5) /* treat value as unsigned */ #define DP_F_UNSIGNED (1 << 6) @@ -707,8 +707,6 @@ fmtfp(char **sbuffer, fracpart = (fracpart / 10); } - if (fplace == sizeof(fconvert)) - fplace--; fconvert[fplace] = 0; /* convert exponent part */ @@ -847,10 +845,8 @@ doapr_outch(char **sbuffer, *maxlen += BUFFER_INC; if (*buffer == NULL) { - if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) return 0; - } if (*currlen > 0) { if (!ossl_assert(*sbuffer != NULL)) return 0; @@ -861,10 +857,8 @@ doapr_outch(char **sbuffer, char *tmpbuf; tmpbuf = OPENSSL_realloc(*buffer, *maxlen); - if (tmpbuf == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (tmpbuf == NULL) return 0; - } *buffer = tmpbuf; } } diff --git a/crypto/bio/bio_sock.c b/crypto/bio/bio_sock.c index 476cbcc5ce..3c8b28501c 100644 --- a/crypto/bio/bio_sock.c +++ b/crypto/bio/bio_sock.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -130,6 +130,11 @@ struct hostent *BIO_gethostbyname(const char *name) } # endif +# ifdef BIO_HAVE_WSAMSG +LPFN_WSARECVMSG bio_WSARecvMsg; +LPFN_WSASENDMSG bio_WSASendMsg; +# endif + int BIO_sock_init(void) { # ifdef OPENSSL_SYS_WINDOWS @@ -150,6 +155,39 @@ int BIO_sock_init(void) ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP); return -1; } + + /* + * On Windows, some socket functions are not exposed as a prototype. + * Instead, their function pointers must be loaded via this elaborate + * process... + */ +# ifdef BIO_HAVE_WSAMSG + { + GUID id_WSARecvMsg = WSAID_WSARECVMSG; + GUID id_WSASendMsg = WSAID_WSASENDMSG; + DWORD len_out = 0; + SOCKET s; + + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s != INVALID_SOCKET) { + if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, + &id_WSARecvMsg, sizeof(id_WSARecvMsg), + &bio_WSARecvMsg, sizeof(bio_WSARecvMsg), + &len_out, NULL, NULL) != 0 + || len_out != sizeof(bio_WSARecvMsg)) + bio_WSARecvMsg = NULL; + + if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, + &id_WSASendMsg, sizeof(id_WSASendMsg), + &bio_WSASendMsg, sizeof(bio_WSASendMsg), + &len_out, NULL, NULL) != 0 + || len_out != sizeof(bio_WSASendMsg)) + bio_WSASendMsg = NULL; + + closesocket(s); + } + } +# endif } # endif /* OPENSSL_SYS_WINDOWS */ # ifdef WATT32 @@ -267,13 +305,14 @@ int BIO_accept(int sock, char **ip_port) if (ip_port != NULL) { char *host = BIO_ADDR_hostname_string(&res, 1); char *port = BIO_ADDR_service_string(&res, 1); - if (host != NULL && port != NULL) + if (host != NULL && port != NULL) { *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2); - else + } else { *ip_port = NULL; + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); + } if (*ip_port == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); BIO_closesocket(ret); ret = (int)INVALID_SOCKET; } else { @@ -315,7 +354,7 @@ int BIO_socket_nbio(int s, int mode) int l; l = mode; -# ifdef FIONBIO +# if defined(FIONBIO) && !defined(OPENSSL_SYS_TANDEM) l = mode; ret = BIO_socket_ioctl(s, FIONBIO, &l); diff --git a/crypto/bio/bio_sock2.c b/crypto/bio/bio_sock2.c index b746e40ba0..252a9ab074 100644 --- a/crypto/bio/bio_sock2.c +++ b/crypto/bio/bio_sock2.c @@ -13,6 +13,7 @@ #include "bio_local.h" #include "internal/ktls.h" +#include "internal/bio_tfo.h" #include @@ -68,6 +69,7 @@ int BIO_socket(int domain, int socktype, int protocol, int options) * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages. * - BIO_SOCK_NONBLOCK: Make the socket non-blocking. * - BIO_SOCK_NODELAY: don't delay small messages. + * - BIO_SOCK_TFO: use TCP Fast Open * * options holds BIO socket options that can be used * You should call this for every address returned by BIO_lookup @@ -107,6 +109,68 @@ int BIO_connect(int sock, const BIO_ADDR *addr, int options) return 0; } } + if (options & BIO_SOCK_TFO) { +# if defined(OSSL_TFO_CLIENT_FLAG) +# if defined(OSSL_TFO_SYSCTL_CLIENT) + int enabled = 0; + size_t enabledlen = sizeof(enabled); + + /* Later FreeBSD */ + if (sysctlbyname(OSSL_TFO_SYSCTL_CLIENT, &enabled, &enabledlen, NULL, 0) < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT); + return 0; + } + /* Need to check for client flag */ + if (!(enabled & OSSL_TFO_CLIENT_FLAG)) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED); + return 0; + } +# elif defined(OSSL_TFO_SYSCTL) + int enabled = 0; + size_t enabledlen = sizeof(enabled); + + /* macOS */ + if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT); + return 0; + } + /* Need to check for client flag */ + if (!(enabled & OSSL_TFO_CLIENT_FLAG)) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED); + return 0; + } +# endif +# endif +# if defined(OSSL_TFO_CONNECTX) + sa_endpoints_t sae; + + memset(&sae, 0, sizeof(sae)); + sae.sae_dstaddr = BIO_ADDR_sockaddr(addr); + sae.sae_dstaddrlen = BIO_ADDR_sockaddr_size(addr); + if (connectx(sock, &sae, SAE_ASSOCID_ANY, + CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE, + NULL, 0, NULL, NULL) == -1) { + if (!BIO_sock_should_retry(-1)) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling connectx()"); + ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR); + } + return 0; + } +# endif +# if defined(OSSL_TFO_CLIENT_SOCKOPT) + if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_CLIENT_SOCKOPT, + (const void *)&on, sizeof(on)) != 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO); + return 0; + } +# endif +# if defined(OSSL_TFO_DO_NOT_CONNECT) + return 1; +# endif + } if (connect(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) == -1) { @@ -199,6 +263,7 @@ int BIO_bind(int sock, const BIO_ADDR *addr, int options) * for a recently closed port. * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only * for IPv6 addresses and not IPv4 addresses mapped to IPv6. + * - BIO_SOCK_TFO: accept TCP fast open (set TCP_FASTOPEN) * * It's recommended that you set up both an IPv6 and IPv4 listen socket, and * then check both for new clients that connect to it. You want to set up @@ -290,6 +355,54 @@ int BIO_listen(int sock, const BIO_ADDR *addr, int options) return 0; } +# if defined(OSSL_TFO_SERVER_SOCKOPT) + /* + * Must do it explicitly after listen() for macOS, still + * works fine on other OS's + */ + if ((options & BIO_SOCK_TFO) && socktype != SOCK_DGRAM) { + int q = OSSL_TFO_SERVER_SOCKOPT_VALUE; +# if defined(OSSL_TFO_CLIENT_FLAG) +# if defined(OSSL_TFO_SYSCTL_SERVER) + int enabled = 0; + size_t enabledlen = sizeof(enabled); + + /* Later FreeBSD */ + if (sysctlbyname(OSSL_TFO_SYSCTL_SERVER, &enabled, &enabledlen, NULL, 0) < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT); + return 0; + } + /* Need to check for server flag */ + if (!(enabled & OSSL_TFO_SERVER_FLAG)) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED); + return 0; + } +# elif defined(OSSL_TFO_SYSCTL) + int enabled = 0; + size_t enabledlen = sizeof(enabled); + + /* Early FreeBSD, macOS */ + if (sysctlbyname(OSSL_TFO_SYSCTL, &enabled, &enabledlen, NULL, 0) < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_NO_KERNEL_SUPPORT); + return 0; + } + /* Need to check for server flag */ + if (!(enabled & OSSL_TFO_SERVER_FLAG)) { + ERR_raise(ERR_LIB_BIO, BIO_R_TFO_DISABLED); + return 0; + } +# endif +# endif + if (setsockopt(sock, IPPROTO_TCP, OSSL_TFO_SERVER_SOCKOPT, + (void *)&q, sizeof(q)) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_TFO); + return 0; + } + } +# endif + return 1; } diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c index 3da66f355a..4ccdca18ec 100644 --- a/crypto/bio/bss_acpt.c +++ b/crypto/bio/bss_acpt.c @@ -92,10 +92,8 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void) { BIO_ACCEPT *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } ret->accept_family = BIO_FAMILY_IPANY; ret->accept_sock = (int)INVALID_SOCKET; return ret; @@ -452,10 +450,14 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) data->bio_chain = (BIO *)ptr; } else if (num == 4) { data->accept_family = *(int *)ptr; + } else if (num == 5) { + data->bind_mode |= BIO_SOCK_TFO; } } else { if (num == 2) { data->bind_mode &= ~BIO_SOCK_NONBLOCK; + } else if (num == 5) { + data->bind_mode &= ~BIO_SOCK_TFO; } } break; diff --git a/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c index 5039a621f0..3af3b27ea5 100644 --- a/crypto/bio/bss_bio.c +++ b/crypto/bio/bss_bio.c @@ -273,7 +273,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) BIO_clear_retry_flags(bio); - if (!bio->init || buf == NULL || num == 0) + if (!bio->init || buf == NULL || num_ <= 0) return 0; b = bio->ptr; @@ -620,20 +620,16 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) if (b1->buf == NULL) { b1->buf = OPENSSL_malloc(b1->size); - if (b1->buf == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (b1->buf == NULL) return 0; - } b1->len = 0; b1->offset = 0; } if (b2->buf == NULL) { b2->buf = OPENSSL_malloc(b2->size); - if (b2->buf == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (b2->buf == NULL) return 0; - } b2->len = 0; b2->offset = 0; } diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index 2247678ae0..fb3c4d2ba3 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #include #include "bio_local.h" +#include "internal/bio_tfo.h" #include "internal/ktls.h" #ifndef OPENSSL_NO_SOCK @@ -18,12 +19,14 @@ typedef struct bio_connect_st { int state; int connect_family; + int connect_sock_type; char *param_hostname; char *param_service; int connect_mode; # ifndef OPENSSL_NO_KTLS unsigned char record_type; # endif + int tfo_first; BIO_ADDRINFO *addr_first; const BIO_ADDRINFO *addr_iter; @@ -37,20 +40,30 @@ typedef struct bio_connect_st { * ssl info_callback */ BIO_info_cb *info_callback; + /* + * Used when connect_sock_type is SOCK_DGRAM. Owned by us; we forward + * read/write(mmsg) calls to this if present. + */ + BIO *dgram_bio; } BIO_CONNECT; static int conn_write(BIO *h, const char *buf, int num); static int conn_read(BIO *h, char *buf, int size); static int conn_puts(BIO *h, const char *str); +static int conn_gets(BIO *h, char *buf, int size); static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int conn_new(BIO *h); static int conn_free(BIO *data); static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *); +static int conn_sendmmsg(BIO *h, BIO_MSG *m, size_t s, size_t n, + uint64_t f, size_t *mp); +static int conn_recvmmsg(BIO *h, BIO_MSG *m, size_t s, size_t n, + uint64_t f, size_t *mp); static int conn_state(BIO *b, BIO_CONNECT *c); static void conn_close_socket(BIO *data); -BIO_CONNECT *BIO_CONNECT_new(void); -void BIO_CONNECT_free(BIO_CONNECT *a); +static BIO_CONNECT *BIO_CONNECT_new(void); +static void BIO_CONNECT_free(BIO_CONNECT *a); #define BIO_CONN_S_BEFORE 1 #define BIO_CONN_S_GET_ADDR 2 @@ -68,13 +81,33 @@ static const BIO_METHOD methods_connectp = { bread_conv, conn_read, conn_puts, - NULL, /* conn_gets, */ + conn_gets, conn_ctrl, conn_new, conn_free, conn_callback_ctrl, + conn_sendmmsg, + conn_recvmmsg, }; +static int conn_create_dgram_bio(BIO *b, BIO_CONNECT *c) +{ + if (c->connect_sock_type != SOCK_DGRAM) + return 1; + +#ifndef OPENSSL_NO_DGRAM + c->dgram_bio = BIO_new_dgram(b->num, 0); + if (c->dgram_bio == NULL) + goto err; + + return 1; + +err: +#endif + c->state = BIO_CONN_S_CONNECT_ERROR; + return 0; +} + static int conn_state(BIO *b, BIO_CONNECT *c) { int ret = -1, i; @@ -125,7 +158,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c) } if (BIO_lookup(c->param_hostname, c->param_service, BIO_LOOKUP_CLIENT, - family, SOCK_STREAM, &c->addr_first) == 0) + family, c->connect_sock_type, + &c->addr_first) == 0) goto exit_loop; } if (c->addr_first == NULL) { @@ -183,6 +217,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c) goto exit_loop; } else { ERR_clear_last_mark(); + if (!conn_create_dgram_bio(b, c)) + break; c->state = BIO_CONN_S_OK; } break; @@ -209,6 +245,8 @@ static int conn_state(BIO *b, BIO_CONNECT *c) ret = 0; goto exit_loop; } else { + if (!conn_create_dgram_bio(b, c)) + break; c->state = BIO_CONN_S_OK; # ifndef OPENSSL_NO_KTLS /* @@ -249,20 +287,19 @@ static int conn_state(BIO *b, BIO_CONNECT *c) return ret; } -BIO_CONNECT *BIO_CONNECT_new(void) +static BIO_CONNECT *BIO_CONNECT_new(void) { BIO_CONNECT *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } ret->state = BIO_CONN_S_BEFORE; ret->connect_family = BIO_FAMILY_IPANY; + ret->connect_sock_type = SOCK_STREAM; return ret; } -void BIO_CONNECT_free(BIO_CONNECT *a) +static void BIO_CONNECT_free(BIO_CONNECT *a) { if (a == NULL) return; @@ -310,6 +347,8 @@ static int conn_free(BIO *a) return 0; data = (BIO_CONNECT *)a->ptr; + BIO_free(data->dgram_bio); + if (a->shutdown) { conn_close_socket(a); BIO_CONNECT_free(data); @@ -332,6 +371,13 @@ static int conn_read(BIO *b, char *out, int outl) return ret; } + if (data->dgram_bio != NULL) { + BIO_clear_retry_flags(b); + ret = BIO_read(data->dgram_bio, out, outl); + BIO_set_flags(b, BIO_get_retry_flags(data->dgram_bio)); + return ret; + } + if (out != NULL) { clear_socket_error(); # ifndef OPENSSL_NO_KTLS @@ -363,6 +409,13 @@ static int conn_write(BIO *b, const char *in, int inl) return ret; } + if (data->dgram_bio != NULL) { + BIO_clear_retry_flags(b); + ret = BIO_write(data->dgram_bio, in, inl); + BIO_set_flags(b, BIO_get_retry_flags(data->dgram_bio)); + return ret; + } + clear_socket_error(); # ifndef OPENSSL_NO_KTLS if (BIO_should_ktls_ctrl_msg_flag(b)) { @@ -372,6 +425,15 @@ static int conn_write(BIO *b, const char *in, int inl) BIO_clear_ktls_ctrl_msg_flag(b); } } else +# endif +# if defined(OSSL_TFO_SENDTO) + if (data->tfo_first) { + int peerlen = BIO_ADDRINFO_sockaddr_size(data->addr_iter); + + ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO, + BIO_ADDRINFO_sockaddr(data->addr_iter), peerlen); + data->tfo_first = 0; + } else # endif ret = writesocket(b->num, in, inl); BIO_clear_retry_flags(b); @@ -389,6 +451,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) const char **pptr = NULL; long ret = 1; BIO_CONNECT *data; + const BIO_ADDR *dg_addr; # ifndef OPENSSL_NO_KTLS ktls_crypto_info_t *crypto_info; # endif @@ -437,6 +500,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) ret = -1; break; } + } else if (num == 4) { + ret = data->connect_mode; } else { ret = 0; } @@ -491,14 +556,90 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) } } break; + case BIO_C_SET_SOCK_TYPE: + if ((num != SOCK_STREAM && num != SOCK_DGRAM) + || data->state >= BIO_CONN_S_GET_ADDR) { + ret = 0; + break; + } + + data->connect_sock_type = (int)num; + ret = 1; + break; + case BIO_C_GET_SOCK_TYPE: + ret = data->connect_sock_type; + break; + case BIO_C_GET_DGRAM_BIO: + if (data->dgram_bio != NULL) { + *(BIO **)ptr = data->dgram_bio; + ret = 1; + } else { + ret = 0; + } + break; + case BIO_CTRL_DGRAM_GET_PEER: + case BIO_CTRL_DGRAM_DETECT_PEER_ADDR: + if (data->state != BIO_CONN_S_OK) + conn_state(b, data); /* best effort */ + + if (data->state >= BIO_CONN_S_CREATE_SOCKET + && data->addr_iter != NULL + && (dg_addr = BIO_ADDRINFO_address(data->addr_iter)) != NULL) { + + ret = BIO_ADDR_sockaddr_size(dg_addr); + if (num == 0 || num > ret) + num = ret; + + memcpy(ptr, dg_addr, num); + ret = num; + } else { + ret = 0; + } + + break; + case BIO_CTRL_GET_RPOLL_DESCRIPTOR: + case BIO_CTRL_GET_WPOLL_DESCRIPTOR: + { + BIO_POLL_DESCRIPTOR *pd = ptr; + + if (data->state != BIO_CONN_S_OK) + conn_state(b, data); /* best effort */ + + if (data->state >= BIO_CONN_S_CREATE_SOCKET) { + pd->type = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; + pd->value.fd = b->num; + } else { + ret = 0; + } + } + break; case BIO_C_SET_NBIO: if (num != 0) data->connect_mode |= BIO_SOCK_NONBLOCK; else data->connect_mode &= ~BIO_SOCK_NONBLOCK; + + if (data->dgram_bio != NULL) + ret = BIO_set_nbio(data->dgram_bio, num); + break; +#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO) + case BIO_C_SET_TFO: + if (num != 0) { + data->connect_mode |= BIO_SOCK_TFO; + data->tfo_first = 1; + } else { + data->connect_mode &= ~BIO_SOCK_TFO; + data->tfo_first = 0; + } + break; +#endif case BIO_C_SET_CONNECT_MODE: data->connect_mode = (int)num; + if (num & BIO_SOCK_TFO) + data->tfo_first = 1; + else + data->tfo_first = 0; break; case BIO_C_GET_FD: if (b->init) { @@ -571,6 +712,11 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_clear_ktls_ctrl_msg_flag(b); ret = 0; break; + case BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE: + ret = ktls_enable_tx_zerocopy_sendfile(b->num); + if (ret) + BIO_set_ktls_zerocopy_sendfile_flag(b); + break; # endif default: ret = 0; @@ -608,6 +754,123 @@ static int conn_puts(BIO *bp, const char *str) return ret; } +int conn_gets(BIO *bio, char *buf, int size) +{ + BIO_CONNECT *data; + char *ptr = buf; + int ret = 0; + + if (buf == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (size <= 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + *buf = '\0'; + + if (bio == NULL || bio->ptr == NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) + return ret; + } + + if (data->dgram_bio != NULL) { + ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + clear_socket_error(); + while (size-- > 1) { +# ifndef OPENSSL_NO_KTLS + if (BIO_get_ktls_recv(bio)) + ret = ktls_read_record(bio->num, ptr, 1); + else +# endif + ret = readsocket(bio->num, ptr, 1); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(bio); + else if (ret == 0) + bio->flags |= BIO_FLAGS_IN_EOF; + break; + } + if (*ptr++ == '\n') + break; + } + *ptr = '\0'; + return ret > 0 || (bio->flags & BIO_FLAGS_IN_EOF) != 0 ? ptr - buf : ret; +} + +static int conn_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msgs, + uint64_t flags, size_t *msgs_processed) +{ + int ret; + BIO_CONNECT *data; + + if (bio == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + *msgs_processed = 0; + return 0; + } + } + + if (data->dgram_bio == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return BIO_sendmmsg(data->dgram_bio, msg, stride, num_msgs, + flags, msgs_processed); +} + +static int conn_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, size_t num_msgs, + uint64_t flags, size_t *msgs_processed) +{ + int ret; + BIO_CONNECT *data; + + if (bio == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + *msgs_processed = 0; + return 0; + } + } + + if (data->dgram_bio == NULL) { + *msgs_processed = 0; + ERR_raise(ERR_LIB_BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + return BIO_recvmmsg(data->dgram_bio, msg, stride, num_msgs, + flags, msgs_processed); +} + BIO *BIO_new_connect(const char *str) { BIO *ret; diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index cdbb786b58..5195634fdf 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,7 @@ #include #include +#include "internal/time.h" #include "bio_local.h" #ifndef OPENSSL_NO_DGRAM @@ -42,6 +43,93 @@ ((a)->s6_addr32[2] == htonl(0x0000ffff))) # endif +/* Determine what method to use for BIO_sendmmsg and BIO_recvmmsg. */ +# define M_METHOD_NONE 0 +# define M_METHOD_RECVMMSG 1 +# define M_METHOD_RECVMSG 2 +# define M_METHOD_RECVFROM 3 +# define M_METHOD_WSARECVMSG 4 + +# if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if !(__GLIBC_PREREQ(2, 14)) +# undef NO_RECVMMSG + /* + * Some old glibc versions may have recvmmsg and MSG_WAITFORONE flag, but + * not sendmmsg. We need both so force this to be disabled on these old + * versions + */ +# define NO_RECVMMSG +# endif +# endif +# if !defined(M_METHOD) +# if defined(OPENSSL_SYS_WINDOWS) && defined(BIO_HAVE_WSAMSG) && !defined(NO_WSARECVMSG) +# define M_METHOD M_METHOD_WSARECVMSG +# elif !defined(OPENSSL_SYS_WINDOWS) && defined(MSG_WAITFORONE) && !defined(NO_RECVMMSG) +# define M_METHOD M_METHOD_RECVMMSG +# elif !defined(OPENSSL_SYS_WINDOWS) && defined(CMSG_LEN) && !defined(NO_RECVMSG) +# define M_METHOD M_METHOD_RECVMSG +# elif !defined(NO_RECVFROM) +# define M_METHOD M_METHOD_RECVFROM +# else +# define M_METHOD M_METHOD_NONE +# endif +# endif + +# if defined(OPENSSL_SYS_WINDOWS) +# define BIO_CMSG_SPACE(x) WSA_CMSG_SPACE(x) +# define BIO_CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x) +# define BIO_CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y) +# define BIO_CMSG_DATA(x) WSA_CMSG_DATA(x) +# define BIO_CMSG_LEN(x) WSA_CMSG_LEN(x) +# define MSGHDR_TYPE WSAMSG +# define CMSGHDR_TYPE WSACMSGHDR +# else +# define MSGHDR_TYPE struct msghdr +# define CMSGHDR_TYPE struct cmsghdr +# define BIO_CMSG_SPACE(x) CMSG_SPACE(x) +# define BIO_CMSG_FIRSTHDR(x) CMSG_FIRSTHDR(x) +# define BIO_CMSG_NXTHDR(x, y) CMSG_NXTHDR(x, y) +# define BIO_CMSG_DATA(x) CMSG_DATA(x) +# define BIO_CMSG_LEN(x) CMSG_LEN(x) +# endif + +# if M_METHOD == M_METHOD_RECVMMSG \ + || M_METHOD == M_METHOD_RECVMSG \ + || M_METHOD == M_METHOD_WSARECVMSG +# if defined(__APPLE__) + /* + * CMSG_SPACE is not a constant expresson on OSX even though POSIX + * says it's supposed to be. This should be adequate. + */ +# define BIO_CMSG_ALLOC_LEN 64 +# else +# if defined(IPV6_PKTINFO) +# define BIO_CMSG_ALLOC_LEN_1 BIO_CMSG_SPACE(sizeof(struct in6_pktinfo)) +# else +# define BIO_CMSG_ALLOC_LEN_1 0 +# endif +# if defined(IP_PKTINFO) +# define BIO_CMSG_ALLOC_LEN_2 BIO_CMSG_SPACE(sizeof(struct in_pktinfo)) +# else +# define BIO_CMSG_ALLOC_LEN_2 0 +# endif +# if defined(IP_RECVDSTADDR) +# define BIO_CMSG_ALLOC_LEN_3 BIO_CMSG_SPACE(sizeof(struct in_addr)) +# else +# define BIO_CMSG_ALLOC_LEN_3 0 +# endif +# define BIO_MAX(X,Y) ((X) > (Y) ? (X) : (Y)) +# define BIO_CMSG_ALLOC_LEN \ + BIO_MAX(BIO_CMSG_ALLOC_LEN_1, \ + BIO_MAX(BIO_CMSG_ALLOC_LEN_2, BIO_CMSG_ALLOC_LEN_3)) +# endif +# if (defined(IP_PKTINFO) || defined(IP_RECVDSTADDR)) && defined(IPV6_RECVPKTINFO) +# define SUPPORT_LOCAL_ADDR +# endif +# endif + +# define BIO_MSG_N(array, stride, n) (*(BIO_MSG *)((char *)(array) + (n)*(stride))) + static int dgram_write(BIO *h, const char *buf, int num); static int dgram_read(BIO *h, char *buf, int size); static int dgram_puts(BIO *h, const char *str); @@ -49,6 +137,12 @@ static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int dgram_new(BIO *h); static int dgram_free(BIO *data); static int dgram_clear(BIO *bio); +static int dgram_sendmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, + uint64_t flags, size_t *num_processed); +static int dgram_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, + uint64_t flags, size_t *num_processed); # ifndef OPENSSL_NO_SCTP static int dgram_sctp_write(BIO *h, const char *buf, int num); @@ -67,8 +161,6 @@ static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notificatio static int BIO_dgram_should_retry(int s); -static void get_current_time(struct timeval *t); - static const BIO_METHOD methods_dgramp = { BIO_TYPE_DGRAM, "datagram socket", @@ -82,6 +174,8 @@ static const BIO_METHOD methods_dgramp = { dgram_new, dgram_free, NULL, /* dgram_callback_ctrl */ + dgram_sendmmsg, + dgram_recvmmsg, }; # ifndef OPENSSL_NO_SCTP @@ -98,17 +192,21 @@ static const BIO_METHOD methods_dgramp_sctp = { dgram_sctp_new, dgram_sctp_free, NULL, /* dgram_callback_ctrl */ + NULL, /* sendmmsg */ + NULL, /* recvmmsg */ }; # endif typedef struct bio_dgram_data_st { BIO_ADDR peer; + BIO_ADDR local_addr; unsigned int connected; unsigned int _errno; unsigned int mtu; - struct timeval next_timeout; - struct timeval socket_timeout; + OSSL_TIME next_timeout; + OSSL_TIME socket_timeout; unsigned int peekmode; + char local_addr_enabled; } bio_dgram_data; # ifndef OPENSSL_NO_SCTP @@ -118,11 +216,13 @@ typedef struct bio_dgram_sctp_save_message_st { int length; } bio_dgram_sctp_save_message; +/* + * Note: bio_dgram_data must be first here + * as we use dgram_ctrl for underlying dgram operations + * which will cast this struct to a bio_dgram_data + */ typedef struct bio_dgram_sctp_data_st { - BIO_ADDR peer; - unsigned int connected; - unsigned int _errno; - unsigned int mtu; + bio_dgram_data dgram; struct bio_dgram_sctp_sndinfo sndinfo; struct bio_dgram_sctp_rcvinfo rcvinfo; struct bio_dgram_sctp_prinfo prinfo; @@ -195,96 +295,102 @@ static void dgram_adjust_rcv_timeout(BIO *b) { # if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; + OSSL_TIME timeleft; /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { - struct timeval timenow, timeleft; - + if (!ossl_time_is_zero(data->next_timeout)) { /* Read current socket timeout */ # ifdef OPENSSL_SYS_WINDOWS int timeout; - int sz = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz) < 0) { - perror("getsockopt"); - } else { - data->socket_timeout.tv_sec = timeout / 1000; - data->socket_timeout.tv_usec = (timeout % 1000) * 1000; - } + (void *)&timeout, &sz) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); + else + data->socket_timeout = ossl_ms2time(timeout); # else - socklen_t sz = sizeof(data->socket_timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - &(data->socket_timeout), &sz) < 0) { - perror("getsockopt"); - } else - OPENSSL_assert((size_t)sz <= sizeof(data->socket_timeout)); -# endif + struct timeval tv; + socklen_t sz = sizeof(tv); - /* Get current time */ - get_current_time(&timenow); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, &sz) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); + else + data->socket_timeout = ossl_time_from_timeval(tv); +# endif /* Calculate time left until timer expires */ - memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); - if (timeleft.tv_usec < timenow.tv_usec) { - timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; - timeleft.tv_sec--; - } else { - timeleft.tv_usec -= timenow.tv_usec; - } - if (timeleft.tv_sec < timenow.tv_sec) { - timeleft.tv_sec = 0; - timeleft.tv_usec = 1; - } else { - timeleft.tv_sec -= timenow.tv_sec; - } + timeleft = ossl_time_subtract(data->next_timeout, ossl_time_now()); + if (ossl_time_compare(timeleft, ossl_ticks2time(OSSL_TIME_US)) < 0) + timeleft = ossl_ticks2time(OSSL_TIME_US); /* * Adjust socket timeout if next handshake message timer will expire * earlier. */ - if ((data->socket_timeout.tv_sec == 0 - && data->socket_timeout.tv_usec == 0) - || (data->socket_timeout.tv_sec > timeleft.tv_sec) - || (data->socket_timeout.tv_sec == timeleft.tv_sec - && data->socket_timeout.tv_usec >= timeleft.tv_usec)) { + if (ossl_time_is_zero(data->socket_timeout) + || ossl_time_compare(data->socket_timeout, timeleft) >= 0) { # ifdef OPENSSL_SYS_WINDOWS - timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + timeout = (int)ossl_time2ms(timeleft); if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - } + (void *)&timeout, sizeof(timeout)) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - } + tv = ossl_time_to_timeval(timeleft); + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, + sizeof(tv)) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # endif } } # endif } +static void dgram_update_local_addr(BIO *b) +{ + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + socklen_t addr_len = sizeof(data->local_addr); + + if (getsockname(b->num, &data->local_addr.sa, &addr_len) < 0) + /* + * This should not be possible, but zero-initialize and return + * anyway. + */ + BIO_ADDR_clear(&data->local_addr); +} + +# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG || M_METHOD == M_METHOD_WSARECVMSG +static int dgram_get_sock_family(BIO *b) +{ + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + return data->local_addr.sa.sa_family; +} +# endif + static void dgram_reset_rcv_timeout(BIO *b) { # if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + if (!ossl_time_is_zero(data->next_timeout)) { # ifdef OPENSSL_SYS_WINDOWS - int timeout = data->socket_timeout.tv_sec * 1000 + - data->socket_timeout.tv_usec / 1000; + int timeout = (int)ossl_time2ms(data->socket_timeout); + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - } + (void *)&timeout, sizeof(timeout)) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # else - if (setsockopt - (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - } + struct timeval tv = ossl_time_to_timeval(data->socket_timeout); + + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # endif } # endif @@ -301,7 +407,7 @@ static int dgram_read(BIO *b, char *out, int outl) if (out != NULL) { clear_socket_error(); - memset(&peer, 0, sizeof(peer)); + BIO_ADDR_clear(&peer); dgram_adjust_rcv_timeout(b); if (data->peekmode) flags = MSG_PEEK; @@ -388,12 +494,54 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data) return ret; } +/* Enables appropriate destination address reception option on the socket. */ +# if defined(SUPPORT_LOCAL_ADDR) +static int enable_local_addr(BIO *b, int enable) { + int af = dgram_get_sock_family(b); + + if (af == AF_INET) { +# if defined(IP_PKTINFO) + /* IP_PKTINFO is preferred */ + if (setsockopt(b->num, IPPROTO_IP, IP_PKTINFO, + (void *)&enable, sizeof(enable)) < 0) + return 0; + + return 1; + +# elif defined(IP_RECVDSTADDR) + /* Fall back to IP_RECVDSTADDR */ + + if (setsockopt(b->num, IPPROTO_IP, IP_RECVDSTADDR, + &enable, sizeof(enable)) < 0) + return 0; + + return 1; +# endif + } + +# if OPENSSL_USE_IPV6 + if (af == AF_INET6) { +# if defined(IPV6_RECVPKTINFO) + if (setsockopt(b->num, IPPROTO_IPV6, IPV6_RECVPKTINFO, + &enable, sizeof(enable)) < 0) + return 0; + + return 1; +# endif + } +# endif + + return 0; +} +# endif + static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; bio_dgram_data *data = NULL; # ifndef __DJGPP__ + /* There are currently no cases where this is used on djgpp/watt32. */ int sockopt_val = 0; # endif int d_errno; @@ -419,6 +567,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) b->num = *((int *)ptr); b->shutdown = (int)num; b->init = 1; + dgram_update_local_addr(b); +# if defined(SUPPORT_LOCAL_ADDR) + if (data->local_addr_enabled) { + if (enable_local_addr(b, 1) < 1) + data->local_addr_enabled = 0; + } +# endif break; case BIO_C_GET_FD: if (b->init) { @@ -450,7 +605,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DGRAM_MTU_DISCOVER: # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) addr_len = (socklen_t) sizeof(addr); - memset(&addr, 0, sizeof(addr)); + BIO_ADDR_clear(&addr); if (getsockname(b->num, &addr.sa, &addr_len) < 0) { ret = 0; break; @@ -460,14 +615,16 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) sockopt_val = IP_PMTUDISC_DO; if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, &sockopt_val, sizeof(sockopt_val))) < 0) - perror("setsockopt"); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); break; # if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) case AF_INET6: sockopt_val = IPV6_PMTUDISC_DO; if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &sockopt_val, sizeof(sockopt_val))) < 0) - perror("setsockopt"); + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); break; # endif default: @@ -481,7 +638,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DGRAM_QUERY_MTU: # if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) addr_len = (socklen_t) sizeof(addr); - memset(&addr, 0, sizeof(addr)); + BIO_ADDR_clear(&addr); if (getsockname(b->num, &addr.sa, &addr_len) < 0) { ret = 0; break; @@ -564,7 +721,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); } else { data->connected = 0; - memset(&data->peer, 0, sizeof(data->peer)); + BIO_ADDR_clear(&data->peer); } break; case BIO_CTRL_DGRAM_GET_PEER: @@ -578,8 +735,34 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DGRAM_SET_PEER: BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr)); break; + case BIO_CTRL_DGRAM_DETECT_PEER_ADDR: + { + BIO_ADDR xaddr, *p = &data->peer; + socklen_t xaddr_len = sizeof(xaddr.sa); + + if (BIO_ADDR_family(p) == AF_UNSPEC) { + if (getpeername(b->num, (void *)&xaddr.sa, &xaddr_len) == 0 + && BIO_ADDR_family(&xaddr) != AF_UNSPEC) { + p = &xaddr; + } else { + ret = 0; + break; + } + } + + ret = BIO_ADDR_sockaddr_size(p); + if (num == 0 || num > ret) + num = ret; + + memcpy(ptr, p, (ret = num)); + } + break; + case BIO_C_SET_NBIO: + if (!BIO_socket_nbio(b->num, num != 0)) + ret = 0; + break; case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + data->next_timeout = ossl_time_from_timeval(*(struct timeval *)ptr); break; # if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: @@ -587,18 +770,17 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) { struct timeval *tv = (struct timeval *)ptr; int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - ret = -1; - } + + if ((ret = setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); } # else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - ret = -1; - } + if ((ret = setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # endif break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: @@ -609,10 +791,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) struct timeval *tv = (struct timeval *)ptr; sz = sizeof(timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz) < 0) { - perror("getsockopt"); - ret = -1; + if ((ret = getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz)) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); } else { tv->tv_sec = timeout / 1000; tv->tv_usec = (timeout % 1000) * 1000; @@ -620,10 +802,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) } # else socklen_t sz = sizeof(struct timeval); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - ptr, &sz) < 0) { - perror("getsockopt"); - ret = -1; + if ((ret = getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, &sz)) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); } else { OPENSSL_assert((size_t)sz <= sizeof(struct timeval)); ret = (int)sz; @@ -638,18 +820,17 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) { struct timeval *tv = (struct timeval *)ptr; int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - ret = -1; - } + + if ((ret = setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, sizeof(timeout))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); } # else - if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - ret = -1; - } + if ((ret = setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # endif break; case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: @@ -660,10 +841,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) struct timeval *tv = (struct timeval *)ptr; sz = sizeof(timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, &sz) < 0) { - perror("getsockopt"); - ret = -1; + if ((ret = getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, &sz)) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); } else { tv->tv_sec = timeout / 1000; tv->tv_usec = (timeout % 1000) * 1000; @@ -671,10 +852,11 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) } # else socklen_t sz = sizeof(struct timeval); - if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - ptr, &sz) < 0) { - perror("getsockopt"); - ret = -1; + + if ((ret = getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, &sz)) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling getsockopt()"); } else { OPENSSL_assert((size_t)sz <= sizeof(struct timeval)); ret = (int)sz; @@ -712,25 +894,22 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) # if defined(IP_DONTFRAG) sockopt_val = num ? 1 : 0; if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } + &sockopt_val, sizeof(sockopt_val))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE) sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT; if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } + &sockopt_val, sizeof(sockopt_val))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT) sockopt_val = num ? 1 : 0; if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT, (const char *)&sockopt_val, - sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } + sizeof(sockopt_val))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # else ret = -1; # endif @@ -741,17 +920,16 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) sockopt_val = num ? 1 : 0; if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG, (const void *)&sockopt_val, - sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } + sizeof(sockopt_val))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); + # elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER) sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT; if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } + &sockopt_val, sizeof(sockopt_val))) < 0) + ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), + "calling setsockopt()"); # else ret = -1; # endif @@ -777,10 +955,59 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DGRAM_SET_PEEK_MODE: data->peekmode = (unsigned int)num; break; + + case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: +# if defined(SUPPORT_LOCAL_ADDR) + ret = 1; +# else + ret = 0; +# endif + break; + + case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: +# if defined(SUPPORT_LOCAL_ADDR) + num = num > 0; + if (num != data->local_addr_enabled) { + if (enable_local_addr(b, num) < 1) { + ret = 0; + break; + } + + data->local_addr_enabled = (char)num; + } +# else + ret = 0; +# endif + break; + + case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: + *(int *)ptr = data->local_addr_enabled; + break; + + case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: + ret = (long)(BIO_DGRAM_CAP_HANDLES_DST_ADDR + | BIO_DGRAM_CAP_HANDLES_SRC_ADDR + | BIO_DGRAM_CAP_PROVIDES_DST_ADDR + | BIO_DGRAM_CAP_PROVIDES_SRC_ADDR); + break; + + case BIO_CTRL_GET_RPOLL_DESCRIPTOR: + case BIO_CTRL_GET_WPOLL_DESCRIPTOR: + { + BIO_POLL_DESCRIPTOR *pd = ptr; + + pd->type = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; + pd->value.fd = b->num; + } + break; + default: ret = 0; break; } + /* Normalize if error */ + if (ret < 0) + ret = -1; return ret; } @@ -793,6 +1020,718 @@ static int dgram_puts(BIO *bp, const char *str) return ret; } +# if M_METHOD == M_METHOD_WSARECVMSG +static void translate_msg_win(BIO *b, WSAMSG *mh, WSABUF *iov, + unsigned char *control, BIO_MSG *msg) +{ + iov->len = msg->data_len; + iov->buf = msg->data; + + /* Windows requires namelen to be set exactly */ + mh->name = msg->peer != NULL ? &msg->peer->sa : NULL; + if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET) + mh->namelen = sizeof(struct sockaddr_in); +# if OPENSSL_USE_IPV6 + else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6) + mh->namelen = sizeof(struct sockaddr_in6); +# endif + else + mh->namelen = 0; + + /* + * When local address reception (IP_PKTINFO, etc.) is enabled, on Windows + * this causes WSARecvMsg to fail if the control buffer is too small to hold + * the structure, or if no control buffer is passed. So we need to give it + * the control buffer even if we aren't actually going to examine the + * result. + */ + mh->lpBuffers = iov; + mh->dwBufferCount = 1; + mh->Control.len = BIO_CMSG_ALLOC_LEN; + mh->Control.buf = control; + mh->dwFlags = 0; +} +# endif + +# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG +/* Translates a BIO_MSG to a msghdr and iovec. */ +static void translate_msg(BIO *b, struct msghdr *mh, struct iovec *iov, + unsigned char *control, BIO_MSG *msg) +{ + iov->iov_base = msg->data; + iov->iov_len = msg->data_len; + + /* macOS requires msg_namelen be 0 if msg_name is NULL */ + mh->msg_name = msg->peer != NULL ? &msg->peer->sa : NULL; + if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET) + mh->msg_namelen = sizeof(struct sockaddr_in); +# if OPENSSL_USE_IPV6 + else if (msg->peer != NULL && dgram_get_sock_family(b) == AF_INET6) + mh->msg_namelen = sizeof(struct sockaddr_in6); +# endif + else + mh->msg_namelen = 0; + + mh->msg_iov = iov; + mh->msg_iovlen = 1; + mh->msg_control = msg->local != NULL ? control : NULL; + mh->msg_controllen = msg->local != NULL ? BIO_CMSG_ALLOC_LEN : 0; + mh->msg_flags = 0; +} +# endif + +# if M_METHOD == M_METHOD_RECVMMSG || M_METHOD == M_METHOD_RECVMSG || M_METHOD == M_METHOD_WSARECVMSG +/* Extracts destination address from the control buffer. */ +static int extract_local(BIO *b, MSGHDR_TYPE *mh, BIO_ADDR *local) { +# if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO) + CMSGHDR_TYPE *cmsg; + int af = dgram_get_sock_family(b); + + for (cmsg = BIO_CMSG_FIRSTHDR(mh); cmsg != NULL; + cmsg = BIO_CMSG_NXTHDR(mh, cmsg)) { + if (af == AF_INET) { + if (cmsg->cmsg_level != IPPROTO_IP) + continue; + +# if defined(IP_PKTINFO) + if (cmsg->cmsg_type != IP_PKTINFO) + continue; + + local->s_in.sin_addr = + ((struct in_pktinfo *)BIO_CMSG_DATA(cmsg))->ipi_addr; + +# elif defined(IP_RECVDSTADDR) + if (cmsg->cmsg_type != IP_RECVDSTADDR) + continue; + + local->s_in.sin_addr = *(struct in_addr *)BIO_CMSG_DATA(cmsg); +# endif + +# if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) + { + bio_dgram_data *data = b->ptr; + + local->s_in.sin_family = AF_INET; + local->s_in.sin_port = data->local_addr.s_in.sin_port; + } + return 1; +# endif + } +# if OPENSSL_USE_IPV6 + else if (af == AF_INET6) { + if (cmsg->cmsg_level != IPPROTO_IPV6) + continue; + +# if defined(IPV6_RECVPKTINFO) + if (cmsg->cmsg_type != IPV6_PKTINFO) + continue; + + { + bio_dgram_data *data = b->ptr; + + local->s_in6.sin6_addr = + ((struct in6_pktinfo *)BIO_CMSG_DATA(cmsg))->ipi6_addr; + local->s_in6.sin6_family = AF_INET6; + local->s_in6.sin6_port = data->local_addr.s_in6.sin6_port; + local->s_in6.sin6_scope_id = + data->local_addr.s_in6.sin6_scope_id; + local->s_in6.sin6_flowinfo = 0; + } + return 1; +# endif + } +# endif + } +# endif + + return 0; +} + +static int pack_local(BIO *b, MSGHDR_TYPE *mh, const BIO_ADDR *local) { + int af = dgram_get_sock_family(b); +# if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO) + CMSGHDR_TYPE *cmsg; + bio_dgram_data *data = b->ptr; +# endif + + if (af == AF_INET) { +# if defined(IP_PKTINFO) + struct in_pktinfo *info; + +# if defined(OPENSSL_SYS_WINDOWS) + cmsg = (CMSGHDR_TYPE *)mh->Control.buf; +# else + cmsg = (CMSGHDR_TYPE *)mh->msg_control; +# endif + + cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in_pktinfo)); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + + info = (struct in_pktinfo *)BIO_CMSG_DATA(cmsg); +# if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_CYGWIN) + info->ipi_spec_dst = local->s_in.sin_addr; +# endif + info->ipi_addr.s_addr = 0; + info->ipi_ifindex = 0; + + /* + * We cannot override source port using this API, therefore + * ensure the application specified a source port of 0 + * or the one we are bound to. (Better to error than silently + * ignore this.) + */ + if (local->s_in.sin_port != 0 + && data->local_addr.s_in.sin_port != local->s_in.sin_port) { + ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH); + return 0; + } + +# if defined(OPENSSL_SYS_WINDOWS) + mh->Control.len = BIO_CMSG_SPACE(sizeof(struct in_pktinfo)); +# else + mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in_pktinfo)); +# endif + return 1; + +# elif defined(IP_SENDSRCADDR) + struct in_addr *info; + + /* + * At least FreeBSD is very pedantic about using IP_SENDSRCADDR when we + * are not bound to 0.0.0.0 or ::, even if the address matches what we + * bound to. Support this by not packing the structure if the address + * matches our understanding of our local address. IP_SENDSRCADDR is a + * BSD thing, so we don't need an explicit test for BSD here. + */ + if (local->s_in.sin_addr.s_addr == data->local_addr.s_in.sin_addr.s_addr) { + mh->msg_control = NULL; + mh->msg_controllen = 0; + return 1; + } + + cmsg = (struct cmsghdr *)mh->msg_control; + cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in_addr)); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + + info = (struct in_addr *)BIO_CMSG_DATA(cmsg); + *info = local->s_in.sin_addr; + + /* See comment above. */ + if (local->s_in.sin_port != 0 + && data->local_addr.s_in.sin_port != local->s_in.sin_port) { + ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH); + return 0; + } + + mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in_addr)); + return 1; +# endif + } +# if OPENSSL_USE_IPV6 + else if (af == AF_INET6) { +# if defined(IPV6_PKTINFO) + struct in6_pktinfo *info; + +# if defined(OPENSSL_SYS_WINDOWS) + cmsg = (CMSGHDR_TYPE *)mh->Control.buf; +# else + cmsg = (CMSGHDR_TYPE *)mh->msg_control; +# endif + cmsg->cmsg_len = BIO_CMSG_LEN(sizeof(struct in6_pktinfo)); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + + info = (struct in6_pktinfo *)BIO_CMSG_DATA(cmsg); + info->ipi6_addr = local->s_in6.sin6_addr; + info->ipi6_ifindex = 0; + + /* + * See comment above, but also applies to the other fields + * in sockaddr_in6. + */ + if (local->s_in6.sin6_port != 0 + && data->local_addr.s_in6.sin6_port != local->s_in6.sin6_port) { + ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH); + return 0; + } + + if (local->s_in6.sin6_scope_id != 0 + && data->local_addr.s_in6.sin6_scope_id != local->s_in6.sin6_scope_id) { + ERR_raise(ERR_LIB_BIO, BIO_R_PORT_MISMATCH); + return 0; + } + +# if defined(OPENSSL_SYS_WINDOWS) + mh->Control.len = BIO_CMSG_SPACE(sizeof(struct in6_pktinfo)); +# else + mh->msg_controllen = BIO_CMSG_SPACE(sizeof(struct in6_pktinfo)); +# endif + return 1; +# endif + } +# endif + + return 0; +} +# endif + +/* + * Converts flags passed to BIO_sendmmsg or BIO_recvmmsg to syscall flags. You + * should mask out any system flags returned by this function you cannot support + * in a particular circumstance. Currently no flags are defined. + */ +# if M_METHOD != M_METHOD_NONE +static int translate_flags(uint64_t flags) { + return 0; +} +# endif + +static int dgram_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, size_t *num_processed) +{ +# if M_METHOD != M_METHOD_NONE && M_METHOD != M_METHOD_RECVMSG + int ret; +# endif +# if M_METHOD == M_METHOD_RECVMMSG +# define BIO_MAX_MSGS_PER_CALL 64 + int sysflags; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + size_t i; + struct mmsghdr mh[BIO_MAX_MSGS_PER_CALL]; + struct iovec iov[BIO_MAX_MSGS_PER_CALL]; + unsigned char control[BIO_MAX_MSGS_PER_CALL][BIO_CMSG_ALLOC_LEN]; + int have_local_enabled = data->local_addr_enabled; +# elif M_METHOD == M_METHOD_RECVMSG + int sysflags; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + ossl_ssize_t l; + struct msghdr mh; + struct iovec iov; + unsigned char control[BIO_CMSG_ALLOC_LEN]; + int have_local_enabled = data->local_addr_enabled; +# elif M_METHOD == M_METHOD_WSARECVMSG + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + int have_local_enabled = data->local_addr_enabled; + WSAMSG wmsg; + WSABUF wbuf; + DWORD num_bytes_sent = 0; + unsigned char control[BIO_CMSG_ALLOC_LEN]; +# endif +# if M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG + int sysflags; +# endif + + if (num_msg == 0) { + *num_processed = 0; + return 1; + } + + if (num_msg > OSSL_SSIZE_MAX) + num_msg = OSSL_SSIZE_MAX; + +# if M_METHOD != M_METHOD_NONE + sysflags = translate_flags(flags); +# endif + +# if M_METHOD == M_METHOD_RECVMMSG + /* + * In the sendmmsg/recvmmsg case, we need to allocate our translated struct + * msghdr and struct iovec on the stack to support multithreaded use. Thus + * we place a fixed limit on the number of messages per call, in the + * expectation that we will be called again if there were more messages to + * be sent. + */ + if (num_msg > BIO_MAX_MSGS_PER_CALL) + num_msg = BIO_MAX_MSGS_PER_CALL; + + for (i = 0; i < num_msg; ++i) { + translate_msg(b, &mh[i].msg_hdr, &iov[i], + control[i], &BIO_MSG_N(msg, stride, i)); + + /* If local address was requested, it must have been enabled */ + if (BIO_MSG_N(msg, stride, i).local != NULL) { + if (!have_local_enabled) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + if (pack_local(b, &mh[i].msg_hdr, + BIO_MSG_N(msg, stride, i).local) < 1) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + } + } + + /* Do the batch */ + ret = sendmmsg(b->num, mh, num_msg, sysflags); + if (ret < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + for (i = 0; i < (size_t)ret; ++i) { + BIO_MSG_N(msg, stride, i).data_len = mh[i].msg_len; + BIO_MSG_N(msg, stride, i).flags = 0; + } + + *num_processed = (size_t)ret; + return 1; + +# elif M_METHOD == M_METHOD_RECVMSG + /* + * If sendmsg is available, use it. + */ + translate_msg(b, &mh, &iov, control, msg); + + if (msg->local != NULL) { + if (!have_local_enabled) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + if (pack_local(b, &mh, msg->local) < 1) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + } + + l = sendmsg(b->num, &mh, sysflags); + if (l < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + msg->data_len = (size_t)l; + msg->flags = 0; + *num_processed = 1; + return 1; + +# elif M_METHOD == M_METHOD_WSARECVMSG || M_METHOD == M_METHOD_RECVFROM +# if M_METHOD == M_METHOD_WSARECVMSG + if (bio_WSASendMsg != NULL) { + /* WSASendMsg-based implementation for Windows. */ + translate_msg_win(b, &wmsg, &wbuf, control, msg); + + if (msg[0].local != NULL) { + if (!have_local_enabled) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + if (pack_local(b, &wmsg, msg[0].local) < 1) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + } + + ret = WSASendMsg((SOCKET)b->num, &wmsg, 0, &num_bytes_sent, NULL, NULL); + if (ret < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + msg[0].data_len = num_bytes_sent; + msg[0].flags = 0; + *num_processed = 1; + return 1; + } +# endif + + /* + * Fallback to sendto and send a single message. + */ + if (msg[0].local != NULL) { + /* + * We cannot set the local address if using sendto + * so fail in this case + */ + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + ret = sendto(b->num, msg[0].data, +# if defined(OPENSSL_SYS_WINDOWS) + (int)msg[0].data_len, +# else + msg[0].data_len, +# endif + sysflags, + msg[0].peer != NULL ? BIO_ADDR_sockaddr(msg[0].peer) : NULL, + msg[0].peer != NULL ? BIO_ADDR_sockaddr_size(msg[0].peer) : 0); + if (ret <= 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + msg[0].data_len = ret; + msg[0].flags = 0; + *num_processed = 1; + return 1; + +# else + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + *num_processed = 0; + return 0; +# endif +} + +static int dgram_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, + uint64_t flags, size_t *num_processed) +{ +# if M_METHOD != M_METHOD_NONE && M_METHOD != M_METHOD_RECVMSG + int ret; +# endif +# if M_METHOD == M_METHOD_RECVMMSG + int sysflags; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + size_t i; + struct mmsghdr mh[BIO_MAX_MSGS_PER_CALL]; + struct iovec iov[BIO_MAX_MSGS_PER_CALL]; + unsigned char control[BIO_MAX_MSGS_PER_CALL][BIO_CMSG_ALLOC_LEN]; + int have_local_enabled = data->local_addr_enabled; +# elif M_METHOD == M_METHOD_RECVMSG + int sysflags; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + ossl_ssize_t l; + struct msghdr mh; + struct iovec iov; + unsigned char control[BIO_CMSG_ALLOC_LEN]; + int have_local_enabled = data->local_addr_enabled; +# elif M_METHOD == M_METHOD_WSARECVMSG + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + int have_local_enabled = data->local_addr_enabled; + WSAMSG wmsg; + WSABUF wbuf; + DWORD num_bytes_received = 0; + unsigned char control[BIO_CMSG_ALLOC_LEN]; +# endif +# if M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG + int sysflags; + socklen_t slen; +# endif + + if (num_msg == 0) { + *num_processed = 0; + return 1; + } + + if (num_msg > OSSL_SSIZE_MAX) + num_msg = OSSL_SSIZE_MAX; + +# if M_METHOD != M_METHOD_NONE + sysflags = translate_flags(flags); +# endif + +# if M_METHOD == M_METHOD_RECVMMSG + /* + * In the sendmmsg/recvmmsg case, we need to allocate our translated struct + * msghdr and struct iovec on the stack to support multithreaded use. Thus + * we place a fixed limit on the number of messages per call, in the + * expectation that we will be called again if there were more messages to + * be sent. + */ + if (num_msg > BIO_MAX_MSGS_PER_CALL) + num_msg = BIO_MAX_MSGS_PER_CALL; + + for (i = 0; i < num_msg; ++i) { + translate_msg(b, &mh[i].msg_hdr, &iov[i], + control[i], &BIO_MSG_N(msg, stride, i)); + + /* If local address was requested, it must have been enabled */ + if (BIO_MSG_N(msg, stride, i).local != NULL && !have_local_enabled) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + } + + /* Do the batch */ + ret = recvmmsg(b->num, mh, num_msg, sysflags, NULL); + if (ret < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + for (i = 0; i < (size_t)ret; ++i) { + BIO_MSG_N(msg, stride, i).data_len = mh[i].msg_len; + BIO_MSG_N(msg, stride, i).flags = 0; + /* + * *(msg->peer) will have been filled in by recvmmsg; + * for msg->local we parse the control data returned + */ + if (BIO_MSG_N(msg, stride, i).local != NULL) + if (extract_local(b, &mh[i].msg_hdr, + BIO_MSG_N(msg, stride, i).local) < 1) + /* + * It appears BSDs do not support local addresses for + * loopback sockets. In this case, just clear the local + * address, as for OS X and Windows in some circumstances + * (see below). + */ + BIO_ADDR_clear(msg->local); + } + + *num_processed = (size_t)ret; + return 1; + +# elif M_METHOD == M_METHOD_RECVMSG + /* + * If recvmsg is available, use it. + */ + translate_msg(b, &mh, &iov, control, msg); + + /* If local address was requested, it must have been enabled */ + if (msg->local != NULL && !have_local_enabled) { + /* + * If we have done at least one message, we must return the + * count; if we haven't done any, we can give an error code + */ + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + l = recvmsg(b->num, &mh, sysflags); + if (l < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + msg->data_len = (size_t)l; + msg->flags = 0; + + if (msg->local != NULL) + if (extract_local(b, &mh, msg->local) < 1) + /* + * OS X exhibits odd behaviour where it appears that if a packet is + * sent before the receiving interface enables IP_PKTINFO, it will + * sometimes not have any control data returned even if the + * receiving interface enables IP_PKTINFO before calling recvmsg(). + * This appears to occur non-deterministically. Presumably, OS X + * handles IP_PKTINFO at the time the packet is enqueued into a + * socket's receive queue, rather than at the time recvmsg() is + * called, unlike most other operating systems. Thus (if this + * hypothesis is correct) there is a race between where IP_PKTINFO + * is enabled by the process and when the kernel's network stack + * queues the incoming message. + * + * We cannot return the local address if we do not have it, but this + * is not a caller error either, so just return a zero address + * structure. This is similar to how we handle Windows loopback + * interfaces (see below). We enable this workaround for all + * platforms, not just Apple, as this kind of quirk in OS networking + * stacks seems to be common enough that failing hard if a local + * address is not provided appears to be too brittle. + */ + BIO_ADDR_clear(msg->local); + + *num_processed = 1; + return 1; + +# elif M_METHOD == M_METHOD_RECVFROM || M_METHOD == M_METHOD_WSARECVMSG +# if M_METHOD == M_METHOD_WSARECVMSG + if (bio_WSARecvMsg != NULL) { + /* WSARecvMsg-based implementation for Windows. */ + translate_msg_win(b, &wmsg, &wbuf, control, msg); + + /* If local address was requested, it must have been enabled */ + if (msg[0].local != NULL && !have_local_enabled) { + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + ret = WSARecvMsg((SOCKET)b->num, &wmsg, &num_bytes_received, NULL, NULL); + if (ret < 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + *num_processed = 0; + return 0; + } + + msg[0].data_len = num_bytes_received; + msg[0].flags = 0; + if (msg[0].local != NULL) + if (extract_local(b, &wmsg, msg[0].local) < 1) + /* + * On Windows, loopback is not a "proper" interface and it works + * differently; packets are essentially short-circuited and + * don't go through all of the normal processing. A consequence + * of this is that packets sent from the local machine to the + * local machine _will not have IP_PKTINFO_ even if the + * IP_PKTINFO socket option is enabled. WSARecvMsg just sets + * Control.len to 0 on returning. + * + * This applies regardless of whether the loopback address, + * 127.0.0.1 is used, or a local interface address (e.g. + * 192.168.1.1); in both cases IP_PKTINFO will not be present. + * + * We report this condition by setting the local BIO_ADDR's + * family to 0. + */ + BIO_ADDR_clear(msg[0].local); + + *num_processed = 1; + return 1; + } +# endif + + /* + * Fallback to recvfrom and receive a single message. + */ + if (msg[0].local != NULL) { + /* + * We cannot determine the local address if using recvfrom + * so fail in this case + */ + ERR_raise(ERR_LIB_BIO, BIO_R_LOCAL_ADDR_NOT_AVAILABLE); + *num_processed = 0; + return 0; + } + + slen = sizeof(*msg[0].peer); + ret = recvfrom(b->num, msg[0].data, +# if defined(OPENSSL_SYS_WINDOWS) + (int)msg[0].data_len, +# else + msg[0].data_len, +# endif + sysflags, + msg[0].peer != NULL ? &msg[0].peer->sa : NULL, + msg[0].peer != NULL ? &slen : NULL); + if (ret <= 0) { + ERR_raise(ERR_LIB_SYS, get_last_socket_error()); + return 0; + } + + msg[0].data_len = ret; + msg[0].flags = 0; + *num_processed = 1; + return 1; + +# else + ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD); + *num_processed = 0; + return 0; +# endif +} + # ifndef OPENSSL_NO_SCTP const BIO_METHOD *BIO_s_datagram_sctp(void) { @@ -941,10 +1880,8 @@ static int dgram_sctp_new(BIO *bi) bi->init = 0; bi->num = 0; - if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) return 0; - } # ifdef SCTP_PR_SCTP_NONE data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; # endif @@ -1166,7 +2103,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) if (ret < 0) { if (BIO_dgram_should_retry(ret)) { BIO_set_retry_read(b); - data->_errno = get_last_socket_error(); + data->dgram._errno = get_last_socket_error(); } } @@ -1179,10 +2116,8 @@ static int dgram_sctp_read(BIO *b, char *out, int outl) optlen = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); authchunks = OPENSSL_malloc(optlen); - if (authchunks == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (authchunks == NULL) return -1; - } memset(authchunks, 0, optlen); ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen); @@ -1320,7 +2255,7 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl) if (ret <= 0) { if (BIO_dgram_should_retry(ret)) { BIO_set_retry_write(b); - data->_errno = get_last_socket_error(); + data->dgram._errno = get_last_socket_error(); } } return ret; @@ -1342,16 +2277,16 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) * Set to maximum (2^14) and ignore user input to enable transport * protocol fragmentation. Returns always 2^14. */ - data->mtu = 16384; - ret = data->mtu; + data->dgram.mtu = 16384; + ret = data->dgram.mtu; break; case BIO_CTRL_DGRAM_SET_MTU: /* * Set to maximum (2^14) and ignore input to enable transport * protocol fragmentation. Returns always 2^14. */ - data->mtu = 16384; - ret = data->mtu; + data->dgram.mtu = 16384; + ret = data->dgram.mtu; break; case BIO_CTRL_DGRAM_SET_CONNECTED: case BIO_CTRL_DGRAM_CONNECT: @@ -1899,27 +2834,4 @@ int BIO_dgram_non_fatal_error(int err) return 0; } -static void get_current_time(struct timeval *t) -{ -# if defined(_WIN32) - SYSTEMTIME st; - unsigned __int64 now_ul; - FILETIME now_ft; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now_ft); - now_ul = ((unsigned __int64)now_ft.dwHighDateTime << 32) | now_ft.dwLowDateTime; -# ifdef __MINGW32__ - now_ul -= 116444736000000000ULL; -# else - now_ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ -# endif - t->tv_sec = (long)(now_ul / 10000000); - t->tv_usec = ((int)(now_ul % 10000000)) / 10; -# else - if (gettimeofday(t, NULL) < 0) - perror("gettimeofday"); -# endif -} - #endif diff --git a/crypto/bio/bss_dgram_pair.c b/crypto/bio/bss_dgram_pair.c new file mode 100644 index 0000000000..08dd802d8f --- /dev/null +++ b/crypto/bio/bss_dgram_pair.c @@ -0,0 +1,1328 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "bio_local.h" +#include "internal/cryptlib.h" +#include "internal/safe_math.h" + +#if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK) + +OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) + +/* =========================================================================== + * Byte-wise ring buffer which supports pushing and popping blocks of multiple + * bytes at a time. + */ +struct ring_buf { + unsigned char *start; /* start of buffer */ + size_t len; /* size of buffer allocation in bytes */ + size_t count; /* number of bytes currently pushed */ + /* + * These index into start. Where idx[0] == idx[1], the buffer is full + * (if count is nonzero) and empty otherwise. + */ + size_t idx[2]; /* 0: head, 1: tail */ +}; + +static int ring_buf_init(struct ring_buf *r, size_t nbytes) +{ + r->start = OPENSSL_malloc(nbytes); + if (r->start == NULL) + return 0; + + r->len = nbytes; + r->idx[0] = r->idx[1] = r->count = 0; + return 1; +} + +static void ring_buf_destroy(struct ring_buf *r) +{ + OPENSSL_free(r->start); + r->start = NULL; + r->len = 0; + r->count = 0; +} + +/* + * Get a pointer to the next place to write data to be pushed to the ring buffer + * (idx=0), or the next data to be popped from the ring buffer (idx=1). The + * pointer is written to *buf and the maximum number of bytes which can be + * read/written are written to *len. After writing data to the buffer, call + * ring_buf_push/pop() with the number of bytes actually read/written, which + * must not exceed the returned length. + */ +static void ring_buf_head_tail(struct ring_buf *r, int idx, uint8_t **buf, size_t *len) +{ + size_t max_len = r->len - r->idx[idx]; + + if (idx == 0 && max_len > r->len - r->count) + max_len = r->len - r->count; + if (idx == 1 && max_len > r->count) + max_len = r->count; + + *buf = (uint8_t *)r->start + r->idx[idx]; + *len = max_len; +} + +#define ring_buf_head(r, buf, len) ring_buf_head_tail((r), 0, (buf), (len)) +#define ring_buf_tail(r, buf, len) ring_buf_head_tail((r), 1, (buf), (len)) + +/* + * Commit bytes to the ring buffer previously filled after a call to + * ring_buf_head(). + */ +static void ring_buf_push_pop(struct ring_buf *r, int idx, size_t num_bytes) +{ + size_t new_idx; + + /* A single push/pop op cannot wrap around, though it can reach the end. + * If the caller adheres to the convention of using the length returned + * by ring_buf_head/tail(), this cannot happen. + */ + if (!ossl_assert(num_bytes <= r->len - r->idx[idx])) + return; + + /* + * Must not overfill the buffer, or pop more than is in the buffer either. + */ + if (!ossl_assert(idx != 0 ? num_bytes <= r->count + : num_bytes + r->count <= r->len)) + return; + + /* Update the index. */ + new_idx = r->idx[idx] + num_bytes; + if (new_idx == r->len) + new_idx = 0; + + r->idx[idx] = new_idx; + if (idx != 0) + r->count -= num_bytes; + else + r->count += num_bytes; +} + +#define ring_buf_push(r, num_bytes) ring_buf_push_pop((r), 0, (num_bytes)) +#define ring_buf_pop(r, num_bytes) ring_buf_push_pop((r), 1, (num_bytes)) + +static void ring_buf_clear(struct ring_buf *r) +{ + r->idx[0] = r->idx[1] = r->count = 0; +} + +static int ring_buf_resize(struct ring_buf *r, size_t nbytes) +{ + unsigned char *new_start; + + if (r->start == NULL) + return ring_buf_init(r, nbytes); + + if (nbytes == r->len) + return 1; + + if (r->count > 0 && nbytes < r->len) + /* fail shrinking the ring buffer when there is any data in it */ + return 0; + + new_start = OPENSSL_realloc(r->start, nbytes); + if (new_start == NULL) + return 0; + + /* Moving tail if it is after (or equal to) head */ + if (r->count > 0) { + if (r->idx[0] <= r->idx[1]) { + size_t offset = nbytes - r->len; + + memmove(new_start + r->idx[1] + offset, new_start + r->idx[1], + r->len - r->idx[1]); + r->idx[1] += offset; + } + } else { + /* just reset the head/tail because it might be pointing outside */ + r->idx[0] = r->idx[1] = 0; + } + + r->start = new_start; + r->len = nbytes; + + return 1; +} + +/* =========================================================================== + * BIO_s_dgram_pair is documented in BIO_s_dgram_pair(3). + * + * INTERNAL DATA STRUCTURE + * + * This is managed internally by using a bytewise ring buffer which supports + * pushing and popping spans of multiple bytes at once. The ring buffer stores + * internal packets which look like this: + * + * struct dgram_hdr hdr; + * uint8_t data[]; + * + * The header contains the length of the data and metadata such as + * source/destination addresses. + * + * The datagram pair BIO is designed to support both traditional + * BIO_read/BIO_write (likely to be used by applications) as well as + * BIO_recvmmsg/BIO_sendmmsg. + */ +struct bio_dgram_pair_st; +static int dgram_pair_write(BIO *bio, const char *buf, int sz_); +static int dgram_pair_read(BIO *bio, char *buf, int sz_); +static int dgram_mem_read(BIO *bio, char *buf, int sz_); +static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr); +static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr); +static int dgram_pair_init(BIO *bio); +static int dgram_mem_init(BIO *bio); +static int dgram_pair_free(BIO *bio); +static int dgram_pair_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *num_processed); +static int dgram_pair_recvmmsg(BIO *b, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *num_processed); + +static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1); +static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, + size_t sz); + +#define BIO_MSG_N(array, n) (*(BIO_MSG *)((char *)(array) + (n)*stride)) + +static const BIO_METHOD dgram_pair_method = { + BIO_TYPE_DGRAM_PAIR, + "BIO dgram pair", + bwrite_conv, + dgram_pair_write, + bread_conv, + dgram_pair_read, + NULL, /* dgram_pair_puts */ + NULL, /* dgram_pair_gets */ + dgram_pair_ctrl, + dgram_pair_init, + dgram_pair_free, + NULL, /* dgram_pair_callback_ctrl */ + dgram_pair_sendmmsg, + dgram_pair_recvmmsg, +}; + +static const BIO_METHOD dgram_mem_method = { + BIO_TYPE_DGRAM_MEM, + "BIO dgram mem", + bwrite_conv, + dgram_pair_write, + bread_conv, + dgram_mem_read, + NULL, /* dgram_pair_puts */ + NULL, /* dgram_pair_gets */ + dgram_mem_ctrl, + dgram_mem_init, + dgram_pair_free, + NULL, /* dgram_pair_callback_ctrl */ + dgram_pair_sendmmsg, + dgram_pair_recvmmsg, +}; + +const BIO_METHOD *BIO_s_dgram_pair(void) +{ + return &dgram_pair_method; +} + +const BIO_METHOD *BIO_s_dgram_mem(void) +{ + return &dgram_mem_method; +} + +struct dgram_hdr { + size_t len; /* payload length in bytes, not including this struct */ + BIO_ADDR src_addr, dst_addr; /* family == 0: not present */ +}; + +struct bio_dgram_pair_st { + /* The other half of the BIO pair. NULL for dgram_mem. */ + BIO *peer; + /* Writes are directed to our own ringbuf and reads to our peer. */ + struct ring_buf rbuf; + /* Requested size of rbuf buffer in bytes once we initialize. */ + size_t req_buf_len; + /* Largest possible datagram size */ + size_t mtu; + /* Capability flags. */ + uint32_t cap; + /* + * This lock protects updates to our rbuf. Since writes are directed to our + * own rbuf, this means we use this lock for writes and our peer's lock for + * reads. + */ + CRYPTO_RWLOCK *lock; + unsigned int no_trunc : 1; /* Reads fail if they would truncate */ + unsigned int local_addr_enable : 1; /* Can use BIO_MSG->local? */ + unsigned int role : 1; /* Determines lock order */ + unsigned int grows_on_write : 1; /* Set for BIO_s_dgram_mem only */ +}; + +#define MIN_BUF_LEN (1024) + +#define is_dgram_pair(b) (b->peer != NULL) + +static int dgram_pair_init(BIO *bio) +{ + struct bio_dgram_pair_st *b = OPENSSL_zalloc(sizeof(*b)); + + if (b == NULL) + return 0; + + b->mtu = 1472; /* conservative default MTU */ + /* default buffer size */ + b->req_buf_len = 9 * (sizeof(struct dgram_hdr) + b->mtu); + + b->lock = CRYPTO_THREAD_lock_new(); + if (b->lock == NULL) { + OPENSSL_free(b); + return 0; + } + + bio->ptr = b; + return 1; +} + +static int dgram_mem_init(BIO *bio) +{ + struct bio_dgram_pair_st *b; + + if (!dgram_pair_init(bio)) + return 0; + + b = bio->ptr; + + if (ring_buf_init(&b->rbuf, b->req_buf_len) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); + return 0; + } + + b->grows_on_write = 1; + + bio->init = 1; + return 1; +} + +static int dgram_pair_free(BIO *bio) +{ + struct bio_dgram_pair_st *b; + + if (bio == NULL) + return 0; + + b = bio->ptr; + if (!ossl_assert(b != NULL)) + return 0; + + /* We are being freed. Disconnect any peer and destroy buffers. */ + dgram_pair_ctrl_destroy_bio_pair(bio); + + CRYPTO_THREAD_lock_free(b->lock); + OPENSSL_free(b); + return 1; +} + +/* BIO_make_bio_pair (BIO_C_MAKE_BIO_PAIR) */ +static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2) +{ + struct bio_dgram_pair_st *b1, *b2; + + /* peer must be non-NULL. */ + if (bio1 == NULL || bio2 == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return 0; + } + + /* Ensure the BIO we have been passed is actually a dgram pair BIO. */ + if (bio1->method != &dgram_pair_method || bio2->method != &dgram_pair_method) { + ERR_raise_data(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT, + "both BIOs must be BIO_dgram_pair"); + return 0; + } + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (!ossl_assert(b1 != NULL && b2 != NULL)) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + /* + * This ctrl cannot be used to associate a BIO pair half which is already + * associated. + */ + if (b1->peer != NULL || b2->peer != NULL) { + ERR_raise_data(ERR_LIB_BIO, BIO_R_IN_USE, + "cannot associate a BIO_dgram_pair which is already in use"); + return 0; + } + + if (!ossl_assert(b1->req_buf_len >= MIN_BUF_LEN + && b2->req_buf_len >= MIN_BUF_LEN)) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + + if (b1->rbuf.len != b1->req_buf_len) + if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); + return 0; + } + + if (b2->rbuf.len != b2->req_buf_len) + if (ring_buf_init(&b2->rbuf, b2->req_buf_len) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); + ring_buf_destroy(&b1->rbuf); + return 0; + } + + b1->peer = bio2; + b2->peer = bio1; + b1->role = 0; + b2->role = 1; + bio1->init = 1; + bio2->init = 1; + return 1; +} + +/* BIO_destroy_bio_pair (BIO_C_DESTROY_BIO_PAIR) */ +static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1) +{ + BIO *bio2; + struct bio_dgram_pair_st *b1 = bio1->ptr, *b2; + + ring_buf_destroy(&b1->rbuf); + bio1->init = 0; + + /* Early return if we don't have a peer. */ + if (b1->peer == NULL) + return 1; + + bio2 = b1->peer; + b2 = bio2->ptr; + + /* Invariant. */ + if (!ossl_assert(b2->peer == bio1)) + return 0; + + /* Free buffers. */ + ring_buf_destroy(&b2->rbuf); + + bio2->init = 0; + b1->peer = NULL; + b2->peer = NULL; + return 1; +} + +/* BIO_eof (BIO_CTRL_EOF) */ +static int dgram_pair_ctrl_eof(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr, *peerb; + + if (!ossl_assert(b != NULL)) + return -1; + + /* If we aren't initialized, we can never read anything */ + if (!bio->init) + return 1; + if (!is_dgram_pair(b)) + return 0; + + + peerb = b->peer->ptr; + if (!ossl_assert(peerb != NULL)) + return -1; + + /* + * Since we are emulating datagram semantics, never indicate EOF so long as + * we have a peer. + */ + return 0; +} + +/* BIO_set_write_buf_size (BIO_C_SET_WRITE_BUF_SIZE) */ +static int dgram_pair_ctrl_set_write_buf_size(BIO *bio, size_t len) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + /* Changing buffer sizes is not permitted while a peer is connected. */ + if (b->peer != NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE); + return 0; + } + + /* Enforce minimum size. */ + if (len < MIN_BUF_LEN) + len = MIN_BUF_LEN; + + if (b->rbuf.start != NULL) { + if (!ring_buf_resize(&b->rbuf, len)) + return 0; + } + + b->req_buf_len = len; + b->grows_on_write = 0; + return 1; +} + +/* BIO_reset (BIO_CTRL_RESET) */ +static int dgram_pair_ctrl_reset(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + ring_buf_clear(&b->rbuf); + return 1; +} + +/* BIO_pending (BIO_CTRL_PENDING) (Threadsafe) */ +static size_t dgram_pair_ctrl_pending(BIO *bio) +{ + size_t saved_idx, saved_count; + struct bio_dgram_pair_st *b = bio->ptr, *readb; + struct dgram_hdr hdr; + size_t l; + + /* Safe to check; init may not change during this call */ + if (!bio->init) + return 0; + if (is_dgram_pair(b)) + readb = b->peer->ptr; + else + readb = b; + + if (CRYPTO_THREAD_write_lock(readb->lock) == 0) + return 0; + + saved_idx = readb->rbuf.idx[1]; + saved_count = readb->rbuf.count; + + l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr)); + + readb->rbuf.idx[1] = saved_idx; + readb->rbuf.count = saved_count; + + CRYPTO_THREAD_unlock(readb->lock); + + if (!ossl_assert(l == 0 || l == sizeof(hdr))) + return 0; + + return l > 0 ? hdr.len : 0; +} + +/* BIO_get_write_guarantee (BIO_C_GET_WRITE_GUARANTEE) (Threadsafe) */ +static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio) +{ + size_t l; + struct bio_dgram_pair_st *b = bio->ptr; + + if (CRYPTO_THREAD_read_lock(b->lock) == 0) + return 0; + + l = b->rbuf.len - b->rbuf.count; + if (l >= sizeof(struct dgram_hdr)) + l -= sizeof(struct dgram_hdr); + + /* + * If the amount of buffer space would not be enough to accommodate the + * worst-case size of a datagram, report no space available. + */ + if (l < b->mtu) + l = 0; + + CRYPTO_THREAD_unlock(b->lock); + return l; +} + +/* BIO_dgram_get_local_addr_cap (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP) */ +static int dgram_pair_ctrl_get_local_addr_cap(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr, *readb; + + if (!bio->init) + return 0; + + if (is_dgram_pair(b)) + readb = b->peer->ptr; + else + readb = b; + + return (~readb->cap & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR + | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0; +} + +/* BIO_dgram_get_effective_caps (BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS) */ +static int dgram_pair_ctrl_get_effective_caps(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr, *peerb; + + if (b->peer == NULL) + return 0; + + peerb = b->peer->ptr; + + return peerb->cap; +} + +/* BIO_dgram_get_caps (BIO_CTRL_DGRAM_GET_CAPS) */ +static uint32_t dgram_pair_ctrl_get_caps(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + return b->cap; +} + +/* BIO_dgram_set_caps (BIO_CTRL_DGRAM_SET_CAPS) */ +static int dgram_pair_ctrl_set_caps(BIO *bio, uint32_t caps) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + b->cap = caps; + return 1; +} + +/* BIO_dgram_get_local_addr_enable (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE) */ +static int dgram_pair_ctrl_get_local_addr_enable(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + return b->local_addr_enable; +} + +/* BIO_dgram_set_local_addr_enable (BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE) */ +static int dgram_pair_ctrl_set_local_addr_enable(BIO *bio, int enable) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + if (dgram_pair_ctrl_get_local_addr_cap(bio) == 0) + return 0; + + b->local_addr_enable = (enable != 0 ? 1 : 0); + return 1; +} + +/* BIO_dgram_get_mtu (BIO_CTRL_DGRAM_GET_MTU) */ +static int dgram_pair_ctrl_get_mtu(BIO *bio) +{ + struct bio_dgram_pair_st *b = bio->ptr; + + return b->mtu; +} + +/* BIO_dgram_set_mtu (BIO_CTRL_DGRAM_SET_MTU) */ +static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu) +{ + struct bio_dgram_pair_st *b = bio->ptr, *peerb; + + b->mtu = mtu; + + if (b->peer != NULL) { + peerb = b->peer->ptr; + peerb->mtu = mtu; + } + + return 1; +} + +/* Partially threadsafe (some commands) */ +static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + struct bio_dgram_pair_st *b = bio->ptr; + + if (!ossl_assert(b != NULL)) + return 0; + + switch (cmd) { + /* + * BIO_set_write_buf_size: Set the size of the ring buffer used for storing + * datagrams. No more writes can be performed once the buffer is filled up, + * until reads are performed. This cannot be used after a peer is connected. + */ + case BIO_C_SET_WRITE_BUF_SIZE: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_set_write_buf_size(bio, (size_t)num); + break; + + /* + * BIO_get_write_buf_size: Get ring buffer size. + */ + case BIO_C_GET_WRITE_BUF_SIZE: /* Non-threadsafe */ + ret = (long)b->req_buf_len; + break; + + /* + * BIO_reset: Clear all data which was written to this side of the pair. + */ + case BIO_CTRL_RESET: /* Non-threadsafe */ + dgram_pair_ctrl_reset(bio); + break; + + /* + * BIO_get_write_guarantee: Any BIO_write providing a buffer less than or + * equal to this value is guaranteed to succeed. + */ + case BIO_C_GET_WRITE_GUARANTEE: /* Threadsafe */ + ret = (long)dgram_pair_ctrl_get_write_guarantee(bio); + break; + + /* BIO_pending: Bytes available to read. */ + case BIO_CTRL_PENDING: /* Threadsafe */ + ret = (long)dgram_pair_ctrl_pending(bio); + break; + + /* BIO_flush: No-op. */ + case BIO_CTRL_FLUSH: /* Threadsafe */ + break; + + /* BIO_dgram_get_no_trunc */ + case BIO_CTRL_DGRAM_GET_NO_TRUNC: /* Non-threadsafe */ + ret = (long)b->no_trunc; + break; + + /* BIO_dgram_set_no_trunc */ + case BIO_CTRL_DGRAM_SET_NO_TRUNC: /* Non-threadsafe */ + b->no_trunc = (num > 0); + break; + + /* BIO_dgram_get_local_addr_enable */ + case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */ + *(int *)ptr = (int)dgram_pair_ctrl_get_local_addr_enable(bio); + break; + + /* BIO_dgram_set_local_addr_enable */ + case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_set_local_addr_enable(bio, num); + break; + + /* BIO_dgram_get_local_addr_cap: Can local addresses be supported? */ + case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_get_local_addr_cap(bio); + break; + + /* BIO_dgram_get_effective_caps */ + case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */ + /* BIO_dgram_get_caps */ + case BIO_CTRL_DGRAM_GET_CAPS: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_get_caps(bio); + break; + + /* BIO_dgram_set_caps */ + case BIO_CTRL_DGRAM_SET_CAPS: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_set_caps(bio, (uint32_t)num); + break; + + /* BIO_dgram_get_mtu */ + case BIO_CTRL_DGRAM_GET_MTU: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_get_mtu(bio); + break; + + /* BIO_dgram_set_mtu */ + case BIO_CTRL_DGRAM_SET_MTU: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num); + break; + + /* + * BIO_eof: Returns whether this half of the BIO pair is empty of data to + * read. + */ + case BIO_CTRL_EOF: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_eof(bio); + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + /* + * BIO_make_bio_pair: this is usually used by BIO_new_dgram_pair, though it + * may be used manually after manually creating each half of a BIO pair + * using BIO_new. This only needs to be called on one of the BIOs. + */ + case BIO_C_MAKE_BIO_PAIR: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_make_bio_pair(bio, (BIO *)ptr); + break; + + /* + * BIO_destroy_bio_pair: Manually disconnect two halves of a BIO pair so + * that they are no longer peers. + */ + case BIO_C_DESTROY_BIO_PAIR: /* Non-threadsafe */ + dgram_pair_ctrl_destroy_bio_pair(bio); + break; + + /* BIO_dgram_get_effective_caps */ + case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */ + ret = (long)dgram_pair_ctrl_get_effective_caps(bio); + break; + + default: + ret = dgram_mem_ctrl(bio, cmd, num, ptr); + break; + } + + return ret; +} + +int BIO_new_bio_dgram_pair(BIO **pbio1, size_t writebuf1, + BIO **pbio2, size_t writebuf2) +{ + int ret = 0; + long r; + BIO *bio1 = NULL, *bio2 = NULL; + + bio1 = BIO_new(BIO_s_dgram_pair()); + if (bio1 == NULL) + goto err; + + bio2 = BIO_new(BIO_s_dgram_pair()); + if (bio2 == NULL) + goto err; + + if (writebuf1 > 0) { + r = BIO_set_write_buf_size(bio1, writebuf1); + if (r == 0) + goto err; + } + + if (writebuf2 > 0) { + r = BIO_set_write_buf_size(bio2, writebuf2); + if (r == 0) + goto err; + } + + r = BIO_make_bio_pair(bio1, bio2); + if (r == 0) + goto err; + + ret = 1; +err: + if (ret == 0) { + BIO_free(bio1); + bio1 = NULL; + BIO_free(bio2); + bio2 = NULL; + } + + *pbio1 = bio1; + *pbio2 = bio2; + return ret; +} + +/* Must hold peer write lock */ +static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, size_t sz) +{ + size_t total_read = 0; + + /* + * We repeat pops from the ring buffer for as long as we have more + * application *buffer to fill until we fail. We may not be able to pop + * enough data to fill the buffer in one operation if the ring buffer wraps + * around, but there may still be more data available. + */ + while (sz > 0) { + uint8_t *src_buf = NULL; + size_t src_len = 0; + + /* + * There are two BIO instances, each with a ringbuf. We read from the + * peer ringbuf and write to our own ringbuf. + */ + ring_buf_tail(&b->rbuf, &src_buf, &src_len); + if (src_len == 0) + break; + + if (src_len > sz) + src_len = sz; + + if (buf != NULL) + memcpy(buf, src_buf, src_len); + + ring_buf_pop(&b->rbuf, src_len); + + if (buf != NULL) + buf += src_len; + total_read += src_len; + sz -= src_len; + } + + return total_read; +} + +/* + * Must hold peer write lock. Returns number of bytes processed or negated BIO + * response code. + */ +static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, + BIO_ADDR *local, BIO_ADDR *peer, + int is_multi) +{ + size_t l, trunc = 0, saved_idx, saved_count; + struct bio_dgram_pair_st *b = bio->ptr, *readb; + struct dgram_hdr hdr; + + if (!is_multi) + BIO_clear_retry_flags(bio); + + if (!bio->init) + return -BIO_R_UNINITIALIZED; + + if (!ossl_assert(b != NULL)) + return -BIO_R_TRANSFER_ERROR; + + if (is_dgram_pair(b)) + readb = b->peer->ptr; + else + readb = b; + if (!ossl_assert(readb != NULL && readb->rbuf.start != NULL)) + return -BIO_R_TRANSFER_ERROR; + + if (sz > 0 && buf == NULL) + return -BIO_R_INVALID_ARGUMENT; + + /* If the caller wants to know the local address, it must be enabled */ + if (local != NULL && b->local_addr_enable == 0) + return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE; + + /* Read the header. */ + saved_idx = readb->rbuf.idx[1]; + saved_count = readb->rbuf.count; + l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr)); + if (l == 0) { + /* Buffer was empty. */ + if (!is_multi) + BIO_set_retry_read(bio); + return -BIO_R_NON_FATAL; + } + + if (!ossl_assert(l == sizeof(hdr))) + /* + * This should not be possible as headers (and their following payloads) + * should always be written atomically. + */ + return -BIO_R_BROKEN_PIPE; + + if (sz > hdr.len) { + sz = hdr.len; + } else if (sz < hdr.len) { + /* Truncation is occurring. */ + trunc = hdr.len - sz; + if (b->no_trunc) { + /* Restore original state. */ + readb->rbuf.idx[1] = saved_idx; + readb->rbuf.count = saved_count; + return -BIO_R_NON_FATAL; + } + } + + l = dgram_pair_read_inner(readb, (uint8_t *)buf, sz); + if (!ossl_assert(l == sz)) + /* We were somehow not able to read the entire datagram. */ + return -BIO_R_TRANSFER_ERROR; + + /* + * If the datagram was truncated due to an inadequate buffer, discard the + * remainder. + */ + if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(readb, NULL, trunc) == trunc)) + /* We were somehow not able to read/skip the entire datagram. */ + return -BIO_R_TRANSFER_ERROR; + + if (local != NULL) + *local = hdr.dst_addr; + if (peer != NULL) + *peer = hdr.src_addr; + + return (ossl_ssize_t)l; +} + +/* Threadsafe */ +static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a, + struct bio_dgram_pair_st *b) +{ + struct bio_dgram_pair_st *x, *y; + + x = (a->role == 1) ? a : b; + y = (a->role == 1) ? b : a; + + if (!ossl_assert(a->role != b->role)) + return 0; + + if (!ossl_assert(a != b && x != y)) + return 0; + + if (CRYPTO_THREAD_write_lock(x->lock) == 0) + return 0; + + if (CRYPTO_THREAD_write_lock(y->lock) == 0) { + CRYPTO_THREAD_unlock(x->lock); + return 0; + } + + return 1; +} + +static void dgram_pair_unlock_both(struct bio_dgram_pair_st *a, + struct bio_dgram_pair_st *b) +{ + CRYPTO_THREAD_unlock(a->lock); + CRYPTO_THREAD_unlock(b->lock); +} + +/* Threadsafe */ +static int dgram_pair_read(BIO *bio, char *buf, int sz_) +{ + int ret; + ossl_ssize_t l; + struct bio_dgram_pair_st *b = bio->ptr, *peerb; + + if (sz_ < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + + if (b->peer == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); + return -1; + } + + peerb = b->peer->ptr; + + /* + * For BIO_read we have to acquire both locks because we touch the retry + * flags on the local bio. (This is avoided in the recvmmsg case as it does + * not touch the retry flags.) + */ + if (dgram_pair_lock_both_write(peerb, b) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + return -1; + } + + l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0); + if (l < 0) { + if (l != -BIO_R_NON_FATAL) + ERR_raise(ERR_LIB_BIO, -l); + ret = -1; + } else { + ret = (int)l; + } + + dgram_pair_unlock_both(peerb, b); + return ret; +} + +/* Threadsafe */ +static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg, + size_t stride, size_t num_msg, + uint64_t flags, + size_t *num_processed) +{ + int ret; + ossl_ssize_t l; + BIO_MSG *m; + size_t i; + struct bio_dgram_pair_st *b = bio->ptr, *readb; + + if (num_msg == 0) { + *num_processed = 0; + return 1; + } + + if (!bio->init) { + ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); + *num_processed = 0; + return 0; + } + + if (is_dgram_pair(b)) + readb = b->peer->ptr; + else + readb = b; + + if (CRYPTO_THREAD_write_lock(readb->lock) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + *num_processed = 0; + return 0; + } + + for (i = 0; i < num_msg; ++i) { + m = &BIO_MSG_N(msg, i); + l = dgram_pair_read_actual(bio, m->data, m->data_len, + m->local, m->peer, 1); + if (l < 0) { + *num_processed = i; + if (i > 0) { + ret = 1; + } else { + ERR_raise(ERR_LIB_BIO, -l); + ret = 0; + } + goto out; + } + + m->data_len = l; + m->flags = 0; + } + + *num_processed = i; + ret = 1; +out: + CRYPTO_THREAD_unlock(readb->lock); + return ret; +} + +/* Threadsafe */ +static int dgram_mem_read(BIO *bio, char *buf, int sz_) +{ + int ret; + ossl_ssize_t l; + struct bio_dgram_pair_st *b = bio->ptr; + + if (sz_ < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + + if (CRYPTO_THREAD_write_lock(b->lock) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + return -1; + } + + l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0); + if (l < 0) { + if (l != -BIO_R_NON_FATAL) + ERR_raise(ERR_LIB_BIO, -l); + ret = -1; + } else { + ret = (int)l; + } + + CRYPTO_THREAD_unlock(b->lock); + return ret; +} + +/* + * Calculate the array growth based on the target size. + * + * The growth factor is a rational number and is defined by a numerator + * and a denominator. According to Andrew Koenig in his paper "Why Are + * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less + * than the golden ratio (1.618...). + * + * We use an expansion factor of 8 / 5 = 1.6 + */ +static const size_t max_rbuf_size = SIZE_MAX / 2; /* unlimited in practice */ +static ossl_inline size_t compute_rbuf_growth(size_t target, size_t current) +{ + int err = 0; + + while (current < target) { + if (current >= max_rbuf_size) + return 0; + + current = safe_muldiv_size_t(current, 8, 5, &err); + if (err) + return 0; + if (current >= max_rbuf_size) + current = max_rbuf_size; + } + return current; +} + +/* Must hold local write lock */ +static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b, + const uint8_t *buf, size_t sz) +{ + size_t total_written = 0; + + /* + * We repeat pushes to the ring buffer for as long as we have data until we + * fail. We may not be able to push in one operation if the ring buffer + * wraps around, but there may still be more room for data. + */ + while (sz > 0) { + size_t dst_len; + uint8_t *dst_buf; + + /* + * There are two BIO instances, each with a ringbuf. We write to our own + * ringbuf and read from the peer ringbuf. + */ + ring_buf_head(&b->rbuf, &dst_buf, &dst_len); + if (dst_len == 0) { + size_t new_len; + + if (!b->grows_on_write) /* resize only if size not set explicitly */ + break; + /* increase the size */ + new_len = compute_rbuf_growth(b->req_buf_len + sz, b->req_buf_len); + if (new_len == 0 || !ring_buf_resize(&b->rbuf, new_len)) + break; + b->req_buf_len = new_len; + } + + if (dst_len > sz) + dst_len = sz; + + memcpy(dst_buf, buf, dst_len); + ring_buf_push(&b->rbuf, dst_len); + + buf += dst_len; + sz -= dst_len; + total_written += dst_len; + } + + return total_written; +} + +/* + * Must hold local write lock. Returns number of bytes processed or negated BIO + * response code. + */ +static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz, + const BIO_ADDR *local, const BIO_ADDR *peer, + int is_multi) +{ + static const BIO_ADDR zero_addr; + size_t saved_idx, saved_count; + struct bio_dgram_pair_st *b = bio->ptr, *readb; + struct dgram_hdr hdr = {0}; + + if (!is_multi) + BIO_clear_retry_flags(bio); + + if (!bio->init) + return -BIO_R_UNINITIALIZED; + + if (!ossl_assert(b != NULL && b->rbuf.start != NULL)) + return -BIO_R_TRANSFER_ERROR; + + if (sz > 0 && buf == NULL) + return -BIO_R_INVALID_ARGUMENT; + + if (local != NULL && b->local_addr_enable == 0) + return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE; + + if (is_dgram_pair(b)) + readb = b->peer->ptr; + else + readb = b; + if (peer != NULL && (readb->cap & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0) + return -BIO_R_PEER_ADDR_NOT_AVAILABLE; + + hdr.len = sz; + hdr.dst_addr = (peer != NULL ? *peer : zero_addr); + hdr.src_addr = (local != NULL ? *local : zero_addr); + + saved_idx = b->rbuf.idx[0]; + saved_count = b->rbuf.count; + if (dgram_pair_write_inner(b, (const uint8_t *)&hdr, sizeof(hdr)) != sizeof(hdr) + || dgram_pair_write_inner(b, (const uint8_t *)buf, sz) != sz) { + /* + * We were not able to push the header and the entirety of the payload + * onto the ring buffer, so abort and roll back the ring buffer state. + */ + b->rbuf.idx[0] = saved_idx; + b->rbuf.count = saved_count; + if (!is_multi) + BIO_set_retry_write(bio); + return -BIO_R_NON_FATAL; + } + + return sz; +} + +/* Threadsafe */ +static int dgram_pair_write(BIO *bio, const char *buf, int sz_) +{ + int ret; + ossl_ssize_t l; + struct bio_dgram_pair_st *b = bio->ptr; + + if (sz_ < 0) { + ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); + return -1; + } + + if (CRYPTO_THREAD_write_lock(b->lock) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + return -1; + } + + l = dgram_pair_write_actual(bio, buf, (size_t)sz_, NULL, NULL, 0); + if (l < 0) { + ERR_raise(ERR_LIB_BIO, -l); + ret = -1; + } else { + ret = (int)l; + } + + CRYPTO_THREAD_unlock(b->lock); + return ret; +} + +/* Threadsafe */ +static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg, + size_t stride, size_t num_msg, + uint64_t flags, size_t *num_processed) +{ + ossl_ssize_t ret, l; + BIO_MSG *m; + size_t i; + struct bio_dgram_pair_st *b = bio->ptr; + + if (num_msg == 0) { + *num_processed = 0; + return 1; + } + + if (CRYPTO_THREAD_write_lock(b->lock) == 0) { + ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + *num_processed = 0; + return 0; + } + + for (i = 0; i < num_msg; ++i) { + m = &BIO_MSG_N(msg, i); + l = dgram_pair_write_actual(bio, m->data, m->data_len, + m->local, m->peer, 1); + if (l < 0) { + *num_processed = i; + if (i > 0) { + ret = 1; + } else { + ERR_raise(ERR_LIB_BIO, -l); + ret = 0; + } + goto out; + } + + m->flags = 0; + } + + *num_processed = i; + ret = 1; +out: + CRYPTO_THREAD_unlock(b->lock); + return ret; +} + +#endif diff --git a/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c index b830f3cbf6..41514589a5 100644 --- a/crypto/bio/bss_fd.c +++ b/crypto/bio/bss_fd.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index 5b10b22ade..05d87cfe90 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c index 82abfd5cec..c22e603b04 100644 --- a/crypto/bio/bss_log.c +++ b/crypto/bio/bss_log.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,6 +24,8 @@ #if defined(OPENSSL_SYS_WINCE) #elif defined(OPENSSL_SYS_WIN32) +#elif defined(__wasi__) +# define NO_SYSLOG #elif defined(OPENSSL_SYS_VMS) # include # include @@ -197,10 +199,8 @@ static int slg_write(BIO *b, const char *in, int inl) if (inl < 0) return 0; - if ((buf = OPENSSL_malloc(inl + 1)) == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(inl + 1)) == NULL) return 0; - } memcpy(buf, in, inl); buf[inl] = '\0'; diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c index 9153c1f1cd..6deacba42d 100644 --- a/crypto/bio/bss_mem.c +++ b/crypto/bio/bss_mem.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index f5d8810230..82f7be85ae 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,7 @@ #include #include #include "bio_local.h" +#include "internal/bio_tfo.h" #include "internal/cryptlib.h" #include "internal/ktls.h" @@ -27,6 +28,14 @@ # define sock_puts SockPuts # endif +struct bss_sock_st { + BIO_ADDR tfo_peer; + int tfo_first; +#ifndef OPENSSL_NO_KTLS + unsigned char ktls_record_type; +#endif +}; + static int sock_write(BIO *h, const char *buf, int num); static int sock_read(BIO *h, char *buf, int size); static int sock_puts(BIO *h, const char *str); @@ -81,8 +90,10 @@ static int sock_new(BIO *bi) { bi->init = 0; bi->num = 0; - bi->ptr = NULL; bi->flags = 0; + bi->ptr = OPENSSL_zalloc(sizeof(struct bss_sock_st)); + if (bi->ptr == NULL) + return 0; return 1; } @@ -97,6 +108,8 @@ static int sock_free(BIO *a) a->init = 0; a->flags = 0; } + OPENSSL_free(a->ptr); + a->ptr = NULL; return 1; } @@ -126,17 +139,30 @@ static int sock_read(BIO *b, char *out, int outl) static int sock_write(BIO *b, const char *in, int inl) { int ret = 0; +# if !defined(OPENSSL_NO_KTLS) || defined(OSSL_TFO_SENDTO) + struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; +# endif clear_socket_error(); # ifndef OPENSSL_NO_KTLS if (BIO_should_ktls_ctrl_msg_flag(b)) { - unsigned char record_type = (intptr_t)b->ptr; + unsigned char record_type = data->ktls_record_type; ret = ktls_send_ctrl_message(b->num, record_type, in, inl); if (ret >= 0) { ret = inl; BIO_clear_ktls_ctrl_msg_flag(b); } } else +# endif +# if defined(OSSL_TFO_SENDTO) + if (data->tfo_first) { + struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; + socklen_t peerlen = BIO_ADDR_sockaddr_size(&data->tfo_peer); + + ret = sendto(b->num, in, inl, OSSL_TFO_SENDTO, + BIO_ADDR_sockaddr(&data->tfo_peer), peerlen); + data->tfo_first = 0; + } else # endif ret = writesocket(b->num, in, inl); BIO_clear_retry_flags(b); @@ -151,16 +177,24 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; + struct bss_sock_st *data = (struct bss_sock_st *)b->ptr; # ifndef OPENSSL_NO_KTLS ktls_crypto_info_t *crypto_info; # endif switch (cmd) { case BIO_C_SET_FD: - sock_free(b); + /* minimal sock_free() */ + if (b->shutdown) { + if (b->init) + BIO_closesocket(b->num); + b->flags = 0; + } b->num = *((int *)ptr); b->shutdown = (int)num; b->init = 1; + data->tfo_first = 0; + memset(&data->tfo_peer, 0, sizeof(data->tfo_peer)); break; case BIO_C_GET_FD: if (b->init) { @@ -181,6 +215,20 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: ret = 1; break; + case BIO_CTRL_GET_RPOLL_DESCRIPTOR: + case BIO_CTRL_GET_WPOLL_DESCRIPTOR: + { + BIO_POLL_DESCRIPTOR *pd = ptr; + + if (!b->init) { + ret = 0; + break; + } + + pd->type = BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; + pd->value.fd = b->num; + } + break; # ifndef OPENSSL_NO_KTLS case BIO_CTRL_SET_KTLS: crypto_info = (ktls_crypto_info_t *)ptr; @@ -194,17 +242,41 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) return BIO_should_ktls_flag(b, 0) != 0; case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG: BIO_set_ktls_ctrl_msg_flag(b); - b->ptr = (void *)num; + data->ktls_record_type = (unsigned char)num; ret = 0; break; case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG: BIO_clear_ktls_ctrl_msg_flag(b); ret = 0; break; + case BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE: + ret = ktls_enable_tx_zerocopy_sendfile(b->num); + if (ret) + BIO_set_ktls_zerocopy_sendfile_flag(b); + break; # endif case BIO_CTRL_EOF: ret = (b->flags & BIO_FLAGS_IN_EOF) != 0; break; + case BIO_C_GET_CONNECT: + if (ptr != NULL && num == 2) { + const char **pptr = (const char **)ptr; + + *pptr = (const char *)&data->tfo_peer; + } else { + ret = 0; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL && num == 2) { + ret = BIO_ADDR_make(&data->tfo_peer, + BIO_ADDR_sockaddr((const BIO_ADDR *)ptr)); + if (ret) + data->tfo_first = 1; + } else { + ret = 0; + } + break; default: ret = 0; break; diff --git a/crypto/bio/build.info b/crypto/bio/build.info index b203ed5e63..2102038c74 100644 --- a/crypto/bio/build.info +++ b/crypto/bio/build.info @@ -11,7 +11,7 @@ SOURCE[../../libcrypto]=\ SOURCE[../../libcrypto]=\ bss_null.c bss_mem.c bss_bio.c bss_fd.c bss_file.c \ bss_sock.c bss_conn.c bss_acpt.c bss_dgram.c \ - bss_log.c bss_core.c + bss_log.c bss_core.c bss_dgram_pair.c # Filters SOURCE[../../libcrypto]=\ diff --git a/crypto/bio/ossl_core_bio.c b/crypto/bio/ossl_core_bio.c index 328302ea34..8d21115b65 100644 --- a/crypto/bio/ossl_core_bio.c +++ b/crypto/bio/ossl_core_bio.c @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,7 +17,6 @@ */ struct ossl_core_bio_st { CRYPTO_REF_COUNT ref_cnt; - CRYPTO_RWLOCK *ref_lock; BIO *bio; }; @@ -25,11 +24,10 @@ static OSSL_CORE_BIO *core_bio_new(void) { OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb)); - if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) { + if (cb == NULL || !CRYPTO_NEW_REF(&cb->ref_cnt, 1)) { OPENSSL_free(cb); return NULL; } - cb->ref_cnt = 1; return cb; } @@ -37,7 +35,7 @@ int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb) { int ref = 0; - return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock); + return CRYPTO_UP_REF(&cb->ref_cnt, &ref); } int ossl_core_bio_free(OSSL_CORE_BIO *cb) @@ -45,10 +43,10 @@ int ossl_core_bio_free(OSSL_CORE_BIO *cb) int ref = 0, res = 1; if (cb != NULL) { - CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock); + CRYPTO_DOWN_REF(&cb->ref_cnt, &ref); if (ref <= 0) { res = BIO_free(cb->bio); - CRYPTO_THREAD_lock_free(cb->ref_lock); + CRYPTO_FREE_REF(&cb->ref_cnt); OPENSSL_free(cb); } } diff --git a/crypto/bn/asm/armv8-mont.pl b/crypto/bn/asm/armv8-mont.pl index 93cd45cd37..21ab12bdf0 100755 --- a/crypto/bn/asm/armv8-mont.pl +++ b/crypto/bn/asm/armv8-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/mips.pl b/crypto/bn/asm/mips.pl index bc18826d08..91b7aac6e7 100644 --- a/crypto/bn/asm/mips.pl +++ b/crypto/bn/asm/mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/rsaz-2k-avx512.pl b/crypto/bn/asm/rsaz-2k-avx512.pl index 87e44e0d5c..7ee02778df 100644 --- a/crypto/bn/asm/rsaz-2k-avx512.pl +++ b/crypto/bn/asm/rsaz-2k-avx512.pl @@ -58,7 +58,7 @@ # clang 7.0.0 is Apple clang 10.0.1 $avx512ifma = ($ver>=10.0001) } else { - $avx512ifma = ($3>=7.0); + $avx512ifma = ($ver>=7.0); } } diff --git a/crypto/bn/asm/sparcv8.S b/crypto/bn/asm/sparcv8.S index 9448700844..e5402cc4e2 100644 --- a/crypto/bn/asm/sparcv8.S +++ b/crypto/bn/asm/sparcv8.S @@ -381,7 +381,7 @@ bn_add_words: inc 16,%o1 addxcc %g3,%g4,%g3 st %g3,[%o0+4] - + ld [%o1-4],%g3 ld [%o2+12],%g4 inc 16,%o2 @@ -469,7 +469,7 @@ bn_sub_words: inc 16,%o1 subxcc %g3,%g4,%g4 st %g4,[%o0+4] - + ld [%o1-4],%g3 ld [%o2+12],%g4 inc 16,%o2 @@ -1040,7 +1040,7 @@ bn_mul_comba4: addxcc c_2,t_2,c_2 != st c_1,rp(6) !r[6]=c1; st c_2,rp(7) !r[7]=c2; - + ret restore %g0,%g0,%o0 @@ -1448,7 +1448,7 @@ bn_sqr_comba4: addxcc c_2,t_2,c_2 != st c_1,rp(6) !r[6]=c1; st c_2,rp(7) !r[7]=c2; - + ret restore %g0,%g0,%o0 diff --git a/crypto/bn/asm/sparcv8plus.S b/crypto/bn/asm/sparcv8plus.S index 696dc7b5fe..8a936f1c72 100644 --- a/crypto/bn/asm/sparcv8plus.S +++ b/crypto/bn/asm/sparcv8plus.S @@ -496,7 +496,7 @@ bn_add_words: inc 16,%o1 addccc %g1,%g2,%g1 stuw %g1,[%o0+4] - + inc 16,%o2 addccc %g3,%g4,%g3 stuw %g3,[%o0+8] @@ -1126,7 +1126,7 @@ bn_mul_comba4: srlx t_1,32,c_12 != stuw t_1,rp(6) !r[6]=c1; stuw c_12,rp(7) !r[7]=c2; - + ret restore %g0,%g0,%o0 @@ -1548,7 +1548,7 @@ bn_sqr_comba4: srlx t_1,32,c_12 stuw t_1,rp(6) !r[6]=c1; stuw c_12,rp(7) !r[7]=c2; - + ret restore %g0,%g0,%o0 diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index 185d9e76ce..1faea0bcf8 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index 7e5a1c52e2..6c6de1a30f 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -33,14 +33,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) bn_check_top(mod); - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_CRYPTO_LIB); OPENSSL_free(ret); return NULL; } diff --git a/crypto/bn/bn_const.c b/crypto/bn/bn_const.c index 96ad0268be..190a363912 100644 --- a/crypto/bn/bn_const.c +++ b/crypto/bn/bn_const.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_conv.c b/crypto/bn/bn_conv.c index 75054f5d6a..849440e71e 100644 --- a/crypto/bn/bn_conv.c +++ b/crypto/bn/bn_conv.c @@ -23,10 +23,8 @@ char *BN_bn2hex(const BIGNUM *a) if (BN_is_zero(a)) return OPENSSL_strdup("0"); buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); - if (buf == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto err; - } p = buf; if (a->neg) *p++ = '-'; @@ -70,10 +68,8 @@ char *BN_bn2dec(const BIGNUM *a) bn_data_num = num / BN_DEC_NUM + 1; bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); buf = OPENSSL_malloc(tbytes); - if (buf == NULL || bn_data == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (buf == NULL || bn_data == NULL) goto err; - } if ((t = BN_dup(a)) == NULL) goto err; diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c index 35a7ddbab7..aa70ca7a3f 100644 --- a/crypto/bn/bn_ctx.c +++ b/crypto/bn/bn_ctx.c @@ -119,10 +119,8 @@ BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx) { BN_CTX *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } /* Initialise the structure */ BN_POOL_init(&ret->pool); BN_STACK_init(&ret->stack); @@ -268,10 +266,8 @@ static int BN_STACK_push(BN_STACK *st, unsigned int idx) st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES; unsigned int *newitems; - if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((newitems = OPENSSL_malloc(sizeof(*newitems) * newsize)) == NULL) return 0; - } if (st->depth) memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth); OPENSSL_free(st->indexes); @@ -322,10 +318,8 @@ static BIGNUM *BN_POOL_get(BN_POOL *p, int flag) if (p->used == p->size) { BN_POOL_ITEM *item; - if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) return NULL; - } for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) { bn_init(bn); if ((flag & BN_FLG_SECURE) != 0) diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 4d02dcda53..b876edbfac 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -169,7 +169,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { - int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int i, j, bits, ret = 0, wstart, wend, window; int start = 1; BIGNUM *aa; /* Table of variables obtained from 'ctx' */ @@ -239,14 +239,23 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, start = 1; /* This is used to avoid multiplication etc * when there is only the value '1' in the * buffer. */ - wvalue = 0; /* The 'value' of the window */ wstart = bits - 1; /* The top bit of the window */ wend = 0; /* The bottom bit of the window */ + if (r == p) { + BIGNUM *p_dup = BN_CTX_get(ctx); + + if (p_dup == NULL || BN_copy(p_dup, p) == NULL) + goto err; + p = p_dup; + } + if (!BN_one(r)) goto err; for (;;) { + int wvalue; /* The 'value' of the window */ + if (BN_is_bit_set(p, wstart) == 0) { if (!start) if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) @@ -288,7 +297,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* move the 'window' down further */ wstart -= wend + 1; - wvalue = 0; start = 0; if (wstart < 0) break; @@ -304,7 +312,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) { - int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int i, j, bits, ret = 0, wstart, wend, window; int start = 1; BIGNUM *d, *r; const BIGNUM *aa; @@ -384,7 +392,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, start = 1; /* This is used to avoid multiplication etc * when there is only the value '1' in the * buffer. */ - wvalue = 0; /* The 'value' of the window */ wstart = bits - 1; /* The top bit of the window */ wend = 0; /* The bottom bit of the window */ @@ -404,6 +411,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx)) goto err; for (;;) { + int wvalue; /* The 'value' of the window */ + if (BN_is_bit_set(p, wstart) == 0) { if (!start) { if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) @@ -446,7 +455,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, /* move the 'window' down further */ wstart -= wend + 1; - wvalue = 0; start = 0; if (wstart < 0) break; @@ -1303,7 +1311,7 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { - int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int i, j, bits, ret = 0, wstart, wend, window; int start = 1; BIGNUM *d; /* Table of variables obtained from 'ctx' */ @@ -1317,6 +1325,11 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, return 0; } + if (r == m) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + bits = BN_num_bits(p); if (bits == 0) { /* x**0 mod 1, or x**0 mod -1 is still zero. */ @@ -1358,14 +1371,23 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, start = 1; /* This is used to avoid multiplication etc * when there is only the value '1' in the * buffer. */ - wvalue = 0; /* The 'value' of the window */ wstart = bits - 1; /* The top bit of the window */ wend = 0; /* The bottom bit of the window */ + if (r == p) { + BIGNUM *p_dup = BN_CTX_get(ctx); + + if (p_dup == NULL || BN_copy(p_dup, p) == NULL) + goto err; + p = p_dup; + } + if (!BN_one(r)) goto err; for (;;) { + int wvalue; /* The 'value' of the window */ + if (BN_is_bit_set(p, wstart) == 0) { if (!start) if (!BN_mod_mul(r, r, r, m, ctx)) @@ -1407,7 +1429,6 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* move the 'window' down further */ wstart -= wend + 1; - wvalue = 0; start = 0; if (wstart < 0) break; diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c index 879a84b8ae..7303d3b959 100644 --- a/crypto/bn/bn_gcd.c +++ b/crypto/bn/bn_gcd.c @@ -522,7 +522,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, if (ctx == NULL) { ctx = new_ctx = BN_CTX_new_ex(NULL); if (ctx == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB); return NULL; } } diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c index 304c2ea08d..83e1f11e18 100644 --- a/crypto/bn/bn_gf2m.c +++ b/crypto/bn/bn_gf2m.c @@ -474,10 +474,8 @@ int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, bn_check_top(p); arr = OPENSSL_malloc(sizeof(*arr) * max); - if (arr == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (arr == NULL) return 0; - } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); @@ -536,10 +534,8 @@ int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) bn_check_top(p); arr = OPENSSL_malloc(sizeof(*arr) * max); - if (arr == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (arr == NULL) return 0; - } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); @@ -915,10 +911,8 @@ int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, bn_check_top(p); arr = OPENSSL_malloc(sizeof(*arr) * max); - if (arr == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (arr == NULL) return 0; - } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); @@ -979,10 +973,8 @@ int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) bn_check_top(p); arr = OPENSSL_malloc(sizeof(*arr) * max); - if (arr == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (arr == NULL) return 0; - } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); @@ -1115,10 +1107,8 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, bn_check_top(p); arr = OPENSSL_malloc(sizeof(*arr) * max); - if (arr == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (arr == NULL) goto err; - } ret = BN_GF2m_poly2arr(p, arr, max); if (!ret || ret > max) { ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); diff --git a/crypto/bn/bn_intern.c b/crypto/bn/bn_intern.c index c0f7f5fea6..505a9dfcc3 100644 --- a/crypto/bn/bn_intern.c +++ b/crypto/bn/bn_intern.c @@ -29,10 +29,8 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) if (BN_is_zero(scalar)) { r = OPENSSL_malloc(1); - if (r == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (r == NULL) goto err; - } r[0] = 0; *ret_len = 1; return r; @@ -62,10 +60,8 @@ signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) * (*ret_len will be set to the actual length, i.e. at most * BN_num_bits(scalar) + 1) */ - if (r == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (r == NULL) goto err; - } window_val = scalar->d[0] & mask; j = 0; while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, @@ -188,7 +184,7 @@ void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size) int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words) { if (bn_wexpand(a, num_words) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB); return 0; } diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index 75d73e4885..9070647b35 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -244,10 +244,8 @@ BIGNUM *BN_new(void) { BIGNUM *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } ret->flags = BN_FLG_MALLOCED; bn_check_top(ret); return ret; @@ -279,10 +277,8 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) a = OPENSSL_secure_zalloc(words * sizeof(*a)); else a = OPENSSL_zalloc(words * sizeof(*a)); - if (a == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (a == NULL) return NULL; - } assert(b->top <= words); if (b->top > 0) @@ -430,42 +426,102 @@ int BN_set_word(BIGNUM *a, BN_ULONG w) return 1; } -BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +typedef enum {BIG, LITTLE} endianness_t; +typedef enum {SIGNED, UNSIGNED} signedness_t; + +static BIGNUM *bin2bn(const unsigned char *s, int len, BIGNUM *ret, + endianness_t endianness, signedness_t signedness) { - unsigned int i, m; + int inc; + const unsigned char *s2; + int inc2; + int neg = 0, xor = 0, carry = 0; + unsigned int i; unsigned int n; - BN_ULONG l; BIGNUM *bn = NULL; + /* Negative length is not acceptable */ + if (len < 0) + return NULL; + if (ret == NULL) ret = bn = BN_new(); if (ret == NULL) return NULL; bn_check_top(ret); - /* Skip leading zero's. */ - for ( ; len > 0 && *s == 0; s++, len--) + + /* + * If the input has no bits, the number is considered zero. + * This makes calls with s==NULL and len==0 safe. + */ + if (len == 0) { + BN_clear(ret); + return ret; + } + + /* + * The loop that does the work iterates from least to most + * significant BIGNUM chunk, so we adapt parameters to transfer + * input bytes accordingly. + */ + if (endianness == LITTLE) { + s2 = s + len - 1; + inc2 = -1; + inc = 1; + } else { + s2 = s; + inc2 = 1; + inc = -1; + s += len - 1; + } + + /* Take note of the signedness of the input bytes*/ + if (signedness == SIGNED) { + neg = !!(*s2 & 0x80); + xor = neg ? 0xff : 0x00; + carry = neg; + } + + /* + * Skip leading sign extensions (the value of |xor|). + * This is the only spot where |s2| and |inc2| are used. + */ + for ( ; len > 0 && *s2 == xor; s2 += inc2, len--) continue; - n = len; - if (n == 0) { + + /* + * If there was a set of 0xff, we backtrack one byte unless the next + * one has a sign bit, as the last 0xff is then part of the actual + * number, rather then a mere sign extension. + */ + if (xor == 0xff) { + if (len == 0 || !(*s2 & 0x80)) + len++; + } + /* If it was all zeros, we're done */ + if (len == 0) { ret->top = 0; return ret; } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (bn_wexpand(ret, (int)i) == NULL) { + n = ((len - 1) / BN_BYTES) + 1; /* Number of resulting bignum chunks */ + if (bn_wexpand(ret, (int)n) == NULL) { BN_free(bn); return NULL; } - ret->top = i; - ret->neg = 0; - l = 0; - while (n--) { - l = (l << 8L) | *(s++); - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; + ret->top = n; + ret->neg = neg; + for (i = 0; n-- > 0; i++) { + BN_ULONG l = 0; /* Accumulator */ + unsigned int m = 0; /* Offset in a bignum chunk, in bits */ + + for (; len > 0 && m < BN_BYTES * 8; len--, s += inc, m += 8) { + BN_ULONG byte_xored = *s ^ xor; + BN_ULONG byte = (byte_xored + carry) & 0xff; + + carry = byte_xored > byte; /* Implicit 1 or 0 */ + l |= (byte << m); } + ret->d[i] = l; } /* * need to call this due to clear byte at top if avoiding having the top @@ -475,30 +531,58 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) return ret; } -typedef enum {big, little} endianess_t; +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + return bin2bn(s, len, ret, BIG, UNSIGNED); +} + +BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + return bin2bn(s, len, ret, BIG, SIGNED); +} -/* ignore negative */ -static -int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endianess) +static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, + endianness_t endianness, signedness_t signedness) { - int n; + int inc; + int n, n8; + int xor = 0, carry = 0, ext = 0; size_t i, lasti, j, atop, mask; BN_ULONG l; /* - * In case |a| is fixed-top, BN_num_bytes can return bogus length, + * In case |a| is fixed-top, BN_num_bits can return bogus length, * but it's assumed that fixed-top inputs ought to be "nominated" * even for padded output, so it works out... */ - n = BN_num_bytes(a); + n8 = BN_num_bits(a); + n = (n8 + 7) / 8; /* This is what BN_num_bytes() does */ + + /* Take note of the signedness of the bignum */ + if (signedness == SIGNED) { + xor = a->neg ? 0xff : 0x00; + carry = a->neg; + + /* + * if |n * 8 == n|, then the MSbit is set, otherwise unset. + * We must compensate with one extra byte if that doesn't + * correspond to the signedness of the bignum with regards + * to 2's complement. + */ + ext = (n * 8 == n8) + ? !a->neg /* MSbit set on nonnegative bignum */ + : a->neg; /* MSbit unset on negative bignum */ + } + if (tolen == -1) { - tolen = n; - } else if (tolen < n) { /* uncommon/unlike case */ + tolen = n + ext; + } else if (tolen < n + ext) { /* uncommon/unlike case */ BIGNUM temp = *a; bn_correct_top(&temp); - n = BN_num_bytes(&temp); - if (tolen < n) + n8 = BN_num_bits(&temp); + n = (n8 + 7) / 8; /* This is what BN_num_bytes() does */ + if (tolen < n + ext) return -1; } @@ -510,19 +594,30 @@ int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianess_t endiane return tolen; } + /* + * The loop that does the work iterates from least significant + * to most significant BIGNUM limb, so we adapt parameters to + * transfer output bytes accordingly. + */ + if (endianness == LITTLE) { + inc = 1; + } else { + inc = -1; + to += tolen - 1; /* Move to the last byte, not beyond */ + } + lasti = atop - 1; atop = a->top * BN_BYTES; - if (endianess == big) - to += tolen; /* start from the end of the buffer */ for (i = 0, j = 0; j < (size_t)tolen; j++) { - unsigned char val; + unsigned char byte, byte_xored; + l = a->d[i / BN_BYTES]; mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); - val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); - if (endianess == big) - *--to = val; - else - *to++ = val; + byte = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + byte_xored = byte ^ xor; + *to = (unsigned char)(byte_xored + carry); + carry = byte_xored > *to; /* Implicit 1 or 0 */ + to += inc; i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ } @@ -533,66 +628,43 @@ int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) { if (tolen < 0) return -1; - return bn2binpad(a, to, tolen, big); + return bn2binpad(a, to, tolen, BIG, UNSIGNED); +} + +int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen) +{ + if (tolen < 0) + return -1; + return bn2binpad(a, to, tolen, BIG, SIGNED); } int BN_bn2bin(const BIGNUM *a, unsigned char *to) { - return bn2binpad(a, to, -1, big); + return bn2binpad(a, to, -1, BIG, UNSIGNED); } BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) { - unsigned int i, m; - unsigned int n; - BN_ULONG l; - BIGNUM *bn = NULL; + return bin2bn(s, len, ret, LITTLE, UNSIGNED); +} - if (ret == NULL) - ret = bn = BN_new(); - if (ret == NULL) - return NULL; - bn_check_top(ret); - s += len; - /* Skip trailing zeroes. */ - for ( ; len > 0 && s[-1] == 0; s--, len--) - continue; - n = len; - if (n == 0) { - ret->top = 0; - return ret; - } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (bn_wexpand(ret, (int)i) == NULL) { - BN_free(bn); - return NULL; - } - ret->top = i; - ret->neg = 0; - l = 0; - while (n--) { - s--; - l = (l << 8L) | *s; - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; - } - } - /* - * need to call this due to clear byte at top if avoiding having the top - * bit set (-ve number) - */ - bn_correct_top(ret); - return ret; +BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + return bin2bn(s, len, ret, LITTLE, SIGNED); } int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) { if (tolen < 0) return -1; - return bn2binpad(a, to, tolen, little); + return bn2binpad(a, to, tolen, LITTLE, UNSIGNED); +} + +int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) +{ + if (tolen < 0) + return -1; + return bn2binpad(a, to, tolen, LITTLE, SIGNED); } BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret) @@ -604,6 +676,15 @@ BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret) return BN_bin2bn(s, len, ret); } +BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + return BN_signed_lebin2bn(s, len, ret); + return BN_signed_bin2bn(s, len, ret); +} + int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen) { DECLARE_IS_ENDIAN; @@ -613,6 +694,15 @@ int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen) return BN_bn2binpad(a, to, tolen); } +int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen) +{ + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) + return BN_signed_bn2lebin(a, to, tolen); + return BN_signed_bn2bin(a, to, tolen); +} + int BN_ucmp(const BIGNUM *a, const BIGNUM *b) { int i; @@ -963,10 +1053,8 @@ BN_GENCB *BN_GENCB_new(void) { BN_GENCB *ret; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) return NULL; - } return ret; } diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h index 50e9d26e21..b5be37ba97 100644 --- a/crypto/bn/bn_local.h +++ b/crypto/bn/bn_local.h @@ -243,8 +243,11 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); struct bignum_st { - BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit - * chunks. */ + BN_ULONG *d; /* + * Pointer to an array of 'BN_BITS2' bit + * chunks. These chunks are organised in + * a least significant chunk first order. + */ int top; /* Index of last used d +1. */ /* The next are internal book keeping for bn_expand. */ int dmax; /* Size of the d array. */ diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c index 7f5afa25ec..ce58d5501a 100644 --- a/crypto/bn/bn_mod.c +++ b/crypto/bn/bn_mod.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,11 @@ int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) * always holds) */ + if (r == d) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (!(BN_mod(r, m, d, ctx))) return 0; if (!r->neg) @@ -58,10 +63,8 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (mtop > sizeof(storage) / sizeof(storage[0])) { tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG)); - if (tp == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (tp == NULL) return 0; - } } ap = a->d != NULL ? a->d : tp; @@ -186,6 +189,11 @@ int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) { + if (r == m) { + ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (!BN_sub(r, a, b)) return 0; if (r->neg) diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c index 1c5d66bbf8..8b4c7900ad 100644 --- a/crypto/bn/bn_mont.c +++ b/crypto/bn/bn_mont.c @@ -229,10 +229,8 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) { BN_MONT_CTX *ret; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) return NULL; - } BN_MONT_CTX_init(ret); ret->flags = BN_FLG_MALLOCED; diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c index 0d4a0a232b..c3864b8c69 100644 --- a/crypto/bn/bn_mul.c +++ b/crypto/bn/bn_mul.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index 3d4d9a2fb2..c1dbed0598 100644 --- a/crypto/bn/bn_nist.c +++ b/crypto/bn/bn_nist.c @@ -251,7 +251,7 @@ const BIGNUM *BN_get0_nist_prime_521(void) /* * To avoid more recent compilers (specifically clang-14) from treating this - * code as a violation of the strict aliasing conditions and omiting it, this + * code as a violation of the strict aliasing conditions and omitting it, this * cannot be declared as a function. Moreover, the dst parameter cannot be * cached in a local since this no longer references the union and again falls * foul of the strict aliasing criteria. Refer to #18225 for the initial diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index 79776f1ce5..96eb1b3c34 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -145,10 +145,8 @@ int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe, } mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES); - if (mods == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (mods == NULL) return 0; - } BN_CTX_start(ctx); t = BN_CTX_get(ctx); diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index 2ca426ff76..a94dfcecdf 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -41,10 +41,8 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom, mask = 0xff << (bit + 1); buf = OPENSSL_malloc(bytes); - if (buf == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto err; - } /* make a random number and set the top and bottom bits */ b = flag == NORMAL ? RAND_bytes_ex(libctx, buf, bytes, strength) diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c index 3a2c812ac6..83fd175c43 100644 --- a/crypto/bn/bn_recp.c +++ b/crypto/bn/bn_recp.c @@ -21,10 +21,8 @@ BN_RECP_CTX *BN_RECP_CTX_new(void) { BN_RECP_CTX *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } bn_init(&(ret->N)); bn_init(&(ret->Nr)); diff --git a/crypto/bn/bn_rsa_fips186_4.c b/crypto/bn/bn_rsa_fips186_4.c index c3466dfc39..c967ca9629 100644 --- a/crypto/bn/bn_rsa_fips186_4.c +++ b/crypto/bn/bn_rsa_fips186_4.c @@ -143,7 +143,7 @@ static int bn_rsa_fips186_4_find_aux_prob_prime(const BIGNUM *Xp1, BN_set_flags(p1, BN_FLG_CONSTTIME); /* Find the first odd number >= Xp1 that is probably prime */ - for(;;) { + for (;;) { i++; BN_GENCB_call(cb, 0, i); /* MR test with trial division */ diff --git a/crypto/bn/bn_s390x.c b/crypto/bn/bn_s390x.c new file mode 100644 index 0000000000..5449143f4f --- /dev/null +++ b/crypto/bn/bn_s390x.c @@ -0,0 +1,143 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "crypto/bn.h" +#include "crypto/s390x_arch.h" + +#ifdef S390X_MOD_EXP + +# include +# include +# include +# include +# include +# include +# include + +static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m) +{ + struct ica_rsa_modexpo me; + unsigned char *buffer; + size_t size; + int res = 0; + + if (OPENSSL_s390xcex == -1) + return 0; + size = BN_num_bytes(m); + buffer = OPENSSL_zalloc(4 * size); + if (buffer == NULL) + return 0; + me.inputdata = buffer; + me.inputdatalength = size; + me.outputdata = buffer + size; + me.outputdatalength = size; + me.b_key = buffer + 2 * size; + me.n_modulus = buffer + 3 * size; + if (BN_bn2binpad(a, me.inputdata, size) == -1 + || BN_bn2binpad(p, me.b_key, size) == -1 + || BN_bn2binpad(m, me.n_modulus, size) == -1) + goto dealloc; + if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) != -1) { + if (BN_bin2bn(me.outputdata, size, r) != NULL) + res = 1; + } else if (errno == EBADF) { + /*- + * In this cases, someone (e.g. a sandbox) closed the fd. + * Make sure to not further use this hardware acceleration. + */ + OPENSSL_s390xcex = -1; + } + dealloc: + OPENSSL_clear_free(buffer, 4 * size); + return res; +} + +int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + if (s390x_mod_exp_hw(r, a, p, m) == 1) + return 1; + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q, + const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp) +{ + struct ica_rsa_modexpo_crt crt; + unsigned char *buffer, *part; + size_t size, plen, qlen; + int res = 0; + + if (OPENSSL_s390xcex == -1) + return 0; + /*- + * Hardware-accelerated CRT can only deal with p>q. Fall back to + * software in the (hopefully rare) other cases. + */ + if (BN_ucmp(p, q) != 1) + return 0; + plen = BN_num_bytes(p); + qlen = BN_num_bytes(q); + size = (plen > qlen ? plen : qlen); + buffer = OPENSSL_zalloc(9 * size + 24); + if (buffer == NULL) + return 0; + part = buffer; + crt.inputdata = part; + crt.inputdatalength = 2 * size; + part += 2 * size; + crt.outputdata = part; + crt.outputdatalength = 2 * size; + part += 2 * size; + crt.bp_key = part; + part += size + 8; + crt.bq_key = part; + part += size; + crt.np_prime = part; + part += size + 8; + crt.nq_prime = part; + part += size; + crt.u_mult_inv = part; + if (BN_bn2binpad(i, crt.inputdata, crt.inputdatalength) == -1 + || BN_bn2binpad(p, crt.np_prime, size + 8) == -1 + || BN_bn2binpad(q, crt.nq_prime, size) == -1 + || BN_bn2binpad(dmp, crt.bp_key, size + 8) == -1 + || BN_bn2binpad(dmq, crt.bq_key, size) == -1 + || BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1) + goto dealloc; + if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) { + if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL) + res = 1; + } else if (errno == EBADF) { + /*- + * In this cases, someone (e.g. a sandbox) closed the fd. + * Make sure to not further use this hardware acceleration. + */ + OPENSSL_s390xcex = -1; + } + dealloc: + OPENSSL_clear_free(buffer, 9 * size + 24); + return res; +} + +#else +int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q, + const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp) +{ + return 0; +} + +#endif diff --git a/crypto/bn/build.info b/crypto/bn/build.info index cbf80ce6ca..2f30681b3b 100644 --- a/crypto/bn/build.info +++ b/crypto/bn/build.info @@ -58,7 +58,7 @@ IF[{- !$disabled{asm} -}] IF[{- ($target{perlasm_scheme} // '') eq '31' -}] $BNASM_s390x=bn_asm.c s390x-mont.S ELSE - $BNASM_s390x=asm/s390x.S s390x-mont.S + $BNASM_s390x=asm/s390x.S s390x-mont.S bn_s390x.c ENDIF $BNDEF_s390x=OPENSSL_BN_ASM_MONT $BNASM_s390x_ec2m=s390x-gf2m.s diff --git a/crypto/bn/rsaz_exp.c b/crypto/bn/rsaz_exp.c index 2a1ff09eef..80b583f35a 100644 --- a/crypto/bn/rsaz_exp.c +++ b/crypto/bn/rsaz_exp.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2012, Intel Corporation. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -13,6 +13,7 @@ */ #include +#include "internal/common.h" #include "rsaz_exp.h" #ifndef RSAZ_ENABLED @@ -31,16 +32,8 @@ void rsaz_1024_scatter5_avx2(void *tbl, const void *val, int i); void rsaz_1024_gather5_avx2(void *val, const void *tbl, int i); void rsaz_1024_red2norm_avx2(void *norm, const void *red); -#if defined(__GNUC__) -# define ALIGN64 __attribute__((aligned(64))) -#elif defined(_MSC_VER) -# define ALIGN64 __declspec(align(64)) -#elif defined(__SUNPRO_C) -# define ALIGN64 +#if defined(__SUNPRO_C) # pragma align 64(one,two80) -#else -/* not fatal, might hurt performance a little */ -# define ALIGN64 #endif ALIGN64 static const BN_ULONG one[40] = { diff --git a/crypto/bn/rsaz_exp.h b/crypto/bn/rsaz_exp.h index e27e9f0471..45dc9cc197 100644 --- a/crypto/bn/rsaz_exp.h +++ b/crypto/bn/rsaz_exp.h @@ -1,5 +1,5 @@ /* - * Copyright 2013-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2020, Intel Corporation. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/rsaz_exp_x2.c b/crypto/bn/rsaz_exp_x2.c index e458b856b5..70705486a1 100644 --- a/crypto/bn/rsaz_exp_x2.c +++ b/crypto/bn/rsaz_exp_x2.c @@ -254,6 +254,7 @@ int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1, bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, factor_size); bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, factor_size); + err: if (storage != NULL) { OPENSSL_cleanse(storage, storage_len_bytes); @@ -402,11 +403,10 @@ int RSAZ_mod_exp_x2_ifma256(BN_ULONG *out, /* Exponentiation */ { - int rem = modulus_bitsize % exp_win_size; - int delta = rem ? rem : exp_win_size; - BN_ULONG table_idx_mask = exp_win_mask; + const int rem = modulus_bitsize % exp_win_size; + const BN_ULONG table_idx_mask = exp_win_mask; - int exp_bit_no = modulus_bitsize - delta; + int exp_bit_no = modulus_bitsize - rem; int exp_chunk_no = exp_bit_no / 64; int exp_chunk_shift = exp_bit_no % 64; @@ -425,6 +425,7 @@ int RSAZ_mod_exp_x2_ifma256(BN_ULONG *out, /* Process 1-st exp window - just init result */ red_table_idx_0 = expz[exp_chunk_no + 0 * (exp_digits + 1)]; red_table_idx_1 = expz[exp_chunk_no + 1 * (exp_digits + 1)]; + /* * The function operates with fixed moduli sizes divisible by 64, * thus table index here is always in supported range [0, EXP_WIN_SIZE). diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c index db1ea38b19..3394342986 100644 --- a/crypto/buffer/buffer.c +++ b/crypto/buffer/buffer.c @@ -33,10 +33,8 @@ BUF_MEM *BUF_MEM_new(void) BUF_MEM *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } return ret; } @@ -87,7 +85,7 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len) } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } n = (len + 3) / 3 * 4; @@ -96,7 +94,6 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len) else ret = OPENSSL_realloc(str->data, n); if (ret == NULL) { - ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); len = 0; } else { str->data = ret; @@ -125,7 +122,7 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len) } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BUF, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } n = (len + 3) / 3 * 4; @@ -134,7 +131,6 @@ size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len) else ret = OPENSSL_clear_realloc(str->data, str->max, n); if (ret == NULL) { - ERR_raise(ERR_LIB_BUF, ERR_R_MALLOC_FAILURE); len = 0; } else { str->data = ret; diff --git a/crypto/build.info b/crypto/build.info index aafa2197a1..2d5b22fcff 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -6,7 +6,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ - ffc + ffc hpke thread LIBS=../libcrypto @@ -99,13 +99,15 @@ $UTIL_COMMON=\ cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \ threads_pthread.c threads_win.c threads_none.c initthread.c \ context.c sparse_array.c asn1_dsa.c packet.c param_build.c \ - param_build_set.c der_writer.c threads_lib.c params_dup.c + param_build_set.c der_writer.c threads_lib.c params_dup.c \ + time.c params_idx.c SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \ - punycode.c passphrase.c + punycode.c passphrase.c sleep.c deterministic_nonce.c quic_vlint.c \ + time.c SOURCE[../providers/libfips.a]=$UTIL_COMMON SOURCE[../libcrypto]=$UPLINKSRC diff --git a/crypto/buildinf.h b/crypto/buildinf.h index 6fc575949e..ad1a834b25 100644 --- a/crypto/buildinf.h +++ b/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-armv4" -#define DATE "built on: Thu Nov 9 15:26:10 2023 UTC" +#define DATE "built on: Tue Nov 28 09:20:18 2023 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/crypto/chacha/asm/chacha-loongarch64.pl b/crypto/chacha/asm/chacha-loongarch64.pl new file mode 100644 index 0000000000..ea9cc7ecce --- /dev/null +++ b/crypto/chacha/asm/chacha-loongarch64.pl @@ -0,0 +1,1413 @@ +#! /usr/bin/env perl +# Author: Min Zhou +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; + +my $code; + +# Here is the scalar register layout for LoongArch. +my ($zero,$ra,$tp,$sp,$fp)=map("\$r$_",(0..3,22)); +my ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$r$_",(4..11)); +my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$x)=map("\$r$_",(12..21)); +my ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8)=map("\$r$_",(23..31)); + +# Here is the 128-bit vector register layout for LSX extension. +my ($vr0,$vr1,$vr2,$vr3,$vr4,$vr5,$vr6,$vr7,$vr8,$vr9,$vr10, + $vr11,$vr12,$vr13,$vr14,$vr15,$vr16,$vr17,$vr18,$vr19, + $vr20,$vr21,$vr22,$vr23,$vr24,$vr25,$vr26,$vr27,$vr28, + $vr29,$vr30,$vr31)=map("\$vr$_",(0..31)); + +# Here is the 256-bit vector register layout for LASX extension. +my ($xr0,$xr1,$xr2,$xr3,$xr4,$xr5,$xr6,$xr7,$xr8,$xr9,$xr10, + $xr11,$xr12,$xr13,$xr14,$xr15,$xr16,$xr17,$xr18,$xr19, + $xr20,$xr21,$xr22,$xr23,$xr24,$xr25,$xr26,$xr27,$xr28, + $xr29,$xr30,$xr31)=map("\$xr$_",(0..31)); + +my $output; +for (@ARGV) { $output=$_ if (/\w[\w\-]*\.\w+$/); } +open STDOUT,">$output"; + +# Input parameter block +my ($out, $inp, $len, $key, $counter) = ($a0, $a1, $a2, $a3, $a4); + +$code .= < #include +#define LOCAL_BUF_SIZE 2048 struct CMAC_CTX_st { /* Cipher context to use */ EVP_CIPHER_CTX *cctx; @@ -53,10 +54,8 @@ CMAC_CTX *CMAC_CTX_new(void) { CMAC_CTX *ctx; - if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_malloc(sizeof(*ctx))) == NULL) return NULL; - } ctx->cctx = EVP_CIPHER_CTX_new(); if (ctx->cctx == NULL) { OPENSSL_free(ctx); @@ -164,6 +163,8 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; int bl; + size_t max_burst_blocks, cipher_blocks; + unsigned char buf[LOCAL_BUF_SIZE]; if (ctx->nlast_block == -1) return 0; @@ -190,11 +191,35 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) return 0; } /* Encrypt all but one of the complete blocks left */ - while (dlen > (size_t)bl) { - if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0) - return 0; - dlen -= bl; - data += bl; + + max_burst_blocks = LOCAL_BUF_SIZE / bl; + cipher_blocks = (dlen - 1) / bl; + if (max_burst_blocks == 0) { + /* + * When block length is greater than local buffer size, + * use ctx->tbl as cipher output. + */ + while (dlen > (size_t)bl) { + if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0) + return 0; + dlen -= bl; + data += bl; + } + } else { + while (cipher_blocks > max_burst_blocks) { + if (EVP_Cipher(ctx->cctx, buf, data, max_burst_blocks * bl) <= 0) + return 0; + dlen -= max_burst_blocks * bl; + data += max_burst_blocks * bl; + cipher_blocks -= max_burst_blocks; + } + if (cipher_blocks > 0) { + if (EVP_Cipher(ctx->cctx, buf, data, cipher_blocks * bl) <= 0) + return 0; + dlen -= cipher_blocks * bl; + data += cipher_blocks * bl; + memcpy(ctx->tbl, &buf[(cipher_blocks - 1) * bl], bl); + } } /* Copy any data left to last block buffer */ memcpy(ctx->last_block, data, dlen); diff --git a/crypto/cmp/build.info b/crypto/cmp/build.info index a2a57c14ec..907d78d25f 100644 --- a/crypto/cmp/build.info +++ b/crypto/cmp/build.info @@ -1,4 +1,11 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \ +$OPENSSLSRC=\ + cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \ cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \ - cmp_server.c cmp_client.c cmp_http.c + cmp_server.c cmp_client.c cmp_genm.c + +IF[{- !$disabled{'http'} -}] + $OPENSSLSRC=$OPENSSLSRC cmp_http.c +ENDIF + +SOURCE[../../libcrypto]=$OPENSSLSRC diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index a8de73ad97..0133dc5f80 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -28,7 +28,6 @@ ASN1_SEQUENCE(OSSL_CMP_REVANNCONTENT) = { } ASN1_SEQUENCE_END(OSSL_CMP_REVANNCONTENT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVANNCONTENT) - ASN1_SEQUENCE(OSSL_CMP_CHALLENGE) = { ASN1_OPT(OSSL_CMP_CHALLENGE, owf, X509_ALGOR), ASN1_SIMPLE(OSSL_CMP_CHALLENGE, witness, ASN1_OCTET_STRING), @@ -36,19 +35,16 @@ ASN1_SEQUENCE(OSSL_CMP_CHALLENGE) = { } ASN1_SEQUENCE_END(OSSL_CMP_CHALLENGE) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CHALLENGE) - ASN1_ITEM_TEMPLATE(OSSL_CMP_POPODECKEYCHALLCONTENT) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_POPODECKEYCHALLCONTENT, OSSL_CMP_CHALLENGE) ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POPODECKEYCHALLCONTENT) - ASN1_ITEM_TEMPLATE(OSSL_CMP_POPODECKEYRESPCONTENT) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_POPODECKEYRESPCONTENT, ASN1_INTEGER) ASN1_ITEM_TEMPLATE_END(OSSL_CMP_POPODECKEYRESPCONTENT) - ASN1_SEQUENCE(OSSL_CMP_CAKEYUPDANNCONTENT) = { /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ ASN1_SIMPLE(OSSL_CMP_CAKEYUPDANNCONTENT, oldWithNew, X509), @@ -59,7 +55,6 @@ ASN1_SEQUENCE(OSSL_CMP_CAKEYUPDANNCONTENT) = { } ASN1_SEQUENCE_END(OSSL_CMP_CAKEYUPDANNCONTENT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) - ASN1_SEQUENCE(OSSL_CMP_ERRORMSGCONTENT) = { ASN1_SIMPLE(OSSL_CMP_ERRORMSGCONTENT, pKIStatusInfo, OSSL_CMP_PKISI), ASN1_OPT(OSSL_CMP_ERRORMSGCONTENT, errorCode, ASN1_INTEGER), @@ -119,10 +114,16 @@ ASN1_ADB(OSSL_CMP_ITAV) = { ADB_ENTRY(NID_id_it_suppLangTags, ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.suppLangTagsValue, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_it_caCerts, + ASN1_SEQUENCE_OF_OPT(OSSL_CMP_ITAV, infoValue.caCerts, X509)), + ADB_ENTRY(NID_id_it_rootCaCert, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaCert, X509)), + ADB_ENTRY(NID_id_it_rootCaKeyUpdate, + ASN1_OPT(OSSL_CMP_ITAV, infoValue.rootCaKeyUpdate, + OSSL_CMP_ROOTCAKEYUPDATE)), } ASN1_ADB_END(OSSL_CMP_ITAV, 0, infoType, 0, &infotypeandvalue_default_tt, NULL); - ASN1_SEQUENCE(OSSL_CMP_ITAV) = { ASN1_SIMPLE(OSSL_CMP_ITAV, infoType, ASN1_OBJECT), ASN1_ADB_OBJECT(OSSL_CMP_ITAV) @@ -130,6 +131,14 @@ ASN1_SEQUENCE(OSSL_CMP_ITAV) = { IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ITAV) IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) +ASN1_SEQUENCE(OSSL_CMP_ROOTCAKEYUPDATE) = { + /* OSSL_CMP_CMPCERTIFICATE is effectively X509 so it is used directly */ + ASN1_SIMPLE(OSSL_CMP_ROOTCAKEYUPDATE, newWithNew, X509), + ASN1_EXP_OPT(OSSL_CMP_ROOTCAKEYUPDATE, newWithOld, X509, 0), + ASN1_EXP_OPT(OSSL_CMP_ROOTCAKEYUPDATE, oldWithNew, X509, 1) +} ASN1_SEQUENCE_END(OSSL_CMP_ROOTCAKEYUPDATE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE) + OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value) { OSSL_CMP_ITAV *itav; @@ -188,6 +197,115 @@ int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, return 0; } +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts) +{ + OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new(); + + if (itav == NULL) + return NULL; + if (sk_X509_num(caCerts) > 0 + && (itav->infoValue.caCerts = + sk_X509_deep_copy(caCerts, X509_dup, X509_free)) == NULL) { + OSSL_CMP_ITAV_free(itav); + return NULL; + } + itav->infoType = OBJ_nid2obj(NID_id_it_caCerts); + return itav; +} + +int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out) +{ + if (itav == NULL || out == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_caCerts) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *out = sk_X509_num(itav->infoValue.caCerts) > 0 + ? itav->infoValue.caCerts : NULL; + return 1; +} + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaCert(const X509 *rootCaCert) +{ + OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_new(); + + if (itav == NULL) + return NULL; + if (rootCaCert != NULL + && (itav->infoValue.rootCaCert = X509_dup(rootCaCert)) == NULL) { + OSSL_CMP_ITAV_free(itav); + return NULL; + } + itav->infoType = OBJ_nid2obj(NID_id_it_rootCaCert); + return itav; +} + +int OSSL_CMP_ITAV_get0_rootCaCert(const OSSL_CMP_ITAV *itav, X509 **out) +{ + if (itav == NULL || out == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_rootCaCert) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *out = itav->infoValue.rootCaCert; + return 1; +} +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, + const X509 *newWithOld, + const X509 *oldWithNew) +{ + OSSL_CMP_ITAV *itav; + OSSL_CMP_ROOTCAKEYUPDATE *upd = OSSL_CMP_ROOTCAKEYUPDATE_new(); + + if (upd == NULL) + return NULL; + if (newWithNew != NULL && (upd->newWithNew = X509_dup(newWithNew)) == NULL) + goto err; + if (newWithOld != NULL && (upd->newWithOld = X509_dup(newWithOld)) == NULL) + goto err; + if (oldWithNew != NULL && (upd->oldWithNew = X509_dup(oldWithNew)) == NULL) + goto err; + if ((itav = OSSL_CMP_ITAV_new()) == NULL) + goto err; + itav->infoType = OBJ_nid2obj(NID_id_it_rootCaKeyUpdate); + itav->infoValue.rootCaKeyUpdate = upd; + return itav; + + err: + OSSL_CMP_ROOTCAKEYUPDATE_free(upd); + return NULL; +} + +int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, + X509 **newWithNew, + X509 **newWithOld, + X509 **oldWithNew) +{ + OSSL_CMP_ROOTCAKEYUPDATE *upd; + + if (itav == NULL || newWithNew == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (OBJ_obj2nid(itav->infoType) != NID_id_it_rootCaKeyUpdate) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + upd = itav->infoValue.rootCaKeyUpdate; + *newWithNew = upd->newWithNew; + if (newWithOld != NULL) + *newWithOld = upd->newWithOld; + if (oldWithNew != NULL) + *oldWithNew = upd->oldWithNew; + return 1; +} + /* get ASN.1 encoded integer, return -2 on error; -1 is valid for certReqId */ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a) { @@ -255,7 +373,6 @@ ASN1_CHOICE(OSSL_CMP_CERTORENCCERT) = { } ASN1_CHOICE_END(OSSL_CMP_CERTORENCCERT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTORENCCERT) - ASN1_SEQUENCE(OSSL_CMP_CERTIFIEDKEYPAIR) = { ASN1_SIMPLE(OSSL_CMP_CERTIFIEDKEYPAIR, certOrEncCert, OSSL_CMP_CERTORENCCERT), @@ -266,20 +383,17 @@ ASN1_SEQUENCE(OSSL_CMP_CERTIFIEDKEYPAIR) = { } ASN1_SEQUENCE_END(OSSL_CMP_CERTIFIEDKEYPAIR) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTIFIEDKEYPAIR) - ASN1_SEQUENCE(OSSL_CMP_REVDETAILS) = { ASN1_SIMPLE(OSSL_CMP_REVDETAILS, certDetails, OSSL_CRMF_CERTTEMPLATE), ASN1_OPT(OSSL_CMP_REVDETAILS, crlEntryDetails, X509_EXTENSIONS) } ASN1_SEQUENCE_END(OSSL_CMP_REVDETAILS) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS) - ASN1_ITEM_TEMPLATE(OSSL_CMP_REVREQCONTENT) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, OSSL_CMP_REVREQCONTENT, OSSL_CMP_REVDETAILS) ASN1_ITEM_TEMPLATE_END(OSSL_CMP_REVREQCONTENT) - ASN1_SEQUENCE(OSSL_CMP_REVREPCONTENT) = { ASN1_SEQUENCE_OF(OSSL_CMP_REVREPCONTENT, status, OSSL_CMP_PKISI), ASN1_EXP_SEQUENCE_OF_OPT(OSSL_CMP_REVREPCONTENT, revCerts, OSSL_CRMF_CERTID, @@ -288,7 +402,6 @@ ASN1_SEQUENCE(OSSL_CMP_REVREPCONTENT) = { } ASN1_SEQUENCE_END(OSSL_CMP_REVREPCONTENT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_REVREPCONTENT) - ASN1_SEQUENCE(OSSL_CMP_KEYRECREPCONTENT) = { ASN1_SIMPLE(OSSL_CMP_KEYRECREPCONTENT, status, OSSL_CMP_PKISI), ASN1_EXP_OPT(OSSL_CMP_KEYRECREPCONTENT, newSigCert, X509, 0), @@ -298,7 +411,6 @@ ASN1_SEQUENCE(OSSL_CMP_KEYRECREPCONTENT) = { } ASN1_SEQUENCE_END(OSSL_CMP_KEYRECREPCONTENT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_KEYRECREPCONTENT) - ASN1_ITEM_TEMPLATE(OSSL_CMP_PKISTATUS) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_UNIVERSAL, 0, status, ASN1_INTEGER) ASN1_ITEM_TEMPLATE_END(OSSL_CMP_PKISTATUS) @@ -321,7 +433,8 @@ IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI) ASN1_SEQUENCE(OSSL_CMP_CERTSTATUS) = { ASN1_SIMPLE(OSSL_CMP_CERTSTATUS, certHash, ASN1_OCTET_STRING), ASN1_SIMPLE(OSSL_CMP_CERTSTATUS, certReqId, ASN1_INTEGER), - ASN1_OPT(OSSL_CMP_CERTSTATUS, statusInfo, OSSL_CMP_PKISI) + ASN1_OPT(OSSL_CMP_CERTSTATUS, statusInfo, OSSL_CMP_PKISI), + ASN1_EXP_OPT(OSSL_CMP_CERTSTATUS, hashAlg, X509_ALGOR, 0) } ASN1_SEQUENCE_END(OSSL_CMP_CERTSTATUS) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS) diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c index a6b641521a..b5b0557b0d 100644 --- a/crypto/cmp/cmp_client.c +++ b/crypto/cmp/cmp_client.c @@ -11,7 +11,6 @@ #include "cmp_local.h" #include "internal/cryptlib.h" -#include "internal/e_os.h" /* ossl_sleep() */ /* explicit #includes not strictly needed since implied by the above: */ #include @@ -32,7 +31,7 @@ static int unprotected_exception(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *rep, int invalid_protection, - int expected_type /* ignored here */) + ossl_unused int expected_type) { int rcvd_type = OSSL_CMP_MSG_get_bodytype(rep /* may be NULL */); const char *msg_type = NULL; @@ -135,8 +134,10 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, int time_left; OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb; +#ifndef OPENSSL_NO_HTTP if (transfer_cb == NULL) transfer_cb = OSSL_CMP_MSG_http_perform; +#endif *rep = NULL; if (ctx->total_timeout != 0 /* not waiting indefinitely */) { @@ -328,7 +329,7 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, OSSL_CMP_MSG_free(prep); prep = NULL; if (sleep) { - ossl_sleep((unsigned long)(1000 * check_after)); + OSSL_sleep((unsigned long)(1000 * check_after)); } else { if (checkAfter != NULL) *checkAfter = (int)check_after; @@ -487,6 +488,7 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, { X509_STORE *out_trusted = OSSL_CMP_CTX_get_certConf_cb_arg(ctx); STACK_OF(X509) *chain = NULL; + (void)text; /* make (artificial) use of var to prevent compiler warning */ if (fail_info != 0) /* accept any error flagged by CMP core library */ @@ -541,7 +543,7 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, "success building approximate chain for newly enrolled cert"); } (void)ossl_cmp_ctx_set1_newChain(ctx, chain); - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); return fail_info; } @@ -556,7 +558,8 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, */ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, OSSL_CMP_MSG **resp, int *checkAfter, - int req_type, int expected_type) + ossl_unused int req_type, + ossl_unused int expected_type) { EVP_PKEY *rkey = ossl_cmp_ctx_get0_newPubkey(ctx); int fail_info = 0; /* no failure */ @@ -646,6 +649,10 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, if (fail_info != 0) /* immediately log error before any certConf exchange */ ossl_cmp_log1(ERROR, ctx, "rejecting newly enrolled cert with subject: %s", subj); + /* + * certConf exchange should better be moved to do_certreq_seq() such that + * also more low-level errors with CertReqMessages get reported to server + */ if (!ctx->disableConfirm && !ossl_cmp_hdr_has_implicitConfirm((*resp)->header)) { if (!ossl_cmp_exchange_certConf(ctx, rid, fail_info, txt)) @@ -729,7 +736,6 @@ int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, const OSSL_CRMF_MSG *crm) { - OSSL_CMP_MSG *rep = NULL; int is_p10 = req_type == OSSL_CMP_PKIBODY_P10CR; int rid = is_p10 ? OSSL_CMP_CERTREQID_NONE : OSSL_CMP_CERTREQID; @@ -770,7 +776,8 @@ int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx) return 0; } ctx->status = OSSL_CMP_PKISTATUS_request; - if (ctx->oldCert == NULL && ctx->p10CSR == NULL) { + if (ctx->oldCert == NULL && ctx->p10CSR == NULL + && (ctx->serialNumber == NULL || ctx->issuer == NULL)) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT); return 0; } @@ -837,7 +844,8 @@ int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx) OSSL_CRMF_CERTTEMPLATE *tmpl = sk_OSSL_CMP_REVDETAILS_value(rr->body->value.rr, rsid)->certDetails; const X509_NAME *issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl); - const ASN1_INTEGER *serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl); + const ASN1_INTEGER *serial = + OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl); if (sk_OSSL_CRMF_CERTID_num(rrep->revCerts) != num_RevDetails) { ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT); diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index c5424557e5..947d2ceb8f 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -20,16 +20,35 @@ #include #include +#define DEFINE_OSSL_CMP_CTX_get0(FIELD, TYPE) \ + DEFINE_OSSL_CMP_CTX_get0_NAME(FIELD, FIELD, TYPE) +#define DEFINE_OSSL_CMP_CTX_get0_NAME(NAME, FIELD, TYPE) \ +TYPE *OSSL_CMP_CTX_get0_##NAME(const OSSL_CMP_CTX *ctx) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return NULL; \ + } \ + return ctx->FIELD; \ +} + /* * Get current certificate store containing trusted root CA certs */ -X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->trusted; +DEFINE_OSSL_CMP_CTX_get0_NAME(trusted, trusted, X509_STORE) + +#define DEFINE_OSSL_set0(PREFIX, FIELD, TYPE) \ + DEFINE_OSSL_set0_NAME(PREFIX, FIELD, FIELD, TYPE) +#define DEFINE_OSSL_set0_NAME(PREFIX, NAME, FIELD, TYPE) \ +int PREFIX##_set0##_##NAME(OSSL_CMP_CTX *ctx, TYPE *val) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + TYPE##_free(ctx->FIELD); \ + ctx->FIELD = val; \ + return 1; \ } /* @@ -37,26 +56,13 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx) * and a cert verification callback function used for CMP server authentication. * Any already existing store entry is freed. Given NULL, the entry is reset. */ -int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - X509_STORE_free(ctx->trusted); - ctx->trusted = store; - return 1; -} +DEFINE_OSSL_set0_NAME(OSSL_CMP_CTX, trusted, trusted, X509_STORE) + +DEFINE_OSSL_CMP_CTX_get0(libctx, OSSL_LIB_CTX) +DEFINE_OSSL_CMP_CTX_get0(propq, const char) /* Get current list of non-trusted intermediate certs */ -STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->untrusted; -} +DEFINE_OSSL_CMP_CTX_get0(untrusted, STACK_OF(X509)) /* * Set untrusted certificates for path construction in authentication of @@ -73,11 +79,11 @@ int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) if (!ossl_x509_add_certs_new(&untrusted, certs, X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) goto err; - sk_X509_pop_free(ctx->untrusted, X509_free); + OSSL_STACK_OF_X509_free(ctx->untrusted); ctx->untrusted = untrusted; return 1; err: - sk_X509_pop_free(untrusted, X509_free); + OSSL_STACK_OF_X509_free(untrusted); return 0; } @@ -108,7 +114,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) ctx->libctx = libctx; if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) - goto oom; + goto err; ctx->log_verbosity = OSSL_CMP_LOG_INFO; @@ -117,9 +123,12 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) ctx->keep_alive = 1; ctx->msg_timeout = -1; + ctx->tls_used = -1; /* default for backward compatibility */ - if ((ctx->untrusted = sk_X509_new_null()) == NULL) - goto oom; + if ((ctx->untrusted = sk_X509_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); + goto err; + } ctx->pbm_slen = 16; if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256)) @@ -135,8 +144,6 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) /* all other elements are initialized to 0 or NULL, respectively */ return ctx; - oom: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); err: OSSL_CMP_CTX_free(ctx); return NULL; @@ -157,11 +164,13 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) return 0; } +#ifndef OPENSSL_NO_HTTP if (ctx->http_ctx != NULL) { (void)OSSL_HTTP_close(ctx->http_ctx, 1); ossl_cmp_debug(ctx, "disconnected from CMP server"); ctx->http_ctx = NULL; } +#endif ctx->status = OSSL_CMP_PKISTATUS_unspecified; ctx->failInfoCode = -1; @@ -173,7 +182,7 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) && ossl_cmp_ctx_set1_newChain(ctx, NULL) && ossl_cmp_ctx_set1_caPubs(ctx, NULL) && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL) - && ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL) + && ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL) && OSSL_CMP_CTX_set1_transactionID(ctx, NULL) && OSSL_CMP_CTX_set1_senderNonce(ctx, NULL) && ossl_cmp_ctx_set1_recipNonce(ctx, NULL); @@ -185,10 +194,12 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) if (ctx == NULL) return; +#ifndef OPENSSL_NO_HTTP if (ctx->http_ctx != NULL) { (void)OSSL_HTTP_close(ctx->http_ctx, 1); ossl_cmp_debug(ctx, "disconnected from CMP server"); } +#endif OPENSSL_free(ctx->propq); OPENSSL_free(ctx->serverPath); OPENSSL_free(ctx->server); @@ -199,10 +210,10 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) X509_free(ctx->validatedSrvCert); X509_NAME_free(ctx->expected_sender); X509_STORE_free(ctx->trusted); - sk_X509_pop_free(ctx->untrusted, X509_free); + OSSL_STACK_OF_X509_free(ctx->untrusted); X509_free(ctx->cert); - sk_X509_pop_free(ctx->chain, X509_free); + OSSL_STACK_OF_X509_free(ctx->chain); EVP_PKEY_free(ctx->pkey); ASN1_OCTET_STRING_free(ctx->referenceValue); if (ctx->secretValue != NULL) @@ -215,120 +226,82 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) ASN1_OCTET_STRING_free(ctx->transactionID); ASN1_OCTET_STRING_free(ctx->senderNonce); ASN1_OCTET_STRING_free(ctx->recipNonce); - sk_OSSL_CMP_ITAV_pop_free(ctx->geninfo_ITAVs, OSSL_CMP_ITAV_free); - sk_X509_pop_free(ctx->extraCertsOut, X509_free); + OSSL_CMP_ITAVs_free(ctx->geninfo_ITAVs); + OSSL_STACK_OF_X509_free(ctx->extraCertsOut); EVP_PKEY_free(ctx->newPkey); X509_NAME_free(ctx->issuer); + ASN1_INTEGER_free(ctx->serialNumber); X509_NAME_free(ctx->subjectName); sk_GENERAL_NAME_pop_free(ctx->subjectAltNames, GENERAL_NAME_free); - sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free); + X509_EXTENSIONS_free(ctx->reqExtensions); sk_POLICYINFO_pop_free(ctx->policies, POLICYINFO_free); X509_free(ctx->oldCert); X509_REQ_free(ctx->p10CSR); - sk_OSSL_CMP_ITAV_pop_free(ctx->genm_ITAVs, OSSL_CMP_ITAV_free); + OSSL_CMP_ITAVs_free(ctx->genm_ITAVs); - sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free); + OSSL_CMP_PKIFREETEXT_free(ctx->statusString); X509_free(ctx->newCert); - sk_X509_pop_free(ctx->newChain, X509_free); - sk_X509_pop_free(ctx->caPubs, X509_free); - sk_X509_pop_free(ctx->extraCertsIn, X509_free); + OSSL_STACK_OF_X509_free(ctx->newChain); + OSSL_STACK_OF_X509_free(ctx->caPubs); + OSSL_STACK_OF_X509_free(ctx->extraCertsIn); OPENSSL_free(ctx); } -int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - ctx->status = status; - return 1; +#define DEFINE_OSSL_set(PREFIX, FIELD, TYPE) \ +int PREFIX##_set_##FIELD(OSSL_CMP_CTX *ctx, TYPE val) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + ctx->FIELD = val; \ + return 1; \ +} + +DEFINE_OSSL_set(ossl_cmp_ctx, status, int) + +#define DEFINE_OSSL_get(PREFIX, FIELD, TYPE, ERR_RET) \ +TYPE PREFIX##_get_##FIELD(const OSSL_CMP_CTX *ctx) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return ERR_RET; \ + } \ + return ctx->FIELD; \ } /* * Returns the PKIStatus from the last CertRepMessage * or Revocation Response or error message, -1 on error */ -int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return -1; - } - return ctx->status; -} +DEFINE_OSSL_get(OSSL_CMP_CTX, status, int, -1) /* * Returns the statusString from the last CertRepMessage * or Revocation Response or error message, NULL on error */ -OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->statusString; -} +DEFINE_OSSL_CMP_CTX_get0(statusString, OSSL_CMP_PKIFREETEXT) -int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, - OSSL_CMP_PKIFREETEXT *text) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free); - ctx->statusString = text; - return 1; -} - -int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - X509_free(ctx->validatedSrvCert); - ctx->validatedSrvCert = cert; - return 1; -} +DEFINE_OSSL_set0(ossl_cmp_ctx, statusString, OSSL_CMP_PKIFREETEXT) /* Set callback function for checking if the cert is ok or should be rejected */ -int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->certConf_cb = cb; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, certConf_cb, OSSL_CMP_certConf_cb_t) /* * Set argument, respectively a pointer to a structure containing arguments, * optionally to be used by the certConf callback. */ -int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->certConf_cb_arg = arg; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, certConf_cb_arg, void *) /* * Get argument, respectively the pointer to a structure containing arguments, * optionally to be used by certConf callback. * Returns callback argument set previously (NULL if not set or on error) */ -void *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->certConf_cb_arg; -} +DEFINE_OSSL_get(OSSL_CMP_CTX, certConf_cb_arg, void *, NULL) #ifndef OPENSSL_NO_TRACE static size_t ossl_cmp_log_trace_cb(const char *buf, size_t cnt, @@ -452,8 +425,8 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return 0; } - return ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref, - len); + return + ossl_cmp_asn1_octet_string_set1_bytes(&ctx->referenceValue, ref, len); } /* Set or clear the password to be used for protecting messages with PBMAC */ @@ -461,6 +434,7 @@ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, int len) { ASN1_OCTET_STRING *secretValue = NULL; + if (ctx == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return 0; @@ -475,74 +449,51 @@ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, return 1; } +#define DEFINE_OSSL_CMP_CTX_get1_certs(FIELD) \ +STACK_OF(X509) *OSSL_CMP_CTX_get1_##FIELD(const OSSL_CMP_CTX *ctx) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return NULL; \ + } \ + return X509_chain_up_ref(ctx->FIELD); \ +} + /* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */ -STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return X509_chain_up_ref(ctx->newChain); +DEFINE_OSSL_CMP_CTX_get1_certs(newChain) + +#define DEFINE_OSSL_set1_certs(PREFIX, FIELD) \ +int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + OSSL_STACK_OF_X509_free(ctx->FIELD); \ + ctx->FIELD = NULL; \ + return certs == NULL || (ctx->FIELD = X509_chain_up_ref(certs)) != NULL; \ } /* * Copies any given stack of inbound X509 certificates to newChain * of the OSSL_CMP_CTX structure so that they may be retrieved later. */ -int ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - - sk_X509_pop_free(ctx->newChain, X509_free); - ctx->newChain = NULL; - return newChain == NULL || - (ctx->newChain = X509_chain_up_ref(newChain)) != NULL; -} +DEFINE_OSSL_set1_certs(ossl_cmp_ctx, newChain) /* Returns the stack of extraCerts received in CertRepMessage, NULL on error */ -STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return X509_chain_up_ref(ctx->extraCertsIn); -} +DEFINE_OSSL_CMP_CTX_get1_certs(extraCertsIn) /* * Copies any given stack of inbound X509 certificates to extraCertsIn * of the OSSL_CMP_CTX structure so that they may be retrieved later. */ -int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, - STACK_OF(X509) *extraCertsIn) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - - sk_X509_pop_free(ctx->extraCertsIn, X509_free); - ctx->extraCertsIn = NULL; - return extraCertsIn == NULL - || (ctx->extraCertsIn = X509_chain_up_ref(extraCertsIn)) != NULL; -} +DEFINE_OSSL_set1_certs(ossl_cmp_ctx, extraCertsIn) /* * Copies any given stack as the new stack of X509 * certificates to send out in the extraCerts field. */ -int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, - STACK_OF(X509) *extraCertsOut) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - - sk_X509_pop_free(ctx->extraCertsOut, X509_free); - ctx->extraCertsOut = NULL; - return extraCertsOut == NULL - || (ctx->extraCertsOut = X509_chain_up_ref(extraCertsOut)) != NULL; -} +DEFINE_OSSL_set1_certs(OSSL_CMP_CTX, extraCertsOut) /* * Add the given policy info object @@ -598,28 +549,13 @@ int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) * were received in the caPubs field of the last CertRepMessage. * Returns NULL on error */ -STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return X509_chain_up_ref(ctx->caPubs); -} +DEFINE_OSSL_CMP_CTX_get1_certs(caPubs) /* * Copies any given stack of certificates to the given * OSSL_CMP_CTX structure so that they may be retrieved later. */ -int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - - sk_X509_pop_free(ctx->caPubs, X509_free); - ctx->caPubs = NULL; - return caPubs == NULL || (ctx->caPubs = X509_chain_up_ref(caPubs)) != NULL; -} +DEFINE_OSSL_set1_certs(ossl_cmp_ctx, caPubs) #define char_dup OPENSSL_strdup #define char_free OPENSSL_free @@ -642,8 +578,9 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \ #define X509_invalid(cert) (!ossl_x509v3_cache_extensions(cert)) #define EVP_PKEY_invalid(key) 0 -#define DEFINE_OSSL_CMP_CTX_set1_up_ref(FIELD, TYPE) \ -int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ + +#define DEFINE_OSSL_set1_up_ref(PREFIX, FIELD, TYPE) \ +int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ { \ if (ctx == NULL) { \ ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ @@ -662,12 +599,14 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ return 1; \ } +DEFINE_OSSL_set1_up_ref(ossl_cmp_ctx, validatedSrvCert, X509) + /* * Pins the server certificate to be directly trusted (even if it is expired) * for verifying response messages. * Cert pointer is not consumed. It may be NULL to clear the entry. */ -DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509) +DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, srvCert, X509) /* Set the X509 name of the recipient to be placed in the PKIHeader */ DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME) @@ -678,6 +617,8 @@ DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME) /* Set the X509 name of the issuer to be placed in the certTemplate */ DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME) +/* Set the ASN1_INTEGER serial to be placed in the certTemplate for rr */ +DEFINE_OSSL_CMP_CTX_set1(serialNumber, ASN1_INTEGER) /* * Set the subject name that will be placed in the certificate * request. This will be the subject name on the received certificate. @@ -697,7 +638,7 @@ int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts) ERR_raise(ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES); return 0; } - sk_X509_EXTENSION_pop_free(ctx->reqExtensions, X509_EXTENSION_free); + X509_EXTENSIONS_free(ctx->reqExtensions); ctx->reqExtensions = exts; return 1; } @@ -750,7 +691,7 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, * Set our own client certificate, used for example in KUR and when * doing the IR with existing certificate. */ -DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509) +DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, cert, X509) int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, STACK_OF(X509) *candidates) @@ -784,7 +725,7 @@ int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, * Also used as reference cert (defaulting to cert) for deriving subject DN * and SANs. Its issuer is used as default recipient in the CMP message header. */ -DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509) +DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, oldCert, X509) /* Set the PKCS#10 CSR to be sent in P10CR */ DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ) @@ -793,31 +734,19 @@ DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ) * Set the (newly received in IP/KUP/CP) certificate in the context. * This only permits for one cert to be enrolled at a time. */ -int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert) -{ - if (!ossl_assert(ctx != NULL)) - return 0; +DEFINE_OSSL_set0(ossl_cmp_ctx, newCert, X509) - X509_free(ctx->newCert); - ctx->newCert = cert; - return 1; -} +/* Get successfully validated server cert, if any, of current transaction */ +DEFINE_OSSL_CMP_CTX_get0(validatedSrvCert, X509) /* * Get the (newly received in IP/KUP/CP) client certificate from the context * This only permits for one client cert to be received... */ -X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->newCert; -} +DEFINE_OSSL_CMP_CTX_get0(newCert, X509) /* Set the client's current private key */ -DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY) +DEFINE_OSSL_set1_up_ref(OSSL_CMP_CTX, pkey, EVP_PKEY) /* Set new key pair. Used e.g. when doing Key Update */ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey) @@ -864,36 +793,24 @@ EVP_PKEY *ossl_cmp_ctx_get0_newPubkey(const OSSL_CMP_CTX *ctx) return ctx->pkey; } -/* Set the given transactionID to the context */ -int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, - const ASN1_OCTET_STRING *id) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id); +#define DEFINE_set1_ASN1_OCTET_STRING(PREFIX, FIELD) \ +int PREFIX##_set1_##FIELD(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *id) \ +{ \ + if (ctx == NULL) { \ + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \ + return 0; \ + } \ + return ossl_cmp_asn1_octet_string_set1(&ctx->FIELD, id); \ } +/* Set the given transactionID to the context */ +DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, transactionID) + /* Set the nonce to be used for the recipNonce in the message created next */ -int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, - const ASN1_OCTET_STRING *nonce) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce); -} +DEFINE_set1_ASN1_OCTET_STRING(ossl_cmp_ctx, recipNonce) /* Stores the given nonce as the last senderNonce sent out */ -int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx, - const ASN1_OCTET_STRING *nonce) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce); -} +DEFINE_set1_ASN1_OCTET_STRING(OSSL_CMP_CTX, senderNonce) /* Set the proxy server to use for HTTP(S) connections */ DEFINE_OSSL_CMP_CTX_set1(proxy, char) @@ -904,111 +821,46 @@ DEFINE_OSSL_CMP_CTX_set1(server, char) /* Set the server exclusion list of the HTTP proxy server */ DEFINE_OSSL_CMP_CTX_set1(no_proxy, char) +#ifndef OPENSSL_NO_HTTP /* Set the http connect/disconnect callback function to be used for HTTP(S) */ -int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->http_cb = cb; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb, OSSL_HTTP_bio_cb_t) /* Set argument optionally to be used by the http connect/disconnect callback */ -int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->http_cb_arg = arg; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, http_cb_arg, void *) /* * Get argument optionally to be used by the http connect/disconnect callback * Returns callback argument set previously (NULL if not set or on error) */ -void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->http_cb_arg; -} +DEFINE_OSSL_get(OSSL_CMP_CTX, http_cb_arg, void *, NULL) +#endif /* Set callback function for sending CMP request and receiving response */ -int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->transfer_cb = cb; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb, OSSL_CMP_transfer_cb_t) /* Set argument optionally to be used by the transfer callback */ -int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->transfer_cb_arg = arg; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, transfer_cb_arg, void *) /* * Get argument optionally to be used by the transfer callback. * Returns callback argument set previously (NULL if not set or on error) */ -void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return NULL; - } - return ctx->transfer_cb_arg; -} +DEFINE_OSSL_get(OSSL_CMP_CTX, transfer_cb_arg, void *, NULL) /** Set the HTTP server port to be used */ -int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return 0; - } - ctx->serverPort = port; - return 1; -} +DEFINE_OSSL_set(OSSL_CMP_CTX, serverPort, int) /* Set the HTTP path to be used on the server (e.g "pkix/") */ DEFINE_OSSL_CMP_CTX_set1(serverPath, char) /* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */ -int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info) -{ - if (!ossl_assert(ctx != NULL)) - return 0; - ctx->failInfoCode = fail_info; - return 1; -} +DEFINE_OSSL_set(ossl_cmp_ctx, failInfoCode, int) /* * Get the failInfo error code in OSSL_CMP_CTX as bit encoding. * Returns bit string as integer on success, -1 on error */ -int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx) -{ - if (ctx == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); - return -1; - } - return ctx->failInfoCode; -} +DEFINE_OSSL_get(OSSL_CMP_CTX, failInfoCode, int, -1) /* Set a Boolean or integer option of the context to the "val" arg */ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) @@ -1098,6 +950,9 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) case OSSL_CMP_OPT_TOTAL_TIMEOUT: ctx->total_timeout = val; break; + case OSSL_CMP_OPT_USE_TLS: + ctx->tls_used = val; + break; case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR: ctx->permitTAInExtraCertsForIR = val; break; @@ -1162,6 +1017,8 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) return ctx->msg_timeout; case OSSL_CMP_OPT_TOTAL_TIMEOUT: return ctx->total_timeout; + case OSSL_CMP_OPT_USE_TLS: + return ctx->tls_used; case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR: return ctx->permitTAInExtraCertsForIR; case OSSL_CMP_OPT_REVOCATION_REASON: diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index dfc6dfbede..3853e52605 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -84,8 +84,12 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { "failure obtaining random"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE), "fail info out of range"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GETTING_GENP), "getting genp"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE), + "invalid rootcakeyupdate"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION), "missing key input for creating protection"}, @@ -139,6 +143,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED), "transactionid unmatched"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), "unexpected pkistatus"}, diff --git a/crypto/cmp/cmp_genm.c b/crypto/cmp/cmp_genm.c new file mode 100644 index 0000000000..dad6ef1189 --- /dev/null +++ b/crypto/cmp/cmp_genm.c @@ -0,0 +1,346 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Siemens AG 2022 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cmp_local.h" +#include + +static const X509_VERIFY_PARAM *get0_trustedStore_vpm(const OSSL_CMP_CTX *ctx) +{ + const X509_STORE *ts = OSSL_CMP_CTX_get0_trustedStore(ctx); + + return ts == NULL ? NULL : X509_STORE_get0_param(ts); +} + +static void cert_msg(const char *func, const char *file, int lineno, + OSSL_CMP_severity level, OSSL_CMP_CTX *ctx, + const char *source, X509 *cert, const char *msg) +{ + char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); + + ossl_cmp_print_log(level, ctx, func, file, lineno, + level == OSSL_CMP_LOG_WARNING ? "WARN" : "ERR", + "certificate from '%s' with subject '%s' %s", + source, subj, msg); + OPENSSL_free(subj); +} + +/* use |type_CA| -1 (no CA type check) or 0 (must be EE) or 1 (must be CA) */ +static int ossl_X509_check(OSSL_CMP_CTX *ctx, const char *source, X509 *cert, + int type_CA, const X509_VERIFY_PARAM *vpm) +{ + uint32_t ex_flags = X509_get_extension_flags(cert); + int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), + X509_get0_notAfter(cert)); + int ret = res == 0; + OSSL_CMP_severity level = + vpm == NULL ? OSSL_CMP_LOG_WARNING : OSSL_CMP_LOG_ERR; + + if (!ret) + cert_msg(OPENSSL_FUNC, OPENSSL_FILE, OPENSSL_LINE, level, ctx, + source, cert, res > 0 ? "has expired" : "not yet valid"); + if (type_CA >= 0 && (ex_flags & EXFLAG_V1) == 0) { + int is_CA = (ex_flags & EXFLAG_CA) != 0; + + if ((type_CA != 0) != is_CA) { + cert_msg(OPENSSL_FUNC, OPENSSL_FILE, OPENSSL_LINE, level, ctx, + source, cert, + is_CA ? "is not an EE cert" : "is not a CA cert"); + ret = 0; + } + } + return ret; +} + +static int ossl_X509_check_all(OSSL_CMP_CTX *ctx, const char *source, + STACK_OF(X509) *certs, + int type_CA, const X509_VERIFY_PARAM *vpm) +{ + int i; + int ret = 1; + + for (i = 0; i < sk_X509_num(certs /* may be NULL */); i++) + ret = ossl_X509_check(ctx, source, + sk_X509_value(certs, i), type_CA, vpm) + && ret; /* Having 'ret' after the '&&', all certs are checked. */ + return ret; +} + +static OSSL_CMP_ITAV *get_genm_itav(OSSL_CMP_CTX *ctx, + OSSL_CMP_ITAV *req, /* gets consumed */ + int expected, const char *desc) +{ + STACK_OF(OSSL_CMP_ITAV) *itavs = NULL; + int i, n; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + goto err; + } + if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_unspecified) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_UNCLEAN_CTX, + "client context in unsuitable state; should call CMPclient_reinit() before"); + goto err; + } + + if (!OSSL_CMP_CTX_push0_genm_ITAV(ctx, req)) + goto err; + req = NULL; + itavs = OSSL_CMP_exec_GENM_ses(ctx); + if (itavs == NULL) { + if (OSSL_CMP_CTX_get_status(ctx) != OSSL_CMP_PKISTATUS_request) + ERR_raise_data(ERR_LIB_CMP, CMP_R_GETTING_GENP, + "with infoType %s", desc); + return NULL; + } + + if ((n = sk_OSSL_CMP_ITAV_num(itavs)) <= 0) { + ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP, + "response on genm requesting infoType %s does not include suitable value", desc); + sk_OSSL_CMP_ITAV_free(itavs); + return NULL; + } + + if (n > 1) + ossl_cmp_log2(WARN, ctx, + "response on genm contains %d ITAVs; will use the first ITAV with infoType id-it-%s", + n, desc); + for (i = 0; i < n; i++) { + OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_shift(itavs); + ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav); + char name[128] = "genp contains InfoType '"; + size_t offset = strlen(name); + + if (OBJ_obj2nid(obj) == expected) { + for (i++; i < n; i++) + OSSL_CMP_ITAV_free(sk_OSSL_CMP_ITAV_shift(itavs)); + sk_OSSL_CMP_ITAV_free(itavs); + return itav; + } + + if (OBJ_obj2txt(name + offset, sizeof(name) - offset, obj, 0) < 0) + strcat(name, ""); + ossl_cmp_log2(WARN, ctx, "%s' while expecting 'id-it-%s'", name, desc); + OSSL_CMP_ITAV_free(itav); + } + ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_GENP, + "could not find any ITAV for %s", desc); + + err: + sk_OSSL_CMP_ITAV_free(itavs); + OSSL_CMP_ITAV_free(req); + return NULL; +} + +int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out) +{ + OSSL_CMP_ITAV *req, *itav; + STACK_OF(X509) *certs = NULL; + int ret = 0; + + if (out == NULL) { + ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); + return 0; + } + *out = NULL; + + if ((req = OSSL_CMP_ITAV_new_caCerts(NULL)) == NULL) + return 0; + if ((itav = get_genm_itav(ctx, req, NID_id_it_caCerts, "caCerts")) == NULL) + return 0; + if (!OSSL_CMP_ITAV_get0_caCerts(itav, &certs)) + goto end; + ret = 1; + if (certs == NULL) /* no CA certificate available */ + goto end; + + if (!ossl_X509_check_all(ctx, "genp", certs, 1 /* CA */, + get0_trustedStore_vpm(ctx))) { + ret = 0; + goto end; + } + *out = sk_X509_new_reserve(NULL, sk_X509_num(certs)); + if (!X509_add_certs(*out, certs, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) { + sk_X509_pop_free(*out, X509_free); + *out = NULL; + ret = 0; + } + + end: + OSSL_CMP_ITAV_free(itav); + return ret; +} + +static int selfsigned_verify_cb(int ok, X509_STORE_CTX *store_ctx) +{ + if (ok == 0 + && X509_STORE_CTX_get_error_depth(store_ctx) == 0 + && X509_STORE_CTX_get_error(store_ctx) + == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) { + /* in this case, custom chain building */ + int i; + STACK_OF(X509) *trust; + STACK_OF(X509) *chain = X509_STORE_CTX_get0_chain(store_ctx); + STACK_OF(X509) *untrusted = X509_STORE_CTX_get0_untrusted(store_ctx); + X509_STORE_CTX_check_issued_fn check_issued = + X509_STORE_CTX_get_check_issued(store_ctx); + X509 *cert = sk_X509_value(chain, 0); /* target cert */ + X509 *issuer; + + for (i = 0; i < sk_X509_num(untrusted); i++) { + cert = sk_X509_value(untrusted, i); + if (!X509_add_cert(chain, cert, X509_ADD_FLAG_UP_REF)) + return 0; + } + + trust = X509_STORE_get1_all_certs(X509_STORE_CTX_get0_store(store_ctx)); + for (i = 0; i < sk_X509_num(trust); i++) { + issuer = sk_X509_value(trust, i); + if ((*check_issued)(store_ctx, cert, issuer)) { + if (X509_add_cert(chain, cert, X509_ADD_FLAG_UP_REF)) + ok = 1; + break; + } + } + sk_X509_pop_free(trust, X509_free); + return ok; + } else { + X509_STORE *ts = X509_STORE_CTX_get0_store(store_ctx); + X509_STORE_CTX_verify_cb verify_cb; + + if (ts == NULL || (verify_cb = X509_STORE_get_verify_cb(ts)) == NULL) + return ok; + return (*verify_cb)(ok, store_ctx); + } +} + +/* vanilla X509_verify_cert() does not support self-signed certs as target */ +static int verify_ss_cert(OSSL_LIB_CTX *libctx, const char *propq, + X509_STORE *ts, STACK_OF(X509) *untrusted, + X509 *target) +{ + X509_STORE_CTX *csc = NULL; + int ok = 0; + + if (ts == NULL || target == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((csc = X509_STORE_CTX_new_ex(libctx, propq)) == NULL + || !X509_STORE_CTX_init(csc, ts, target, untrusted)) + goto err; + X509_STORE_CTX_set_verify_cb(csc, selfsigned_verify_cb); + ok = X509_verify_cert(csc) > 0; + + err: + X509_STORE_CTX_free(csc); + return ok; +} + +static int +verify_ss_cert_trans(OSSL_CMP_CTX *ctx, X509 *trusted /* may be NULL */, + X509 *trans /* the only untrusted cert, may be NULL */, + X509 *target, const char *desc) +{ + X509_STORE *ts = OSSL_CMP_CTX_get0_trusted(ctx); + STACK_OF(X509) *untrusted = NULL; + int res = 0; + + if (trusted != NULL) { + X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts); + + if ((ts = X509_STORE_new()) == NULL) + return 0; + if (!X509_STORE_set1_param(ts, vpm) + || !X509_STORE_add_cert(ts, trusted)) + goto err; + } + + if (trans != NULL + && !ossl_x509_add_cert_new(&untrusted, trans, X509_ADD_FLAG_UP_REF)) + goto err; + + res = verify_ss_cert(OSSL_CMP_CTX_get0_libctx(ctx), + OSSL_CMP_CTX_get0_propq(ctx), + ts, untrusted, target); + if (!res) + ERR_raise_data(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE, + "failed to validate %s certificate received in genp %s", + desc, trusted == NULL ? "using trust store" + : "with given certificate as trust anchor"); + + err: + sk_X509_pop_free(untrusted, X509_free); + if (trusted != NULL) + X509_STORE_free(ts); + return res; +} + +int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, + const X509 *oldWithOld, X509 **newWithNew, + X509 **newWithOld, X509 **oldWithNew) +{ + X509 *oldWithOld_copy = NULL, *my_newWithOld, *my_oldWithNew; + OSSL_CMP_ITAV *req, *itav; + int res = 0; + + if (newWithNew == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + *newWithNew = NULL; + + if ((req = OSSL_CMP_ITAV_new_rootCaCert(oldWithOld)) == NULL) + return 0; + itav = get_genm_itav(ctx, req, NID_id_it_rootCaKeyUpdate, "rootCaKeyUpdate"); + if (itav == NULL) + return 0; + + if (!OSSL_CMP_ITAV_get0_rootCaKeyUpdate(itav, newWithNew, + &my_newWithOld, &my_oldWithNew)) + goto end; + + if (*newWithNew == NULL) /* no root CA cert update available */ + goto end; + if ((oldWithOld_copy = X509_dup(oldWithOld)) == NULL && oldWithOld != NULL) + goto end; + if (!verify_ss_cert_trans(ctx, oldWithOld_copy, my_newWithOld, + *newWithNew, "newWithNew")) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE); + goto end; + } + if (oldWithOld != NULL && my_oldWithNew != NULL + && !verify_ss_cert_trans(ctx, *newWithNew, my_oldWithNew, + oldWithOld_copy, "oldWithOld")) { + ERR_raise(ERR_LIB_CMP, CMP_R_INVALID_ROOTCAKEYUPDATE); + goto end; + } + + if (!X509_up_ref(*newWithNew)) + goto end; + if (newWithOld != NULL && + (*newWithOld = my_newWithOld) != NULL && !X509_up_ref(*newWithOld)) + goto free; + if (oldWithNew == NULL || + (*oldWithNew = my_oldWithNew) == NULL || X509_up_ref(*oldWithNew)) { + res = 1; + goto end; + } + if (newWithOld != NULL) + X509_free(*newWithOld); + free: + X509_free(*newWithNew); + + end: + OSSL_CMP_ITAV_free(itav); + X509_free(oldWithOld_copy); + return res; +} diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c index 8c553af61a..5fabf1aa33 100644 --- a/crypto/cmp/cmp_hdr.c +++ b/crypto/cmp/cmp_hdr.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -276,8 +276,7 @@ int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) if (!set_random(&ctx->transactionID, ctx, OSSL_CMP_TRANSACTIONID_LENGTH)) return 0; - tid = OPENSSL_buf2hexstr(ctx->transactionID->data, - ctx->transactionID->length); + tid = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID); if (tid != NULL) ossl_cmp_log1(DEBUG, ctx, "Starting new transaction with ID=%s", tid); @@ -302,11 +301,12 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) return 0; /* - * If neither protection cert nor oldCert nor subject are given, + * If no protection cert nor oldCert nor CSR nor subject is given, * sender name is not known to the client and thus set to NULL-DN */ sender = ctx->cert != NULL ? X509_get_subject_name(ctx->cert) : ctx->oldCert != NULL ? X509_get_subject_name(ctx->oldCert) : + ctx->p10CSR != NULL ? X509_REQ_get_subject_name(ctx->p10CSR) : ctx->subjectName; if (!ossl_cmp_hdr_set1_sender(hdr, sender)) return 0; diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c index 7c2e048685..d08c362a70 100644 --- a/crypto/cmp/cmp_http.c +++ b/crypto/cmp/cmp_http.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -14,7 +14,6 @@ #include #include -#include "internal/sockets.h" #include #include "cmp_local.h" @@ -45,7 +44,6 @@ static int keep_alive(int keep_alive, int body_type) /* * Send the PKIMessage req and on success return the response, else NULL. - * Any previous error queue entries will likely be removed by ERR_clear_error(). */ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req) @@ -70,7 +68,8 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, if (ctx->serverPort != 0) BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); - tls_used = OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; + tls_used = ctx->tls_used >= 0 ? ctx->tls_used != 0 + : OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; /* backward compat */ if (ctx->http_ctx == NULL) ossl_cmp_log3(DEBUG, ctx, "connecting to CMP server %s:%s%s", ctx->server, server_port, tls_used ? " using TLS" : ""); diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index 149dc89119..29aa84cd2a 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -25,7 +25,7 @@ # include # include "crypto/x509.h" -#define IS_NULL_DN(name) (X509_NAME_get_entry(name, 0) == NULL) +# define IS_NULL_DN(name) (X509_NAME_get_entry(name, 0) == NULL) /* * this structure is used to store the context for CMP sessions @@ -49,10 +49,13 @@ struct ossl_cmp_ctx_st { int keep_alive; /* persistent connection: 0=no, 1=prefer, 2=require */ int msg_timeout; /* max seconds to wait for each CMP message round trip */ int total_timeout; /* max number of seconds an enrollment may take, incl. */ + int tls_used; /* whether to use TLS for client-side HTTP connections */ /* attempts polling for a response if a 'waiting' PKIStatus is received */ time_t end_time; /* session start time + totaltimeout */ +# ifndef OPENSSL_NO_HTTP OSSL_HTTP_bio_cb_t http_cb; void *http_cb_arg; /* allows to store optional argument to cb */ +# endif /* server authentication */ /* @@ -101,7 +104,8 @@ struct ossl_cmp_ctx_st { /* certificate template */ EVP_PKEY *newPkey; /* explicit new private/public key for cert enrollment */ int newPkey_priv; /* flag indicating if newPkey contains private key */ - X509_NAME *issuer; /* issuer name to used in cert template */ + X509_NAME *issuer; /* issuer name to used in cert template, also in rr */ + ASN1_INTEGER *serialNumber; /* certificate serial number to use in rr */ int days; /* Number of days new certificates are asked to be valid for */ X509_NAME *subjectName; /* subject name to be used in cert template */ STACK_OF(GENERAL_NAME) *subjectAltNames; /* to add to the cert template */ @@ -118,7 +122,7 @@ struct ossl_cmp_ctx_st { int revocationReason; /* revocation reason code to be included in RR */ STACK_OF(OSSL_CMP_ITAV) *genm_ITAVs; /* content of general message */ - /* result returned in responses */ + /* result returned in responses, so far supporting only one certResponse */ int status; /* PKIStatus of last received IP/CP/KUP/RP/error or -1 */ OSSL_CMP_PKIFREETEXT *statusString; /* of last IP/CP/KUP/RP/error */ int failInfoCode; /* failInfoCode of last received IP/CP/KUP/error, or -1 */ @@ -202,6 +206,9 @@ typedef struct ossl_cmp_cakeyupdanncontent_st { } OSSL_CMP_CAKEYUPDANNCONTENT; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CAKEYUPDANNCONTENT) +typedef struct ossl_cmp_rootcakeyupdate_st OSSL_CMP_ROOTCAKEYUPDATE; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE) + /*- * declared already here as it will be used in OSSL_CMP_MSG (nested) and * infoType and infoValue @@ -247,6 +254,12 @@ struct ossl_cmp_itav_st { OSSL_CMP_MSGS *origPKIMessage; /* NID_id_it_suppLangTags - Supported Language Tags */ STACK_OF(ASN1_UTF8STRING) *suppLangTagsValue; + /* NID_id_it_caCerts - CA Certificates */ + STACK_OF(X509) *caCerts; + /* NID_id_it_rootCaCert - Root CA Certificate */ + X509 *rootCaCert; + /* NID_id_it_rootCaKeyUpdate - Root CA Certificate Update */ + OSSL_CMP_ROOTCAKEYUPDATE *rootCaKeyUpdate; /* this is to be used for so far undeclared objects */ ASN1_TYPE *other; } infoValue; @@ -369,13 +382,15 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ERRORMSGCONTENT) * -- as is used to create and verify the certificate signature * certReqId INTEGER, * -- to match this confirmation with the corresponding req/rep - * statusInfo PKIStatusInfo OPTIONAL + * statusInfo PKIStatusInfo OPTIONAL, + * hashAlg [0] AlgorithmIdentifier OPTIONAL * } */ struct ossl_cmp_certstatus_st { ASN1_OCTET_STRING *certHash; ASN1_INTEGER *certReqId; OSSL_CMP_PKISI *statusInfo; + X509_ALGOR *hashAlg; /* 0 */ } /* OSSL_CMP_CERTSTATUS */; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS) typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT; @@ -446,7 +461,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_POLLREPCONTENT) /*- * PKIHeader ::= SEQUENCE { - * pvno INTEGER { cmp1999(1), cmp2000(2) }, + * pvno INTEGER { cmp1999(1), cmp2000(2), cmp2021(3) }, * sender GeneralName, * -- identifies the sender * recipient GeneralName, @@ -708,6 +723,7 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART) * } -- or HMAC [RFC2104, RFC2202]) */ /*- + * Not supported: * id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} * DHBMParameter ::= SEQUENCE { * owf AlgorithmIdentifier, @@ -730,6 +746,21 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PROTECTEDPART) * } */ +/* + * RootCaKeyUpdateContent ::= SEQUENCE { + * newWithNew CMPCertificate, + * newWithOld [0] CMPCertificate OPTIONAL, + * oldWithNew [1] CMPCertificate OPTIONAL + * } + */ + +struct ossl_cmp_rootcakeyupdate_st { + X509 *newWithNew; + X509 *newWithOld; + X509 *oldWithNew; +} /* OSSL_CMP_ROOTCAKEYUPDATE */; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ROOTCAKEYUPDATE) + /* from cmp_asn.c */ int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a); @@ -777,7 +808,7 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, # define ossl_cmp_info(ctx, msg) ossl_cmp_log(INFO, ctx, msg) # define ossl_cmp_debug(ctx, msg) ossl_cmp_log(DEBUG, ctx, msg) # define ossl_cmp_trace(ctx, msg) ossl_cmp_log(TRACE, ctx, msg) -int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert); +int ossl_cmp_ctx_set1_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert); int ossl_cmp_ctx_set_status(OSSL_CMP_CTX *ctx, int status); int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIFREETEXT *text); diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index c8e467f3c2..e00afc809e 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -59,7 +59,6 @@ int ossl_cmp_msg_set0_libctx(OSSL_CMP_MSG *msg, OSSL_LIB_CTX *libctx, return 1; } - OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg) { if (msg == NULL) { @@ -326,9 +325,9 @@ OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid) && (exts = X509_REQ_get_extensions(ctx->p10CSR)) == NULL) goto err; if (!ctx->SubjectAltName_nodefault && !HAS_SAN(ctx) && refcert != NULL - && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), - NID_subject_alt_name, NULL, NULL)) - != NULL + && (default_sans = X509V3_get_d2i(X509_get0_extensions(refcert), + NID_subject_alt_name, NULL, NULL)) + != NULL && !add1_extension(&exts, NID_subject_alt_name, crit, default_sans)) goto err; if (ctx->reqExtensions != NULL /* augment/override existing ones */ @@ -519,27 +518,38 @@ OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx) { OSSL_CMP_MSG *msg = NULL; + const X509_NAME *issuer = NULL; + const X509_NAME *subject = NULL; + const ASN1_INTEGER *serialNumber = NULL; + EVP_PKEY *pubkey = NULL; OSSL_CMP_REVDETAILS *rd; int ret; - if (!ossl_assert(ctx != NULL && (ctx->oldCert != NULL - || ctx->p10CSR != NULL))) + if (!ossl_assert(ctx != NULL + && (ctx->oldCert != NULL || ctx->p10CSR != NULL + || (ctx->serialNumber != NULL && ctx->issuer != NULL)))) return NULL; if ((rd = OSSL_CMP_REVDETAILS_new()) == NULL) goto err; + if (ctx->serialNumber != NULL && ctx->issuer != NULL) { + issuer = ctx->issuer; + serialNumber = ctx->serialNumber; + } else if (ctx->oldCert != NULL) { + issuer = X509_get_issuer_name(ctx->oldCert); + serialNumber = X509_get0_serialNumber(ctx->oldCert); + } else if (ctx->p10CSR != NULL) { + pubkey = X509_REQ_get0_pubkey(ctx->p10CSR); + subject = X509_REQ_get_subject_name(ctx->p10CSR); + } + else { + goto err; + } + /* Fill the template from the contents of the certificate to be revoked */ - ret = ctx->oldCert != NULL - ? OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, - NULL /* pubkey would be redundant */, - NULL /* subject would be redundant */, - X509_get_issuer_name(ctx->oldCert), - X509_get0_serialNumber(ctx->oldCert)) - : OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, - X509_REQ_get0_pubkey(ctx->p10CSR), - X509_REQ_get_subject_name(ctx->p10CSR), - NULL, NULL); + ret = OSSL_CRMF_CERTTEMPLATE_fill(rd->certDetails, pubkey, subject, + issuer, serialNumber); if (!ret) goto err; @@ -673,7 +683,7 @@ int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg, } /* - * Creates a new General Message/Response with an empty itav stack + * Creates a new General Message/Response with a copy of the given itav stack * returns a pointer to the PKIMessage on success, NULL on error */ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, @@ -787,6 +797,8 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId, { OSSL_CMP_MSG *msg = NULL; OSSL_CMP_CERTSTATUS *certStatus = NULL; + EVP_MD *md; + int is_fallback; ASN1_OCTET_STRING *certHash = NULL; OSSL_CMP_PKISI *sinfo; @@ -814,13 +826,23 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int certReqId, /* set the ID of the certReq */ if (!ASN1_INTEGER_set(certStatus->certReqId, certReqId)) goto err; + + certStatus->hashAlg = NULL; /* * The hash of the certificate, using the same hash algorithm * as is used to create and verify the certificate signature. - * If not available, a default hash algorithm is used. + * If not available, a fallback hash algorithm is used. */ - if ((certHash = X509_digest_sig(ctx->newCert, NULL, NULL)) == NULL) + if ((certHash = X509_digest_sig(ctx->newCert, &md, &is_fallback)) == NULL) goto err; + if (is_fallback) { + if (!ossl_cmp_hdr_set_pvno(msg->header, OSSL_CMP_PVNO_3)) + goto err; + if ((certStatus->hashAlg = X509_ALGOR_new()) == NULL) + goto err; + X509_ALGOR_set_md(certStatus->hashAlg, md); + } + EVP_MD_free(md); if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash)) goto err; @@ -1106,8 +1128,8 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx, } msg = OSSL_CMP_MSG_new(libctx, propq); - if (msg == NULL){ - ERR_raise(ERR_LIB_CMP, ERR_R_MALLOC_FAILURE); + if (msg == NULL) { + ERR_raise(ERR_LIB_CMP, ERR_R_CMP_LIB); return NULL; } diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c index 539f6534cd..f59fee44ec 100644 --- a/crypto/cmp/cmp_protect.c +++ b/crypto/cmp/cmp_protect.c @@ -10,6 +10,7 @@ */ #include "cmp_local.h" +#include "crypto/asn1.h" /* explicit #includes not strictly needed since implied by the above: */ #include @@ -21,9 +22,11 @@ /* * This function is also used by the internal verify_PBMAC() in cmp_vfy.c. * - * Calculate protection for given PKImessage according to - * the algorithm and parameters in the message header's protectionAlg + * Calculate protection for |msg| according to |msg->header->protectionAlg| * using the credentials, library context, and property criteria in the ctx. + * Unless |msg->header->protectionAlg| is PasswordBasedMAC, + * its value is completed according to |ctx->pkey| and |ctx->digest|, + * where the latter irrelevant in the case of Edwards curves. * * returns ASN1_BIT_STRING representing the protection on success, else NULL */ @@ -91,9 +94,8 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, if ((prot = ASN1_BIT_STRING_new()) == NULL) goto end; - /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ - prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; + /* OpenSSL by default encodes all bit strings as ASN.1 NamedBitList */ + ossl_asn1_string_set_bits_left(prot, 0); if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { ASN1_BIT_STRING_free(prot); prot = NULL; @@ -104,23 +106,22 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, OPENSSL_free(prot_part_der); return prot; } else { - int md_nid; - const EVP_MD *md = NULL; + const EVP_MD *md = ctx->digest; + char name[80] = ""; if (ctx->pkey == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); return NULL; } - if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL) - || (md = EVP_get_digestbynid(md_nid)) == NULL) { - ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID); - return NULL; - } + if (EVP_PKEY_get_default_digest_name(ctx->pkey, name, sizeof(name)) > 0 + && strcmp(name, "UNDEF") == 0) /* at least for Ed25519, Ed448 */ + md = NULL; if ((prot = ASN1_BIT_STRING_new()) == NULL) return NULL; - if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), NULL, + if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), + msg->header->protectionAlg, /* sets X509_ALGOR */ NULL, prot, &prot_part, NULL, ctx->pkey, md, ctx->libctx, ctx->propq)) return prot; @@ -185,15 +186,16 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) * Create an X509_ALGOR structure for PasswordBasedMAC protection based on * the pbm settings in the context */ -static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) +static X509_ALGOR *pbmac_algor(const OSSL_CMP_CTX *ctx) { OSSL_CRMF_PBMPARAMETER *pbm = NULL; unsigned char *pbm_der = NULL; int pbm_der_len; ASN1_STRING *pbm_str = NULL; + X509_ALGOR *alg = NULL; if (!ossl_assert(ctx != NULL)) - return 0; + return NULL; pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen, EVP_MD_get_type(ctx->pbm_owf), ctx->pbm_itercnt, @@ -201,47 +203,18 @@ static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) pbm_str = ASN1_STRING_new(); if (pbm == NULL || pbm_str == NULL) goto err; - if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) goto err; - if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) goto err; - if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) - goto err; - OPENSSL_free(pbm_der); - - X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), - V_ASN1_SEQUENCE, pbm_str); - OSSL_CRMF_PBMPARAMETER_free(pbm); - return 1; - + alg = ossl_X509_ALGOR_from_nid(NID_id_PasswordBasedMAC, + V_ASN1_SEQUENCE, pbm_str); err: - ASN1_STRING_free(pbm_str); + if (alg == NULL) + ASN1_STRING_free(pbm_str); OPENSSL_free(pbm_der); OSSL_CRMF_PBMPARAMETER_free(pbm); - return 0; -} - -static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) -{ - int nid = 0; - ASN1_OBJECT *algo = NULL; - - if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_get_type(ctx->digest), - EVP_PKEY_get_id(ctx->pkey))) { - ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE); - return 0; - } - if ((algo = OBJ_nid2obj(nid)) == NULL) - return 0; - if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) - return 0; - - if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL)) - return 1; - ASN1_OBJECT_free(algo); - return 0; + return alg; } static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg, @@ -260,6 +233,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) /* * For the case of re-protection remove pre-existing protection. + * Does not remove any pre-existing extraCerts. */ X509_ALGOR_free(msg->header->protectionAlg); msg->header->protectionAlg = NULL; @@ -271,7 +245,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } else if (ctx->secretValue != NULL) { /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ - if (!set_pbmac_algor(ctx, &msg->header->protectionAlg)) + if ((msg->header->protectionAlg = pbmac_algor(ctx)) == NULL) goto err; if (!set_senderKID(ctx, msg, NULL)) goto err; @@ -290,7 +264,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } - if (!set_sig_algor(ctx, &msg->header->protectionAlg)) + if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) goto err; /* set senderKID to keyIdentifier of the cert according to 5.1.1 */ if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert))) @@ -306,6 +280,7 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } if (!ctx->unprotectedSend + /* protect according to msg->header->protectionAlg partly set above */ && ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)) goto err; diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c index 96f977636c..06ef8fbb61 100644 --- a/crypto/cmp/cmp_server.c +++ b/crypto/cmp/cmp_server.c @@ -235,14 +235,15 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, msg = ossl_cmp_certrep_new(srv_ctx->ctx, bodytype, certReqId, si, certOut, NULL /* enc */, chainOut, caPubs, srv_ctx->sendUnprotectedErrors); + /* When supporting OSSL_CRMF_POPO_KEYENC, "enc" will need to be set */ if (msg == NULL) ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP); err: OSSL_CMP_PKISI_free(si); X509_free(certOut); - sk_X509_pop_free(chainOut, X509_free); - sk_X509_pop_free(caPubs, X509_free); + OSSL_STACK_OF_X509_free(chainOut); + OSSL_STACK_OF_X509_free(caPubs); return msg; } @@ -496,10 +497,8 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, case OSSL_CMP_PKIBODY_GENM: case OSSL_CMP_PKIBODY_ERROR: if (ctx->transactionID != NULL) { - char *tid; + char *tid = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID); - tid = OPENSSL_buf2hexstr(ctx->transactionID->data, - ctx->transactionID->length); if (tid != NULL) ossl_cmp_log1(WARN, ctx, "Assuming that last transaction with ID=%s got aborted", @@ -570,6 +569,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, rsp = process_pollReq(srv_ctx, req); break; default: + /* Other request message types are not supported */ ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY); break; } @@ -581,6 +581,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, int flags = 0; unsigned long err = ERR_peek_error_data(&data, &flags); int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest; + /* fail_info is not very specific */ OSSL_CMP_PKISI *si = NULL; if (!req_verified) { @@ -630,6 +631,8 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, case OSSL_CMP_PKIBODY_PKICONF: case OSSL_CMP_PKIBODY_GENP: case OSSL_CMP_PKIBODY_ERROR: + /* Other terminating response message types are not supported */ + /* Prepare for next transaction, ignoring any errors here: */ (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL); ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ diff --git a/crypto/cmp/cmp_status.c b/crypto/cmp/cmp_status.c index 68144aa4fe..b9086d84f8 100644 --- a/crypto/cmp/cmp_status.c +++ b/crypto/cmp/cmp_status.c @@ -184,11 +184,11 @@ char *snprint_PKIStatusInfo_parts(int status, int fail_info, || (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL) return NULL; -#define ADVANCE_BUFFER \ - if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \ - return NULL; \ - write_ptr += printed_chars; \ - bufsize -= printed_chars; +#define ADVANCE_BUFFER \ + if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \ + return NULL; \ + write_ptr += printed_chars; \ + bufsize -= printed_chars; printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string); ADVANCE_BUFFER; diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c index 7cf27cc9d4..f3c21c5d91 100644 --- a/crypto/cmp/cmp_util.c +++ b/crypto/cmp/cmp_util.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -53,8 +53,7 @@ static OSSL_CMP_severity parse_level(const char *level) if (end_level == NULL) return -1; - if (strncmp(level, OSSL_CMP_LOG_PREFIX, - strlen(OSSL_CMP_LOG_PREFIX)) == 0) + if (HAS_PREFIX(level, OSSL_CMP_LOG_PREFIX)) level += strlen(OSSL_CMP_LOG_PREFIX); len = end_level - level; if (len > max_level_len) @@ -190,7 +189,7 @@ void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn) BIO_free(bio); } #else - /* ERR_raise(ERR_LIB_CMP, CMP_R_NO_STDIO) makes no sense during error printing */ + /* ERR_raise(..., CMP_R_NO_STDIO) would make no sense here */ #endif } else { if (log_fn(component, file, line, OSSL_CMP_LOG_ERR, msg) <= 0) @@ -244,6 +243,7 @@ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, const ASN1_OCTET_STRING *src) { ASN1_OCTET_STRING *new; + if (tgt == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); return 0; diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index f0b5dd2847..1869fae696 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -34,7 +34,8 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, return 0; bio = BIO_new(BIO_s_mem()); /* may be NULL */ - + if (bio == NULL) + return 0; /* verify that keyUsage, if present, contains digitalSignature */ if (!cmp_ctx->ignore_keyusage && (X509_get_key_usage(cert) & X509v3_KU_DIGITAL_SIGNATURE) == 0) { @@ -138,6 +139,24 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, return valid; } +static int verify_cb_cert(X509_STORE *ts, X509 *cert, int err) +{ + X509_STORE_CTX_verify_cb verify_cb; + X509_STORE_CTX *csc; + int ok = 0; + + if (ts == NULL || (verify_cb = X509_STORE_get_verify_cb(ts)) == NULL) + return ok; + if ((csc = X509_STORE_CTX_new()) != NULL + && X509_STORE_CTX_init(csc, ts, cert, NULL)) { + X509_STORE_CTX_set_error(csc, err); + X509_STORE_CTX_set_current_cert(csc, cert); + ok = (*verify_cb)(0, csc); + } + X509_STORE_CTX_free(csc); + return ok; +} + /* Return 0 if expect_name != NULL and there is no matching actual_name */ static int check_name(const OSSL_CMP_CTX *ctx, int log_success, const char *actual_desc, const X509_NAME *actual_name, @@ -186,7 +205,7 @@ static int check_kid(const OSSL_CMP_CTX *ctx, ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate"); return 0; } - str = OPENSSL_buf2hexstr(ckid->data, ckid->length); + str = i2s_ASN1_OCTET_STRING(NULL, ckid); if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) { if (str != NULL) ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str); @@ -197,7 +216,7 @@ static int check_kid(const OSSL_CMP_CTX *ctx, if (str != NULL) ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str); OPENSSL_free(str); - if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL) + if ((str = i2s_ASN1_OCTET_STRING(NULL, skid)) != NULL) ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", str); OPENSSL_free(str); return 0; @@ -255,9 +274,14 @@ static int cert_acceptable(const OSSL_CMP_CTX *ctx, time_cmp = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), X509_get0_notAfter(cert)); if (time_cmp != 0) { + int err = time_cmp > 0 ? X509_V_ERR_CERT_HAS_EXPIRED + : X509_V_ERR_CERT_NOT_YET_VALID; + ossl_cmp_warn(ctx, time_cmp > 0 ? "cert has expired" : "cert is not yet valid"); - return 0; + if (ctx->log_cb != NULL /* logging not temporarily disabled */ + && verify_cb_cert(ts, cert, err) <= 0) + return 0; } if (!check_name(ctx, 1, @@ -353,7 +377,7 @@ static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert, /*- * Try all certs in given list for verifying msg, normally or in 3GPP mode. * If already_checked1 == NULL then certs are assumed to be the msg->extraCerts. - * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). */ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, const char *desc, @@ -382,13 +406,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert) : check_cert_path(ctx, ctx->trusted, cert)) { /* store successful sender cert for further msgs in transaction */ - if (!X509_up_ref(cert)) - return 0; - if (!ossl_cmp_ctx_set0_validatedSrvCert(ctx, cert)) { - X509_free(cert); - return 0; - } - return 1; + return ossl_cmp_ctx_set1_validatedSrvCert(ctx, cert); } } if (in_extraCerts && n_acceptable_certs == 0) @@ -399,7 +417,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, /*- * Verify msg trying first ctx->untrusted, which should include extraCerts * at its front, then trying the trusted certs in truststore (if any) of ctx. - * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). */ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, int mode_3gpp) @@ -426,25 +444,20 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, : "no trusted store"); } else { STACK_OF(X509) *trusted = X509_STORE_get1_all_certs(ctx->trusted); + ret = check_msg_with_certs(ctx, trusted, mode_3gpp ? "self-issued extraCerts" : "certs in trusted store", msg->extraCerts, ctx->untrusted, msg, mode_3gpp); - sk_X509_pop_free(trusted, X509_free); + OSSL_STACK_OF_X509_free(trusted); } return ret; } -static int no_log_cb(const char *func, const char *file, int line, - OSSL_CMP_severity level, const char *msg) -{ - return 1; -} - /*- * Verify message signature with any acceptable and valid candidate cert. - * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). */ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) { @@ -459,6 +472,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) if (sender == NULL || msg->body == NULL) return 0; /* other NULL cases already have been checked */ if (sender->type != GEN_DIRNAME) { + /* So far, only X509_NAME is supported */ ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); return 0; } @@ -468,7 +482,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /* enable clearing irrelevant errors in attempts to validate sender certs */ (void)ERR_set_mark(); - ctx->log_cb = no_log_cb; /* temporarily disable logging */ + ctx->log_cb = NULL; /* temporarily disable logging */ /* * try first cached scrt, used successfully earlier in same transaction, @@ -481,7 +495,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) return 1; } /* cached sender cert has shown to be no more successfully usable */ - (void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL); + (void)ossl_cmp_ctx_set1_validatedSrvCert(ctx, NULL); /* re-do the above check (just) for adding diagnostic information */ ossl_cmp_info(ctx, "trying to verify msg signature with previously validated cert"); @@ -500,8 +514,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) (void)ERR_clear_last_mark(); sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0); - skid_str = skid == NULL ? NULL - : OPENSSL_buf2hexstr(skid->data, skid->length); + skid_str = skid == NULL ? NULL : i2s_ASN1_OCTET_STRING(NULL, skid); if (ctx->log_cb != NULL) { ossl_cmp_info(ctx, "trying to verify msg signature with a valid cert that.."); if (sname != NULL) @@ -537,7 +550,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) * the sender certificate can have been pinned by providing it in ctx->srvCert, * else it is searched in msg->extraCerts, ctx->untrusted, in ctx->trusted * (in this order) and is path is validated against ctx->trusted. - * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). * * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg, * the trust anchor for validating the IP msg may be taken from msg->extraCerts @@ -624,15 +637,17 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_TRUST_ANCHOR); return 0; } - if (check_msg_find_cert(ctx, msg)) + if (check_msg_find_cert(ctx, msg)) { + ossl_cmp_debug(ctx, + "successfully validated signature-based CMP message protection using trust store"); return 1; + } } else { /* use pinned sender cert */ /* use ctx->srvCert for signature check even if not acceptable */ if (verify_signature(ctx, msg, scrt)) { ossl_cmp_debug(ctx, - "successfully validated signature-based CMP message protection"); - - return 1; + "successfully validated signature-based CMP message protection using pinned server cert"); + return ossl_cmp_ctx_set1_validatedSrvCert(ctx, scrt); } ossl_cmp_warn(ctx, "CMP message signature verification failed"); ERR_raise(ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG); @@ -642,6 +657,29 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) return 0; } +static int check_transactionID_or_nonce(ASN1_OCTET_STRING *expected, + ASN1_OCTET_STRING *actual, int reason) +{ + if (expected != NULL + && (actual == NULL || ASN1_OCTET_STRING_cmp(expected, actual) != 0)) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + char *expected_str, *actual_str; + + expected_str = i2s_ASN1_OCTET_STRING(NULL, expected); + actual_str = actual == NULL ? NULL: i2s_ASN1_OCTET_STRING(NULL, actual); + ERR_raise_data(ERR_LIB_CMP, reason, + "expected = %s, actual = %s", + expected_str == NULL ? "?" : expected_str, + actual == NULL ? "(none)" : + actual_str == NULL ? "?" : actual_str); + OPENSSL_free(expected_str); + OPENSSL_free(actual_str); + return 0; +#endif + } + return 1; +} + /*- * Check received message (i.e., response by server or request from client) * Any msg->extraCerts are prepended to ctx->untrusted. @@ -728,7 +766,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, } /* check CMP version number in header */ - if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) { + if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO_2 + && ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO_3) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PVNO); return 0; @@ -743,26 +782,14 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, } /* compare received transactionID with the expected one in previous msg */ - if (ctx->transactionID != NULL - && (hdr->transactionID == NULL - || ASN1_OCTET_STRING_cmp(ctx->transactionID, - hdr->transactionID) != 0)) { -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ERR_raise(ERR_LIB_CMP, CMP_R_TRANSACTIONID_UNMATCHED); + if (!check_transactionID_or_nonce(ctx->transactionID, hdr->transactionID, + CMP_R_TRANSACTIONID_UNMATCHED)) return 0; -#endif - } /* compare received nonce with the one we sent */ - if (ctx->senderNonce != NULL - && (msg->header->recipNonce == NULL - || ASN1_OCTET_STRING_cmp(ctx->senderNonce, - hdr->recipNonce) != 0)) { -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ERR_raise(ERR_LIB_CMP, CMP_R_RECIPNONCE_UNMATCHED); + if (!check_transactionID_or_nonce(ctx->senderNonce, hdr->recipNonce, + CMP_R_RECIPNONCE_UNMATCHED)) return 0; -#endif - } /* if not yet present, learn transactionID */ if (ctx->transactionID == NULL diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c index ebbc8e1bcd..bc6b2769f9 100644 --- a/crypto/cms/cms_asn1.c +++ b/crypto/cms/cms_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -83,6 +83,7 @@ ASN1_NDEF_SEQUENCE(CMS_SignedData) = { ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1), ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo) } ASN1_NDEF_SEQUENCE_END(CMS_SignedData) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_SignedData) ASN1_SEQUENCE(CMS_OriginatorInfo) = { ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), diff --git a/crypto/cms/cms_cd.c b/crypto/cms/cms_cd.c index 6de6d55e58..3000268480 100644 --- a/crypto/cms/cms_cd.c +++ b/crypto/cms/cms_cd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,7 +17,7 @@ #include #include "cms_local.h" -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB /* CMS CompressedData Utilities */ @@ -50,8 +50,9 @@ CMS_ContentInfo *ossl_cms_CompressedData_create(int comp_nid, cd->version = 0; - X509_ALGOR_set0(cd->compressionAlgorithm, - OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL); + (void)X509_ALGOR_set0(cd->compressionAlgorithm, + OBJ_nid2obj(NID_zlib_compression), + V_ASN1_UNDEF, NULL); /* cannot fail */ cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c index 6a7c049ef3..40b20249a3 100644 --- a/crypto/cms/cms_dd.c +++ b/crypto/cms/cms_dd.c @@ -66,7 +66,7 @@ int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, CMS_DigestedData *dd; if (mctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c index 9509796317..c6e8c076da 100644 --- a/crypto/cms/cms_dh.c +++ b/crypto/cms/cms_dh.c @@ -13,6 +13,7 @@ #include #include #include "internal/sizes.h" +#include "crypto/asn1.h" #include "crypto/evp.h" #include "cms_local.h" @@ -234,12 +235,11 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) if (penclen <= 0) goto err; ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(pubkey, 0); penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), - V_ASN1_UNDEF, NULL); + (void)X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), + V_ASN1_UNDEF, NULL); /* cannot fail */ } /* See if custom parameters set */ @@ -316,10 +316,10 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) goto err; ASN1_STRING_set0(wrap_str, penc, penclen); penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), - V_ASN1_SEQUENCE, wrap_str); - - rv = 1; + rv = X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), + V_ASN1_SEQUENCE, wrap_str); + if (!rv) + ASN1_STRING_free(wrap_str); err: OPENSSL_free(penc); diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c index 6ec2822b44..a4427d7ee2 100644 --- a/crypto/cms/cms_ec.c +++ b/crypto/cms/cms_ec.c @@ -13,6 +13,7 @@ #include #include #include "internal/sizes.h" +#include "crypto/asn1.h" #include "crypto/evp.h" #include "cms_local.h" @@ -281,8 +282,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) if (enckeylen > INT_MAX || enckeylen == 0) goto err; ASN1_STRING_set0(pubkey, penc, (int)enckeylen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(pubkey, 0); penc = NULL; (void)X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), @@ -369,9 +369,9 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) goto err; ASN1_STRING_set0(wrap_str, penc, penclen); penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); - - rv = 1; + rv = X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); + if (!rv) + ASN1_STRING_free(wrap_str); err: OPENSSL_free(penc); diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index ae88df33a7..f42670cdfb 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -45,7 +45,7 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, b = BIO_new(BIO_f_cipher()); if (b == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB); return NULL; } @@ -121,10 +121,8 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, /* Generate random session key */ if (!enc || !ec->key) { tkey = OPENSSL_malloc(tkeylen); - if (tkey == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (tkey == NULL) goto err; - } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; } @@ -168,7 +166,7 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, if (enc) { calg->parameter = ASN1_TYPE_new(); if (calg->parameter == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); goto err; } if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { @@ -211,10 +209,8 @@ int ossl_cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, { ec->cipher = cipher; if (key) { - if ((ec->key = OPENSSL_malloc(keylen)) == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if ((ec->key = OPENSSL_malloc(keylen)) == NULL) return 0; - } memcpy(ec->key, key, keylen); } ec->keylen = keylen; @@ -235,7 +231,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, if (ciph) { cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); if (!cms->d.encryptedData) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return 0; } cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index 99cf1dcb39..b877e10619 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -83,7 +83,7 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) if (cms->d.other == NULL) { cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); if (cms->d.envelopedData == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return NULL; } cms->d.envelopedData->version = 0; @@ -102,7 +102,7 @@ cms_auth_enveloped_data_init(CMS_ContentInfo *cms) if (cms->d.other == NULL) { cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData); if (cms->d.authEnvelopedData == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return NULL; } /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */ @@ -241,18 +241,18 @@ CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) - goto merr; + goto err; env = cms_enveloped_data_init(cms); if (env == NULL) - goto merr; + goto err; if (!ossl_cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, 0, ossl_cms_get0_cmsctx(cms))) - goto merr; + goto err; return cms; - merr: + err: CMS_ContentInfo_free(cms); - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return NULL; } @@ -261,6 +261,44 @@ CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) return CMS_EnvelopedData_create_ex(cipher, NULL, NULL); } +BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, + EVP_PKEY *pkey, X509 *cert, + ASN1_OCTET_STRING *secret, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) +{ + CMS_ContentInfo *ci; + BIO *bio = NULL; + int res = 0; + + if (env == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL + || (bio = BIO_new(BIO_s_mem())) == NULL) + goto end; + ci->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); + ci->d.envelopedData = env; + if (secret != NULL + && CMS_decrypt_set1_password(ci, (unsigned char *) + ASN1_STRING_get0_data(secret), + ASN1_STRING_length(secret)) != 1) + goto end; + res = CMS_decrypt(ci, secret == NULL ? pkey : NULL, + secret == NULL ? cert : NULL, detached_data, bio, flags); + + end: + if (ci != NULL) + ci->d.envelopedData = NULL; /* do not indirectly free |env| */ + CMS_ContentInfo_free(ci); + if (!res) { + BIO_free(bio); + bio = NULL; + } + return bio; +} + CMS_ContentInfo * CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, const char *propq) @@ -281,7 +319,7 @@ CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, return cms; merr: CMS_ContentInfo_free(cms); - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return NULL; } @@ -364,8 +402,10 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); - if (ri == NULL) - goto merr; + if (ri == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } pk = X509_get0_pubkey(recip); if (pk == NULL) { @@ -392,13 +432,13 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, } - if (!sk_CMS_RecipientInfo_push(ris, ri)) - goto merr; + if (!sk_CMS_RecipientInfo_push(ris, ri)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; + } return ri; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(ri, CMS_RecipientInfo); return NULL; @@ -509,11 +549,8 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, goto err; ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (ek == NULL) goto err; - } if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) goto err; @@ -590,25 +627,17 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, if (!ossl_cms_env_asn1_ctrl(ri, 1)) goto err; - if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) - goto err; + if (EVP_PKEY_is_a(pkey, "RSA")) + /* upper layer CMS code incorrectly assumes that a successful RSA + * decryption means that the key matches ciphertext (which never + * was the case, implicit rejection or not), so to make it work + * disable implicit rejection for RSA keys */ + EVP_PKEY_CTX_ctrl_str(ktri->pctx, "rsa_pkcs1_implicit_rejection", "0"); - ek = OPENSSL_malloc(eklen); - if (ek == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) goto err; - } - - if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0 - || eklen == 0 - || (fixlen != 0 && eklen != fixlen)) { - ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); - goto err; - } ret = 1; @@ -714,24 +743,32 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; + if (!ri) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); - if (!ri->d.kekri) - goto merr; + if (!ri->d.kekri) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } ri->type = CMS_RECIPINFO_KEK; kekri = ri->d.kekri; if (otherTypeId) { kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); - if (kekri->kekid->other == NULL) - goto merr; + if (kekri->kekid->other == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } } - if (!sk_CMS_RecipientInfo_push(ris, ri)) - goto merr; + if (!sk_CMS_RecipientInfo_push(ris, ri)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; + } /* After this point no calls can fail */ @@ -749,13 +786,11 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, kekri->kekid->other->keyAttr = otherType; } - X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, - OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + (void)X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, OBJ_nid2obj(nid), + V_ASN1_UNDEF, NULL); /* cannot fail */ return ri; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(ri, CMS_RecipientInfo); return NULL; @@ -814,7 +849,7 @@ static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx) { const char *alg = NULL; - switch(keylen) { + switch (keylen) { case 16: alg = "AES-128-WRAP"; break; @@ -866,14 +901,12 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, /* 8 byte prefix for AES wrap ciphers */ wkey = OPENSSL_malloc(ec->keylen + 8); - if (wkey == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (wkey == NULL) goto err; - } ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } @@ -949,14 +982,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, } ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - if (ukey == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (ukey == NULL) goto err; - } ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } @@ -1254,7 +1285,7 @@ int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); if (env->unprotectedAttrs == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); return 0; } diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index 4bd6a0dc1b..40aeb7088c 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -109,6 +109,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_OPERATION_UNSUPPORTED), + "operation unsupported"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index 6c43dd102a..0885a68216 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -121,13 +121,17 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( CMS_ReceiptRequest *rr; rr = CMS_ReceiptRequest_new(); - if (rr == NULL) - goto merr; + if (rr == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } if (id) ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); else { - if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) - goto merr; + if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32, 0) <= 0) goto err; @@ -146,9 +150,6 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( return rr; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); - err: CMS_ReceiptRequest_free(rr); return NULL; @@ -169,19 +170,20 @@ int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) int rrderlen, r = 0; rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); - if (rrderlen < 0) - goto merr; + if (rrderlen < 0) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, - V_ASN1_SEQUENCE, rrder, rrderlen)) - goto merr; + V_ASN1_SEQUENCE, rrder, rrderlen)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } r = 1; - merr: - if (!r) - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); - + err: OPENSSL_free(rrder); return r; @@ -241,7 +243,7 @@ int ossl_cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) } if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, V_ASN1_OCTET_STRING, dig, diglen)) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return 0; } return 1; diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c index dab70af73c..f5d70e84ce 100644 --- a/crypto/cms/cms_io.c +++ b/crypto/cms/cms_io.c @@ -18,6 +18,7 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); if (pos == NULL) return 0; @@ -29,7 +30,7 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) *boundary = &(*pos)->data; return 1; } - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return 0; } diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c index 4cc7e3cb61..afc210c9d0 100644 --- a/crypto/cms/cms_lib.c +++ b/crypto/cms/cms_lib.c @@ -60,7 +60,6 @@ CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) if (ci->ctx.propq == NULL) { CMS_ContentInfo_free(ci); ci = NULL; - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } } } @@ -176,7 +175,7 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) case NID_pkcs7_digest: cmsbio = ossl_cms_DigestedData_init_bio(cms); break; -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB case NID_id_smime_ct_compressedData: cmsbio = ossl_cms_CompressedData_init_bio(cms); break; @@ -210,6 +209,13 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) /* unfortunately cannot constify SMIME_write_ASN1() due to this function */ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) +{ + return ossl_cms_DataFinal(cms, cmsbio, NULL, 0); +} + +int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio, + const unsigned char *precomp_md, + unsigned int precomp_mdlen) { ASN1_OCTET_STRING **pos = CMS_get0_content(cms); @@ -248,7 +254,7 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) return ossl_cms_AuthEnvelopedData_final(cms, cmsbio); case NID_pkcs7_signed: - return ossl_cms_SignedData_final(cms, cmsbio); + return ossl_cms_SignedData_final(cms, cmsbio, precomp_md, precomp_mdlen); case NID_pkcs7_digest: return ossl_cms_DigestedData_do_final(cms, cmsbio, 0); @@ -398,7 +404,7 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached) (*pos)->flags |= ASN1_STRING_FLAG_CONT; return 1; } - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return 0; } @@ -532,9 +538,9 @@ int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { cch = sk_CMS_CertificateChoices_value(*pcerts, i); if (cch->type == CMS_CERTCHOICE_CERT) { - if (!X509_cmp(cch->d.certificate, cert)) { - ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT); - return 0; + if (X509_cmp(cch->d.certificate, cert) == 0) { + X509_free(cert); + return 1; /* cert already present */ } } } @@ -548,11 +554,12 @@ int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) { - int r; - r = CMS_add0_cert(cms, cert); - if (r > 0) - X509_up_ref(cert); - return r; + if (!X509_up_ref(cert)) + return 0; + if (CMS_add0_cert(cms, cert)) + return 1; + X509_free(cert); + return 0; } static STACK_OF(CMS_RevocationInfoChoice) @@ -604,9 +611,9 @@ CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) { - CMS_RevocationInfoChoice *rch; - rch = CMS_add0_RevocationInfoChoice(cms); - if (!rch) + CMS_RevocationInfoChoice *rch = CMS_add0_RevocationInfoChoice(cms); + + if (rch == NULL) return 0; rch->type = CMS_REVCHOICE_CRL; rch->d.crl = crl; @@ -638,7 +645,7 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) if (cch->type == 0) { if (!ossl_x509_add_cert_new(&certs, cch->d.certificate, X509_ADD_FLAG_UP_REF)) { - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); return NULL; } } @@ -660,16 +667,15 @@ STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); if (rch->type == 0) { - if (!crls) { - crls = sk_X509_CRL_new_null(); - if (!crls) + if (crls == NULL) { + if ((crls = sk_X509_CRL_new_null()) == NULL) return NULL; } - if (!sk_X509_CRL_push(crls, rch->d.crl)) { + if (!sk_X509_CRL_push(crls, rch->d.crl) + || !X509_CRL_up_ref(rch->d.crl)) { sk_X509_CRL_pop_free(crls, X509_CRL_free); return NULL; } - X509_CRL_up_ref(rch->d.crl); } } return crls; @@ -697,18 +703,23 @@ int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) { CMS_IssuerAndSerialNumber *ias; ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber); - if (!ias) + if (!ias) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); goto err; - if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) + } + if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) { + ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB); goto err; - if (!ASN1_STRING_copy(ias->serialNumber, X509_get0_serialNumber(cert))) + } + if (!ASN1_STRING_copy(ias->serialNumber, X509_get0_serialNumber(cert))) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); goto err; + } M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber); *pias = ias; return 1; err: M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber); - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } @@ -723,7 +734,7 @@ int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) } keyid = ASN1_STRING_dup(cert_keyid); if (!keyid) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return 0; } ASN1_OCTET_STRING_free(*pkeyid); diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index c262a906f8..7069021267 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -21,11 +21,9 @@ typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; -typedef struct CMS_SignedData_st CMS_SignedData; typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; -typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; typedef struct CMS_DigestedData_st CMS_DigestedData; typedef struct CMS_EncryptedData_st CMS_EncryptedData; typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; @@ -395,6 +393,9 @@ const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx); void ossl_cms_resolve_libctx(CMS_ContentInfo *ci); CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *ctx, const char *propq); +int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio, + const unsigned char *precomp_md, + unsigned int precomp_mdlen); CMS_ContentInfo *ossl_cms_DigestedData_create(const EVP_MD *md, OSSL_LIB_CTX *libctx, @@ -404,7 +405,9 @@ int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify); BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms); -int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); +int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain, + const unsigned char *precomp_md, + unsigned int precomp_mdlen); int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type, const CMS_CTX *ctx); int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c index 2373092bed..8b5beb2157 100644 --- a/crypto/cms/cms_pwri.c +++ b/crypto/cms/cms_pwri.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -82,11 +82,12 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, /* Setup algorithm identifier for cipher */ encalg = X509_ALGOR_new(); if (encalg == NULL) { - goto merr; + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; } ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } @@ -110,7 +111,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, } encalg->parameter = ASN1_TYPE_new(); if (!encalg->parameter) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { @@ -126,12 +127,16 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); - if (ri == NULL) - goto merr; + if (ri == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); - if (ri->d.pwri == NULL) - goto merr; + if (ri->d.pwri == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } ri->type = CMS_RECIPINFO_PASS; pwri = ri->d.pwri; @@ -139,17 +144,23 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, /* Since this is overwritten, free up empty structure already there */ X509_ALGOR_free(pwri->keyEncryptionAlgorithm); pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); - if (pwri->keyEncryptionAlgorithm == NULL) - goto merr; + if (pwri->keyEncryptionAlgorithm == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); - if (pwri->keyEncryptionAlgorithm->parameter == NULL) - goto merr; + if (pwri->keyEncryptionAlgorithm->parameter == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), &pwri->keyEncryptionAlgorithm->parameter-> - value.sequence)) - goto merr; + value.sequence)) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; X509_ALGOR_free(encalg); @@ -165,13 +176,13 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, CMS_RecipientInfo_set0_password(ri, pass, passlen); pwri->version = 0; - if (!sk_CMS_RecipientInfo_push(ris, ri)) - goto merr; + if (!sk_CMS_RecipientInfo_push(ris, ri)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; + } return ri; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: EVP_CIPHER_CTX_free(ctx); if (ri) @@ -201,10 +212,8 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, /* Invalid size */ return 0; } - if ((tmp = OPENSSL_malloc(inlen)) == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if ((tmp = OPENSSL_malloc(inlen)) == NULL) return 0; - } /* setup IV by decrypting last two blocks */ if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, in + inlen - 2 * blocklen, blocklen * 2) @@ -335,7 +344,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, kekctx = EVP_CIPHER_CTX_new(); if (kekctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ @@ -376,11 +385,8 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, pwri->encryptedKey->length = keylen; } else { key = OPENSSL_malloc(pwri->encryptedKey->length); - - if (key == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (key == NULL) goto err; - } if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, pwri->encryptedKey->length, kekctx)) { diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c index 61fd43fb54..e3e9a220fd 100644 --- a/crypto/cms/cms_rsa.c +++ b/crypto/cms/cms_rsa.c @@ -114,6 +114,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) const EVP_MD *md, *mgf1md; RSA_OAEP_PARAMS *oaep = NULL; ASN1_STRING *os = NULL; + ASN1_OCTET_STRING *los = NULL; X509_ALGOR *alg; EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; @@ -125,10 +126,10 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } + if (pad_mode == RSA_PKCS1_PADDING) + return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, NULL); + /* Not supported */ if (pad_mode != RSA_PKCS1_OAEP_PADDING) return 0; @@ -147,30 +148,31 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) if (!ossl_x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) goto err; if (labellen > 0) { - ASN1_OCTET_STRING *los; - - oaep->pSourceFunc = X509_ALGOR_new(); - if (oaep->pSourceFunc == NULL) - goto err; los = ASN1_OCTET_STRING_new(); + if (los == NULL) goto err; - if (!ASN1_OCTET_STRING_set(los, label, labellen)) { - ASN1_OCTET_STRING_free(los); + if (!ASN1_OCTET_STRING_set(los, label, labellen)) goto err; - } - X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), - V_ASN1_OCTET_STRING, los); + + oaep->pSourceFunc = ossl_X509_ALGOR_from_nid(NID_pSpecified, + V_ASN1_OCTET_STRING, los); + if (oaep->pSourceFunc == NULL) + goto err; + + los = NULL; } - /* create string with pss parameter encoding. */ + /* create string with oaep parameter encoding. */ if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) - goto err; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + goto err; + if (!X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os)) + goto err; os = NULL; rv = 1; err: RSA_OAEP_PARAMS_free(oaep); ASN1_STRING_free(os); + ASN1_OCTET_STRING_free(los); return rv; } @@ -203,10 +205,10 @@ static int rsa_cms_sign(CMS_SignerInfo *si) if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } + if (pad_mode == RSA_PKCS1_PADDING) + return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, NULL); + /* We don't support it */ if (pad_mode != RSA_PKCS1_PSS_PADDING) return 0; diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index cfac556957..b41e3571b2 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -38,7 +38,7 @@ static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) if (cms->d.other == NULL) { cms->d.signedData = M_ASN1_new_of(CMS_SignedData); if (!cms->d.signedData) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); return NULL; } cms->d.signedData->version = 1; @@ -53,7 +53,6 @@ static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) } /* Just initialise SignedData e.g. for certs only structure */ - int CMS_SignedData_init(CMS_ContentInfo *cms) { if (cms_signed_data_init(cms)) @@ -62,9 +61,7 @@ int CMS_SignedData_init(CMS_ContentInfo *cms) return 0; } - /* Check structures and fixup version numbers (if necessary) */ - static void cms_sd_set_version(CMS_SignedData *sd) { int i; @@ -105,8 +102,9 @@ static void cms_sd_set_version(CMS_SignedData *sd) si->version = 3; if (sd->version < 3) sd->version = 3; - } else if (si->version < 1) + } else if (si->version < 1) { si->version = 1; + } } if (sd->version < 1) @@ -136,7 +134,6 @@ static int cms_set_si_contentType_attr(CMS_ContentInfo *cms, CMS_SignerInfo *si) } /* Copy an existing messageDigest value */ - static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) { STACK_OF(CMS_SignerInfo) *sinfos; @@ -212,8 +209,9 @@ int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { if (keyid) *keyid = sid->d.subjectKeyIdentifier; - } else + } else { return 0; + } return 1; } @@ -228,17 +226,16 @@ int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) } /* Method to map any, incl. provider-implemented PKEY types to OIDs */ -/* ECDSA and DSA and all provider-delivered signatures implementation is the same */ +/* (EC)DSA and all provider-delivered signatures implementation is the same */ static int cms_generic_sign(CMS_SignerInfo *si, int verify) { if (!ossl_assert(verify == 0 || verify == 1)) return -1; if (!verify) { - int snid, hnid, pknid; - X509_ALGOR *alg1, *alg2; EVP_PKEY *pkey = si->pkey; - pknid = EVP_PKEY_get_id(pkey); + int snid, hnid, pknid = EVP_PKEY_get_id(pkey); + X509_ALGOR *alg1, *alg2; CMS_SignerInfo_get0_algs(si, NULL, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) @@ -248,6 +245,7 @@ static int cms_generic_sign(CMS_SignerInfo *si, int verify) return -1; if (pknid <= 0) { /* check whether a provider registered a NID */ const char *typename = EVP_PKEY_get0_type_name(pkey); + if (typename != NULL) pknid = OBJ_txt2nid(typename); } @@ -351,8 +349,10 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); - if (!si) - goto merr; + if (!si) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } /* Call for side-effect of computing hash and caching extensions */ X509_check_purpose(signer, -1, -1); @@ -366,7 +366,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, si->pctx = NULL; if (si->mctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } @@ -399,16 +399,6 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } } - if (!md) { - ERR_raise(ERR_LIB_CMS, CMS_R_NO_DIGEST_SET); - goto err; - } - - if (md == NULL) { - ERR_raise(ERR_LIB_CMS, CMS_R_NO_DIGEST_SET); - goto err; - } - X509_ALGOR_set_md(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ @@ -424,13 +414,15 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { - alg = X509_ALGOR_new(); - if (alg == NULL) - goto merr; + if ((alg = X509_ALGOR_new()) == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); + goto err; + } X509_ALGOR_set_md(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); - goto merr; + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; } } @@ -446,18 +438,23 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); - if (!si->signedAttrs) - goto merr; + if (!si->signedAttrs) { + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; + } } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; + i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - if (!i) - goto merr; + if (!i) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } } if (flags & CMS_CADES) { ESS_SIGNING_CERT *sc = NULL; @@ -493,8 +490,10 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ - if (!CMS_add1_cert(cms, signer)) - goto merr; + if (!CMS_add1_cert(cms, signer)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } } if (flags & CMS_KEY_PARAM) { @@ -517,15 +516,15 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } } - if (!sd->signerInfos) + if (sd->signerInfos == NULL) sd->signerInfos = sk_CMS_SignerInfo_new_null(); - if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) - goto merr; + if (sd->signerInfos == NULL || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB); + goto err; + } return si; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(si, CMS_SignerInfo); return NULL; @@ -560,21 +559,22 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) else tt = X509_gmtime_adj(NULL, 0); - if (tt == NULL) - goto merr; + if (tt == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB); + goto err; + } if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, - tt->type, tt, -1) <= 0) - goto merr; + tt->type, tt, -1) <= 0) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } r = 1; - merr: + err: if (t == NULL) ASN1_TIME_free(tt); - if (!r) - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); - return r; } @@ -674,7 +674,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { cch = sk_CMS_CertificateChoices_value(certs, j); - if (cch->type != 0) + if (cch->type != CMS_CERTCHOICE_CERT) continue; x = cch->d.certificate; if (CMS_SignerInfo_cert_cmp(si, x) == 0) { @@ -707,7 +707,9 @@ ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) } static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, - CMS_SignerInfo *si, BIO *chain) + CMS_SignerInfo *si, BIO *chain, + const unsigned char *md, + unsigned int mdlen) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); int r = 0; @@ -715,7 +717,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); if (mctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return 0; } @@ -733,13 +735,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, /* * If any signed attributes calculate and add messageDigest attribute */ - if (CMS_signed_get_attr_count(si) >= 0) { - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; + unsigned char computed_md[EVP_MAX_MD_SIZE]; - if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) - goto err; + if (md == NULL) { + if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen)) + goto err; + md = computed_md; + } if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING, md, mdlen)) goto err; @@ -752,18 +755,17 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, } else if (si->pctx) { unsigned char *sig; size_t siglen; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; + unsigned char computed_md[EVP_MAX_MD_SIZE]; pctx = si->pctx; - if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) - goto err; + if (md == NULL) { + if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen)) + goto err; + md = computed_md; + } siglen = EVP_PKEY_get_size(si->pkey); - sig = OPENSSL_malloc(siglen); - if (sig == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (siglen == 0 || (sig = OPENSSL_malloc(siglen)) == NULL) goto err; - } if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) { OPENSSL_free(sig); goto err; @@ -773,11 +775,13 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, unsigned char *sig; unsigned int siglen; - sig = OPENSSL_malloc(EVP_PKEY_get_size(si->pkey)); - if (sig == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (md != NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_OPERATION_UNSUPPORTED); goto err; } + siglen = EVP_PKEY_get_size(si->pkey); + if (siglen == 0 || (sig = OPENSSL_malloc(siglen)) == NULL) + goto err; if (!EVP_SignFinal_ex(mctx, sig, &siglen, si->pkey, ossl_cms_ctx_get0_libctx(ctx), ossl_cms_ctx_get0_propq(ctx))) { @@ -797,7 +801,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, } -int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) +int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain, + const unsigned char *precomp_md, + unsigned int precomp_mdlen) { STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; @@ -806,7 +812,8 @@ int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (!cms_SignerInfo_content_sign(cms, si, chain)) + if (!cms_SignerInfo_content_sign(cms, si, chain, + precomp_md, precomp_mdlen)) return 0; } cms->d.signedData->encapContentInfo->partial = 0; @@ -824,7 +831,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) char md_name[OSSL_MAX_NAME_SIZE]; if (OBJ_obj2txt(md_name, sizeof(md_name), - si->digestAlgorithm->algorithm, 0) <= 0) + si->digestAlgorithm->algorithm, 0) <= 0) return 0; if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { @@ -835,9 +842,9 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) if (!ossl_cms_si_check_attributes(si)) goto err; - if (si->pctx) + if (si->pctx) { pctx = si->pctx; - else { + } else { EVP_MD_CTX_reset(mctx); if (EVP_DigestSignInit_ex(mctx, &pctx, md_name, ossl_cms_ctx_get0_libctx(ctx), @@ -911,7 +918,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) (void)ERR_pop_to_mark(); if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } mctx = si->mctx; @@ -943,7 +950,6 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) } /* Create a chain of digest BIOs from a CMS ContentInfo */ - BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms) { int i; @@ -985,7 +991,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) unsigned int mlen; if (mctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB); goto err; } /* If we have any signed attributes look for messageDigest value */ @@ -1008,7 +1014,6 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) } /* If messageDigest found compare it */ - if (os != NULL) { if (mlen != (unsigned int)os->length) { ERR_raise(ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); @@ -1018,8 +1023,9 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) if (memcmp(mval, os->data, mlen)) { ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE); r = 0; - } else + } else { r = 1; + } } else { const EVP_MD *md = EVP_MD_CTX_get0_md(mctx); const CMS_CTX *ctx = si->cms_ctx; @@ -1051,6 +1057,47 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) } +BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data, + STACK_OF(X509) *scerts, X509_STORE *store, + STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls, + unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) +{ + CMS_ContentInfo *ci; + BIO *bio = NULL; + int i, res = 0; + + if (sd == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL) + return NULL; + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto end; + ci->contentType = OBJ_nid2obj(NID_pkcs7_signed); + ci->d.signedData = sd; + + for (i = 0; i < sk_X509_num(extra); i++) + if (!CMS_add1_cert(ci, sk_X509_value(extra, i))) + goto end; + for (i = 0; i < sk_X509_CRL_num(crls); i++) + if (!CMS_add1_crl(ci, sk_X509_CRL_value(crls, i))) + goto end; + res = CMS_verify(ci, scerts, store, detached_data, bio, flags); + + end: + if (ci != NULL) + ci->d.signedData = NULL; /* do not indirectly free |sd| */ + CMS_ContentInfo_free(ci); + if (!res) { + BIO_free(bio); + bio = NULL; + } + return bio; +} + int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) { unsigned char *smder = NULL; @@ -1078,14 +1125,13 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, return 0; } } - alg = X509_ALGOR_new(); + alg = ossl_X509_ALGOR_from_nid(algnid, key != NULL ? V_ASN1_INTEGER : + V_ASN1_UNDEF, key); if (alg == NULL) { ASN1_INTEGER_free(key); return 0; } - X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), - key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); if (*algs == NULL) *algs = sk_X509_ALGOR_new_null(); if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) { @@ -1096,7 +1142,6 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, } /* Check to see if a cipher exists and if so add S/MIME capabilities */ - static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) { if (EVP_get_cipherbynid(nid)) diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index 479038d573..99a72f4dff 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -39,7 +39,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) tmpout = cms_get_text_bio(out, flags); if (tmpout == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); goto err; } @@ -259,7 +259,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, - STACK_OF(X509) *certs, + STACK_OF(X509) *untrusted, STACK_OF(X509_CRL) *crls, STACK_OF(X509) **chain, const CMS_CTX *cms_ctx) @@ -271,11 +271,11 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, ctx = X509_STORE_CTX_new_ex(ossl_cms_ctx_get0_libctx(cms_ctx), ossl_cms_ctx_get0_propq(cms_ctx)); if (ctx == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB); goto err; } CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); - if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { + if (!X509_STORE_CTX_init(ctx, store, signer, untrusted)) { ERR_raise(ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR); goto err; } @@ -301,6 +301,7 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, } +/* This strongly overlaps with PKCS7_verify() */ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) { @@ -336,7 +337,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); - if (signer) + if (signer != NULL) scount++; } @@ -355,10 +356,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, if (cadesVerify) { /* Certificate trust chain is required to check CAdES signature */ si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0])); - if (si_chains == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + if (si_chains == NULL) goto err; - } } cms_certs = CMS_get1_certs(cms); if (!(flags & CMS_NOCRL)) @@ -405,7 +404,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, len = BIO_get_mem_data(dcont, &ptr); tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len); if (tmpin == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB); goto err2; } } else { @@ -422,7 +421,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, */ tmpout = cms_get_text_bio(out, flags); if (tmpout == NULL) { - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); goto err; } cmsbio = CMS_dataInit(cms, tmpout); @@ -479,10 +478,10 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, err2: if (si_chains != NULL) { for (i = 0; i < scount; ++i) - sk_X509_pop_free(si_chains[i], X509_free); + OSSL_STACK_OF_X509_free(si_chains[i]); OPENSSL_free(si_chains); } - sk_X509_pop_free(cms_certs, X509_free); + OSSL_STACK_OF_X509_free(cms_certs); sk_X509_CRL_pop_free(crls, X509_CRL_free); return ret; @@ -510,12 +509,16 @@ CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, int i; cms = CMS_ContentInfo_new_ex(libctx, propq); - if (cms == NULL || !CMS_SignedData_init(cms)) - goto merr; + if (cms == NULL || !CMS_SignedData_init(cms)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } if (flags & CMS_ASCIICRLF && !CMS_set1_eContentType(cms, - OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) + OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); goto err; + } if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR); @@ -525,8 +528,10 @@ CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, for (i = 0; i < sk_X509_num(certs); i++) { X509 *x = sk_X509_value(certs, i); - if (!CMS_add1_cert(cms, x)) - goto merr; + if (!CMS_add1_cert(cms, x)) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } } if (!(flags & CMS_DETACHED)) @@ -538,9 +543,6 @@ CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, else goto err; - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); - err: CMS_ContentInfo_free(cms); return NULL; @@ -558,7 +560,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, { CMS_SignerInfo *rct_si; CMS_ContentInfo *cms = NULL; - ASN1_OCTET_STRING **pos, *os; + ASN1_OCTET_STRING **pos, *os = NULL; BIO *rct_cont = NULL; int r = 0; const CMS_CTX *ctx = si->cms_ctx; @@ -620,6 +622,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, if (r) return cms; CMS_ContentInfo_free(cms); + ASN1_OCTET_STRING_free(os); return NULL; } @@ -636,8 +639,10 @@ CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data, cms = (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq) : CMS_EnvelopedData_create_ex(cipher, libctx, propq); - if (cms == NULL) - goto merr; + if (cms == NULL) { + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); + goto err; + } for (i = 0; i < sk_X509_num(certs); i++) { recip = sk_X509_value(certs, i); if (!CMS_add1_recipient_cert(cms, recip, flags)) { @@ -653,10 +658,8 @@ CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data, || CMS_final(cms, data, NULL, flags)) return cms; else - goto err; + ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); - merr: - ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: CMS_ContentInfo_free(cms); return NULL; @@ -914,7 +917,32 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) } -#ifdef ZLIB +int CMS_final_digest(CMS_ContentInfo *cms, + const unsigned char *md, unsigned int mdlen, + BIO *dcont, unsigned int flags) +{ + BIO *cmsbio; + int ret = 0; + + if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); + return 0; + } + + (void)BIO_flush(cmsbio); + + if (!ossl_cms_DataFinal(cms, cmsbio, md, mdlen)) { + ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR); + goto err; + } + ret = 1; + +err: + do_free_upto(cmsbio, dcont); + return ret; +} + +#ifndef OPENSSL_NO_ZLIB int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) diff --git a/crypto/comp/build.info b/crypto/comp/build.info index 65df46a175..7892c96ff2 100644 --- a/crypto/comp/build.info +++ b/crypto/comp/build.info @@ -1,4 +1,6 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]= \ comp_lib.c comp_err.c \ + c_brotli.c \ + c_zstd.c \ c_zlib.c diff --git a/crypto/comp/c_brotli.c b/crypto/comp/c_brotli.c new file mode 100644 index 0000000000..07e1e76471 --- /dev/null +++ b/crypto/comp/c_brotli.c @@ -0,0 +1,800 @@ +/* + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Uses brotli compression library from https://github.com/google/brotli + */ + +#include +#include +#include +#include +#include "internal/comp.h" +#include +#include "crypto/cryptlib.h" +#include "internal/bio.h" +#include "internal/thread_once.h" +#include "comp_local.h" + +COMP_METHOD *COMP_brotli(void); + +#ifdef OPENSSL_NO_BROTLI +# undef BROTLI_SHARED +#else + +# include +# include + +/* memory allocations functions for brotli initialisation */ +static void *brotli_alloc(void *opaque, size_t size) +{ + return OPENSSL_zalloc(size); +} + +static void brotli_free(void *opaque, void *address) +{ + OPENSSL_free(address); +} + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the BROTLI.DLL be available in order for the OpenSSL DLLs to + * work. Therefore, all BROTLI routines are loaded at run time + * and we do not link to a .LIB file when BROTLI_SHARED is set. + */ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# endif + +# ifdef BROTLI_SHARED +# include "internal/dso.h" + +/* Function pointers */ +typedef BrotliEncoderState *(*encode_init_ft)(brotli_alloc_func, brotli_free_func, void *); +typedef BROTLI_BOOL (*encode_stream_ft)(BrotliEncoderState *, BrotliEncoderOperation, size_t *, const uint8_t **, size_t *, uint8_t **, size_t *); +typedef BROTLI_BOOL (*encode_has_more_ft)(BrotliEncoderState *); +typedef void (*encode_end_ft)(BrotliEncoderState *); +typedef BROTLI_BOOL (*encode_oneshot_ft)(int, int, BrotliEncoderMode, size_t, const uint8_t in[], size_t *, uint8_t out[]); + +typedef BrotliDecoderState *(*decode_init_ft)(brotli_alloc_func, brotli_free_func, void *); +typedef BROTLI_BOOL (*decode_stream_ft)(BrotliDecoderState *, size_t *, const uint8_t **, size_t *, uint8_t **, size_t *); +typedef BROTLI_BOOL (*decode_has_more_ft)(BrotliDecoderState *); +typedef void (*decode_end_ft)(BrotliDecoderState *); +typedef BrotliDecoderErrorCode (*decode_error_ft)(BrotliDecoderState *); +typedef const char *(*decode_error_string_ft)(BrotliDecoderErrorCode); +typedef BROTLI_BOOL (*decode_is_finished_ft)(BrotliDecoderState *); +typedef BrotliDecoderResult (*decode_oneshot_ft)(size_t, const uint8_t in[], size_t *, uint8_t out[]); + +static encode_init_ft p_encode_init = NULL; +static encode_stream_ft p_encode_stream = NULL; +static encode_has_more_ft p_encode_has_more = NULL; +static encode_end_ft p_encode_end = NULL; +static encode_oneshot_ft p_encode_oneshot = NULL; + +static decode_init_ft p_decode_init = NULL; +static decode_stream_ft p_decode_stream = NULL; +static decode_has_more_ft p_decode_has_more = NULL; +static decode_end_ft p_decode_end = NULL; +static decode_error_ft p_decode_error = NULL; +static decode_error_string_ft p_decode_error_string = NULL; +static decode_is_finished_ft p_decode_is_finished = NULL; +static decode_oneshot_ft p_decode_oneshot = NULL; + +static DSO *brotli_encode_dso = NULL; +static DSO *brotli_decode_dso = NULL; + +# define BrotliEncoderCreateInstance p_encode_init +# define BrotliEncoderCompressStream p_encode_stream +# define BrotliEncoderHasMoreOutput p_encode_has_more +# define BrotliEncoderDestroyInstance p_encode_end +# define BrotliEncoderCompress p_encode_oneshot + +# define BrotliDecoderCreateInstance p_decode_init +# define BrotliDecoderDecompressStream p_decode_stream +# define BrotliDecoderHasMoreOutput p_decode_has_more +# define BrotliDecoderDestroyInstance p_decode_end +# define BrotliDecoderGetErrorCode p_decode_error +# define BrotliDecoderErrorString p_decode_error_string +# define BrotliDecoderIsFinished p_decode_is_finished +# define BrotliDecoderDecompress p_decode_oneshot + +# endif /* ifdef BROTLI_SHARED */ + + +struct brotli_state { + BrotliEncoderState *encoder; + BrotliDecoderState *decoder; +}; + +static int brotli_stateful_init(COMP_CTX *ctx) +{ + struct brotli_state *state = OPENSSL_zalloc(sizeof(*state)); + + if (state == NULL) + return 0; + + state->encoder = BrotliEncoderCreateInstance(brotli_alloc, brotli_free, NULL); + if (state->encoder == NULL) + goto err; + + state->decoder = BrotliDecoderCreateInstance(brotli_alloc, brotli_free, NULL); + if (state->decoder == NULL) + goto err; + + ctx->data = state; + return 1; + err: + BrotliDecoderDestroyInstance(state->decoder); + BrotliEncoderDestroyInstance(state->encoder); + OPENSSL_free(state); + return 0; +} + +static void brotli_stateful_finish(COMP_CTX *ctx) +{ + struct brotli_state *state = ctx->data; + + if (state != NULL) { + BrotliDecoderDestroyInstance(state->decoder); + BrotliEncoderDestroyInstance(state->encoder); + OPENSSL_free(state); + ctx->data = NULL; + } +} + +static ossl_ssize_t brotli_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + BROTLI_BOOL done; + struct brotli_state *state = ctx->data; + size_t in_avail = ilen; + size_t out_avail = olen; + + if (state == NULL || olen > OSSL_SSIZE_MAX) + return -1; + + if (ilen == 0) + return 0; + + /* + * The finish API does not provide a final output buffer, + * so each compress operation has to be flushed, if all + * the input data can't be accepted, or there is more output, + * this has to be considered an error, since there is no more + * output buffer space + */ + done = BrotliEncoderCompressStream(state->encoder, BROTLI_OPERATION_FLUSH, + &in_avail, (const uint8_t**)&in, + &out_avail, &out, NULL); + if (done == BROTLI_FALSE + || in_avail != 0 + || BrotliEncoderHasMoreOutput(state->encoder)) + return -1; + + if (out_avail > olen) + return -1; + return (ossl_ssize_t)(olen - out_avail); +} + +static ossl_ssize_t brotli_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + BrotliDecoderResult result; + struct brotli_state *state = ctx->data; + size_t in_avail = ilen; + size_t out_avail = olen; + + if (state == NULL || olen > OSSL_SSIZE_MAX) + return -1; + + if (ilen == 0) + return 0; + + result = BrotliDecoderDecompressStream(state->decoder, &in_avail, + (const uint8_t**)&in, &out_avail, + &out, NULL); + if (result == BROTLI_DECODER_RESULT_ERROR + || in_avail != 0 + || BrotliDecoderHasMoreOutput(state->decoder)) + return -1; + + if (out_avail > olen) + return -1; + return (ossl_ssize_t)(olen - out_avail); +} + +static COMP_METHOD brotli_stateful_method = { + NID_brotli, + LN_brotli, + brotli_stateful_init, + brotli_stateful_finish, + brotli_stateful_compress_block, + brotli_stateful_expand_block +}; + +static int brotli_oneshot_init(COMP_CTX *ctx) +{ + return 1; +} + +static void brotli_oneshot_finish(COMP_CTX *ctx) +{ +} + +static ossl_ssize_t brotli_oneshot_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + size_t out_size = olen; + ossl_ssize_t ret; + + if (ilen == 0) + return 0; + + if (BrotliEncoderCompress(BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, + BROTLI_DEFAULT_MODE, ilen, in, + &out_size, out) == BROTLI_FALSE) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + ret = (ossl_ssize_t)out_size; + if (ret < 0) + return -1; + return ret; +} + +static ossl_ssize_t brotli_oneshot_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + size_t out_size = olen; + ossl_ssize_t ret; + + if (ilen == 0) + return 0; + + if (BrotliDecoderDecompress(ilen, in, &out_size, out) != BROTLI_DECODER_RESULT_SUCCESS) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + ret = (ossl_ssize_t)out_size; + if (ret < 0) + return -1; + return ret; +} + +static COMP_METHOD brotli_oneshot_method = { + NID_brotli, + LN_brotli, + brotli_oneshot_init, + brotli_oneshot_finish, + brotli_oneshot_compress_block, + brotli_oneshot_expand_block +}; + +static CRYPTO_ONCE brotli_once = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_comp_brotli_init) +{ +# ifdef BROTLI_SHARED +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# define LIBBROTLIENC "BROTLIENC" +# define LIBBROTLIDEC "BROTLIDEC" +# else +# define LIBBROTLIENC "brotlienc" +# define LIBBROTLIDEC "brotlidec" +# endif + + brotli_encode_dso = DSO_load(NULL, LIBBROTLIENC, NULL, 0); + if (brotli_encode_dso != NULL) { + p_encode_init = (encode_init_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderCreateInstance"); + p_encode_stream = (encode_stream_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderCompressStream"); + p_encode_has_more = (encode_has_more_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderHasMoreOutput"); + p_encode_end = (encode_end_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderDestroyInstance"); + p_encode_oneshot = (encode_oneshot_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderCompress"); + } + + brotli_decode_dso = DSO_load(NULL, LIBBROTLIDEC, NULL, 0); + if (brotli_decode_dso != NULL) { + p_decode_init = (decode_init_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderCreateInstance"); + p_decode_stream = (decode_stream_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderDecompressStream"); + p_decode_has_more = (decode_has_more_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderHasMoreOutput"); + p_decode_end = (decode_end_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderDestroyInstance"); + p_decode_error = (decode_error_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderGetErrorCode"); + p_decode_error_string = (decode_error_string_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderErrorString"); + p_decode_is_finished = (decode_is_finished_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderIsFinished"); + p_decode_oneshot = (decode_oneshot_ft)DSO_bind_func(brotli_decode_dso, "BrotliDecoderDecompress"); + } + + if (p_encode_init == NULL || p_encode_stream == NULL || p_encode_has_more == NULL + || p_encode_end == NULL || p_encode_oneshot == NULL || p_decode_init == NULL + || p_decode_stream == NULL || p_decode_has_more == NULL || p_decode_end == NULL + || p_decode_error == NULL || p_decode_error_string == NULL || p_decode_is_finished == NULL + || p_decode_oneshot == NULL) { + ossl_comp_brotli_cleanup(); + return 0; + } +# endif + return 1; +} +#endif /* ifndef BROTLI / else */ + +COMP_METHOD *COMP_brotli(void) +{ + COMP_METHOD *meth = NULL; + +#ifndef OPENSSL_NO_BROTLI + if (RUN_ONCE(&brotli_once, ossl_comp_brotli_init)) + meth = &brotli_stateful_method; +#endif + return meth; +} + +COMP_METHOD *COMP_brotli_oneshot(void) +{ + COMP_METHOD *meth = NULL; + +#ifndef OPENSSL_NO_BROTLI + if (RUN_ONCE(&brotli_once, ossl_comp_brotli_init)) + meth = &brotli_oneshot_method; +#endif + return meth; +} + +/* Also called from OPENSSL_cleanup() */ +void ossl_comp_brotli_cleanup(void) +{ +#ifdef BROTLI_SHARED + DSO_free(brotli_encode_dso); + brotli_encode_dso = NULL; + DSO_free(brotli_decode_dso); + brotli_decode_dso = NULL; + p_encode_init = NULL; + p_encode_stream = NULL; + p_encode_has_more = NULL; + p_encode_end = NULL; + p_encode_oneshot = NULL; + p_decode_init = NULL; + p_decode_stream = NULL; + p_decode_has_more = NULL; + p_decode_end = NULL; + p_decode_error = NULL; + p_decode_error_string = NULL; + p_decode_is_finished = NULL; + p_decode_oneshot = NULL; +#endif +} + +#ifndef OPENSSL_NO_BROTLI + +/* Brotli-based compression/decompression filter BIO */ + +typedef struct { + struct { /* input structure */ + size_t avail_in; + unsigned char *next_in; + size_t avail_out; + unsigned char *next_out; + unsigned char *buf; + size_t bufsize; + BrotliDecoderState *state; + } decode; + struct { /* output structure */ + size_t avail_in; + unsigned char *next_in; + size_t avail_out; + unsigned char *next_out; + unsigned char *buf; + size_t bufsize; + BrotliEncoderState *state; + int mode; /* Encoder mode to use */ + int done; + unsigned char *ptr; + size_t count; + } encode; +} BIO_BROTLI_CTX; + +# define BROTLI_DEFAULT_BUFSIZE 1024 + +static int bio_brotli_new(BIO *bi); +static int bio_brotli_free(BIO *bi); +static int bio_brotli_read(BIO *b, char *out, int outl); +static int bio_brotli_write(BIO *b, const char *in, int inl); +static long bio_brotli_ctrl(BIO *b, int cmd, long num, void *ptr); +static long bio_brotli_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); + +static const BIO_METHOD bio_meth_brotli = { + BIO_TYPE_COMP, + "brotli", + /* TODO: Convert to new style write function */ + bwrite_conv, + bio_brotli_write, + /* TODO: Convert to new style read function */ + bread_conv, + bio_brotli_read, + NULL, /* bio_brotli_puts, */ + NULL, /* bio_brotli_gets, */ + bio_brotli_ctrl, + bio_brotli_new, + bio_brotli_free, + bio_brotli_callback_ctrl +}; +#endif + +const BIO_METHOD *BIO_f_brotli(void) +{ +#ifndef OPENSSL_NO_BROTLI + if (RUN_ONCE(&brotli_once, ossl_comp_brotli_init)) + return &bio_meth_brotli; +#endif + return NULL; +} + +#ifndef OPENSSL_NO_BROTLI + +static int bio_brotli_new(BIO *bi) +{ + BIO_BROTLI_CTX *ctx; + +# ifdef BROTLI_SHARED + if (!RUN_ONCE(&brotli_once, ossl_comp_brotli_init)) { + ERR_raise(ERR_LIB_COMP, COMP_R_BROTLI_NOT_SUPPORTED); + return 0; + } +# endif + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->decode.bufsize = BROTLI_DEFAULT_BUFSIZE; + ctx->decode.state = BrotliDecoderCreateInstance(brotli_alloc, brotli_free, NULL); + if (ctx->decode.state == NULL) + goto err; + ctx->encode.bufsize = BROTLI_DEFAULT_BUFSIZE; + ctx->encode.state = BrotliEncoderCreateInstance(brotli_alloc, brotli_free, NULL); + if (ctx->encode.state == NULL) + goto err; + ctx->encode.mode = BROTLI_DEFAULT_MODE; + BIO_set_init(bi, 1); + BIO_set_data(bi, ctx); + + return 1; + + err: + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + BrotliDecoderDestroyInstance(ctx->decode.state); + BrotliEncoderDestroyInstance(ctx->encode.state); + OPENSSL_free(ctx); + return 0; +} + +static int bio_brotli_free(BIO *bi) +{ + BIO_BROTLI_CTX *ctx; + + if (bi == NULL) + return 0; + + ctx = BIO_get_data(bi); + if (ctx != NULL) { + BrotliDecoderDestroyInstance(ctx->decode.state); + OPENSSL_free(ctx->decode.buf); + BrotliEncoderDestroyInstance(ctx->encode.state); + OPENSSL_free(ctx->encode.buf); + OPENSSL_free(ctx); + } + BIO_set_data(bi, NULL); + BIO_set_init(bi, 0); + + return 1; +} + +static int bio_brotli_read(BIO *b, char *out, int outl) +{ + BIO_BROTLI_CTX *ctx; + BrotliDecoderResult bret; + int ret; + BIO *next = BIO_next(b); + + if (out == NULL || outl <= 0) { + ERR_raise(ERR_LIB_COMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#if INT_MAX > SIZE_MAX + if ((unsigned int)outl > SIZE_MAX) { + ERR_raise(ERR_LIB_COMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#endif + + ctx = BIO_get_data(b); + BIO_clear_retry_flags(b); + if (ctx->decode.buf == NULL) { + ctx->decode.buf = OPENSSL_malloc(ctx->decode.bufsize); + if (ctx->decode.buf == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->decode.next_in = ctx->decode.buf; + ctx->decode.avail_in = 0; + } + + /* Copy output data directly to supplied buffer */ + ctx->decode.next_out = (unsigned char *)out; + ctx->decode.avail_out = (size_t)outl; + for (;;) { + /* Decompress while data available */ + while (ctx->decode.avail_in > 0 || BrotliDecoderHasMoreOutput(ctx->decode.state)) { + bret = BrotliDecoderDecompressStream(ctx->decode.state, &ctx->decode.avail_in, (const uint8_t**)&ctx->decode.next_in, + &ctx->decode.avail_out, &ctx->decode.next_out, NULL); + if (bret == BROTLI_DECODER_RESULT_ERROR) { + ERR_raise(ERR_LIB_COMP, COMP_R_BROTLI_DECODE_ERROR); + ERR_add_error_data(1, BrotliDecoderErrorString(BrotliDecoderGetErrorCode(ctx->decode.state))); + return 0; + } + /* If EOF or we've read everything then return */ + if (BrotliDecoderIsFinished(ctx->decode.state) || ctx->decode.avail_out == 0) + return (int)(outl - ctx->decode.avail_out); + } + + /* If EOF */ + if (BrotliDecoderIsFinished(ctx->decode.state)) + return 0; + + /* + * No data in input buffer try to read some in, if an error then + * return the total data read. + */ + ret = BIO_read(next, ctx->decode.buf, ctx->decode.bufsize); + if (ret <= 0) { + /* Total data read */ + int tot = outl - ctx->decode.avail_out; + + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + ctx->decode.avail_in = ret; + ctx->decode.next_in = ctx->decode.buf; + } +} + +static int bio_brotli_write(BIO *b, const char *in, int inl) +{ + BIO_BROTLI_CTX *ctx; + BROTLI_BOOL brret; + int ret; + BIO *next = BIO_next(b); + + if (in == NULL || inl <= 0) { + ERR_raise(ERR_LIB_COMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#if INT_MAX > SIZE_MAX + if ((unsigned int)inl > SIZE_MAX) { + ERR_raise(ERR_LIB_COMP, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } +#endif + + ctx = BIO_get_data(b); + if (ctx->encode.done) + return 0; + + BIO_clear_retry_flags(b); + if (ctx->encode.buf == NULL) { + ctx->encode.buf = OPENSSL_malloc(ctx->encode.bufsize); + if (ctx->encode.buf == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->encode.ptr = ctx->encode.buf; + ctx->encode.count = 0; + ctx->encode.next_out = ctx->encode.buf; + ctx->encode.avail_out = ctx->encode.bufsize; + } + /* Obtain input data directly from supplied buffer */ + ctx->encode.next_in = (unsigned char *)in; + ctx->encode.avail_in = (size_t)inl; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->encode.count > 0) { + ret = BIO_write(next, ctx->encode.ptr, ctx->encode.count); + if (ret <= 0) { + /* Total data written */ + int tot = inl - ctx->encode.avail_in; + + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + ctx->encode.ptr += ret; + ctx->encode.count -= ret; + } + + /* Have we consumed all supplied data? */ + if (ctx->encode.avail_in == 0 && !BrotliEncoderHasMoreOutput(ctx->encode.state)) + return inl; + + /* Compress some more */ + + /* Reset buffer */ + ctx->encode.ptr = ctx->encode.buf; + ctx->encode.next_out = ctx->encode.buf; + ctx->encode.avail_out = ctx->encode.bufsize; + /* Compress some more */ + brret = BrotliEncoderCompressStream(ctx->encode.state, BROTLI_OPERATION_FLUSH, &ctx->encode.avail_in, (const uint8_t**)&ctx->encode.next_in, + &ctx->encode.avail_out, &ctx->encode.next_out, NULL); + if (brret != BROTLI_TRUE) { + ERR_raise(ERR_LIB_COMP, COMP_R_BROTLI_ENCODE_ERROR); + ERR_add_error_data(1, "brotli encoder error"); + return 0; + } + ctx->encode.count = ctx->encode.bufsize - ctx->encode.avail_out; + } +} + +static int bio_brotli_flush(BIO *b) +{ + BIO_BROTLI_CTX *ctx; + BROTLI_BOOL brret; + int ret; + BIO *next = BIO_next(b); + + ctx = BIO_get_data(b); + + /* If no data written or already flush show success */ + if (ctx->encode.buf == NULL || (ctx->encode.done && ctx->encode.count == 0)) + return 1; + + BIO_clear_retry_flags(b); + /* No more input data */ + ctx->encode.next_in = NULL; + ctx->encode.avail_in = 0; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->encode.count > 0) { + ret = BIO_write(next, ctx->encode.ptr, ctx->encode.count); + if (ret <= 0) { + BIO_copy_next_retry(b); + return ret; + } + ctx->encode.ptr += ret; + ctx->encode.count -= ret; + } + if (ctx->encode.done) + return 1; + + /* Compress some more */ + + /* Reset buffer */ + ctx->encode.ptr = ctx->encode.buf; + ctx->encode.next_out = ctx->encode.buf; + ctx->encode.avail_out = ctx->encode.bufsize; + /* Compress some more */ + brret = BrotliEncoderCompressStream(ctx->encode.state, BROTLI_OPERATION_FINISH, &ctx->encode.avail_in, + (const uint8_t**)&ctx->encode.next_in, &ctx->encode.avail_out, &ctx->encode.next_out, NULL); + if (brret != BROTLI_TRUE) { + ERR_raise(ERR_LIB_COMP, COMP_R_BROTLI_DECODE_ERROR); + ERR_add_error_data(1, "brotli encoder error"); + return 0; + } + if (!BrotliEncoderHasMoreOutput(ctx->encode.state) && ctx->encode.avail_in == 0) + ctx->encode.done = 1; + ctx->encode.count = ctx->encode.bufsize - ctx->encode.avail_out; + } +} + +static long bio_brotli_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_BROTLI_CTX *ctx; + unsigned char *tmp; + int ret = 0, *ip; + size_t ibs, obs; + BIO *next = BIO_next(b); + + if (next == NULL) + return 0; + ctx = BIO_get_data(b); + switch (cmd) { + + case BIO_CTRL_RESET: + ctx->encode.count = 0; + ctx->encode.done = 0; + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = bio_brotli_flush(b); + if (ret > 0) { + ret = BIO_flush(next); + BIO_copy_next_retry(b); + } + break; + + case BIO_C_SET_BUFF_SIZE: + ibs = ctx->decode.bufsize; + obs = ctx->encode.bufsize; + if (ptr != NULL) { + ip = ptr; + if (*ip == 0) + ibs = (size_t)num; + else + obs = (size_t)num; + } else { + ibs = (size_t)num; + obs = ibs; + } + + if (ibs > 0 && ibs != ctx->decode.bufsize) { + /* Do not free/alloc, only reallocate */ + if (ctx->decode.buf != NULL) { + tmp = OPENSSL_realloc(ctx->decode.buf, ibs); + if (tmp == NULL) + return 0; + ctx->decode.buf = tmp; + } + ctx->decode.bufsize = ibs; + } + + if (obs > 0 && obs != ctx->encode.bufsize) { + /* Do not free/alloc, only reallocate */ + if (ctx->encode.buf != NULL) { + tmp = OPENSSL_realloc(ctx->encode.buf, obs); + if (tmp == NULL) + return 0; + ctx->encode.buf = tmp; + } + ctx->encode.bufsize = obs; + } + ret = 1; + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_WPENDING: + if (BrotliEncoderHasMoreOutput(ctx->encode.state)) + ret = 1; + else + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + case BIO_CTRL_PENDING: + if (!BrotliDecoderIsFinished(ctx->decode.state)) + ret = 1; + else + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + default: + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + } + + return ret; +} + +static long bio_brotli_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + BIO *next = BIO_next(b); + if (next == NULL) + return 0; + return BIO_callback_ctrl(next, cmd, fp); +} + +#endif diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 9a7087e444..0fbab8f014 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,16 +20,7 @@ COMP_METHOD *COMP_zlib(void); -static COMP_METHOD zlib_method_nozlib = { - NID_undef, - "(undef)", - NULL, - NULL, - NULL, - NULL, -}; - -#ifndef ZLIB +#ifdef OPENSSL_NO_ZLIB # undef ZLIB_SHARED #else @@ -37,12 +28,12 @@ static COMP_METHOD zlib_method_nozlib = { static int zlib_stateful_init(COMP_CTX *ctx); static void zlib_stateful_finish(COMP_CTX *ctx); -static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); -static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); +static ossl_ssize_t zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen); +static ossl_ssize_t zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen); /* memory allocations functions for zlib initialisation */ static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size) @@ -83,8 +74,10 @@ static COMP_METHOD zlib_stateful_method = { # include "internal/dso.h" /* Function pointers */ -typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, +typedef int (*compress_ft) (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +typedef int (*uncompress_ft) (Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); typedef int (*inflateEnd_ft) (z_streamp strm); typedef int (*inflate_ft) (z_streamp strm, int flush); typedef int (*inflateInit__ft) (z_streamp strm, @@ -95,6 +88,7 @@ typedef int (*deflateInit__ft) (z_streamp strm, int level, const char *version, int stream_size); typedef const char *(*zError__ft) (int err); static compress_ft p_compress = NULL; +static uncompress_ft p_uncompress = NULL; static inflateEnd_ft p_inflateEnd = NULL; static inflate_ft p_inflate = NULL; static inflateInit__ft p_inflateInit_ = NULL; @@ -106,6 +100,7 @@ static zError__ft p_zError = NULL; static DSO *zlib_dso = NULL; # define compress p_compress +# define uncompress p_uncompress # define inflateEnd p_inflateEnd # define inflate p_inflate # define inflateInit_ p_inflateInit_ @@ -162,9 +157,9 @@ static void zlib_stateful_finish(COMP_CTX *ctx) OPENSSL_free(state); } -static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) +static ossl_ssize_t zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) { int err = Z_OK; struct zlib_state *state = ctx->data; @@ -180,12 +175,14 @@ static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, err = deflate(&state->ostream, Z_SYNC_FLUSH); if (err != Z_OK) return -1; - return olen - state->ostream.avail_out; + if (state->ostream.avail_out > olen) + return -1; + return (ossl_ssize_t)(olen - state->ostream.avail_out); } -static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) +static ossl_ssize_t zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) { int err = Z_OK; struct zlib_state *state = ctx->data; @@ -201,9 +198,75 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, err = inflate(&state->istream, Z_SYNC_FLUSH); if (err != Z_OK) return -1; - return olen - state->istream.avail_out; + if (state->istream.avail_out > olen) + return -1; + return (ossl_ssize_t)(olen - state->istream.avail_out); +} + +/* ONESHOT COMPRESSION/DECOMPRESSION */ + +static int zlib_oneshot_init(COMP_CTX *ctx) +{ + return 1; +} + +static void zlib_oneshot_finish(COMP_CTX *ctx) +{ +} + +static ossl_ssize_t zlib_oneshot_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + uLongf out_size; + + if (ilen == 0) + return 0; + + /* zlib's uLongf defined as unsigned long FAR */ + if (olen > ULONG_MAX) + return -1; + out_size = (uLongf)olen; + + if (compress(out, &out_size, in, ilen) != Z_OK) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + return (ossl_ssize_t)out_size; } +static ossl_ssize_t zlib_oneshot_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + uLongf out_size; + + if (ilen == 0) + return 0; + + /* zlib's uLongf defined as unsigned long FAR */ + if (olen > ULONG_MAX) + return -1; + out_size = (uLongf)olen; + + if (uncompress(out, &out_size, in, ilen) != Z_OK) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + return (ossl_ssize_t)out_size; +} + +static COMP_METHOD zlib_oneshot_method = { + NID_zlib_compression, + LN_zlib_compression, + zlib_oneshot_init, + zlib_oneshot_finish, + zlib_oneshot_compress_block, + zlib_oneshot_expand_block +}; + static CRYPTO_ONCE zlib_once = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) { @@ -222,6 +285,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); if (zlib_dso != NULL) { p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); + p_uncompress = (compress_ft) DSO_bind_func(zlib_dso, "uncompress"); p_inflateEnd = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); p_inflateInit_ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); @@ -230,7 +294,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) p_deflateInit_ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); - if (p_compress == NULL || p_inflateEnd == NULL + if (p_compress == NULL || p_uncompress == NULL || p_inflateEnd == NULL || p_inflate == NULL || p_inflateInit_ == NULL || p_deflateEnd == NULL || p_deflate == NULL || p_deflateInit_ == NULL || p_zError == NULL) { @@ -245,9 +309,9 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) COMP_METHOD *COMP_zlib(void) { - COMP_METHOD *meth = &zlib_method_nozlib; + COMP_METHOD *meth = NULL; -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) meth = &zlib_stateful_method; #endif @@ -255,6 +319,18 @@ COMP_METHOD *COMP_zlib(void) return meth; } +COMP_METHOD *COMP_zlib_oneshot(void) +{ + COMP_METHOD *meth = NULL; + +#ifndef OPENSSL_NO_ZLIB + if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) + meth = &zlib_oneshot_method; +#endif + + return meth; +} + /* Also called from OPENSSL_cleanup() */ void ossl_comp_zlib_cleanup(void) { @@ -264,7 +340,7 @@ void ossl_comp_zlib_cleanup(void) #endif } -#ifdef ZLIB +#ifndef OPENSSL_NO_ZLIB /* Zlib based compression/decompression filter BIO */ @@ -304,12 +380,18 @@ static const BIO_METHOD bio_meth_zlib = { bio_zlib_free, bio_zlib_callback_ctrl }; +#endif const BIO_METHOD *BIO_f_zlib(void) { - return &bio_meth_zlib; +#ifndef OPENSSL_NO_ZLIB + if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) + return &bio_meth_zlib; +#endif + return NULL; } +#ifndef OPENSSL_NO_ZLIB static int bio_zlib_new(BIO *bi) { BIO_ZLIB_CTX *ctx; @@ -321,10 +403,8 @@ static int bio_zlib_new(BIO *bi) } # endif ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return 0; - } ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; ctx->zin.zalloc = Z_NULL; @@ -376,10 +456,8 @@ static int bio_zlib_read(BIO *b, char *out, int outl) BIO_clear_retry_flags(b); if (!ctx->ibuf) { ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); - if (ctx->ibuf == NULL) { - ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + if (ctx->ibuf == NULL) return 0; - } if ((ret = inflateInit(zin)) != Z_OK) { ERR_raise_data(ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR, "zlib error: %s", zError(ret)); @@ -441,10 +519,8 @@ static int bio_zlib_write(BIO *b, const char *in, int inl) if (!ctx->obuf) { ctx->obuf = OPENSSL_malloc(ctx->obufsize); /* Need error here */ - if (ctx->obuf == NULL) { - ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + if (ctx->obuf == NULL) return 0; - } ctx->optr = ctx->obuf; ctx->ocount = 0; if ((ret = deflateInit(zout, ctx->comp_level)) != Z_OK) { @@ -564,8 +640,10 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: ret = bio_zlib_flush(b); - if (ret > 0) + if (ret > 0) { ret = BIO_flush(next); + BIO_copy_next_retry(b); + } break; case BIO_C_SET_BUFF_SIZE: diff --git a/crypto/comp/c_zstd.c b/crypto/comp/c_zstd.c new file mode 100644 index 0000000000..b4667649f3 --- /dev/null +++ b/crypto/comp/c_zstd.c @@ -0,0 +1,845 @@ +/* + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Uses zstd compression library from https://github.com/facebook/zstd + * Requires version 1.4.x (latest as of this writing is 1.4.5) + * Using custom free functions require static linking, so that is disabled when + * using the shared library. + */ + +#include +#include +#include +#include +#include "internal/comp.h" +#include +#include "crypto/cryptlib.h" +#include "internal/bio.h" +#include "internal/thread_once.h" +#include "comp_local.h" + +COMP_METHOD *COMP_zstd(void); + +#ifdef OPENSSL_NO_ZSTD +# undef ZSTD_SHARED +#else + +# ifndef ZSTD_SHARED +# define ZSTD_STATIC_LINKING_ONLY +# endif +# include + +/* Note: There is also a linux zstd.h file in the kernel source */ +# ifndef ZSTD_H_235446 +# error Wrong (i.e. linux) zstd.h included. +# endif + +# if ZSTD_VERSION_MAJOR != 1 && ZSTD_VERSION_MINOR < 4 +# error Expecting version 1.4 or greater of ZSTD +# endif + +# ifndef ZSTD_SHARED +/* memory allocations functions for zstd initialisation */ +static void *zstd_alloc(void *opaque, size_t size) +{ + return OPENSSL_zalloc(size); +} + +static void zstd_free(void *opaque, void *address) +{ + OPENSSL_free(address); +} + +static ZSTD_customMem zstd_mem_funcs = { + zstd_alloc, + zstd_free, + NULL +}; +# endif + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the LIBZSTD.DLL be available in order for the OpenSSL DLLs to + * work. Therefore, all ZSTD routines are loaded at run time + * and we do not link to a .LIB file when ZSTD_SHARED is set. + */ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# endif + +# ifdef ZSTD_SHARED +# include "internal/dso.h" + +/* Function pointers */ +typedef ZSTD_CStream* (*createCStream_ft)(void); +typedef size_t (*initCStream_ft)(ZSTD_CStream*, int); +typedef size_t (*freeCStream_ft)(ZSTD_CStream*); +typedef size_t (*compressStream2_ft)(ZSTD_CCtx*, ZSTD_outBuffer*, ZSTD_inBuffer*, ZSTD_EndDirective); +typedef size_t (*flushStream_ft)(ZSTD_CStream*, ZSTD_outBuffer*); +typedef size_t (*endStream_ft)(ZSTD_CStream*, ZSTD_outBuffer*); +typedef size_t (*compress_ft)(void*, size_t, const void*, size_t, int); +typedef ZSTD_DStream* (*createDStream_ft)(void); +typedef size_t (*initDStream_ft)(ZSTD_DStream*); +typedef size_t (*freeDStream_ft)(ZSTD_DStream*); +typedef size_t (*decompressStream_ft)(ZSTD_DStream*, ZSTD_outBuffer*, ZSTD_inBuffer*); +typedef size_t (*decompress_ft)(void*, size_t, const void*, size_t); +typedef unsigned (*isError_ft)(size_t); +typedef const char* (*getErrorName_ft)(size_t); +typedef size_t (*DStreamInSize_ft)(void); +typedef size_t (*CStreamInSize_ft)(void); + +static createCStream_ft p_createCStream = NULL; +static initCStream_ft p_initCStream = NULL; +static freeCStream_ft p_freeCStream = NULL; +static compressStream2_ft p_compressStream2 = NULL; +static flushStream_ft p_flushStream = NULL; +static endStream_ft p_endStream = NULL; +static compress_ft p_compress = NULL; +static createDStream_ft p_createDStream = NULL; +static initDStream_ft p_initDStream = NULL; +static freeDStream_ft p_freeDStream = NULL; +static decompressStream_ft p_decompressStream = NULL; +static decompress_ft p_decompress = NULL; +static isError_ft p_isError = NULL; +static getErrorName_ft p_getErrorName = NULL; +static DStreamInSize_ft p_DStreamInSize = NULL; +static CStreamInSize_ft p_CStreamInSize = NULL; + +static DSO *zstd_dso = NULL; + +# define ZSTD_createCStream p_createCStream +# define ZSTD_initCStream p_initCStream +# define ZSTD_freeCStream p_freeCStream +# define ZSTD_compressStream2 p_compressStream2 +# define ZSTD_flushStream p_flushStream +# define ZSTD_endStream p_endStream +# define ZSTD_compress p_compress +# define ZSTD_createDStream p_createDStream +# define ZSTD_initDStream p_initDStream +# define ZSTD_freeDStream p_freeDStream +# define ZSTD_decompressStream p_decompressStream +# define ZSTD_decompress p_decompress +# define ZSTD_isError p_isError +# define ZSTD_getErrorName p_getErrorName +# define ZSTD_DStreamInSize p_DStreamInSize +# define ZSTD_CStreamInSize p_CStreamInSize + +# endif /* ifdef ZSTD_SHARED */ + +struct zstd_state { + ZSTD_CStream *compressor; + ZSTD_DStream *decompressor; +}; + +static int zstd_stateful_init(COMP_CTX *ctx) +{ + struct zstd_state *state = OPENSSL_zalloc(sizeof(*state)); + + if (state == NULL) + return 0; + +# ifdef ZSTD_SHARED + state->compressor = ZSTD_createCStream(); +# else + state->compressor = ZSTD_createCStream_advanced(zstd_mem_funcs); +# endif + if (state->compressor == NULL) + goto err; + ZSTD_initCStream(state->compressor, ZSTD_CLEVEL_DEFAULT); + +# ifdef ZSTD_SHARED + state->decompressor = ZSTD_createDStream(); +# else + state->decompressor = ZSTD_createDStream_advanced(zstd_mem_funcs); +# endif + if (state->decompressor == NULL) + goto err; + ZSTD_initDStream(state->decompressor); + + ctx->data = state; + return 1; + err: + ZSTD_freeCStream(state->compressor); + ZSTD_freeDStream(state->decompressor); + OPENSSL_free(state); + return 0; +} + +static void zstd_stateful_finish(COMP_CTX *ctx) +{ + struct zstd_state *state = ctx->data; + + if (state != NULL) { + ZSTD_freeCStream(state->compressor); + ZSTD_freeDStream(state->decompressor); + OPENSSL_free(state); + ctx->data = NULL; + } +} + +static ossl_ssize_t zstd_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + ZSTD_inBuffer inbuf; + ZSTD_outBuffer outbuf; + size_t ret; + ossl_ssize_t fret; + struct zstd_state *state = ctx->data; + + inbuf.src = in; + inbuf.size = ilen; + inbuf.pos = 0; + outbuf.dst = out; + outbuf.size = olen; + outbuf.pos = 0; + + if (state == NULL) + return -1; + + /* If input length is zero, end the stream/frame ? */ + if (ilen == 0) { + ret = ZSTD_endStream(state->compressor, &outbuf); + if (ZSTD_isError(ret)) + return -1; + goto end; + } + + /* + * The finish API does not provide a final output buffer, + * so each compress operation has to be ended, if all + * the input data can't be accepted, or there is more output, + * this has to be considered an error, since there is no more + * output buffer space. + */ + do { + ret = ZSTD_compressStream2(state->compressor, &outbuf, &inbuf, ZSTD_e_continue); + if (ZSTD_isError(ret)) + return -1; + /* do I need to check for ret == 0 ? */ + } while (inbuf.pos < inbuf.size); + + /* Did not consume all the data */ + if (inbuf.pos < inbuf.size) + return -1; + + ret = ZSTD_flushStream(state->compressor, &outbuf); + if (ZSTD_isError(ret)) + return -1; + + end: + if (outbuf.pos > OSSL_SSIZE_MAX) + return -1; + fret = (ossl_ssize_t)outbuf.pos; + if (fret < 0) + return -1; + return fret; +} + +static ossl_ssize_t zstd_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + ZSTD_inBuffer inbuf; + ZSTD_outBuffer outbuf; + size_t ret; + ossl_ssize_t fret; + struct zstd_state *state = ctx->data; + + inbuf.src = in; + inbuf.size = ilen; + inbuf.pos = 0; + outbuf.dst = out; + outbuf.size = olen; + outbuf.pos = 0; + + if (state == NULL) + return -1; + + if (ilen == 0) + return 0; + + do { + ret = ZSTD_decompressStream(state->decompressor, &outbuf, &inbuf); + if (ZSTD_isError(ret)) + return -1; + /* If we completed a frame, and there's more data, try again */ + } while (ret == 0 && inbuf.pos < inbuf.size); + + /* Did not consume all the data */ + if (inbuf.pos < inbuf.size) + return -1; + + if (outbuf.pos > OSSL_SSIZE_MAX) + return -1; + fret = (ossl_ssize_t)outbuf.pos; + if (fret < 0) + return -1; + return fret; +} + + +static COMP_METHOD zstd_stateful_method = { + NID_zstd, + LN_zstd, + zstd_stateful_init, + zstd_stateful_finish, + zstd_stateful_compress_block, + zstd_stateful_expand_block +}; + +static int zstd_oneshot_init(COMP_CTX *ctx) +{ + return 1; +} + +static void zstd_oneshot_finish(COMP_CTX *ctx) +{ +} + +static ossl_ssize_t zstd_oneshot_compress_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + size_t out_size; + ossl_ssize_t ret; + + if (ilen == 0) + return 0; + + /* Note: uses STDLIB memory allocators */ + out_size = ZSTD_compress(out, olen, in, ilen, ZSTD_CLEVEL_DEFAULT); + if (ZSTD_isError(out_size)) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + ret = (ossl_ssize_t)out_size; + if (ret < 0) + return -1; + return ret; +} + +static ossl_ssize_t zstd_oneshot_expand_block(COMP_CTX *ctx, unsigned char *out, + size_t olen, unsigned char *in, + size_t ilen) +{ + size_t out_size; + ossl_ssize_t ret; + + if (ilen == 0) + return 0; + + /* Note: uses STDLIB memory allocators */ + out_size = ZSTD_decompress(out, olen, in, ilen); + if (ZSTD_isError(out_size)) + return -1; + + if (out_size > OSSL_SSIZE_MAX) + return -1; + ret = (ossl_ssize_t)out_size; + if (ret < 0) + return -1; + return ret; +} + +static COMP_METHOD zstd_oneshot_method = { + NID_zstd, + LN_zstd, + zstd_oneshot_init, + zstd_oneshot_finish, + zstd_oneshot_compress_block, + zstd_oneshot_expand_block +}; + +static CRYPTO_ONCE zstd_once = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_comp_zstd_init) +{ +# ifdef ZSTD_SHARED +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# define LIBZSTD "LIBZSTD" +# else +# define LIBZSTD "zstd" +# endif + + zstd_dso = DSO_load(NULL, LIBZSTD, NULL, 0); + if (zstd_dso != NULL) { + p_createCStream = (createCStream_ft)DSO_bind_func(zstd_dso, "ZSTD_createCStream"); + p_initCStream = (initCStream_ft)DSO_bind_func(zstd_dso, "ZSTD_initCStream"); + p_freeCStream = (freeCStream_ft)DSO_bind_func(zstd_dso, "ZSTD_freeCStream"); + p_compressStream2 = (compressStream2_ft)DSO_bind_func(zstd_dso, "ZSTD_compressStream2"); + p_flushStream = (flushStream_ft)DSO_bind_func(zstd_dso, "ZSTD_flushStream"); + p_endStream = (endStream_ft)DSO_bind_func(zstd_dso, "ZSTD_endStream"); + p_compress = (compress_ft)DSO_bind_func(zstd_dso, "ZSTD_compress"); + p_createDStream = (createDStream_ft)DSO_bind_func(zstd_dso, "ZSTD_createDStream"); + p_initDStream = (initDStream_ft)DSO_bind_func(zstd_dso, "ZSTD_initDStream"); + p_freeDStream = (freeDStream_ft)DSO_bind_func(zstd_dso, "ZSTD_freeDStream"); + p_decompressStream = (decompressStream_ft)DSO_bind_func(zstd_dso, "ZSTD_decompressStream"); + p_decompress = (decompress_ft)DSO_bind_func(zstd_dso, "ZSTD_decompress"); + p_isError = (isError_ft)DSO_bind_func(zstd_dso, "ZSTD_isError"); + p_getErrorName = (getErrorName_ft)DSO_bind_func(zstd_dso, "ZSTD_getErrorName"); + p_DStreamInSize = (DStreamInSize_ft)DSO_bind_func(zstd_dso, "ZSTD_DStreamInSize"); + p_CStreamInSize = (CStreamInSize_ft)DSO_bind_func(zstd_dso, "ZSTD_CStreamInSize"); + } + + if (p_createCStream == NULL || p_initCStream == NULL || p_freeCStream == NULL + || p_compressStream2 == NULL || p_flushStream == NULL || p_endStream == NULL + || p_compress == NULL || p_createDStream == NULL || p_initDStream == NULL + || p_freeDStream == NULL || p_decompressStream == NULL || p_decompress == NULL + || p_isError == NULL || p_getErrorName == NULL || p_DStreamInSize == NULL + || p_CStreamInSize == NULL) { + ossl_comp_zstd_cleanup(); + return 0; + } +# endif + return 1; +} +#endif /* ifndef ZSTD / else */ + +COMP_METHOD *COMP_zstd(void) +{ + COMP_METHOD *meth = NULL; + +#ifndef OPENSSL_NO_ZSTD + if (RUN_ONCE(&zstd_once, ossl_comp_zstd_init)) + meth = &zstd_stateful_method; +#endif + return meth; +} + +COMP_METHOD *COMP_zstd_oneshot(void) +{ + COMP_METHOD *meth = NULL; + +#ifndef OPENSSL_NO_ZSTD + if (RUN_ONCE(&zstd_once, ossl_comp_zstd_init)) + meth = &zstd_oneshot_method; +#endif + return meth; +} + +/* Also called from OPENSSL_cleanup() */ +void ossl_comp_zstd_cleanup(void) +{ +#ifdef ZSTD_SHARED + DSO_free(zstd_dso); + zstd_dso = NULL; + p_createCStream = NULL; + p_initCStream = NULL; + p_freeCStream = NULL; + p_compressStream2 = NULL; + p_flushStream = NULL; + p_endStream = NULL; + p_compress = NULL; + p_createDStream = NULL; + p_initDStream = NULL; + p_freeDStream = NULL; + p_decompressStream = NULL; + p_decompress = NULL; + p_isError = NULL; + p_getErrorName = NULL; + p_DStreamInSize = NULL; + p_CStreamInSize = NULL; +#endif +} + +#ifndef OPENSSL_NO_ZSTD + +/* Zstd-based compression/decompression filter BIO */ + +typedef struct { + struct { /* input structure */ + ZSTD_DStream *state; + ZSTD_inBuffer inbuf; /* has const src */ + size_t bufsize; + void* buffer; + } decompress; + struct { /* output structure */ + ZSTD_CStream *state; + ZSTD_outBuffer outbuf; + size_t bufsize; + size_t write_pos; + } compress; +} BIO_ZSTD_CTX; + +# define ZSTD_DEFAULT_BUFSIZE 1024 + +static int bio_zstd_new(BIO *bi); +static int bio_zstd_free(BIO *bi); +static int bio_zstd_read(BIO *b, char *out, int outl); +static int bio_zstd_write(BIO *b, const char *in, int inl); +static long bio_zstd_ctrl(BIO *b, int cmd, long num, void *ptr); +static long bio_zstd_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); + +static const BIO_METHOD bio_meth_zstd = { + BIO_TYPE_COMP, + "zstd", + /* TODO: Convert to new style write function */ + bwrite_conv, + bio_zstd_write, + /* TODO: Convert to new style read function */ + bread_conv, + bio_zstd_read, + NULL, /* bio_zstd_puts, */ + NULL, /* bio_zstd_gets, */ + bio_zstd_ctrl, + bio_zstd_new, + bio_zstd_free, + bio_zstd_callback_ctrl +}; +#endif + +const BIO_METHOD *BIO_f_zstd(void) +{ +#ifndef OPENSSL_NO_ZSTD + if (RUN_ONCE(&zstd_once, ossl_comp_zstd_init)) + return &bio_meth_zstd; +#endif + return NULL; +} + +#ifndef OPENSSL_NO_ZSTD +static int bio_zstd_new(BIO *bi) +{ + BIO_ZSTD_CTX *ctx; + +# ifdef ZSTD_SHARED + (void)COMP_zstd(); + if (zstd_dso == NULL) { + ERR_raise(ERR_LIB_COMP, COMP_R_ZSTD_NOT_SUPPORTED); + return 0; + } +# endif + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + +# ifdef ZSTD_SHARED + ctx->decompress.state = ZSTD_createDStream(); +# else + ctx->decompress.state = ZSTD_createDStream_advanced(zstd_mem_funcs); +# endif + if (ctx->decompress.state == NULL) + goto err; + ZSTD_initDStream(ctx->decompress.state); + ctx->decompress.bufsize = ZSTD_DStreamInSize(); + +# ifdef ZSTD_SHARED + ctx->compress.state = ZSTD_createCStream(); +# else + ctx->compress.state = ZSTD_createCStream_advanced(zstd_mem_funcs); +# endif + if (ctx->compress.state == NULL) + goto err; + ZSTD_initCStream(ctx->compress.state, ZSTD_CLEVEL_DEFAULT); + ctx->compress.bufsize = ZSTD_CStreamInSize(); + + BIO_set_init(bi, 1); + BIO_set_data(bi, ctx); + + return 1; + err: + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + ZSTD_freeDStream(ctx->decompress.state); + ZSTD_freeCStream(ctx->compress.state); + OPENSSL_free(ctx); + return 0; +} + +static int bio_zstd_free(BIO *bi) +{ + BIO_ZSTD_CTX *ctx; + + if (bi == NULL) + return 0; + + ctx = BIO_get_data(bi); + if (ctx != NULL) { + ZSTD_freeDStream(ctx->decompress.state); + OPENSSL_free(ctx->decompress.buffer); + ZSTD_freeCStream(ctx->compress.state); + OPENSSL_free(ctx->compress.outbuf.dst); + OPENSSL_free(ctx); + } + BIO_set_data(bi, NULL); + BIO_set_init(bi, 0); + + return 1; +} + +static int bio_zstd_read(BIO *b, char *out, int outl) +{ + BIO_ZSTD_CTX *ctx; + size_t zret; + int ret; + ZSTD_outBuffer outBuf; + BIO *next = BIO_next(b); + + if (out == NULL || outl <= 0) + return 0; + + ctx = BIO_get_data(b); + BIO_clear_retry_flags(b); + if (ctx->decompress.buffer == NULL) { + ctx->decompress.buffer = OPENSSL_malloc(ctx->decompress.bufsize); + if (ctx->decompress.buffer == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->decompress.inbuf.src = ctx->decompress.buffer; + ctx->decompress.inbuf.size = 0; + ctx->decompress.inbuf.pos = 0; + } + + /* Copy output data directly to supplied buffer */ + outBuf.dst = out; + outBuf.size = (size_t)outl; + outBuf.pos = 0; + for (;;) { + /* Decompress while data available */ + do { + zret = ZSTD_decompressStream(ctx->decompress.state, &outBuf, &ctx->decompress.inbuf); + if (ZSTD_isError(zret)) { + ERR_raise(ERR_LIB_COMP, COMP_R_ZSTD_DECOMPRESS_ERROR); + ERR_add_error_data(1, ZSTD_getErrorName(zret)); + return -1; + } + /* No more output space */ + if (outBuf.pos == outBuf.size) + return outBuf.pos; + } while (ctx->decompress.inbuf.pos < ctx->decompress.inbuf.size); + + /* + * No data in input buffer try to read some in, if an error then + * return the total data read. + */ + ret = BIO_read(next, ctx->decompress.buffer, ctx->decompress.bufsize); + if (ret <= 0) { + BIO_copy_next_retry(b); + if (ret < 0 && outBuf.pos == 0) + return ret; + return outBuf.pos; + } + ctx->decompress.inbuf.size = ret; + ctx->decompress.inbuf.pos = 0; + } +} + +static int bio_zstd_write(BIO *b, const char *in, int inl) +{ + BIO_ZSTD_CTX *ctx; + size_t zret; + ZSTD_inBuffer inBuf; + int ret; + int done = 0; + BIO *next = BIO_next(b); + + if (in == NULL || inl <= 0) + return 0; + + ctx = BIO_get_data(b); + + BIO_clear_retry_flags(b); + if (ctx->compress.outbuf.dst == NULL) { + ctx->compress.outbuf.dst = OPENSSL_malloc(ctx->compress.bufsize); + if (ctx->compress.outbuf.dst == NULL) { + ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->compress.outbuf.size = ctx->compress.bufsize; + ctx->compress.outbuf.pos = 0; + ctx->compress.write_pos = 0; + } + /* Obtain input data directly from supplied buffer */ + inBuf.src = in; + inBuf.size = inl; + inBuf.pos = 0; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->compress.write_pos < ctx->compress.outbuf.pos) { + ret = BIO_write(next, (unsigned char*)ctx->compress.outbuf.dst + ctx->compress.write_pos, + ctx->compress.outbuf.pos - ctx->compress.write_pos); + if (ret <= 0) { + BIO_copy_next_retry(b); + if (ret < 0 && inBuf.pos == 0) + return ret; + return inBuf.pos; + } + ctx->compress.write_pos += ret; + } + + /* Have we consumed all supplied data? */ + if (done) + return inBuf.pos; + + /* Reset buffer */ + ctx->compress.outbuf.pos = 0; + ctx->compress.outbuf.size = ctx->compress.bufsize; + ctx->compress.write_pos = 0; + /* Compress some more */ + zret = ZSTD_compressStream2(ctx->compress.state, &ctx->compress.outbuf, &inBuf, ZSTD_e_end); + if (ZSTD_isError(zret)) { + ERR_raise(ERR_LIB_COMP, COMP_R_ZSTD_COMPRESS_ERROR); + ERR_add_error_data(1, ZSTD_getErrorName(zret)); + return 0; + } else if (zret == 0) { + done = 1; + } + } +} + +static int bio_zstd_flush(BIO *b) +{ + BIO_ZSTD_CTX *ctx; + size_t zret; + int ret; + BIO *next = BIO_next(b); + + ctx = BIO_get_data(b); + + /* If no data written or already flush show success */ + if (ctx->compress.outbuf.dst == NULL) + return 1; + + BIO_clear_retry_flags(b); + /* No more input data */ + ctx->compress.outbuf.pos = 0; + ctx->compress.outbuf.size = ctx->compress.bufsize; + ctx->compress.write_pos = 0; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->compress.write_pos < ctx->compress.outbuf.pos) { + ret = BIO_write(next, (unsigned char*)ctx->compress.outbuf.dst + ctx->compress.write_pos, + ctx->compress.outbuf.pos - ctx->compress.write_pos); + if (ret <= 0) { + BIO_copy_next_retry(b); + return ret; + } + ctx->compress.write_pos += ret; + } + + /* Reset buffer */ + ctx->compress.outbuf.pos = 0; + ctx->compress.outbuf.size = ctx->compress.bufsize; + ctx->compress.write_pos = 0; + /* Compress some more */ + zret = ZSTD_flushStream(ctx->compress.state, &ctx->compress.outbuf); + if (ZSTD_isError(zret)) { + ERR_raise(ERR_LIB_COMP, COMP_R_ZSTD_DECODE_ERROR); + ERR_add_error_data(1, ZSTD_getErrorName(zret)); + return 0; + } + if (zret == 0) + return 1; + } +} + +static long bio_zstd_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_ZSTD_CTX *ctx; + int ret = 0, *ip; + size_t ibs, obs; + unsigned char *tmp; + BIO *next = BIO_next(b); + + if (next == NULL) + return 0; + ctx = BIO_get_data(b); + switch (cmd) { + + case BIO_CTRL_RESET: + ctx->compress.write_pos = 0; + ctx->compress.bufsize = 0; + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = bio_zstd_flush(b); + if (ret > 0) { + ret = BIO_flush(next); + BIO_copy_next_retry(b); + } + break; + + case BIO_C_SET_BUFF_SIZE: + ibs = ctx->decompress.bufsize; + obs = ctx->compress.bufsize; + if (ptr != NULL) { + ip = ptr; + if (*ip == 0) + ibs = (size_t)num; + else + obs = (size_t)num; + } else { + obs = ibs = (size_t)num; + } + + if (ibs > 0 && ibs != ctx->decompress.bufsize) { + if (ctx->decompress.buffer != NULL) { + tmp = OPENSSL_realloc(ctx->decompress.buffer, ibs); + if (tmp == NULL) + return 0; + if (ctx->decompress.inbuf.src == ctx->decompress.buffer) + ctx->decompress.inbuf.src = tmp; + ctx->decompress.buffer = tmp; + } + ctx->decompress.bufsize = ibs; + } + + if (obs > 0 && obs != ctx->compress.bufsize) { + if (ctx->compress.outbuf.dst != NULL) { + tmp = OPENSSL_realloc(ctx->compress.outbuf.dst, obs); + if (tmp == NULL) + return 0; + ctx->compress.outbuf.dst = tmp; + } + ctx->compress.bufsize = obs; + } + ret = 1; + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_WPENDING: + if (ctx->compress.outbuf.pos < ctx->compress.outbuf.size) + ret = 1; + else + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + case BIO_CTRL_PENDING: + if (ctx->decompress.inbuf.pos < ctx->decompress.inbuf.size) + ret = 1; + else + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + default: + ret = BIO_ctrl(next, cmd, num, ptr); + break; + + } + + return ret; +} + +static long bio_zstd_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) +{ + BIO *next = BIO_next(b); + if (next == NULL) + return 0; + return BIO_callback_ctrl(next, cmd, fp); +} + +#endif diff --git a/crypto/comp/comp_err.c b/crypto/comp/comp_err.c index 70a6eea0f0..2345da693e 100644 --- a/crypto/comp/comp_err.c +++ b/crypto/comp/comp_err.c @@ -17,12 +17,25 @@ # ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA COMP_str_reasons[] = { + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_DECODE_ERROR), + "brotli decode error"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_ENCODE_ERROR), + "brotli encode error"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_NOT_SUPPORTED), + "brotli not supported"}, {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"}, {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"}, {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_COMPRESS_ERROR), + "zstd compress error"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_DECODE_ERROR), "zstd decode error"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_DECOMPRESS_ERROR), + "zstd decompress error"}, + {ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_NOT_SUPPORTED), + "zstd not supported"}, {0, NULL} }; diff --git a/crypto/comp/comp_lib.c b/crypto/comp/comp_lib.c index bf9069d871..56ca17a7a5 100644 --- a/crypto/comp/comp_lib.c +++ b/crypto/comp/comp_lib.c @@ -19,10 +19,11 @@ COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) { COMP_CTX *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_COMP, ERR_R_MALLOC_FAILURE); + if (meth == NULL) + return NULL; + + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } ret->meth = meth; if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { OPENSSL_free(ret); @@ -38,11 +39,15 @@ const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx) int COMP_get_type(const COMP_METHOD *meth) { + if (meth == NULL) + return NID_undef; return meth->type; } const char *COMP_get_name(const COMP_METHOD *meth) { + if (meth == NULL) + return NULL; return meth->name; } diff --git a/crypto/comp/comp_local.h b/crypto/comp/comp_local.h index acf113e31c..d8be9271a0 100644 --- a/crypto/comp/comp_local.h +++ b/crypto/comp/comp_local.h @@ -12,12 +12,12 @@ struct comp_method_st { const char *name; /* A text string to identify the library */ int (*init) (COMP_CTX *ctx); void (*finish) (COMP_CTX *ctx); - int (*compress) (COMP_CTX *ctx, - unsigned char *out, unsigned int olen, - unsigned char *in, unsigned int ilen); - int (*expand) (COMP_CTX *ctx, - unsigned char *out, unsigned int olen, - unsigned char *in, unsigned int ilen); + ossl_ssize_t (*compress) (COMP_CTX *ctx, + unsigned char *out, size_t olen, + unsigned char *in, size_t ilen); + ossl_ssize_t (*expand) (COMP_CTX *ctx, + unsigned char *out, size_t olen, + unsigned char *in, size_t ilen); }; struct comp_ctx_st { diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index 26686a0ec3..e047746f67 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -193,10 +193,10 @@ static int def_load(CONF *conf, const char *name, long *line) static int parsebool(const char *pval, int *flag) { if (OPENSSL_strcasecmp(pval, "on") == 0 - || OPENSSL_strcasecmp(pval, "true") == 0) { + || OPENSSL_strcasecmp(pval, "true") == 0) { *flag = 1; } else if (OPENSSL_strcasecmp(pval, "off") == 0 - || OPENSSL_strcasecmp(pval, "false") == 0) { + || OPENSSL_strcasecmp(pval, "false") == 0) { *flag = 0; } else { ERR_raise(ERR_LIB_CONF, CONF_R_INVALID_PRAGMA); @@ -236,13 +236,11 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) } section = OPENSSL_strdup("default"); - if (section == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if (section == NULL) goto err; - } if (_CONF_new_data(conf) == 0) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CONF_LIB); goto err; } @@ -392,8 +390,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) psection = section; } p = eat_ws(conf, end); - if (strncmp(pname, ".pragma", 7) == 0 - && (p != pname + 7 || *p == '=')) { + if (CHECK_AND_SKIP_PREFIX(pname, ".pragma") + && (p != pname || *p == '=')) { char *pval; if (*p == '=') { @@ -428,18 +426,16 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) goto err; } else if (strcmp(p, "includedir") == 0) { OPENSSL_free(conf->includedir); - if ((conf->includedir = OPENSSL_strdup(pval)) == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if ((conf->includedir = OPENSSL_strdup(pval)) == NULL) goto err; - } } /* * We *ignore* any unknown pragma. */ continue; - } else if (strncmp(pname, ".include", 8) == 0 - && (p != pname + 8 || *p == '=')) { + } else if (CHECK_AND_SKIP_PREFIX(pname, ".include") + && (p != pname || *p == '=')) { char *include = NULL; BIO *next; const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE"); @@ -475,7 +471,6 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) include_path = OPENSSL_malloc(newlen); if (include_path == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); OPENSSL_free(include); goto err; } @@ -512,13 +507,13 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) /* push the currently processing BIO onto stack */ if (biosk == NULL) { if ((biosk = sk_BIO_new_null()) == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); BIO_free(next); goto err; } } if (!sk_BIO_push(biosk, in)) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); BIO_free(next); goto err; } @@ -536,16 +531,12 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) start = eat_ws(conf, p); trim_ws(conf, start); - if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) goto err; - } v->name = OPENSSL_strdup(pname); v->value = NULL; - if (v->name == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if (v->name == NULL) goto err; - } if (!str_copy(conf, psection, &(v->value), start)) goto err; @@ -561,7 +552,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) } else tv = sv; if (_CONF_add_string(conf, tv, v) == 0) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CONF_LIB); goto err; } v = NULL; @@ -774,7 +765,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) goto err; } if (!BUF_MEM_grow_clean(buf, newsize)) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_BUF_LIB); goto err; } while (*p) @@ -858,18 +849,16 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) if ((namelen > 5 && OPENSSL_strcasecmp(filename + namelen - 5, ".conf") == 0) - || (namelen > 4 - && OPENSSL_strcasecmp(filename + namelen - 4, ".cnf") == 0)) { + || (namelen > 4 + && OPENSSL_strcasecmp(filename + namelen - 4, ".cnf") == 0)) { size_t newlen; char *newpath; BIO *bio; newlen = pathlen + namelen + 2; newpath = OPENSSL_zalloc(newlen); - if (newpath == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if (newpath == NULL) break; - } #ifdef OPENSSL_SYS_VMS /* * If the given path isn't clear VMS syntax, @@ -903,7 +892,7 @@ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) static int is_keytype(const CONF *conf, char c, unsigned short type) { - const unsigned short * keytypes = (const unsigned short *) conf->meth_data; + const unsigned short *keytypes = (const unsigned short *) conf->meth_data; unsigned char key = (unsigned char)c; #ifdef CHARSET_EBCDIC diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c index 1766facd65..62ac82729c 100644 --- a/crypto/conf/conf_lib.c +++ b/crypto/conf/conf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -188,7 +188,7 @@ CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth) ret = meth->create(meth); if (ret == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CONF_LIB); return NULL; } ret->libctx = libctx; @@ -421,6 +421,12 @@ OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void) #ifndef OPENSSL_NO_STDIO +/* + * If CRYPTO_set_mem_functions is called after this, then + * memory allocation and deallocation in this function can + * become disjointed. Avoid this by always using standard + * strdup & free instead of OPENSSL_strdup & OPENSSL_free. + */ int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, const char *filename) { @@ -444,6 +450,12 @@ void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, settings->flags = flags; } +/* + * If CRYPTO_set_mem_functions is called after this, then + * memory allocation and deallocation in this function can + * become disjointed. Avoid this by always using standard + * strdup & free instead of OPENSSL_strdup & OPENSSL_free. + */ int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, const char *appname) { diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 1ea32648e9..d6a5f3ff35 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -100,7 +100,7 @@ DEFINE_RUN_ONCE_STATIC(do_init_module_list_lock) { module_list_lock = CRYPTO_THREAD_lock_new(); if (module_list_lock == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); return 0; } @@ -338,10 +338,8 @@ static CONF_MODULE *module_add(DSO *dso, const char *name, supported_modules = sk_CONF_MODULE_new_null(); if (supported_modules == NULL) goto err; - if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL) { - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + if ((tmod = OPENSSL_zalloc(sizeof(*tmod))) == NULL) goto err; - } tmod->dso = dso; tmod->name = OPENSSL_strdup(name); @@ -441,14 +439,14 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value, initialized_modules = sk_CONF_IMODULE_new_null(); if (initialized_modules == NULL) { CRYPTO_THREAD_unlock(module_list_lock); - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); goto err; } } if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { CRYPTO_THREAD_unlock(module_list_lock); - ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CONF, ERR_R_CRYPTO_LIB); goto err; } diff --git a/crypto/context.c b/crypto/context.c index e294ea1512..33d52a964b 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -14,6 +14,7 @@ #include "internal/core.h" #include "internal/bio.h" #include "internal/provider.h" +#include "crypto/decoder.h" #include "crypto/context.h" struct ossl_lib_ctx_st { @@ -33,9 +34,13 @@ struct ossl_lib_ctx_st { void *bio_core; void *child_provider; OSSL_METHOD_STORE *decoder_store; + void *decoder_cache; OSSL_METHOD_STORE *encoder_store; OSSL_METHOD_STORE *store_loader_store; void *self_test_cb; +#endif +#if defined(OPENSSL_THREADS) + void *threads; #endif void *rand_crngt; #ifdef FIPS_MODULE @@ -107,10 +112,16 @@ static int context_init(OSSL_LIB_CTX *ctx) goto err; #ifndef FIPS_MODULE - /* P2. We want decoder_store to be cleaned up before the provider store */ + /* + * P2. We want decoder_store/decoder_cache to be cleaned up before the + * provider store + */ ctx->decoder_store = ossl_method_store_new(ctx); if (ctx->decoder_store == NULL) goto err; + ctx->decoder_cache = ossl_decoder_cache_new(ctx); + if (ctx->decoder_cache == NULL) + goto err; /* P2. We want encoder_store to be cleaned up before the provider store */ ctx->encoder_store = ossl_method_store_new(ctx); @@ -171,6 +182,12 @@ static int context_init(OSSL_LIB_CTX *ctx) goto err; #endif +#ifndef OPENSSL_NO_THREAD_POOL + ctx->threads = ossl_threads_ctx_new(ctx); + if (ctx->threads == NULL) + goto err; +#endif + /* Low priority. */ #ifndef FIPS_MODULE ctx->child_provider = ossl_child_prov_ctx_new(ctx); @@ -217,11 +234,19 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx) ctx->provider_conf = NULL; } - /* P2. We want decoder_store to be cleaned up before the provider store */ + /* + * P2. We want decoder_store/decoder_cache to be cleaned up before the + * provider store + */ if (ctx->decoder_store != NULL) { ossl_method_store_free(ctx->decoder_store); ctx->decoder_store = NULL; } + if (ctx->decoder_cache != NULL) { + ossl_decoder_cache_free(ctx->decoder_cache); + ctx->decoder_cache = NULL; + } + /* P2. We want encoder_store to be cleaned up before the provider store */ if (ctx->encoder_store != NULL) { @@ -299,6 +324,13 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx) } #endif +#ifndef OPENSSL_NO_THREAD_POOL + if (ctx->threads != NULL) { + ossl_threads_ctx_free(ctx->threads); + ctx->threads = NULL; + } +#endif + /* Low priority. */ #ifndef FIPS_MODULE if (ctx->child_provider != NULL) { @@ -543,6 +575,8 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index) return ctx->child_provider; case OSSL_LIB_CTX_DECODER_STORE_INDEX: return ctx->decoder_store; + case OSSL_LIB_CTX_DECODER_CACHE_INDEX: + return ctx->decoder_cache; case OSSL_LIB_CTX_ENCODER_STORE_INDEX: return ctx->encoder_store; case OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX: @@ -550,6 +584,10 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index) case OSSL_LIB_CTX_SELF_TEST_CB_INDEX: return ctx->self_test_cb; #endif +#ifndef OPENSSL_NO_THREAD_POOL + case OSSL_LIB_CTX_THREAD_INDEX: + return ctx->threads; +#endif case OSSL_LIB_CTX_RAND_CRNGT_INDEX: { diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c index c245c814d9..16055bad30 100644 --- a/crypto/core_algorithm.c +++ b/crypto/core_algorithm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -193,7 +193,5 @@ char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo) first_name_len = first_name_end - algo->algorithm_names; ret = OPENSSL_strndup(algo->algorithm_names, first_name_len); - if (ret == NULL) - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return ret; } diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index 38db36ee1f..d311158d77 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cpuid.c b/crypto/cpuid.c index 21b2a59b4f..51cbe5ea09 100644 --- a/crypto/cpuid.c +++ b/crypto/cpuid.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,7 @@ static variant_char *ossl_getenv(const char *name) { /* * Since we pull only one environment variable, it's simpler to - * to just ignore |name| and use equivalent wide-char L-literal. + * just ignore |name| and use equivalent wide-char L-literal. * As well as to ignore excessively long values... */ static WCHAR value[48]; @@ -71,7 +71,7 @@ static uint64_t ossl_strtouint64(const variant_char *str) base = 16, str++; } - while((digit = todigit(*str++)) < base) + while ((digit = todigit(*str++)) < base) ret = ret * base + digit; return ret; @@ -80,7 +80,7 @@ static uint64_t ossl_strtouint64(const variant_char *str) static variant_char *ossl_strchr(const variant_char *str, char srch) { variant_char c; - while((c = *str)) { + while ((c = *str)) { if (c == srch) return (variant_char *)str; str++; @@ -173,7 +173,7 @@ void OPENSSL_cpuid_setup(void) */ /* - * The volatile is used to to ensure that the compiler generates code that reads + * The volatile is used to ensure that the compiler generates code that reads * all values from the array and doesn't try to optimize this away. The standard * doesn't actually require this behavior if the original data pointed to is * not volatile, but compilers do this in practice anyway. @@ -181,7 +181,7 @@ void OPENSSL_cpuid_setup(void) * There are also assembler versions of this function. */ # undef CRYPTO_memcmp -int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len) +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { size_t i; const volatile unsigned char *a = in_a; diff --git a/crypto/crmf/crmf_asn.c b/crypto/crmf/crmf_asn.c index 3354b89736..85b4213934 100644 --- a/crypto/crmf/crmf_asn.c +++ b/crypto/crmf/crmf_asn.c @@ -26,14 +26,14 @@ ASN1_SEQUENCE(OSSL_CRMF_PRIVATEKEYINFO) = { } ASN1_SEQUENCE_END(OSSL_CRMF_PRIVATEKEYINFO) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) - ASN1_CHOICE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) = { - ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.string, ASN1_UTF8STRING), - ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.generalName, GENERAL_NAME) + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, + value.string, ASN1_UTF8STRING), + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, + value.generalName, GENERAL_NAME) } ASN1_CHOICE_END(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) - ASN1_SEQUENCE(OSSL_CRMF_ENCKEYWITHID) = { ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID, privateKey, OSSL_CRMF_PRIVATEKEYINFO), ASN1_OPT(OSSL_CRMF_ENCKEYWITHID, identifier, @@ -41,7 +41,6 @@ ASN1_SEQUENCE(OSSL_CRMF_ENCKEYWITHID) = { } ASN1_SEQUENCE_END(OSSL_CRMF_ENCKEYWITHID) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) - ASN1_SEQUENCE(OSSL_CRMF_CERTID) = { ASN1_SIMPLE(OSSL_CRMF_CERTID, issuer, GENERAL_NAME), ASN1_SIMPLE(OSSL_CRMF_CERTID, serialNumber, ASN1_INTEGER) @@ -49,7 +48,6 @@ ASN1_SEQUENCE(OSSL_CRMF_CERTID) = { IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) - ASN1_SEQUENCE(OSSL_CRMF_ENCRYPTEDVALUE) = { ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, intendedAlg, X509_ALGOR, 0), ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, symmAlg, X509_ALGOR, 1), @@ -66,7 +64,6 @@ ASN1_SEQUENCE(OSSL_CRMF_SINGLEPUBINFO) = { } ASN1_SEQUENCE_END(OSSL_CRMF_SINGLEPUBINFO) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO) - ASN1_SEQUENCE(OSSL_CRMF_PKIPUBLICATIONINFO) = { ASN1_SIMPLE(OSSL_CRMF_PKIPUBLICATIONINFO, action, ASN1_INTEGER), ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_PKIPUBLICATIONINFO, pubInfos, @@ -75,24 +72,22 @@ ASN1_SEQUENCE(OSSL_CRMF_PKIPUBLICATIONINFO) = { IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO) IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) - ASN1_SEQUENCE(OSSL_CRMF_PKMACVALUE) = { ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, algId, X509_ALGOR), ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, value, ASN1_BIT_STRING) } ASN1_SEQUENCE_END(OSSL_CRMF_PKMACVALUE) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) - ASN1_CHOICE(OSSL_CRMF_POPOPRIVKEY) = { ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.thisMessage, ASN1_BIT_STRING, 0), ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.subsequentMessage, ASN1_INTEGER, 1), ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.dhMAC, ASN1_BIT_STRING, 2), ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.agreeMAC, OSSL_CRMF_PKMACVALUE, 3), ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.encryptedKey, ASN1_NULL, 4), + /* When supported, ASN1_NULL needs to be replaced by CMS_ENVELOPEDDATA */ } ASN1_CHOICE_END(OSSL_CRMF_POPOPRIVKEY) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) - ASN1_SEQUENCE(OSSL_CRMF_PBMPARAMETER) = { ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, salt, ASN1_OCTET_STRING), ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, owf, X509_ALGOR), @@ -101,7 +96,6 @@ ASN1_SEQUENCE(OSSL_CRMF_PBMPARAMETER) = { } ASN1_SEQUENCE_END(OSSL_CRMF_PBMPARAMETER) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER) - ASN1_CHOICE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) = { ASN1_EXP(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO, value.sender, GENERAL_NAME, 0), @@ -110,7 +104,6 @@ ASN1_CHOICE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) = { } ASN1_CHOICE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) - ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEYINPUT) = { ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT, authInfo, OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO), @@ -118,7 +111,6 @@ ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEYINPUT) = { } ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) - ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEY) = { ASN1_IMP_OPT(OSSL_CRMF_POPOSIGNINGKEY, poposkInput, OSSL_CRMF_POPOSIGNINGKEYINPUT, 0), @@ -127,7 +119,6 @@ ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEY) = { } ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEY) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) - ASN1_CHOICE(OSSL_CRMF_POPO) = { ASN1_IMP(OSSL_CRMF_POPO, value.raVerified, ASN1_NULL, 0), ASN1_IMP(OSSL_CRMF_POPO, value.signature, OSSL_CRMF_POPOSIGNINGKEY, 1), @@ -136,7 +127,6 @@ ASN1_CHOICE(OSSL_CRMF_POPO) = { } ASN1_CHOICE_END(OSSL_CRMF_POPO) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPO) - ASN1_ADB_TEMPLATE(attributetypeandvalue_default) = ASN1_OPT(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, value.other, ASN1_ANY); ASN1_ADB(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { @@ -165,7 +155,6 @@ ASN1_ADB(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { } ASN1_ADB_END(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, 0, type, 0, &attributetypeandvalue_default_tt, NULL); - ASN1_SEQUENCE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, type, ASN1_OBJECT), ASN1_ADB_OBJECT(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) @@ -174,14 +163,12 @@ ASN1_SEQUENCE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) - ASN1_SEQUENCE(OSSL_CRMF_OPTIONALVALIDITY) = { ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notBefore, ASN1_TIME, 0), ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notAfter, ASN1_TIME, 1) } ASN1_SEQUENCE_END(OSSL_CRMF_OPTIONALVALIDITY) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) - ASN1_SEQUENCE(OSSL_CRMF_CERTTEMPLATE) = { ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, version, ASN1_INTEGER, 0), /* @@ -208,7 +195,6 @@ ASN1_SEQUENCE(OSSL_CRMF_CERTTEMPLATE) = { } ASN1_SEQUENCE_END(OSSL_CRMF_CERTTEMPLATE) IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE) - ASN1_SEQUENCE(OSSL_CRMF_CERTREQUEST) = { ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certReqId, ASN1_INTEGER), ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certTemplate, OSSL_CRMF_CERTTEMPLATE), @@ -218,7 +204,6 @@ ASN1_SEQUENCE(OSSL_CRMF_CERTREQUEST) = { IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) - ASN1_SEQUENCE(OSSL_CRMF_MSG) = { ASN1_SIMPLE(OSSL_CRMF_MSG, certReq, OSSL_CRMF_CERTREQUEST), ASN1_OPT(OSSL_CRMF_MSG, popo, OSSL_CRMF_POPO), diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 3607fb0bf4..cb077e41d2 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -1,5 +1,5 @@ /*- - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2018 * Copyright Siemens AG 2015-2019 * @@ -29,8 +29,9 @@ #include #include "crmf_local.h" -#include "internal/constant_time.h" #include "internal/sizes.h" +#include "crypto/evp.h" +#include "crypto/x509.h" /* explicit #includes not strictly needed since implied by the above: */ #include @@ -80,7 +81,6 @@ int OSSL_CRMF_MSG_set1_##ctrlinf##_##atyp(OSSL_CRMF_MSG *msg, const valt *in) \ return 0; \ } - /*- * Pushes the given control attribute into the controls stack of a CertRequest * (section 6) @@ -243,7 +243,6 @@ IMPLEMENT_CRMF_CTRL_FUNC(utf8Pairs, ASN1_UTF8STRING, regInfo) /* id-regInfo-certReq to regInfo (section 7.2) */ IMPLEMENT_CRMF_CTRL_FUNC(certReq, OSSL_CRMF_CERTREQUEST, regInfo) - /* retrieves the certificate template of crm */ OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm) { @@ -254,7 +253,6 @@ OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm) return crm->certReq->certTemplate; } - int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm, ASN1_TIME *notBefore, ASN1_TIME *notAfter) { @@ -274,7 +272,6 @@ int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm, return 1; } - int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid) { if (crm == NULL || crm->certReq == NULL || crm->certReq->certReqId == NULL) { @@ -314,7 +311,6 @@ int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm) return crmf_asn1_get_int(crm->certReq->certReqId); } - int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, X509_EXTENSIONS *exts) { @@ -335,7 +331,6 @@ int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, return 1; } - int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext) { @@ -370,11 +365,16 @@ static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps, OSSL_LIB_CTX *libctx, const char *propq) { char name[80] = ""; + EVP_PKEY *pub; if (ps == NULL || cr == NULL || pkey == NULL) { ERR_raise(ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT); return 0; } + pub = X509_PUBKEY_get0(cr->certTemplate->publicKey); + if (!ossl_x509_check_private_key(pub, pkey)) + return 0; + if (ps->poposkInput != NULL) { /* We do not support cases 1+2 defined in RFC 4211, section 4.1 */ ERR_raise(ERR_LIB_CRMF, CRMF_R_POPOSKINPUT_NOT_SUPPORTED); @@ -386,11 +386,11 @@ static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps, digest = NULL; return ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), - ps->algorithmIdentifier, NULL, ps->signature, cr, - NULL, pkey, digest, libctx, propq); + ps->algorithmIdentifier, /* sets this X509_ALGOR */ + NULL, ps->signature, /* sets the ASN1_BIT_STRING */ + cr, NULL, pkey, digest, libctx, propq); } - int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, const EVP_MD *digest, OSSL_LIB_CTX *libctx, const char *propq) @@ -506,6 +506,12 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, ERR_raise(ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY); return 0; } + + /* + * Should check at this point the contents of the authInfo sub-field + * as requested in FR #19807 according to RFC 4211 section 4.1. + */ + it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT); asn = sig->poposkInput; } else { @@ -522,6 +528,12 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, return 0; break; case OSSL_CRMF_POPO_KEYENC: + /* + * When OSSL_CMP_certrep_new() supports encrypted certs, + * should return 1 if the type of req->popo->value.keyEncipherment + * is OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE and + * its value.subsequentMessage == OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT + */ case OSSL_CRMF_POPO_KEYAGREE: default: ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_POPO_METHOD); @@ -530,7 +542,12 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, return 1; } -/* retrieves the serialNumber of the given cert template or NULL on error */ +X509_PUBKEY +*OSSL_CRMF_CERTTEMPLATE_get0_publicKey(const OSSL_CRMF_CERTTEMPLATE *tmpl) +{ + return tmpl != NULL ? tmpl->publicKey : NULL; +} + const ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl) { @@ -538,40 +555,38 @@ const ASN1_INTEGER } const X509_NAME - *OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl) +*OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl) { return tmpl != NULL ? tmpl->subject : NULL; } -/* retrieves the issuer name of the given cert template or NULL on error */ const X509_NAME - *OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl) +*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl) { return tmpl != NULL ? tmpl->issuer : NULL; } X509_EXTENSIONS - *OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl) +*OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl) { return tmpl != NULL ? tmpl->extensions : NULL; } -/* retrieves the issuer name of the given CertId or NULL on error */ const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid) { return cid != NULL && cid->issuer->type == GEN_DIRNAME ? cid->issuer->d.directoryName : NULL; } -/* retrieves the serialNumber of the given CertId or NULL on error */ -const ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid) +const ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID + *cid) { return cid != NULL ? cid->serialNumber : NULL; } /*- - * fill in certificate template. - * Any value argument that is NULL will leave the respective field unchanged. + * Fill in the certificate template |tmpl|. + * Any other NULL argument will leave the respective field unchanged. */ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, EVP_PKEY *pubkey, @@ -597,7 +612,6 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, return 1; } - /*- * Decrypts the certificate in the given encryptedValue using private key pkey. * This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2. @@ -648,28 +662,12 @@ X509 cikeysize = EVP_CIPHER_get_key_length(cipher); /* first the symmetric key needs to be decrypted */ pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); - if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx) > 0) { - ASN1_BIT_STRING *encKey = ecert->encSymmKey; - size_t failure; - int retval; - - if (EVP_PKEY_decrypt(pkctx, NULL, &eksize, - encKey->data, encKey->length) <= 0 - || (ek = OPENSSL_malloc(eksize)) == NULL) - goto end; - retval = EVP_PKEY_decrypt(pkctx, ek, &eksize, - encKey->data, encKey->length); - ERR_clear_error(); /* error state may have sensitive information */ - failure = ~constant_time_is_zero_s(constant_time_msb(retval) - | constant_time_is_zero(retval)); - failure |= ~constant_time_eq_s(eksize, (size_t)cikeysize); - if (failure) { - ERR_raise(ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY); - goto end; - } - } else { + if (pkctx == NULL || EVP_PKEY_decrypt_init(pkctx) <= 0 + || evp_pkey_decrypt_alloc(pkctx, &ek, &eksize, (size_t)cikeysize, + ecert->encSymmKey->data, + ecert->encSymmKey->length) <= 0) goto end; - } + if ((iv = OPENSSL_malloc(EVP_CIPHER_get_iv_length(cipher))) == NULL) goto end; if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv, diff --git a/crypto/crmf/crmf_local.h b/crypto/crmf/crmf_local.h index 3b8c3701b5..e8937b4231 100644 --- a/crypto/crmf/crmf_local.h +++ b/crypto/crmf/crmf_local.h @@ -126,7 +126,6 @@ struct ossl_crmf_singlepubinfo_st { DEFINE_STACK_OF(OSSL_CRMF_SINGLEPUBINFO) typedef STACK_OF(OSSL_CRMF_SINGLEPUBINFO) OSSL_CRMF_PUBINFOS; - /*- * PKIPublicationInfo ::= SEQUENCE { * action INTEGER { @@ -189,6 +188,7 @@ typedef struct ossl_crmf_popoprivkey_st { ASN1_BIT_STRING *dhMAC; /* 2 */ /* Deprecated */ OSSL_CRMF_PKMACVALUE *agreeMAC; /* 3 */ ASN1_NULL *encryptedKey; /* 4 */ + /* When supported, ASN1_NULL needs to be replaced by CMS_ENVELOPEDDATA */ } value; } OSSL_CRMF_POPOPRIVKEY; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) @@ -330,7 +330,7 @@ struct ossl_crmf_certtemplate_st { struct ossl_crmf_certrequest_st { ASN1_INTEGER *certReqId; OSSL_CRMF_CERTTEMPLATE *certTemplate; - STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE /* Controls expanded */) *controls; } /* OSSL_CRMF_CERTREQUEST */; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c index 02f4c2fb46..d4c7af38cb 100644 --- a/crypto/crmf/crmf_pbm.c +++ b/crypto/crmf/crmf_pbm.c @@ -1,5 +1,5 @@ /*- - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -11,7 +11,6 @@ * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. */ - #include #include @@ -124,6 +123,7 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen, * |outlen| if not NULL, will set variable to the length of the mac on success * returns 1 on success, 0 on error */ +/* could be combined with other MAC calculations in the library */ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, const OSSL_CRMF_PBMPARAMETER *pbmp, const unsigned char *msg, size_t msglen, @@ -200,10 +200,11 @@ int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, mac_nid, NULL, &hmac_md_nid, NULL) || OBJ_obj2txt(hmac_mdname, sizeof(hmac_mdname), - OBJ_nid2obj(hmac_md_nid), 0) <= 0) { + OBJ_nid2obj(hmac_md_nid), 0) <= 0) { ERR_raise(ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM); goto err; } + /* could be generalized to allow non-HMAC: */ if (EVP_Q_mac(libctx, "HMAC", propq, hmac_mdname, NULL, basekey, bklen, msg, msglen, mac_res, EVP_MAX_MD_SIZE, outlen) == NULL) goto err; diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index b722d2bb5f..6c19479438 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -12,7 +12,7 @@ #include "crypto/cryptlib.h" #include -#if defined(_WIN32) +#if defined(_WIN32) && !defined(OPENSSL_SYS_UEFI) # include # include # ifdef __WATCOMC__ @@ -256,7 +256,7 @@ void OPENSSL_die(const char *message, const char *file, int line) { OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n", file, line, message); -#if !defined(_WIN32) +#if !defined(_WIN32) || defined(OPENSSL_SYS_UEFI) abort(); #else /* diff --git a/crypto/ct/ct_b64.c b/crypto/ct/ct_b64.c index d3f783962a..2535442063 100644 --- a/crypto/ct/ct_b64.c +++ b/crypto/ct/ct_b64.c @@ -34,10 +34,8 @@ static int ct_base64_decode(const char *in, unsigned char **out) outlen = (inlen / 4) * 3; outbuf = OPENSSL_malloc(outlen); - if (outbuf == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (outbuf == NULL) goto err; - } outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen); if (outlen < 0) { @@ -71,7 +69,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, int declen; if (sct == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_CT_LIB); return NULL; } diff --git a/crypto/ct/ct_log.c b/crypto/ct/ct_log.c index d19dda2cd2..95084dc76f 100644 --- a/crypto/ct/ct_log.c +++ b/crypto/ct/ct_log.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,9 +62,6 @@ static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new(void) { CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); - return ctx; } @@ -104,23 +101,19 @@ CTLOG_STORE *CTLOG_STORE_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->libctx = libctx; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); - if (ret->propq == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ret->propq == NULL) goto err; - } } ret->logs = sk_CTLOG_new_null(); if (ret->logs == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CT, ERR_R_CRYPTO_LIB); goto err; } @@ -196,7 +189,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len, tmp = OPENSSL_strndup(log_name, log_name_len); if (tmp == NULL) - goto mem_err; + return -1; ret = ctlog_new_from_conf(load_ctx->log_store, &ct_log, load_ctx->conf, tmp); OPENSSL_free(tmp); @@ -212,14 +205,11 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len, } if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) { - goto mem_err; + CTLOG_free(ct_log); + ERR_raise(ERR_LIB_CT, ERR_R_CRYPTO_LIB); + return -1; } return 1; - -mem_err: - CTLOG_free(ct_log); - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); - return -1; } int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file) @@ -269,25 +259,19 @@ CTLOG *CTLOG_new_ex(EVP_PKEY *public_key, const char *name, OSSL_LIB_CTX *libctx { CTLOG *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->libctx = libctx; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); - if (ret->propq == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ret->propq == NULL) goto err; - } } ret->name = OPENSSL_strdup(name); - if (ret->name == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ret->name == NULL) goto err; - } if (ct_v1_log_id_from_pkey(ret, public_key) != 1) goto err; diff --git a/crypto/ct/ct_oct.c b/crypto/ct/ct_oct.c index 72a4337479..145b277109 100644 --- a/crypto/ct/ct_oct.c +++ b/crypto/ct/ct_oct.c @@ -178,10 +178,8 @@ int i2o_SCT_signature(const SCT *sct, unsigned char **out) *out += len; } else { pstart = p = OPENSSL_malloc(len); - if (p == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (p == NULL) goto err; - } *out = p; } @@ -225,10 +223,8 @@ int i2o_SCT(const SCT *sct, unsigned char **out) *out += len; } else { pstart = p = OPENSSL_malloc(len); - if (p == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (p == NULL) goto err; - } *out = p; } @@ -330,10 +326,8 @@ int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp) ERR_raise(ERR_LIB_CT, CT_R_SCT_LIST_INVALID); return -1; } - if ((*pp = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if ((*pp = OPENSSL_malloc(len)) == NULL) return -1; - } is_pp_new = 1; } p = *pp + 2; diff --git a/crypto/ct/ct_policy.c b/crypto/ct/ct_policy.c index 80a8baabe1..725be7ce2a 100644 --- a/crypto/ct/ct_policy.c +++ b/crypto/ct/ct_policy.c @@ -13,7 +13,7 @@ #include #include -#include +#include "internal/time.h" #include "ct_local.h" @@ -29,25 +29,23 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX)); + OSSL_TIME now; - if (ctx == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->libctx = libctx; if (propq != NULL) { ctx->propq = OPENSSL_strdup(propq); if (ctx->propq == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); OPENSSL_free(ctx); return NULL; } } - /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */ - ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) * - 1000; + now = ossl_time_add(ossl_time_now(), + ossl_seconds2time(SCT_CLOCK_DRIFT_TOLERANCE)); + ctx->epoch_time_in_ms = ossl_time2ms(now); return ctx; } diff --git a/crypto/ct/ct_sct.c b/crypto/ct/ct_sct.c index 10a67ed6d6..ec87d02309 100644 --- a/crypto/ct/ct_sct.c +++ b/crypto/ct/ct_sct.c @@ -23,10 +23,8 @@ SCT *SCT_new(void) { SCT *sct = OPENSSL_zalloc(sizeof(*sct)); - if (sct == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (sct == NULL) return NULL; - } sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET; sct->version = SCT_VERSION_NOT_SET; @@ -105,10 +103,8 @@ int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len) if (log_id != NULL && log_id_len > 0) { sct->log_id = OPENSSL_memdup(log_id, log_id_len); - if (sct->log_id == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (sct->log_id == NULL) return 0; - } sct->log_id_len = log_id_len; } return 1; @@ -157,10 +153,8 @@ int SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len) if (ext != NULL && ext_len > 0) { sct->ext = OPENSSL_memdup(ext, ext_len); - if (sct->ext == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (sct->ext == NULL) return 0; - } sct->ext_len = ext_len; } return 1; @@ -183,10 +177,8 @@ int SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len) if (sig != NULL && sig_len > 0) { sct->sig = OPENSSL_memdup(sig, sig_len); - if (sct->sig == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (sct->sig == NULL) return 0; - } sct->sig_len = sig_len; } return 1; diff --git a/crypto/ct/ct_sct_ctx.c b/crypto/ct/ct_sct_ctx.c index 8653684814..effd724a0a 100644 --- a/crypto/ct/ct_sct_ctx.c +++ b/crypto/ct/ct_sct_ctx.c @@ -24,16 +24,13 @@ SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) { SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx)); - if (sctx == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); + if (sctx == NULL) return NULL; - } sctx->libctx = libctx; if (propq != NULL) { sctx->propq = OPENSSL_strdup(propq); if (sctx->propq == NULL) { - ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); OPENSSL_free(sctx); return NULL; } diff --git a/crypto/ctype.c b/crypto/ctype.c index de2e836ff7..48b3025ba5 100644 --- a/crypto/ctype.c +++ b/crypto/ctype.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -258,7 +258,7 @@ int ossl_ctype_check(int c, unsigned int mask) } /* - * Implement some of the simplier functions directly to avoid the overhead of + * Implement some of the simpler functions directly to avoid the overhead of * accessing memory via ctype_char_map[]. */ diff --git a/crypto/der_writer.c b/crypto/der_writer.c index 2ab7480a67..bd330785f9 100644 --- a/crypto/der_writer.c +++ b/crypto/der_writer.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/des_local.h b/crypto/des/des_local.h index 24d93bd3fb..d43f2c8737 100644 --- a/crypto/des/des_local.h +++ b/crypto/des/des_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -59,21 +59,6 @@ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) -/* - * replacements for htonl and ntohl since I have no idea what to do when - * faced with machines with 8 byte longs. - */ - -# define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ - l|=((DES_LONG)(*((c)++)))<<16L, \ - l|=((DES_LONG)(*((c)++)))<< 8L, \ - l|=((DES_LONG)(*((c)++)))) - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - /* NOTE - c is not incremented as per l2c */ # define l2cn(l1,l2,c,n) { \ c+=n; \ diff --git a/crypto/des/set_key.c b/crypto/des/set_key.c index adcfb7f124..068fb9133b 100644 --- a/crypto/des/set_key.c +++ b/crypto/des/set_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/deterministic_nonce.c b/crypto/deterministic_nonce.c new file mode 100644 index 0000000000..60af7f6ab6 --- /dev/null +++ b/crypto/deterministic_nonce.c @@ -0,0 +1,198 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/deterministic_nonce.h" + +/* + * Convert a Bit String to an Integer (See RFC 6979 Section 2.3.2) + * + * Params: + * out The returned Integer as a BIGNUM + * qlen_bits The maximum size of the returned integer in bits. The returned + * Integer is shifted right if inlen is larger than qlen_bits.. + * in, inlen The input Bit String (in bytes). + * Returns: 1 if successful, or 0 otherwise. + */ +static int bits2int(BIGNUM *out, int qlen_bits, + const unsigned char *in, size_t inlen) +{ + int blen_bits = inlen * 8; + int shift; + + if (BN_bin2bn(in, (int)inlen, out) == NULL) + return 0; + + shift = blen_bits - qlen_bits; + if (shift > 0) + return BN_rshift(out, out, shift); + return 1; +} + +/* + * Convert an Integer to an Octet String (See RFC 6979 2.3.3). + * The value is zero padded if required. + * + * Params: + * out The returned Octet String + * num The input Integer + * rlen The required size of the returned Octet String in bytes + * Returns: 1 if successful, or 0 otherwise. + */ +static int int2octets(unsigned char *out, const BIGNUM *num, int rlen) +{ + return BN_bn2binpad(num, out, rlen) >= 0; +} + +/* + * Convert a Bit String to an Octet String (See RFC 6979 Section 2.3.4) + * + * Params: + * out The returned octet string. + * q The modulus + * qlen_bits The length of q in bits + * rlen The value of qlen_bits rounded up to the nearest 8 bits. + * in, inlen The input bit string (in bytes) + * Returns: 1 if successful, or 0 otherwise. + */ +static int bits2octets(unsigned char *out, const BIGNUM *q, int qlen_bits, + int rlen, const unsigned char *in, size_t inlen) +{ + int ret = 0; + BIGNUM *z = BN_new(); + + if (z == NULL + || !bits2int(z, qlen_bits, in, inlen)) + goto err; + + /* z2 = z1 mod q (Do a simple subtract, since z1 < 2^qlen_bits) */ + if (BN_cmp(z, q) >= 0 + && !BN_usub(z, z, q)) + goto err; + + ret = int2octets(out, z, rlen); +err: + BN_free(z); + return ret; +} + +/* + * Setup a KDF HMAC_DRBG object using fixed entropy and nonce data. + * + * Params: + * digestname The digest name for the HMAC + * entropy, entropylen A fixed input entropy buffer + * nonce, noncelen A fixed input nonce buffer + * libctx, propq Are used for fetching algorithms + * + * Returns: The created KDF HMAC_DRBG object if successful, or NULL otherwise. + */ +static EVP_KDF_CTX *kdf_setup(const char *digestname, + const unsigned char *entropy, size_t entropylen, + const unsigned char *nonce, size_t noncelen, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_KDF_CTX *ctx = NULL; + EVP_KDF *kdf = NULL; + OSSL_PARAM params[5], *p; + + kdf = EVP_KDF_fetch(libctx, "HMAC-DRBG-KDF", propq); + ctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (ctx == NULL) + goto err; + + p = params; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)digestname, 0); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)propq, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_HMACDRBG_ENTROPY, + (void *)entropy, entropylen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_HMACDRBG_NONCE, + (void *)nonce, noncelen); + *p = OSSL_PARAM_construct_end(); + + if (EVP_KDF_CTX_set_params(ctx, params) <= 0) + goto err; + + return ctx; +err: + EVP_KDF_CTX_free(ctx); + return NULL; +} + +/* + * Generate a Deterministic nonce 'k' for DSA/ECDSA as defined in + * RFC 6979 Section 3.3. "Alternate Description of the Generation of k" + * + * Params: + * out Returns the generated deterministic nonce 'k' + * q A large prime number used for modulus operations for DSA and ECDSA. + * priv The private key in the range [1, q-1] + * hm, hmlen The digested message buffer in bytes + * digestname The digest name used for signing. It is used as the HMAC digest. + * libctx, propq Used for fetching algorithms + * + * Returns: 1 if successful, or 0 otherwise. + */ +int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, + const BIGNUM *priv, + const unsigned char *hm, size_t hmlen, + const char *digestname, + OSSL_LIB_CTX *libctx, + const char *propq) +{ + EVP_KDF_CTX *kdfctx = NULL; + int ret = 0, rlen = 0, qlen_bits = 0; + unsigned char *entropyx = NULL, *nonceh = NULL, *T = NULL; + size_t allocsz = 0; + + if (out == NULL) + return 0; + + qlen_bits = BN_num_bits(q); + if (qlen_bits == 0) + return 0; + + /* Note rlen used here is in bytes since the input values are byte arrays */ + rlen = (qlen_bits + 7) / 8; + allocsz = 3 * rlen; + + /* Use a single alloc for the buffers T, nonceh and entropyx */ + T = (unsigned char *)OPENSSL_zalloc(allocsz); + if (T == NULL) + return 0; + nonceh = T + rlen; + entropyx = nonceh + rlen; + + if (!int2octets(entropyx, priv, rlen) + || !bits2octets(nonceh, q, qlen_bits, rlen, hm, hmlen)) + goto end; + + kdfctx = kdf_setup(digestname, entropyx, rlen, nonceh, rlen, libctx, propq); + if (kdfctx == NULL) + goto end; + + do { + if (!EVP_KDF_derive(kdfctx, T, rlen, NULL) + || !bits2int(out, qlen_bits, T, rlen)) + goto end; + } while (BN_is_zero(out) || BN_is_one(out) || BN_cmp(out, q) >= 0); + ret = 1; + +end: + EVP_KDF_CTX_free(kdfctx); + OPENSSL_clear_free(T, allocsz); + return ret; +} diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index 8430872a9a..80e1612256 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -121,12 +121,12 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) str = ASN1_STRING_new(); if (str == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_ASN1_LIB); goto err; } str->length = i2d_dhp(pkey, dh, &str->data); if (str->length <= 0) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_ASN1_LIB); goto err; } ptype = V_ASN1_SEQUENCE; @@ -140,7 +140,7 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ASN1_INTEGER_free(pub_key); if (penclen <= 0) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_ASN1_LIB); goto err; } @@ -184,13 +184,13 @@ static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_ASN1_LIB); goto err; } params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_ASN1_LIB); goto err; } params->type = V_ASN1_SEQUENCE; @@ -514,7 +514,7 @@ static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx, DH *dh = ossl_dh_new_ex(pctx->libctx); if (dh == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_DH_LIB); return 0; } DH_clear_flags(dh, DH_FLAG_TYPE_MASK); diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c index 726843fd30..1aaa88daca 100644 --- a/crypto/dh/dh_backend.c +++ b/crypto/dh/dh_backend.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,13 +31,7 @@ static int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[]) { int ret; - FFC_PARAMS *ffc; - - if (dh == NULL) - return 0; - ffc = ossl_dh_get0_params(dh); - if (ffc == NULL) - return 0; + FFC_PARAMS *ffc = ossl_dh_get0_params(dh); ret = ossl_ffc_params_fromdata(ffc, params); if (ret) diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 7ba2beae7f..e20eb62081 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -249,6 +249,18 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) */ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) { + /* Don't do any checks at all with an excessively large modulus */ + if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); + *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID; + return 0; + } + + if (dh->params.q != NULL && BN_ucmp(dh->params.p, dh->params.q) < 0) { + *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; + return 1; + } + return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); } diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index 4152397426..4d6d2acd98 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -42,6 +42,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = { "invalid parameter nid"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "invalid public key"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_SECRET), "invalid secret"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_SIZE), "invalid size"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"}, @@ -54,6 +55,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = { {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR), "unable to check generator"}, diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 204662a81c..b73bfb7f3b 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index d84ea99241..7132b9b68e 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -49,6 +49,12 @@ int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) goto err; } + if (dh->params.q != NULL + && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE); + goto err; + } + if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) { ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); return 0; @@ -184,7 +190,11 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { +#ifdef S390X_MOD_EXP + return s390x_mod_exp(r, a, p, m, ctx, m_ctx); +#else return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +#endif } static int dh_init(DH *dh) @@ -267,6 +277,12 @@ static int generate_key(DH *dh) return 0; } + if (dh->params.q != NULL + && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE); + return 0; + } + if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) { ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL); return 0; @@ -417,14 +433,15 @@ size_t ossl_dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, if (!alloc) { if (size >= (size_t)p_size) pbuf = *pbuf_out; + if (pbuf == NULL) + ERR_raise(ERR_LIB_DH, DH_R_INVALID_SIZE); } else { pbuf = OPENSSL_malloc(p_size); } - if (pbuf == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + /* Errors raised above */ + if (pbuf == NULL) return 0; - } /* * As per Section 4.2.8.1 of RFC 8446 left pad public * key with zeros to the size of p diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 5577413e1e..9d5a6b0b6c 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -75,15 +75,18 @@ static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DH *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } - ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_CRYPTO_LIB); + OPENSSL_free(ret); + return NULL; + } + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; } @@ -137,7 +140,7 @@ void DH_free(DH *r) if (r == NULL) return; - CRYPTO_DOWN_REF(&r->references, &i, r->lock); + CRYPTO_DOWN_REF(&r->references, &i); REF_PRINT_COUNT("DH", r); if (i > 0) return; @@ -153,6 +156,7 @@ void DH_free(DH *r) #endif CRYPTO_THREAD_lock_free(r->lock); + CRYPTO_FREE_REF(&r->references); ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); @@ -164,7 +168,7 @@ int DH_up_ref(DH *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + if (CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; REF_PRINT_COUNT("DH", r); diff --git a/crypto/dh/dh_meth.c b/crypto/dh/dh_meth.c index 5c15cd2b8c..f5652e0785 100644 --- a/crypto/dh/dh_meth.c +++ b/crypto/dh/dh_meth.c @@ -31,7 +31,6 @@ DH_METHOD *DH_meth_new(const char *name, int flags) OPENSSL_free(dhm); } - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return NULL; } @@ -57,7 +56,6 @@ DH_METHOD *DH_meth_dup(const DH_METHOD *dhm) OPENSSL_free(ret); } - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return NULL; } @@ -70,10 +68,8 @@ int DH_meth_set1_name(DH_METHOD *dhm, const char *name) { char *tmpname = OPENSSL_strdup(name); - if (tmpname == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + if (tmpname == NULL) return 0; - } OPENSSL_free(dhm->name); dhm->name = tmpname; diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index f201eede0d..c11ada9826 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -55,10 +55,8 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) { DH_PKEY_CTX *dctx; - if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) return 0; - } dctx->prime_len = 2048; dctx->subprime_len = -1; dctx->generator = 2; @@ -445,10 +443,8 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, ret = 0; if ((Zlen = DH_size(dh)) <= 0) return 0; - if ((Z = OPENSSL_malloc(Zlen)) == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + if ((Z = OPENSSL_malloc(Zlen)) == NULL) return 0; - } if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0) goto err; if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 482b9e1e0a..15a5266ca4 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -54,7 +54,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { if ((dsa = DSA_new()) == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB); goto err; } } else { @@ -101,12 +101,12 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) && dsa->params.g != NULL) { str = ASN1_STRING_new(); if (str == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } ptype = V_ASN1_SEQUENCE; @@ -116,7 +116,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL); if (pubint == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } @@ -124,7 +124,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) ASN1_INTEGER_free(pubint); if (penclen <= 0) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } @@ -175,13 +175,13 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_ASN1_LIB); goto err; } params->type = V_ASN1_SEQUENCE; @@ -483,7 +483,7 @@ static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) DSA *dsa = ossl_dsa_new(pctx->libctx); if (dsa == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB); return 0; } diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c index 389df304bd..8bd4b8ad7e 100644 --- a/crypto/dsa/dsa_backend.c +++ b/crypto/dsa/dsa_backend.c @@ -158,11 +158,11 @@ DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, } /* Calculate public key */ if ((dsa_pubkey = BN_new()) == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB); goto dsaerr; } if ((ctx = BN_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB); goto dsaerr; } diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index bd67627e11..1c2bab1714 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,8 +28,7 @@ # define MIN_STRENGTH 80 #endif -static int dsa_keygen(DSA *dsa, int pairwise_test); -static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg); +static int dsa_keygen(DSA *dsa); int DSA_generate_key(DSA *dsa) { @@ -37,7 +36,7 @@ int DSA_generate_key(DSA *dsa) if (dsa->meth->dsa_keygen != NULL) return dsa->meth->dsa_keygen(dsa); #endif - return dsa_keygen(dsa, 0); + return dsa_keygen(dsa); } int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, @@ -59,6 +58,7 @@ int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, return ret; } +#ifdef FIPS_MODULE /* * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1 * Perform a KAT by duplicating the public key generation. @@ -107,7 +107,44 @@ static int dsa_keygen_knownanswer_test(DSA *dsa, BN_CTX *ctx, return ret; } -static int dsa_keygen(DSA *dsa, int pairwise_test) +/* + * FIPS 140-2 IG 9.9 AS09.33 + * Perform a sign/verify operation. + */ +static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) +{ + int ret = 0; + unsigned char dgst[16] = {0}; + unsigned int dgst_len = (unsigned int)sizeof(dgst); + DSA_SIG *sig = NULL; + OSSL_SELF_TEST *st = NULL; + + st = OSSL_SELF_TEST_new(cb, cbarg); + if (st == NULL) + goto err; + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_DSA); + + sig = DSA_do_sign(dgst, (int)dgst_len, dsa); + if (sig == NULL) + goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, dgst); + + if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) + goto err; + + ret = 1; +err: + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); + DSA_SIG_free(sig); + return ret; +} +#endif /* FIPS_MODULE */ + +static int dsa_keygen(DSA *dsa) { int ok = 0; BN_CTX *ctx = NULL; @@ -151,12 +188,9 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) dsa->priv_key = priv_key; dsa->pub_key = pub_key; -#ifdef FIPS_MODULE - pairwise_test = 1; -#endif /* FIPS_MODULE */ - ok = 1; - if (pairwise_test) { +#ifdef FIPS_MODULE + { OSSL_CALLBACK *cb = NULL; void *cbarg = NULL; @@ -173,6 +207,7 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) return ok; } } +#endif dsa->dirty_cnt++; err: @@ -184,39 +219,3 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) return ok; } - -/* - * FIPS 140-2 IG 9.9 AS09.33 - * Perform a sign/verify operation. - */ -static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) -{ - int ret = 0; - unsigned char dgst[16] = {0}; - unsigned int dgst_len = (unsigned int)sizeof(dgst); - DSA_SIG *sig = NULL; - OSSL_SELF_TEST *st = NULL; - - st = OSSL_SELF_TEST_new(cb, cbarg); - if (st == NULL) - goto err; - - OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, - OSSL_SELF_TEST_DESC_PCT_DSA); - - sig = DSA_do_sign(dgst, (int)dgst_len, dsa); - if (sig == NULL) - goto err; - - OSSL_SELF_TEST_oncorrupt_byte(st, dgst); - - if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) - goto err; - - ret = 1; -err: - OSSL_SELF_TEST_onend(st, ret); - OSSL_SELF_TEST_free(st); - DSA_SIG_free(sig); - return ret; -} diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 2ae3f8e36b..7997c2ac25 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -134,15 +134,18 @@ static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DSA *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } - ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSA, ERR_R_CRYPTO_LIB); + OPENSSL_free(ret); + return NULL; + } + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; } @@ -214,7 +217,7 @@ void DSA_free(DSA *r) if (r == NULL) return; - CRYPTO_DOWN_REF(&r->references, &i, r->lock); + CRYPTO_DOWN_REF(&r->references, &i); REF_PRINT_COUNT("DSA", r); if (i > 0) return; @@ -231,6 +234,7 @@ void DSA_free(DSA *r) #endif CRYPTO_THREAD_lock_free(r->lock); + CRYPTO_FREE_REF(&r->references); ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); @@ -242,7 +246,7 @@ int DSA_up_ref(DSA *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + if (CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; REF_PRINT_COUNT("DSA", r); @@ -349,13 +353,7 @@ FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa) int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) { int ret; - FFC_PARAMS *ffc; - - if (dsa == NULL) - return 0; - ffc = ossl_dsa_get0_params(dsa); - if (ffc == NULL) - return 0; + FFC_PARAMS *ffc = ossl_dsa_get0_params(dsa); ret = ossl_ffc_params_fromdata(ffc, params); if (ret) diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h index 4e963809ba..38cb64a829 100644 --- a/crypto/dsa/dsa_local.h +++ b/crypto/dsa/dsa_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -69,4 +69,6 @@ struct dsa_method { int (*dsa_keygen) (DSA *dsa); }; -DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa); +DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); diff --git a/crypto/dsa/dsa_meth.c b/crypto/dsa/dsa_meth.c index 2f0a0bf460..f2b759a9de 100644 --- a/crypto/dsa/dsa_meth.c +++ b/crypto/dsa/dsa_meth.c @@ -32,7 +32,6 @@ DSA_METHOD *DSA_meth_new(const char *name, int flags) OPENSSL_free(dsam); } - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -58,7 +57,6 @@ DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam) OPENSSL_free(ret); } - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -71,10 +69,8 @@ int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name) { char *tmpname = OPENSSL_strdup(name); - if (tmpname == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + if (tmpname == NULL) return 0; - } OPENSSL_free(dsam->name); dsam->name = tmpname; diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 8fd66a950e..234362b6d7 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -20,6 +20,7 @@ #include #include "dsa_local.h" #include +#include "internal/deterministic_nonce.h" #define MIN_DSA_SIGN_QBITS 128 #define MAX_DSA_SIGN_RETRIES 8 @@ -28,7 +29,9 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp, const unsigned char *dgst, int dlen); + BIGNUM **rp, const unsigned char *dgst, int dlen, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); static int dsa_init(DSA *dsa); @@ -70,7 +73,9 @@ const DSA_METHOD *DSA_OpenSSL(void) return &openssl_dsa_meth; } -DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa) +DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) { BIGNUM *kinv = NULL; BIGNUM *m, *blind, *blindm, *tmp; @@ -110,7 +115,8 @@ DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa) goto err; redo: - if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen)) + if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen, + nonce_type, digestname, libctx, propq)) goto err; if (dlen > BN_num_bytes(dsa->params.q)) @@ -197,18 +203,22 @@ DSA_SIG *ossl_dsa_do_sign_int(const unsigned char *dgst, int dlen, DSA *dsa) static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { - return ossl_dsa_do_sign_int(dgst, dlen, dsa); + return ossl_dsa_do_sign_int(dgst, dlen, dsa, + 0, NULL, NULL, NULL); } static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { - return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0); + return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0, + 0, NULL, NULL, NULL); } static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp, - const unsigned char *dgst, int dlen) + const unsigned char *dgst, int dlen, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) { BN_CTX *ctx = NULL; BIGNUM *k, *kinv = NULL, *r = *rp; @@ -258,13 +268,24 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, /* Get random k */ do { if (dgst != NULL) { - /* - * We calculate k from SHA512(private_key + H(message) + random). - * This protects the private key from a weak PRNG. - */ - if (!BN_generate_dsa_nonce(k, dsa->params.q, dsa->priv_key, dgst, - dlen, ctx)) - goto err; + if (nonce_type == 1) { +#ifndef FIPS_MODULE + if (!ossl_gen_deterministic_nonce_rfc6979(k, dsa->params.q, + dsa->priv_key, + dgst, dlen, + digestname, + libctx, propq)) +#endif + goto err; + } else { + /* + * We calculate k from SHA512(private_key + H(message) + random). + * This protects the private key from a weak PRNG. + */ + if (!BN_generate_dsa_nonce(k, dsa->params.q, dsa->priv_key, dgst, + dlen, ctx)) + goto err; + } } else if (!BN_priv_rand_range_ex(k, dsa->params.q, 0, ctx)) goto err; } while (BN_is_zero(k)); diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index ddfbfa18af..b806e7e655 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -34,8 +34,7 @@ int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) DSA_SIG *DSA_SIG_new(void) { DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); - if (sig == NULL) - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + return sig; } @@ -152,7 +151,9 @@ int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) } int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa) + unsigned char *sig, unsigned int *siglen, DSA *dsa, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) { DSA_SIG *s; @@ -160,7 +161,8 @@ int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, if (dsa->libctx == NULL || dsa->meth != DSA_get_default_method()) s = DSA_do_sign(dgst, dlen, dsa); else - s = ossl_dsa_do_sign_int(dgst, dlen, dsa); + s = ossl_dsa_do_sign_int(dgst, dlen, dsa, + nonce_type, digestname, libctx, propq); if (s == NULL) { *siglen = 0; return 0; @@ -173,7 +175,8 @@ int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { - return ossl_dsa_sign_int(type, dgst, dlen, sig, siglen, dsa); + return ossl_dsa_sign_int(type, dgst, dlen, sig, siglen, dsa, + 0, NULL, NULL, NULL); } /* data has already been hashed (probably with SHA or SHA-1). */ diff --git a/crypto/dso/dso_dl.c b/crypto/dso/dso_dl.c index f4e6e5f457..ac94254807 100644 --- a/crypto/dso/dso_dl.c +++ b/crypto/dso/dso_dl.c @@ -165,20 +165,16 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) */ if (!filespec2 || filespec1[0] == '/') { merged = OPENSSL_strdup(filespec1); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } } /* * If the first file specification is missing, the second one rules. */ else if (!filespec1) { merged = OPENSSL_strdup(filespec2); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } } else /* * This part isn't as trivial as it looks. It assumes that the @@ -198,10 +194,8 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) len--; } merged = OPENSSL_malloc(len + 2); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } strcpy(merged, filespec2); merged[spec2len] = '/'; strcpy(&merged[spec2len + 1], filespec1); diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c index c292b41c43..2befd67248 100644 --- a/crypto/dso/dso_dlfcn.c +++ b/crypto/dso/dso_dlfcn.c @@ -207,20 +207,16 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, */ if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { merged = OPENSSL_strdup(filespec1); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } } /* * If the first file specification is missing, the second one rules. */ else if (!filespec1) { merged = OPENSSL_strdup(filespec2); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } } else { /* * This part isn't as trivial as it looks. It assumes that the @@ -239,10 +235,8 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, len--; } merged = OPENSSL_malloc(len + 2); - if (merged == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (merged == NULL) return NULL; - } strcpy(merged, filespec2); merged[spec2len] = '/'; strcpy(&merged[spec2len + 1], filespec1); diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c index 9d755986d7..8f3387e9b8 100644 --- a/crypto/dso/dso_lib.c +++ b/crypto/dso/dso_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,22 +15,17 @@ static DSO *DSO_new_method(DSO_METHOD *meth) DSO *ret; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->meth_data = sk_void_new_null(); if (ret->meth_data == NULL) { /* sk_new doesn't generate any errors so we do */ - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_CRYPTO_LIB); OPENSSL_free(ret); return NULL; } ret->meth = DSO_METHOD_openssl(); - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { sk_void_free(ret->meth_data); OPENSSL_free(ret); return NULL; @@ -56,7 +51,7 @@ int DSO_free(DSO *dso) if (dso == NULL) return 1; - if (CRYPTO_DOWN_REF(&dso->references, &i, dso->lock) <= 0) + if (CRYPTO_DOWN_REF(&dso->references, &i) <= 0) return 0; REF_PRINT_COUNT("DSO", dso); @@ -79,7 +74,7 @@ int DSO_free(DSO *dso) sk_void_free(dso->meth_data); OPENSSL_free(dso->filename); OPENSSL_free(dso->loaded_filename); - CRYPTO_THREAD_lock_free(dso->lock); + CRYPTO_FREE_REF(&dso->references); OPENSSL_free(dso); return 1; } @@ -98,7 +93,7 @@ int DSO_up_ref(DSO *dso) return 0; } - if (CRYPTO_UP_REF(&dso->references, &i, dso->lock) <= 0) + if (CRYPTO_UP_REF(&dso->references, &i) <= 0) return 0; REF_PRINT_COUNT("DSO", dso); @@ -114,7 +109,7 @@ DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) if (dso == NULL) { ret = DSO_new_method(meth); if (ret == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DSO, ERR_R_DSO_LIB); goto err; } allocated = 1; @@ -241,10 +236,8 @@ int DSO_set_filename(DSO *dso, const char *filename) } /* We'll duplicate filename */ copied = OPENSSL_strdup(filename); - if (copied == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (copied == NULL) return 0; - } OPENSSL_free(dso->filename); dso->filename = copied; return 1; @@ -289,10 +282,8 @@ char *DSO_convert_filename(DSO *dso, const char *filename) } if (result == NULL) { result = OPENSSL_strdup(filename); - if (result == NULL) { - ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE); + if (result == NULL) return NULL; - } } return result; } diff --git a/crypto/dso/dso_local.h b/crypto/dso/dso_local.h index 8aa29c1826..d7af0b064e 100644 --- a/crypto/dso/dso_local.h +++ b/crypto/dso/dso_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,7 +61,6 @@ struct dso_st { * loaded. */ char *loaded_filename; - CRYPTO_RWLOCK *lock; }; struct dso_meth_st { diff --git a/crypto/ec/asm/ecp_nistp384-ppc64.pl b/crypto/ec/asm/ecp_nistp384-ppc64.pl new file mode 100755 index 0000000000..28f4168e52 --- /dev/null +++ b/crypto/ec/asm/ecp_nistp384-ppc64.pl @@ -0,0 +1,306 @@ +#! /usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +# +# ==================================================================== +# Written by Rohan McLure for the OpenSSL +# project. +# ==================================================================== +# +# p384 lower-level primitives for PPC64 using vector instructions. +# + +use strict; +use warnings; + +my $flavour = shift; +my $output = ""; +while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} +if (!$output) { + $output = "-"; +} + +my ($xlate, $dir); +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +my $code = ""; + +my ($sp, $outp, $savelr, $savesp) = ("r1", "r3", "r10", "r12"); + +my $vzero = "v32"; + +sub startproc($) +{ + my ($name) = @_; + + $code.=<<___; + .globl ${name} + .align 5 +${name}: + +___ +} + +sub endproc($) +{ + my ($name) = @_; + + $code.=<<___; + blr + .size ${name},.-${name} + +___ +} + +sub load_vrs($$) +{ + my ($pointer, $reg_list) = @_; + + for (my $i = 0; $i <= 6; $i++) { + my $offset = $i * 8; + $code.=<<___; + lxsd $reg_list->[$i],$offset($pointer) +___ + } + + $code.=<<___; + +___ +} + +sub store_vrs($$) +{ + my ($pointer, $reg_list) = @_; + + for (my $i = 0; $i <= 12; $i++) { + my $offset = $i * 16; + $code.=<<___; + stxv $reg_list->[$i],$offset($pointer) +___ + } + + $code.=<<___; + +___ +} + +$code.=<<___; +.machine "any" +.text + +___ + +{ + # mul/square common + my ($t1, $t2, $t3, $t4) = ("v33", "v34", "v42", "v43"); + my ($zero, $one) = ("r8", "r9"); + my $out = "v51"; + + { + # + # p384_felem_mul + # + + my ($in1p, $in2p) = ("r4", "r5"); + my @in1 = map("v$_",(44..50)); + my @in2 = map("v$_",(35..41)); + + startproc("p384_felem_mul"); + + $code.=<<___; + vspltisw $vzero,0 + +___ + + load_vrs($in1p, \@in1); + load_vrs($in2p, \@in2); + + $code.=<<___; + vmsumudm $out,$in1[0],$in2[0],$vzero + stxv $out,0($outp) + + xxpermdi $t1,$in1[0],$in1[1],0b00 + xxpermdi $t2,$in2[1],$in2[0],0b00 + vmsumudm $out,$t1,$t2,$vzero + stxv $out,16($outp) + + xxpermdi $t2,$in2[2],$in2[1],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$in1[2],$in2[0],$out + stxv $out,32($outp) + + xxpermdi $t2,$in2[1],$in2[0],0b00 + xxpermdi $t3,$in1[2],$in1[3],0b00 + xxpermdi $t4,$in2[3],$in2[2],0b00 + vmsumudm $out,$t1,$t4,$vzero + vmsumudm $out,$t3,$t2,$out + stxv $out,48($outp) + + xxpermdi $t2,$in2[4],$in2[3],0b00 + xxpermdi $t4,$in2[2],$in2[1],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$t3,$t4,$out + vmsumudm $out,$in1[4],$in2[0],$out + stxv $out,64($outp) + + xxpermdi $t2,$in2[5],$in2[4],0b00 + xxpermdi $t4,$in2[3],$in2[2],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$t3,$t4,$out + xxpermdi $t4,$in2[1],$in2[0],0b00 + xxpermdi $t1,$in1[4],$in1[5],0b00 + vmsumudm $out,$t1,$t4,$out + stxv $out,80($outp) + + xxpermdi $t1,$in1[0],$in1[1],0b00 + xxpermdi $t2,$in2[6],$in2[5],0b00 + xxpermdi $t4,$in2[4],$in2[3],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$t3,$t4,$out + xxpermdi $t2,$in2[2],$in2[1],0b00 + xxpermdi $t1,$in1[4],$in1[5],0b00 + vmsumudm $out,$t1,$t2,$out + vmsumudm $out,$in1[6],$in2[0],$out + stxv $out,96($outp) + + xxpermdi $t1,$in1[1],$in1[2],0b00 + xxpermdi $t2,$in2[6],$in2[5],0b00 + xxpermdi $t3,$in1[3],$in1[4],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$t3,$t4,$out + xxpermdi $t3,$in2[2],$in2[1],0b00 + xxpermdi $t1,$in1[5],$in1[6],0b00 + vmsumudm $out,$t1,$t3,$out + stxv $out,112($outp) + + xxpermdi $t1,$in1[2],$in1[3],0b00 + xxpermdi $t3,$in1[4],$in1[5],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$t3,$t4,$out + vmsumudm $out,$in1[6],$in2[2],$out + stxv $out,128($outp) + + xxpermdi $t1,$in1[3],$in1[4],0b00 + vmsumudm $out,$t1,$t2,$vzero + xxpermdi $t1,$in1[5],$in1[6],0b00 + vmsumudm $out,$t1,$t4,$out + stxv $out,144($outp) + + vmsumudm $out,$t3,$t2,$vzero + vmsumudm $out,$in1[6],$in2[4],$out + stxv $out,160($outp) + + vmsumudm $out,$t1,$t2,$vzero + stxv $out,176($outp) + + vmsumudm $out,$in1[6],$in2[6],$vzero + stxv $out,192($outp) +___ + + endproc("p384_felem_mul"); + } + + { + # + # p384_felem_square + # + + my ($inp) = ("r4"); + my @in = map("v$_",(44..50)); + my @inx2 = map("v$_",(35..41)); + + startproc("p384_felem_square"); + + $code.=<<___; + vspltisw $vzero,0 + +___ + + load_vrs($inp, \@in); + + $code.=<<___; + li $zero,0 + li $one,1 + mtvsrdd $t1,$one,$zero +___ + + for (my $i = 0; $i <= 6; $i++) { + $code.=<<___; + vsld $inx2[$i],$in[$i],$t1 +___ + } + + $code.=<<___; + vmsumudm $out,$in[0],$in[0],$vzero + stxv $out,0($outp) + + vmsumudm $out,$in[0],$inx2[1],$vzero + stxv $out,16($outp) + + vmsumudm $out,$in[0],$inx2[2],$vzero + vmsumudm $out,$in[1],$in[1],$out + stxv $out,32($outp) + + xxpermdi $t1,$in[0],$in[1],0b00 + xxpermdi $t2,$inx2[3],$inx2[2],0b00 + vmsumudm $out,$t1,$t2,$vzero + stxv $out,48($outp) + + xxpermdi $t4,$inx2[4],$inx2[3],0b00 + vmsumudm $out,$t1,$t4,$vzero + vmsumudm $out,$in[2],$in[2],$out + stxv $out,64($outp) + + xxpermdi $t2,$inx2[5],$inx2[4],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$in[2],$inx2[3],$out + stxv $out,80($outp) + + xxpermdi $t2,$inx2[6],$inx2[5],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$in[2],$inx2[4],$out + vmsumudm $out,$in[3],$in[3],$out + stxv $out,96($outp) + + xxpermdi $t3,$in[1],$in[2],0b00 + vmsumudm $out,$t3,$t2,$vzero + vmsumudm $out,$in[3],$inx2[4],$out + stxv $out,112($outp) + + xxpermdi $t1,$in[2],$in[3],0b00 + vmsumudm $out,$t1,$t2,$vzero + vmsumudm $out,$in[4],$in[4],$out + stxv $out,128($outp) + + xxpermdi $t1,$in[3],$in[4],0b00 + vmsumudm $out,$t1,$t2,$vzero + stxv $out,144($outp) + + vmsumudm $out,$in[4],$inx2[6],$vzero + vmsumudm $out,$in[5],$in[5],$out + stxv $out,160($outp) + + vmsumudm $out,$in[5],$inx2[6],$vzero + stxv $out,176($outp) + + vmsumudm $out,$in[6],$in[6],$vzero + stxv $out,192($outp) +___ + + endproc("p384_felem_square"); + } +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl index 5bb6990e81..6c5d0e8b3c 100644 --- a/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/asm/ecp_sm2p256-armv8.S b/crypto/ec/asm/ecp_sm2p256-armv8.S new file mode 100644 index 0000000000..686943e51e --- /dev/null +++ b/crypto/ec/asm/ecp_sm2p256-armv8.S @@ -0,0 +1,826 @@ +#include "arm_arch.h" +.arch armv8-a +.text + +.align 5 +// The polynomial p +.Lpoly: +.quad 0xffffffffffffffff,0xffffffff00000000,0xffffffffffffffff,0xfffffffeffffffff +// The order of polynomial n +.Lord: +.quad 0x53bbf40939d54123,0x7203df6b21c6052b,0xffffffffffffffff,0xfffffffeffffffff +// (p + 1) / 2 +.Lpoly_div_2: +.quad 0x8000000000000000,0xffffffff80000000,0xffffffffffffffff,0x7fffffff7fffffff +// (n + 1) / 2 +.Lord_div_2: +.quad 0xa9ddfa049ceaa092,0xb901efb590e30295,0xffffffffffffffff,0x7fffffff7fffffff + +// void bn_rshift1(BN_ULONG *a); +.globl bn_rshift1 +.type bn_rshift1,%function +.align 5 +bn_rshift1: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x0] + ldp x9,x10,[x0,#16] + + # Right shift + extr x7,x8,x7,#1 + extr x8,x9,x8,#1 + extr x9,x10,x9,#1 + lsr x10,x10,#1 + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + + ret +.size bn_rshift1,.-bn_rshift1 + +// void bn_sub(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +.globl bn_sub +.type bn_sub,%function +.align 5 +bn_sub: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Subtraction + subs x7,x7,x11 + sbcs x8,x8,x12 + sbcs x9,x9,x13 + sbc x10,x10,x14 + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + + ret +.size bn_sub,.-bn_sub + +// void ecp_sm2p256_div_by_2(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_div_by_2 +.type ecp_sm2p256_div_by_2,%function +.align 5 +ecp_sm2p256_div_by_2: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + + # Save the least significant bit + mov x3,x7 + + # Right shift 1 + extr x7,x8,x7,#1 + extr x8,x9,x8,#1 + extr x9,x10,x9,#1 + lsr x10,x10,#1 + + # Load mod + adr x2,.Lpoly_div_2 + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Parity check + tst x3,#1 + csel x11,xzr,x11,eq + csel x12,xzr,x12,eq + csel x13,xzr,x13,eq + csel x14,xzr,x14,eq + + # Add + adds x7,x7,x11 + adcs x8,x8,x12 + adcs x9,x9,x13 + adc x10,x10,x14 + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + ret +.size ecp_sm2p256_div_by_2,.-ecp_sm2p256_div_by_2 + +// void ecp_sm2p256_div_by_2_mod_ord(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_div_by_2_mod_ord +.type ecp_sm2p256_div_by_2_mod_ord,%function +.align 5 +ecp_sm2p256_div_by_2_mod_ord: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + + # Save the least significant bit + mov x3,x7 + + # Right shift 1 + extr x7,x8,x7,#1 + extr x8,x9,x8,#1 + extr x9,x10,x9,#1 + lsr x10,x10,#1 + + # Load mod + adr x2,.Lord_div_2 + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Parity check + tst x3,#1 + csel x11,xzr,x11,eq + csel x12,xzr,x12,eq + csel x13,xzr,x13,eq + csel x14,xzr,x14,eq + + # Add + adds x7,x7,x11 + adcs x8,x8,x12 + adcs x9,x9,x13 + adc x10,x10,x14 + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + ret +.size ecp_sm2p256_div_by_2_mod_ord,.-ecp_sm2p256_div_by_2_mod_ord + +// void ecp_sm2p256_mul_by_3(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_mul_by_3 +.type ecp_sm2p256_mul_by_3,%function +.align 5 +ecp_sm2p256_mul_by_3: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + + # 2*a + adds x7,x7,x7 + adcs x8,x8,x8 + adcs x9,x9,x9 + adcs x10,x10,x10 + adcs x15,xzr,xzr + + mov x3,x7 + mov x4,x8 + mov x5,x9 + mov x6,x10 + + # Sub polynomial + adr x2,.Lpoly + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + subs x7,x7,x11 + sbcs x8,x8,x12 + sbcs x9,x9,x13 + sbcs x10,x10,x14 + sbcs x15,x15,xzr + + csel x7,x7,x3,cs + csel x8,x8,x4,cs + csel x9,x9,x5,cs + csel x10,x10,x6,cs + eor x15,x15,x15 + + # 3*a + ldp x11,x12,[x1] + ldp x13,x14,[x1,#16] + adds x7,x7,x11 + adcs x8,x8,x12 + adcs x9,x9,x13 + adcs x10,x10,x14 + adcs x15,xzr,xzr + + mov x3,x7 + mov x4,x8 + mov x5,x9 + mov x6,x10 + + # Sub polynomial + adr x2,.Lpoly + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + subs x7,x7,x11 + sbcs x8,x8,x12 + sbcs x9,x9,x13 + sbcs x10,x10,x14 + sbcs x15,x15,xzr + + csel x7,x7,x3,cs + csel x8,x8,x4,cs + csel x9,x9,x5,cs + csel x10,x10,x6,cs + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + + ret +.size ecp_sm2p256_mul_by_3,.-ecp_sm2p256_mul_by_3 + +// void ecp_sm2p256_add(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_add +.type ecp_sm2p256_add,%function +.align 5 +ecp_sm2p256_add: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Addition + adds x7,x7,x11 + adcs x8,x8,x12 + adcs x9,x9,x13 + adcs x10,x10,x14 + adc x15,xzr,xzr + + # Load polynomial + adr x2,.Lpoly + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Backup Addition + mov x3,x7 + mov x4,x8 + mov x5,x9 + mov x6,x10 + + # Sub polynomial + subs x3,x3,x11 + sbcs x4,x4,x12 + sbcs x5,x5,x13 + sbcs x6,x6,x14 + sbcs x15,x15,xzr + + # Select based on carry + csel x7,x7,x3,cc + csel x8,x8,x4,cc + csel x9,x9,x5,cc + csel x10,x10,x6,cc + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + ret +.size ecp_sm2p256_add,.-ecp_sm2p256_add + +// void ecp_sm2p256_sub(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_sub +.type ecp_sm2p256_sub,%function +.align 5 +ecp_sm2p256_sub: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Subtraction + subs x7,x7,x11 + sbcs x8,x8,x12 + sbcs x9,x9,x13 + sbcs x10,x10,x14 + sbc x15,xzr,xzr + + # Load polynomial + adr x2,.Lpoly + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Backup subtraction + mov x3,x7 + mov x4,x8 + mov x5,x9 + mov x6,x10 + + # Add polynomial + adds x3,x3,x11 + adcs x4,x4,x12 + adcs x5,x5,x13 + adcs x6,x6,x14 + tst x15,x15 + + # Select based on carry + csel x7,x7,x3,eq + csel x8,x8,x4,eq + csel x9,x9,x5,eq + csel x10,x10,x6,eq + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + ret +.size ecp_sm2p256_sub,.-ecp_sm2p256_sub + +// void ecp_sm2p256_sub_mod_ord(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_sub_mod_ord +.type ecp_sm2p256_sub_mod_ord,%function +.align 5 +ecp_sm2p256_sub_mod_ord: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Subtraction + subs x7,x7,x11 + sbcs x8,x8,x12 + sbcs x9,x9,x13 + sbcs x10,x10,x14 + sbc x15,xzr,xzr + + # Load polynomial + adr x2,.Lord + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + + # Backup subtraction + mov x3,x7 + mov x4,x8 + mov x5,x9 + mov x6,x10 + + # Add polynomial + adds x3,x3,x11 + adcs x4,x4,x12 + adcs x5,x5,x13 + adcs x6,x6,x14 + tst x15,x15 + + # Select based on carry + csel x7,x7,x3,eq + csel x8,x8,x4,eq + csel x9,x9,x5,eq + csel x10,x10,x6,eq + + # Store results + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + ret +.size ecp_sm2p256_sub_mod_ord,.-ecp_sm2p256_sub_mod_ord + +.macro RDC + # a = | s7 | ... | s0 |, where si are 64-bit quantities + # = |a15|a14| ... |a1|a0|, where ai are 32-bit quantities + # | s7 | s6 | s5 | s4 | + # | a15 | a14 | a13 | a12 | a11 | a10 | a9 | a8 | + # | s3 | s2 | s1 | s0 | + # | a7 | a6 | a5 | a4 | a3 | a2 | a1 | a0 | + # ================================================= + # | a8 | a11 | a10 | a9 | a8 | 0 | s4 | (+) + # | a9 | a15 | s6 | a11 | 0 | a10 | a9 | (+) + # | a10 | 0 | a14 | a13 | a12 | 0 | s5 | (+) + # | a11 | 0 | s7 | a13 | 0 | a12 | a11 | (+) + # | a12 | 0 | s7 | a13 | 0 | s6 | (+) + # | a12 | 0 | 0 | a15 | a14 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | a15 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | 0 | 0 | s7 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | s7 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | s7 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | 0 | 0 | 0 | 0 | 0 | a8 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a9 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a13 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a14 | 0 | 0 | (-) + # | U[7]| U[6]| U[5]| U[4]| U[3]| U[2]| U[1]| U[0]| + # | V[3] | V[2] | V[1] | V[0] | + + # 1. 64-bit addition + # t2=s6+s7+s7 + adds x5,x13,x14 + adcs x4,xzr,xzr + adds x5,x5,x14 + adcs x4,x4,xzr + # t3=s4+s5+t2 + adds x6,x11,x5 + adcs x15,x4,xzr + adds x6,x6,x12 + adcs x15,x15,xzr + # sum + adds x7,x7,x6 + adcs x8,x8,x15 + adcs x9,x9,x5 + adcs x10,x10,x14 + adcs x3,xzr,xzr + adds x10,x10,x4 + adcs x3,x3,xzr + + stp x7,x8,[sp,#32] + stp x9,x10,[sp,#48] + + # 2. 64-bit to 32-bit spread + mov x4,#0xffffffff + mov x7,x11 + mov x8,x12 + mov x9,x13 + mov x10,x14 + and x7,x7,x4 // a8 + and x8,x8,x4 // a10 + and x9,x9,x4 // a12 + and x10,x10,x4 // a14 + lsr x11,x11,#32 // a9 + lsr x12,x12,#32 // a11 + lsr x13,x13,#32 // a13 + lsr x14,x14,#32 // a15 + + # 3. 32-bit addition + add x4,x10,x9 // t1 <- a12 + a14 + add x5,x14,x13 // t2 <- a13 + a15 + add x6,x7,x11 // t3 <- a8 + a9 + add x15,x10,x8 // t4 <- a10 + a14 + add x14,x14,x12 // a15 <- a11 + a15 + add x9,x5,x4 // a12 <- a12 + a13 + a14 + a15 + add x8,x8,x9 // a10 <- a10 + a12 + a13 + a14 + a15 + add x8,x8,x9 // a10 <- a10 + 2*(a12 + a13 + a14 + a15) + add x8,x8,x6 // a10 <- a8 + a9 + a10 + 2*(a12 + a13 + a14 + a15) + add x8,x8,x12 // a10 <- a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + add x9,x9,x13 // a12 <- a12 + 2*a13 + a14 + a15 + add x9,x9,x12 // a12 <- a11 + a12 + 2*a13 + a14 + a15 + add x9,x9,x7 // a12 <- a8 + a11 + a12 + 2*a13 + a14 + a15 + add x6,x6,x10 // t3 <- a8 + a9 + a14 + add x6,x6,x13 // t3 <- a8 + a9 + a13 + a14 + add x11,x11,x5 // a9 <- a9 + a13 + a15 + add x12,x12,x11 // a11 <- a9 + a11 + a13 + a15 + add x12,x12,x5 // a11 <- a9 + a11 + 2*(a13 + a15) + add x4,x4,x15 // t1 <- a10 + a12 + 2*a14 + + # U[0] s5 a9 + a11 + 2*(a13 + a15) + # U[1] t1 a10 + a12 + 2*a14 + # U[2] -t3 a8 + a9 + a13 + a14 + # U[3] s2 a8 + a11 + a12 + 2*a13 + a14 + a15 + # U[4] s4 a9 + a13 + a15 + # U[5] t4 a10 + a14 + # U[6] s7 a11 + a15 + # U[7] s1 a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + + # 4. 32-bit to 64-bit + lsl x7,x4,#32 + extr x4,x9,x4,#32 + extr x9,x15,x9,#32 + extr x15,x8,x15,#32 + lsr x8,x8,#32 + + # 5. 64-bit addition + adds x12,x12,x7 + adcs x4,x4,xzr + adcs x11,x11,x9 + adcs x14,x14,x15 + adcs x3,x3,x8 + + # V[0] s5 + # V[1] t1 + # V[2] s4 + # V[3] s7 + # carry t0 + # sub t3 + + # 5. Process s0-s3 + ldp x7,x8,[sp,#32] + ldp x9,x10,[sp,#48] + # add with V0-V3 + adds x7,x7,x12 + adcs x8,x8,x4 + adcs x9,x9,x11 + adcs x10,x10,x14 + adcs x3,x3,xzr + # sub with t3 + subs x8,x8,x6 + sbcs x9,x9,xzr + sbcs x10,x10,xzr + sbcs x3,x3,xzr + + # 6. MOD + # First Mod + lsl x4,x3,#32 + subs x5,x4,x3 + + adds x7,x7,x3 + adcs x8,x8,x5 + adcs x9,x9,xzr + adcs x10,x10,x4 + + # Last Mod + # return y - p if y > p else y + mov x11,x7 + mov x12,x8 + mov x13,x9 + mov x14,x10 + + adr x3,.Lpoly + ldp x4,x5,[x3] + ldp x6,x15,[x3,#16] + + adcs x16,xzr,xzr + + subs x7,x7,x4 + sbcs x8,x8,x5 + sbcs x9,x9,x6 + sbcs x10,x10,x15 + sbcs x16,x16,xzr + + csel x7,x7,x11,cs + csel x8,x8,x12,cs + csel x9,x9,x13,cs + csel x10,x10,x14,cs + +.endm + +// void ecp_sm2p256_mul(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +.globl ecp_sm2p256_mul +.type ecp_sm2p256_mul,%function +.align 5 +ecp_sm2p256_mul: + AARCH64_SIGN_LINK_REGISTER + # Store scalar registers + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x16,x17,[sp,#16] + stp x18,x19,[sp,#64] + + # Load inputs + ldp x7,x8,[x1] + ldp x9,x10,[x1,#16] + ldp x11,x12,[x2] + ldp x13,x14,[x2,#16] + +### multiplication ### + # ======================== + # s3 s2 s1 s0 + # * s7 s6 s5 s4 + # ------------------------ + # + s0 s0 s0 s0 + # * * * * + # s7 s6 s5 s4 + # s1 s1 s1 s1 + # * * * * + # s7 s6 s5 s4 + # s2 s2 s2 s2 + # * * * * + # s7 s6 s5 s4 + # s3 s3 s3 s3 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s0*s4 ### + mul x16,x7,x11 + umulh x5,x7,x11 + +### s1*s4 + s0*s5 ### + mul x3,x8,x11 + umulh x4,x8,x11 + adds x5,x5,x3 + adcs x6,x4,xzr + + mul x3,x7,x12 + umulh x4,x7,x12 + adds x5,x5,x3 + adcs x6,x6,x4 + adcs x15,xzr,xzr + +### s2*s4 + s1*s5 + s0*s6 ### + mul x3,x9,x11 + umulh x4,x9,x11 + adds x6,x6,x3 + adcs x15,x15,x4 + + mul x3,x8,x12 + umulh x4,x8,x12 + adds x6,x6,x3 + adcs x15,x15,x4 + adcs x17,xzr,xzr + + mul x3,x7,x13 + umulh x4,x7,x13 + adds x6,x6,x3 + adcs x15,x15,x4 + adcs x17,x17,xzr + +### s3*s4 + s2*s5 + s1*s6 + s0*s7 ### + mul x3,x10,x11 + umulh x4,x10,x11 + adds x15,x15,x3 + adcs x17,x17,x4 + adcs x18,xzr,xzr + + mul x3,x9,x12 + umulh x4,x9,x12 + adds x15,x15,x3 + adcs x17,x17,x4 + adcs x18,x18,xzr + + mul x3,x8,x13 + umulh x4,x8,x13 + adds x15,x15,x3 + adcs x17,x17,x4 + adcs x18,x18,xzr + + mul x3,x7,x14 + umulh x4,x7,x14 + adds x15,x15,x3 + adcs x17,x17,x4 + adcs x18,x18,xzr + +### s3*s5 + s2*s6 + s1*s7 ### + mul x3,x10,x12 + umulh x4,x10,x12 + adds x17,x17,x3 + adcs x18,x18,x4 + adcs x19,xzr,xzr + + mul x3,x9,x13 + umulh x4,x9,x13 + adds x17,x17,x3 + adcs x18,x18,x4 + adcs x19,x19,xzr + + mul x3,x8,x14 + umulh x4,x8,x14 + adds x11,x17,x3 + adcs x18,x18,x4 + adcs x19,x19,xzr + +### s3*s6 + s2*s7 ### + mul x3,x10,x13 + umulh x4,x10,x13 + adds x18,x18,x3 + adcs x19,x19,x4 + adcs x17,xzr,xzr + + mul x3,x9,x14 + umulh x4,x9,x14 + adds x12,x18,x3 + adcs x19,x19,x4 + adcs x17,x17,xzr + +### s3*s7 ### + mul x3,x10,x14 + umulh x4,x10,x14 + adds x13,x19,x3 + adcs x14,x17,x4 + + mov x7,x16 + mov x8,x5 + mov x9,x6 + mov x10,x15 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + + # Restore scalar registers + ldp x16,x17,[sp,#16] + ldp x18,x19,[sp,#64] + ldp x29,x30,[sp],#80 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_sm2p256_mul,.-ecp_sm2p256_mul + +// void ecp_sm2p256_sqr(BN_ULONG *r, const BN_ULONG *a); +.globl ecp_sm2p256_sqr +.type ecp_sm2p256_sqr,%function +.align 5 + +ecp_sm2p256_sqr: + AARCH64_SIGN_LINK_REGISTER + # Store scalar registers + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x16,x17,[sp,#16] + stp x18,x19,[sp,#64] + + # Load inputs + ldp x11,x12,[x1] + ldp x13,x14,[x1,#16] + +### square ### + # ======================== + # s7 s6 s5 s4 + # * s7 s6 s5 s4 + # ------------------------ + # + s4 s4 s4 s4 + # * * * * + # s7 s6 s5 s4 + # s5 s5 s5 s5 + # * * * * + # s7 s6 s5 s4 + # s6 s6 s6 s6 + # * * * * + # s7 s6 s5 s4 + # s7 s7 s7 s7 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s4*s5 ### + mul x8,x11,x12 + umulh x9,x11,x12 + +### s4*s6 ### + mul x3,x13,x11 + umulh x10,x13,x11 + adds x9,x9,x3 + adcs x10,x10,xzr + +### s4*s7 + s5*s6 ### + mul x3,x14,x11 + umulh x4,x14,x11 + adds x10,x10,x3 + adcs x7,x4,xzr + + mul x3,x13,x12 + umulh x4,x13,x12 + adds x10,x10,x3 + adcs x7,x7,x4 + adcs x5,xzr,xzr + +### s5*s7 ### + mul x3,x14,x12 + umulh x4,x14,x12 + adds x7,x7,x3 + adcs x5,x5,x4 + +### s6*s7 ### + mul x3,x14,x13 + umulh x4,x14,x13 + adds x5,x5,x3 + adcs x6,x4,xzr + +### 2*(t3,t2,s0,s3,s2,s1) ### + adds x8,x8,x8 + adcs x9,x9,x9 + adcs x10,x10,x10 + adcs x7,x7,x7 + adcs x5,x5,x5 + adcs x6,x6,x6 + adcs x15,xzr,xzr + +### s4*s4 ### + mul x16,x11,x11 + umulh x17,x11,x11 + +### s5*s5 ### + mul x11,x12,x12 + umulh x12,x12,x12 + +### s6*s6 ### + mul x3,x13,x13 + umulh x4,x13,x13 + +### s7*s7 ### + mul x18,x14,x14 + umulh x19,x14,x14 + + adds x8,x8,x17 + adcs x9,x9,x11 + adcs x10,x10,x12 + adcs x7,x7,x3 + adcs x5,x5,x4 + adcs x6,x6,x18 + adcs x15,x15,x19 + + mov x11,x7 + mov x7,x16 + mov x12,x5 + mov x13,x6 + mov x14,x15 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + stp x7,x8,[x0] + stp x9,x10,[x0,#16] + + # Restore scalar registers + ldp x16,x17,[sp,#16] + ldp x18,x19,[sp,#64] + ldp x29,x30,[sp],#80 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_sm2p256_sqr,.-ecp_sm2p256_sqr diff --git a/crypto/ec/asm/ecp_sm2p256-armv8.pl b/crypto/ec/asm/ecp_sm2p256-armv8.pl new file mode 100644 index 0000000000..50950865e4 --- /dev/null +++ b/crypto/ec/asm/ecp_sm2p256-armv8.pl @@ -0,0 +1,823 @@ +#! /usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +my ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("x$_",(7..14)); +my ($a8,$a10,$a12,$a14,$a9,$a11,$a13,$a15)=map("x$_",(7..14)); +my ($t0,$t1,$t2,$t3)=map("x$_",(3..6)); +my ($t4,$t5,$t6,$t7,$t8)=map("x$_",(15..19)); + +sub bn_mod_add() { + my $mod = shift; +$code.=<<___; + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Addition + adds $s0,$s0,$s4 + adcs $s1,$s1,$s5 + adcs $s2,$s2,$s6 + adcs $s3,$s3,$s7 + adc $t4,xzr,xzr + + # Load polynomial + adr x2,$mod + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Backup Addition + mov $t0,$s0 + mov $t1,$s1 + mov $t2,$s2 + mov $t3,$s3 + + # Sub polynomial + subs $t0,$t0,$s4 + sbcs $t1,$t1,$s5 + sbcs $t2,$t2,$s6 + sbcs $t3,$t3,$s7 + sbcs $t4,$t4,xzr + + # Select based on carry + csel $s0,$s0,$t0,cc + csel $s1,$s1,$t1,cc + csel $s2,$s2,$t2,cc + csel $s3,$s3,$t3,cc + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] +___ +} + +sub bn_mod_sub() { + my $mod = shift; +$code.=<<___; + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Subtraction + subs $s0,$s0,$s4 + sbcs $s1,$s1,$s5 + sbcs $s2,$s2,$s6 + sbcs $s3,$s3,$s7 + sbc $t4,xzr,xzr + + # Load polynomial + adr x2,$mod + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Backup subtraction + mov $t0,$s0 + mov $t1,$s1 + mov $t2,$s2 + mov $t3,$s3 + + # Add polynomial + adds $t0,$t0,$s4 + adcs $t1,$t1,$s5 + adcs $t2,$t2,$s6 + adcs $t3,$t3,$s7 + tst $t4,$t4 + + # Select based on carry + csel $s0,$s0,$t0,eq + csel $s1,$s1,$t1,eq + csel $s2,$s2,$t2,eq + csel $s3,$s3,$t3,eq + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] +___ +} + +sub bn_mod_div_by_2() { + my $mod = shift; +$code.=<<___; + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + + # Save the least significant bit + mov $t0,$s0 + + # Right shift 1 + extr $s0,$s1,$s0,#1 + extr $s1,$s2,$s1,#1 + extr $s2,$s3,$s2,#1 + lsr $s3,$s3,#1 + + # Load mod + adr x2,$mod + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Parity check + tst $t0,#1 + csel $s4,xzr,$s4,eq + csel $s5,xzr,$s5,eq + csel $s6,xzr,$s6,eq + csel $s7,xzr,$s7,eq + + # Add + adds $s0,$s0,$s4 + adcs $s1,$s1,$s5 + adcs $s2,$s2,$s6 + adc $s3,$s3,$s7 + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] +___ +} + +{ +$code.=<<___; +#include "arm_arch.h" +.arch armv8-a +.text + +.align 5 +// The polynomial p +.Lpoly: +.quad 0xffffffffffffffff,0xffffffff00000000,0xffffffffffffffff,0xfffffffeffffffff +// The order of polynomial n +.Lord: +.quad 0x53bbf40939d54123,0x7203df6b21c6052b,0xffffffffffffffff,0xfffffffeffffffff +// (p + 1) / 2 +.Lpoly_div_2: +.quad 0x8000000000000000,0xffffffff80000000,0xffffffffffffffff,0x7fffffff7fffffff +// (n + 1) / 2 +.Lord_div_2: +.quad 0xa9ddfa049ceaa092,0xb901efb590e30295,0xffffffffffffffff,0x7fffffff7fffffff + +// void bn_rshift1(BN_ULONG *a); +.globl bn_rshift1 +.type bn_rshift1,%function +.align 5 +bn_rshift1: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp $s0,$s1,[x0] + ldp $s2,$s3,[x0,#16] + + # Right shift + extr $s0,$s1,$s0,#1 + extr $s1,$s2,$s1,#1 + extr $s2,$s3,$s2,#1 + lsr $s3,$s3,#1 + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] + + ret +.size bn_rshift1,.-bn_rshift1 + +// void bn_sub(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +.globl bn_sub +.type bn_sub,%function +.align 5 +bn_sub: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + + # Subtraction + subs $s0,$s0,$s4 + sbcs $s1,$s1,$s5 + sbcs $s2,$s2,$s6 + sbc $s3,$s3,$s7 + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] + + ret +.size bn_sub,.-bn_sub + +// void ecp_sm2p256_div_by_2(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_div_by_2 +.type ecp_sm2p256_div_by_2,%function +.align 5 +ecp_sm2p256_div_by_2: + AARCH64_VALID_CALL_TARGET +___ + &bn_mod_div_by_2(".Lpoly_div_2"); +$code.=<<___; + ret +.size ecp_sm2p256_div_by_2,.-ecp_sm2p256_div_by_2 + +// void ecp_sm2p256_div_by_2_mod_ord(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_div_by_2_mod_ord +.type ecp_sm2p256_div_by_2_mod_ord,%function +.align 5 +ecp_sm2p256_div_by_2_mod_ord: + AARCH64_VALID_CALL_TARGET +___ + &bn_mod_div_by_2(".Lord_div_2"); +$code.=<<___; + ret +.size ecp_sm2p256_div_by_2_mod_ord,.-ecp_sm2p256_div_by_2_mod_ord + +// void ecp_sm2p256_mul_by_3(BN_ULONG *r,const BN_ULONG *a); +.globl ecp_sm2p256_mul_by_3 +.type ecp_sm2p256_mul_by_3,%function +.align 5 +ecp_sm2p256_mul_by_3: + AARCH64_VALID_CALL_TARGET + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + + # 2*a + adds $s0,$s0,$s0 + adcs $s1,$s1,$s1 + adcs $s2,$s2,$s2 + adcs $s3,$s3,$s3 + adcs $t4,xzr,xzr + + mov $t0,$s0 + mov $t1,$s1 + mov $t2,$s2 + mov $t3,$s3 + + # Sub polynomial + adr x2,.Lpoly + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + subs $s0,$s0,$s4 + sbcs $s1,$s1,$s5 + sbcs $s2,$s2,$s6 + sbcs $s3,$s3,$s7 + sbcs $t4,$t4,xzr + + csel $s0,$s0,$t0,cs + csel $s1,$s1,$t1,cs + csel $s2,$s2,$t2,cs + csel $s3,$s3,$t3,cs + eor $t4,$t4,$t4 + + # 3*a + ldp $s4,$s5,[x1] + ldp $s6,$s7,[x1,#16] + adds $s0,$s0,$s4 + adcs $s1,$s1,$s5 + adcs $s2,$s2,$s6 + adcs $s3,$s3,$s7 + adcs $t4,xzr,xzr + + mov $t0,$s0 + mov $t1,$s1 + mov $t2,$s2 + mov $t3,$s3 + + # Sub polynomial + adr x2,.Lpoly + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + subs $s0,$s0,$s4 + sbcs $s1,$s1,$s5 + sbcs $s2,$s2,$s6 + sbcs $s3,$s3,$s7 + sbcs $t4,$t4,xzr + + csel $s0,$s0,$t0,cs + csel $s1,$s1,$t1,cs + csel $s2,$s2,$t2,cs + csel $s3,$s3,$t3,cs + + # Store results + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] + + ret +.size ecp_sm2p256_mul_by_3,.-ecp_sm2p256_mul_by_3 + +// void ecp_sm2p256_add(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_add +.type ecp_sm2p256_add,%function +.align 5 +ecp_sm2p256_add: + AARCH64_VALID_CALL_TARGET +___ + &bn_mod_add(".Lpoly"); +$code.=<<___; + ret +.size ecp_sm2p256_add,.-ecp_sm2p256_add + +// void ecp_sm2p256_sub(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_sub +.type ecp_sm2p256_sub,%function +.align 5 +ecp_sm2p256_sub: + AARCH64_VALID_CALL_TARGET +___ + &bn_mod_sub(".Lpoly"); +$code.=<<___; + ret +.size ecp_sm2p256_sub,.-ecp_sm2p256_sub + +// void ecp_sm2p256_sub_mod_ord(BN_ULONG *r,const BN_ULONG *a,const BN_ULONG *b); +.globl ecp_sm2p256_sub_mod_ord +.type ecp_sm2p256_sub_mod_ord,%function +.align 5 +ecp_sm2p256_sub_mod_ord: + AARCH64_VALID_CALL_TARGET +___ + &bn_mod_sub(".Lord"); +$code.=<<___; + ret +.size ecp_sm2p256_sub_mod_ord,.-ecp_sm2p256_sub_mod_ord + +.macro RDC + # a = | s7 | ... | s0 |, where si are 64-bit quantities + # = |a15|a14| ... |a1|a0|, where ai are 32-bit quantities + # | s7 | s6 | s5 | s4 | + # | a15 | a14 | a13 | a12 | a11 | a10 | a9 | a8 | + # | s3 | s2 | s1 | s0 | + # | a7 | a6 | a5 | a4 | a3 | a2 | a1 | a0 | + # ================================================= + # | a8 | a11 | a10 | a9 | a8 | 0 | s4 | (+) + # | a9 | a15 | s6 | a11 | 0 | a10 | a9 | (+) + # | a10 | 0 | a14 | a13 | a12 | 0 | s5 | (+) + # | a11 | 0 | s7 | a13 | 0 | a12 | a11 | (+) + # | a12 | 0 | s7 | a13 | 0 | s6 | (+) + # | a12 | 0 | 0 | a15 | a14 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | a15 | 0 | a14 | a13 | (+) + # | a13 | 0 | 0 | 0 | 0 | 0 | s7 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | s7 | (+) + # | a14 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | a15 | (+) + # | a15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | s7 | 0 | 0 | 0 | 0 | 0 | 0 | (+) + # | 0 | 0 | 0 | 0 | 0 | a8 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a9 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a13 | 0 | 0 | (-) + # | 0 | 0 | 0 | 0 | 0 | a14 | 0 | 0 | (-) + # | U[7]| U[6]| U[5]| U[4]| U[3]| U[2]| U[1]| U[0]| + # | V[3] | V[2] | V[1] | V[0] | + + # 1. 64-bit addition + # t2=s6+s7+s7 + adds $t2,$s6,$s7 + adcs $t1,xzr,xzr + adds $t2,$t2,$s7 + adcs $t1,$t1,xzr + # t3=s4+s5+t2 + adds $t3,$s4,$t2 + adcs $t4,$t1,xzr + adds $t3,$t3,$s5 + adcs $t4,$t4,xzr + # sum + adds $s0,$s0,$t3 + adcs $s1,$s1,$t4 + adcs $s2,$s2,$t2 + adcs $s3,$s3,$s7 + adcs $t0,xzr,xzr + adds $s3,$s3,$t1 + adcs $t0,$t0,xzr + + stp $s0,$s1,[sp,#32] + stp $s2,$s3,[sp,#48] + + # 2. 64-bit to 32-bit spread + mov $t1,#0xffffffff + mov $s0,$s4 + mov $s1,$s5 + mov $s2,$s6 + mov $s3,$s7 + and $s0,$s0,$t1 // a8 + and $s1,$s1,$t1 // a10 + and $s2,$s2,$t1 // a12 + and $s3,$s3,$t1 // a14 + lsr $s4,$s4,#32 // a9 + lsr $s5,$s5,#32 // a11 + lsr $s6,$s6,#32 // a13 + lsr $s7,$s7,#32 // a15 + + # 3. 32-bit addition + add $t1,$a14,$a12 // t1 <- a12 + a14 + add $t2,$a15,$a13 // t2 <- a13 + a15 + add $t3,$a8,$a9 // t3 <- a8 + a9 + add $t4,$a14,$a10 // t4 <- a10 + a14 + add $a15,$a15,$a11 // a15 <- a11 + a15 + add $a12,$t2,$t1 // a12 <- a12 + a13 + a14 + a15 + add $a10,$a10,$a12 // a10 <- a10 + a12 + a13 + a14 + a15 + add $a10,$a10,$a12 // a10 <- a10 + 2*(a12 + a13 + a14 + a15) + add $a10,$a10,$t3 // a10 <- a8 + a9 + a10 + 2*(a12 + a13 + a14 + a15) + add $a10,$a10,$a11 // a10 <- a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + add $a12,$a12,$a13 // a12 <- a12 + 2*a13 + a14 + a15 + add $a12,$a12,$a11 // a12 <- a11 + a12 + 2*a13 + a14 + a15 + add $a12,$a12,$a8 // a12 <- a8 + a11 + a12 + 2*a13 + a14 + a15 + add $t3,$t3,$a14 // t3 <- a8 + a9 + a14 + add $t3,$t3,$a13 // t3 <- a8 + a9 + a13 + a14 + add $a9,$a9,$t2 // a9 <- a9 + a13 + a15 + add $a11,$a11,$a9 // a11 <- a9 + a11 + a13 + a15 + add $a11,$a11,$t2 // a11 <- a9 + a11 + 2*(a13 + a15) + add $t1,$t1,$t4 // t1 <- a10 + a12 + 2*a14 + + # U[0] s5 a9 + a11 + 2*(a13 + a15) + # U[1] t1 a10 + a12 + 2*a14 + # U[2] -t3 a8 + a9 + a13 + a14 + # U[3] s2 a8 + a11 + a12 + 2*a13 + a14 + a15 + # U[4] s4 a9 + a13 + a15 + # U[5] t4 a10 + a14 + # U[6] s7 a11 + a15 + # U[7] s1 a8 + a9 + a10 + a11 + 2*(a12 + a13 + a14 + a15) + + # 4. 32-bit to 64-bit + lsl $s0,$t1,#32 + extr $t1,$s2,$t1,#32 + extr $s2,$t4,$s2,#32 + extr $t4,$s1,$t4,#32 + lsr $s1,$s1,#32 + + # 5. 64-bit addition + adds $s5,$s5,$s0 + adcs $t1,$t1,xzr + adcs $s4,$s4,$s2 + adcs $s7,$s7,$t4 + adcs $t0,$t0,$s1 + + # V[0] s5 + # V[1] t1 + # V[2] s4 + # V[3] s7 + # carry t0 + # sub t3 + + # 5. Process s0-s3 + ldp $s0,$s1,[sp,#32] + ldp $s2,$s3,[sp,#48] + # add with V0-V3 + adds $s0,$s0,$s5 + adcs $s1,$s1,$t1 + adcs $s2,$s2,$s4 + adcs $s3,$s3,$s7 + adcs $t0,$t0,xzr + # sub with t3 + subs $s1,$s1,$t3 + sbcs $s2,$s2,xzr + sbcs $s3,$s3,xzr + sbcs $t0,$t0,xzr + + # 6. MOD + # First Mod + lsl $t1,$t0,#32 + subs $t2,$t1,$t0 + + adds $s0,$s0,$t0 + adcs $s1,$s1,$t2 + adcs $s2,$s2,xzr + adcs $s3,$s3,$t1 + + # Last Mod + # return y - p if y > p else y + mov $s4,$s0 + mov $s5,$s1 + mov $s6,$s2 + mov $s7,$s3 + + adr $t0,.Lpoly + ldp $t1,$t2,[$t0] + ldp $t3,$t4,[$t0,#16] + + adcs $t5,xzr,xzr + + subs $s0,$s0,$t1 + sbcs $s1,$s1,$t2 + sbcs $s2,$s2,$t3 + sbcs $s3,$s3,$t4 + sbcs $t5,$t5,xzr + + csel $s0,$s0,$s4,cs + csel $s1,$s1,$s5,cs + csel $s2,$s2,$s6,cs + csel $s3,$s3,$s7,cs + +.endm + +// void ecp_sm2p256_mul(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +.globl ecp_sm2p256_mul +.type ecp_sm2p256_mul,%function +.align 5 +ecp_sm2p256_mul: + AARCH64_SIGN_LINK_REGISTER + # Store scalar registers + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x16,x17,[sp,#16] + stp x18,x19,[sp,#64] + + # Load inputs + ldp $s0,$s1,[x1] + ldp $s2,$s3,[x1,#16] + ldp $s4,$s5,[x2] + ldp $s6,$s7,[x2,#16] + +### multiplication ### + # ======================== + # s3 s2 s1 s0 + # * s7 s6 s5 s4 + # ------------------------ + # + s0 s0 s0 s0 + # * * * * + # s7 s6 s5 s4 + # s1 s1 s1 s1 + # * * * * + # s7 s6 s5 s4 + # s2 s2 s2 s2 + # * * * * + # s7 s6 s5 s4 + # s3 s3 s3 s3 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s0*s4 ### + mul $t5,$s0,$s4 + umulh $t2,$s0,$s4 + +### s1*s4 + s0*s5 ### + mul $t0,$s1,$s4 + umulh $t1,$s1,$s4 + adds $t2,$t2,$t0 + adcs $t3,$t1,xzr + + mul $t0,$s0,$s5 + umulh $t1,$s0,$s5 + adds $t2,$t2,$t0 + adcs $t3,$t3,$t1 + adcs $t4,xzr,xzr + +### s2*s4 + s1*s5 + s0*s6 ### + mul $t0,$s2,$s4 + umulh $t1,$s2,$s4 + adds $t3,$t3,$t0 + adcs $t4,$t4,$t1 + + mul $t0,$s1,$s5 + umulh $t1,$s1,$s5 + adds $t3,$t3,$t0 + adcs $t4,$t4,$t1 + adcs $t6,xzr,xzr + + mul $t0,$s0,$s6 + umulh $t1,$s0,$s6 + adds $t3,$t3,$t0 + adcs $t4,$t4,$t1 + adcs $t6,$t6,xzr + +### s3*s4 + s2*s5 + s1*s6 + s0*s7 ### + mul $t0,$s3,$s4 + umulh $t1,$s3,$s4 + adds $t4,$t4,$t0 + adcs $t6,$t6,$t1 + adcs $t7,xzr,xzr + + mul $t0,$s2,$s5 + umulh $t1,$s2,$s5 + adds $t4,$t4,$t0 + adcs $t6,$t6,$t1 + adcs $t7,$t7,xzr + + mul $t0,$s1,$s6 + umulh $t1,$s1,$s6 + adds $t4,$t4,$t0 + adcs $t6,$t6,$t1 + adcs $t7,$t7,xzr + + mul $t0,$s0,$s7 + umulh $t1,$s0,$s7 + adds $t4,$t4,$t0 + adcs $t6,$t6,$t1 + adcs $t7,$t7,xzr + +### s3*s5 + s2*s6 + s1*s7 ### + mul $t0,$s3,$s5 + umulh $t1,$s3,$s5 + adds $t6,$t6,$t0 + adcs $t7,$t7,$t1 + adcs $t8,xzr,xzr + + mul $t0,$s2,$s6 + umulh $t1,$s2,$s6 + adds $t6,$t6,$t0 + adcs $t7,$t7,$t1 + adcs $t8,$t8,xzr + + mul $t0,$s1,$s7 + umulh $t1,$s1,$s7 + adds $s4,$t6,$t0 + adcs $t7,$t7,$t1 + adcs $t8,$t8,xzr + +### s3*s6 + s2*s7 ### + mul $t0,$s3,$s6 + umulh $t1,$s3,$s6 + adds $t7,$t7,$t0 + adcs $t8,$t8,$t1 + adcs $t6,xzr,xzr + + mul $t0,$s2,$s7 + umulh $t1,$s2,$s7 + adds $s5,$t7,$t0 + adcs $t8,$t8,$t1 + adcs $t6,$t6,xzr + +### s3*s7 ### + mul $t0,$s3,$s7 + umulh $t1,$s3,$s7 + adds $s6,$t8,$t0 + adcs $s7,$t6,$t1 + + mov $s0,$t5 + mov $s1,$t2 + mov $s2,$t3 + mov $s3,$t4 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] + + # Restore scalar registers + ldp x16,x17,[sp,#16] + ldp x18,x19,[sp,#64] + ldp x29,x30,[sp],#80 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_sm2p256_mul,.-ecp_sm2p256_mul + +// void ecp_sm2p256_sqr(BN_ULONG *r, const BN_ULONG *a); +.globl ecp_sm2p256_sqr +.type ecp_sm2p256_sqr,%function +.align 5 + +ecp_sm2p256_sqr: + AARCH64_SIGN_LINK_REGISTER + # Store scalar registers + stp x29,x30,[sp,#-80]! + add x29,sp,#0 + stp x16,x17,[sp,#16] + stp x18,x19,[sp,#64] + + # Load inputs + ldp $s4,$s5,[x1] + ldp $s6,$s7,[x1,#16] + +### square ### + # ======================== + # s7 s6 s5 s4 + # * s7 s6 s5 s4 + # ------------------------ + # + s4 s4 s4 s4 + # * * * * + # s7 s6 s5 s4 + # s5 s5 s5 s5 + # * * * * + # s7 s6 s5 s4 + # s6 s6 s6 s6 + # * * * * + # s7 s6 s5 s4 + # s7 s7 s7 s7 + # * * * * + # s7 s6 s5 s4 + # ------------------------ + # s7 s6 s5 s4 s3 s2 s1 s0 + # ======================== + +### s4*s5 ### + mul $s1,$s4,$s5 + umulh $s2,$s4,$s5 + +### s4*s6 ### + mul $t0,$s6,$s4 + umulh $s3,$s6,$s4 + adds $s2,$s2,$t0 + adcs $s3,$s3,xzr + +### s4*s7 + s5*s6 ### + mul $t0,$s7,$s4 + umulh $t1,$s7,$s4 + adds $s3,$s3,$t0 + adcs $s0,$t1,xzr + + mul $t0,$s6,$s5 + umulh $t1,$s6,$s5 + adds $s3,$s3,$t0 + adcs $s0,$s0,$t1 + adcs $t2,xzr,xzr + +### s5*s7 ### + mul $t0,$s7,$s5 + umulh $t1,$s7,$s5 + adds $s0,$s0,$t0 + adcs $t2,$t2,$t1 + +### s6*s7 ### + mul $t0,$s7,$s6 + umulh $t1,$s7,$s6 + adds $t2,$t2,$t0 + adcs $t3,$t1,xzr + +### 2*(t3,t2,s0,s3,s2,s1) ### + adds $s1,$s1,$s1 + adcs $s2,$s2,$s2 + adcs $s3,$s3,$s3 + adcs $s0,$s0,$s0 + adcs $t2,$t2,$t2 + adcs $t3,$t3,$t3 + adcs $t4,xzr,xzr + +### s4*s4 ### + mul $t5,$s4,$s4 + umulh $t6,$s4,$s4 + +### s5*s5 ### + mul $s4,$s5,$s5 + umulh $s5,$s5,$s5 + +### s6*s6 ### + mul $t0,$s6,$s6 + umulh $t1,$s6,$s6 + +### s7*s7 ### + mul $t7,$s7,$s7 + umulh $t8,$s7,$s7 + + adds $s1,$s1,$t6 + adcs $s2,$s2,$s4 + adcs $s3,$s3,$s5 + adcs $s0,$s0,$t0 + adcs $t2,$t2,$t1 + adcs $t3,$t3,$t7 + adcs $t4,$t4,$t8 + + mov $s4,$s0 + mov $s0,$t5 + mov $s5,$t2 + mov $s6,$t3 + mov $s7,$t4 + + # result of mul: s7 s6 s5 s4 s3 s2 s1 s0 + +### Reduction ### + RDC + + stp $s0,$s1,[x0] + stp $s2,$s3,[x0,#16] + + # Restore scalar registers + ldp x16,x17,[sp,#16] + ldp x18,x19,[sp,#64] + ldp x29,x30,[sp],#80 + + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ecp_sm2p256_sqr,.-ecp_sm2p256_sqr +___ +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + print $_,"\n"; +} +close STDOUT or die "error closing STDOUT: $!"; # enforce flush diff --git a/crypto/ec/build.info b/crypto/ec/build.info index a511e887a9..2f376a39c6 100644 --- a/crypto/ec/build.info +++ b/crypto/ec/build.info @@ -3,9 +3,12 @@ IF[{- !$disabled{asm} -}] $ECASM_x86=ecp_nistz256.c ecp_nistz256-x86.S $ECDEF_x86=ECP_NISTZ256_ASM - $ECASM_x86_64=ecp_nistz256.c ecp_nistz256-x86_64.s x25519-x86_64.s - $ECDEF_x86_64=ECP_NISTZ256_ASM X25519_ASM - + $ECASM_x86_64=ecp_nistz256.c ecp_nistz256-x86_64.s + $ECDEF_x86_64=ECP_NISTZ256_ASM + IF[{- !$disabled{'ecx'} -}] + $ECASM_x86_64=$ECASM_x86_64 x25519-x86_64.s + $ECDEF_x86_64=$ECDEF_x86_64 X25519_ASM + ENDIF $ECASM_ia64= $ECASM_sparcv9=ecp_nistz256.c ecp_nistz256-sparcv9.S @@ -18,25 +21,41 @@ IF[{- !$disabled{asm} -}] $ECASM_mips32= $ECASM_mips64= - $ECASM_s390x=ecp_s390x_nistp.c ecx_s390x.c + $ECASM_s390x=ecp_s390x_nistp.c + IF[{- !$disabled{'ecx'} -}] + $ECASM_s390x=$ECASM_s390x ecx_s390x.c + ENDIF $ECDEF_s390x=S390X_EC_ASM $ECASM_armv4=ecp_nistz256.c ecp_nistz256-armv4.S $ECDEF_armv4=ECP_NISTZ256_ASM $ECASM_aarch64=ecp_nistz256.c ecp_nistz256-armv8.S $ECDEF_aarch64=ECP_NISTZ256_ASM + IF[{- !$disabled{'sm2'} -}] + $ECASM_aarch64=$ECASM_aarch64 ecp_sm2p256.c ecp_sm2p256-armv8.S + IF[{- !$disabled{'sm2-precomp'} -}] + $ECASM_aarch64=$ECASM_aarch64 ecp_sm2p256_table.c + ENDIF + $ECDEF_aarch64=$ECDEF_aarch64 ECP_SM2P256_ASM + ENDIF $ECASM_parisc11= $ECASM_parisc20_64= $ECASM_ppc32= - $ECASM_ppc64=ecp_nistz256.c ecp_ppc.c ecp_nistz256-ppc64.s x25519-ppc64.s - $ECDEF_ppc64=ECP_NISTZ256_ASM X25519_ASM + $ECASM_ppc64=ecp_nistz256.c ecp_ppc.c ecp_nistz256-ppc64.s + $ECDEF_ppc64=ECP_NISTZ256_ASM IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}] - $ECASM_ppc64=$ECASM_ppc64 ecp_nistp521-ppc64.s - $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP521_ASM + $ECASM_ppc64=$ECASM_ppc64 ecp_nistp384-ppc64.s ecp_nistp521-ppc64.s + $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP384_ASM ECP_NISTP521_ASM + INCLUDE[ecp_nistp384.o]=.. INCLUDE[ecp_nistp521.o]=.. ENDIF + IF[{- !$disabled{'ecx'} -}] + $ECASM_ppc64=$ECASM_ppc64 x25519-ppc64.s + $ECDEF_ppc64=$ECDEF_ppc64 X25519_ASM + INCLUDE[ecx_s390x.o]=.. + ENDIF $ECASM_c64xplus= @@ -49,22 +68,29 @@ IF[{- !$disabled{asm} -}] ENDIF $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ - ec_curve.c ec_check.c ec_key.c ec_kmeth.c ecx_key.c ec_asn1.c \ + ec_curve.c ec_check.c ec_key.c ec_kmeth.c ec_asn1.c \ ec2_smpl.c \ ecp_oct.c ec2_oct.c ec_oct.c ecdh_ossl.c \ - ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \ - curve448/f_generic.c curve448/scalar.c \ - curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ - $ECASM ec_backend.c ecx_backend.c ecdh_kdf.c curve448/arch_64/f_impl64.c \ - curve448/arch_32/f_impl32.c + ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c \ + $ECASM ec_backend.c ecdh_kdf.c + +IF[{- !$disabled{'ecx'} -}] + $COMMON=$COMMON curve25519.c curve448/f_generic.c curve448/scalar.c \ + curve448/arch_64/f_impl64.c ecx_backend.c curve448/arch_32/f_impl32.c \ + curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ + ecx_key.c +ENDIF IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}] - $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c + $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp384.c ecp_nistp521.c ecp_nistputil.c ENDIF -SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c \ +SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c \ ec_err.c eck_prn.c \ ec_deprecated.c ec_print.c +IF[{- !$disabled{'ecx'} -}] + SOURCE[../../libcrypto]=ecx_meth.c +ENDIF SOURCE[../../providers/libfips.a]=$COMMON # Implementations are now spread across several libraries, so the defines @@ -90,8 +116,10 @@ GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl INCLUDE[ecp_nistz256-sparcv9.o]=.. INCLUDE[ecp_s390x_nistp.o]=.. -INCLUDE[ecx_s390x.o]=.. -INCLUDE[ecx_meth.o]=.. +IF[{- !$disabled{'ecx'} -}] + INCLUDE[ecx_meth.o]=.. + INCLUDE[ecx_key.o]=.. +ENDIF GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl INCLUDE[ecp_nistz256-armv4.o]=.. @@ -99,7 +127,15 @@ GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl INCLUDE[ecp_nistz256-armv8.o]=.. GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl +GENERATE[ecp_nistp384-ppc64.s]=asm/ecp_nistp384-ppc64.pl GENERATE[ecp_nistp521-ppc64.s]=asm/ecp_nistp521-ppc64.pl +IF[{- !$disabled{'ecx'} -}] GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.pl +ENDIF + +IF[{- !$disabled{'sm2'} -}] + GENERATE[ecp_sm2p256-armv8.S]=asm/ecp_sm2p256-armv8.pl + INCLUDE[ecp_sm2p256-armv8.o]=.. +ENDIF diff --git a/crypto/ec/curve25519.c b/crypto/ec/curve25519.c index 286d6bff80..cae2ac101d 100644 --- a/crypto/ec/curve25519.c +++ b/crypto/ec/curve25519.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -5434,9 +5434,47 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, s[31] = (uint8_t) (s11 >> 17); } +static int hash_init_with_dom(EVP_MD_CTX *hash_ctx, + EVP_MD *sha512, + const uint8_t dom2flag, + const uint8_t phflag, + const uint8_t *context, + const size_t context_len) +{ + /* ASCII: "SigEd25519 no Ed25519 collisions", in hex for EBCDIC compatibility */ + const char dom_s[] = + "\x53\x69\x67\x45\x64\x32\x35\x35\x31\x39\x20\x6e" + "\x6f\x20\x45\x64\x32\x35\x35\x31\x39\x20\x63\x6f" + "\x6c\x6c\x69\x73\x69\x6f\x6e\x73"; + uint8_t dom[2]; + + if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL)) + return 0; + + /* return early if dom2flag is not set */ + if (!dom2flag) + return 1; + + if (context_len > UINT8_MAX) + return 0; + + dom[0] = (uint8_t)(phflag >= 1 ? 1 : 0); + dom[1] = (uint8_t)context_len; + + if (!EVP_DigestUpdate(hash_ctx, dom_s, sizeof(dom_s)-1) + || !EVP_DigestUpdate(hash_ctx, dom, sizeof(dom)) + || !EVP_DigestUpdate(hash_ctx, context, context_len)) { + return 0; + } + + return 1; +} + int -ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, +ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *tbs, size_t tbs_len, const uint8_t public_key[32], const uint8_t private_key[32], + const uint8_t dom2flag, const uint8_t phflag, const uint8_t csflag, + const uint8_t *context, size_t context_len, OSSL_LIB_CTX *libctx, const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; @@ -5448,6 +5486,17 @@ ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, unsigned int sz; int res = 0; + if (context == NULL) + context_len = 0; + + /* if csflag is set, then a non-empty context-string is required */ + if (csflag && context_len == 0) + goto err; + + /* if dom2flag is not set, then an empty context-string is required */ + if (!dom2flag && context_len > 0) + goto err; + if (sha512 == NULL || hash_ctx == NULL) goto err; @@ -5460,9 +5509,9 @@ ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, az[31] &= 63; az[31] |= 64; - if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + if (!hash_init_with_dom(hash_ctx, sha512, dom2flag, phflag, context, context_len) || !EVP_DigestUpdate(hash_ctx, az + 32, 32) - || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestUpdate(hash_ctx, tbs, tbs_len) || !EVP_DigestFinal_ex(hash_ctx, nonce, &sz)) goto err; @@ -5470,10 +5519,10 @@ ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, ge_scalarmult_base(&R, nonce); ge_p3_tobytes(out_sig, &R); - if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + if (!hash_init_with_dom(hash_ctx, sha512, dom2flag, phflag, context, context_len) || !EVP_DigestUpdate(hash_ctx, out_sig, 32) || !EVP_DigestUpdate(hash_ctx, public_key, 32) - || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestUpdate(hash_ctx, tbs, tbs_len) || !EVP_DigestFinal_ex(hash_ctx, hram, &sz)) goto err; @@ -5492,8 +5541,10 @@ ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, static const char allzeroes[15]; int -ossl_ed25519_verify(const uint8_t *message, size_t message_len, +ossl_ed25519_verify(const uint8_t *tbs, size_t tbs_len, const uint8_t signature[64], const uint8_t public_key[32], + const uint8_t dom2flag, const uint8_t phflag, const uint8_t csflag, + const uint8_t *context, size_t context_len, OSSL_LIB_CTX *libctx, const char *propq) { int i; @@ -5512,6 +5563,17 @@ ossl_ed25519_verify(const uint8_t *message, size_t message_len, 0xDE, 0xF9, 0xDE, 0x14 }; + if (context == NULL) + context_len = 0; + + /* if csflag is set, then a non-empty context-string is required */ + if (csflag && context_len == 0) + return 0; + + /* if dom2flag is not set, then an empty context-string is required */ + if (!dom2flag && context_len > 0) + return 0; + r = signature; s = signature + 32; @@ -5556,10 +5618,10 @@ ossl_ed25519_verify(const uint8_t *message, size_t message_len, if (hash_ctx == NULL) goto err; - if (!EVP_DigestInit_ex(hash_ctx, sha512, NULL) + if (!hash_init_with_dom(hash_ctx, sha512, dom2flag, phflag, context, context_len) || !EVP_DigestUpdate(hash_ctx, r, 32) || !EVP_DigestUpdate(hash_ctx, public_key, 32) - || !EVP_DigestUpdate(hash_ctx, message, message_len) + || !EVP_DigestUpdate(hash_ctx, tbs, tbs_len) || !EVP_DigestFinal_ex(hash_ctx, h, &sz)) goto err; @@ -5570,6 +5632,14 @@ ossl_ed25519_verify(const uint8_t *message, size_t message_len, ge_tobytes(rcheck, &R); res = CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0; + + /* note that we have used the strict verification equation here. + * we checked that ENC( [h](-A) + [s]B ) == r + * B is the base point. + * + * the less strict verification equation uses the curve cofactor: + * [h*8](-A) + [s*8]B == [8]R + */ err: EVP_MD_free(sha512); EVP_MD_CTX_free(hash_ctx); diff --git a/crypto/ec/curve448/arch_32/f_impl32.c b/crypto/ec/curve448/arch_32/f_impl32.c index 14f7b786f4..140c73c64f 100644 --- a/crypto/ec/curve448/arch_32/f_impl32.c +++ b/crypto/ec/curve448/arch_32/f_impl32.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -21,7 +21,7 @@ NON_EMPTY_TRANSLATION_UNIT # include "../field.h" -void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) +void ossl_gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) { const uint32_t *a = as->limb, *b = bs->limb; uint32_t *c = cs->limb; @@ -70,7 +70,7 @@ void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) c[1] += ((uint32_t)(accum1)); } -void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) +void ossl_gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) { const uint32_t *a = as->limb; uint32_t *c = cs->limb; @@ -98,8 +98,8 @@ void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) c[1] += (uint32_t)(accum8 >> 28); } -void gf_sqr(gf_s * RESTRICT cs, const gf as) +void ossl_gf_sqr(gf_s * RESTRICT cs, const gf as) { - gf_mul(cs, as, as); /* Performs better with a dedicated square */ + ossl_gf_mul(cs, as, as); /* Performs better with a dedicated square */ } #endif diff --git a/crypto/ec/curve448/arch_64/f_impl64.c b/crypto/ec/curve448/arch_64/f_impl64.c index 10a9b065e5..c944005da5 100644 --- a/crypto/ec/curve448/arch_64/f_impl64.c +++ b/crypto/ec/curve448/arch_64/f_impl64.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -21,7 +21,7 @@ NON_EMPTY_TRANSLATION_UNIT # include "../field.h" -void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) +void ossl_gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) { const uint64_t *a = as->limb, *b = bs->limb; uint64_t *c = cs->limb; @@ -73,7 +73,7 @@ void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs) c[1] += ((uint64_t)(accum1)); } -void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) +void ossl_gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) { const uint64_t *a = as->limb; uint64_t *c = cs->limb; @@ -99,7 +99,7 @@ void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b) c[1] += accum4 >> 56; } -void gf_sqr(gf_s * RESTRICT cs, const gf as) +void ossl_gf_sqr(gf_s * RESTRICT cs, const gf as) { const uint64_t *a = as->limb; uint64_t *c = cs->limb; diff --git a/crypto/ec/curve448/curve448.c b/crypto/ec/curve448/curve448.c index 6928d9693c..2422d068a0 100644 --- a/crypto/ec/curve448/curve448.c +++ b/crypto/ec/curve448/curve448.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -44,13 +44,13 @@ static void gf_invert(gf y, const gf x, int assert_nonzero) mask_t ret; gf t1, t2; - gf_sqr(t1, x); /* o^2 */ + ossl_gf_sqr(t1, x); /* o^2 */ ret = gf_isr(t2, t1); /* +-1/sqrt(o^2) = +-1/o */ (void)ret; if (assert_nonzero) assert(ret); - gf_sqr(t1, t2); - gf_mul(t2, t1, x); /* not direct to y in case of alias. */ + ossl_gf_sqr(t1, t2); + ossl_gf_mul(t2, t1, x); /* not direct to y in case of alias. */ gf_copy(y, t2); } @@ -63,23 +63,23 @@ static void point_double_internal(curve448_point_t p, const curve448_point_t q, { gf a, b, c, d; - gf_sqr(c, q->x); - gf_sqr(a, q->y); + ossl_gf_sqr(c, q->x); + ossl_gf_sqr(a, q->y); gf_add_nr(d, c, a); /* 2+e */ gf_add_nr(p->t, q->y, q->x); /* 2+e */ - gf_sqr(b, p->t); + ossl_gf_sqr(b, p->t); gf_subx_nr(b, b, d, 3); /* 4+e */ gf_sub_nr(p->t, a, c); /* 3+e */ - gf_sqr(p->x, q->z); + ossl_gf_sqr(p->x, q->z); gf_add_nr(p->z, p->x, p->x); /* 2+e */ gf_subx_nr(a, p->z, p->t, 4); /* 6+e */ if (GF_HEADROOM == 5) gf_weak_reduce(a); /* or 1+e */ - gf_mul(p->x, a, b); - gf_mul(p->z, p->t, a); - gf_mul(p->y, p->t, d); + ossl_gf_mul(p->x, a, b); + ossl_gf_mul(p->z, p->t, a); + ossl_gf_mul(p->y, p->t, d); if (!before_double) - gf_mul(p->t, b, d); + ossl_gf_mul(p->t, b, d); } void ossl_curve448_point_double(curve448_point_t p, const curve448_point_t q) @@ -108,17 +108,17 @@ static void pniels_to_pt(curve448_point_t e, const pniels_t d) gf_add(eu, d->n->b, d->n->a); gf_sub(e->y, d->n->b, d->n->a); - gf_mul(e->t, e->y, eu); - gf_mul(e->x, d->z, e->y); - gf_mul(e->y, d->z, eu); - gf_sqr(e->z, d->z); + ossl_gf_mul(e->t, e->y, eu); + ossl_gf_mul(e->x, d->z, e->y); + ossl_gf_mul(e->y, d->z, eu); + ossl_gf_sqr(e->z, d->z); } static void niels_to_pt(curve448_point_t e, const niels_t n) { gf_add(e->y, n->b, n->a); gf_sub(e->x, n->b, n->a); - gf_mul(e->t, e->y, e->x); + ossl_gf_mul(e->t, e->y, e->x); gf_copy(e->z, ONE); } @@ -128,19 +128,19 @@ static void add_niels_to_pt(curve448_point_t d, const niels_t e, gf a, b, c; gf_sub_nr(b, d->y, d->x); /* 3+e */ - gf_mul(a, e->a, b); + ossl_gf_mul(a, e->a, b); gf_add_nr(b, d->x, d->y); /* 2+e */ - gf_mul(d->y, e->b, b); - gf_mul(d->x, e->c, d->t); + ossl_gf_mul(d->y, e->b, b); + ossl_gf_mul(d->x, e->c, d->t); gf_add_nr(c, a, d->y); /* 2+e */ gf_sub_nr(b, d->y, a); /* 3+e */ gf_sub_nr(d->y, d->z, d->x); /* 3+e */ gf_add_nr(a, d->x, d->z); /* 2+e */ - gf_mul(d->z, a, d->y); - gf_mul(d->x, d->y, b); - gf_mul(d->y, a, c); + ossl_gf_mul(d->z, a, d->y); + ossl_gf_mul(d->x, d->y, b); + ossl_gf_mul(d->y, a, c); if (!before_double) - gf_mul(d->t, b, c); + ossl_gf_mul(d->t, b, c); } static void sub_niels_from_pt(curve448_point_t d, const niels_t e, @@ -149,19 +149,19 @@ static void sub_niels_from_pt(curve448_point_t d, const niels_t e, gf a, b, c; gf_sub_nr(b, d->y, d->x); /* 3+e */ - gf_mul(a, e->b, b); + ossl_gf_mul(a, e->b, b); gf_add_nr(b, d->x, d->y); /* 2+e */ - gf_mul(d->y, e->a, b); - gf_mul(d->x, e->c, d->t); + ossl_gf_mul(d->y, e->a, b); + ossl_gf_mul(d->x, e->c, d->t); gf_add_nr(c, a, d->y); /* 2+e */ gf_sub_nr(b, d->y, a); /* 3+e */ gf_add_nr(d->y, d->z, d->x); /* 2+e */ gf_sub_nr(a, d->z, d->x); /* 3+e */ - gf_mul(d->z, a, d->y); - gf_mul(d->x, d->y, b); - gf_mul(d->y, a, c); + ossl_gf_mul(d->z, a, d->y); + ossl_gf_mul(d->x, d->y, b); + ossl_gf_mul(d->y, a, c); if (!before_double) - gf_mul(d->t, b, c); + ossl_gf_mul(d->t, b, c); } static void add_pniels_to_pt(curve448_point_t p, const pniels_t pn, @@ -169,7 +169,7 @@ static void add_pniels_to_pt(curve448_point_t p, const pniels_t pn, { gf L0; - gf_mul(L0, p->z, pn->z); + ossl_gf_mul(L0, p->z, pn->z); gf_copy(p->z, L0); add_niels_to_pt(p, pn->n, before_double); } @@ -179,7 +179,7 @@ static void sub_pniels_from_pt(curve448_point_t p, const pniels_t pn, { gf L0; - gf_mul(L0, p->z, pn->z); + ossl_gf_mul(L0, p->z, pn->z); gf_copy(p->z, L0); sub_niels_from_pt(p, pn->n, before_double); } @@ -192,8 +192,8 @@ ossl_curve448_point_eq(const curve448_point_t p, gf a, b; /* equality mod 2-torsion compares x/y */ - gf_mul(a, p->y, q->x); - gf_mul(b, q->y, p->x); + ossl_gf_mul(a, p->y, q->x); + ossl_gf_mul(b, q->y, p->x); succ = gf_eq(a, b); return mask_to_bool(succ); @@ -205,15 +205,15 @@ ossl_curve448_point_valid(const curve448_point_t p) mask_t out; gf a, b, c; - gf_mul(a, p->x, p->y); - gf_mul(b, p->z, p->t); + ossl_gf_mul(a, p->x, p->y); + ossl_gf_mul(b, p->z, p->t); out = gf_eq(a, b); - gf_sqr(a, p->x); - gf_sqr(b, p->y); + ossl_gf_sqr(a, p->x); + ossl_gf_sqr(b, p->y); gf_sub(a, b, a); - gf_sqr(b, p->t); + ossl_gf_sqr(b, p->t); gf_mulw(c, b, TWISTED_D); - gf_sqr(b, p->z); + ossl_gf_sqr(b, p->z); gf_add(b, b, c); out &= gf_eq(a, b); out &= ~gf_eq(p->z, ZERO); @@ -221,7 +221,7 @@ ossl_curve448_point_valid(const curve448_point_t p) } static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni, - const niels_t * table, + const niels_t *table, int nelts, int idx) { constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx); @@ -229,7 +229,7 @@ static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni, void ossl_curve448_precomputed_scalarmul(curve448_point_t out, - const curve448_precomputed_s * table, + const curve448_precomputed_s *table, const curve448_scalar_t scalar) { unsigned int i, j, k; @@ -290,26 +290,26 @@ ossl_curve448_point_mul_by_ratio_and_encode_like_eddsa( /* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */ gf u; - gf_sqr(x, q->x); - gf_sqr(t, q->y); + ossl_gf_sqr(x, q->x); + ossl_gf_sqr(t, q->y); gf_add(u, x, t); gf_add(z, q->y, q->x); - gf_sqr(y, z); + ossl_gf_sqr(y, z); gf_sub(y, y, u); gf_sub(z, t, x); - gf_sqr(x, q->z); + ossl_gf_sqr(x, q->z); gf_add(t, x, x); gf_sub(t, t, z); - gf_mul(x, t, y); - gf_mul(y, z, u); - gf_mul(z, u, t); + ossl_gf_mul(x, t, y); + ossl_gf_mul(y, z, u); + ossl_gf_mul(z, u, t); OPENSSL_cleanse(u, sizeof(u)); } /* Affinize */ gf_invert(z, z, 1); - gf_mul(t, x, z); - gf_mul(x, y, z); + ossl_gf_mul(t, x, z); + ossl_gf_mul(x, y, z); /* Encode */ enc[EDDSA_448_PRIVATE_BYTES - 1] = 0; @@ -340,15 +340,15 @@ ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio( succ = gf_deserialize(p->y, enc2, 1, 0); succ &= word_is_zero(enc2[EDDSA_448_PRIVATE_BYTES - 1]); - gf_sqr(p->x, p->y); + ossl_gf_sqr(p->x, p->y); gf_sub(p->z, ONE, p->x); /* num = 1-y^2 */ gf_mulw(p->t, p->x, EDWARDS_D); /* dy^2 */ gf_sub(p->t, ONE, p->t); /* denom = 1-dy^2 or 1-d + dy^2 */ - gf_mul(p->x, p->z, p->t); + ossl_gf_mul(p->x, p->z, p->t); succ &= gf_isr(p->t, p->x); /* 1/sqrt(num * denom) */ - gf_mul(p->x, p->t, p->z); /* sqrt(num / denom) */ + ossl_gf_mul(p->x, p->t, p->z); /* sqrt(num / denom) */ gf_cond_neg(p->x, gf_lobit(p->x) ^ low); gf_copy(p->z, ONE); @@ -356,20 +356,20 @@ ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio( gf a, b, c, d; /* 4-isogeny 2xy/(y^2-ax^2), (y^2+ax^2)/(2-y^2-ax^2) */ - gf_sqr(c, p->x); - gf_sqr(a, p->y); + ossl_gf_sqr(c, p->x); + ossl_gf_sqr(a, p->y); gf_add(d, c, a); gf_add(p->t, p->y, p->x); - gf_sqr(b, p->t); + ossl_gf_sqr(b, p->t); gf_sub(b, b, d); gf_sub(p->t, a, c); - gf_sqr(p->x, p->z); + ossl_gf_sqr(p->x, p->z); gf_add(p->z, p->x, p->x); gf_sub(a, p->z, d); - gf_mul(p->x, a, b); - gf_mul(p->z, p->t, a); - gf_mul(p->y, p->t, d); - gf_mul(p->t, b, d); + ossl_gf_mul(p->x, a, b); + ossl_gf_mul(p->z, p->t, a); + ossl_gf_mul(p->y, p->t, d); + ossl_gf_mul(p->t, b, d); OPENSSL_cleanse(a, sizeof(a)); OPENSSL_cleanse(b, sizeof(b)); OPENSSL_cleanse(c, sizeof(c)); @@ -424,30 +424,30 @@ ossl_x448_int(uint8_t out[X_PUBLIC_BYTES], gf_add_nr(t1, x2, z2); /* A = x2 + z2 */ /* 2+e */ gf_sub_nr(t2, x2, z2); /* B = x2 - z2 */ /* 3+e */ gf_sub_nr(z2, x3, z3); /* D = x3 - z3 */ /* 3+e */ - gf_mul(x2, t1, z2); /* DA */ + ossl_gf_mul(x2, t1, z2); /* DA */ gf_add_nr(z2, z3, x3); /* C = x3 + z3 */ /* 2+e */ - gf_mul(x3, t2, z2); /* CB */ + ossl_gf_mul(x3, t2, z2); /* CB */ gf_sub_nr(z3, x2, x3); /* DA-CB */ /* 3+e */ - gf_sqr(z2, z3); /* (DA-CB)^2 */ - gf_mul(z3, x1, z2); /* z3 = x1(DA-CB)^2 */ + ossl_gf_sqr(z2, z3); /* (DA-CB)^2 */ + ossl_gf_mul(z3, x1, z2); /* z3 = x1(DA-CB)^2 */ gf_add_nr(z2, x2, x3); /* (DA+CB) */ /* 2+e */ - gf_sqr(x3, z2); /* x3 = (DA+CB)^2 */ + ossl_gf_sqr(x3, z2); /* x3 = (DA+CB)^2 */ - gf_sqr(z2, t1); /* AA = A^2 */ - gf_sqr(t1, t2); /* BB = B^2 */ - gf_mul(x2, z2, t1); /* x2 = AA*BB */ + ossl_gf_sqr(z2, t1); /* AA = A^2 */ + ossl_gf_sqr(t1, t2); /* BB = B^2 */ + ossl_gf_mul(x2, z2, t1); /* x2 = AA*BB */ gf_sub_nr(t2, z2, t1); /* E = AA-BB */ /* 3+e */ gf_mulw(t1, t2, -EDWARDS_D); /* E*-d = a24*E */ gf_add_nr(t1, t1, z2); /* AA + a24*E */ /* 2+e */ - gf_mul(z2, t2, t1); /* z2 = E(AA+a24*E) */ + ossl_gf_mul(z2, t2, t1); /* z2 = E(AA+a24*E) */ } /* Finish */ gf_cond_swap(x2, x3, swap); gf_cond_swap(z2, z3, swap); gf_invert(z2, z2, 0); - gf_mul(x1, x2, z2); + ossl_gf_mul(x1, x2, z2); gf_serialize(out, x1, 1); nz = ~gf_eq(x1, ZERO); @@ -471,8 +471,8 @@ ossl_curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t curve448_point_copy(q, p); gf_invert(q->t, q->x, 0); /* 1/x */ - gf_mul(q->z, q->t, q->y); /* y/x */ - gf_sqr(q->y, q->z); /* (y/x)^2 */ + ossl_gf_mul(q->z, q->t, q->y); /* y/x */ + ossl_gf_sqr(q->y, q->z); /* (y/x)^2 */ gf_serialize(out, q->y, 1); ossl_curve448_point_destroy(q); } @@ -586,9 +586,15 @@ static int recode_wnaf(struct smvt_control *control, int32_t delta = odd & mask; assert(position >= 0); - assert(pos < 32); /* can't fail since current & 0xFFFF != 0 */ if (odd & (1 << (table_bits + 1))) delta -= (1 << (table_bits + 1)); + /* + * Coverity gets confused by the value of pos, thinking it might be + * 32. This would require current & 0xFFFF to be zero which isn't + * possible. Suppress this false positive, since adding a check + * isn't desirable. + */ + /* coverity[overflow_before_widen] */ current -= delta * (1 << pos); control[position].power = pos + 16 * (w - 1); control[position].addend = delta; @@ -606,7 +612,7 @@ static int recode_wnaf(struct smvt_control *control, return n - 1; } -static void prepare_wnaf_table(pniels_t * output, +static void prepare_wnaf_table(pniels_t *output, const curve448_point_t working, unsigned int tbits) { diff --git a/crypto/ec/curve448/curve448_local.h b/crypto/ec/curve448/curve448_local.h index 3410f091a6..5c569ea8b9 100644 --- a/crypto/ec/curve448/curve448_local.h +++ b/crypto/ec/curve448/curve448_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,15 +10,4 @@ # define OSSL_CRYPTO_EC_CURVE448_LOCAL_H # include "curve448utils.h" -int -ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len, const char *propq); - -int -ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], - const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len, - const char *propq); - #endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */ diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c index 6648692ff3..ff7f11dd34 100644 --- a/crypto/ec/curve448/eddsa.c +++ b/crypto/ec/curve448/eddsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -61,12 +61,8 @@ static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx, size_t context_len, const char *propq) { -#ifdef CHARSET_EBCDIC - const char dom_s[] = {0x53, 0x69, 0x67, 0x45, - 0x64, 0x34, 0x34, 0x38, 0x00}; -#else - const char dom_s[] = "SigEd448"; -#endif + /* ASCII: "SigEd448", in hex for EBCDIC compatibility */ + const char dom_s[] = "\x53\x69\x67\x45\x64\x34\x34\x38"; uint8_t dom[2]; EVP_MD *shake256 = NULL; @@ -82,7 +78,7 @@ static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx, return C448_FAILURE; if (!EVP_DigestInit_ex(hashctx, shake256, NULL) - || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s)) + || !EVP_DigestUpdate(hashctx, dom_s, sizeof(dom_s)-1) || !EVP_DigestUpdate(hashctx, dom, sizeof(dom)) || !EVP_DigestUpdate(hashctx, context, context_len)) { EVP_MD_free(shake256); @@ -373,47 +369,29 @@ ossl_c448_ed448_verify_prehash( } int -ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message, - size_t message_len, const uint8_t public_key[57], - const uint8_t private_key[57], const uint8_t *context, - size_t context_len, const char *propq) +ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, + const uint8_t *message, size_t message_len, + const uint8_t public_key[57], const uint8_t private_key[57], + const uint8_t *context, size_t context_len, + const uint8_t phflag, const char *propq) { return ossl_c448_ed448_sign(ctx, out_sig, private_key, public_key, message, - message_len, 0, context, context_len, + message_len, phflag, context, context_len, propq) == C448_SUCCESS; } int -ossl_ed448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len, +ossl_ed448_verify(OSSL_LIB_CTX *ctx, + const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len, const char *propq) + const uint8_t *context, size_t context_len, + const uint8_t phflag, const char *propq) { return ossl_c448_ed448_verify(ctx, signature, public_key, message, - message_len, 0, context, (uint8_t)context_len, + message_len, phflag, context, (uint8_t)context_len, propq) == C448_SUCCESS; } -int -ossl_ed448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], - const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len, const char *propq) -{ - return ossl_c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, - hash, context, context_len, - propq) == C448_SUCCESS; -} - -int -ossl_ed448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], - const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len, - const char *propq) -{ - return ossl_c448_ed448_verify_prehash(ctx, signature, public_key, hash, - context, (uint8_t)context_len, - propq) == C448_SUCCESS; -} - int ossl_ed448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57], const uint8_t private_key[57], const char *propq) diff --git a/crypto/ec/curve448/f_generic.c b/crypto/ec/curve448/f_generic.c index 4c571810d3..9a4675a8b3 100644 --- a/crypto/ec/curve448/f_generic.c +++ b/crypto/ec/curve448/f_generic.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -18,7 +18,7 @@ static const gf MODULUS = { }; /* Serialize to wire format. */ -void gf_serialize(uint8_t *serial, const gf x, int with_hibit) +void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_hibit) { unsigned int j = 0, fill = 0; dword_t buffer = 0; @@ -173,32 +173,32 @@ mask_t gf_isr(gf a, const gf x) { gf L0, L1, L2; - gf_sqr(L1, x); - gf_mul(L2, x, L1); - gf_sqr(L1, L2); - gf_mul(L2, x, L1); + ossl_gf_sqr(L1, x); + ossl_gf_mul(L2, x, L1); + ossl_gf_sqr(L1, L2); + ossl_gf_mul(L2, x, L1); gf_sqrn(L1, L2, 3); - gf_mul(L0, L2, L1); + ossl_gf_mul(L0, L2, L1); gf_sqrn(L1, L0, 3); - gf_mul(L0, L2, L1); + ossl_gf_mul(L0, L2, L1); gf_sqrn(L2, L0, 9); - gf_mul(L1, L0, L2); - gf_sqr(L0, L1); - gf_mul(L2, x, L0); + ossl_gf_mul(L1, L0, L2); + ossl_gf_sqr(L0, L1); + ossl_gf_mul(L2, x, L0); gf_sqrn(L0, L2, 18); - gf_mul(L2, L1, L0); + ossl_gf_mul(L2, L1, L0); gf_sqrn(L0, L2, 37); - gf_mul(L1, L2, L0); + ossl_gf_mul(L1, L2, L0); gf_sqrn(L0, L1, 37); - gf_mul(L1, L2, L0); + ossl_gf_mul(L1, L2, L0); gf_sqrn(L0, L1, 111); - gf_mul(L2, L1, L0); - gf_sqr(L0, L2); - gf_mul(L1, x, L0); + ossl_gf_mul(L2, L1, L0); + ossl_gf_sqr(L0, L2); + ossl_gf_mul(L1, x, L0); gf_sqrn(L0, L1, 223); - gf_mul(L1, L2, L0); - gf_sqr(L2, L1); - gf_mul(L0, L2, x); + ossl_gf_mul(L1, L2, L0); + ossl_gf_sqr(L2, L1); + ossl_gf_mul(L0, L2, x); gf_copy(a, L1); return gf_eq(L0, ONE); } diff --git a/crypto/ec/curve448/field.h b/crypto/ec/curve448/field.h index e1c6333789..80b1355b77 100644 --- a/crypto/ec/curve448/field.h +++ b/crypto/ec/curve448/field.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -54,15 +54,15 @@ static INLINE_UNUSED void gf_weak_reduce(gf inout); void gf_strong_reduce(gf inout); void gf_add(gf out, const gf a, const gf b); void gf_sub(gf out, const gf a, const gf b); -void gf_mul(gf_s * RESTRICT out, const gf a, const gf b); -void gf_mulw_unsigned(gf_s * RESTRICT out, const gf a, uint32_t b); -void gf_sqr(gf_s * RESTRICT out, const gf a); +void ossl_gf_mul(gf_s * RESTRICT out, const gf a, const gf b); +void ossl_gf_mulw_unsigned(gf_s * RESTRICT out, const gf a, uint32_t b); +void ossl_gf_sqr(gf_s * RESTRICT out, const gf a); mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */ mask_t gf_eq(const gf x, const gf y); mask_t gf_lobit(const gf x); mask_t gf_hibit(const gf x); -void gf_serialize(uint8_t *serial, const gf x, int with_highbit); +void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_highbit); mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit, uint8_t hi_nmask); @@ -85,16 +85,16 @@ static ossl_inline void gf_sqrn(gf_s * RESTRICT y, const gf x, int n) assert(n > 0); if (n & 1) { - gf_sqr(y, x); + ossl_gf_sqr(y, x); n--; } else { - gf_sqr(tmp, x); - gf_sqr(y, tmp); + ossl_gf_sqr(tmp, x); + ossl_gf_sqr(y, tmp); n -= 2; } for (; n; n -= 2) { - gf_sqr(tmp, y); - gf_sqr(y, tmp); + ossl_gf_sqr(tmp, y); + ossl_gf_sqr(y, tmp); } } @@ -122,9 +122,9 @@ static ossl_inline void gf_subx_nr(gf c, const gf a, const gf b, int amt) static ossl_inline void gf_mulw(gf c, const gf a, int32_t w) { if (w > 0) { - gf_mulw_unsigned(c, a, w); + ossl_gf_mulw_unsigned(c, a, w); } else { - gf_mulw_unsigned(c, a, -w); + ossl_gf_mulw_unsigned(c, a, -w); gf_sub(c, ZERO, c); } } diff --git a/crypto/ec/curve448/point_448.h b/crypto/ec/curve448/point_448.h index e67ea68044..96a54558d6 100644 --- a/crypto/ec/curve448/point_448.h +++ b/crypto/ec/curve448/point_448.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -271,7 +271,7 @@ ossl_x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES], */ void ossl_curve448_precomputed_scalarmul(curve448_point_t scaled, - const curve448_precomputed_s * base, + const curve448_precomputed_s *base, const curve448_scalar_t scalar); /* diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index d6a51137aa..13e702684e 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -188,7 +188,7 @@ int ossl_ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } @@ -545,7 +545,7 @@ int ossl_ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point * We have a curve defined by a Weierstrass equation * y^2 + x*y = x^3 + a*x^2 + b. * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 - * <=> ((x + a) * x + y ) * x + b + y^2 = 0 + * <=> ((x + a) * x + y) * x + b + y^2 = 0 */ if (!BN_GF2m_add(lh, point->X, group->a)) goto err; @@ -826,7 +826,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group, t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t2 == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -905,7 +905,7 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r, */ if ((t = EC_POINT_new(group)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index d4348ff244..ad28ba6827 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -568,7 +568,7 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, if (ecbits <= 0) goto err; - sz = (ecbits + 7 ) / 8; + sz = (ecbits + 7) / 8; if (!OSSL_PARAM_BLD_push_BN_pad(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, priv_key, sz)) @@ -613,7 +613,7 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery); if (ec == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 7a0b35a594..b32697fb85 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,6 +19,7 @@ #include #include #include "internal/nelem.h" +#include "crypto/asn1.h" #include "crypto/asn1_dsa.h" #ifndef FIPS_MODULE @@ -205,7 +206,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) if (nid == NID_X9_62_prime_field) { if ((tmp = BN_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } /* the parameters are specified by the prime number p */ @@ -234,7 +235,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two = field->p.char_two; if (char_two == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } @@ -260,7 +261,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two->p.tpBasis = ASN1_INTEGER_new(); if (char_two->p.tpBasis == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { @@ -275,7 +276,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); if (char_two->p.ppBasis == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } @@ -288,7 +289,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) /* for ONB the parameters are (asn1) NULL */ char_two->p.onBasis = ASN1_NULL_new(); if (char_two->p.onBasis == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } @@ -317,7 +318,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) return 0; if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -334,10 +335,8 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) */ len = ((size_t)EC_GROUP_get_degree(group) + 7) / 8; if ((a_buf = OPENSSL_malloc(len)) == NULL - || (b_buf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + || (b_buf = OPENSSL_malloc(len)) == NULL) goto err; - } if (BN_bn2binpad(tmp_1, a_buf, len) < 0 || BN_bn2binpad(tmp_2, b_buf, len) < 0) { ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); @@ -355,11 +354,10 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) if (group->seed) { if (!curve->seed) if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } - curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(curve->seed, 0); if (!ASN1_BIT_STRING_set(curve->seed, group->seed, (int)group->seed_len)) { ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); @@ -393,7 +391,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, if (params == NULL) { if ((ret = ECPARAMETERS_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } } else @@ -429,7 +427,7 @@ ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, } if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { OPENSSL_free(buffer); - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } ASN1_STRING_set0(ret->base, buffer, len); @@ -474,7 +472,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, if (ret == NULL) { if ((ret = ECPKPARAMETERS_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); return NULL; } } else { @@ -580,7 +578,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) } if ((p = BN_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -698,10 +696,8 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) goto err; } OPENSSL_free(ret->seed); - if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) goto err; - } memcpy(ret->seed, params->curve->seed->data, params->curve->seed->length); ret->seed_len = params->curve->seed->length; @@ -945,7 +941,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) if (a == NULL || *a == NULL) { if ((ret = EC_KEY_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } else @@ -1033,7 +1029,7 @@ int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out) } if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1061,7 +1057,7 @@ int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out) if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { priv_key->publicKey = ASN1_BIT_STRING_new(); if (priv_key->publicKey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); goto err; } @@ -1072,8 +1068,7 @@ int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out) goto err; } - priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(priv_key->publicKey, 0); ASN1_STRING_set0(priv_key->publicKey, pub, publen); pub = NULL; } @@ -1110,7 +1105,7 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) if (a == NULL || *a == NULL) { if ((ret = EC_KEY_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return NULL; } } else @@ -1174,10 +1169,8 @@ int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out) return buf_len; if (*out == NULL) { - if ((*out = OPENSSL_malloc(buf_len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((*out = OPENSSL_malloc(buf_len)) == NULL) return 0; - } new_buffer = 1; } if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, @@ -1202,8 +1195,7 @@ DECLARE_ASN1_ENCODE_FUNCTIONS_name(ECDSA_SIG, ECDSA_SIG) ECDSA_SIG *ECDSA_SIG_new(void) { ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); - if (sig == NULL) - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return sig; } diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index e159ba0c61..b9ebc96465 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -191,7 +191,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, BIGNUM *b = BN_CTX_get(bnctx); if (b == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -202,7 +202,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -217,7 +217,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, } if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, order)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -227,7 +227,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, if (!ossl_param_build_set_utf8_string(tmpl, params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_type)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -250,7 +250,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, if (!ossl_param_build_set_octet_string(tmpl, params, OSSL_PKEY_PARAM_EC_GENERATOR, *genbuf, genbuf_len)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -262,7 +262,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, if (cofactor != NULL && !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -277,7 +277,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, && !ossl_param_build_set_octet_string(tmpl, params, OSSL_PKEY_PARAM_EC_SEED, seed, seed_len)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } @@ -296,7 +296,7 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, point_conversion_form_t genform; if (group == NULL) { - ERR_raise(ERR_LIB_EC,EC_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER); return 0; } @@ -774,7 +774,7 @@ EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, X509_ALGOR_get0(NULL, &ptype, &pval, palg); if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto ecerr; } diff --git a/crypto/ec/ec_check.c b/crypto/ec/ec_check.c index 484124915d..9ed94b328c 100644 --- a/crypto/ec/ec_check.c +++ b/crypto/ec/ec_check.c @@ -30,7 +30,7 @@ int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only, if (ctx == NULL) { ctx = new_ctx = BN_CTX_new_ex(NULL); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return NID_undef; } } @@ -69,7 +69,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index b5b2f3342d..d703d16b3c 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -2838,6 +2838,8 @@ static const ec_list_element curve_list[] = { {NID_secp384r1, &_EC_NIST_PRIME_384.h, # if defined(S390X_EC_ASM) EC_GFp_s390x_nistp384_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + ossl_ec_GFp_nistp384_method, # else 0, # endif @@ -2931,6 +2933,8 @@ static const ec_list_element curve_list[] = { {NID_secp384r1, &_EC_NIST_PRIME_384.h, # if defined(S390X_EC_ASM) EC_GFp_s390x_nistp384_method, +# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + ossl_ec_GFp_nistp384_method, # else 0, # endif @@ -3107,8 +3111,13 @@ static const ec_list_element curve_list[] = { "RFC 5639 curve over a 512 bit prime field"}, {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"}, -# ifndef OPENSSL_NO_SM2 - {NID_sm2, &_EC_sm2p256v1.h, 0, +#ifndef OPENSSL_NO_SM2 + {NID_sm2, &_EC_sm2p256v1.h, +# ifdef ECP_SM2P256_ASM + EC_GFp_sm2p256_method, +# else + 0, +# endif "SM2 curve over a 256 bit prime field"}, # endif }; @@ -3151,7 +3160,7 @@ static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx, curve.meth != NULL ? curve.meth() : NULL); if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } diff --git a/crypto/ec/ec_deprecated.c b/crypto/ec/ec_deprecated.c index 765894c329..905b560638 100644 --- a/crypto/ec/ec_deprecated.c +++ b/crypto/ec/ec_deprecated.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -47,10 +47,8 @@ EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, if ((buf_len = BN_num_bytes(bn)) == 0) buf_len = 1; - if ((buf = OPENSSL_malloc(buf_len)) == NULL) { - ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(buf_len)) == NULL) return NULL; - } if (BN_bn2binpad(bn, buf, buf_len) < 0) { OPENSSL_free(buf); diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 901630dad5..9bc4e032c5 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -24,6 +24,7 @@ #endif #include #include "prov/providercommon.h" +#include "prov/ecx.h" #include "crypto/bn.h" static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, @@ -74,7 +75,7 @@ void EC_KEY_free(EC_KEY *r) if (r == NULL) return; - CRYPTO_DOWN_REF(&r->references, &i, r->lock); + CRYPTO_DOWN_REF(&r->references, &i); REF_PRINT_COUNT("EC_KEY", r); if (i > 0) return; @@ -93,7 +94,7 @@ void EC_KEY_free(EC_KEY *r) #ifndef FIPS_MODULE CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); #endif - CRYPTO_THREAD_lock_free(r->lock); + CRYPTO_FREE_REF(&r->references); EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); @@ -193,7 +194,7 @@ int EC_KEY_up_ref(EC_KEY *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + if (CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; REF_PRINT_COUNT("EC_KEY", r); @@ -401,6 +402,43 @@ static int ec_generate_key(EC_KEY *eckey, int pairwise_test) return ok; } +#ifndef FIPS_MODULE +/* + * This is similar to ec_generate_key(), except it uses an ikm to + * derive the private key. + */ +int ossl_ec_generate_key_dhkem(EC_KEY *eckey, + const unsigned char *ikm, size_t ikmlen) +{ + int ok = 0; + + if (eckey->priv_key == NULL) { + eckey->priv_key = BN_secure_new(); + if (eckey->priv_key == NULL) + goto err; + } + if (ossl_ec_dhkem_derive_private(eckey, eckey->priv_key, ikm, ikmlen) <= 0) + goto err; + if (eckey->pub_key == NULL) { + eckey->pub_key = EC_POINT_new(eckey->group); + if (eckey->pub_key == NULL) + goto err; + } + if (!ossl_ec_key_simple_generate_public_key(eckey)) + goto err; + + ok = 1; +err: + if (!ok) { + BN_clear_free(eckey->priv_key); + eckey->priv_key = NULL; + if (eckey->pub_key != NULL) + EC_POINT_set_to_infinity(eckey->group, eckey->pub_key); + } + return ok; +} +#endif + int ossl_ec_key_simple_generate_key(EC_KEY *eckey) { return ec_generate_key(eckey, 0); @@ -1005,7 +1043,7 @@ int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, if (eckey->priv_key == NULL) eckey->priv_key = BN_secure_new(); if (eckey->priv_key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) { @@ -1024,10 +1062,8 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf) len = EC_KEY_priv2oct(eckey, NULL, 0); if (len == 0) return 0; - if ((buf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(len)) == NULL) return 0; - } len = EC_KEY_priv2oct(eckey, buf, len); if (len == 0) { OPENSSL_free(buf); diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index 8c011635cb..054a3333a7 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -83,25 +83,19 @@ EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) + return NULL; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + OPENSSL_free(ret); return NULL; } ret->libctx = libctx; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); - if (ret->propq == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret->propq == NULL) goto err; - } - } - - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - goto err; } ret->meth = EC_KEY_get_default_method(); @@ -129,6 +123,7 @@ EC_KEY *ossl_ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, /* No ex_data inside the FIPS provider */ #ifndef FIPS_MODULE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { + ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } #endif diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index a84e088c19..c92b4dcb0a 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -19,6 +19,7 @@ #include #include #include +#include #include "crypto/ec.h" #include "internal/nelem.h" #include "ec_local.h" @@ -40,18 +41,14 @@ EC_GROUP *ossl_ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, } ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->libctx = libctx; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); - if (ret->propq == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret->propq == NULL) goto err; - } } ret->meth = meth; if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) { @@ -102,12 +99,16 @@ void EC_pre_comp_free(EC_GROUP *group) case PCT_nistp256: EC_nistp256_pre_comp_free(group->pre_comp.nistp256); break; + case PCT_nistp384: + ossl_ec_nistp384_pre_comp_free(group->pre_comp.nistp384); + break; case PCT_nistp521: EC_nistp521_pre_comp_free(group->pre_comp.nistp521); break; #else case PCT_nistp224: case PCT_nistp256: + case PCT_nistp384: case PCT_nistp521: break; #endif @@ -191,12 +192,16 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) case PCT_nistp256: dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256); break; + case PCT_nistp384: + dest->pre_comp.nistp384 = ossl_ec_nistp384_pre_comp_dup(src->pre_comp.nistp384); + break; case PCT_nistp521: dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521); break; #else case PCT_nistp224: case PCT_nistp256: + case PCT_nistp384: case PCT_nistp521: break; #endif @@ -246,10 +251,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) if (src->seed) { OPENSSL_free(dest->seed); - if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) return 0; - } if (!memcpy(dest->seed, src->seed, src->seed_len)) return 0; dest->seed_len = src->seed_len; @@ -532,10 +535,8 @@ size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) if (!len || !p) return 1; - if ((group->seed = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((group->seed = OPENSSL_malloc(len)) == NULL) return 0; - } memcpy(group->seed, p, len); group->seed_len = len; @@ -726,10 +727,8 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) } ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->meth = group->meth; ret->curve_name = group->curve_name; @@ -1582,7 +1581,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], /* If it gets here then we are trying explicit parameters */ bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } BN_CTX_start(bnctx); @@ -1592,7 +1591,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], b = BN_CTX_get(bnctx); order = BN_CTX_get(bnctx); if (order == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -1758,3 +1757,38 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], return group; #endif /* FIPS_MODULE */ } + +OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx, + const char *propq, BN_CTX *bnctx) +{ + OSSL_PARAM_BLD *tmpl = NULL; + BN_CTX *new_bnctx = NULL; + unsigned char *gen_buf = NULL; + OSSL_PARAM *params = NULL; + + if (group == NULL) + goto err; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + goto err; + + if (bnctx == NULL) + bnctx = new_bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) + goto err; + BN_CTX_start(bnctx); + + if (!ossl_ec_group_todata( + group, tmpl, NULL, libctx, propq, bnctx, &gen_buf)) + goto err; + + params = OSSL_PARAM_BLD_to_param(tmpl); + + err: + OSSL_PARAM_BLD_free(tmpl); + OPENSSL_free(gen_buf); + BN_CTX_end(bnctx); + BN_CTX_free(new_bnctx); + return params; +} diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h index f34e06aea8..2814d87394 100644 --- a/crypto/ec/ec_local.h +++ b/crypto/ec/ec_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -203,6 +203,7 @@ struct ec_method_st { */ typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP; typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP; +typedef struct nistp384_pre_comp_st NISTP384_PRE_COMP; typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP; typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP; typedef struct ec_pre_comp_st EC_PRE_COMP; @@ -245,7 +246,7 @@ struct ec_group_st { * equation of the form y^2 + x*y = x^3 + a*x^2 + b. */ BIGNUM *a, *b; - /* enable optimized point arithmetics for special case */ + /* enable optimized point arithmetic for special case */ int a_is_minus3; /* method-specific (e.g., Montgomery structure) */ void *field_data1; @@ -264,12 +265,13 @@ struct ec_group_st { */ enum { PCT_none, - PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256, + PCT_nistp224, PCT_nistp256, PCT_nistp384, PCT_nistp521, PCT_nistz256, PCT_ec } pre_comp_type; union { NISTP224_PRE_COMP *nistp224; NISTP256_PRE_COMP *nistp256; + NISTP384_PRE_COMP *nistp384; NISTP521_PRE_COMP *nistp521; NISTZ256_PRE_COMP *nistz256; EC_PRE_COMP *ec; @@ -298,7 +300,6 @@ struct ec_key_st { #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; #endif - CRYPTO_RWLOCK *lock; OSSL_LIB_CTX *libctx; char *propq; @@ -318,7 +319,7 @@ struct ec_point_st { BIGNUM *Y; BIGNUM *Z; /* Jacobian projective coordinates: * (X, Y, * Z) represents (X/Z^2, Y/Z^3) if Z != 0 */ - int Z_is_one; /* enable optimized point arithmetics for + int Z_is_one; /* enable optimized point arithmetic for * special case */ }; @@ -333,6 +334,7 @@ static ossl_inline int ec_point_is_compat(const EC_POINT *point, NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *); NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *); +NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *); NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *); NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *); NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *); @@ -341,6 +343,7 @@ EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *); void EC_pre_comp_free(EC_GROUP *group); void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *); void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *); +void ossl_ec_nistp384_pre_comp_free(NISTP384_PRE_COMP *); void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *); void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *); void EC_ec_pre_comp_free(EC_PRE_COMP *); @@ -552,6 +555,27 @@ int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); +/* method functions in ecp_nistp384.c */ +int ossl_ec_GFp_nistp384_group_init(EC_GROUP *group); +int ossl_ec_GFp_nistp384_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ossl_ec_GFp_nistp384_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ossl_ec_GFp_nistp384_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ossl_ec_GFp_nistp384_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ossl_ec_GFp_nistp384_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ossl_ec_GFp_nistp384_have_precompute_mult(const EC_GROUP *group); +const EC_METHOD *ossl_ec_GFp_nistp384_method(void); + /* method functions in ecp_nistp521.c */ int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group); int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, @@ -629,6 +653,11 @@ int ossl_ec_key_simple_generate_key(EC_KEY *eckey); int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey); int ossl_ec_key_simple_check_key(const EC_KEY *eckey); +#ifdef ECP_SM2P256_ASM +/* Returns optimized methods for SM2 */ +const EC_METHOD *EC_GFp_sm2p256_method(void); +#endif + int ossl_ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx); /* EC_METHOD definitions */ diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index c6ec2964b7..9eb007cdf9 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -45,7 +45,6 @@ struct ec_pre_comp_st { * objects followed by a NULL */ size_t num; /* numblocks * 2^(w-1) */ CRYPTO_REF_COUNT references; - CRYPTO_RWLOCK *lock; }; static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) @@ -56,19 +55,14 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) return NULL; ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return ret; - } ret->group = group; ret->blocksize = 8; /* default */ ret->w = 4; /* default */ - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret); return NULL; } @@ -79,7 +73,7 @@ EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre) { int i; if (pre != NULL) - CRYPTO_UP_REF(&pre->references, &i, pre->lock); + CRYPTO_UP_REF(&pre->references, &i); return pre; } @@ -90,7 +84,7 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre) if (pre == NULL) return; - CRYPTO_DOWN_REF(&pre->references, &i, pre->lock); + CRYPTO_DOWN_REF(&pre->references, &i); REF_PRINT_COUNT("EC_ec", pre); if (i > 0) return; @@ -103,7 +97,7 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre) EC_POINT_free(*pts); OPENSSL_free(pre->points); } - CRYPTO_THREAD_lock_free(pre->lock); + CRYPTO_FREE_REF(&pre->references); OPENSSL_free(pre); } @@ -171,7 +165,7 @@ int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, if (((p = EC_POINT_new(group)) == NULL) || ((s = EC_POINT_new(group)) == NULL)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -195,7 +189,7 @@ int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, lambda = BN_CTX_get(ctx); k = BN_CTX_get(ctx); if (k == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -520,10 +514,8 @@ int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (wNAF != NULL) wNAF[0] = NULL; /* preliminary pivot */ - if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) goto err; - } /* * num_val will be the total number of temporarily precomputed points @@ -633,7 +625,6 @@ int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, wNAF[i + 1] = NULL; wNAF[i] = OPENSSL_malloc(wNAF_len[i]); if (wNAF[i] == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp_wNAF); goto err; } @@ -661,10 +652,8 @@ int ossl_ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * subarray of 'pre_comp->points' if we already have precomputation. */ val = OPENSSL_malloc((num_val + 1) * sizeof(val[0])); - if (val == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (val == NULL) goto err; - } val[num_val] = NULL; /* pivot element */ /* allocate points for precomputation */ @@ -893,23 +882,21 @@ int ossl_ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) * and store */ points = OPENSSL_malloc(sizeof(*points) * (num + 1)); - if (points == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (points == NULL) goto err; - } var = points; var[num] = NULL; /* pivot */ for (i = 0; i < num; i++) { if ((var[i] = EC_POINT_new(group)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } } if ((tmp_point = EC_POINT_new(group)) == NULL || (base = EC_POINT_new(group)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } diff --git a/crypto/ec/ec_oct.c b/crypto/ec/ec_oct.c index 790a0b2907..0ad3394c82 100644 --- a/crypto/ec/ec_oct.c +++ b/crypto/ec/ec_oct.c @@ -140,10 +140,8 @@ size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL); if (len == 0) return 0; - if ((buf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(len)) == NULL) return 0; - } len = EC_POINT_point2oct(group, point, form, buf, len, ctx); if (len == 0) { OPENSSL_free(buf); diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 19e2f0d0c0..716b1860bb 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -48,10 +48,8 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) { EC_PKEY_CTX *dctx; - if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) return 0; - } dctx->cofactor_mode = -1; dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; @@ -229,10 +227,8 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, return 0; if (!pkey_ec_derive(ctx, NULL, &ktmplen)) return 0; - if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) return 0; - } if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ diff --git a/crypto/ec/ecdh_ossl.c b/crypto/ec/ecdh_ossl.c index 8016c6d7ad..41f7e39046 100644 --- a/crypto/ec/ecdh_ossl.c +++ b/crypto/ec/ecdh_ossl.c @@ -63,7 +63,7 @@ int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, BN_CTX_start(ctx); x = BN_CTX_get(ctx); if (x == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -80,16 +80,19 @@ int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, * * peer_public_key. */ if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { - if (!EC_GROUP_get_cofactor(group, x, NULL) || - !BN_mul(x, x, priv_key, ctx)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (!EC_GROUP_get_cofactor(group, x, NULL)) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); + goto err; + } + if (!BN_mul(x, x, priv_key, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } priv_key = x; } if ((tmp = EC_POINT_new(group)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -118,10 +121,8 @@ int ossl_ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen, ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); goto err; } - if ((buf = OPENSSL_malloc(buflen)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(buflen)) == NULL) goto err; - } memset(buf, 0, buflen - len); if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c index 0bf4635e2f..0da33799e4 100644 --- a/crypto/ec/ecdsa_ossl.c +++ b/crypto/ec/ecdsa_ossl.c @@ -19,6 +19,7 @@ #include #include "crypto/bn.h" #include "ec_local.h" +#include "internal/deterministic_nonce.h" #define MIN_ECDSA_SIGN_ORDERBITS 64 /* @@ -29,6 +30,12 @@ */ #define MAX_ECDSA_SIGN_RETRIES 8 +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); + int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { @@ -80,9 +87,39 @@ int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, return 1; } +int ossl_ecdsa_deterministic_sign(const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, + EC_KEY *eckey, unsigned int nonce_type, + const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) +{ + ECDSA_SIG *s; + BIGNUM *kinv = NULL, *r = NULL; + int ret = 0; + + *siglen = 0; + if (!ecdsa_sign_setup(eckey, NULL, &kinv, &r, dgst, dlen, + nonce_type, digestname, libctx, propq)) + return 0; + + s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); + if (s == NULL) + goto end; + + *siglen = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL); + ECDSA_SIG_free(s); + ret = 1; +end: + BN_clear_free(kinv); + BN_clear_free(r); + return ret; +} + static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp, - const unsigned char *dgst, int dlen) + const unsigned char *dgst, int dlen, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *X = NULL; @@ -109,7 +146,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, if ((ctx = ctx_in) == NULL) { if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return 0; } } @@ -118,7 +155,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, r = BN_new(); /* this value is later returned in *rp */ X = BN_new(); if (k == NULL || r == NULL || X == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } if ((tmp_point = EC_POINT_new(group)) == NULL) { @@ -137,19 +174,29 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, goto err; do { - /* get random k */ + /* get random or deterministic value of k */ do { + int res = 0; + if (dgst != NULL) { - if (!BN_generate_dsa_nonce(k, order, priv_key, - dgst, dlen, ctx)) { - ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); - goto err; + if (nonce_type == 1) { +#ifndef FIPS_MODULE + res = ossl_gen_deterministic_nonce_rfc6979(k, order, + priv_key, + dgst, dlen, + digestname, + libctx, propq); +#endif + } else { + res = BN_generate_dsa_nonce(k, order, priv_key, dgst, dlen, + ctx); } } else { - if (!BN_priv_rand_range_ex(k, order, 0, ctx)) { - ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); - goto err; - } + res = BN_priv_rand_range_ex(k, order, 0, ctx); + } + if (!res) { + ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; } } while (BN_is_zero(k)); @@ -198,7 +245,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { - return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0); + return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0, + 0, NULL, NULL, NULL); } ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, @@ -233,20 +281,20 @@ ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, ret = ECDSA_SIG_new(); if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); return NULL; } ret->r = BN_new(); ret->s = BN_new(); if (ret->r == NULL || ret->s == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } s = ret->s; if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL || (m = BN_new()) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } @@ -268,7 +316,8 @@ ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, } do { if (in_kinv == NULL || in_r == NULL) { - if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) { + if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len, + 0, NULL, NULL, NULL)) { ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); goto err; } @@ -276,7 +325,7 @@ ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, } else { ckinv = in_kinv; if (BN_copy(ret->r, in_r) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } @@ -395,7 +444,7 @@ int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, ctx = BN_CTX_new_ex(eckey->libctx); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return -1; } BN_CTX_start(ctx); @@ -454,7 +503,7 @@ int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, } if ((point = EC_POINT_new(group)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c index 96ced7c8be..1bb58c6f33 100644 --- a/crypto/ec/eck_prn.c +++ b/crypto/ec/eck_prn.c @@ -89,7 +89,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) ctx = BN_CTX_new(); if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; + reason = ERR_R_BN_LIB; goto err; } @@ -127,7 +127,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || (b = BN_new()) == NULL) { - reason = ERR_R_MALLOC_FAILURE; + reason = ERR_R_BN_LIB; goto err; } diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 8f381fc36b..12750b6003 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index 4a55f925c4..d28306a6bd 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -97,7 +97,7 @@ static const felem_bytearray nistp256_curve_params[5] = { * values, or four 64-bit values. The field element represented is: * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p) * or: - * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p) + * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[7]*2^448 (mod p) * * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits * apart, but are 128-bits wide, the most significant bits of each limb overlap @@ -1773,7 +1773,6 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, struct nistp256_pre_comp_st { smallfelem g_pre_comp[2][16][3]; CRYPTO_REF_COUNT references; - CRYPTO_RWLOCK *lock; }; const EC_METHOD *EC_GFp_nistp256_method(void) @@ -1849,16 +1848,10 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void) { NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return ret; - } - - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret); return NULL; } @@ -1869,7 +1862,7 @@ NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p) { int i; if (p != NULL) - CRYPTO_UP_REF(&p->references, &i, p->lock); + CRYPTO_UP_REF(&p->references, &i); return p; } @@ -1880,13 +1873,13 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre) if (pre == NULL) return; - CRYPTO_DOWN_REF(&pre->references, &i, pre->lock); + CRYPTO_DOWN_REF(&pre->references, &i); REF_PRINT_COUNT("EC_nistp256", pre); if (i > 0) return; REF_ASSERT_ISNT(i < 0); - CRYPTO_THREAD_lock_free(pre->lock); + CRYPTO_FREE_REF(&pre->references); OPENSSL_free(pre); } @@ -2099,10 +2092,8 @@ int ossl_ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, tmp_smallfelems = OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1)); if ((secrets == NULL) || (pre_comp == NULL) - || (mixed && (tmp_smallfelems == NULL))) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + || (mixed && (tmp_smallfelems == NULL))) goto err; - } /* * we treat NULL scalars as 0, and NULL points as points at infinity, diff --git a/crypto/ec/ecp_nistp384.c b/crypto/ec/ecp_nistp384.c new file mode 100644 index 0000000000..ff68f9cc7a --- /dev/null +++ b/crypto/ec/ecp_nistp384.c @@ -0,0 +1,1997 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Copyright 2023 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Designed for 56-bit limbs by Rohan McLure . + * The layout is based on that of ecp_nistp{224,521}.c, allowing even for asm + * acceleration of felem_{square,mul} as supported in these files. + */ + +#include + +#include +#include +#include "ec_local.h" + +#include "internal/numbers.h" + +#ifndef INT128_MAX +# error "Your compiler doesn't appear to support 128-bit integer types" +#endif + +typedef uint8_t u8; +typedef uint64_t u64; + +/* + * The underlying field. P384 operates over GF(2^384-2^128-2^96+2^32-1). We + * can serialize an element of this field into 48 bytes. We call this an + * felem_bytearray. + */ + +typedef u8 felem_bytearray[48]; + +/* + * These are the parameters of P384, taken from FIPS 186-3, section D.1.2.4. + * These values are big-endian. + */ +static const felem_bytearray nistp384_curve_params[5] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a = -3 */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC}, + {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, /* b */ + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF}, + {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, /* x */ + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7}, + {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, /* y */ + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F}, +}; + +/*- + * The representation of field elements. + * ------------------------------------ + * + * We represent field elements with seven values. These values are either 64 or + * 128 bits and the field element represented is: + * v[0]*2^0 + v[1]*2^56 + v[2]*2^112 + ... + v[6]*2^336 (mod p) + * Each of the seven values is called a 'limb'. Since the limbs are spaced only + * 56 bits apart, but are greater than 56 bits in length, the most significant + * bits of each limb overlap with the least significant bits of the next + * + * This representation is considered to be 'redundant' in the sense that + * intermediate values can each contain more than a 56-bit value in each limb. + * Reduction causes all but the final limb to be reduced to contain a value less + * than 2^56, with the final value represented allowed to be larger than 2^384, + * inasmuch as we can be sure that arithmetic overflow remains impossible. The + * reduced value must of course be congruent to the unreduced value. + * + * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a + * 'widefelem', featuring enough bits to store the result of a multiplication + * and even some further arithmetic without need for immediate reduction. + */ + +#define NLIMBS 7 + +typedef uint64_t limb; +typedef uint128_t widelimb; +typedef limb limb_aX __attribute((__aligned__(1))); +typedef limb felem[NLIMBS]; +typedef widelimb widefelem[2*NLIMBS-1]; + +static const limb bottom56bits = 0xffffffffffffff; + +/* Helper functions (de)serialising reduced field elements in little endian */ +static void bin48_to_felem(felem out, const u8 in[48]) +{ + memset(out, 0, 56); + out[0] = (*((limb *) & in[0])) & bottom56bits; + out[1] = (*((limb_aX *) & in[7])) & bottom56bits; + out[2] = (*((limb_aX *) & in[14])) & bottom56bits; + out[3] = (*((limb_aX *) & in[21])) & bottom56bits; + out[4] = (*((limb_aX *) & in[28])) & bottom56bits; + out[5] = (*((limb_aX *) & in[35])) & bottom56bits; + memmove(&out[6], &in[42], 6); +} + +static void felem_to_bin48(u8 out[48], const felem in) +{ + memset(out, 0, 48); + (*((limb *) & out[0])) |= (in[0] & bottom56bits); + (*((limb_aX *) & out[7])) |= (in[1] & bottom56bits); + (*((limb_aX *) & out[14])) |= (in[2] & bottom56bits); + (*((limb_aX *) & out[21])) |= (in[3] & bottom56bits); + (*((limb_aX *) & out[28])) |= (in[4] & bottom56bits); + (*((limb_aX *) & out[35])) |= (in[5] & bottom56bits); + memmove(&out[42], &in[6], 6); +} + +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_out; + int num_bytes; + + if (BN_is_negative(bn)) { + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out)); + if (num_bytes < 0) { + ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + bin48_to_felem(out, b_out); + return 1; +} + +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) +{ + felem_bytearray b_out; + + felem_to_bin48(b_out, in); + return BN_lebin2bn(b_out, sizeof(b_out), out); +} + +/*- + * Field operations + * ---------------- + */ + +static void felem_one(felem out) +{ + out[0] = 1; + memset(&out[1], 0, sizeof(limb) * (NLIMBS-1)); +} + +static void felem_assign(felem out, const felem in) +{ + memcpy(out, in, sizeof(felem)); +} + +/* felem_sum64 sets out = out + in. */ +static void felem_sum64(felem out, const felem in) +{ + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out[i] += in[i]; +} + +/* felem_scalar sets out = in * scalar */ +static void felem_scalar(felem out, const felem in, limb scalar) +{ + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out[i] = in[i] * scalar; +} + +/* felem_scalar64 sets out = out * scalar */ +static void felem_scalar64(felem out, limb scalar) +{ + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out[i] *= scalar; +} + +/* felem_scalar128 sets out = out * scalar */ +static void felem_scalar128(widefelem out, limb scalar) +{ + unsigned int i; + + for (i = 0; i < 2*NLIMBS-1; i++) + out[i] *= scalar; +} + +/*- + * felem_neg sets |out| to |-in| + * On entry: + * in[i] < 2^60 - 2^29 + * On exit: + * out[i] < 2^60 + */ +static void felem_neg(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add a multiple of p before subtracting. + * Use telescopic sums to represent 2^12 * p redundantly with each limb + * of the form 2^60 + ... + */ + static const limb two60m52m4 = (((limb) 1) << 60) + - (((limb) 1) << 52) + - (((limb) 1) << 4); + static const limb two60p44m12 = (((limb) 1) << 60) + + (((limb) 1) << 44) + - (((limb) 1) << 12); + static const limb two60m28m4 = (((limb) 1) << 60) + - (((limb) 1) << 28) + - (((limb) 1) << 4); + static const limb two60m4 = (((limb) 1) << 60) + - (((limb) 1) << 4); + + out[0] = two60p44m12 - in[0]; + out[1] = two60m52m4 - in[1]; + out[2] = two60m28m4 - in[2]; + out[3] = two60m4 - in[3]; + out[4] = two60m4 - in[4]; + out[5] = two60m4 - in[5]; + out[6] = two60m4 - in[6]; +} + +/*- + * felem_diff64 subtracts |in| from |out| + * On entry: + * in[i] < 2^60 - 2^52 - 2^4 + * On exit: + * out[i] < out_orig[i] + 2^60 + 2^44 + */ +static void felem_diff64(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add a multiple of p before subtracting. + * Use telescopic sums to represent 2^12 * p redundantly with each limb + * of the form 2^60 + ... + */ + + static const limb two60m52m4 = (((limb) 1) << 60) + - (((limb) 1) << 52) + - (((limb) 1) << 4); + static const limb two60p44m12 = (((limb) 1) << 60) + + (((limb) 1) << 44) + - (((limb) 1) << 12); + static const limb two60m28m4 = (((limb) 1) << 60) + - (((limb) 1) << 28) + - (((limb) 1) << 4); + static const limb two60m4 = (((limb) 1) << 60) + - (((limb) 1) << 4); + + out[0] += two60p44m12 - in[0]; + out[1] += two60m52m4 - in[1]; + out[2] += two60m28m4 - in[2]; + out[3] += two60m4 - in[3]; + out[4] += two60m4 - in[4]; + out[5] += two60m4 - in[5]; + out[6] += two60m4 - in[6]; +} + +/* + * in[i] < 2^63 + * out[i] < out_orig[i] + 2^64 + 2^48 + */ +static void felem_diff_128_64(widefelem out, const felem in) +{ + /* + * In order to prevent underflow, we add a multiple of p before subtracting. + * Use telescopic sums to represent 2^16 * p redundantly with each limb + * of the form 2^64 + ... + */ + + static const widelimb two64m56m8 = (((widelimb) 1) << 64) + - (((widelimb) 1) << 56) + - (((widelimb) 1) << 8); + static const widelimb two64m32m8 = (((widelimb) 1) << 64) + - (((widelimb) 1) << 32) + - (((widelimb) 1) << 8); + static const widelimb two64m8 = (((widelimb) 1) << 64) + - (((widelimb) 1) << 8); + static const widelimb two64p48m16 = (((widelimb) 1) << 64) + + (((widelimb) 1) << 48) + - (((widelimb) 1) << 16); + unsigned int i; + + out[0] += two64p48m16; + out[1] += two64m56m8; + out[2] += two64m32m8; + out[3] += two64m8; + out[4] += two64m8; + out[5] += two64m8; + out[6] += two64m8; + + for (i = 0; i < NLIMBS; i++) + out[i] -= in[i]; +} + +/* + * in[i] < 2^127 - 2^119 - 2^71 + * out[i] < out_orig[i] + 2^127 + 2^111 + */ +static void felem_diff128(widefelem out, const widefelem in) +{ + /* + * In order to prevent underflow, we add a multiple of p before subtracting. + * Use telescopic sums to represent 2^415 * p redundantly with each limb + * of the form 2^127 + ... + */ + + static const widelimb two127 = ((widelimb) 1) << 127; + static const widelimb two127m71 = (((widelimb) 1) << 127) + - (((widelimb) 1) << 71); + static const widelimb two127p111m79m71 = (((widelimb) 1) << 127) + + (((widelimb) 1) << 111) + - (((widelimb) 1) << 79) + - (((widelimb) 1) << 71); + static const widelimb two127m119m71 = (((widelimb) 1) << 127) + - (((widelimb) 1) << 119) + - (((widelimb) 1) << 71); + static const widelimb two127m95m71 = (((widelimb) 1) << 127) + - (((widelimb) 1) << 95) + - (((widelimb) 1) << 71); + unsigned int i; + + out[0] += two127; + out[1] += two127m71; + out[2] += two127m71; + out[3] += two127m71; + out[4] += two127m71; + out[5] += two127m71; + out[6] += two127p111m79m71; + out[7] += two127m119m71; + out[8] += two127m95m71; + out[9] += two127m71; + out[10] += two127m71; + out[11] += two127m71; + out[12] += two127m71; + + for (i = 0; i < 2*NLIMBS-1; i++) + out[i] -= in[i]; +} + +static void felem_square_ref(widefelem out, const felem in) +{ + felem inx2; + felem_scalar(inx2, in, 2); + + out[0] = ((uint128_t) in[0]) * in[0]; + + out[1] = ((uint128_t) in[0]) * inx2[1]; + + out[2] = ((uint128_t) in[0]) * inx2[2] + + ((uint128_t) in[1]) * in[1]; + + out[3] = ((uint128_t) in[0]) * inx2[3] + + ((uint128_t) in[1]) * inx2[2]; + + out[4] = ((uint128_t) in[0]) * inx2[4] + + ((uint128_t) in[1]) * inx2[3] + + ((uint128_t) in[2]) * in[2]; + + out[5] = ((uint128_t) in[0]) * inx2[5] + + ((uint128_t) in[1]) * inx2[4] + + ((uint128_t) in[2]) * inx2[3]; + + out[6] = ((uint128_t) in[0]) * inx2[6] + + ((uint128_t) in[1]) * inx2[5] + + ((uint128_t) in[2]) * inx2[4] + + ((uint128_t) in[3]) * in[3]; + + out[7] = ((uint128_t) in[1]) * inx2[6] + + ((uint128_t) in[2]) * inx2[5] + + ((uint128_t) in[3]) * inx2[4]; + + out[8] = ((uint128_t) in[2]) * inx2[6] + + ((uint128_t) in[3]) * inx2[5] + + ((uint128_t) in[4]) * in[4]; + + out[9] = ((uint128_t) in[3]) * inx2[6] + + ((uint128_t) in[4]) * inx2[5]; + + out[10] = ((uint128_t) in[4]) * inx2[6] + + ((uint128_t) in[5]) * in[5]; + + out[11] = ((uint128_t) in[5]) * inx2[6]; + + out[12] = ((uint128_t) in[6]) * in[6]; +} + +static void felem_mul_ref(widefelem out, const felem in1, const felem in2) +{ + out[0] = ((uint128_t) in1[0]) * in2[0]; + + out[1] = ((uint128_t) in1[0]) * in2[1] + + ((uint128_t) in1[1]) * in2[0]; + + out[2] = ((uint128_t) in1[0]) * in2[2] + + ((uint128_t) in1[1]) * in2[1] + + ((uint128_t) in1[2]) * in2[0]; + + out[3] = ((uint128_t) in1[0]) * in2[3] + + ((uint128_t) in1[1]) * in2[2] + + ((uint128_t) in1[2]) * in2[1] + + ((uint128_t) in1[3]) * in2[0]; + + out[4] = ((uint128_t) in1[0]) * in2[4] + + ((uint128_t) in1[1]) * in2[3] + + ((uint128_t) in1[2]) * in2[2] + + ((uint128_t) in1[3]) * in2[1] + + ((uint128_t) in1[4]) * in2[0]; + + out[5] = ((uint128_t) in1[0]) * in2[5] + + ((uint128_t) in1[1]) * in2[4] + + ((uint128_t) in1[2]) * in2[3] + + ((uint128_t) in1[3]) * in2[2] + + ((uint128_t) in1[4]) * in2[1] + + ((uint128_t) in1[5]) * in2[0]; + + out[6] = ((uint128_t) in1[0]) * in2[6] + + ((uint128_t) in1[1]) * in2[5] + + ((uint128_t) in1[2]) * in2[4] + + ((uint128_t) in1[3]) * in2[3] + + ((uint128_t) in1[4]) * in2[2] + + ((uint128_t) in1[5]) * in2[1] + + ((uint128_t) in1[6]) * in2[0]; + + out[7] = ((uint128_t) in1[1]) * in2[6] + + ((uint128_t) in1[2]) * in2[5] + + ((uint128_t) in1[3]) * in2[4] + + ((uint128_t) in1[4]) * in2[3] + + ((uint128_t) in1[5]) * in2[2] + + ((uint128_t) in1[6]) * in2[1]; + + out[8] = ((uint128_t) in1[2]) * in2[6] + + ((uint128_t) in1[3]) * in2[5] + + ((uint128_t) in1[4]) * in2[4] + + ((uint128_t) in1[5]) * in2[3] + + ((uint128_t) in1[6]) * in2[2]; + + out[9] = ((uint128_t) in1[3]) * in2[6] + + ((uint128_t) in1[4]) * in2[5] + + ((uint128_t) in1[5]) * in2[4] + + ((uint128_t) in1[6]) * in2[3]; + + out[10] = ((uint128_t) in1[4]) * in2[6] + + ((uint128_t) in1[5]) * in2[5] + + ((uint128_t) in1[6]) * in2[4]; + + out[11] = ((uint128_t) in1[5]) * in2[6] + + ((uint128_t) in1[6]) * in2[5]; + + out[12] = ((uint128_t) in1[6]) * in2[6]; +} + +/*- + * Reduce thirteen 128-bit coefficients to seven 64-bit coefficients. + * in[i] < 2^128 - 2^125 + * out[i] < 2^56 for i < 6, + * out[6] <= 2^48 + * + * The technique in use here stems from the format of the prime modulus: + * P384 = 2^384 - delta + * + * Thus we can reduce numbers of the form (X + 2^384 * Y) by substituting + * them with (X + delta Y), with delta = 2^128 + 2^96 + (-2^32 + 1). These + * coefficients are still quite large, and so we repeatedly apply this + * technique on high-order bits in order to guarantee the desired bounds on + * the size of our output. + * + * The three phases of elimination are as follows: + * [1]: Y = 2^120 (in[12] | in[11] | in[10] | in[9]) + * [2]: Y = 2^8 (acc[8] | acc[7]) + * [3]: Y = 2^48 (acc[6] >> 48) + * (Where a | b | c | d = (2^56)^3 a + (2^56)^2 b + (2^56) c + d) + */ +static void felem_reduce(felem out, const widefelem in) +{ + /* + * In order to prevent underflow, we add a multiple of p before subtracting. + * Use telescopic sums to represent 2^76 * p redundantly with each limb + * of the form 2^124 + ... + */ + static const widelimb two124m68 = (((widelimb) 1) << 124) + - (((widelimb) 1) << 68); + static const widelimb two124m116m68 = (((widelimb) 1) << 124) + - (((widelimb) 1) << 116) + - (((widelimb) 1) << 68); + static const widelimb two124p108m76 = (((widelimb) 1) << 124) + + (((widelimb) 1) << 108) + - (((widelimb) 1) << 76); + static const widelimb two124m92m68 = (((widelimb) 1) << 124) + - (((widelimb) 1) << 92) + - (((widelimb) 1) << 68); + widelimb temp, acc[9]; + unsigned int i; + + memcpy(acc, in, sizeof(widelimb) * 9); + + acc[0] += two124p108m76; + acc[1] += two124m116m68; + acc[2] += two124m92m68; + acc[3] += two124m68; + acc[4] += two124m68; + acc[5] += two124m68; + acc[6] += two124m68; + + /* [1]: Eliminate in[9], ..., in[12] */ + acc[8] += in[12] >> 32; + acc[7] += (in[12] & 0xffffffff) << 24; + acc[7] += in[12] >> 8; + acc[6] += (in[12] & 0xff) << 48; + acc[6] -= in[12] >> 16; + acc[5] -= (in[12] & 0xffff) << 40; + acc[6] += in[12] >> 48; + acc[5] += (in[12] & 0xffffffffffff) << 8; + + acc[7] += in[11] >> 32; + acc[6] += (in[11] & 0xffffffff) << 24; + acc[6] += in[11] >> 8; + acc[5] += (in[11] & 0xff) << 48; + acc[5] -= in[11] >> 16; + acc[4] -= (in[11] & 0xffff) << 40; + acc[5] += in[11] >> 48; + acc[4] += (in[11] & 0xffffffffffff) << 8; + + acc[6] += in[10] >> 32; + acc[5] += (in[10] & 0xffffffff) << 24; + acc[5] += in[10] >> 8; + acc[4] += (in[10] & 0xff) << 48; + acc[4] -= in[10] >> 16; + acc[3] -= (in[10] & 0xffff) << 40; + acc[4] += in[10] >> 48; + acc[3] += (in[10] & 0xffffffffffff) << 8; + + acc[5] += in[9] >> 32; + acc[4] += (in[9] & 0xffffffff) << 24; + acc[4] += in[9] >> 8; + acc[3] += (in[9] & 0xff) << 48; + acc[3] -= in[9] >> 16; + acc[2] -= (in[9] & 0xffff) << 40; + acc[3] += in[9] >> 48; + acc[2] += (in[9] & 0xffffffffffff) << 8; + + /* + * [2]: Eliminate acc[7], acc[8], that is the 7 and eighth limbs, as + * well as the contributions made from eliminating higher limbs. + * acc[7] < in[7] + 2^120 + 2^56 < in[7] + 2^121 + * acc[8] < in[8] + 2^96 + */ + acc[4] += acc[8] >> 32; + acc[3] += (acc[8] & 0xffffffff) << 24; + acc[3] += acc[8] >> 8; + acc[2] += (acc[8] & 0xff) << 48; + acc[2] -= acc[8] >> 16; + acc[1] -= (acc[8] & 0xffff) << 40; + acc[2] += acc[8] >> 48; + acc[1] += (acc[8] & 0xffffffffffff) << 8; + + acc[3] += acc[7] >> 32; + acc[2] += (acc[7] & 0xffffffff) << 24; + acc[2] += acc[7] >> 8; + acc[1] += (acc[7] & 0xff) << 48; + acc[1] -= acc[7] >> 16; + acc[0] -= (acc[7] & 0xffff) << 40; + acc[1] += acc[7] >> 48; + acc[0] += (acc[7] & 0xffffffffffff) << 8; + + /*- + * acc[k] < in[k] + 2^124 + 2^121 + * < in[k] + 2^125 + * < 2^128, for k <= 6 + */ + + /* + * Carry 4 -> 5 -> 6 + * This has the effect of ensuring that these more significant limbs + * will be small in value after eliminating high bits from acc[6]. + */ + acc[5] += acc[4] >> 56; + acc[4] &= 0x00ffffffffffffff; + + acc[6] += acc[5] >> 56; + acc[5] &= 0x00ffffffffffffff; + + /*- + * acc[6] < in[6] + 2^124 + 2^121 + 2^72 + 2^16 + * < in[6] + 2^125 + * < 2^128 + */ + + /* [3]: Eliminate high bits of acc[6] */ + temp = acc[6] >> 48; + acc[6] &= 0x0000ffffffffffff; + + /* temp < 2^80 */ + + acc[3] += temp >> 40; + acc[2] += (temp & 0xffffffffff) << 16; + acc[2] += temp >> 16; + acc[1] += (temp & 0xffff) << 40; + acc[1] -= temp >> 24; + acc[0] -= (temp & 0xffffff) << 32; + acc[0] += temp; + + /*- + * acc[k] < acc_old[k] + 2^64 + 2^56 + * < in[k] + 2^124 + 2^121 + 2^72 + 2^64 + 2^56 + 2^16 , k < 4 + */ + + /* Carry 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 */ + acc[1] += acc[0] >> 56; /* acc[1] < acc_old[1] + 2^72 */ + acc[0] &= 0x00ffffffffffffff; + + acc[2] += acc[1] >> 56; /* acc[2] < acc_old[2] + 2^72 + 2^16 */ + acc[1] &= 0x00ffffffffffffff; + + acc[3] += acc[2] >> 56; /* acc[3] < acc_old[3] + 2^72 + 2^16 */ + acc[2] &= 0x00ffffffffffffff; + + /*- + * acc[k] < acc_old[k] + 2^72 + 2^16 + * < in[k] + 2^124 + 2^121 + 2^73 + 2^64 + 2^56 + 2^17 + * < in[k] + 2^125 + * < 2^128 , k < 4 + */ + + acc[4] += acc[3] >> 56; /*- + * acc[4] < acc_old[4] + 2^72 + 2^16 + * < 2^72 + 2^56 + 2^16 + */ + acc[3] &= 0x00ffffffffffffff; + + acc[5] += acc[4] >> 56; /*- + * acc[5] < acc_old[5] + 2^16 + 1 + * < 2^56 + 2^16 + 1 + */ + acc[4] &= 0x00ffffffffffffff; + + acc[6] += acc[5] >> 56; /* acc[6] < 2^48 + 1 <= 2^48 */ + acc[5] &= 0x00ffffffffffffff; + + for (i = 0; i < NLIMBS; i++) + out[i] = acc[i]; +} + +#if defined(ECP_NISTP384_ASM) +static void felem_square_wrapper(widefelem out, const felem in); +static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2); + +static void (*felem_square_p)(widefelem out, const felem in) = + felem_square_wrapper; +static void (*felem_mul_p)(widefelem out, const felem in1, const felem in2) = + felem_mul_wrapper; + +void p384_felem_square(widefelem out, const felem in); +void p384_felem_mul(widefelem out, const felem in1, const felem in2); + +# if defined(_ARCH_PPC64) +# include "crypto/ppc_arch.h" +# endif + +static void felem_select(void) +{ +# if defined(_ARCH_PPC64) + if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) { + felem_square_p = p384_felem_square; + felem_mul_p = p384_felem_mul; + + return; + } +# endif + + /* Default */ + felem_square_p = felem_square_ref; + felem_mul_p = felem_mul_ref; +} + +static void felem_square_wrapper(widefelem out, const felem in) +{ + felem_select(); + felem_square_p(out, in); +} + +static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2) +{ + felem_select(); + felem_mul_p(out, in1, in2); +} + +# define felem_square felem_square_p +# define felem_mul felem_mul_p +#else +# define felem_square felem_square_ref +# define felem_mul felem_mul_ref +#endif + +static ossl_inline void felem_square_reduce(felem out, const felem in) +{ + widefelem tmp; + + felem_square(tmp, in); + felem_reduce(out, tmp); +} + +static ossl_inline void felem_mul_reduce(felem out, const felem in1, const felem in2) +{ + widefelem tmp; + + felem_mul(tmp, in1, in2); + felem_reduce(out, tmp); +} + +/*- + * felem_inv calculates |out| = |in|^{-1} + * + * Based on Fermat's Little Theorem: + * a^p = a (mod p) + * a^{p-1} = 1 (mod p) + * a^{p-2} = a^{-1} (mod p) + */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6; + unsigned int i = 0; + + felem_square_reduce(ftmp, in); /* 2^1 */ + felem_mul_reduce(ftmp, ftmp, in); /* 2^1 + 2^0 */ + felem_assign(ftmp2, ftmp); + + felem_square_reduce(ftmp, ftmp); /* 2^2 + 2^1 */ + felem_mul_reduce(ftmp, ftmp, in); /* 2^2 + 2^1 * 2^0 */ + felem_assign(ftmp3, ftmp); + + for (i = 0; i < 3; i++) + felem_square_reduce(ftmp, ftmp); /* 2^5 + 2^4 + 2^3 */ + felem_mul_reduce(ftmp, ftmp3, ftmp); /* 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 */ + felem_assign(ftmp4, ftmp); + + for (i = 0; i < 6; i++) + felem_square_reduce(ftmp, ftmp); /* 2^11 + ... + 2^6 */ + felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^11 + ... + 2^0 */ + + for (i = 0; i < 3; i++) + felem_square_reduce(ftmp, ftmp); /* 2^14 + ... + 2^3 */ + felem_mul_reduce(ftmp, ftmp3, ftmp); /* 2^14 + ... + 2^0 */ + felem_assign(ftmp5, ftmp); + + for (i = 0; i < 15; i++) + felem_square_reduce(ftmp, ftmp); /* 2^29 + ... + 2^15 */ + felem_mul_reduce(ftmp, ftmp5, ftmp); /* 2^29 + ... + 2^0 */ + felem_assign(ftmp6, ftmp); + + for (i = 0; i < 30; i++) + felem_square_reduce(ftmp, ftmp); /* 2^59 + ... + 2^30 */ + felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^59 + ... + 2^0 */ + felem_assign(ftmp4, ftmp); + + for (i = 0; i < 60; i++) + felem_square_reduce(ftmp, ftmp); /* 2^119 + ... + 2^60 */ + felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^119 + ... + 2^0 */ + felem_assign(ftmp4, ftmp); + + for (i = 0; i < 120; i++) + felem_square_reduce(ftmp, ftmp); /* 2^239 + ... + 2^120 */ + felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^239 + ... + 2^0 */ + + for (i = 0; i < 15; i++) + felem_square_reduce(ftmp, ftmp); /* 2^254 + ... + 2^15 */ + felem_mul_reduce(ftmp, ftmp5, ftmp); /* 2^254 + ... + 2^0 */ + + for (i = 0; i < 31; i++) + felem_square_reduce(ftmp, ftmp); /* 2^285 + ... + 2^31 */ + felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^285 + ... + 2^31 + 2^29 + ... + 2^0 */ + + for (i = 0; i < 2; i++) + felem_square_reduce(ftmp, ftmp); /* 2^287 + ... + 2^33 + 2^31 + ... + 2^2 */ + felem_mul_reduce(ftmp, ftmp2, ftmp); /* 2^287 + ... + 2^33 + 2^31 + ... + 2^0 */ + + for (i = 0; i < 94; i++) + felem_square_reduce(ftmp, ftmp); /* 2^381 + ... + 2^127 + 2^125 + ... + 2^94 */ + felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^381 + ... + 2^127 + 2^125 + ... + 2^94 + 2^29 + ... + 2^0 */ + + for (i = 0; i < 2; i++) + felem_square_reduce(ftmp, ftmp); /* 2^383 + ... + 2^129 + 2^127 + ... + 2^96 + 2^31 + ... + 2^2 */ + felem_mul_reduce(ftmp, in, ftmp); /* 2^383 + ... + 2^129 + 2^127 + ... + 2^96 + 2^31 + ... + 2^2 + 2^0 */ + + memcpy(out, ftmp, sizeof(felem)); +} + +/* + * Zero-check: returns a limb with all bits set if |in| == 0 (mod p) + * and 0 otherwise. We know that field elements are reduced to + * 0 < in < 2p, so we only need to check two cases: + * 0 and 2^384 - 2^128 - 2^96 + 2^32 - 1 + * in[k] < 2^56, k < 6 + * in[6] <= 2^48 + */ +static limb felem_is_zero(const felem in) +{ + limb zero, p384; + + zero = in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6]; + zero = ((int64_t) (zero) - 1) >> 63; + p384 = (in[0] ^ 0x000000ffffffff) | (in[1] ^ 0xffff0000000000) + | (in[2] ^ 0xfffffffffeffff) | (in[3] ^ 0xffffffffffffff) + | (in[4] ^ 0xffffffffffffff) | (in[5] ^ 0xffffffffffffff) + | (in[6] ^ 0xffffffffffff); + p384 = ((int64_t) (p384) - 1) >> 63; + + return (zero | p384); +} + +static int felem_is_zero_int(const void *in) +{ + return (int)(felem_is_zero(in) & ((limb) 1)); +} + +/*- + * felem_contract converts |in| to its unique, minimal representation. + * Assume we've removed all redundant bits. + * On entry: + * in[k] < 2^56, k < 6 + * in[6] <= 2^48 + */ +static void felem_contract(felem out, const felem in) +{ + static const int64_t two56 = ((limb) 1) << 56; + + /* + * We know for a fact that 0 <= |in| < 2*p, for p = 2^384 - 2^128 - 2^96 + 2^32 - 1 + * Perform two successive, idempotent subtractions to reduce if |in| >= p. + */ + + int64_t tmp[NLIMBS], cond[5], a; + unsigned int i; + + memcpy(tmp, in, sizeof(felem)); + + /* Case 1: a = 1 iff |in| >= 2^384 */ + a = (in[6] >> 48); + tmp[0] += a; + tmp[0] -= a << 32; + tmp[1] += a << 40; + tmp[2] += a << 16; + tmp[6] &= 0x0000ffffffffffff; + + /* + * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be + * non-zero, so we only need one step + */ + + a = tmp[0] >> 63; + tmp[0] += a & two56; + tmp[1] -= a & 1; + + /* Carry 1 -> 2 -> 3 -> 4 -> 5 -> 6 */ + tmp[2] += tmp[1] >> 56; + tmp[1] &= 0x00ffffffffffffff; + + tmp[3] += tmp[2] >> 56; + tmp[2] &= 0x00ffffffffffffff; + + tmp[4] += tmp[3] >> 56; + tmp[3] &= 0x00ffffffffffffff; + + tmp[5] += tmp[4] >> 56; + tmp[4] &= 0x00ffffffffffffff; + + tmp[6] += tmp[5] >> 56; /* tmp[6] < 2^48 */ + tmp[5] &= 0x00ffffffffffffff; + + /* + * Case 2: a = all ones if p <= |in| < 2^384, 0 otherwise + */ + + /* 0 iff (2^129..2^383) are all one */ + cond[0] = ((tmp[6] | 0xff000000000000) & tmp[5] & tmp[4] & tmp[3] & (tmp[2] | 0x0000000001ffff)) + 1; + /* 0 iff 2^128 bit is one */ + cond[1] = (tmp[2] | ~0x00000000010000) + 1; + /* 0 iff (2^96..2^127) bits are all one */ + cond[2] = ((tmp[2] | 0xffffffffff0000) & (tmp[1] | 0x0000ffffffffff)) + 1; + /* 0 iff (2^32..2^95) bits are all zero */ + cond[3] = (tmp[1] & ~0xffff0000000000) | (tmp[0] & ~((int64_t) 0x000000ffffffff)); + /* 0 iff (2^0..2^31) bits are all one */ + cond[4] = (tmp[0] | 0xffffff00000000) + 1; + + /* + * In effect, invert our conditions, so that 0 values become all 1's, + * any non-zero value in the low-order 56 bits becomes all 0's + */ + for (i = 0; i < 5; i++) + cond[i] = ((cond[i] & 0x00ffffffffffffff) - 1) >> 63; + + /* + * The condition for determining whether in is greater than our + * prime is given by the following condition. + */ + + /* First subtract 2^384 - 2^129 cheaply */ + a = cond[0] & (cond[1] | (cond[2] & (~cond[3] | cond[4]))); + tmp[6] &= ~a; + tmp[5] &= ~a; + tmp[4] &= ~a; + tmp[3] &= ~a; + tmp[2] &= ~a | 0x0000000001ffff; + + /* + * Subtract 2^128 - 2^96 by + * means of disjoint cases. + */ + + /* subtract 2^128 if that bit is present, and add 2^96 */ + a = cond[0] & cond[1]; + tmp[2] &= ~a | 0xfffffffffeffff; + tmp[1] += a & ((int64_t) 1 << 40); + + /* otherwise, clear bits 2^127 .. 2^96 */ + a = cond[0] & ~cond[1] & (cond[2] & (~cond[3] | cond[4])); + tmp[2] &= ~a | 0xffffffffff0000; + tmp[1] &= ~a | 0x0000ffffffffff; + + /* finally, subtract the last 2^32 - 1 */ + a = cond[0] & (cond[1] | (cond[2] & (~cond[3] | cond[4]))); + tmp[0] += a & (-((int64_t) 1 << 32) + 1); + + /* + * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be + * non-zero, so we only need one step + */ + a = tmp[0] >> 63; + tmp[0] += a & two56; + tmp[1] -= a & 1; + + /* Carry 1 -> 2 -> 3 -> 4 -> 5 -> 6 */ + tmp[2] += tmp[1] >> 56; + tmp[1] &= 0x00ffffffffffffff; + + tmp[3] += tmp[2] >> 56; + tmp[2] &= 0x00ffffffffffffff; + + tmp[4] += tmp[3] >> 56; + tmp[3] &= 0x00ffffffffffffff; + + tmp[5] += tmp[4] >> 56; + tmp[4] &= 0x00ffffffffffffff; + + tmp[6] += tmp[5] >> 56; + tmp[5] &= 0x00ffffffffffffff; + + memcpy(out, tmp, sizeof(felem)); +} + +/*- + * Group operations + * ---------------- + * + * Building on top of the field operations we have the operations on the + * elliptic curve group itself. Points on the curve are represented in Jacobian + * coordinates + */ + +/*- + * point_double calculates 2*(x_in, y_in, z_in) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. + * while x_out == y_in is not (maybe this works, but it's not tested). + */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + widefelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + + felem_assign(ftmp, x_in); + felem_assign(ftmp2, x_in); + + /* delta = z^2 */ + felem_square_reduce(delta, z_in); /* delta[i] < 2^56 */ + + /* gamma = y^2 */ + felem_square_reduce(gamma, y_in); /* gamma[i] < 2^56 */ + + /* beta = x*gamma */ + felem_mul_reduce(beta, x_in, gamma); /* beta[i] < 2^56 */ + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff64(ftmp, delta); /* ftmp[i] < 2^60 + 2^58 + 2^44 */ + felem_sum64(ftmp2, delta); /* ftmp2[i] < 2^59 */ + felem_scalar64(ftmp2, 3); /* ftmp2[i] < 2^61 */ + felem_mul_reduce(alpha, ftmp, ftmp2); /* alpha[i] < 2^56 */ + + /* x' = alpha^2 - 8*beta */ + felem_square(tmp, alpha); /* tmp[i] < 2^115 */ + felem_assign(ftmp, beta); /* ftmp[i] < 2^56 */ + felem_scalar64(ftmp, 8); /* ftmp[i] < 2^59 */ + felem_diff_128_64(tmp, ftmp); /* tmp[i] < 2^115 + 2^64 + 2^48 */ + felem_reduce(x_out, tmp); /* x_out[i] < 2^56 */ + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum64(delta, gamma); /* delta[i] < 2^57 */ + felem_assign(ftmp, y_in); /* ftmp[i] < 2^56 */ + felem_sum64(ftmp, z_in); /* ftmp[i] < 2^56 */ + felem_square(tmp, ftmp); /* tmp[i] < 2^115 */ + felem_diff_128_64(tmp, delta); /* tmp[i] < 2^115 + 2^64 + 2^48 */ + felem_reduce(z_out, tmp); /* z_out[i] < 2^56 */ + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar64(beta, 4); /* beta[i] < 2^58 */ + felem_diff64(beta, x_out); /* beta[i] < 2^60 + 2^58 + 2^44 */ + felem_mul(tmp, alpha, beta); /* tmp[i] < 2^119 */ + felem_square(tmp2, gamma); /* tmp2[i] < 2^115 */ + felem_scalar128(tmp2, 8); /* tmp2[i] < 2^118 */ + felem_diff128(tmp, tmp2); /* tmp[i] < 2^127 + 2^119 + 2^111 */ + felem_reduce(y_out, tmp); /* tmp[i] < 2^56 */ +} + +/* copy_conditional copies in to out iff mask is all ones. */ +static void copy_conditional(felem out, const felem in, limb mask) +{ + unsigned int i; + + for (i = 0; i < NLIMBS; i++) + out[i] ^= mask & (in[i] ^ out[i]); +} + +/*- + * point_add calculates (x1, y1, z1) + (x2, y2, z2) + * + * The method is taken from + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). + * + * This function includes a branch for checking whether the two input points + * are equal (while not equal to the point at infinity). See comment below + * on constant-time. + */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const felem x2, const felem y2, + const felem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; + widefelem tmp, tmp2; + limb x_equal, y_equal, z1_is_zero, z2_is_zero; + limb points_equal; + + z1_is_zero = felem_is_zero(z1); + z2_is_zero = felem_is_zero(z2); + + /* ftmp = z1z1 = z1**2 */ + felem_square_reduce(ftmp, z1); /* ftmp[i] < 2^56 */ + + if (!mixed) { + /* ftmp2 = z2z2 = z2**2 */ + felem_square_reduce(ftmp2, z2); /* ftmp2[i] < 2^56 */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_mul_reduce(ftmp3, x1, ftmp2); /* ftmp3[i] < 2^56 */ + + /* ftmp5 = z1 + z2 */ + felem_assign(ftmp5, z1); /* ftmp5[i] < 2^56 */ + felem_sum64(ftmp5, z2); /* ftmp5[i] < 2^57 */ + + /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */ + felem_square(tmp, ftmp5); /* tmp[i] < 2^117 */ + felem_diff_128_64(tmp, ftmp); /* tmp[i] < 2^117 + 2^64 + 2^48 */ + felem_diff_128_64(tmp, ftmp2); /* tmp[i] < 2^117 + 2^65 + 2^49 */ + felem_reduce(ftmp5, tmp); /* ftmp5[i] < 2^56 */ + + /* ftmp2 = z2 * z2z2 */ + felem_mul_reduce(ftmp2, ftmp2, z2); /* ftmp2[i] < 2^56 */ + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_mul_reduce(ftmp6, y1, ftmp2); /* ftmp6[i] < 2^56 */ + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_assign(ftmp3, x1); /* ftmp3[i] < 2^56 */ + + /* ftmp5 = 2*z1z2 */ + felem_scalar(ftmp5, z1, 2); /* ftmp5[i] < 2^57 */ + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_assign(ftmp6, y1); /* ftmp6[i] < 2^56 */ + } + /* ftmp3[i] < 2^56, ftmp5[i] < 2^57, ftmp6[i] < 2^56 */ + + /* u2 = x2*z1z1 */ + felem_mul(tmp, x2, ftmp); /* tmp[i] < 2^115 */ + + /* h = ftmp4 = u2 - u1 */ + felem_diff_128_64(tmp, ftmp3); /* tmp[i] < 2^115 + 2^64 + 2^48 */ + felem_reduce(ftmp4, tmp); /* ftmp[4] < 2^56 */ + + x_equal = felem_is_zero(ftmp4); + + /* z_out = ftmp5 * h */ + felem_mul_reduce(z_out, ftmp5, ftmp4); /* z_out[i] < 2^56 */ + + /* ftmp = z1 * z1z1 */ + felem_mul_reduce(ftmp, ftmp, z1); /* ftmp[i] < 2^56 */ + + /* s2 = tmp = y2 * z1**3 */ + felem_mul(tmp, y2, ftmp); /* tmp[i] < 2^115 */ + + /* r = ftmp5 = (s2 - s1)*2 */ + felem_diff_128_64(tmp, ftmp6); /* tmp[i] < 2^115 + 2^64 + 2^48 */ + felem_reduce(ftmp5, tmp); /* ftmp5[i] < 2^56 */ + y_equal = felem_is_zero(ftmp5); + felem_scalar64(ftmp5, 2); /* ftmp5[i] < 2^57 */ + + /* + * The formulae are incorrect if the points are equal, in affine coordinates + * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this + * happens. + * + * We use bitwise operations to avoid potential side-channels introduced by + * the short-circuiting behaviour of boolean operators. + * + * The special case of either point being the point at infinity (z1 and/or + * z2 are zero), is handled separately later on in this function, so we + * avoid jumping to point_double here in those special cases. + * + * Notice the comment below on the implications of this branching for timing + * leaks and why it is considered practically irrelevant. + */ + points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)); + + if (points_equal) { + /* + * This is obviously not constant-time but it will almost-never happen + * for ECDH / ECDSA. + */ + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* I = ftmp = (2h)**2 */ + felem_assign(ftmp, ftmp4); /* ftmp[i] < 2^56 */ + felem_scalar64(ftmp, 2); /* ftmp[i] < 2^57 */ + felem_square_reduce(ftmp, ftmp); /* ftmp[i] < 2^56 */ + + /* J = ftmp2 = h * I */ + felem_mul_reduce(ftmp2, ftmp4, ftmp); /* ftmp2[i] < 2^56 */ + + /* V = ftmp4 = U1 * I */ + felem_mul_reduce(ftmp4, ftmp3, ftmp); /* ftmp4[i] < 2^56 */ + + /* x_out = r**2 - J - 2V */ + felem_square(tmp, ftmp5); /* tmp[i] < 2^117 */ + felem_diff_128_64(tmp, ftmp2); /* tmp[i] < 2^117 + 2^64 + 2^48 */ + felem_assign(ftmp3, ftmp4); /* ftmp3[i] < 2^56 */ + felem_scalar64(ftmp4, 2); /* ftmp4[i] < 2^57 */ + felem_diff_128_64(tmp, ftmp4); /* tmp[i] < 2^117 + 2^65 + 2^49 */ + felem_reduce(x_out, tmp); /* x_out[i] < 2^56 */ + + /* y_out = r(V-x_out) - 2 * s1 * J */ + felem_diff64(ftmp3, x_out); /* ftmp3[i] < 2^60 + 2^56 + 2^44 */ + felem_mul(tmp, ftmp5, ftmp3); /* tmp[i] < 2^116 */ + felem_mul(tmp2, ftmp6, ftmp2); /* tmp2[i] < 2^115 */ + felem_scalar128(tmp2, 2); /* tmp2[i] < 2^116 */ + felem_diff128(tmp, tmp2); /* tmp[i] < 2^127 + 2^116 + 2^111 */ + felem_reduce(y_out, tmp); /* y_out[i] < 2^56 */ + + copy_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/*- + * Base point pre computation + * -------------------------- + * + * Two different sorts of precomputed tables are used in the following code. + * Each contain various points on the curve, where each point is three field + * elements (x, y, z). + * + * For the base point table, z is usually 1 (0 for the point at infinity). + * This table has 16 elements: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^95G + * 3 | 0 0 1 1 | (2^95 + 1)G + * 4 | 0 1 0 0 | 2^190G + * 5 | 0 1 0 1 | (2^190 + 1)G + * 6 | 0 1 1 0 | (2^190 + 2^95)G + * 7 | 0 1 1 1 | (2^190 + 2^95 + 1)G + * 8 | 1 0 0 0 | 2^285G + * 9 | 1 0 0 1 | (2^285 + 1)G + * 10 | 1 0 1 0 | (2^285 + 2^95)G + * 11 | 1 0 1 1 | (2^285 + 2^95 + 1)G + * 12 | 1 1 0 0 | (2^285 + 2^190)G + * 13 | 1 1 0 1 | (2^285 + 2^190 + 1)G + * 14 | 1 1 1 0 | (2^285 + 2^190 + 2^95)G + * 15 | 1 1 1 1 | (2^285 + 2^190 + 2^95 + 1)G + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point. + * + * Tables for other points have table[i] = iG for i in 0 .. 16. + */ + +/* gmul is the table of precomputed base points */ +static const felem gmul[16][3] = { +{{0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0}}, +{{0x00545e3872760ab7, 0x00f25dbf55296c3a, 0x00e082542a385502, 0x008ba79b9859f741, + 0x0020ad746e1d3b62, 0x0005378eb1c71ef3, 0x0000aa87ca22be8b}, + {0x00431d7c90ea0e5f, 0x00b1ce1d7e819d7a, 0x0013b5f0b8c00a60, 0x00289a147ce9da31, + 0x0092dc29f8f41dbd, 0x002c6f5d9e98bf92, 0x00003617de4a9626}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00024711cc902a90, 0x00acb2e579ab4fe1, 0x00af818a4b4d57b1, 0x00a17c7bec49c3de, + 0x004280482d726a8b, 0x00128dd0f0a90f3b, 0x00004387c1c3fa3c}, + {0x002ce76543cf5c3a, 0x00de6cee5ef58f0a, 0x00403e42fa561ca6, 0x00bc54d6f9cb9731, + 0x007155f925fb4ff1, 0x004a9ce731b7b9bc, 0x00002609076bd7b2}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00e74c9182f0251d, 0x0039bf54bb111974, 0x00b9d2f2eec511d2, 0x0036b1594eb3a6a4, + 0x00ac3bb82d9d564b, 0x00f9313f4615a100, 0x00006716a9a91b10}, + {0x0046698116e2f15c, 0x00f34347067d3d33, 0x008de4ccfdebd002, 0x00e838c6b8e8c97b, + 0x006faf0798def346, 0x007349794a57563c, 0x00002629e7e6ad84}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x0075300e34fd163b, 0x0092e9db4e8d0ad3, 0x00254be9f625f760, 0x00512c518c72ae68, + 0x009bfcf162bede5a, 0x00bf9341566ce311, 0x0000cd6175bd41cf}, + {0x007dfe52af4ac70f, 0x0002159d2d5c4880, 0x00b504d16f0af8d0, 0x0014585e11f5e64c, + 0x0089c6388e030967, 0x00ffb270cbfa5f71, 0x00009a15d92c3947}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x0033fc1278dc4fe5, 0x00d53088c2caa043, 0x0085558827e2db66, 0x00c192bef387b736, + 0x00df6405a2225f2c, 0x0075205aa90fd91a, 0x0000137e3f12349d}, + {0x00ce5b115efcb07e, 0x00abc3308410deeb, 0x005dc6fc1de39904, 0x00907c1c496f36b4, + 0x0008e6ad3926cbe1, 0x00110747b787928c, 0x0000021b9162eb7e}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x008180042cfa26e1, 0x007b826a96254967, 0x0082473694d6b194, 0x007bd6880a45b589, + 0x00c0a5097072d1a3, 0x0019186555e18b4e, 0x000020278190e5ca}, + {0x00b4bef17de61ac0, 0x009535e3c38ed348, 0x002d4aa8e468ceab, 0x00ef40b431036ad3, + 0x00defd52f4542857, 0x0086edbf98234266, 0x00002025b3a7814d}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00b238aa97b886be, 0x00ef3192d6dd3a32, 0x0079f9e01fd62df8, 0x00742e890daba6c5, + 0x008e5289144408ce, 0x0073bbcc8e0171a5, 0x0000c4fd329d3b52}, + {0x00c6f64a15ee23e7, 0x00dcfb7b171cad8b, 0x00039f6cbd805867, 0x00de024e428d4562, + 0x00be6a594d7c64c5, 0x0078467b70dbcd64, 0x0000251f2ed7079b}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x000e5cc25fc4b872, 0x005ebf10d31ef4e1, 0x0061e0ebd11e8256, 0x0076e026096f5a27, + 0x0013e6fc44662e9a, 0x0042b00289d3597e, 0x000024f089170d88}, + {0x001604d7e0effbe6, 0x0048d77cba64ec2c, 0x008166b16da19e36, 0x006b0d1a0f28c088, + 0x000259fcd47754fd, 0x00cc643e4d725f9a, 0x00007b10f3c79c14}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00430155e3b908af, 0x00b801e4fec25226, 0x00b0d4bcfe806d26, 0x009fc4014eb13d37, + 0x0066c94e44ec07e8, 0x00d16adc03874ba2, 0x000030c917a0d2a7}, + {0x00edac9e21eb891c, 0x00ef0fb768102eff, 0x00c088cef272a5f3, 0x00cbf782134e2964, + 0x0001044a7ba9a0e3, 0x00e363f5b194cf3c, 0x00009ce85249e372}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x001dd492dda5a7eb, 0x008fd577be539fd1, 0x002ff4b25a5fc3f1, 0x0074a8a1b64df72f, + 0x002ba3d8c204a76c, 0x009d5cff95c8235a, 0x0000e014b9406e0f}, + {0x008c2e4dbfc98aba, 0x00f30bb89f1a1436, 0x00b46f7aea3e259c, 0x009224454ac02f54, + 0x00906401f5645fa2, 0x003a1d1940eabc77, 0x00007c9351d680e6}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x005a35d872ef967c, 0x0049f1b7884e1987, 0x0059d46d7e31f552, 0x00ceb4869d2d0fb6, + 0x00e8e89eee56802a, 0x0049d806a774aaf2, 0x0000147e2af0ae24}, + {0x005fd1bd852c6e5e, 0x00b674b7b3de6885, 0x003b9ea5eb9b6c08, 0x005c9f03babf3ef7, + 0x00605337fecab3c7, 0x009a3f85b11bbcc8, 0x0000455470f330ec}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x002197ff4d55498d, 0x00383e8916c2d8af, 0x00eb203f34d1c6d2, 0x0080367cbd11b542, + 0x00769b3be864e4f5, 0x0081a8458521c7bb, 0x0000c531b34d3539}, + {0x00e2a3d775fa2e13, 0x00534fc379573844, 0x00ff237d2a8db54a, 0x00d301b2335a8882, + 0x000f75ea96103a80, 0x0018fecb3cdd96fa, 0x0000304bf61e94eb}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00b2afc332a73dbd, 0x0029a0d5bb007bc5, 0x002d628eb210f577, 0x009f59a36dd05f50, + 0x006d339de4eca613, 0x00c75a71addc86bc, 0x000060384c5ea93c}, + {0x00aa9641c32a30b4, 0x00cc73ae8cce565d, 0x00ec911a4df07f61, 0x00aa4b762ea4b264, + 0x0096d395bb393629, 0x004efacfb7632fe0, 0x00006f252f46fa3f}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00567eec597c7af6, 0x0059ba6795204413, 0x00816d4e6f01196f, 0x004ae6b3eb57951d, + 0x00420f5abdda2108, 0x003401d1f57ca9d9, 0x0000cf5837b0b67a}, + {0x00eaa64b8aeeabf9, 0x00246ddf16bcb4de, 0x000e7e3c3aecd751, 0x0008449f04fed72e, + 0x00307b67ccf09183, 0x0017108c3556b7b1, 0x0000229b2483b3bf}, + {1, 0, 0, 0, 0, 0, 0}}, +{{0x00e7c491a7bb78a1, 0x00eafddd1d3049ab, 0x00352c05e2bc7c98, 0x003d6880c165fa5c, + 0x00b6ac61cc11c97d, 0x00beeb54fcf90ce5, 0x0000dc1f0b455edc}, + {0x002db2e7aee34d60, 0x0073b5f415a2d8c0, 0x00dd84e4193e9a0c, 0x00d02d873467c572, + 0x0018baaeda60aee5, 0x0013fb11d697c61e, 0x000083aafcc3a973}, + {1, 0, 0, 0, 0, 0, 0}} +}; + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + * + * pre_comp below is of the size provided in |size|. + */ +static void select_point(const limb idx, unsigned int size, + const felem pre_comp[][3], felem out[3]) +{ + unsigned int i, j; + limb *outlimbs = &out[0][0]; + + memset(out, 0, sizeof(*out) * 3); + + for (i = 0; i < size; i++) { + const limb *inlimbs = &pre_comp[i][0][0]; + limb mask = i ^ idx; + + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < NLIMBS * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, int i) +{ + if (i < 0 || i >= 384) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned int num_points, const u8 *g_scalar, + const int mixed, const felem pre_comp[][17][3], + const felem g_pre_comp[16][3]) +{ + int i, skip; + unsigned int num, gen_mul = (g_scalar != NULL); + felem nq[3], tmp[4]; + limb bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, sizeof(nq)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (last quarter of rounds) and additions of other + * points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 380 : 98); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 98)) { + bits = get_bit(g_scalar, i + 285) << 3; + if (i < 95) { + bits |= get_bit(g_scalar, i + 190) << 2; + bits |= get_bit(g_scalar, i + 95) << 1; + bits |= get_bit(g_scalar, i); + } + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp, tmp); + if (!skip) { + /* The 1 argument below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, + tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* + * select the point to add or subtract, in constant time + */ + select_point(digit, 17, pre_comp[num], tmp); + felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_conditional(tmp[1], tmp[3], (-(limb) sign)); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], mixed, + tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/* Precomputation for the group generator. */ +struct nistp384_pre_comp_st { + felem g_pre_comp[16][3]; + CRYPTO_REF_COUNT references; +}; + +const EC_METHOD *ossl_ec_GFp_nistp384_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ossl_ec_GFp_nistp384_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_nist_group_copy, + ossl_ec_GFp_nistp384_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ossl_ec_GFp_nistp384_point_get_affine_coordinates, + 0, /* point_set_compressed_coordinates */ + 0, /* point2oct */ + 0, /* oct2point */ + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, + ossl_ec_GFp_nistp384_points_mul, + ossl_ec_GFp_nistp384_precompute_mult, + ossl_ec_GFp_nistp384_have_precompute_mult, + ossl_ec_GFp_nist_field_mul, + ossl_ec_GFp_nist_field_sqr, + 0, /* field_div */ + ossl_ec_GFp_simple_field_inv, + 0, /* field_encode */ + 0, /* field_decode */ + 0, /* field_set_to_one */ + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, + 0, /* set private */ + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, + 0, /* keycopy */ + 0, /* keyfinish */ + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, + 0, /* field_inverse_mod_ord */ + 0, /* blind_coordinates */ + 0, /* ladder_pre */ + 0, /* ladder_step */ + 0 /* ladder_post */ + }; + + return &ret; +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP384_PRE_COMP *nistp384_pre_comp_new(void) +{ + NISTP384_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) + return ret; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + OPENSSL_free(ret); + return NULL; + } + return ret; +} + +NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *p) +{ + int i; + + if (p != NULL) + CRYPTO_UP_REF(&p->references, &i); + return p; +} + +void ossl_ec_nistp384_pre_comp_free(NISTP384_PRE_COMP *p) +{ + int i; + + if (p == NULL) + return; + + CRYPTO_DOWN_REF(&p->references, &i); + REF_PRINT_COUNT("ossl_ec_nistp384", p); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + + CRYPTO_FREE_REF(&p->references); + OPENSSL_free(p); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ossl_ec_GFp_nistp384_group_init(EC_GROUP *group) +{ + int ret; + + ret = ossl_ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ossl_ec_GFp_nistp384_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *curve_p, *curve_a, *curve_b; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + + BN_CTX_start(ctx); + curve_p = BN_CTX_get(ctx); + curve_a = BN_CTX_get(ctx); + curve_b = BN_CTX_get(ctx); + if (curve_b == NULL) + goto err; + BN_bin2bn(nistp384_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp384_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp384_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_384; + ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); +#ifndef FIPS_MODULE + BN_CTX_free(new_ctx); +#endif + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ossl_ec_GFp_nistp384_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in, x_out, y_out; + widefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) || + (!BN_to_felem(z1, point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!felem_to_BN(x, x_out)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!felem_to_BN(y, y_out)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +/* points below is of size |num|, and tmp_felems is of size |num+1/ */ +static void make_points_affine(size_t num, felem points[][3], + felem tmp_felems[]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ossl_ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, + (void (*)(void *, const void *, const void*)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ossl_ec_GFp_nistp384_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + int mixed = 0; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + felem (*pre_comp)[17][3] = NULL; + felem *tmp_felems = NULL; + unsigned int i; + int num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + felem x_in, y_in, z_in, x_out, y_out, z_out; + NISTP384_PRE_COMP *pre = NULL; + felem(*g_pre_comp)[3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + tmp_scalar = BN_CTX_get(ctx); + if (tmp_scalar == NULL) + goto err; + + if (scalar != NULL) { + pre = group->pre_comp.nistp384; + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = &pre->g_pre_comp[0]; + else + /* try to use the standard precomputation */ + g_pre_comp = (felem(*)[3]) gmul; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!felem_to_BN(x, g_pre_comp[1][0]) || + !felem_to_BN(y, g_pre_comp[1][1]) || + !felem_to_BN(z, g_pre_comp[1][2])) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, + generator, + x, y, z, ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points++; + } + + if (num_points > 0) { + if (num_points >= 2) { + /* + * unless we precompute multiples for just one point, converting + * those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points); + pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points); + if (mixed) + tmp_felems = + OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_felems == NULL))) + goto err; + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + for (i = 0; i < num_points; ++i) { + if (i == num) { + /* + * we didn't have a valid precomputation, so we pick the + * generator + */ + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else { + /* the i^th point */ + p = points[i]; + p_scalar = scalars[i]; + } + if (p_scalar != NULL && p != NULL) { + /* reduce scalar to 0 <= scalar < 2^384 */ + if ((BN_num_bits(p_scalar) > 384) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2lebinpad(tmp_scalar, + secrets[i], sizeof(secrets[i])); + } else { + num_bytes = BN_bn2lebinpad(p_scalar, + secrets[i], sizeof(secrets[i])); + } + if (num_bytes < 0) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + /* precompute multiples */ + if ((!BN_to_felem(x_out, p->X)) || + (!BN_to_felem(y_out, p->Y)) || + (!BN_to_felem(z_out, p->Z))) + goto err; + memcpy(pre_comp[i][1][0], x_out, sizeof(felem)); + memcpy(pre_comp[i][1][1], y_out, sizeof(felem)); + memcpy(pre_comp[i][1][2], z_out, sizeof(felem)); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2], + pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2], 0, + pre_comp[i][j - 1][0], pre_comp[i][j - 1][1], pre_comp[i][j - 1][2]); + } else { + point_double(pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2], + pre_comp[i][j / 2][0], pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_felems); + } + + /* the scalar for the generator */ + if (scalar != NULL && have_pre_comp) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^384 */ + if ((BN_num_bits(scalar) > 384) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret)); + } else { + num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret)); + } + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const felem(*)[17][3])pre_comp, + (const felem(*)[3])g_pre_comp); + } else { + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + } + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || + (!felem_to_BN(z, z_in))) { + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z, + ctx); + + err: + BN_CTX_end(ctx); + EC_POINT_free(generator); + OPENSSL_free(secrets); + OPENSSL_free(pre_comp); + OPENSSL_free(tmp_felems); + return ret; +} + +int ossl_ec_GFp_nistp384_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP384_PRE_COMP *pre = NULL; + int i, j; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + felem tmp_felems[16]; +#ifndef FIPS_MODULE + BN_CTX *new_ctx = NULL; +#endif + + /* throw away old precomputation */ + EC_pre_comp_free(group); + +#ifndef FIPS_MODULE + if (ctx == NULL) + ctx = new_ctx = BN_CTX_new(); +#endif + if (ctx == NULL) + return 0; + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp384_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp384_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp384_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + goto done; + } + if ((!BN_to_felem(pre->g_pre_comp[1][0], group->generator->X)) || + (!BN_to_felem(pre->g_pre_comp[1][1], group->generator->Y)) || + (!BN_to_felem(pre->g_pre_comp[1][2], group->generator->Z))) + goto err; + /* compute 2^95*G, 2^190*G, 2^285*G */ + for (i = 1; i <= 4; i <<= 1) { + point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], + pre->g_pre_comp[i][0], pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]); + for (j = 0; j < 94; ++j) { + point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], + pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2]); + } + } + /* g_pre_comp[0] is the point at infinity */ + memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0])); + /* the remaining multiples */ + /* 2^95*G + 2^190*G */ + point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1], pre->g_pre_comp[6][2], + pre->g_pre_comp[4][0], pre->g_pre_comp[4][1], pre->g_pre_comp[4][2], 0, + pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], pre->g_pre_comp[2][2]); + /* 2^95*G + 2^285*G */ + point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1], pre->g_pre_comp[10][2], + pre->g_pre_comp[8][0], pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], 0, + pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], pre->g_pre_comp[2][2]); + /* 2^190*G + 2^285*G */ + point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], + pre->g_pre_comp[8][0], pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], 0, + pre->g_pre_comp[4][0], pre->g_pre_comp[4][1], pre->g_pre_comp[4][2]); + /* 2^95*G + 2^190*G + 2^285*G */ + point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1], pre->g_pre_comp[14][2], + pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], 0, + pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], pre->g_pre_comp[2][2]); + for (i = 1; i < 8; ++i) { + /* odd multiples: add G */ + point_add(pre->g_pre_comp[2 * i + 1][0], pre->g_pre_comp[2 * i + 1][1], pre->g_pre_comp[2 * i + 1][2], + pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0, + pre->g_pre_comp[1][0], pre->g_pre_comp[1][1], pre->g_pre_comp[1][2]); + } + make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems); + + done: + SETPRECOMP(group, nistp384, pre); + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + EC_POINT_free(generator); +#ifndef FIPS_MODULE + BN_CTX_free(new_ctx); +#endif + ossl_ec_nistp384_pre_comp_free(pre); + return ret; +} + +int ossl_ec_GFp_nistp384_have_precompute_mult(const EC_GROUP *group) +{ + return HAVEPRECOMP(group, nistp384); +} diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index d65f6984de..5760639a2e 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2014, Intel Corporation. All Rights Reserved. * Copyright (c) 2015, CloudFlare, Inc. * @@ -37,14 +37,6 @@ # define TOBN(hi,lo) ((BN_ULONG)hi<<32|lo) #endif -#if defined(__GNUC__) -# define ALIGN32 __attribute((aligned(32))) -#elif defined(_MSC_VER) -# define ALIGN32 __declspec(align(32)) -#else -# define ALIGN32 -#endif - #define ALIGNPTR(p,N) ((unsigned char *)p+N-(size_t)p%N) #define P256_LIMBS (256/BN_BITS2) @@ -75,7 +67,6 @@ struct nistz256_pre_comp_st { PRECOMP256_ROW *precomp; void *precomp_storage; CRYPTO_REF_COUNT references; - CRYPTO_RWLOCK *lock; }; /* Functions implemented in assembly */ @@ -636,10 +627,8 @@ __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group, OPENSSL_malloc((num * 16 + 5) * sizeof(P256_POINT) + 64)) == NULL || (p_str = OPENSSL_malloc(num * 33 * sizeof(unsigned char))) == NULL - || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) goto err; - } table = (void *)ALIGNPTR(table_storage, 64); temp = (P256_POINT *)(table + num); @@ -868,10 +857,8 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) w = 7; if ((precomp_storage = - OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) goto err; - } preComputedTable = (void *)ALIGNPTR(precomp_storage, 64); @@ -974,7 +961,7 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, BIGNUM *tmp_scalar; if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } @@ -1123,16 +1110,12 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, * handled like a normal point. */ new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *)); - if (new_scalars == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (new_scalars == NULL) goto err; - } new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *)); - if (new_points == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (new_points == NULL) goto err; - } memcpy(new_scalars, scalars, num * sizeof(BIGNUM *)); new_scalars[num] = scalar; @@ -1226,18 +1209,13 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group) ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return ret; - } ret->group = group; ret->w = 6; /* default */ - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret); return NULL; } @@ -1248,7 +1226,7 @@ NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p) { int i; if (p != NULL) - CRYPTO_UP_REF(&p->references, &i, p->lock); + CRYPTO_UP_REF(&p->references, &i); return p; } @@ -1259,14 +1237,14 @@ void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre) if (pre == NULL) return; - CRYPTO_DOWN_REF(&pre->references, &i, pre->lock); + CRYPTO_DOWN_REF(&pre->references, &i); REF_PRINT_COUNT("EC_nistz256", pre); if (i > 0) return; REF_ASSERT_ISNT(i < 0); OPENSSL_free(pre->precomp_storage); - CRYPTO_THREAD_lock_free(pre->lock); + CRYPTO_FREE_REF(&pre->references); OPENSSL_free(pre); } @@ -1378,7 +1356,7 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r, /* * The bottom 128 bit of the exponent are processed with fixed 4-bit window */ - for(i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) { /* expLo - the low 128 bits of the exponent we use (ord(p256) - 2), * split into nibbles */ static const unsigned char expLo[32] = { diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c index 0c10196ea3..f13f8bed24 100644 --- a/crypto/ec/ecp_s390x_nistp.c +++ b/crypto/ec/ecp_s390x_nistp.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -152,14 +152,14 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst, k = BN_secure_new(); sig = ECDSA_SIG_new(); if (k == NULL || sig == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); goto ret; } sig->r = BN_new(); sig->s = BN_new(); if (sig->r == NULL || sig->s == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto ret; } @@ -178,7 +178,7 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst, goto ret; } /* - * Generate random k and copy to param param block. RAND_priv_bytes_ex + * Generate random k and copy to param block. RAND_priv_bytes_ex * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce * because kdsa instruction constructs an in-range, invertible nonce * internally implementing counter-measures for RNG weakness. @@ -247,7 +247,7 @@ static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen, ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); return -1; } @@ -256,7 +256,7 @@ static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen, x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); if (x == NULL || y == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto ret; } diff --git a/crypto/ec/ecp_sm2p256.c b/crypto/ec/ecp_sm2p256.c new file mode 100644 index 0000000000..6ec4245529 --- /dev/null +++ b/crypto/ec/ecp_sm2p256.c @@ -0,0 +1,790 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + */ + +/* + * SM2 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include "crypto/bn.h" +#include "ec_local.h" +#include "internal/common.h" +#include "internal/constant_time.h" + +#define P256_LIMBS (256 / BN_BITS2) + +#if !defined(OPENSSL_NO_SM2_PRECOMP) +extern const BN_ULONG ecp_sm2p256_precomputed[8 * 32 * 256]; +#endif + +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; + BN_ULONG Z[P256_LIMBS]; +} P256_POINT; + +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; +} P256_POINT_AFFINE; + +#if !defined(OPENSSL_NO_SM2_PRECOMP) +/* Coordinates of G, for which we have precomputed tables */ +static const BN_ULONG def_xG[P256_LIMBS] ALIGN32 = { + 0x715a4589334c74c7, 0x8fe30bbff2660be1, + 0x5f9904466a39c994, 0x32c4ae2c1f198119 +}; + +static const BN_ULONG def_yG[P256_LIMBS] ALIGN32 = { + 0x02df32e52139f0a0, 0xd0a9877cc62a4740, + 0x59bdcee36b692153, 0xbc3736a2f4f6779c, +}; +#endif + +/* p and order for SM2 according to GB/T 32918.5-2017 */ +static const BN_ULONG def_p[P256_LIMBS] ALIGN32 = { + 0xffffffffffffffff, 0xffffffff00000000, + 0xffffffffffffffff, 0xfffffffeffffffff +}; +static const BN_ULONG def_ord[P256_LIMBS] ALIGN32 = { + 0x53bbf40939d54123, 0x7203df6b21c6052b, + 0xffffffffffffffff, 0xfffffffeffffffff +}; + +static const BN_ULONG ONE[P256_LIMBS] ALIGN32 = {1, 0, 0, 0}; + +/* Functions implemented in assembly */ +/* + * Most of below mentioned functions *preserve* the property of inputs + * being fully reduced, i.e. being in [0, modulus) range. Simply put if + * inputs are fully reduced, then output is too. + */ +/* Right shift: a >> 1 */ +void bn_rshift1(BN_ULONG *a); +/* Sub: r = a - b */ +void bn_sub(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +/* Modular div by 2: r = a / 2 mod p */ +void ecp_sm2p256_div_by_2(BN_ULONG *r, const BN_ULONG *a); +/* Modular div by 2: r = a / 2 mod n, where n = ord(p) */ +void ecp_sm2p256_div_by_2_mod_ord(BN_ULONG *r, const BN_ULONG *a); +/* Modular add: r = a + b mod p */ +void ecp_sm2p256_add(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +/* Modular sub: r = a - b mod p */ +void ecp_sm2p256_sub(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +/* Modular sub: r = a - b mod n, where n = ord(p) */ +void ecp_sm2p256_sub_mod_ord(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +/* Modular mul by 3: out = 3 * a mod p */ +void ecp_sm2p256_mul_by_3(BN_ULONG *r, const BN_ULONG *a); +/* Modular mul: r = a * b mod p */ +void ecp_sm2p256_mul(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b); +/* Modular sqr: r = a ^ 2 mod p */ +void ecp_sm2p256_sqr(BN_ULONG *r, const BN_ULONG *a); + +static ossl_inline BN_ULONG is_zeros(const BN_ULONG *a) +{ + BN_ULONG res; + + res = a[0] | a[1] | a[2] | a[3]; + + return constant_time_is_zero_64(res); +} + +static ossl_inline int is_equal(const BN_ULONG *a, const BN_ULONG *b) +{ + BN_ULONG res; + + res = a[0] ^ b[0]; + res |= a[1] ^ b[1]; + res |= a[2] ^ b[2]; + res |= a[3] ^ b[3]; + + return constant_time_is_zero_64(res); +} + +static ossl_inline int is_greater(const BN_ULONG *a, const BN_ULONG *b) +{ + int i; + + for (i = P256_LIMBS - 1; i >= 0; --i) { + if (a[i] > b[i]) + return 1; + if (a[i] < b[i]) + return -1; + } + + return 0; +} + +#define is_one(a) is_equal(a, ONE) +#define is_even(a) !(a[0] & 1) +#define is_point_equal(a, b) \ + is_equal(a->X, b->X) && \ + is_equal(a->Y, b->Y) && \ + is_equal(a->Z, b->Z) + +/* Bignum and field elements conversion */ +#define ecp_sm2p256_bignum_field_elem(out, in) \ + bn_copy_words(out, in, P256_LIMBS) + +/* Binary algorithm for inversion in Fp */ +#define BN_MOD_INV(out, in, mod_div, mod_sub, mod) \ + do { \ + BN_ULONG u[4] ALIGN32; \ + BN_ULONG v[4] ALIGN32; \ + BN_ULONG x1[4] ALIGN32 = {1, 0, 0, 0}; \ + BN_ULONG x2[4] ALIGN32 = {0}; \ + \ + if (is_zeros(in)) \ + return; \ + memcpy(u, in, 32); \ + memcpy(v, mod, 32); \ + while (!is_one(u) && !is_one(v)) { \ + while (is_even(u)) { \ + bn_rshift1(u); \ + mod_div(x1, x1); \ + } \ + while (is_even(v)) { \ + bn_rshift1(v); \ + mod_div(x2, x2); \ + } \ + if (is_greater(u, v) == 1) { \ + bn_sub(u, u, v); \ + mod_sub(x1, x1, x2); \ + } else { \ + bn_sub(v, v, u); \ + mod_sub(x2, x2, x1); \ + } \ + } \ + if (is_one(u)) \ + memcpy(out, x1, 32); \ + else \ + memcpy(out, x2, 32); \ + } while (0) + +/* Modular inverse |out| = |in|^(-1) mod |p|. */ +static ossl_inline void ecp_sm2p256_mod_inverse(BN_ULONG* out, + const BN_ULONG* in) { + BN_MOD_INV(out, in, ecp_sm2p256_div_by_2, ecp_sm2p256_sub, def_p); +} + +/* Modular inverse mod order |out| = |in|^(-1) % |ord|. */ +static ossl_inline void ecp_sm2p256_mod_ord_inverse(BN_ULONG* out, + const BN_ULONG* in) { + BN_MOD_INV(out, in, ecp_sm2p256_div_by_2_mod_ord, ecp_sm2p256_sub_mod_ord, + def_ord); +} + +/* Point double: R <- P + P */ +static void ecp_sm2p256_point_double(P256_POINT *R, const P256_POINT *P) +{ + unsigned int i; + BN_ULONG tmp0[P256_LIMBS] ALIGN32; + BN_ULONG tmp1[P256_LIMBS] ALIGN32; + BN_ULONG tmp2[P256_LIMBS] ALIGN32; + + /* zero-check P->Z */ + if (is_zeros(P->Z)) { + for (i = 0; i < P256_LIMBS; ++i) + R->Z[i] = 0; + + return; + } + + ecp_sm2p256_sqr(tmp0, P->Z); + ecp_sm2p256_sub(tmp1, P->X, tmp0); + ecp_sm2p256_add(tmp0, P->X, tmp0); + ecp_sm2p256_mul(tmp1, tmp1, tmp0); + ecp_sm2p256_mul_by_3(tmp1, tmp1); + ecp_sm2p256_add(R->Y, P->Y, P->Y); + ecp_sm2p256_mul(R->Z, R->Y, P->Z); + ecp_sm2p256_sqr(R->Y, R->Y); + ecp_sm2p256_mul(tmp2, R->Y, P->X); + ecp_sm2p256_sqr(R->Y, R->Y); + ecp_sm2p256_div_by_2(R->Y, R->Y); + ecp_sm2p256_sqr(R->X, tmp1); + ecp_sm2p256_add(tmp0, tmp2, tmp2); + ecp_sm2p256_sub(R->X, R->X, tmp0); + ecp_sm2p256_sub(tmp0, tmp2, R->X); + ecp_sm2p256_mul(tmp0, tmp0, tmp1); + ecp_sm2p256_sub(tmp1, tmp0, R->Y); + memcpy(R->Y, tmp1, 32); +} + +/* Point add affine: R <- P + Q */ +static void ecp_sm2p256_point_add_affine(P256_POINT *R, const P256_POINT *P, + const P256_POINT_AFFINE *Q) +{ + unsigned int i; + BN_ULONG tmp0[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG tmp1[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG tmp2[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG tmp3[P256_LIMBS] ALIGN32 = {0}; + + /* zero-check P->Z */ + if (is_zeros(P->Z)) { + for (i = 0; i < P256_LIMBS; ++i) { + R->X[i] = Q->X[i]; + R->Y[i] = Q->Y[i]; + R->Z[i] = 0; + } + R->Z[0] = 1; + + return; + } + + ecp_sm2p256_sqr(tmp0, P->Z); + ecp_sm2p256_mul(tmp1, tmp0, P->Z); + ecp_sm2p256_mul(tmp0, tmp0, Q->X); + ecp_sm2p256_mul(tmp1, tmp1, Q->Y); + ecp_sm2p256_sub(tmp0, tmp0, P->X); + ecp_sm2p256_sub(tmp1, tmp1, P->Y); + + /* zero-check tmp0, tmp1 */ + if (is_zeros(tmp0)) { + if (is_zeros(tmp1)) { + P256_POINT K; + + for (i = 0; i < P256_LIMBS; ++i) { + K.X[i] = Q->X[i]; + K.Y[i] = Q->Y[i]; + K.Z[i] = 0; + } + K.Z[0] = 1; + ecp_sm2p256_point_double(R, &K); + } else { + for (i = 0; i < P256_LIMBS; ++i) + R->Z[i] = 0; + } + + return; + } + + ecp_sm2p256_mul(R->Z, P->Z, tmp0); + ecp_sm2p256_sqr(tmp2, tmp0); + ecp_sm2p256_mul(tmp3, tmp2, tmp0); + ecp_sm2p256_mul(tmp2, tmp2, P->X); + ecp_sm2p256_add(tmp0, tmp2, tmp2); + ecp_sm2p256_sqr(R->X, tmp1); + ecp_sm2p256_sub(R->X, R->X, tmp0); + ecp_sm2p256_sub(R->X, R->X, tmp3); + ecp_sm2p256_sub(tmp2, tmp2, R->X); + ecp_sm2p256_mul(tmp2, tmp2, tmp1); + ecp_sm2p256_mul(tmp3, tmp3, P->Y); + ecp_sm2p256_sub(R->Y, tmp2, tmp3); +} + +/* Point add: R <- P + Q */ +static void ecp_sm2p256_point_add(P256_POINT *R, const P256_POINT *P, + const P256_POINT *Q) +{ + unsigned int i; + BN_ULONG tmp0[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG tmp1[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG tmp2[P256_LIMBS] ALIGN32 = {0}; + + /* zero-check P | Q ->Z */ + if (is_zeros(P->Z)) { + for (i = 0; i < P256_LIMBS; ++i) { + R->X[i] = Q->X[i]; + R->Y[i] = Q->Y[i]; + R->Z[i] = Q->Z[i]; + } + + return; + } else if (is_zeros(Q->Z)) { + for (i = 0; i < P256_LIMBS; ++i) { + R->X[i] = P->X[i]; + R->Y[i] = P->Y[i]; + R->Z[i] = P->Z[i]; + } + + return; + } else if (is_point_equal(P, Q)) { + ecp_sm2p256_point_double(R, Q); + + return; + } + + ecp_sm2p256_sqr(tmp0, P->Z); + ecp_sm2p256_mul(tmp1, tmp0, P->Z); + ecp_sm2p256_mul(tmp0, tmp0, Q->X); + ecp_sm2p256_mul(tmp1, tmp1, Q->Y); + ecp_sm2p256_mul(R->Y, P->Y, Q->Z); + ecp_sm2p256_mul(R->Z, Q->Z, P->Z); + ecp_sm2p256_sqr(tmp2, Q->Z); + ecp_sm2p256_mul(R->Y, tmp2, R->Y); + ecp_sm2p256_mul(R->X, tmp2, P->X); + ecp_sm2p256_sub(tmp0, tmp0, R->X); + ecp_sm2p256_mul(R->Z, tmp0, R->Z); + ecp_sm2p256_sub(tmp1, tmp1, R->Y); + ecp_sm2p256_sqr(tmp2, tmp0); + ecp_sm2p256_mul(tmp0, tmp0, tmp2); + ecp_sm2p256_mul(tmp2, tmp2, R->X); + ecp_sm2p256_sqr(R->X, tmp1); + ecp_sm2p256_sub(R->X, R->X, tmp2); + ecp_sm2p256_sub(R->X, R->X, tmp2); + ecp_sm2p256_sub(R->X, R->X, tmp0); + ecp_sm2p256_sub(tmp2, tmp2, R->X); + ecp_sm2p256_mul(tmp2, tmp1, tmp2); + ecp_sm2p256_mul(tmp0, tmp0, R->Y); + ecp_sm2p256_sub(R->Y, tmp2, tmp0); +} + +#if !defined(OPENSSL_NO_SM2_PRECOMP) +/* Base point mul by scalar: k - scalar, G - base point */ +static void ecp_sm2p256_point_G_mul_by_scalar(P256_POINT *R, const BN_ULONG *k) +{ + unsigned int i, index, mask = 0xff; + P256_POINT_AFFINE Q; + + memset(R, 0, sizeof(P256_POINT)); + + if (is_zeros(k)) + return; + + index = k[0] & mask; + if (index) { + index = index * 8; + memcpy(R->X, ecp_sm2p256_precomputed + index, 32); + memcpy(R->Y, ecp_sm2p256_precomputed + index + P256_LIMBS, 32); + R->Z[0] = 1; + } + + for (i = 1; i < 32; ++i) { + index = (k[i / 8] >> (8 * (i % 8))) & mask; + + if (index) { + index = index + i * 256; + index = index * 8; + memcpy(Q.X, ecp_sm2p256_precomputed + index, 32); + memcpy(Q.Y, ecp_sm2p256_precomputed + index + P256_LIMBS, 32); + ecp_sm2p256_point_add_affine(R, R, &Q); + } + } +} +#endif + +/* + * Affine point mul by scalar: k - scalar, P - affine point + */ +static void ecp_sm2p256_point_P_mul_by_scalar(P256_POINT *R, const BN_ULONG *k, + P256_POINT_AFFINE P) +{ + int i, init = 0; + unsigned int index, mask = 0x0f; + P256_POINT precomputed[16] ALIGN64; + + memset(R, 0, sizeof(P256_POINT)); + + if (is_zeros(k)) + return; + + /* The first value of the precomputed table is P. */ + memcpy(precomputed[1].X, P.X, 32); + memcpy(precomputed[1].Y, P.Y, 32); + precomputed[1].Z[0] = 1; + precomputed[1].Z[1] = 0; + precomputed[1].Z[2] = 0; + precomputed[1].Z[3] = 0; + + /* The second value of the precomputed table is 2P. */ + ecp_sm2p256_point_double(&precomputed[2], &precomputed[1]); + + /* The subsequent elements are 3P, 4P, and so on. */ + for (i = 3; i < 16; ++i) + ecp_sm2p256_point_add_affine(&precomputed[i], &precomputed[i - 1], &P); + + for (i = 64 - 1; i >= 0; --i) { + index = (k[i / 16] >> (4 * (i % 16))) & mask; + + if (init == 0) { + if (index) { + memcpy(R, &precomputed[index], sizeof(P256_POINT)); + init = 1; + } + } else { + ecp_sm2p256_point_double(R, R); + ecp_sm2p256_point_double(R, R); + ecp_sm2p256_point_double(R, R); + ecp_sm2p256_point_double(R, R); + if (index) + ecp_sm2p256_point_add(R, R, &precomputed[index]); + } + } +} + +/* Get affine point */ +static void ecp_sm2p256_point_get_affine(P256_POINT_AFFINE *R, + const P256_POINT *P) +{ + BN_ULONG z_inv3[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG z_inv2[P256_LIMBS] ALIGN32 = {0}; + + if (is_one(P->Z)) { + memcpy(R->X, P->X, 32); + memcpy(R->Y, P->Y, 32); + return; + } + + ecp_sm2p256_mod_inverse(z_inv3, P->Z); + ecp_sm2p256_sqr(z_inv2, z_inv3); + ecp_sm2p256_mul(R->X, P->X, z_inv2); + ecp_sm2p256_mul(z_inv3, z_inv3, z_inv2); + ecp_sm2p256_mul(R->Y, P->Y, z_inv3); +} + +#if !defined(OPENSSL_NO_SM2_PRECOMP) +static int ecp_sm2p256_is_affine_G(const EC_POINT *generator) +{ + return (bn_get_top(generator->X) == P256_LIMBS) + && (bn_get_top(generator->Y) == P256_LIMBS) + && is_equal(bn_get_words(generator->X), def_xG) + && is_equal(bn_get_words(generator->Y), def_yG) + && (generator->Z_is_one == 1); +} +#endif + +/* + * Convert Jacobian coordinate point into affine coordinate (x,y) + */ +static int ecp_sm2p256_get_affine(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) +{ + BN_ULONG z_inv2[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG z_inv3[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG x_aff[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG y_aff[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG point_x[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG point_y[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG point_z[P256_LIMBS] ALIGN32 = {0}; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + if (ecp_sm2p256_bignum_field_elem(point_x, point->X) <= 0 + || ecp_sm2p256_bignum_field_elem(point_y, point->Y) <= 0 + || ecp_sm2p256_bignum_field_elem(point_z, point->Z) <= 0) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_sm2p256_mod_inverse(z_inv3, point_z); + ecp_sm2p256_sqr(z_inv2, z_inv3); + + if (x != NULL) { + ecp_sm2p256_mul(x_aff, point_x, z_inv2); + if (!bn_set_words(x, x_aff, P256_LIMBS)) + return 0; + } + + if (y != NULL) { + ecp_sm2p256_mul(z_inv3, z_inv3, z_inv2); + ecp_sm2p256_mul(y_aff, point_y, z_inv3); + if (!bn_set_words(y, y_aff, P256_LIMBS)) + return 0; + } + + return 1; +} + +/* r = sum(scalar[i]*point[i]) */ +static int ecp_sm2p256_windowed_mul(const EC_GROUP *group, + P256_POINT *r, + const BIGNUM **scalar, + const EC_POINT **point, + size_t num, BN_CTX *ctx) +{ + unsigned int i; + int ret = 0; + const BIGNUM **scalars = NULL; + BN_ULONG k[P256_LIMBS] ALIGN32 = {0}; + P256_POINT kP; + ALIGN32 union { + P256_POINT p; + P256_POINT_AFFINE a; + } t, p; + + if (num > OPENSSL_MALLOC_MAX_NELEMS(P256_POINT) + || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) { + ECerr(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + memset(r, 0, sizeof(P256_POINT)); + + for (i = 0; i < num; i++) { + if (EC_POINT_is_at_infinity(group, point[i])) + continue; + + if ((BN_num_bits(scalar[i]) > 256) || BN_is_negative(scalar[i])) { + BIGNUM *tmp; + + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_nnmod(tmp, scalar[i], group->order, ctx)) { + ECerr(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + scalars[i] = tmp; + } else { + scalars[i] = scalar[i]; + } + + if (ecp_sm2p256_bignum_field_elem(k, scalars[i]) <= 0 + || ecp_sm2p256_bignum_field_elem(p.p.X, point[i]->X) <= 0 + || ecp_sm2p256_bignum_field_elem(p.p.Y, point[i]->Y) <= 0 + || ecp_sm2p256_bignum_field_elem(p.p.Z, point[i]->Z) <= 0) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + + ecp_sm2p256_point_get_affine(&t.a, &p.p); + ecp_sm2p256_point_P_mul_by_scalar(&kP, k, t.a); + ecp_sm2p256_point_add(r, r, &kP); + } + + ret = 1; +err: + OPENSSL_free(scalars); + return ret; +} + +/* r = scalar*G + sum(scalars[i]*points[i]) */ +static int ecp_sm2p256_points_mul(const EC_GROUP *group, + EC_POINT *r, + const BIGNUM *scalar, + size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0, p_is_infinity = 0; + const EC_POINT *generator = NULL; + BN_ULONG k[P256_LIMBS] ALIGN32 = {0}; + ALIGN32 union { + P256_POINT p; + P256_POINT_AFFINE a; + } t, p; + + if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) { + ECerr(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + + if (scalar) { + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerr(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + if (!ecp_sm2p256_bignum_field_elem(k, scalar)) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } +#if !defined(OPENSSL_NO_SM2_PRECOMP) + if (ecp_sm2p256_is_affine_G(generator)) { + ecp_sm2p256_point_G_mul_by_scalar(&p.p, k); + } else +#endif + { + /* if no precomputed table */ + const EC_POINT *new_generator[1]; + const BIGNUM *g_scalars[1]; + + new_generator[0] = generator; + g_scalars[0] = scalar; + + if (!ecp_sm2p256_windowed_mul(group, &p.p, g_scalars, new_generator, + (new_generator[0] != NULL + && g_scalars[0] != NULL), ctx)) + goto err; + } + } else { + p_is_infinity = 1; + } + if (num) { + P256_POINT *out = &t.p; + + if (p_is_infinity) + out = &p.p; + + if (!ecp_sm2p256_windowed_mul(group, out, scalars, points, num, ctx)) + goto err; + + if (!p_is_infinity) + ecp_sm2p256_point_add(&p.p, &p.p, out); + } + + /* Not constant-time, but we're only operating on the public output. */ + if (!bn_set_words(r->X, p.p.X, P256_LIMBS) + || !bn_set_words(r->Y, p.p.Y, P256_LIMBS) + || !bn_set_words(r->Z, p.p.Z, P256_LIMBS)) + goto err; + r->Z_is_one = is_equal(bn_get_words(r->Z), ONE) & 1; + + ret = 1; +err: + BN_CTX_end(ctx); + return ret; +} + +static int ecp_sm2p256_field_mul(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + BN_ULONG a_fe[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG b_fe[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG r_fe[P256_LIMBS] ALIGN32 = {0}; + + if (a == NULL || b == NULL || r == NULL) + return 0; + + if (!ecp_sm2p256_bignum_field_elem(a_fe, a) + || !ecp_sm2p256_bignum_field_elem(b_fe, b)) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_sm2p256_mul(r_fe, a_fe, b_fe); + + if (!bn_set_words(r, r_fe, P256_LIMBS)) + return 0; + + return 1; +} + +static int ecp_sm2p256_field_sqr(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + BN_ULONG a_fe[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG r_fe[P256_LIMBS] ALIGN32 = {0}; + + if (a == NULL || r == NULL) + return 0; + + if (!ecp_sm2p256_bignum_field_elem(a_fe, a)) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_sm2p256_sqr(r_fe, a_fe); + + if (!bn_set_words(r, r_fe, P256_LIMBS)) + return 0; + + return 1; +} + +static int ecp_sm2p256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *x, BN_CTX *ctx) +{ + int ret = 0; + BN_ULONG t[P256_LIMBS] ALIGN32 = {0}; + BN_ULONG out[P256_LIMBS] ALIGN32 = {0}; + + if (bn_wexpand(r, P256_LIMBS) == NULL) { + ECerr(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + + if ((BN_num_bits(x) > 256) || BN_is_negative(x)) { + BIGNUM *tmp; + + if ((tmp = BN_CTX_get(ctx)) == NULL + || !BN_nnmod(tmp, x, group->order, ctx)) { + ECerr(ERR_LIB_EC, ERR_R_BN_LIB); + goto err; + } + x = tmp; + } + + if (!ecp_sm2p256_bignum_field_elem(t, x)) { + ECerr(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + + ecp_sm2p256_mod_ord_inverse(out, t); + + if (!bn_set_words(r, out, P256_LIMBS)) + goto err; + + ret = 1; +err: + return ret; +} + +const EC_METHOD *EC_GFp_sm2p256_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ossl_ec_GFp_simple_group_init, + ossl_ec_GFp_simple_group_finish, + ossl_ec_GFp_simple_group_clear_finish, + ossl_ec_GFp_simple_group_copy, + ossl_ec_GFp_simple_group_set_curve, + ossl_ec_GFp_simple_group_get_curve, + ossl_ec_GFp_simple_group_get_degree, + ossl_ec_group_simple_order_bits, + ossl_ec_GFp_simple_group_check_discriminant, + ossl_ec_GFp_simple_point_init, + ossl_ec_GFp_simple_point_finish, + ossl_ec_GFp_simple_point_clear_finish, + ossl_ec_GFp_simple_point_copy, + ossl_ec_GFp_simple_point_set_to_infinity, + ossl_ec_GFp_simple_point_set_affine_coordinates, + ecp_sm2p256_get_affine, + 0, 0, 0, + ossl_ec_GFp_simple_add, + ossl_ec_GFp_simple_dbl, + ossl_ec_GFp_simple_invert, + ossl_ec_GFp_simple_is_at_infinity, + ossl_ec_GFp_simple_is_on_curve, + ossl_ec_GFp_simple_cmp, + ossl_ec_GFp_simple_make_affine, + ossl_ec_GFp_simple_points_make_affine, + ecp_sm2p256_points_mul, /* mul */ + 0 /* precompute_mult */, + 0 /* have_precompute_mult */, + ecp_sm2p256_field_mul, + ecp_sm2p256_field_sqr, + 0 /* field_div */, + 0 /* field_inv */, + 0 /* field_encode */, + 0 /* field_decode */, + 0 /* field_set_to_one */, + ossl_ec_key_simple_priv2oct, + ossl_ec_key_simple_oct2priv, + 0, /* set private */ + ossl_ec_key_simple_generate_key, + ossl_ec_key_simple_check_key, + ossl_ec_key_simple_generate_public_key, + 0, /* keycopy */ + 0, /* keyfinish */ + ossl_ecdh_simple_compute_key, + ossl_ecdsa_simple_sign_setup, + ossl_ecdsa_simple_sign_sig, + ossl_ecdsa_simple_verify_sig, + ecp_sm2p256_inv_mod_ord, + 0, /* blind_coordinates */ + 0, /* ladder_pre */ + 0, /* ladder_step */ + 0 /* ladder_post */ + }; + + return &ret; +} diff --git a/crypto/ec/ecp_sm2p256_table.c b/crypto/ec/ecp_sm2p256_table.c new file mode 100644 index 0000000000..e19df48f55 --- /dev/null +++ b/crypto/ec/ecp_sm2p256_table.c @@ -0,0 +1,16387 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * This is the precomputed table for the code in ecp_sm2p256.c, for the default + * generator. The table consists of 32 subtables, each subtable contains 256 + * affine points. + * subtable 0: 0* (2^0)*G, 1* (2^0)*G, 2* (2^0)*G, ... , 255* (2^0)*G, + * subtable 1: 0* (2^8)*G, 1* (2^8)*G, 2* (2^8)*G, ... , 255* (2^8)*G, + * subtable 2: 0* (2^16)*G, 1* (2^16)*G, 2* (2^16)*G, ... , 255* (2^16)*G, + * ... + * subtable 31: 0*(2^248)*G, 1*(2^248)*G, 2*(2^248)*G, ... , 255*(2^248)*G, + * + * The affine points are encoded as eight uint64's, four for the + * x coordinate and four for the y. Both values are in little-endian order. + */ + +#include + +#if defined(__GNUC__) +__attribute((aligned(4096))) +#elif defined(_MSC_VER) +__declspec(align(4096)) +#elif defined(__SUNPRO_C) +# pragma align 4096(ecp_sm2p256_precomputed) +#endif +extern const BN_ULONG ecp_sm2p256_precomputed[8 * 32 * 256]; +const BN_ULONG ecp_sm2p256_precomputed[8 * 32 * 256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x715a4589334c74c7, 0x8fe30bbff2660be1, 0x5f9904466a39c994, 0x32c4ae2c1f198119, + 0x02df32e52139f0a0, 0xd0a9877cc62a4740, 0x59bdcee36b692153, 0xbc3736a2f4f6779c, + 0x495c2e1da3f2bd52, 0x9c0dfa08c08a7331, 0x0d58ef57fa73ba4d, 0x56cefd60d7c87c00, + 0x6f780d3a970a23c3, 0x6de84c182f6c8e71, 0x68535ce0f8eaf1bd, 0x31b7e7e6cc8189f6, + 0xe26918f1d0509ebf, 0xa13f6bd945302244, 0xbe2daa8cdb41e24c, 0xa97f7cd4b3c993b4, + 0xaaacdd037458f6e6, 0x7c400ee5cd045292, 0xccc5cec08a72150f, 0x530b5dd88c688ef5, + 0xb21646cd34a0ced5, 0x009a084ad5cc937d, 0x2a81052ff641ed69, 0xc239507105c68324, + 0x7a253666cb66e009, 0x6bee2e96ab8c71fb, 0x35f1294ac0db1968, 0xb1bf7ec4080f3c87, + 0xa575da57cc372a9e, 0x344a417b7fce19db, 0x040e008fdd5eb77a, 0xc749061668652e26, + 0xa6976eff5fbe6480, 0x5006206eb579ff7d, 0x4504c622b51cf38f, 0xf2df5db2d144e945, + 0x2c8b1a1a3c4b0d30, 0x05ff8856a6601689, 0xbb17c93e71f22a31, 0x0927afb57d93483b, + 0xd572103000088f63, 0x81adf1f0855a064d, 0xac1c0ef6ebf26645, 0x150c6b1ab4d1fc7e, + 0xcd27e384d9fcaf15, 0xa80198337744ee78, 0xfdbe86a75c139906, 0xddf092555409c19d, + 0x223b949657e52bc1, 0x037937707d6a49a2, 0x5cd6b6e9c12d2922, 0x847d18ffb38e8706, + 0x675d822ded0bb916, 0xd4ea35d60c1c29bb, 0x3db4333d4e860e64, 0xb9c3faeb4b161071, + 0x3c286da2cfd31a3e, 0x0366a8a03024b3e0, 0x2491d2de9accf2be, 0xc519b309ecf7269c, + 0x173472a58cca247e, 0xfe8d59cb43619e4f, 0x0b4a2444a46a74c5, 0xa27233f3a5959508, + 0x85227940922c02e9, 0xc3a8433140d1ebca, 0x768f7689b210f45f, 0x379e72f63722c924, + 0x84a04814db522756, 0xb2d0d065cd219e32, 0x21666061f65c3e32, 0xd3f94862519621c1, + 0x47d46fb2bab82a14, 0xf6b743f64d1482d1, 0x2ebd57d146dca428, 0x4b9030cf676f6a74, + 0x668c74d78ce20ace, 0x125dcdd589c2ff82, 0x7c1aab770f67f543, 0x04b3cb10c9c6d8e2, + 0x739a8fd805174a4b, 0x0c94816e63c4bc72, 0x4918e5c02e2b0b93, 0x63516355287e39fe, + 0x9c9f042d0279270a, 0x5f7b516c5bdaddad, 0xd89058ca059be46e, 0xbfc2df6bb17f971a, + 0xb5fbf87b64af3c26, 0x73c9fc6fd150aaaa, 0xcef696b67939bd7b, 0xb145513f59636106, + 0x2b834f1d509b9cd0, 0x7bea65c6421e189e, 0xfa804513275f58aa, 0x952072d6ff9c65bd, + 0x03891e105e009b00, 0x58d1434ae934ba75, 0x1a473f8d9748f238, 0xe6bb9804458bb70f, + 0x0a44248a36bb0a07, 0xef22ea28be9d44de, 0x4aaf81826982d748, 0x83b4a4de96a4d70f, + 0x2e663cd4373a2f24, 0x3e707c8a43852949, 0xeeb6d6c6d7e74f8e, 0xe481c0d9ee8a98d4, + 0x461b1bbcb80f829c, 0x3b424f35f0ecce4c, 0x3291676c38d39324, 0xf73b839f13912c1a, + 0x4c3533771db0955e, 0xdc2e788fb170aa14, 0x5ee9fab985c12455, 0x32ec7722695dc7cf, + 0x55645bbc8704fb68, 0xea133cd248a93e25, 0xbbce44ef5db3e419, 0x35648233f554ae51, + 0x4411a9a30eca2046, 0x154b1870a6a65166, 0x6117bca9ce885dd6, 0x04d7ac60f6d975ef, + 0x36969f8b77125e6a, 0xbf5113ab85b5ed44, 0x1c993f01115c57f7, 0xdd18aa4aec26eac4, + 0xe0180d54d4ae2221, 0x6cce6001d7c0b853, 0x3361493f76fac50f, 0x161e5851969da822, + 0x427e33ae8ed9c317, 0xa3448557a24554db, 0x221ea8657781ce71, 0x69fdf8a436fd8e5d, + 0x71e35709341fdcab, 0xeb7b1ad657c155f5, 0x6b0a9658b33b347b, 0xbaa856d1cad68af3, + 0x1323f252e493952a, 0xf7c96c55940a4726, 0xe2e0586bb5dc9419, 0xa68b2ec49d1921d0, + 0xfd4520a63f5cc585, 0xb95f2de69200269e, 0x933ef442fca7a734, 0x96f361a23b3deb99, + 0x0588fdd88abdee94, 0xabbb1ea1417f958d, 0x7575e3cb2fa9092d, 0x08314765e44847eb, + 0x5eeb0e99c2eb61e9, 0x7de3a53937e8a75f, 0x6b443ab436095378, 0xdf922344fa592a98, + 0xe1de5f100950c8ab, 0x5b551c86a8976933, 0x137cbf4e8aa50535, 0x6407be639bc5b738, + 0xf945321148e90344, 0x60fcfd988fff6dec, 0x12a9423fd80dea54, 0x141caee612e7ab07, + 0x0755a352dafa1e1d, 0x3e7307f46fa550d1, 0x1835a4d0f3e5e299, 0xe61120569974c0bc, + 0x3b86cc142850b0f3, 0x02855e18d12379b4, 0xd08fc10e5056e4bc, 0xcfe30aa2c3877e52, + 0x4dbb2fcd069d45db, 0xbb570a9f430ea7f6, 0x15c07a8c04226fe3, 0xac8df677299e8288, + 0x7bd8b7c847718ce5, 0x0e9b9643d766da33, 0x30c43be69b23cc14, 0xaef82cf361db1c71, + 0xd7240a35d1f4ffed, 0xec268911ccb79283, 0x314fa6c814c7bda8, 0xdf8a74f904d1715e, + 0xbcb60a9e82017c30, 0xe1c80e7752bd6499, 0x7a7606ef148aa5fb, 0x0fed448a3f263918, + 0x0263b20d539e4139, 0x7e8581fbbcf5de01, 0xce1564c3df7d67ea, 0x178d1f6bd584afcc, + 0x9b499a7da7820bf9, 0x7021aafc29ac8e86, 0x53da45cec1caada1, 0xf575f34e5f6c63c6, + 0x8e6a9e4fdf895290, 0x73783ef304251e74, 0xbcf26fe238a102c2, 0xa0a1a4fbeb476576, + 0xe54f7f3a4896d9d3, 0xec73068587361b34, 0x0d09c3f281d4c41c, 0x8dfdd7cd150d2564, + 0xce37e84fc9541b4b, 0x02a85a7410754529, 0xd7a1f169475b4ddf, 0xec6f34ceacaa73a0, + 0x73306a0ff0485872, 0xe607f33be20135ea, 0x6f251c63fbbd2927, 0x3c85cf62a744817e, + 0x6cb2f058c747d33f, 0x36f0dfe49113c16e, 0x94ed53ed581d191d, 0x91cb72dc55f84346, + 0x3ea6aace93921f31, 0xf4c600e8b5dfe811, 0xf7efb07682931f88, 0x1957ad4cfffd491e, + 0x9dd4ef421635b9dc, 0xc9816be068be66db, 0x625773cae69bbe05, 0x28221c36398c4c3a, + 0x2995225e66b162ba, 0x64c77a81858d4ca1, 0xab2012c41627cd81, 0x3b4d172d6963510b, + 0xfd23ea021da51c9d, 0x8b1ac02e98d543ce, 0xc315796922bf1343, 0x17a5f74d533ae724, + 0x57d2e81dbb945dfe, 0x7befa4db8c8d3eff, 0xb9038823d9ad0d5f, 0x498470ec6752b2ec, + 0xac995c5066bdaaa5, 0x27d053c0f150fe10, 0xd6b48259b69e8530, 0x08daae840b2a43eb, + 0x2458b9e3c73bf657, 0xf7dc310560bbe83a, 0xc1b8e58150da662d, 0x80cc0a980495af87, + 0xa32641e56024666c, 0x791734cd03e5565c, 0xa6d5c2b5817f2329, 0x25d3debd0950d180, + 0xd39e100303fa10a2, 0x0458895120e208b4, 0xb938c406dd5cb0e1, 0x92d99a70679d61ef, + 0x6d69b1bd07837dc9, 0x451641e8455eedb6, 0x4624f85fe9b7cb83, 0xa1aa7f4a42808908, + 0xc3c8bd75b5fe25de, 0x6e67fd81941c6a60, 0xeb15fccc63694830, 0x3d420dee447499cf, + 0x37a60fce33247b4c, 0x1afddac4a9667094, 0x72e11351388e9d3d, 0x87e13ab96307c971, + 0x217ed12bbc413d35, 0xd7ac6191958240c7, 0xadb32c8ad1d8a615, 0x3ff4e73fac0283e5, + 0x549786448c4f3f4d, 0xbaf30f4638d2231b, 0x46dab2eba04afd78, 0x68126a90b051062b, + 0x5a8ce092c6b7c016, 0xe7fec8984be51251, 0x35ecf208bdec5980, 0x7e72f70a2eaf1bf4, + 0xfa2f46cf90a47d2b, 0xe7579164cc5a233c, 0xcdd2cc00d6ce411e, 0x323159ac22478ac2, + 0x939227b1d05f49ba, 0xa94c472c0089e4b4, 0x7e7a32282a0c2900, 0xe488cf88fe83acfc, + 0x31f8514dc6115cb5, 0x8c641a6cb43ae7da, 0x8b8f45b58a12e6cc, 0x3242e1de1fa494c5, + 0x7dab7b373c8f551b, 0x56ab9bcf11b6f25a, 0xaa27b4380a8333ad, 0xcbf18ef2f229c025, + 0xb7d6af71fb640a75, 0x47a9f7f697a28e0b, 0x6b663188dc931a44, 0x7f404379407b0976, + 0xf500974f78295571, 0xc7652177fdfae41b, 0x860bec0a6c78c5d0, 0x3178d1bb1435c9af, + 0xcd1bb864637cf4f9, 0x10e34d63f48c5ed4, 0x5b075be3c412ad03, 0xe6857f7fc3345385, + 0x1ca28a8ee15f1878, 0x5d72264551d68eae, 0x581dfa7d2b4c09e3, 0x6b61903f2ba03769, + 0x2bed704f6dff2150, 0x3b66f17073149664, 0x2a722a8a3b798a66, 0x376bf9e5403eedb7, + 0x95c769d2fc372cd9, 0x35698578596b792f, 0x2670a8f2e7f7a641, 0xf6f8ca3c58d3089e, + 0x47d58af32a91ddc2, 0x30abb6eab3f02921, 0x490df25e43f73f13, 0xf537773939d38a9b, + 0xf9099fa3212d8fc1, 0x63ae367eb959d9f8, 0x8e2e511cce74be18, 0xbeb6132d28ff4099, + 0xc88b69c57731c07e, 0x52ed6a3d227ff763, 0x52cd70822173c59f, 0xd0d299040f1250d8, + 0x5769c965f01be7a3, 0xf6db21dd26bbf942, 0x648ab14004516e12, 0xabfc349e2f1d2118, + 0x0180bb9d84d7141b, 0x134911d8e4bbaaec, 0x4b92b8f64e804905, 0x897da7bb358b6d21, + 0x38ecb2e51caf0aae, 0x6543e7e5a787f93d, 0xf571032510364cd2, 0x995b4a9a20d88c89, + 0xdd379996725be125, 0xb1df2f7a4fcad9d2, 0xa7b5fa7d47457508, 0x2575c600187cec18, + 0x1e259e3d752b00d1, 0x83580245568efa73, 0xed22d2e0508647f4, 0x84442dfc92fb06ff, + 0x3d24524ac4d2c465, 0x0462308a30d9d3e5, 0x45254a01baae8a2e, 0xd2593661cf6daf12, + 0x5dca599abe435bf0, 0xa169da8afcb3a620, 0x6cf13824af9f6508, 0x416b602161b2bbf6, + 0x5c4b342a0ead84ed, 0x654b3a33c67ed63d, 0xa31dbd4bffd8c960, 0x2f7fa743ade7d8ef, + 0x3e6c057797b29702, 0xd19f608ec8d8fdbd, 0xfc7473793f836beb, 0x3a0b20471be6e94a, + 0xec0ddc2b82cb0747, 0xdaeda7da80dde8ce, 0x98e2f9df22a96604, 0x8ab85f67eec67f06, + 0xe2874ab08c6c6e2b, 0x0445b6381fc45c42, 0x53e29b91b9afd253, 0x0d90c6f4584c9d15, + 0xbcafd803c7fa407d, 0xd4a5aebc3d150787, 0xf0d92d5deb9a8696, 0x516478a2567460c7, + 0xab9d905b209fb8a3, 0x0e93b2f066f5b023, 0x36ecf288427a2ed2, 0xcd8596762e7c1384, + 0x2755c80bb1316dd9, 0x787ab24d5a604fb9, 0xdf25cd6e045b914d, 0x968513d803c0a611, + 0x60f9fd6e5a72901a, 0x9a31b57f2e430478, 0x893c927b9668ddd5, 0xb0992fa258261de1, + 0xf4bfcc77ea4809c9, 0xc56284e868ddcfa0, 0x6f0aea97a43907c7, 0xfbb54c148bd5828b, + 0x18c1df9b3daafa9b, 0xd037d19f80bdadce, 0x06a3849d9204ccb4, 0x3ace4fd8dfca573e, + 0x35eaa6e36461d0d3, 0x17905f2a781de540, 0x2d531dd8552f2765, 0x01eeb7b6a1494475, + 0xb769488b3901a9f3, 0x7460ad9d8bcceeb9, 0x66a2abf1c7753bb8, 0xabd4a0f7fac6deb4, + 0x869252402e6a9f99, 0x109e9f4b61c6f6bd, 0x20498d04f39cdf59, 0xd62fed8ce52682d6, + 0x58f3f064c341c481, 0xaeb47ad53e382513, 0xe63d189ea323c1db, 0x106309c4f4f41c3b, + 0x828cc5c0f20462a9, 0x6d96e2a601b93c0e, 0x4cd09b8e39701ff1, 0xd909bb3be4c02cd8, + 0x5eefa9a3ec3f9511, 0x05977fb39adacec7, 0x5bb65608aa16f24f, 0x10d8c2a3b3396bd8, + 0x4b9fdb48e73da1f4, 0xaf424d81ca4837d3, 0x12977a990acddfbc, 0x30c06b0c4ad8881a, + 0xbdb45a06820f214c, 0x0d2b4dcdd1d72197, 0x6ac7be40ce1c0b24, 0xdffe969d5c0c2037, + 0xc86610f34f66b3df, 0x015c9bf09e75950a, 0xcbde1f5982ace379, 0x6a13800155ef04b7, + 0x1d092851b33025b7, 0x41d95d9e42639ac6, 0x84f5b14011d026db, 0x2de1cdf12e9cb8c0, + 0x866723c1db16de4b, 0xdca3ec1ca731d89c, 0x72976afd2d0f4836, 0xb21e68780bd8ee9a, + 0xaeece0bcd44dbd4b, 0x01b03b987a6324f8, 0xcef0026bcefa2aac, 0x85405981156ecd7d, + 0x123308b4a9c5711a, 0x721dd5dacce5bc3d, 0x26804860af6a7e95, 0x7ccbc3bf87cc4d54, + 0x5995334c3e242616, 0x3acfb676b987c213, 0x145518b80573d4c0, 0xc6ebde08aded9af4, + 0x9a4daa72d104dd8b, 0xdde4dac3cd08710b, 0x57e470f1db64f91b, 0x6c7f036eb374832a, + 0x9f07db54caab8fcf, 0xbc06cf52d8d5f56c, 0x4aea7bee9c0e0ed6, 0x282c76e18b24f8b4, + 0xcd43853968e0f8c3, 0x9cab4fb10369ef34, 0xf5aba10ba06befde, 0x99ff4d8ff311e9a0, + 0xd35aaa101d22c55a, 0xf2b3182557bf0529, 0xdd523fc5310a3ecf, 0x0b3cc5a35c82a6b7, + 0x3a15c7a108af767c, 0x0693ab9cd8951ee4, 0x05f23cff908ed521, 0xba38ae4ed8f30818, + 0x3567e7eb19841fbc, 0xd4f1f91388ce0fbd, 0x7b3440651da95cb5, 0x56b6c91fef0c0213, + 0x0c5516aa79811c1c, 0x8869b952943a29fc, 0xf382d60f67fcc2e2, 0xd3a606c601b5c66f, + 0x0d6b519f677f9e84, 0x3ef8e988f9e9e6c0, 0x8726d00ed296c2b3, 0x16429acf62bb2d8f, + 0x858ddab4a1817e91, 0x6f0b334f51351a23, 0x7f09f1f531213b6f, 0x82a81778d373eb3a, + 0xbed0e457d7a8801d, 0x632446bf2a988560, 0x3f2e4e9a57914a68, 0x45690fae01c59d44, + 0x29dc4c21401d787f, 0x5c4a52f82ad10df3, 0x7048dcd10cdece63, 0x5eee8921f4fcd342, + 0x9ffe119727f734ae, 0xf39e93dc1c8b27ad, 0x73516bbad0f603e4, 0xb6b3462b6a39a55b, + 0x4a69c806e78615c2, 0xe988794843797b0c, 0xa47dcf644f700651, 0x97662389f36ce643, + 0x17eef58bf866b33f, 0x5eb06c4515ff01bd, 0x328b8d67d4ae956f, 0xcd4d9449aea5cac5, + 0xcd382e53ed23ae1f, 0x7b1eb83b8306ace5, 0x15a8ecd063d726ba, 0x403b18162679c055, + 0xd0a5d4ebea56f425, 0xdf882dfcffcc84bc, 0x8d61a1c805ef7074, 0xeb42ebf496a7bd69, + 0x4932828fa1eda64a, 0x9b29f654ca04e515, 0x899b922465789ef1, 0xf37e88764c7ac45c, + 0x5c21a5c0dd61d736, 0x2554d8e82845136b, 0xbad57a13e441c8c8, 0xfbf59fee83ed48c0, + 0xb6dfed771b9c57aa, 0xd2a721c4ca5988de, 0x4a72eef2c3b79c4a, 0x4735ff387ce5d531, + 0x6595b84458e25402, 0x9050829a6000ae69, 0x4e309f2a26856099, 0xa8ed2943cca6016f, + 0x93533941dbcc0ace, 0x841a1067098656b6, 0x30bb10f83e216e8a, 0xb4f7130dc7e9212a, + 0x93ce7fc238b81921, 0x5b7e8e5a8f641f8c, 0x9ddc33deb95a5b71, 0x2f29f4a14bab0c77, + 0xfcfdd7e629b3cadf, 0x773924b26ef7247d, 0xda1da81a16bb9420, 0xd25e0cb35f1f1faa, + 0xc545c1a75e458451, 0xabedaafe76dcc117, 0x429b67f6ae073a8f, 0x67295cb2e7ed1851, + 0x844c475a38b961fa, 0x355386afd494c53d, 0x81c6dcf871dd881b, 0x092af9a79f4170d1, + 0x7d3dce96cbf08554, 0x72eac8accba2b32d, 0xca582b8e15cc89af, 0xc9a3d27ecf09b2f3, + 0x09acc52ed3b84f43, 0xb5b0f39553570b43, 0xe9f8c0f1152682a5, 0xdc532866d1359272, + 0xa830e1dfd3792ce9, 0x6ad5e7da482f3096, 0x0c80e17dba0aaedf, 0x306cfc30b3a85aae, + 0x13970909b51d1a80, 0x14ce48989614edc1, 0xdc467497755cbd57, 0x9660670c8b61b1f5, + 0x63d8896cd021a129, 0xff50d6958c5fb8d2, 0x39ee34cd34b67a5f, 0x8358e926ccc8e30d, + 0x99f8edca8af044d5, 0xd3cbf4330b841d22, 0xd174131b63b02eba, 0x38eb496124b15eeb, + 0x48a22e8cfb012cfc, 0xf5da2e278065962b, 0xff4403f9200acae2, 0xf184e282b6b418f7, + 0xc6b107ca5b20c9f3, 0x26f583a441e0630a, 0x92d0e75229f427bc, 0x4f703d0de9e071bc, + 0x3171ddeaace634c6, 0x12c49c6dc514680a, 0xa7002297639b4906, 0x1700f3d434b737fc, + 0xbe75a9cad6bd2300, 0x748db9d9c1cb48ba, 0xadcafa24a2f2c39b, 0xea6d56b46741bf09, + 0xc30eead02da09851, 0x8577fffe20f3731e, 0x245a5b85a5e0ebf1, 0x18e5eead89732407, + 0x746075b5bfc55131, 0xba4453d3d8e14282, 0xf8a86d159d9a709d, 0xa4f4630217f0e85b, + 0xf04d0d9b0b09c7c9, 0xe9669f06d6c1b268, 0xe2e27fbcfbda045e, 0xc8a35bec05eb827b, + 0xeb9d4eaae174d6f2, 0x03e09a3ad81dd4ff, 0xebda3404ab654a2f, 0x5d39c2892dfb220a, + 0xf1c3399fdb7845ad, 0x7d979bb1bce205b1, 0x89d18134a93a533c, 0x35b91f56afed2092, + 0x7c42374fe8984cb6, 0x9c764897cfffdca0, 0xcaac6a4d50fade17, 0xe0ef4846a887c038, + 0xd82902a52c00d995, 0xc5067a8d1a2f3a41, 0x0b4ce0b7d7daff7d, 0x9230ff23783733a8, + 0xad1951435957726a, 0x2206d08929796e05, 0xd4fe4d4127cba088, 0xa162fb5f8af4185f, + 0x3427a4e96c94f67c, 0xe86e6a15f91af428, 0xb465eb367ca10566, 0xb9e3bb2376a12196, + 0xe445463326fd5391, 0xd2cb5fc8266bef82, 0x39f16938e29cf376, 0xb5e7992af43ff901, + 0x4bd11a57af8b46ab, 0x0c5e337332e53a91, 0x5585aff51f34de17, 0x3324dae6ff8a7d31, + 0x7d1a4a46cbefccd9, 0x27f1086e10c87ee9, 0xc78c20aec8a5fdfe, 0x4da8bbb0f99ffecb, + 0xc62e8ca1d2255a8e, 0x6888bcbdff421c66, 0x4505e94b0635a09e, 0xcd4588f38a097beb, + 0x5dd66e10fd954995, 0xf4c89fe58d2946ee, 0x9a994e3b6e6e8e23, 0xd8a26b12ea5c4d4f, + 0x5ad271ccd78f3f33, 0xcc32ddea6b84a3ba, 0xe06e913d6923d4a2, 0x47d54e91bac13b53, + 0x9c284015294338fd, 0xd5e81534cce44432, 0xcbe70ca22e5c5807, 0x28449ff72f96a915, + 0xdde032503e64423c, 0xf7bdbe2478c4a4d8, 0x8b7b8d331850a22f, 0x6c6d8382d09406fb, + 0xef14705131546e8c, 0xe37d671893d4f2fc, 0x5d8d444d3e8cf4ba, 0x61572c322b045a47, + 0x82d10acd5f5bebce, 0xa1959df1dec34077, 0xe91ea4d68a7640f3, 0xe3b511c42ceef515, + 0x481f41613b55ec09, 0xcfc60e29aa074743, 0x58d29712da50cb69, 0x9912f2f0ae0595ac, + 0x43196eb35d95b713, 0x76e6a7ee0eb0d7f7, 0xa63822a6684c88ec, 0x308d561a3f241d0e, + 0xc044c871fa3ba783, 0x37dae2451b0fed32, 0xcfcc32d3fcaf9df7, 0x8363e2ee5e5c4c5c, + 0xf7ed72d0656c9949, 0xdc3b5a0fe7c9306a, 0x1c69661627293531, 0x9efda4aa036202c1, + 0x062de907d0953ad0, 0xf8041e0c6f8a9ecc, 0x6115b8f3de7a86b0, 0x347ddd33f2a2a793, + 0x8e7bcacc36680035, 0x9fa94d3cdc8750a8, 0x04e8b20daa55606e, 0x5a2280dbdb9b3752, + 0x6e31484dbd771d0e, 0xa5fc6ff489cfc13e, 0xb169aadf11e60e81, 0x2837c25fdadc2e26, + 0xf2030f4225a85995, 0x7807147e3e464e77, 0xf99091981e6bac0a, 0xc3723f3fc316243d, + 0x2741ab72959580d9, 0x1cb62f04ad353b13, 0xd083375dc8f7410b, 0xaed46d363137584e, + 0xa3d1bb4c8eb5d8f2, 0x830282b1dc1d81a1, 0x083108d71d52fa0d, 0x3b0d22596a1813ae, + 0x4267a218068f0d8e, 0x0ad610f0ff4c2d83, 0xa8c734baf1d3ad11, 0xec1fbdf9e74e9729, + 0x776d76940e9089f7, 0x423ce1f3edd46634, 0x47826701c68b519b, 0x3eedfd07b9887154, + 0x68ef1d10a42f776a, 0x6386fcab69688add, 0x36a5dd89d191c3cb, 0x8c4881e5d7393294, + 0x66def5145491bd99, 0x0a91c1fa773c3457, 0x43799ffb08efb028, 0x85cdcfb669092acb, + 0x7f4fc84c4030cbfb, 0x72269f3f2b240663, 0x2fbdd32ac29920a7, 0xbdc4d61a0367ef71, + 0xaa1216a122a659a2, 0xab1da8335c171bb0, 0x3ca0d22c3b3e45c4, 0x0f946baaadeae8d8, + 0xef14e81fdd2b364f, 0x2f55ada2ae0de459, 0x940af90140a2de69, 0xc7e75e9aabf401bc, + 0x47a9ff788e1c3a3a, 0x2ce3f69491e5dce8, 0x81dbf7dde0977adc, 0x42ba0b11851f6dd9, + 0x1b4edf339840cf0e, 0xad8ff5b21132fd4f, 0xd5e31a8a588a6101, 0x1661c89b16294868, + 0x8019be652e5068b1, 0xd91b1fada5f73c41, 0x283898bb911395dd, 0x06ba3fad70685b96, + 0xdefeb106c49760ae, 0xdad52aa98d5e77f0, 0x0b9e3af9140b5ea4, 0x6ea78774ca7519f2, + 0xcb4aa4498abb9d51, 0xa5c5b3f4d0469271, 0x397aadf70746ccb3, 0xc624e8dffabcc782, + 0xcfdc959047b20f62, 0x6839796b357d0be1, 0x2c431e27f83005b7, 0x0569f1c4a75037ca, + 0x709460772e4c876a, 0xeaa568fd7c9f7dd9, 0x4eae8ce3c8dd9b61, 0x8847a12643e7a6f3, + 0x50337833e84a623a, 0x6d0f0e64adf10b27, 0xf3029bda34083597, 0x8204c4bb5cc07376, + 0x5eb6dc8d28db1c54, 0x08f42a900ba5d9db, 0x90744ed74b2b207d, 0x1e9991f233d884f0, + 0xaf5ca8e8bfa880e6, 0xfa43aab6924390d1, 0x4a7d2a178fc16736, 0x5a4aa3bf0525ff25, + 0x00092c75b19c8544, 0x31fb7664db32f0ef, 0x196515334ea72250, 0x053efa8bfc39562f, + 0x9bf9efc1b0242cb9, 0xfdd1f568ad88cea0, 0x5bd701ea2ded6b29, 0xe3ffd2783b7121e1, + 0x6301c5c26b454d79, 0xc4d21c15e28fe4f0, 0xa2a4b664ef38802e, 0x7e23d698181dfdd3, + 0x2a76ce3fcc775c7e, 0xbcf7808774f52159, 0x080f9528ffbf916c, 0x885bebd0441de6f0, + 0x51e6593154e91061, 0xe5233d5e7b348535, 0x473b3b3f184aa822, 0x21151e7b977aaa95, + 0xde51ba8cbee9bd99, 0xae5f23f269f957cd, 0x708d74a0a5a682c7, 0x91097071cb646e5e, + 0x3bc35e10f5963bbc, 0xb426789ae226b25e, 0xef6cad6c7f12beb6, 0xeab10ec96bacab69, + 0x23f3533bb1ac8e06, 0x8a6724bfaa07e6b3, 0x7b8760a2905deae8, 0x56702de289f4e2f0, + 0xdada3f65d4f55bf8, 0x7f8c6d057d31d642, 0xc9b00abdc8495650, 0x1c51e60abc0eccd2, + 0xfec65ffbf9c42481, 0x22e8c26bb26384db, 0x6be43bc89cf09d40, 0xbd6c96655fcfe6a2, + 0xb626341c04311030, 0x905fe7ef57925046, 0x9509529bde2ef3df, 0x7948636bc0cdc7a4, + 0xc30c108a100fec81, 0x6221aa9d592e8828, 0xf3c8215591cebb72, 0xd8bf6ea39c57b9dc, + 0x1d183b59164b8c40, 0x7ea2a786319e78a6, 0xc973b32e93bc2f87, 0x9025624014782cbe, + 0xbd6e444a134eac53, 0xfe0f19b444f2e570, 0xf60bc3c21500767c, 0xa8502a4bd10e123e, + 0xded8e57012f4651f, 0xaeb1b9241eb04d7a, 0xd513f05f555fed42, 0xfa0c380af507ac6a, + 0x65b433a8dfb5ce3d, 0x98999ef103eca182, 0xf56d0853313c64ec, 0x3e0417206422ad1b, + 0xed5571f713fb7ed3, 0x02876cabef2d641d, 0x60cabfa0f8547278, 0x63a185e898896c4a, + 0x0e1ecd9e46466a47, 0xd757ae92795b1541, 0xd9dcd23ac5c15de8, 0x3b3de05121ff3a36, + 0xa11606102e19c39b, 0xd6106c43e6eb5c91, 0x5ab4cccacefee53a, 0x007b8326ebd1926d, + 0x32ba940140487c6d, 0x46e0755a22260568, 0x7790f1c8c0222f19, 0xb2bb4be2c6bded6f, + 0x175f675d63cdbf6e, 0xa1809a9af4da899a, 0xf7138f89ad5d7afb, 0x761b3fb67fd8c602, + 0xa2eca2c4334f453b, 0xf64d9dc500a7a507, 0x924adebceb539c8a, 0xc209a7edb19c905e, + 0x6dbbff18fdc777c1, 0x17fd5c2997f84b5a, 0x73c3bbc097fbb941, 0xf67681a6300cb02c, + 0x5dcfafe1b79d21f7, 0x7d4217fb0d2f24bc, 0x53cc4b66d1bf5b67, 0x8512234b09a632ee, + 0x7afef5d3c566680a, 0xcc16073d5ac4919b, 0x8cc1c7b68bbc832d, 0x50c43f4413c4c58c, + 0x724c733a800256f2, 0xff3978a5dbd4f083, 0x9b2a00ed5c8a3916, 0x69e19793abf7a632, + 0xcecb6edcab1857af, 0xa462893d3c564a29, 0x61c82e8a6cd57f10, 0x3fa79f6ccffe83c8, + 0x364ce350ccad2815, 0x83d7adbfcaf46f89, 0x4c2fd40ac0ad5ce2, 0xd51c2c33a7b276b2, + 0x37328b5094395ce3, 0x70812a15ff5243fe, 0x15ad4a85db620d26, 0xff3f9978e53508fc, + 0x4dbe3930f085dd46, 0xe68954afa8bc18b9, 0x1e20699412fc97b3, 0x2b5bc43566c8182b, + 0xe948a5e26d1d3ddc, 0xa35730ae4e899f73, 0x8187e151ade21342, 0x22ddbfb842707e88, + 0x314b8155d6b6ad5b, 0x73d0d75407a752cb, 0xd9da783ff9fa2b9d, 0xf435d414df4f5076, + 0x1dff839d5c16d42b, 0xd136dc23e40ab6c1, 0xfca6360f0e1c5a33, 0xaf1c58598e7cb56e, + 0x43dcc5d73e585d51, 0x519f6ad4eebd062b, 0x80754ac3c1d740f1, 0xaf1fe551463c5b67, + 0x1d24556ff8ace198, 0x02b91a2134d2ee23, 0x13d1ffba18d54997, 0x5d56aaa246770a3d, + 0x4fbbcd60cdb5494b, 0x848f8dffabbea9b6, 0x42672e40d5a53819, 0x584f13fbeaca5bf3, + 0xf160a9ccab6e11b4, 0x51a73a3a653b6373, 0x63c3bc25ecdf58c7, 0x325cc030e9514373, + 0xe2a6b8f7aa1916bf, 0x9c668a4c33a54663, 0x5931972834a653b2, 0xc5e8ca195ea0274e, + 0xa5a7a5e95eabfb91, 0xdd71f31da6f7c46e, 0x51b21e140a5fcb76, 0x7d4dc704d3c881db, + 0x72bb35a49a20c914, 0x1c426d0b4fe64fef, 0xecfeeaed431bab4b, 0x85ac16eb56493abb, + 0x45c61bdd78abbe40, 0x937b96bb7431209a, 0xaccf7f070abbe8fb, 0xa17a2586c5bab868, + 0x0b40d7846acd93bd, 0xe92a3100a8aa7d86, 0x5a90c85c2b95d141, 0x42b957edf0eac80b, + 0x97b291bad89c9cf3, 0x8164c5fc56ad0b3c, 0xe178efd995023ccd, 0x0035cde42dc2cf15, + 0x6a755592839eaf7a, 0x324a4b4eba667d1a, 0xf5c3460b16ba21a4, 0xde9f478017f5ef6b, + 0x8d31bc90b58a334a, 0x31fbdfe21dc8eb9c, 0x23d8b2d4a678ac83, 0x4dbb4cad0a7e2706, + 0x7c91dba2fa129d98, 0x213e75991c59be79, 0x59f768c230bde513, 0x8c2972d5ff12ff22, + 0xc691e275dd7475c9, 0x25f4ac9004ef9825, 0xfaad8de2af3a5b1a, 0x0460afdc2ee1ae1c, + 0x8f542a7f1830047a, 0x2d9c80739c120316, 0x259137908d220bb6, 0xc1f1ed239eb2e2d6, + 0x52fc97633cb4e187, 0x466c94626a15b643, 0x4a2391acbad2fc28, 0xd85fcc762fbee484, + 0xe746df69c444e173, 0xe716b7df6ff3866f, 0xde7f692c0021274f, 0xb5ff42f5c63a693a, + 0x183370004c000aa6, 0xcbb94a5f3fd9d41a, 0x592117ec50ae9cf2, 0xba6d987fe545a9d9, + 0x7f564fc0813b5d4d, 0xb0c3c5252443ec98, 0xf763d3b20ef393ef, 0x86ba065985aab176, + 0x1089bea456d640dc, 0x572ab615149aaddc, 0xbb18497c0b5e8699, 0x42acc8ecf1858fd0, + 0xc7033a8ea70569dd, 0xf6670a5251e942ca, 0x76f01cc756a45ce9, 0x12192f6c25bb90b7, + 0x5e67d8c073397f3e, 0x5943d66bca82b331, 0x2177d44402e76b82, 0x1e247b0fb5819ef9, + 0x69f15537f160c9db, 0x2b7b74de9915f35c, 0xb028cd637d5f3b3f, 0x730cac8955b4a829, + 0xff62e2a27178e739, 0xd895fd5a4574f298, 0x9245177f0510e27b, 0xf5d500feda9a7127, + 0x073a60f73af7d8b2, 0x36fc50273862bdbb, 0xcf8391afee8b886a, 0xcd304e07207e8fd6, + 0xf71260f3d5316697, 0xe8d71e81ffa497c1, 0xa945c9b42720abae, 0x45e5de0e5987e1ad, + 0xce05418c9fdb0589, 0x94a780beb0eda9d8, 0x5b7ded5404d3fa8c, 0xdbe264a2ee1ad880, + 0x7aebcd67079987f5, 0xf60062c177a57277, 0x9f71be1267cec822, 0x3f901c7848bef8e0, + 0xecebbadd7dbef974, 0x3d01a5999ab31878, 0x9646807f6f1f91ba, 0xd8b30022c4e5f774, + 0xd4f845b74984a74a, 0x9ef317840a4cd193, 0x201c39b8e0cbedc6, 0x19204c0d6c7fab92, + 0x2aff1d698b3e9596, 0x03c3310096cbfdfd, 0x37fb5e89e4ade4a1, 0x73fd021127db2008, + 0x1e56cc63984cbbdf, 0x884aa70a81db42e6, 0x2230ad7167d0a7ee, 0x6eac311bf6f3a5af, + 0xa6bb02fdb15ad981, 0xd53d933ff264dba9, 0xa46551cb65cfac45, 0x666c41a76471a819, + 0x7bd7ba38a851312a, 0x480fa8cd7fa30feb, 0xa5c42ef922662d51, 0x0afa1c9a8be1ab4f, + 0x8d9c9aa214346d55, 0x516094082cdc3e18, 0x16a963ea107997d4, 0x8280001138c15cfc, + 0xe4ab234bb9ff258d, 0x69880d3b6699086d, 0x3d7d3d1e32308eca, 0xbed0774a3daa1b2e, + 0xb6df4485983a76d4, 0xc6fb7d520aee753e, 0xdb74f71648c81d1f, 0xb88725df36319c29, + 0x9d0c477978210a58, 0x841060a628470c02, 0x70ccd8bc370e425c, 0x1634e628b865cc42, + 0x0e037ed34a49d063, 0x53cdc28cf90ff0e6, 0x348b5047fc84dcbc, 0xf79591be4e039c0b, + 0x9e5db80c33f78fb6, 0x69ce92f11c21829d, 0x919dc94a46942844, 0x0d8185a00b9273ca, + 0xbb19136e4077238d, 0xdd9d4ca7441d8075, 0xd51e8bfd157c3dca, 0xcefba865bb345540, + 0x89564e91dd8456bc, 0x1029166c5b13d782, 0xe02cd50a812d2c44, 0x654de0c9dadd2e89, + 0x14709b5a9e1a3379, 0xff2a7b2dc49a6ce6, 0x93bb630b0c412bd8, 0x11f4f036687dd7c0, + 0xee7fad8f341b1c8f, 0xaf83447eca86634e, 0xbd9c1795dc812ce4, 0xb7099de7e683f6bc, + 0x2d39ca5fc097f911, 0xfdff3a8358576b7a, 0x272beaee1c8f9796, 0x726e78ffdbc59ca0, + 0xb67d5853eaa0c878, 0xc03a497efc478336, 0xdc72b0f36a94a20f, 0x15d177b6ad45123a, + 0xb887bb864c795fb3, 0x6566180c005efe01, 0xb3b53dc1f6851821, 0x44699e38ee0a6581, + 0x1c55a93806333642, 0x1fcbc68cd58d1cd6, 0xa244bb60d708e219, 0x07173dff1b5350f7, + 0xb8715e9116baeff0, 0xd3752ba762ba2ca1, 0x86d91965e5a31a56, 0x3c27c4951d076d17, + 0xd41f651c2ade59ba, 0x8f2ca8db21b97bc5, 0x1c2a1efdae15b528, 0x96977c9dcdba8c3a, + 0x91c8ddf3688697af, 0xc2de47e16a2fa935, 0x01d09ee453aeaf90, 0x9dbc205a2b000616, + 0xc7a82e96d594c62e, 0x3317b8eb5b8b73e5, 0xfff7c8b4c3a32096, 0x6453b70094e3358c, + 0x2b1bae699aff8a4e, 0xbf7b4736ad753b49, 0x20f6e0752f5bfc7b, 0x497dd9715e1cd5d4, + 0xa91030923e88ceb4, 0x602ac3f33ced7c4c, 0xbf584ae8dfb8e2d9, 0x3105b41ec3549b6f, + 0x163d3abbe998423f, 0x51234aac25187982, 0x8770f9bcfe97c132, 0x1800daeee2fe2a88, + 0x0f02b3a8243fd4aa, 0x4a536e070e2bc9ae, 0x628c64308bc9c315, 0xfbecf1323c9722d9, + 0x331ad785fc3e1d41, 0x5f5508bdfb62937d, 0x91a3214706923e0c, 0xfc796e8da1017f42, + 0xaafe90f59343d9bc, 0x2d136e33a60bef49, 0x02f9f2c3db9d0229, 0xd4892cd932be8419, + 0x79c72ac302f0d281, 0x8abb8e35b1d94786, 0x0c6de808c0c12a8d, 0xac6d4d8e5b9c2ed0, + 0xcba0baa1708e791d, 0x4bec127f651f20ff, 0x261d3b5a50d67450, 0x0fc781b9f92cd6c3, + 0x383faf53f2a71eb8, 0x0c20e971447ba60d, 0x3bdbd7533c088d5b, 0x56c8661b6d330584, + 0xb60ad35ea1d2263f, 0x737d7418bce8ebe2, 0xdda539ab99ec21ed, 0xe5c1cea1abbce298, + 0x4c92449387476985, 0x9c3be4e72e40685f, 0xf6d9c228a9f85902, 0xa44764c91adc6a9a, + 0x0db0d2ba599a7553, 0xe3788aa1dd74946a, 0xd239baffacd81b2e, 0xef52f85666c340f8, + 0xaaadb6ea9b1c8a45, 0x86fc426284837b81, 0xb33810a5001fa2cf, 0xf990bd17f7e2ecf7, + 0x14aa4676275e6c1c, 0xf19a05d12146d05e, 0xea5f3c7c6d5b9b4f, 0x32efb45c62042da0, + 0x7f430093a67ce3ea, 0xc8f47792c4d16d4a, 0xa7e72976b7f5e237, 0x26550333603f8d3e, + 0x9b8fe810f3c3b225, 0x65e904778694f5c3, 0xe18bde37757c008c, 0x4fc064ba9ccda596, + 0xa6ec138b14e30506, 0x064b8d8f63af9202, 0xc3783b153f753ecd, 0x20315c3032141460, + 0xbe04af9758a4cb35, 0xa7f4476ceb2653a3, 0xc4699159169fac3b, 0x4e2d709e9b1d01cd, + 0x4ec5972ace479262, 0x2fc417acdf559f30, 0x0605a730b11000e5, 0x8b65acbb6a17e365, + 0xd967fbe917266184, 0x1c10125e01f5db0a, 0xbf638c23b61967f9, 0x71b359fac654beb9, + 0x9d83451d64277002, 0xc8777ce755abe4f8, 0xfb4530585d7e824a, 0x63c28165d9737d56, + 0x7d9dbb4c39824fe3, 0x469e8165902bacf8, 0x5fad83c408ef9c40, 0xf8b2d576c30d1026, + 0x29f9f4bea44b1781, 0xac726909624bfe7c, 0xaafd751738177909, 0x90563245ba1c612c, + 0x389ec2a7d7e59ce3, 0x50500c567966d3c3, 0x26b15bf6cb1ad6cc, 0xe9080fe122c631b5, + 0x17f6dabe12e3e5d3, 0xc3f85d05a0f070f8, 0x67d33630af152ed4, 0xdb3b4096c5c332d7, + 0xc3dd07768e70b774, 0xa1e0b82d0516b75c, 0x867ca995ad903a61, 0x4fcd47a488ba6d51, + 0x6c6aba39dfc7d00e, 0xab65e0c18b16269b, 0x09ba717e85654122, 0x07e4cb761fb1b0e5, + 0x9265799c5d55a837, 0xf7e6d513b6437316, 0x94a696b3988e41e6, 0x2607761bf2629a5f, + 0x973e75d9df82ece9, 0x48730461eb3c4d75, 0x5796dc273ed9d51a, 0xf325bafd97b61151, + 0x7007d37e9b53ea4c, 0x3368fe5e05f94087, 0xadd778da036b0736, 0xc31fcbabf6fdf8d7, + 0x35de52e719187698, 0x1d2f3e4087fa3c08, 0x8047f5eb6ee05190, 0xd5add1eda45df387, + 0xc2431d8a98a8fe49, 0xb1c0388fa3162e61, 0x1f0ab07565c55677, 0x7f3b14c57417b083, + 0x1f0ffa4f1abb4291, 0xdfec55dc328de4d0, 0xb792695f0a121172, 0xe684ea8df0457fae, + 0xcef58a827a97e9ba, 0xfd341be16fb9e359, 0xc87a2331a9fb1692, 0x2527b948cee2e7e3, + 0x5e101fbe7514323e, 0x0d06560293e73c10, 0x1829f79b98724d80, 0x0c6ea39a34167a64, + 0x1da654dac1c2b486, 0x4381d7a197d73b93, 0xed2de677dfea2660, 0x98cf929f0489101c, + 0xd6f382504a8d8ea7, 0x483110e79c14ef66, 0xce485d95bbc34776, 0xaec1a6a8430e7289, + 0xcafe578fb670a41a, 0x61243b580f10d832, 0x221c3043ce630b2f, 0x8e8705368c784121, + 0x7963cf963518f155, 0xc21b75f27e48406f, 0x8f2f2bb31db2a418, 0x467a4ce355531acb, + 0xd45bfce4db6ad410, 0x116a3d9dbd9162db, 0x26b549e62d30c113, 0xb4799b40daeb1ca5, + 0xac6d4450ef27b16a, 0x51303f5d166ed3ae, 0x2a7b47acf0255aef, 0x85c10733b0fd7de5, + 0xfa1b80f6fcd647ba, 0xc3b3a75c8e36ba96, 0xb89f7cf587c773bb, 0x2585e4ca847ec1e1, + 0x8f587f5b9b828303, 0xdaf3e553b32110ee, 0x5a080e99f299f28b, 0x60b02561cbf056d9, + 0x819439e181a81c62, 0x68e7551c7255e324, 0x8e47a1bdf4e2642f, 0x30b7c9517b5baffe, + 0x2effcd65da6cf6e5, 0xc0e53b063106b643, 0xd1ac9588459392bf, 0xc3a9b3fe5c4914b8, + 0x6fd4a4e70d53afbc, 0xb16f9f98ee51d7d6, 0xc372f1f76b65fc1c, 0x7ace9609a780c6dc, + 0x4b62ba7528b34440, 0xba37cf920321a2ec, 0xdab82152af4d36ec, 0x359da66c3e405aa0, + 0x32133b6e7e57f6b4, 0xfb739dd61168c5ee, 0xfbfc045b30bf74a2, 0xc1c2002bb95c9009, + 0xfb0e87292c13de33, 0xe6a1ada23c8a0b87, 0x4a4ad963b5c4b22f, 0xed9800b5e15d4c3f, + 0x1d3fd890d8ae7729, 0x46aa7d9d9bae01b2, 0x4f6e3a19e1a8fb67, 0x2b460d0337d72c74, + 0x7be622092baae6c5, 0x8949c3aeda3c2feb, 0xa9d884a9e4704860, 0xfd3dd63e0fd6e075, + 0x5de1715bbc8b024c, 0xaebb8f1195f7516c, 0x3bd0bf7a3f4a5378, 0xddd22dd5c8597960, + 0x94e9199dc8d209b4, 0x5de530f34523777b, 0x51ba8ba0b866a17e, 0xfd55a04a1d22b19c, + 0xcdb238bd4130d0d6, 0xa06aeb43357757f5, 0xa475cc0cc62d4527, 0x6d0e779b6e6a8758, + 0x713405fae15e9778, 0x0f00a2b27568a6a3, 0x62bd58efbe3090fb, 0xf05cdf4c267eb1b6, + 0x5e62d04738221b8e, 0xf5b9900f1295612f, 0xa0e5749d177233cf, 0xc44c5592311f8054, + 0xbd52eb6cdf769fe2, 0xdd0d254454cf2122, 0xb981221ff70b0658, 0x3c36fb55ff496fd5, + 0xf430a57f99390967, 0x0954ace551e02989, 0xaafe4ec82b2d9387, 0x6d9fb14548a4f4bc, + 0x8031a9996ef12134, 0xf6416c9d68835bd2, 0xaffdc09d53a51a0c, 0x19ecea50392e51e3, + 0x34a13752a3b17634, 0xee74fe197f0a21c7, 0x428f82d78e4fdbf6, 0x43d9a86b4ee32b41, + 0x37bcb35d71d05a42, 0x6f9295c16c0084c8, 0x83be0ff5413d3a04, 0x3cd1cc1bba243b00, + 0x9a355c5fe780c65d, 0x96f751125aa49305, 0x4996cbc8f7336602, 0x0c35ae189a910bda, + 0x17aa114cd1e76239, 0x3b9a332aabe8563a, 0xe1275ec7a3241720, 0x7725b43f265d42a2, + 0x652de643921dc113, 0x95074114a43d3ba2, 0x6ac46e80d122a80f, 0x1af28df0f5ddb5d8, + 0xc49b4fcafd637609, 0x60812edd2d354b6f, 0x3491bbfbc599c6e0, 0xfc5c0fada9da1453, + 0xb9d457569b43643a, 0x70ba805435dffd85, 0x128cc37ce3a2d1e3, 0xa5e7f2845bf10011, + 0x5a9599124872a087, 0x6358b4f5deaff08f, 0x2d11e3e6dc803a0d, 0xe028f2b88218e837, + 0x0f71a38a839a4b4b, 0xc92a5c359039daaf, 0xb2cc835b6228f5db, 0x8ae04d563cbc4d7a, + 0x1c1cac7a75e61830, 0xfd2fd5f227d0984a, 0xaa90ea33113594e1, 0xf9e02ffebbe576ff, + 0x5ce891014479b80c, 0x605419be299f8523, 0x83202fb7a4ae2a75, 0xf6e64ff96707e5d7, + 0x3ccaf13d7dd066ce, 0x01aac585c5b5e009, 0x1b4aab8014566d6e, 0x11e7198efab59ba3, + 0x24a323f70fc7120c, 0x5609b08316141155, 0x98b0a7b806547c85, 0xaca41a2e51149415, + 0xcf751f8bd38bf1f5, 0x58ccdf65c8344efe, 0x6c72df390c015ec8, 0x133f9c9c23306d85, + 0x61d1cfe15b558202, 0x6a3c4c3582a5f673, 0x637f9512f4c797a7, 0xd330644463579ff0, + 0xf16e1e34b4ee7ea3, 0x618000e4502dc31c, 0xaa71c457381d0335, 0xf8d920561946d767, + 0x9cecf035b94a3d40, 0x3e4545a17b61d5d5, 0x1c3564aa53e6e73f, 0xc2f4bd3857b00d4b, + 0x211858b81239b300, 0x5e4926ac16c86f0a, 0xe83e64adca66d4c2, 0x63f875c830616302, + 0xc6d8069d2b091649, 0x92f747c0d271c5eb, 0x39fa58b367129527, 0x4984ea9b3a80ff9d, + 0x354da29136527160, 0x997edad9709c86fc, 0xad497e23b94da9bf, 0x7d12cc94bd4d5b76, + 0xcabccf6f82027a0d, 0xed6559dcebfc6c95, 0x2f81892df9e2941b, 0x83c3531b95bc842b, + 0xe48a4ee1f58654e0, 0x05fdbf72d0daa87b, 0x51ad2decf57851ea, 0xd61ba55be8f651a5, + 0xceed919f6700c3e6, 0x763257403bff52ef, 0x61af8a4943b1a111, 0xddaf8c619a405fef, + 0xd722bc84759b7dea, 0x35e5a14698bb02c2, 0xadcf17d7252bb6e3, 0xffe831ce375687b0, + 0x02a7b4f8dba11145, 0xd4e67ff0a1cc75bd, 0xf6bed864cb3c0f74, 0xe379cc57b232b594, + 0xb6599ef34e3d74df, 0xd06b61e56f72748b, 0x2ad1cf0c57a4d409, 0x98afe437bbe1e3aa, + 0x1e21f20f87f1dcfb, 0xaaf3d2c81546a6f4, 0x7d14ff98c8a0d395, 0x3664b61f266003a0, + 0x707b3ab273ddc773, 0xbb486f128f8ecd85, 0x7a396e34185f08f6, 0xa9d40d14282ef537, + 0xad0fa6ce1e0d0138, 0x990146e8ced1b2ef, 0xb73509ea936fd5e5, 0x8408168b79b481aa, + 0x9217fc8086230dd9, 0xaf81fa1a7a00519d, 0xd3c65b61ac9d8d7d, 0x3e83ff6d216d466a, + 0x6393d00840e8fe0b, 0x5195eff7a58ecd18, 0x7b7aabcecde2f2bb, 0x1553aee7976dbbb9, + 0x5d7f749ca175d496, 0x6292f95e5d333f51, 0xffe7f74bb8baf5a7, 0xe9649e0679728c39, + 0xa937ccfa06522d38, 0xa7495d7e37c3a928, 0x974158e812ddc092, 0x9a6e70c82ca0b636, + 0x4ba73f678b2d9ba1, 0x752ba57f558e6a5d, 0x9586e2990a7af7b4, 0xa486d8ada4ae89fd, + 0x15ba224f45406dcb, 0x5854cc00ca213240, 0x12cd7a5d7053add0, 0x960b6b398a21e899, + 0xac81ded4ec6e91d1, 0xe148de8034d93ae0, 0x3084579bb0d44847, 0xdb718742421f4cc0, + 0x7358c2d19a2d549a, 0x929c1c9f9de2d932, 0x269b4d558077ce0b, 0x25fcf5912e113dc7, + 0x04cc755f9b71f92b, 0x54069e1f886a4974, 0x5789c6348dc58a5a, 0x1dd27d9819361398, + 0x7a2c2390a9dead06, 0x836b38bd06ad26e8, 0x735114cacf0abb97, 0x4ecfb2f5999e82c0, + 0x85cd7efe9da98029, 0x88e472a38d18b4ce, 0x6e0a3ee3d8777812, 0xa05e44ebb1425ce7, + 0xeb884cca4ee53297, 0x67a0f982cb5689e9, 0x84fee0ff278b4fa9, 0xa002601e44d5e266, + 0x95fa98bbdae12807, 0x118c212dbb88133f, 0x9ede913100051a91, 0xd354ec4f9b29f406, + 0x032ab62fc51a4ed6, 0xbfa91cfd68c85311, 0xfb98f0ef27647507, 0x5e418f8926b631ad, + 0xc17e3e4fee8c4e5a, 0xc221a1b7acf82d68, 0x67bc9540ebff48f4, 0x390b760628e7982d, + 0x0d9a4b18c65ca2ac, 0xe27166e392c64490, 0x081ae367a842acde, 0xa041f47bfe8bde53, + 0x4992b5f7f17e54af, 0x99c4a493193d843c, 0x932846bd07cfbaba, 0x1de956fd8e865a43, + 0xeba2f84cbff126af, 0xfc5a5703ac806638, 0x47cbc2aece2dfa99, 0x20cbbf78bd8d99e2, + 0x22f23b1804c21205, 0x401b1e0887941f00, 0x4421d0c0c7631a72, 0xb7cdbc7b4156fde4, + 0x61fce30f2abd51d0, 0xbc70fa9f22178665, 0x94516d4d06878320, 0xfb4a042f53e53e96, + 0x34e40b1d511804ac, 0x22f37391e01602d1, 0xc280b1aa78edf92d, 0x0efbce19d6a90f10, + 0x2bd9185734d40dcc, 0x213d47ac1e778360, 0xc63af769b6d25114, 0x13232c903e39fab3, + 0xb6757d5b86fd514f, 0x1a6dd98096301f47, 0x18bab6a726908647, 0x05d536ca761feda8, + 0x15bff4d2b834d102, 0x0ddc2d840252dd3a, 0x766542ad05502aff, 0x109015445ce703d5, + 0xae20cb8c3d9dfea0, 0x46c095b0284fdcde, 0x2aec0ae73dbf67c3, 0x85bd72390c54277b, + 0x85d589367f593a03, 0x8c18f9bb056fff2e, 0xfa2e3c913319abe9, 0x9ff6e4cd79254ae9, + 0x03fc24efd2f3d4b4, 0xb2706372e82111fb, 0x097721ba480b1e14, 0x9e06c158cd3746a9, + 0x683ec04d3612e0bb, 0xed3a15599cbe3da5, 0x807d052bd2d5260c, 0xdd923767b4122b7b, + 0xd186423ef1afb4c9, 0x22ac6c53b4c862e1, 0x13da7b1fca53e5df, 0xdd5251565fab22e4, + 0xa1197271cface62f, 0xc877adf578cd19a2, 0xee960066597841bd, 0x366359a40c773e2d, + 0xaeabb0a3600f13fd, 0xabebe74e161a2d18, 0xd71b9e26fe2b124d, 0xc4662e6e1f313619, + 0xfe173a50c65e8caf, 0x1bec45186302f028, 0xc075ff623f3bb554, 0x4323d08715ed7717, + 0xbb776e2356075217, 0x1de047b5503e9641, 0x2e1bae289a76bdd7, 0xa757dc4e78636ced, + 0x1095069123a4d1f9, 0x3f14e9b797008cda, 0xec63848d50b81ff9, 0xaf3b5cad36a95559, + 0x233f53e5cf01a158, 0x5c8d2abb26b8dcce, 0x6d7537e21ef21ad0, 0x3c97225a9782d11a, + 0xa6d3757ad819677a, 0xbb1692af9785433d, 0xd185a54d16cc6631, 0x39a85ac7b47d54d7, + 0xb1a3cc96aa01e9b6, 0x8e7379d626c41f79, 0xde4e39bf11f63063, 0x3583d9a70f56bdd6, + 0x4a41104b4edc1f13, 0xb32372a1e2403d80, 0x24f4942ad83baa34, 0x851fed6fc80a5dab, + 0xcf66b12331d0de29, 0xd29c8987a3759f4f, 0xb724eca99bd71bd8, 0x998eed25e5462fd7, + 0x18cc0667b23ed309, 0xa1678d75c0f9970e, 0x0e94c4407c882ebc, 0xaff49c696b108ff0, + 0x8b85dc03cf67af83, 0xc3b8971a2c053ba2, 0x51b58872e31237dd, 0x270d8a4bdac2c029, + 0x592315a7ffdee7ab, 0x6f9616538e5248cb, 0xd3852c3c412ced71, 0x627199cb4cea1797, + 0xcce13b89571aae9a, 0x6d89ba4fb0251209, 0x1c9f50ab6c243e6b, 0x8aa0b93b2dc1383c, + 0x7f548b6e1f79e9ab, 0x0cebfb32a3be244f, 0x017d1af1793fd3cd, 0x00ff6670e1a38c31, + 0x36eed14d0e34adc7, 0x3abe441ae4f2a164, 0xb72d2b9e2fb7d8d3, 0x9da2accc7a9055af, + 0x97d125518e51fa97, 0x99c34b9a44826d1f, 0x4f4076a28ddf9638, 0xf9c53f64cc369d29, + 0x511e0048328995c1, 0xa88a11c39be88ceb, 0x2cf0f489fdd207e5, 0x9340574aef831f56, + 0x804be4f3f31293ea, 0xbb4faf64c2a79175, 0x7e1b92775f22058c, 0x64ddc9fad2caaf6a, + 0x0cc102dd78d54fcb, 0x75420b65bd9076d6, 0x43ad0f0faf4e6657, 0x7b7be9498e27286c, + 0x28ebea8ca428e47f, 0xb8261eee41c26b60, 0xfb9699617411b1bf, 0xb2f5a238c8e024f6, + 0x7e6243e5c35f8bd3, 0x9d8a370c1d4933d7, 0xf90035f232f83b9d, 0xde869941089e4792, + 0xbb56c69fc5e94c5d, 0x3c20a31cb2acfee3, 0xec681c5669d1aed4, 0x35f813bbbd63efc8, + 0x230bf3de5360fa81, 0x019ca9307351b1ea, 0x89483d5f294ad0d1, 0x2d26d5c3523a7bb0, + 0xf448b3a734829026, 0xea966ac84c0d84a0, 0xbbc75b0df9cb45b3, 0x223fc92dd877705e, + 0x82116ddf8aa5f946, 0xd833740e0435e67f, 0x3dd62d9029b2c9b5, 0x9d586c02e7d84980, + 0x053549bc36234aa6, 0xb714a37694615d34, 0x310fe9eeb979f658, 0x49195c1ebd4390dd, + 0xf8eca25389e4ad62, 0x3c0aec86657896d5, 0xb4ff852a39a579ed, 0x746e85d2c5b681b8, + 0xa79919f1fed354ee, 0x3b5af8c711d7552e, 0x2ad734a81d085256, 0xace41048241012e7, + 0x136b210fcacc5cba, 0x9030ac05d3bc5ef7, 0xae4581e0662ea88a, 0x9dab74fde9f5e395, + 0x97c99675e85ca95b, 0xa6daedb7fba8027a, 0x627efe55a1a9d222, 0xa1ca5bf7d9bdb3b2, + 0x7f9a4f4ff38af6a5, 0xe6daaa3132c047e9, 0x8ed319a4c49017d8, 0xdecec69b23dde41c, + 0x6252770bd96b69b8, 0x57a7550df92a1734, 0xa515e7cc2adc773d, 0x4a0275ace8116020, + 0x8d457d4f899101da, 0xab405c20ee2cc2e7, 0x3dc8c539033cc8f8, 0x1722b2c04c0bdb46, + 0xa5e9648b2dacd730, 0x7034710480a5bd9a, 0x7eac55fe42fbd17d, 0x09289386d2f4082b, + 0xd1a2f0078ce8def6, 0x1242812623174229, 0x08599f664d91c228, 0xc81c406a7396224e, + 0xd509938218066269, 0xd2343389470438bf, 0x3447fb9f941dae35, 0x004de4a9a48ac636, + 0x27ca90f4689c2301, 0x2f3412defbbc0ce5, 0x2ee5bb659869f6c3, 0x15261632db5911f7, + 0x4199cac2a1336353, 0xebf5478d0e80e1e5, 0x48e4fa2e689db485, 0x9f8fc1c1df2169c7, + 0x58acc70991dedf76, 0x32bd6dd6df76e594, 0xb1294d9a558addef, 0x939f07081590bd58, + 0xe7353289595edd46, 0x6843a58ece448307, 0xa4f54869bbaa00e0, 0x3b74ece02c301fda, + 0xe5c428dbe2f92851, 0xa968e8cd8720a09a, 0x04200b07e3772957, 0xf5ea6a41259fe96b, + 0x51ba8890646974d1, 0x23a5b771eb9ef59a, 0x8ce5a677e27e30fa, 0xcd275c9060dad20b, + 0x3db013fabfb3e7f0, 0x05285a98f8dcb9df, 0xfa1f29b103bbb7ef, 0x99b296a1cf43bdea, + 0xb4a6f3c0a0b38b3d, 0xaeb12c1aeb5f28d8, 0xae2f1f03eb3e3968, 0x9693b9a888df1b69, + 0xbec2bac7d73e3d13, 0x820cdad7cbb99d6b, 0xfe541ea866e19a24, 0xf8e2001b77881b99, + 0x4442c8e030e9d71f, 0x3370b7879f9014e3, 0xb37106c5ed768dff, 0xf5f96b4753b52deb, + 0xeb5b72aa23740779, 0x3c02fd793a6a8c6a, 0xbfb37fd699f63b3d, 0x637caaa95593d047, + 0xcc3db0ced7526e79, 0xda0ba925cfaab89c, 0x0a1e599f26764a93, 0x98619f3e4d9ae02b, + 0x9cfce1cf38a28a84, 0x49e24fd3eeb4444f, 0xc55ba9775274a5d1, 0x4039064d18391462, + 0x49bad4dba89b74f5, 0x87a4287d22a51523, 0x08007c717cdbd135, 0xfde0ad0c0dc31b17, + 0xfca05d8e9d566c4a, 0xe1c22849a715f865, 0x4f77083d9194bd32, 0x04de5434dc8aa50a, + 0x8786c84405db498d, 0x451cf2e8867c0994, 0xf6277144136903e6, 0x3d442f97db571722, + 0x14afeca0645cfaa3, 0x1ca827f4190b6464, 0x9b1a7cb30ee81922, 0xdedbbecf9c1f0335, + 0x7f4eb403f969fea2, 0x5ac4f8a651f1348e, 0x003fc5816243b999, 0xe5fe41ff42ee5925, + 0x973631b960509287, 0x06a13b8162813286, 0x9f9f8709acd52ff3, 0x5c11e094abaece8b, + 0x354a7913bd03c8a2, 0x2eafde865751f313, 0x0b8712a8ef75ec69, 0xe848590e2df8c405, + 0x60770245efcbc022, 0x218656367a1d7070, 0xf44c069e7f97795e, 0x72b0541de7a5879c, + 0x08358548d77ac787, 0x92e2c32dc055d4f8, 0x4cc1abe176a5d932, 0x9ec9aab004d3ff13, + 0x0ee5fd1c3b8aec79, 0x5d8f935675f05c32, 0x68ff2e62e4518e70, 0x501f9f82e0fca152, + 0x842603f19c33c874, 0xc735950dc7e2f996, 0x8c1d99be490e3597, 0x8e42d0e66230fe93, + 0xae329aa1564a80e9, 0x5649e17791c1ef21, 0xd02fb4de5056b33c, 0xaf53eb7e9c69160f, + 0x526587c48aeb958b, 0xe5bd7f689e8f1d01, 0xfa7c125443e9cf4b, 0xda376c156aa7605a, + 0x7ec566537c0424d6, 0x8c1a06af932c661f, 0xcd9125069014bc3c, 0xee08acb4bbfc0cee, + 0xe6501cae883efb79, 0xa6f190b1ce1a8394, 0x2c8f90c4a264b718, 0x34a813d4c676a289, + 0xd9ac28124c66cdb9, 0xa84842ddf899fee5, 0xd6f4dfb2165b1a4a, 0xdd9d2eb71a17b11b, + 0xcd78677ebb392b2d, 0xec292883c27357c7, 0xbce91e11f9830d92, 0x7aa8b68435489adb, + 0x54eb584bcdfea954, 0xb8dd62f763e7e58e, 0xa438f6df8db982d8, 0xca9441de3b544abb, + 0x1deda190c70f9a4a, 0x445bb6ced6490995, 0x76bf6a3ded7b314d, 0x8a66f016dfdfab07, + 0x64a21901e2bbdbac, 0x191ff6bb807fc7f4, 0x86b368995e99d41e, 0x417e6535be219210, + 0x1491867633f53559, 0x0cecb02863af988a, 0x8e4e386e752beffa, 0x4ba58fed077cf4a5, + 0xd777631cb7cc0ef3, 0xe11c0ccd18c90c4f, 0x9343426a5050f38e, 0x55efc291307ee56d, + 0x0fbcae5d59aeb627, 0x288b467aa5bdfbca, 0xc0a392953f680019, 0x48916fc91ba84c06, + 0x4a8b4836ba342ed5, 0x03142a9ea4c0e59d, 0xcf342a86d47380b3, 0x3454da8dc9c8791a, + 0x0260f14f96803fa0, 0x973bbe79a5f164a8, 0x49edc10d9edee956, 0x0cf5cacd8fccfba6, + 0xdb4f8f51bb534076, 0x470b7f9d70824b90, 0x1a2e4d589fbe3c75, 0xcbc03b148e363146, + 0x99ee702383e08652, 0x7d3a7bc2b1d17942, 0xe29dbdde2a789780, 0xd05be133837d8a4a, + 0xf2657c5783404faa, 0xe4c60bef204ebf83, 0x8af681c946077603, 0xa4c30856371c7ea4, + 0xfd8491493be53498, 0x65b4bb5c0b432d37, 0xf36cf84d1e69c2fc, 0x72540952b560db4c, + 0x926fe399b48b06bd, 0xbe7bba0600877983, 0x78756a5857287bcf, 0x39344c4f631fab92, + 0x8938f0d75f41bb00, 0x62950eb07231d85c, 0x151250c44835e534, 0xeaa6153d366040b6, + 0x0399ff3ab9d2029b, 0x4f9291ac66bea780, 0x5538b8774466b317, 0x104a472bddd01ce6, + 0xbb530a2727a7c317, 0x12a408915c974a92, 0x02d8e5447e228765, 0xbb6c944b06c2be01, + 0x860518c2841ca8a0, 0x68edab4683438cfd, 0xd5764f712a25913f, 0x14a6ec6cfa7c3115, + 0x6f0cc123ec798547, 0x19ae22cc367c885f, 0xd7be6d5f449e5951, 0x8555f4f8fd21152f, + 0xf3335605e1495f41, 0xb2ea3183d8e360a9, 0xb6221434c5c90c63, 0xdf215d9c2e93390e, + 0x98519ef2b0af8143, 0x06044c2d81e1edf6, 0x645f2661d1fc17e2, 0x469a5d2269c3b05f, + 0xca70212744447558, 0x07a4eb3b4b8e8cfd, 0xef200622675d49f9, 0xd7024c3ac1a6d90c, + 0x5c54fcec35596bf2, 0x030e135fcb8673a0, 0x9f1cc6537857af20, 0xbf75a9960af6a424, + 0xa1ce52907049fd5f, 0xb85d9f1d69b9e757, 0x85beffbfcc396269, 0x0bdf4af30f73131a, + 0x74e5c58ffc16a8fe, 0xc3cc87ed72fe0e64, 0x604c1bc18d443cba, 0x9a1b8fd3634f1d41, + 0xa33795d2516fad6e, 0x99ac9eb1c2ada062, 0xa2713d9be0bcb94d, 0xfd2f6b2989fdf4ea, + 0x55e33b2805a13f58, 0x2c7bd9290ee9b966, 0x81fd6f83134014ff, 0x179f8894deefcc6f, + 0xc61c8e56d5fdb3c0, 0xa4e5343bc6afdde1, 0x36ad5e9310f6d4eb, 0xd5fd90a79e27cc78, + 0xd8ccd606e4d48e8d, 0x25f66a9cc989fed6, 0x3d0402457fc4bae1, 0x612733dcf3d0d07b, + 0xe38fd4832db05d6c, 0x8e2809b7ea934954, 0x52004f18865f4734, 0xbb8ee10a8dd754c1, + 0x0fd0437b265a01b3, 0xad6498e5df9586e8, 0x8e143ecbe7db3bba, 0x17331ca3a86566a0, + 0x50cf16807d23b56d, 0x7c52f40e61c17c15, 0x70aff594054aca7d, 0xa9005fada5801d62, + 0xc2c62f1740a8a26d, 0xccccb11f991fb387, 0x2f38ade83ab14eac, 0x33a947c235f4d753, + 0xa5625e617031d563, 0x4f964fabfa8b3b58, 0x84b4e9eaead9b63c, 0x6df29966734e4146, + 0x11dd7ce026d0c29a, 0x9963e5fa15f8d521, 0x1e20c4ade063847d, 0xaed43f08f72a9080, + 0x3dd7ce36cef85b37, 0x78e5e46f7874aed5, 0x5ded630f68dab2fa, 0x9e41471fb56fd63b, + 0xda4d8c5b0c650d1c, 0x9939dd39cf15b48c, 0xc4caf8da2e6475b3, 0x783e1a913f0b79cb, + 0xd6131558db68427a, 0x544774b505054d4c, 0xa30cadbbabc33d9d, 0xa8d250afca0b7a81, + 0x36f07dfcde5fd8d0, 0xd25bb4feb8a0b5d6, 0x52cfde1125affcca, 0x95876763d947df39, + 0x916a38f31aa8c326, 0x7fbdbbe0054a44be, 0xf26e36f7c5eb7a26, 0xdb7ba35f9caacbbd, + 0x8de921ce9854cb9c, 0x83c48c8ba5f3ac18, 0xea86332217508916, 0x89d816e3efccd171, + 0xea8314449612a664, 0xf3afd7b04e3e9dcd, 0x0265cf8252d368bc, 0xd9b9f2c5b09ab82e, + 0x1be9d93315e7e8e8, 0x4e263044ea592f12, 0x4390a239830f4ecf, 0x55c249d481ef6a4c, + 0xb263e1e7553222ef, 0x11ea971a5642c42c, 0x7894d600bebd1abb, 0xdd6fb6941031338f, + 0x29568a2c0c94d52d, 0x01315555449edeb9, 0xb8a03366e13184df, 0xaafa5d4593a6277d, + 0x066b638835960be2, 0xf5215adaeb2e42da, 0x020ebe86ab18e836, 0x1999e5c85d17cc7c, + 0xf2d3af28af6c1437, 0x168c7ecd2b437f59, 0xeb96f37a2f474f63, 0x9de6b71e12e31189, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xce9cd33d29a59885, 0x462405f2ec37fddb, 0xe9f95e03de5d9678, 0x32a499f45d6d059c, + 0xb7a7c4ac40438c8e, 0x799106a722c97755, 0xeab902f42b28befb, 0x8fb93ba219f0fa22, + 0x5c27fe8e7eed5abc, 0x839ae78e6885ba35, 0x65b2bdd6b571e366, 0xc21239b06a82a68f, + 0x26426a1c44edf006, 0xa51b087898926399, 0x50dd06b95ff73ea8, 0x350fd6832d5d8a71, + 0xdfffa1d7439e847e, 0x50ef50696acbda82, 0x96e7b1adcbe64349, 0xa661c7598c159dc6, + 0x1d0b10a97d969fc3, 0x9ea34b494de74267, 0x4edea005f36498cc, 0x43ebbab5509fa12e, + 0xd1952984a42c160f, 0x76e1e9656957f8b1, 0x61c022aa2b712591, 0x33fcaa4055c87aeb, + 0xf2f3f62c4902c505, 0x2e04362a29622184, 0xf9a8906e4ce8d974, 0x67a92a7c276d6c81, + 0x2e723cc4046cf6f7, 0x46a58eefe418a4de, 0x54146288022ff301, 0xd97b03e5ce48c366, + 0xffc53f77c7e390f1, 0xb19ed264213168ee, 0x1d1cc4cef51ff370, 0x4b01018471a269bd, + 0xd649cd3f8e77bc01, 0xc1c33dee731a6569, 0x9c3debf67492ddcb, 0xc7aba687e18eb596, + 0xa47f2a85253d642d, 0x15ad913edb07477d, 0xbf47cc37cb52a10c, 0x2aa65065b10f5c5e, + 0x074b5755d6c4c79a, 0xea72e605eff0a4c3, 0x7371a011e2152cae, 0xaf3b1d61e69d2d68, + 0x4aeb6a54a16e2a41, 0xfe9ad97748c873d9, 0xbc8e5496ad667e7f, 0x4ed85c905f5fd5c8, + 0xd8d82279edb41f35, 0x04d8b0d26beb0ef2, 0x9e2f258b581de408, 0x0f29dd95946735ef, + 0x93893418172f05f0, 0x1568bfbb7707cf31, 0xffa942d8c58917b7, 0x4f196e37a79fb5c6, + 0xf7a207f21b7fd527, 0x9c7087c54110e248, 0x34599d521c75b202, 0x6f14aa2f1155ee48, + 0x0364d2d6a4f30f2c, 0xeffc87f7a5c96b93, 0x51e101275d5ce3f9, 0xb6e359d2545e7851, + 0xdb4a8673c9e8f7ac, 0x9d6ff1c9ed137d6e, 0xb0375b28098ab5ca, 0x5f9f838ae885cfc2, + 0x8b18c0d17dc8bd1b, 0xc98f728e4bcfafaa, 0xd49567385a62fc16, 0xa75b453d79e39f2d, + 0x6005cfbaa2142cb5, 0x16a1ea8f9993dcb0, 0x9e1bdd41d5e86290, 0x4e6889b02bb09fcf, + 0xc01af3d14afe6920, 0x2a10fc1dbba3bee8, 0xd5b1b81ec507c78a, 0x80b35ebe105e8a93, + 0x5663a0c61d9a4ab1, 0x29f2ce0a4970da65, 0x3437b0ee967e6486, 0xcc33fd7763b4c8ff, + 0x4c88c518fba76872, 0xd3bc1add7a67898d, 0x25f2c0438f15c0b7, 0x09e3614e693f9607, + 0xbf02ea16f5a094cd, 0x24b69e9ffac17b7a, 0xdc80a29a1d7cda5d, 0x15456aef44d51c3f, + 0x164377b5c09ff307, 0x5d3b7bb6ddd312b6, 0x87f264809e1f23ff, 0xfe227dd14beb4201, + 0xae8c9cf168344e2e, 0x50ff5fb8ddebf65f, 0x5173c819ce1ff7f4, 0x9ed606fef487708b, + 0x7e64c28e59b1d380, 0x5c3b447c6e9107ef, 0x572c36727f886cf3, 0xc9840d1b57464bad, + 0x2c8ff89726b24e47, 0xf892e0865e58c01a, 0xa2087103a26e48f8, 0xfdee2bcd7ef8dd1d, + 0x3b0af71e4d202b3a, 0x5f75bb3c3e51ccf0, 0xc16bd22b307df4a0, 0xa65aefa0ac503128, + 0x8a017bdc76ffc624, 0xaed8345f8ed38aea, 0x9602ca421aa4a41b, 0x528dcb8d80e86035, + 0x9a762a7150726cfd, 0xbdea0abb7806701f, 0xf83220cde8ab6637, 0xb1abb72b46da3b76, + 0x0c949efa3a3e00c6, 0xdf0d1fedee06373c, 0x7c51a6ec518d8988, 0xb2ee6d2cb276bb5d, + 0x688d3e5103671753, 0x697802d6ab4b09e6, 0x89fcd60d36e20fcb, 0x23a80b1141f19b8e, + 0x506ec248de4b8233, 0xef56c410b27be458, 0xed77454335dd6871, 0xc530cee3e23f9387, + 0x030bccd0c4749a78, 0x196533d441a8b1a4, 0x8e70fb05bd371e2a, 0xf11863a6929c5aef, + 0xd592ae9078402490, 0x8a52f050f98e9cbd, 0xf9565b2d0752b3f9, 0xdd3f0411d9208eff, + 0x011861f3bb22f806, 0x8d35f291fe54e90a, 0x8e3072b46642a9e4, 0xef2e5ab5bac38983, + 0x0499e866da526590, 0xd8cec600d216861f, 0x969fe2788866ae79, 0x4e7de95abbff7b21, + 0xab967470419117b1, 0x2a4e69c1efb6e380, 0x2b30525b18f750e6, 0x145d53c14819d8c0, + 0xd62b283f3e9377b3, 0x76aec7693edc9101, 0xf4108695d27d5c15, 0x19925416b6c3bf42, + 0x01ac9f16984d19c8, 0x56edcb1ad89f2722, 0x74eb0717070c195b, 0x1e06eec0e7654599, + 0x3291c3fafc4de6b1, 0x4320ec8397d905b7, 0x928eaac9bc81d1b6, 0x41df3061bce0495d, + 0x7910ab7408f81a8b, 0x11cb4e677c1d2c8b, 0x9433d55ca6cdbdd3, 0x697b5b6b6679dd72, + 0x0a534b67c710c4bf, 0x3b8eb34678a993dc, 0x7e5bb5ab0d399626, 0x584009c610f43d01, + 0xebf90e47110fbcbe, 0xd7ac0e55b5e96822, 0x2fd00b7ae7692bd7, 0x45e1b18bdd7a6c69, + 0xc8516a0e57f9e6b5, 0x6926df2085a6344c, 0xd855d061b9c1b838, 0x48cd0f9525a992f6, + 0x185d5a3e13ee333e, 0x29f384731b7d0d80, 0xa9e5d8e653987dad, 0x3da10316f3ed0572, + 0xc2d82daef8504403, 0x96ef96361517796d, 0x0266355d9cd05ed4, 0x2c7a6bd43d20feba, + 0x78895efb12b32745, 0x3742d880356da9c1, 0x417e34f04029ec81, 0x884472fc8ab3ef39, + 0x940f5146848c871a, 0x8ad19248c6678757, 0x243da57d235ac0ef, 0x28d0fd48abd7624d, + 0x6158403bad70c132, 0xf7ab64a82ff7bba0, 0x52619046950c6bc7, 0xb2fdbac92c4d3946, + 0x083dbad044e357f4, 0x60b68c624410adb9, 0x2e6ebfca8dbfd99c, 0x71548e0d5a7f5c78, + 0x81d02f04aa880e60, 0x6357ccf13d437a75, 0xed94ffeabfbfa03b, 0x8e384a7755249be5, + 0x358d5c7e649055e3, 0xb6d566c2e5a72813, 0x3751781f16cef998, 0x10820cdda14076a3, + 0x3244654a70004f7c, 0xdac80e58c4a1ee30, 0x39987eb1363cade4, 0xa1a250c689823cc4, + 0x9248cbb92367da33, 0x5a18469337b6bb34, 0xa9b533e98d982f2e, 0x78b843c8248b3bd7, + 0x47961e2a98984b8d, 0xc9a169f7c1116104, 0xe97a998bb5afc87d, 0x5a05c03e91324046, + 0x0281590b1e3ec8a6, 0xe973965731f3f574, 0x02ad4d1dc419d93e, 0xe15f6d7e84b76d7c, + 0xe33572ca39e2e64b, 0x4bc831af534fae43, 0x12b5c7ab2c5055b3, 0x01f1761317f91623, + 0x18c1bc9d6eb955e8, 0xa8d3380abbf3ccde, 0x4de7e773238d55cf, 0xe4e87d9489b2ebb5, + 0x13490e826637bef1, 0xbe42eb241fe28bd9, 0xd7217da58121a512, 0x95c6210e3bb74e3d, + 0x7d1ac6eedf3d71c7, 0xc95c09597429a11c, 0x7e4e0784ab24f335, 0x6a0648890192e2aa, + 0x9f2ab43c574a70ee, 0xba220b29f5ab259e, 0xa577d4b85131e5f5, 0x94807b00167be83c, + 0x0886b0099def3843, 0x828919abc4bfbbd1, 0x15eae97bdecfa63d, 0xed521b0bf5c81e03, + 0x187f918c504e6983, 0x27a6e27e62d4871d, 0xd9ffd99800a55bb9, 0x2c25c3bf0e9eda64, + 0x48f921d410a43fcb, 0x28bf5c3cc5d00501, 0x3107de4e939e67b6, 0xd157c16234c09df1, + 0xee14ebe712abf81e, 0xa405ba5ac727f573, 0x1cc7ed1b4c220078, 0x5d0d63ce07e8a984, + 0xafbbb4e4fa95252a, 0x8ab805922a2db691, 0x9f0ee146313a0559, 0xcef92a673919d257, + 0xce5b33395f8ae402, 0x9667edef08e9da82, 0xf40b3cf7bb5dcdf2, 0x94bcbdf184e25cb1, + 0x5dedfc82529ee997, 0x8ee63d6a9e1f97f2, 0x2481ea70aec7978d, 0x1e9f21f31414a9dc, + 0x2fda35696dd6ac60, 0xd4069eddc09b6d7a, 0x6fa6d79e8c61bad5, 0xe9124037debe0315, + 0x875d366b1d3af1b4, 0x4ba41987997eedb7, 0x88991624e9ede339, 0x5cc4dd35a2482721, + 0xb367ccf9a420d963, 0xd8c6563f2d4b937b, 0x47c2fd161e4fff57, 0x48a5aede3a1c7445, + 0x46cc670e381c63ed, 0x5de239585075f497, 0x6ac290995c3d25fc, 0xd64b13a283afe917, + 0xad82e07e9d132b7e, 0xdebe6c3d1234d710, 0xe12dbde426a63b9f, 0x4e3bcdec466c5c1a, + 0x22302f851542552f, 0xd59a0a6d1c0e5ebf, 0x8bb0fcb16e2e5603, 0xb1860e0a5d47bacf, + 0xc2845376cb0a34c7, 0x22fc99b6013828d1, 0x777b72cd26525066, 0x2eadf98f42bd63f3, + 0x039531f19d8d7a7a, 0x0d3d6818069762e8, 0x59cad112f2434602, 0x86f0ef66fab5f4ce, + 0x46b20d18f3e6240b, 0x7abb0087549e08cd, 0x5d8bd59edf06503f, 0xdb7f76320fffdad2, + 0x4c381427bafd5b9a, 0xb899d108ae20db81, 0x2fdf4633fa384d1b, 0x94b107e531fdf6ac, + 0xc9c5bceb7c1bd34f, 0xb3581b658ac0d99a, 0x1f8afbaac6afbc2d, 0x70d6156d43c6450a, + 0x842926ed9f05e1e3, 0x1e6d518a2a71b02a, 0xd5b0888842e7a8cd, 0xd07ad72fd30f6845, + 0x51f592161ae80305, 0x70110841dab4a05d, 0x240da5a951529478, 0x547debe7625e8e50, + 0x02b34cb5e18d3268, 0xb0b8de2466f61cc3, 0xeb320d935ea9087a, 0x2fdc0c69b8b029bf, + 0xf2f28aff0fdbffd9, 0x3b6f9c1c70a1985f, 0x80fe1e3be4166bd7, 0x559e5a50eecf59a3, + 0x1730272bfd21abac, 0xc63ab0c6b68d10bc, 0x2e83d0952ef00657, 0x133bece3df9c86d1, + 0x3a3bfbb20cc11064, 0x3f71cd6fdf036725, 0xf14b04848c890f44, 0xf08282b4dd96bdc7, + 0x156c145f9d3bc14f, 0x35f0e9ef3f260eba, 0x18873d2eae28b782, 0x75bcb82cd079f490, + 0x28326233aa654d60, 0x8a999075a5ac1ff6, 0xaa32d4cf56624d0f, 0xc2f2356730590c62, + 0x2268f26231545ef2, 0x316ccc3d2a182e52, 0x2ede43ce94bc6939, 0xb40f57b078f099da, + 0x326d2b364eae3a73, 0x5f0c296a215e1b16, 0x8163d17b3db4f546, 0xdab0077eed69c17f, + 0x2e5d45958ef8de80, 0xe8c55b5a5d0da008, 0x9402720096064471, 0x3360b6f5e0bb04ee, + 0x5a4ccc060bd22de5, 0x71be88fd4db728df, 0xbb327ad0fe1af6ec, 0x4fc7e1315c502a94, + 0xb6c66ac6efb9a6ac, 0x89b4420f6243dccf, 0x88117f89779f1e8d, 0x1d23bd79a54ada3f, + 0xce21ad66ba034da6, 0xdd77d94bdc916b84, 0xa1184047d8426aa4, 0x308844ff7cccf377, + 0x11acc7444bc1b5f8, 0xc9592730fa52948f, 0xb988fa69c01e0fbb, 0xb191f4e6158c55e8, + 0x54817f8639e3a35f, 0x9bbcb207e9b2e285, 0x022374a826b2e928, 0x94fe1ef3b1b5a317, + 0xfa8a3242ea88bf68, 0x84105d09f940f62c, 0x3d631de06096d16e, 0x3e1643ae068e99bf, + 0x07c632c36e8d1052, 0x3a66f06be5541ee3, 0x93a926f1069add4c, 0xf8d149ffdef30ac2, + 0x6d083df690f8660d, 0x5efc819dd7142b9b, 0xe5360d972feb64f9, 0xe27189bad8a028d1, + 0x6277d7c8bf8825b5, 0x07a62b8dc5ff4875, 0xeaadab7f777ea6c8, 0x4ab26bfad6ab0730, + 0x193fb99a8aff3bdc, 0x44e06f020052fe20, 0x047499fd10c250ad, 0xb6867c613cb94540, + 0x36a583541a5e6dd4, 0x022fe6942417e0c1, 0x557ca9a79a2005fd, 0x23ab3219f130ded3, + 0xcea5619744cdb9d2, 0x90f5e84444e7b67c, 0x999bfdb1b0a00321, 0xb9bbacce16f1e0b9, + 0x7a0199f827b1c6d8, 0xbc5e715932f5b276, 0xe554faaa36ce8d11, 0xc947cc430b199be1, + 0x1cde4e48062b9923, 0x90c84902e022c26e, 0xabfc2e4016fcd0cf, 0x15e54c54b9c6e34d, + 0x4d202a1c72ce809a, 0x0f476ab013304cb0, 0xc89feaa2a608b38b, 0x9d10aa03500a965c, + 0x49e4de560a3e3120, 0x87cda8f9d62d6c30, 0x0ec3cee23d7493c8, 0xf2527e6a66f076af, + 0xd2b598de696d8425, 0x8a90c9b8efb64665, 0xc15499c287eb2305, 0xc90f1e0566bfcc79, + 0x37cec803ceb85aac, 0x169488496f78ef0a, 0x8e8183fb0371602e, 0x9399accf97ada886, + 0x8469f7036c59d099, 0x50d075ac36299216, 0xb9591eb6c07b0ef6, 0xd6afe6ace6a660d3, + 0x62417340f518dac5, 0xcb62885b79111c46, 0x32dfed8cac9cbf18, 0x66126697ef9ec8e7, + 0xcc83dacddbe63414, 0x1e6e36ab7bbbfb5d, 0x2e5f5aa5265a2530, 0xe4f35d17fedd405f, + 0x8d706506aa031bba, 0x157ff59964322be5, 0x42464562e8c99089, 0xf5dbf0b014951b8c, + 0xfe171b5720fa323b, 0x497d8043a2e2177a, 0x41f4eab08a51276d, 0xcf4d14c2bfb42d3c, + 0x7ffdd0933902452f, 0x6c6b6d8c4b0bc757, 0xa7bd93e472a74c65, 0x9e9c4d8c33b0af42, + 0xf231c7c356874f8c, 0xe8ee3ec4868623bd, 0xec55f6e875607c21, 0xeff6cac772fcbbc6, + 0x088be87fa8d71291, 0x65960d4d2a0568d0, 0x60c9c6e644cd577c, 0x85972db8164dcf7f, + 0x5ea8a6c7c3d81e99, 0x6d183a1b547d4790, 0xd276b9b33785056d, 0x443b854cd2e6672d, + 0x1215b60944725a76, 0x5f15c8b7bf72c972, 0xfb6888890cc71a2d, 0x467450209a4c9320, + 0xbb87220766d0bad6, 0x1f7f41122eaeff3d, 0xb7dd3b84a9fdea10, 0xe0bc3b16a557bed6, + 0x6885b15ef2ecb0a7, 0x47c3c8283bcb361c, 0xd490da14f3cefdc2, 0x0b9f219ee1f2479c, + 0xff29426234aeb178, 0xcf397e585ac1f35f, 0x0022192c5d6e802e, 0x2930c2c41e433852, + 0xdfb6b15b2891011a, 0x607848ee9f009643, 0x69b3a438994a9f4c, 0xa6199243c826acf8, + 0xa4b60e9f88d5090b, 0x71cf385eee46a0ca, 0x2507240546a85abe, 0x4cb4b627f6de77f2, + 0x4922262d13a9821c, 0x7a6984a32f85525e, 0xaf18252f1b75dab6, 0xe6a673aa7eef2180, + 0x7806edd756a2852e, 0x74dec606e9c06cb8, 0x972926ff1122abbd, 0x7b2491f56bc8b2c9, + 0xfeddc9ad10304871, 0x623da743b20aa41a, 0xe08e311086fab7df, 0xb8b2ed1c6a474a36, + 0x6842096ac2b31a74, 0xcb13d8e8e42dee17, 0x361770960a4dd20e, 0xd9b4fd6d5e564efd, + 0x2abfc723620697c3, 0xbf0eedfd2929a5da, 0x4ef2fb426b8a4a05, 0x35a2f2aca2672d51, + 0xcac536f65747f730, 0x7f7365571d4c5a5a, 0xaacec4c22044e4ce, 0x9682b3cf40290405, + 0x0c49f6555ac57a70, 0xde00b0c17f90c740, 0x84ecde35c6627a91, 0xd116e096c81a1217, + 0xd2cbdec7f45eef5f, 0x0088d8652b1f612f, 0xdae2318aafaf634d, 0x9327b132136fec65, + 0xfe1264e759b15b5f, 0xc90c6d42f891d08f, 0x50d5c463773c15ff, 0x18fa2a8638055787, + 0x3aa1148f3ae55d80, 0x5345f5058b5b3017, 0x36a05171c9be1eb7, 0x28f8a6383658c5c4, + 0x11bcd6a27b089b3f, 0x97229d7f2042db2c, 0x286a34e0c511a4a2, 0x56f9b355ef304101, + 0x3016625356128194, 0x525e1e9b15bbe6bc, 0xa88492e1ed993063, 0xdc7e0427045bb569, + 0xff92e547c0b776bc, 0x42707325cb24de9a, 0xcde793e6692e32a7, 0x01082a5baf3b265d, + 0x5627ce679c7eecd7, 0xb53af94762d9451e, 0x4ac90a2e46a22b54, 0x0636eb94088b5b2f, + 0xaa978edc05e58c33, 0x4857468d8155351a, 0x30ad1dab04165d7d, 0x55e1ca5c8c5284c1, + 0x7e9ba02bc3ceb39e, 0xf8384e0b448134b1, 0x0ab20284b59fd1ef, 0x4776aefb883f09cb, + 0x65416199a6f94b6e, 0x18d6eafa67511359, 0x5f020b18d63815c8, 0xca1a1c12103458e4, + 0xa62b1a0945f55f60, 0x68fdf99ba234bcd3, 0xddac11ada8cdd0c2, 0xd1a3a037f239de59, + 0x55398c5dcee915c0, 0x9d9e88eba93435d9, 0x7150dd4926c6c641, 0x7adb157d082a2fbe, + 0x7893957747ccd1f4, 0xff85909d1ad379e1, 0x164771f773f27c50, 0x74a7dcf2b5cbcb63, + 0x7ddf755923b878de, 0xdbafef8476cab630, 0x84f62cd6e27eb046, 0x4126b031ed360e54, + 0xb43ef63dea606aaa, 0xd7bedd3e0e1049d3, 0xd073705f4b396251, 0x2f930afd9cff2d29, + 0xab7accde57244b1f, 0x786a149e20894642, 0x2d5da33a4d29f1c7, 0x7db3463918f02528, + 0x35954cee1708079e, 0x1d327e6afd118663, 0xc4a6f3bf68487903, 0x5c96d8e500cfa623, + 0x423b8e0b9bb47fef, 0x202a3278d522c149, 0x286ba25e3af87e2e, 0x604dc3f56947be29, + 0x98b284acacbf5f5e, 0xc3eeddd591232f46, 0x0dc95fe8e31d6cc3, 0x58a478931641abd2, + 0x9f062abef9b339b3, 0x132e29390a003c62, 0xf4d69c29138a3a16, 0x4d64ccdc28febb6e, + 0x727ee4557b15798b, 0x47cb29c8fc1f166a, 0x05bef6ae762e9843, 0x5782085ec487599a, + 0x3ded0df93d96362b, 0xfd897a36895ca7ac, 0xdb7d2909aa7d97f1, 0x49a44a61f94a7546, + 0xb40b1c4bb90de48f, 0x90681a39c7fad17e, 0x441694c44b4d59df, 0xc38a234090b8d470, + 0xa379b9d3c65e7da6, 0x93b08a8b49504714, 0x920002e636d314dc, 0x382d5bbbfefc1d58, + 0xe71517d01d13920e, 0xdc0d7b1f76c2f9ad, 0xd5fb7ef326e107c2, 0xa897c68991634567, + 0x09e96eed6883bb00, 0xf8db4aacaad9fed7, 0x96ad16e864a5798f, 0x56b55259f64a1e1c, + 0xd852d6dce3cabad7, 0x58139456004a3fc5, 0x2cc513c4870cf150, 0x710149c0d3f8d7f8, + 0xf5acb979e22b5067, 0x485233ec0d78802f, 0xa67ffd82be61c5ec, 0x07d2513fe2230711, + 0x93a57e3ee20e5c3d, 0xa7622cca0bd4432a, 0xa9e148d538338925, 0xd15a513060fd750f, + 0xd3194239a1d0e137, 0xebbcae0b6759e946, 0x1fa3e1fe3cf41f7c, 0xeae630c9deb0e975, + 0x2b62de7119fb8de0, 0x817a6537bbfe9ab4, 0x287149ea2036b9ac, 0xfccd33dc0a22d5be, + 0x3e2a52ca23d60c87, 0xec7ecf387f125504, 0xa1419faeb7d2e02e, 0x44db7c65160663db, + 0x57c079ecaa6c357e, 0x4ccebed1238dafb2, 0xd5df0f5abe753cf1, 0x850a51369e5d9b37, + 0x04432b31776fb69a, 0xf06f937911a0c85a, 0xa9b1a7ff5d2427aa, 0xc2857bb49ea2b24b, + 0x370e72e71b0b2ddd, 0xdb2e0e456c00285a, 0x16b20f48bf1f1b7f, 0x6ac9f5e466d30b06, + 0x559930c88603bfd5, 0x14926a510f635e09, 0x38cd43e02646f01d, 0x83e17142d7621622, + 0xf8ff2022c9c1d9ad, 0x16534b9f3eec6fe6, 0xe0e086c796c847a2, 0xb9276bed868e378b, + 0x82c8fafd0f198373, 0xb5da23ae85c3285d, 0xcaff4821c276c17e, 0x535c75d372a282fd, + 0x6a32cbb4f78a360c, 0xe65b410e7821f0e6, 0x9198f50e39456b56, 0x9a789ba684ce9559, + 0xc967df274e5066d8, 0x746cae24a0e1ae07, 0xe6e991a9b0636786, 0x97d116f1a6670ffd, + 0xa3a127a26eb5b4ae, 0x3b5caf42b7e5420b, 0x689c017afae63272, 0xa04e48e8d220fbe3, + 0x60c45400321f042d, 0x945fae85fc70a6a7, 0x20e9615815d23dfd, 0xc08196421f43fa7a, + 0x3dad048a6c684a12, 0xd9dbbdd2f29abae6, 0xc59246bd6811629b, 0x7f7c561749d690bd, + 0x08928468e07155a9, 0x2e1c4537dbb6b874, 0x75897ab6bfca4d1a, 0xdfcee05834957c03, + 0x81ecc8672f2e4278, 0xcd0fead39881f35b, 0xa8320620f96315ec, 0xfe73bc013c2eb892, + 0x9ac8f391f05a117f, 0xa447613413670fe7, 0x531e6e6edad44821, 0xea504168dabb56fc, + 0x6a69fb32be89e497, 0xd929ee788cc241f2, 0xab2fd4162f430fc0, 0x6947bb7dfd9f5f17, + 0x8cfffb87f8dd6367, 0x6b777be20118bc95, 0x9abf37d1c8385483, 0x649671a7d2962159, + 0xdde8243bbf3fbbbf, 0xd58659b8a6a43fe0, 0x59bb58338eff9a74, 0xcc70c2517e3acad3, + 0x5788cf013de85217, 0x726ee59b3a7c2bd3, 0xa7b3f5e24715c959, 0xc8748945bcec97cd, + 0xd65881223fee88f0, 0xa775fc34d29d243f, 0xc2222c04196a6bad, 0xc3b1411a427e140a, + 0x3983758ed8d8c35a, 0xa090791d7ba0faf5, 0x8b2d1f2436617576, 0x52dbd9e0e37e48cf, + 0xce65d7a421b6500c, 0x193f1253747ed001, 0x8d4ec1fcc89fd4e4, 0x20e974073e00bb75, + 0x73edde237f81d22f, 0x2484d1999381472c, 0xe4e406643775db15, 0x856fba731aaf09a1, + 0x9913c932e613b0ce, 0x2640355d2e477c24, 0xd7e3d273749a9bd9, 0x4cc35e3cb495fe0c, + 0x63899ba256026ac0, 0xead5e93a07cecb0e, 0x7c620b2bca7a151b, 0xe1eba6e65f69ce8a, + 0x41ae135d1c88314f, 0xa4fc3ea44c1f2b96, 0x1fb948786c605141, 0x81d0655ab3f7bafb, + 0xdad4848bc8c0baea, 0x7e28fdeaab9a28db, 0x6468dded75dbf8f9, 0x2ef2165301f13228, + 0xeba46cf4a77e67c3, 0x34d613b52a79dce8, 0xec5c2a061b18efc1, 0x4c284c8da29af2be, + 0xe1fa5cc4b5a007f1, 0x08eb9356c35bbfba, 0x6fd8aa3ffa19e22a, 0x4a21328128b2ddcd, + 0xb4fa943ad9e8aede, 0xa789c852122cb2cf, 0xf12d42439c2791b7, 0xb04d0d03d3792385, + 0x65d57acc0ff444a7, 0xc033366873d5c00b, 0xd294b23e78c8602b, 0x59807a80172eed79, + 0xa5020f687ce2a759, 0x87a6f7d0826e755e, 0x61e6285db706bfbf, 0x018c5dee15f328d5, + 0xf7c4eaf042d9c573, 0x11957412ec339d79, 0x52932341cee6c7e2, 0x0403f37e50c6274f, + 0x2f4d893dc949344e, 0xfe2eda82948a93db, 0x41234e80aad710b5, 0xe751ffef185137a7, + 0x9f1024297803752a, 0x56d6c5b90e737b77, 0xfc9c5d74ac9e4cd0, 0x1be479f113df8ed0, + 0xc085038cb762c45a, 0xac5c34eeff1c97b6, 0xccd051a558afa7d5, 0x456a3d85f945b88c, + 0xafc366c43fc7b271, 0xee442112df2648a6, 0x7fd202aa89f7a102, 0x29dde3a2863ed340, + 0x63d764e2743b561c, 0xa6e1d40bef68b20a, 0x9617fa08e6bbc892, 0x987113a5151fa4d3, + 0x284af24ee0967178, 0x6d02a35dc8996421, 0x4beadfd485ffc06c, 0x4eb18c652bef47ab, + 0x82b3ddf40e4dcf81, 0x0cbcaad37611cd7a, 0x465108cfdc386a62, 0x6a9b016cfe84e197, + 0x7e0005b6cbb7995e, 0xcc698421aa37d75a, 0xa79fa31e47591250, 0x6150afdb8404ef70, + 0xd6060c1f885337d5, 0x3257da149e09292a, 0xbfa139d2e1524ff9, 0xa98f4e6f5b1e115b, + 0x3e1730621958afde, 0x0873224814ac4379, 0x3419091555e0d493, 0xab4ebdeae9c8a7d4, + 0xe86f4d35bfb1fc27, 0x44e3c686773a38d0, 0xa2b6367ff6bf5b30, 0x4f3d0cf2c552a529, + 0x4d14357098e94c2e, 0x416f11ccf7f2eb57, 0x9692a1a532ae6bb0, 0xc3250774c95d9480, + 0xda7b21617678c39c, 0x16ff125cbd2b1654, 0x4e227d2371754faa, 0x90fcde2ced84ef10, + 0xa4e305c839503f84, 0xf5239010ae84c37a, 0x668868c0772b9838, 0xe232ba6a67fc12d2, + 0x3555e3866690e574, 0xd7b7d75a3c8340a5, 0xcd92f2c093f274e2, 0xac6682eac53a6b0e, + 0x333a3f31e3d066bf, 0xfea9a401f74c110c, 0x626e1fd4b72687b9, 0x9f5d05bcc859b662, + 0x027a2cd31b9d6e9a, 0x6dfd9e90c1e5eaf3, 0x1b44cd8dd5580a20, 0x76a9a9d66000c35c, + 0xcb9aabe58bde2ef1, 0x4006d33c1942184a, 0xa5dc60b5d1f0bca2, 0x6916fa84ae5ffa7d, + 0xbfb074f9ae3b72cd, 0x8d056bfe84ebc669, 0x064d8640ca0c3517, 0x3dc9cf6b51665764, + 0x1c9513a9badbc9c9, 0x33db88d2dbc8ca00, 0xc43db9d873a0b09e, 0x99750c4e3d8b357e, + 0x5b61235d5f813840, 0x8b8bfea400b86a9f, 0x645fc6002bbf066f, 0x3c14dd5aaab9e933, + 0x11e625a05dcb4f42, 0x40413acca73ff872, 0xcc649da0cb6588f4, 0xe4a1be8969502a32, + 0x82684e864fea4804, 0x985457adef73f41f, 0x7ac9fd484a65e6d6, 0x613e43717fcd9461, + 0x7785044a7ee7622b, 0xe0da6db5d19483d0, 0xe0870995d476d95b, 0x6f602ebcde5a6619, + 0x62494bef713407da, 0x9fc3015d7a120ef0, 0x1f680d8d7e84c29e, 0x2e2d0d2f38548ddf, + 0x2ebddb4b32eeffe4, 0xe5c10c326ada7f58, 0xa03077e57a479144, 0xa16774283cefc675, + 0xf48d75a2df25befd, 0x7700d6fe0e3dc28f, 0xeb8c32dd6db708e7, 0x1b92d562ae031022, + 0xaffd80097081a71e, 0x08b192b0654c08c0, 0x80af12e090c2a085, 0x6e15f183065f4ba3, + 0x15b9fdef5abd3e38, 0x970e865b2ab86e5c, 0x488d35a9b4f4f7ce, 0x0a2ef6a631e71e72, + 0xe93158b8c7ff856e, 0xbfa9021a992f1777, 0x84b13d3b9e4807b7, 0x8f5d6e9faa3cb0ab, + 0x6f3208ef5e009ba5, 0xffc109c0bdef5f8e, 0xb649ab5201216c26, 0x72b176118e94382f, + 0xaf0cbde4d4746d6b, 0x104888f5f0354c16, 0x51544859073fef15, 0x090740f99f3ed7c1, + 0x0663517091cb317b, 0x6485fc30210b0700, 0x8011dfafe1f1e18c, 0x91d95f012c4b662f, + 0x1b483a68320b3b73, 0x5523544c2283006c, 0x37707cd1d1f8220f, 0x2e79faec83d19b25, + 0x48bdc14a2e52f984, 0x92f8de0c70cd069b, 0x5efcdc28edd6a4dc, 0x43d3190e41362848, + 0x02bee6b384a82972, 0x8f321209f897e44a, 0x293875c2b93e01ba, 0xc72525236046ff50, + 0x0872ae9f3e528dce, 0xd2175888b7e174fd, 0x82dbb198782f9669, 0x0831edc494c5b0dd, + 0x2ead0626ce4c116a, 0x7a184a4356e37479, 0xce0f0ba1724b4e24, 0x106c07da4facf8cb, + 0x0c874b32816cf0b7, 0x6793a87df29f9e87, 0x676d1f8f6b2ff7f4, 0x2fc0514c6fc036b0, + 0xf76d7fd1dd6a7d0c, 0x811aaf3755124345, 0x50a77086a2ead4fd, 0xde90b81b71d8b412, + 0x2f134daf44e59f0f, 0x01092545bad475a2, 0x5868e8b26586495c, 0x5091d483dd849151, + 0x2ab3413feece9b22, 0xdedba3fdd59d4c96, 0xeeca1bd4a4c50970, 0x3e313d5ea3e73147, + 0xc218a69c78848011, 0x7c87bb26d8b77446, 0x180d65a9f22d57f7, 0x7f8b7f44bd286ec3, + 0x3e9d5c27cff38454, 0x8b7162045b986129, 0x31eedd8bcf746fce, 0x38e97e8921cc3a6a, + 0x55bc6968a565f7da, 0xf661e9351c4f789f, 0x339c6e48890bd0f8, 0x308afb6f9913b380, + 0xab9d4217e388d4ea, 0x26d737f5aff41841, 0xc0eb3015371604bd, 0xdfc7fa471860ff93, + 0xa5477056042ea7b0, 0xafde29f6ca94c465, 0x4b2ce9a6b22ae061, 0x7345a17f576ed214, + 0xed772a6d23a3587f, 0x380ec2389ec715ba, 0x067d8735ba51d8f1, 0x6ffd1fdb1d391b8a, + 0x796e518b42503b6c, 0x6ed597130f567327, 0x73d5949fe348755d, 0xab24e8c4aadbeaba, + 0xa292c13a36061421, 0x057ebc08577913c5, 0x0c8471df91468267, 0x6b38a78d6861a13b, + 0xce75cd1e0cf35ee0, 0x344b8615f7ea78d4, 0x6a18bbddf52baabb, 0x7ac85e6e9e88d446, + 0x01b45e7f78905045, 0xac3b5ceca7469489, 0xf33ae43bc090ef90, 0x1749bd3d527ec2c7, + 0xa8a792948698d22d, 0xe5a8f633159aa8f1, 0x20b7b6afb81435d3, 0x7f8d8b23236278c7, + 0x858b3801da91a76d, 0x7daf88dc407cebe5, 0xa1561aa8427ee064, 0x21344e335fe454ed, + 0x968439626560a8d8, 0x049f03a5b9b8f5bc, 0x6f71a001487119dd, 0xc0662f8bfae92c62, + 0x02f8f41f021396d7, 0x623a7322f1593bda, 0x8015de4b1811cea7, 0x6617ae9b95508a7b, + 0x42a3df0dcaf35414, 0x24912b7d3d231ea5, 0x22c2ce3755d88cb6, 0xc1e17851d9e42ab1, + 0xa4ab5e0b2a35430c, 0xbdec579c5e68d45f, 0x5ac4bcfddaf74d4e, 0x60a9a380525dd890, + 0xb6cc29b6591628e4, 0x55d2e0a1ac916355, 0x16665a96b6b5974d, 0xd66000fac9ced98e, + 0xb6d6365954b149b7, 0xd9d9671f5b740055, 0xa024242467d2bc8d, 0x9ada14ce72667eaf, + 0x6ec9333668e771ca, 0x10ad27cd8f6e66ac, 0x0a7bccfba5dc4956, 0x0369d0625644c922, + 0x3588cb71586578ca, 0x6289b1cbfd434c6e, 0x7216f0b22c378d27, 0xf6f77a7e0ce470d0, + 0xcec1605249c1cefe, 0x8126962615ab8885, 0xde2595bb920c61a0, 0x806608e592892efc, + 0x3a046ccd796a225d, 0xcae7b48f7a75865e, 0xe30fd98a3a5747d5, 0x134d0b17e5b14307, + 0x2ae5066337335ab3, 0x6dd09ba9dd08399c, 0xc773e49ae400f47a, 0x05a4a6492de5beba, + 0x4b0613c897a4caa1, 0xc60090c47c5b2b8b, 0x8c4ae717922add15, 0xbb7abf4308325930, + 0xf1103730e0217557, 0x0af9477ed669fea5, 0xbdd95510d3e36d1e, 0x72f2405f27e8add0, + 0x6b88b7ba6f338839, 0x62294c34e0fb568e, 0x4863f78bc28ac8de, 0xb8b06f74cbc60218, + 0xb657b6df12121b68, 0x50bff128deffb87a, 0xa184ded9e0cbd3d9, 0x45c9136d623fe4da, + 0x784140ba00e3130c, 0x5d30ba34d8f5636b, 0x2f4da588bd4fab71, 0xff003c8617e5e6a2, + 0xf0ae3587fa914e03, 0x2bd066ea89e927bb, 0x2899fe299a990128, 0x98072110bad8d28b, + 0x8758eba8b3dedfa4, 0x27ae832469fc1304, 0x1d8b9df17a66370d, 0xdcd56424dea40687, + 0xc26dc42e1588e98d, 0xc78e5761337ec2a8, 0x49116d6e54ad59b5, 0x9602db1e3010b517, + 0x6686b3acfd4bc339, 0x8d55136c5d375832, 0xdaf5208d6c4b805f, 0xb754c37adf25a422, + 0x41ce33198e749299, 0x31793d3ec0445729, 0x03eef8e00df89311, 0x7cb6481a8ccaa4d1, + 0x8c5a4aff05730e1c, 0x2b44bf01ed5393d4, 0xdfeb429210077af0, 0x4ad3aa4970bb8478, + 0xda01b1b576b8dea3, 0x342a3ad1ab13fe37, 0xc3921c78a353899d, 0xf618e8ff78ab72b0, + 0xe26064a09865301e, 0xf0fec72de8ea4ab5, 0x538408e5a1a338e0, 0x43a36c104835d967, + 0xefe3d3c3422b362e, 0x54ae5cae7d9ef0f9, 0x87bc19cfecdd5b3e, 0x6676d8d951ab8e97, + 0x2de8f0b36955d437, 0x3574f2a188a3d6c2, 0x0862af497eee8061, 0x5f31bdb4441a7cbc, + 0x7cce8cc27cf8b6de, 0x84fa5081d60a10cb, 0x739c89f9d5b939fa, 0x3351be61be26e7c9, + 0x4c1fefb0cfd35f0c, 0x81ec347ada49b412, 0x64f4745dab3e7da7, 0x1f96aa4f31f50472, + 0x5a2f38b99adfbfb6, 0xf5923ca97bdf41d0, 0x838fb2f2d0b6e43d, 0x40296a14276e444e, + 0x6b01ce971050a62a, 0xd06b41b719ac1f03, 0x4cee947899b0bdb6, 0x965b0e8be5a5fd19, + 0x59fbeb1727c1ed00, 0xf238be92dc76f4db, 0xcab30744c4309ea0, 0xaf3ff93c92e99b3b, + 0xe9c2b719e70ff5f2, 0xf4fc768b4e4aedc5, 0xd4bdff465b183204, 0x32f0e024e904a85a, + 0x61f11634874c3731, 0x9f67d1f1ac4a373b, 0xbc63dcc5bc4974d0, 0xf3a188f98fb9d6a1, + 0xc37a586d80957516, 0x4af287b01af49edb, 0xca8ed96fd8baca28, 0xb0f4693e439d1b8c, + 0xb51fc007d4a45a8e, 0x9b2e8975f5e9f99a, 0xf3adbec92122befc, 0x260fc818cb066d66, + 0x33ec0bbc45b52bbf, 0x0b1fbcf571f84d60, 0x2c9a2ad826f19e91, 0x3b7cba9c4ffa9d3b, + 0xc069b968b5e7cdb2, 0xdc22b78bfc0ade6b, 0xa88edef07f8b18ff, 0xdb20bf85ef5af6dc, + 0x0e5ffa0430481f9a, 0x83b142bf68851cfc, 0x37a908d5aae14d6a, 0xbce64e08c6758a3a, + 0x55f66acf41cfab4e, 0x934fea271b6318b6, 0xb23dcb5220559c2c, 0xc31e5fadef26d1f3, + 0x3c627f4f27941e45, 0xed7a79376878aa56, 0x8f30d91a179c8d27, 0x9cb962cb41226742, + 0x7de88ab9d0af50db, 0xe467a9f8194beff1, 0x99ab87d9d5d90192, 0xf619a6c6fd8509d8, + 0xb9a824dda1dfde21, 0xc49d1a0412ba1bc4, 0xd203d148c34aa6e3, 0xff9d182579b13f32, + 0x5ed100d5391e7d4d, 0xb9c212f8e10fa391, 0xde97d1911a2797c8, 0xb1a878569925b652, + 0x8941e5b050857780, 0x940337c0d178a932, 0xd108df1c1b672142, 0xdb7a25ded63b9be8, + 0xdd3043fb3653ab3f, 0x2cae48504121a428, 0x13ad2085c93f7653, 0xbc53e55f4df9e097, + 0x64d2b22c9ad47305, 0xb0a1a41e3b69e03a, 0x19b32ee3435666c4, 0x3ab07ed5ef6df9ba, + 0x13071cc89c19ef25, 0xbb5cd8ebb929e7f6, 0x28fc1e99fe1c8e3d, 0x78e54ffe69d2e4c3, + 0x2f80728f2e79ea4c, 0x5ab72c0a0790cf26, 0x378cc8d4639310a5, 0x7c379d55fa0eccfd, + 0x68905d438e24f6e9, 0x66eb0750218afca1, 0x312b2c940bdc3e0c, 0x92b7f184fe4d72ca, + 0xa33d497406d3a24b, 0x2dd49616dbb9db9d, 0xe053e70838a7e1ee, 0xe5392c47905cf46d, + 0xee166b9887564c3e, 0x466f388c7d8312ae, 0x82d5377a630f752b, 0xb70b515c0fcb1539, + 0x980583cad70240e6, 0x7a64b37e4457058e, 0x7663eba3961139d3, 0xfd2870e8b9ed3ce0, + 0x4fa4ec6edd9fd91f, 0xd045d710002a8a7f, 0xfa98f3323bd5961b, 0x3bbfb08d87a0e913, + 0x8bbe6ae967c4c642, 0x59a6fa8957947732, 0x978e06d0c6dd8016, 0xe9d31815b99b415d, + 0x9bac1528abcc29f4, 0x0c4d60fe3f19249b, 0x9047cd8a3e9a2d55, 0x3f727ff464c48848, + 0xf8c49b4f602f6d57, 0xf0e15e69dcb2129e, 0xc6d9e531555f5efe, 0x0e153b72d0b17d0f, + 0x8c8200491e0f7dc6, 0x0295a1f4ffbee5e6, 0x4c4c8a208a92dac9, 0x3d29a356f64f411c, + 0xbd5200c4329b68e3, 0xc385103c6ee1bb4e, 0xc90cdb0e9722d2ab, 0x37f96bd3ff544360, + 0xa2b7f87f66420330, 0x282c650f7412776b, 0xd6be6343553f5d07, 0xfbfa37ecab3ba920, + 0x9093c38e022e421a, 0xd00daba995ba9af3, 0x786184e46395932c, 0x8b1a3f0d096a55c4, + 0xe08097ba3f0d8347, 0xa91708d75d825097, 0x33b9922f3a9e3324, 0x7a1a3f0f5c1bfb57, + 0x2de4f194498f249f, 0x0aa491bf06febdda, 0x344765cba30629cb, 0x122b8c12911841f1, + 0x2e2bc1f1458487b4, 0x3160bee6f0ff42f3, 0xece0a30498e1227e, 0xddc05d6dcaa8e697, + 0x34021b369ab3137c, 0xf0ddfc469217ba08, 0x95c458c7b6edb68a, 0x17d03378dc847aa0, + 0x6acb679a11730612, 0xcb93255fd17b3e92, 0x18ad048630c8cdb1, 0x9109b30294d63edc, + 0x3ea11ddf29dd321a, 0xb4686da7ff1ff3bd, 0xbbffc672373ab8b6, 0x2999678aabbc815f, + 0x4d55d6261ee4b32d, 0xffd5fe3b3964bedf, 0x187127a056f937a7, 0x7449351c646463ca, + 0x79e8f46d3a8c691e, 0x6d01e77310af77bc, 0xfd1b310004bcc2e1, 0xb959adcad4ad4a01, + 0xaa172b8db4b99cc2, 0xe8571877e9eaafd0, 0x8bd9e92cc2a0db60, 0x1ae02ea738a7c189, + 0xd13b3cdb32fbea18, 0x31a3795d1b2c5f56, 0x07fcf623e164b459, 0xe5739ffba1887878, + 0x874e2d02a88dd9a7, 0x70e7ffb137b23051, 0x5dd6afeedc75ac46, 0x6d00cbd68f2eb6fe, + 0x6fa0eba48d3df55f, 0x3f796f994c555322, 0xe09f5dd186f1b7d2, 0x669e7e57276ac37b, + 0x0e48ece4da9a5b6b, 0xe560f7d6c8e97e82, 0x9d1893c6331697ed, 0x662775fb14e113d7, + 0xece68a44f6fefab9, 0xf4886037b16ee522, 0x6188769dfbd7dda3, 0xc6c046a54f8a8da0, + 0x5f70a8d4aa1e7ccd, 0xe28aecc280084258, 0xbc8a090cffe8f3ad, 0x3b1ee1bc42c0b788, + 0x0638bddfe099c2b5, 0x7ae78bd275e17ae7, 0xdd9210fce6b2f693, 0xca683d0d4e4ad7e2, + 0x455436b77b6706d7, 0xc0ef0bc07a643a0a, 0xeda596b5e5ae00d6, 0xf5598394e8844916, + 0xd9892fecd00afdc6, 0x2079aadacab2eafb, 0x9811ed2bba446388, 0x4e7af7ffaa0c051d, + 0x995053ec23883ad3, 0x349d014674a49f59, 0x3a0d11f9bcc2381f, 0xce50a144106a31f8, + 0xbf5297e11f98e7ae, 0x8cf32c1f952d0188, 0x845de3bd9d249084, 0xb70a5be01bd770ad, + 0xdef0a6e37f1e961f, 0x796b2dacf8cab916, 0x20bd7f9b4b2675d8, 0xd679f4f80bcce924, + 0xb68d90fb6f77a420, 0xdd2eba4c15cd4e8e, 0x68397d36b33b6d37, 0x9d7760f1261b3b74, + 0x117326c6efc03171, 0x7e4976f063ad90ed, 0x77233ca22983fffc, 0xf7fa08ad152dd606, + 0x903921564f4bc56c, 0x8e1f78ba3d557725, 0x6dbe605a2e751171, 0x8da329f666233c1c, + 0x3751a6b65d1021ab, 0x451a21fd52b66e07, 0x84a6cc4d7f35cfaa, 0xaf824cb94484b447, + 0x8b3cabd3601b93be, 0xdc769724be087150, 0xbf56e590ac606aff, 0x8eb0d5630b034d03, + 0x789d435fdc82ee3d, 0x4758325cac904073, 0xaaa669ad894db943, 0x2f3f918688079296, + 0x3deedb53eea04128, 0xf83034c163b06ecb, 0x38ad6e241bf5f53a, 0x2013b91d9835953d, + 0xfcbbd5befbe29a46, 0x305bc4a171141fda, 0xda70fa95095a4904, 0xe1ac43a2ac6a7df8, + 0x51a515201b6e5b88, 0x9a33d82ee03cd5a2, 0x96706534a6930672, 0x11cc14d0e99866d3, + 0xa1a4240dc2cd9cef, 0xf18d96b1e5aaaddc, 0xeacb9e625cdf22a1, 0xaf7d3de65394493a, + 0x1fcf6e0eb5ddba2d, 0x267689828d28e0b3, 0x9572fb35fe171b19, 0x9b253289d31f6387, + 0x6da6cece06df3934, 0xa581b5f8e75ac10b, 0xe90280eadeb3dc98, 0xa45b2bac115ccb72, + 0x9f15e2acb5aa1cf9, 0xfac1b688ac7c60eb, 0xea86b3ef6c59fe13, 0x4fc9804024bd4e59, + 0x1e5c887ac60a5f9a, 0x928b47141320d79e, 0x653b583525ecb311, 0x8f9fce910a219c0e, + 0x4b244987b1c2a8e6, 0xb242c1cf862ab8ea, 0x62e50f4d928de98d, 0x56f08b01ccfbcdc7, + 0x4df8251ad896053a, 0x18627f5b9a4ddd9a, 0x98658586c866ff8e, 0xdf0634ff5e617695, + 0xe75310b02045a095, 0x5cd458e9b9289fe8, 0x5eb35601eb21d130, 0x0986235b2d2d615c, + 0x1c0eb3e6e7fa4dd2, 0xb5676d2ac98ce775, 0x828713c48fdb7a9a, 0x1e6ba5ea46d8b827, + 0x55f45fb565475bf6, 0x1deff33cd0263fb5, 0x6dc23c61ccd9e86d, 0xcba38e84cdffcc40, + 0x1c5c660b914577a6, 0xc28b29d4c8bb48d9, 0x2e017840ee7a1e06, 0x3cba444b69d454a1, + 0xbbd1962356935010, 0x7d39e14f157354fa, 0x4e80e72a07c2b225, 0x044b668a4b369079, + 0x39028d5270ae290c, 0x6e23c4d118fda9d4, 0x7c0dab87cb651b2e, 0xa3e648fc26c64056, + 0xf17351d4d8f7c465, 0xf14cad35f41263ab, 0x2fc7c4d2bca7dc72, 0x2b45432bd7fe7508, + 0xfa7191ed19e004a3, 0x6b786edcc5f6cc55, 0xdbf8236727dee198, 0x3c003e29b549421b, + 0x5876590c0288fabc, 0x166c62ebff9cf93b, 0xd89c54c1c45546a6, 0x1b54ea4e9b13cdd5, + 0x7fa5fed0b2c5315f, 0x6e45b9c3cee19f81, 0x871646f892eba17d, 0xcea5dcf84572730d, + 0xe7bb4eb75d62b166, 0x1ce7e0d6bc7b6f53, 0xa51c772393f4b21b, 0x590fc72de380397b, + 0x78425d4df0b678a0, 0x091b4cb7a7f25869, 0x022b2f2b6b6a04b3, 0x5f1d985860a5cd44, + 0xc2c3be8e9d18d5d8, 0x0336a189de3984c5, 0x0a8b8d6ae2d5f123, 0x616695f353b97305, + 0x0aa4b1ccc099dad2, 0x4dea8d3f2072fbc9, 0x94fedf3f135469be, 0x25a36f9d0a5c2eda, + 0x884ca2d2a2a50392, 0x74d666f96f176f5d, 0x7067b3b8d1467bc8, 0x57f98089136eeb2e, + 0x0c6854b005740632, 0x0e1730262ebba61b, 0xa21875113dbb8880, 0x951f878921f2699c, + 0xc8e592d8c3bc5762, 0xba04bd4429480419, 0xcfba328c26697ed3, 0xaabf3e38640a4c08, + 0x001593cad60fc6df, 0xbe30bdb572a8813f, 0xbce03eaf1e0c9a81, 0x3f7e61956a620bcc, + 0xd0e6c5a7dad27b50, 0x4bb9568a0529457b, 0xc2fe357ef1e9b3d6, 0x31201f101965aa07, + 0x283604999b54350c, 0xec96fe04ea1f853b, 0x8f1f46a165be71ea, 0x7046c9f9ca7ea047, + 0xa6281e87e93e4cc9, 0x52822bed8f3073de, 0x36c38b3806af71de, 0xa5caba5e4b86e58d, + 0x3c33e98f05ca8aef, 0x95608764928c8d9f, 0x3c48bed4c26f2e47, 0x04c4fe49574bfa1b, + 0xc32faf41087ae788, 0x19c1edf3039ebc39, 0x70d72a99938996f8, 0xe445153545a3b83b, + 0xc752513d9e43eecb, 0xd9c20c0c3bcb8320, 0x9b4dcd562ec821e6, 0xbe57ab3d38708c52, + 0x26bea35483ce18a7, 0x0112feccf72fc168, 0x181f79bbea32cdd3, 0x2bd0d7e80280e860, + 0x7371381b7a503808, 0x1f3d064d0db916b2, 0xa8f6d5c3d861721c, 0x3d8f93423749742a, + 0x716ba0fe4341dc13, 0xe90680d07c8ad686, 0x78bd50d600e1ce40, 0x10b7ce5ec57dc74a, + 0x0dc4bd35a1c7fe3f, 0x54f3e5eeca67c171, 0x8671fdf51d402eaf, 0x3a1bcc17a64164ce, + 0x7285f42935c3a7b4, 0x4be8224229e86812, 0xe8ef906c58386c86, 0xaff6758ad9bbdd4d, + 0x61acaf7da7aa2534, 0x9e3f8f907ae528c9, 0xd8e962e31882a959, 0x3d14c68f0267fa2f, + 0xb2b0cce7628bba28, 0x21466664136be05e, 0xf17466b6187ef3b9, 0x6335ce078b14e4bf, + 0x300341488d42c504, 0xf726f17644755c18, 0x34fff8bb2f1dd7e3, 0xf70e518ca981bfe4, + 0xe20a0243fc734350, 0x2b0289d8d43beacf, 0x66d8dd2b0dd995fd, 0x5df8f8e604d7c0f2, + 0x65560ccccaec3fd9, 0xce8322b081aca0e0, 0xec803b146935ed00, 0x250ab8392aa2dde1, + 0x19551b065b977891, 0xaa6beb91bdc6ea0e, 0x1589bb3fddc82063, 0x454c4796188a746a, + 0x6a0f5b67cb792388, 0xd1eb558953359843, 0xd9f7e1764104646d, 0x1cf5feec652c89a0, + 0xe13e08fcf2ebe0d8, 0x42b9a3cefb087af2, 0xa76674dbeaf4cde5, 0xea207abb1be206e4, + 0xa39b429cb9275f9f, 0xf99bb8a915d7adb9, 0x93d1f942e5e37558, 0xe2ebf6e5f5dbc828, + 0xe6eddb4fb64440c1, 0xa0025751c59a1a21, 0x28c3db6665789e98, 0x0b1c2f06496be89d, + 0x3dab34bf51a01a86, 0x8a10df46dabae133, 0x05308a01daf3d037, 0x64135af9e1bb3061, + 0x566f40f1d16c43e8, 0x88b46276a8b83583, 0x3d05a86da3147eaa, 0x15aa65ceffbc11fb, + 0xaefbe23d3312fc7d, 0xeeb1722be82733fd, 0xbe8cddce70f62f8a, 0xbfa729bb3904ab52, + 0x2d7ca46381ee9a0c, 0x300101afb2cfdf9f, 0x262cac81c986a170, 0xfd4ffc22f5e3933e, + 0xb5b3afab9708e332, 0x0b483445de1a68e0, 0xf045e1b3f78406c2, 0x32a75ca09d0b0069, + 0x034e963ca205f24c, 0x8bc305c6febec1a3, 0x9148545792f0d5cb, 0xfefa0c531dd5369e, + 0xd84baf606b249988, 0x6c1c447febf61f87, 0xc7f69738c1aa99aa, 0x6054ba988df8f4c1, + 0x9cf4a0d410341b9a, 0x94841063e9d663ca, 0xb016f475abd322e9, 0x6690ec37c43a9575, + 0x06e489c152f8aaa9, 0x8c7ad22984bd9cc8, 0x3eae03a13784dc12, 0x49b49ae5d383c81d, + 0x13e8d32675098c23, 0x8af75c309ee4ccea, 0x54df63b27ece43ec, 0x190879d4d18e5d2a, + 0x20b77a8baed118b6, 0x6cd0cfabce914858, 0x1d1e32bd826aa8c3, 0x1d18ecdaa21050c0, + 0x3ed09f3e6cdd97c9, 0x0ccd68fd4d2b1123, 0x23308ea911e8dd55, 0xf2532ff72988cf98, + 0xe12598ee5990c53b, 0x0322b6f226c1d204, 0x857773c13bdb2989, 0x618f03e69b90eef6, + 0xe9200ef9b3e73894, 0xc37391eb526a690a, 0xe473e9f1812150b5, 0x166f3fd63eebc15e, + 0x657c0049d2c5828a, 0x8523010031224ad9, 0xd7d61cc41a7d1ee2, 0xb521743076a7a8c9, + 0xcb091f4163220254, 0xca446fabe91f13ce, 0xda61af0926fd2880, 0x04ac4c0b8ace7426, + 0xfe99be0bbeac5447, 0x5ad06e7d5913302a, 0x3bec8f975d0f38bb, 0xf2972a26bcb0b54c, + 0xa108ba67a4fe5ebd, 0xce1c775b1473f30f, 0x5bc00377233babb2, 0xb0ffa56927c5f5b7, + 0x04f6e46142943963, 0xe95aa93d94e19c6e, 0x9d7ff9c22aac07e0, 0x29ab2b161ec1d8a3, + 0xc1a9cd9374cda333, 0x0cd55948d6584ee7, 0x4ec6af6e22bfe771, 0xa2baafdfb6905f81, + 0xd23b82ea048fad3a, 0x1e430f240835b550, 0xdade0e927bfbb569, 0xe393d7ff83dcbf21, + 0x210dfa4ef9602816, 0x805ecdd29f174819, 0x0fc4374088238f46, 0xdae177b99644414a, + 0xb6fb95f2187e7d47, 0x90c02722bf69083e, 0x41b0708667b5cc93, 0xee3d23be16a045eb, + 0xccac36957daefa83, 0x5a0f061df5c8f53c, 0x8b62c3ef372f0712, 0xa03818d30300ec7c, + 0xff0ec8c1b22048cc, 0x251eb53fa70f47b0, 0x8c6f30f7d9dbca54, 0x866f8302b8aff07c, + 0x4a5db4e64eae4c08, 0x9bdcfc376ef333f7, 0x1af745e1169693ed, 0x1b48739aa4ce4bd6, + 0x5ccee7fc1cc71026, 0xfaceb988f576297f, 0xfcd26e301e063253, 0xef12ce21347bb7c0, + 0x4f60907b1dfb36c9, 0x878768ad4d8163af, 0xf240b167f3e66574, 0x24f9a3abd7c7866f, + 0x9ff0264564d52bc2, 0x270488044eefd3ba, 0xcf6a0ac81825d701, 0xaf1987d4b3df8ec4, + 0x74a48be1f828f882, 0x21a178526b0994dd, 0x2c20153ff3f04cdd, 0x4dda3fbfda00bfd0, + 0x09981aada46e2a2c, 0x11de4ee48ec7b656, 0x8d8c192482d18375, 0xb97dc7eda3ac7c59, + 0x8cde6ba7ebff1608, 0x65f3213ea5897d1d, 0xa7a28f179428eab4, 0x7770d1677ba15e20, + 0xd1f4711a6c3c9e2a, 0x0138c261f90794cb, 0x59c6d34042a7e8a1, 0x4cfbc206eceefb8e, + 0xd75e76504459477f, 0x034c86bf5c4d504e, 0xfec8cbb3fb2500a3, 0xe844946434d03dee, + 0x0297506176c6d1f3, 0x7dd14462ce609dec, 0xfc7394065e43d0ec, 0x7febf3ac4e23e42e, + 0x453af607e5aae17f, 0xade34aa36a078ff6, 0x941acbba4f911c47, 0xc28889b78588451f, + 0x9377e1db1bf91b16, 0xe2f3bb7f789cfdc8, 0xbf772980b8af27de, 0xb4a1d9051567dff1, + 0xd55fdb0162d136fb, 0x1f98e82e8819f5e3, 0x70b319ed316a9bb4, 0x321cf31a4d2176cb, + 0x6833732053f95986, 0x9a084c20f6b44de7, 0xfa3adddde3386ac9, 0x06de7616856fa41e, + 0x2708d37f188c8596, 0xffb1643a48c1b65f, 0x5aad2e7b65939922, 0xb1a98ca7d2d85685, + 0x6a73786354e89d70, 0x86044ab44ff7221e, 0x3b3098953db9829f, 0x7a8c3f24589c1b3e, + 0xf70e6395e4a7f2a3, 0xda8316c9b072784a, 0xc24074f0b7b045f7, 0xf50af41f2e937a93, + 0xc1be65ac7d72eb43, 0x186ec42d3b2b5722, 0xaaa10fb0ef2a699a, 0x9d14c0c74a7ae15a, + 0xb1facecf4b1a792d, 0x529d1701894e61f7, 0xc19b35e560f47292, 0xe3be0cfcbde066c0, + 0xe87aafdfd1e06ccf, 0xb4446148b1bae589, 0xe29b2c9884cf5631, 0x00d0eb074cb53da1, + 0x6841df19ffcb6068, 0x22ce112106430bf3, 0xceadf1c25704f801, 0x32bd6478c4ce23e8, + 0xfb43dabaa3d95bba, 0xd50b0f9b8a09c850, 0xb2a5ff6982c9b048, 0x3f2790135a4261d9, + 0x4d9cc300084cf7c6, 0x1c390af95a4c7e1c, 0x20c8da89b7075665, 0x2af80c175a18b9a7, + 0x67f23fa177e7e364, 0x69d274fd5e6e5882, 0x5f56657e8d053b3c, 0x5531eea234fb69d6, + 0x88aee4d9068a4136, 0xb7a84698b4b38176, 0xe03d1fce530bf7d6, 0x9b45dc0850f2b71c, + 0x01fe0cdc2646ee31, 0x26b0d87ffc788c97, 0x69758f37d534d20f, 0xe2abd9346930877a, + 0xbdc667eae4856e2a, 0x826cb5eaf3ab98ca, 0xd5c2acf8e71c14e1, 0x2a4c5998097ebe05, + 0xe59a97d1066c1753, 0xddd2d8cdafc8d9d0, 0xc71ea4858b8ca61b, 0x46e481c79a7a17ba, + 0x233bdbf899c25a5e, 0xce0bb0e1da4c671e, 0x26709c98575020ce, 0xb0365ba5e17d4c4f, + 0x0b5cc36635c83f5b, 0x2fa8fecb95417480, 0x5960626c6cf95e40, 0xdf62912e62294f80, + 0xb8d360e2a7f09a10, 0x3a578b537d5a2d2a, 0xcc24ef33709c40b2, 0xd099e49ad3a4230e, + 0x7a30564e0b46ef72, 0xb1e4e1466b8d3765, 0x12fa332644c62144, 0xbcb2ea48dade6474, + 0xf00d03cc5536393e, 0x8079a6566115b8ef, 0xa80994168c4aff17, 0x6c430c589134622f, + 0x4c7157cf8523dc53, 0xb44d6e671c0b902f, 0xe56b2caf6c161919, 0x2e3a569676dc1c35, + 0xeb05d4aad1981845, 0x174842eda9f65dcf, 0xa64fe4de015be262, 0x491084a228f0ec07, + 0x9ff9f0164b29d97f, 0xbad5728a7549398e, 0xaf54ac566fad451e, 0x043677a314670fec, + 0xffa4ab0bdd4aa1f1, 0xc4d6a29d3a1fa0d6, 0x805e17a9218b3233, 0xfab659408574c7c1, + 0x85659ae0b18ff3f5, 0xe34ba066a333e1af, 0x7c9a323091ead048, 0x6c753b6c7efd4df6, + 0x9036b7becf58383c, 0x24c418c33be323ec, 0x59ab6fdd36de6204, 0xe3494ef60ce568f2, + 0x518837b001bccaa0, 0x0ee65f83e25487a4, 0xd7f77b6aa00949ef, 0xb51b73b1eb5e833f, + 0x750667f39a1e6fb7, 0xc21c9d7c088b42cc, 0xd62b58bbc641de29, 0xc3594f2c5d0cecc7, + 0xb07d8e7e49b7efdd, 0xd0b6f84ffe48bf08, 0x3a3cff3e0e28f152, 0xb68815e527566783, + 0xc1ba107095544fd4, 0x75d59e7db0202c27, 0x907af32626db452e, 0x91de8678714439b0, + 0x0ce39c7dfc7d1278, 0x082715e9242543ca, 0x75ac6b872b754459, 0x761cdb6c21c2ba97, + 0x3b33d435cccf0f06, 0xe375a89fb1eeadb1, 0xdb658e982ba46f98, 0x6c5ab34405fb6344, + 0xfbea45a2a57d50fc, 0x0d9eeb4bf4a30331, 0xd89d0939e616743d, 0xf92ed97c1bf6a4d3, + 0x83fc97deee2ee851, 0x91a312561b1e183e, 0xa80f05c9750d9912, 0xb942abef1e34ca47, + 0xa6eb110e8d54c0cd, 0x8cef800ba5610d3d, 0xc0eaa3ed67f01c6f, 0x9c887f4aa6a3dcf2, + 0x2f710f3576bbbeeb, 0xf759954a869f116a, 0xdfa63c1b4e1e3ccb, 0x3ce9bc3ceaf60219, + 0x3361da3cd02c4703, 0x5c162bb1aefa0dde, 0x8cac1538fa977431, 0xdcc411b78ab69604, + 0x6c1402989eccbde4, 0x375f3c04c3eb345b, 0x9b8dfdd18afd9d3b, 0xae3627b3d854a5b3, + 0x835f74aaedda7694, 0xfa1bbc390557d04c, 0xc83336bb6d3c624c, 0x99591577cdb28e88, + 0x73403eb5ed98b2fe, 0xaa677e810ca2bcef, 0x2f6c2070be1e29a9, 0x4e2dc1313a13bf9e, + 0xaea50f3ae2812b26, 0xfd869c82ac686554, 0xc1facec414697082, 0x92becf92fed11d82, + 0x01a2831aca6b09c6, 0xf49b0c23be77b2d5, 0x4041339a88c8309f, 0xcd8b4bbcd00b786b, + 0x372f6704d3bd3113, 0x9d0b86b7860b0ca7, 0x0a8dd3a96584fef2, 0xef68e2b06f0e7b16, + 0x81a148824c3c7d64, 0xfa37e89ecf88da10, 0x970f753620820d68, 0xf82efee32ae3b5cc, + 0xcaf9534d43561ba3, 0xb9677e3c242d44d4, 0x1389f742075bf073, 0x3f54145149231244, + 0xe3845de16d4f6674, 0xc313dad0ac90b250, 0xeec5772fc03ba5f2, 0x93885adf6a5eb894, + 0xbf987f72b8075306, 0x558e54e09c99f222, 0x0ea9d020a89c9e80, 0x98c95714cb166a40, + 0xae48c57fce993f80, 0x9c7ce2f1e41092ea, 0x49dd74dcaf1d1e84, 0x308f2951fab60b13, + 0x08ddf58bcd3b7afe, 0x96f17b434a3aae15, 0xd248e6342b72ac90, 0x00375d359528e1ae, + 0xa484189341648560, 0x4b38db273dfc473d, 0x07b62afb161372ba, 0x373167ecac67d5d6, + 0x01d1b8c2761f97bf, 0xad95e2ce55888ecd, 0x2ddf6ac916ba2317, 0x6edd29b3a1305fd1, + 0x42e8a6fadcc18446, 0x36795f64c0279b08, 0x16c4c1dc0eb6ca60, 0x3425956489ba1915, + 0x771e3aa060ee5284, 0x3bb800832802f496, 0x117b2fc9525fcd61, 0x2db90016a39104f9, + 0x0c882393d84ebc4c, 0xc859f1507e65b55a, 0xda0dae082af012a1, 0x81f6fa8452e539eb, + 0x0d727468916ea4ba, 0x2acb757b28da6c75, 0xb2032ade6af010dc, 0xc3c1148299a78de8, + 0x01e83d7da89a30f5, 0x294d1781b6148442, 0xd774c29530a6090b, 0xe7f147867eff82d2, + 0x32f7bbd79f909d45, 0x4a1e8a34f6c1df4b, 0xf06fbb207934a0f6, 0x2c295f9d742a78ad, + 0x429df3eec2a1c458, 0x270bc19383b97e1e, 0x7b8ec1a1c86ae6c3, 0x774ee107d5534fad, + 0x530d73bee0be4374, 0xc00c963fca7de8bd, 0x9441adb5d69b490d, 0x704ec48321a008a0, + 0xe524a8e26a6f7c70, 0x2dcae156d20f2b9e, 0x9c721e397d96eb55, 0x47aa2f04da2c2ddd, + 0x204e1731fda296a1, 0xcb8b8011bf6a03c9, 0x218ed7bb391d33e2, 0xdd9af39b6d6914b6, + 0x3c43f22fabf8a310, 0xef38ac110da24c60, 0x42d6c03c0e60890b, 0x210f84ed87b741e3, + 0xe08701075822e0dd, 0x0360633341883d67, 0x5450c00ce7773e75, 0x64809a1fe7870d99, + 0xf7e6f72d5b654392, 0x75960432031877b9, 0xf49af206643cd7e6, 0xe80b00709de42d66, + 0x16d42b6b13160b52, 0x538b2c6b362eef8a, 0x8fe774d825f6d9f8, 0xfbbf3b881b576d3b, + 0x5add2ba6b49b57bd, 0xdafea301209a66cb, 0x270d18fed17f869a, 0x871749140672a041, + 0x53d087cf3bac84ab, 0x1151272d50e386e2, 0xcf092d2478b829a1, 0xc07caf08a97b4ea5, + 0xab1ceb2a1502085c, 0x15aac6580207d92d, 0x47101df376cac03a, 0xedd4ab721e1b0e00, + 0x17140fea8a510be8, 0x434b187b25907435, 0xca1d171078c27c2d, 0x0f1e2e9f0114d4ee, + 0xad2cc7a64fbcd67c, 0x026e2181ad02ac77, 0x13fd7c5bb7b0f5d1, 0x99157656e6487547, + 0x328fcb418479b204, 0x9205b0c6116a08ad, 0x7f8150625f72a321, 0xa66c201723a86dba, + 0x3d73a06b8fb2ee3a, 0x72420179013c109d, 0x2ed221e562f7c5bb, 0x1b55c5ca650da670, + 0x58846c4eed2ab062, 0x389358ae7baa1442, 0x25cd2e4f0756abea, 0x7f7168818c7ba33a, + 0x8e7974a218acecf4, 0xcebbe834286cfc7e, 0xee2d53b0b95eced3, 0x918bb86bd0b3e798, + 0x01afe454314b6595, 0x2149ac3ca01ba713, 0x743c601766822e84, 0x163333e6fcc41323, + 0x17a7cd8bb733cbdd, 0xc170679b9f4803b7, 0x924a19f12c0d0abb, 0xc95bcea2ef79317c, + 0x41db6301e69261bd, 0x27c5d21412832ef1, 0x7d18503979f82676, 0x866335ecf57780f5, + 0x4111e5de057bc51c, 0xd3845fabe3c63ff8, 0x33fe9498c9134cbe, 0x4cda52b2225b16bf, + 0xac62f35ca0c95a04, 0x5213bef690c0714f, 0x3ce2999b0fd69a3b, 0x29c54a1d54c92d6b, + 0xc78a127f7304a30a, 0xec9dbc4bd6e4b2ee, 0x08b29fe98bf02b3c, 0x2a6141db6012b62a, + 0xdb51746b5d9aa18e, 0xd7fef9b6ef4488e4, 0x785db050c8535121, 0x9ac9129cd2f90988, + 0x4a848db771482a1f, 0x8985052c78340c09, 0x138f8b646d8b688c, 0xc2bfe55f2c927977, + 0x9a2d7a2a8cce6322, 0x9211547f7674f354, 0x3d06e1dfa2ddf61f, 0x9d6424ec71eccdb2, + 0xf0d9f74996ec5024, 0xbcd7005014d395c8, 0x76180646fb79649c, 0xc1d3e3cc67e26375, + 0xcedc412a875df84b, 0x2b0ff3e22f82493a, 0x749067b4eaf521a4, 0x2ad9305ac7048c3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x312d5ca67482d023, 0xb3541bd290bed320, 0xb118be112c2b8c73, 0x39d99bbf92f69b5b, + 0x2b875a20cc7cbe33, 0x7f37974671487294, 0x2994db86931d3726, 0xa9c3cd42271b243c, + 0x2f23ee35933e4717, 0x4e296824a48770bf, 0x05572c01d47807c1, 0xcf0c46b0be471f20, + 0xd2eb1f233d544184, 0x8148c9b90080041c, 0xc24c5dfd0952a7d6, 0x7b751753196de8eb, + 0xfef330427abac550, 0x295c63f50b7b1e2c, 0xbc73dfca83df94e8, 0xb8beff9e52a601e3, + 0x0e5bd64ed5fcb2bf, 0x30e8e4eb68530d2e, 0x52e062ef9f25f33f, 0xc60e0dc0bbec8cce, + 0x3cd4e958b1dd35b9, 0x50f857b5a9bfa0a1, 0xa975946e2fee6d98, 0xb0be744f06251460, + 0x1133241b67590148, 0x199e1fb9720c8330, 0xdec7d5392ead9007, 0x232f9df87b8df8c3, + 0x48c0231165b49477, 0x9e6828214fb27fed, 0x7963d93ccb878817, 0x6b34f08826676cbf, + 0xfe1e91b6b6ac2932, 0xf2a6289a1d7fa6b9, 0x6a4065324b89ebec, 0xab0406335c55a0c1, + 0xf249740ced3ce7df, 0x720a88a072183363, 0x09797a286e1ff82a, 0xc643c3409f2ed036, + 0x077764a906b49b52, 0x0c0be7cc9b0601ac, 0xc72812964856cd7c, 0x8e6d1d1612adeda2, + 0x8b63660122a14ef3, 0xbb77167fad558d04, 0x6c0687e55d6fdc1b, 0x5c8a14b9ada3f720, + 0xa9837a1be7d5cc1c, 0x0e9b9b851e8be000, 0xaedf7f77d7d9d23e, 0xacc1a344f673b59e, + 0xfde9da89b2a8dda8, 0xb3cfc7749cbe9aae, 0x0387aeb3a39c0ec9, 0x9a6582348139af0d, + 0x47f019dbcfc35cce, 0xbf2f59a7554eb293, 0x655028fc0b53037f, 0x234a32a7d7b88db8, + 0xdda8dffceff67270, 0x73d3bb89d19ba899, 0x9c22d9b9321b3e22, 0x71ee62c1d06de362, + 0x7abf0efb7398a474, 0x19eeb9bf87b04adf, 0x041a65022f575411, 0x74fdd01facbaaeeb, + 0xa8d6da78b97ba34b, 0x79cd93316e22cc56, 0xee5fceaf8f7e3f09, 0x8b553def10b23433, + 0xb313a697c58128f3, 0x7e800f682a5151e5, 0x720d4f85cb0ff62a, 0xc5bb0f7cc98bff73, + 0x64d1121886f57cb0, 0x6fe272cd86e760fe, 0xb22a2bad9eaf5da8, 0xe101ee90526ebbda, + 0xbc10a4f1234ac302, 0x366392d87bdabba5, 0xec86facc3094c567, 0xd063f1d3a15ca4e7, + 0x4933e1e79ea25542, 0x3ec6e0d97a07d13b, 0xdde4387dd5d7048b, 0xc872294ceed15170, + 0xcf1fc2b88dc3b938, 0x2b22cd0ae1db9a09, 0xe820acfb9d3aba94, 0xf3ee426e2d717cf8, + 0xdf73b5744e40ddec, 0xa3d78de64f41d27b, 0x0bb7970a153b390b, 0x5a97b73fc02ecc76, + 0xf5e825e01a0c0526, 0x24ca17958d5f9bce, 0x1ad0b1b6786050e6, 0xb61b2c8ed004ea2e, + 0x5201c10d0253c063, 0xe205552ad73f348f, 0x4ea7058709d54aec, 0xd5bfc501c6042c7c, + 0x132114c10fd80719, 0x4c46c0e817fc74d9, 0xfd39f91d25e1988a, 0x70a94aa1af7c6fd0, + 0x27d2d577778fa09a, 0xe082c15573d3efab, 0x5cee67e3c2a98563, 0x4a760d4f600cd6ae, + 0x53953646cb1468a1, 0xfae329631b6808c5, 0x0be60bef66bdbccc, 0x76b5dd1e24265fc5, + 0x06f4b5b644608d09, 0x1df17698e506ea02, 0xb8e581555197280b, 0x528d42bdd74af9cc, + 0x05589f0bcb5b0e7e, 0x245926acc4732aca, 0x56d6ab0b0d751eef, 0x22dc58c3cf902884, + 0x2cb3d99efac0aaf1, 0x68434cc011eae7ae, 0x9e7879f5895b0ea8, 0xfca47e35aee48554, + 0x335cc314abb7dc6e, 0x37fa2b11d8291903, 0x3e3f9927c8b95ac5, 0x7596c87ee268453c, + 0x7d878ae25741b216, 0xd7e55f4f3c661959, 0x2880153a576bd510, 0xad1b0c64e7d15ec0, + 0x0e5a5c3682f367b1, 0x0c6b493240d4b3b7, 0x276c7ce6a843b153, 0xca419aed6aa95b8c, + 0xcbf473f5026f80c3, 0xa6facd79a417d6d1, 0x9821411c083c6c8d, 0xd6596e9d24b090cf, + 0x096398c8e680760e, 0x9df16cc77f77bbe4, 0xec87dfff1acdc1ff, 0xab0ebb43021a405f, + 0xb04767572a005839, 0x59c083ac23f9dec8, 0xb26e1a4d34501409, 0x73a91779ffd862ec, + 0xf2572b5602da1ab2, 0x40b448232a7c712d, 0xe3fd6828723db975, 0x331cd783b9c76951, + 0x551a3141cdd4afa0, 0x2a9d34e1d7512de2, 0xa17846cdd1afe710, 0xe8253c71153a383d, + 0xac111dec72748a73, 0x27eb995c4ab2a4e5, 0x62d4217e32e0ae12, 0x1b48d60b95ea496c, + 0xe34d6a8a13c66bfd, 0xb8c44e3f56fe0d8d, 0xee43cd6dec7ede09, 0x511596794c305347, + 0xc6b73dbe48e65803, 0x8f6f2b3ca1c30c4c, 0x8a2766f7d0f8dc57, 0x3b7d4377c505b5b1, + 0x66a3dfbd5eaa3891, 0x84b86daa5bb1be5b, 0x3cc4a67617231b3d, 0x6ff8e897394e5630, + 0x8905dfeade7b2b10, 0xd13e8b0a1c289a16, 0x5c4a2dd7d91806a0, 0xbb37510165a709a6, + 0xeb3f543405a3033b, 0x3486531fb981cc75, 0xb66b4123bbe935cf, 0x19471235b2e5eba6, + 0x8e3e80b14ba9f053, 0x1eac925150d90d9c, 0xbfbafdbb9a4ae0f0, 0x650da8d532acc039, + 0x3ee9d7b69a84c9c8, 0x6b3caf192a958cbc, 0x5258b72debece466, 0x76d5f13566b25dc7, + 0x7fb4290a43974c04, 0x539966aed4a713c7, 0x354e05f48955e8af, 0xcaa89635d4589b4f, + 0x25a90e771ae50873, 0xfbe5a6dad77b363e, 0x5dfa1ef45e4e89b5, 0x850ded439160bc0d, + 0x9d6bcb57fc7ee5f3, 0x20644f05380f107b, 0xf5530ffe5030f7a2, 0x9c3d15a60f400583, + 0xf453224cca482bac, 0x4938b2160cdd6229, 0x56523b710efcf3b2, 0x92e3ff47735809e1, + 0xf0179956c01b834d, 0x885ddb2f283d5bb8, 0xc142a552a9dc6503, 0x8ae9d8d69c0ce536, + 0xba7424aa61225674, 0xda02fb25ac87c6f9, 0x24fa86dd462f2c17, 0xc5cbe5e6a1c27002, + 0xb58af53e273730b9, 0xbc423e3b5b6b423b, 0xbfd482e6f83af2f5, 0xacf809e5edfdedcf, + 0xd397d4904daec822, 0x38dc276c2f305a8d, 0xe0f7fe00bdf9af89, 0xad78e8c89333a14d, + 0x38814f6e19a181b6, 0x01ab2bdcd6721c0d, 0xa4c2cc705383d9c9, 0x3cb3ee9a0aa9a715, + 0xa9b9b6b83cebd9de, 0x1c00bbb7b09ce4a7, 0x27d86fe0b2604ef4, 0x36f4d80b5772cef3, + 0x01b0c8bb000e2d8b, 0x64ce5731055d7d16, 0x5fa750643a153e82, 0xa12191b8ef5cf369, + 0x2c4cfc42e45d9935, 0x3b94396bc848bd4b, 0x9e802678412db686, 0xaf3c12a7ee39f20a, + 0x42e4fed3523edcb4, 0x686e804f132ce3e6, 0xf056bb9cf46cfb73, 0x4b98f1b7b6e3703e, + 0xe1d64e56bef8cd77, 0xe8d79922fa0520ad, 0x5fb12b935ebda7dd, 0x1a202b9abefe3556, + 0x99b81165d1c26fde, 0x93f61afc9cc0d192, 0x5ba564f367170084, 0x6967b93e4513278f, + 0x68036d55ae7e8a0d, 0x100b1d0a89d5196c, 0x02d8c1b2f3a0221b, 0x90aa07065bf579cb, + 0x50230748abb1a5ab, 0x9360177807d84e25, 0xa40b8b480b0c7cdf, 0xe159a74904d949f5, + 0xaecb0353fc9f6cc2, 0x2e17626483dd67ad, 0x295033d20fb07562, 0xac23bd5bf81202c4, + 0x614adf6993b552cb, 0x372c426d9ba8d695, 0x6817d158447c6db0, 0xd711e490bb0a96c9, + 0x42ac67d5d68e5e60, 0xb577d44358cad9a5, 0xeb9088b8b9cc02aa, 0x4eea848c36d01b59, + 0xc39d05204ec54f0e, 0xe9828ebfdfb3fe5b, 0xc5040c3176538a2f, 0x984bd3217b830911, + 0x06693fa6c3603ef0, 0x259c81076f9edc75, 0xe3c16cf9664d3907, 0xd430ee00b2881173, + 0x8530d7db605e5628, 0x42f47a718fbafc99, 0x50a608c2fbed8a9e, 0x9c26bd531ffe3fd9, + 0xe223dbae34e1aea5, 0x5b0b0240280b06b6, 0xd76b9c1ab6331dbb, 0x8976aec739f8bde6, + 0x3b4e1cbdaca0dea9, 0xc08686f40577c408, 0x5ceff49262c3b5ab, 0x8f47c0c2afc9c587, + 0x15289d6b6d62851a, 0x12c6c9dd51627dc8, 0x0b2ebc403d3df551, 0x5aeeab941ef98d4d, + 0xa9f12659a3fe86ab, 0xb6d2b1b9dd255757, 0xb8578a8a29bc39cd, 0x180c6edbe5928616, + 0x05d33444576686c1, 0x2b4c641b4c1e5d89, 0x4e472b011443636e, 0xdc8d4d3357d55249, + 0x127d9600ab065506, 0x7b37bd7b00b6ac5e, 0x78429bffbc743113, 0x3bf46cefb046253e, + 0x9f6984a37b1a8c78, 0xf779d4014a269df3, 0x1e9ad59b99e2b588, 0x0f4ed05c88e7db9a, + 0x8ba3d1d87e794bf1, 0x364018d90031fb40, 0x8331e251cec518b8, 0x4cc30fb8af6a860a, + 0x38382cf1439dbdd7, 0xac04470c04156e11, 0x59f5267affe1403a, 0x5ef24c3e6a8f4170, + 0xdc39a477ef1e3bf0, 0x3fc37d5901bbf073, 0xc427ee1b31d1c02e, 0x4be6b1c312dc89d0, + 0x221fa07be5d8593c, 0x0d4fc8689de97adb, 0x2e17f7d9e3d12cb7, 0xc594ef6d43419f2b, + 0x9116abee38b50c82, 0x51c52fd7fd28b49f, 0xf73f86d0b9552dd9, 0x834feb44ac603498, + 0xa9839fb500f2224f, 0xa24c74e68f5da2b4, 0xc639d19b51e54bb3, 0xe953140e20febd80, + 0x9ff0572a3e88ba86, 0xda4dce319a864fe0, 0x322019c432c6b022, 0x216e04657bf3881a, + 0xd1bdc3697605a32c, 0x6239f065f8a63dd1, 0xe246d650120a72df, 0xeee591b993c7d9e5, + 0xb47a497972bfc831, 0x3788a416a58d5f36, 0x48b2d77e38c2959e, 0x9a2d22f84c6a0dfa, + 0x5bb259df6715569e, 0x2482ebd7239fa03c, 0x7158dc7fd1b04659, 0xb541c0b84e8080e7, + 0xbf1938ff28cf7df3, 0x1d1d5623521871a4, 0x83880b816f22c83c, 0xf2d9cd23933ca820, + 0x02f1bc9202e79f3e, 0xce0b642537878387, 0x6c0eea5c09641d91, 0x359118f2bfba7f36, + 0xd37769614e8bb12b, 0x5661db0649d7d428, 0xba5be9c74f4d9e82, 0xbcb40c8a196f906e, + 0x811c4dacede7cc8c, 0xca2bc0c4eeda9ea5, 0x7b47b3a5b7d12a09, 0x1d38d56d187b5317, + 0xecda6910b28a65ba, 0x42d43b004c8c2f9b, 0xbc561857d386e072, 0x7b6025a93f711eb9, + 0x7edfaf73d1ebf423, 0x493db7c3c21c8ae9, 0xb6cc327fc8fca50c, 0x100d33c71621cb00, + 0xb14e75a7f402bd3e, 0x7f0fd112998e6aa7, 0xfb971b7df0cf0305, 0xcce6fad26a7146b4, + 0xf1b70b605d8e0dc5, 0x58522922a86d9caa, 0x073694e0a6a9a7b8, 0xb2ab94eb5da08701, + 0x15e1b14edc5af741, 0xc18ac460656789ed, 0x681febbc0fcfe064, 0xf718e44338801be7, + 0xe549788c00fb2a14, 0x4ed07586d4719b61, 0x7ce4c1ddf2f6f93b, 0x90d0647fc59e79e0, + 0x75a8d76135a560ff, 0x0576cfeccb2b49dc, 0x6b964bcdf9ee9405, 0x93c8100934fc08e8, + 0x4652fccc60771c39, 0x6e8702f63db7dd1e, 0x2ebbbff348f4f4a8, 0x03ed452f6ce04e55, + 0x9c3dfd4f224f3a9f, 0x3dccb7e0d3b15369, 0x0a2382ee842d4fdc, 0x58676a605f19f272, + 0x80bde8f51637b6e3, 0x9a5136aeb60225a9, 0xcae720b31404842a, 0x2a383cd7509a4082, + 0x07e6194d1a5ffbb6, 0xfee25c0add70b04a, 0xfca6a8da7c0f64a9, 0xda29eede78355989, + 0x10217f2ee22c41bc, 0x4283d723d7e324d9, 0x96b9b0ec5c12add0, 0x3291b6a6ee79a9ac, + 0x535965340cad2fe8, 0xdf08ca2a04135008, 0xf911a3e5180aedd1, 0x74651696b0aa0bbf, + 0xb6cd9282a816c4c9, 0x236a66ab958e3bed, 0xd6a0351a7d05381f, 0xaa2825ee5376f12e, + 0x3385bed07c35853c, 0xf28d9a73f1a15641, 0x2821b03f0dd7586d, 0xe2662af03157ec1d, + 0x8684925475701d69, 0x1a3c3805c3f55e69, 0x3b797b69a2e5e1e5, 0x8fb83d2d42854f7a, + 0x7e85bc3984776a04, 0x9e8535095d074d8e, 0x80438376394bd629, 0x54b70ac619bea9b1, + 0x0707cf21da936b10, 0x89346d57c574d801, 0x7920522e806efb41, 0x6226cc0bd1cc0adf, + 0x21de5073b66ca898, 0x26fd4ccad6e09c04, 0xf2938d59c1cff5ee, 0x3281aa2e788372eb, + 0xb58cd1e3555780df, 0x4985704534857b2c, 0x5da2e64a0061ae75, 0xad9e55b120b3cad2, + 0x59d7c7558a7c0696, 0xa7a250a8b7614398, 0x53e79b60d1996d68, 0xacc82675c77c0360, + 0x9246f8f0d0c21a7a, 0x3b013de96fba5dd6, 0xa4625852462f3c8b, 0x25d407f2854bb16c, + 0x786a22afe48ed932, 0xc2706706d42acd4c, 0x83b13f0cb9957f94, 0x44687b76d0a2c892, + 0x5e8789526efb1a4c, 0x044a0e28299104f2, 0xac5a07253e1599d4, 0xe110dec16f578863, + 0xcd8ad0c903c7fcd0, 0xf737e0335cf99a0c, 0xf7fa1221f164ba0d, 0xbba04ed1b05ed6c9, + 0x783fb7b111149ac7, 0x7d33ff4e090274bf, 0x6388a9746d0050ad, 0xdebc58d7aa14b90d, + 0x0d7f966584b03c9c, 0xef4fa3e1d79b8ea1, 0x62f6b13e45f07436, 0x23d2ce3ee1fee870, + 0x54a6b70450cbcc2a, 0x5a938afef070cae6, 0x4e5d255a50bbe052, 0x52fda18c50742990, + 0x041fd2f6549ada1c, 0x06f6ab85ffd028c5, 0x2517bbdae2b5f33a, 0x153165fbe4f0b6fb, + 0x57b86ae658ca9642, 0x95e59a04bc7fc8f8, 0xfc660809c7f659df, 0xa800b6032603c310, + 0xf09dae04bb02ed1c, 0xd75638af0f171fe5, 0x6c5b388a682d37b9, 0x8b4f44fcd2a2f2a4, + 0x9e4a66ba8cf8f0a8, 0x484ba7bb18b8ca05, 0x317ca915b10e9b9b, 0x0396a9e20c5dfdf8, + 0x076d711d47039bea, 0xbe11a029a8e26cb1, 0xd83adb46bd0f306e, 0x5fa5859d91c4b6ec, + 0xd495c32969586b50, 0xf9dab3b4efd03652, 0xdbf1411db43aef64, 0x053ad2d1fbdbac7e, + 0xcb53b5a673d59299, 0xf16dabf60a5f1620, 0xd599f3a7ac81fe23, 0x084c55c0b13dbb73, + 0x8a37e041c33ff108, 0x9a20507f229901f0, 0x952381708eaaab19, 0xce3e60a911adea9f, + 0xb24d0ea225757a17, 0x7df9c1c3dccee478, 0xa95ce32559f1242a, 0x16a8ca55c0c10c8b, + 0x2a84a5eff3d3aae0, 0x47b1e4e3a6757dae, 0x46276db095d9b343, 0x6ddaaced07e1189d, + 0xc5dc936d36d1ab46, 0x45afba7dfa3da5a7, 0x1ac15182f8f377e2, 0xda59cefb982f5649, + 0xead873adb9cc9d9c, 0xadc1daa6e9526e55, 0xb3eb9982870e6554, 0xa49ecac14ee4bd84, + 0x4d3ead0444662db3, 0x9fa3f51b9cab5713, 0xf1c5ef0d15b5de33, 0xcd1fc13dd78587a6, + 0x5161a0675a9a6edd, 0x7425eb83791c302e, 0x5928da7ada207b7e, 0x6375c8cb9117e707, + 0x940777b1918e6278, 0x7b63f1ef16921659, 0xcf81a9fac69ad6bd, 0xf62087ceb228ce05, + 0xe8d461ba645d55bf, 0xf1c0645c0b541e64, 0x448661994470a165, 0x5de8c01ec2339f21, + 0x78f5d4cc0d9fd908, 0x344cfddad86596f0, 0x87a6ccbe6e597cc4, 0xda79d1a3ab947672, + 0xac1695531ce42d16, 0xaf3ea33b33ed8962, 0x19fc70e1e0d51b56, 0xe275d8dce122ea88, + 0x00c3a18447f6d95b, 0x4918a35167cc533d, 0xc3dd9adfa99c3176, 0x221dcdc52b3d97e0, + 0x3cf7717505485b94, 0xd0b8512cc428e3e5, 0xecafb64ad72469fe, 0xb0ae441963f22554, + 0x107b2ada1915dd7d, 0xbb1058c51d414732, 0x544f2eb9dc624d44, 0xcd55b8020140729a, + 0xd1e8eec02645e66f, 0x9993bd6edd498aef, 0x51059c504807f249, 0xc86d8a3b265aef26, + 0x42bba851517da888, 0xde136def587cf15d, 0xc43449a9e521ebf1, 0xe78c37548b69f458, + 0x1b5505dcb9359706, 0xc132fae79b87596c, 0x66f80ed0f55402d6, 0x990718c8d9b3c3be, + 0xbf4428183b8010a2, 0xec25bf3cc9b033f5, 0xae9baf8a00c13de6, 0x1a86a3fee63d859d, + 0x5f0879d562731087, 0x37e769bdfe25689f, 0x841ec71ddf08daa5, 0x2546e68dbd97ad35, + 0x2ad8cbaced7f6582, 0x55a7017295a07b9b, 0x3811a0bd7fed8668, 0xf14f17b39ee0d520, + 0x30f0a1bd21a950d9, 0x6325a89610d3c33f, 0x3745c78ffe9848dd, 0xcff4aae2c1abfd7a, + 0x24f0779ec0819e25, 0xdde346bcdbd36f17, 0xf0b353d616c9e82c, 0xc43758e13575c0a6, + 0x5c40b054e444ebfd, 0x0ec7a32a3607ae9f, 0x159f1ccdd2ffc5a4, 0xae4fe26a88d957a4, + 0xabbb9a91fd91410e, 0x00a7acdd900d041b, 0x3348fc7ad8d80ff9, 0xcdeefae7f52a08fa, + 0x3c4785569dd936c4, 0x03a7e830f692d0f0, 0x210d33973cc4f5bb, 0x3bf18cc6802f0779, + 0x1085ab5904cc999a, 0x0284a616492747ca, 0x120d948423ed5e6b, 0x2c20131dbc5b7d9e, + 0x0d87b9edc35c9f4b, 0x9ec60dc492d06627, 0x08504d228a86e239, 0x8d3c010ad7f0ef8c, + 0x8564d34dac0c4f5d, 0x176024b99371f730, 0xcbd16f32d8d1ee4e, 0x92f6a6dce381b78b, + 0x2994445875ca9fdd, 0xef229c3bbb957d90, 0x6c2fefee97be83bb, 0x94cbf732af8ec02c, + 0xe76b971d703eb96b, 0x028e42dbf878b9af, 0xee8ff81409b8a3f7, 0xcaa7c608474c5eec, + 0xe0b25f40f8a95229, 0x614d19e395026404, 0xec773dc21daedc04, 0xba48556baae16388, + 0xb0ce57fe2cb3ae70, 0x0c8cd6c46311b484, 0xf025be0fa84e32b2, 0x414956b10d5e09ef, + 0xf82a175185950ed5, 0x79c5cc3172524a1b, 0xec6b599ca612d0ca, 0xde6357473c0de2f6, + 0xf9beebbbbe2d3fdf, 0x64aa78062ab46940, 0x5c33be60d91f9967, 0xb845f47ddb2316bf, + 0xb5217da519e8873a, 0xcfcdf527beb7eca6, 0x8aea0d207833902c, 0x6b9433ca3d4846f4, + 0x9327d9b9ec453ae3, 0x15f331994a71120e, 0x642f32d572770513, 0x0203ce21279a2e0b, + 0xad60b0e8013517b9, 0xb2a87adfe0c45cfb, 0x40756072bf13f93b, 0x6e450f85f2c49750, + 0x2b9ffa2249d4f7b4, 0xc21e70ee6cfe7cdc, 0xc4cdf0e71771da11, 0xde53c5b5f2f1d0d5, + 0xec95592ba613c23a, 0x0a3a93340fd40fd2, 0x03e043c5965dad7e, 0x520f3dc6b0de8694, + 0x7854f2f16b671c87, 0xa3a56d160ed7a7c4, 0x3cc2bee4e4253063, 0x05e13665813d145a, + 0x5cbc21eb53c63872, 0xd1996590eb467b56, 0x667d874b931576b8, 0x1984f1d7dc4d3c12, + 0x80437fd648b16226, 0x516e2eabf31072a9, 0x18951837e2ececd3, 0x3ed1d4a7655326ec, + 0xa5ffe40a6eeea354, 0x5278c3ef75049337, 0xbfdd81c8724948a9, 0x7344b3e9d3fa3840, + 0x332dd7b2a4a06034, 0xbf17ba5e598b60b2, 0x3ed2fba7555b396b, 0x33cfcfc6aa117e45, + 0xef626c2d01ee8ee8, 0x68b83a99d704fff1, 0x14f6a8d183259d84, 0xb0649083cfee42ba, + 0x807e1e81bf7d8906, 0x08ecd1a92907c8a8, 0x30d86f55f18f616c, 0xe5ae9f6604194f19, + 0x2c914dfefed7e32d, 0x0fa9d846863debaf, 0x39d365fefa1b8b66, 0xa6914e2c30fb0836, + 0x209587c1cf285735, 0xbbee81efa7db82f0, 0x69a929a9e03a27b8, 0xe241c119084692c8, + 0x1574d62a36ffa72b, 0xef7a234af30365b5, 0x6e59903b6770870f, 0x574f6a8d9cd025bf, + 0xac12d512d7d9ff83, 0x006226cb3dffb9e8, 0xd10c2e70ed6ca633, 0xaa5611e494a62bb1, + 0x9492e5a3bb91b4a3, 0xa44a1ebd6db1e7d1, 0x6c5b301b349f2e70, 0x86f528c119ff640e, + 0x9379d7e604a6ad12, 0x938cc67f226490f8, 0x01584f8b9159f464, 0x7ab1109eca29cbad, + 0xd1706cb4e50f5b30, 0xa988fcd75bf08f81, 0x80e21af3fcd319b6, 0xdf3c99cb38ae85a6, + 0x106e46ea26b2af54, 0xd25ee32804558f2b, 0xf704bb889cc52e2a, 0x3491b586132b43e3, + 0xe77d908cbc7c89b8, 0x84af26310189048e, 0x9a7165cb6dc883cb, 0x32ac4686c2ac8c6b, + 0x5892839049867c93, 0x185c641dd0102644, 0x80eb59bff6a6c331, 0x0b3c36cf208300d4, + 0xaba0e097a84ecf7b, 0x923f67b087a3c7fe, 0x5995275d3f9dd738, 0x6645c750f4e9f133, + 0xa6a1153815a5dd5f, 0x5d0f9d846a22ca90, 0xfa2bf820de16d38c, 0xdbbd9197ba5309ba, + 0xdfcc51025a2d276a, 0x530d57ac25fbba69, 0xaec92d21327fe30d, 0xbb26b8f6104c6cda, + 0x7b84db2f4d11080f, 0x91883dfb2b54f6ce, 0xbcfa679eb41e1283, 0x7d28333d0034eda4, + 0x11a11b199e55f7cf, 0x970b1c214263e484, 0x39429b421720e3fb, 0xe5d96148e49ee1f3, + 0xd93793be95952616, 0x4d46320649ca0b61, 0x6c6584154d389519, 0xf08b76215515c640, + 0xd64c6f09daf94797, 0x569a38a30dbc9e84, 0x25f46e5d05c5cc83, 0xdbdca940dff6f7d7, + 0x1b8b9f31a6ab1bff, 0xd1d20541294d79bb, 0x0f7da73684c7670b, 0x060cf94a531c6950, + 0x0eb236e888ff6736, 0xc1fcd2670521444b, 0x9beffbb82a6c0633, 0x942e4a635209a344, + 0xb41801e938d0e3d0, 0xbba1b57b7713ca01, 0x25e4b7f3254dbaa3, 0xfc6c59cf5aa6c333, + 0x3127ea1f0afab63c, 0x871d4110ec405664, 0x4569d1bfa03bb9f3, 0x684e0a74d3e0f549, + 0x4608b001ed038410, 0xb2e439be2cd9999c, 0x2337a130dfca21fa, 0x574693f758abd7f6, + 0x8c2d5088df328d29, 0x572f502e601ae05d, 0xea311cd257f8b927, 0x9a2077d5c467c672, + 0x0f1b6f7d49fc02c1, 0x2f0b65736d65933b, 0xbc4996a7cfb754aa, 0x62b82199852c60bd, + 0x9c83f741ae6d713e, 0xfe1cbb2ae64926ac, 0x33711ae6b37a7d12, 0x8c393abee1eed3ad, + 0x0aca6314bef5c746, 0x08ddd91c7eaec4ee, 0x9e6e7abfef89d093, 0x2819563e93a2e4a2, + 0x4cb6022e20ce8e94, 0x1f68f6118b452015, 0x6fe26e1acff61b26, 0x2f00da434955a6ac, + 0x712996f9cd092af8, 0xe240e77a22c5fe28, 0x1fdffb13efd96691, 0x327cb474fc6f86d6, + 0xd4c5730b252f3a33, 0xb317defe5f317a0e, 0x32e25b790a02614f, 0x6a15f06d83a0a1fb, + 0x370b50ff7b77544d, 0x1bf51ea13caaf4f4, 0xa0af8a70e7766e63, 0x0eb0600db8074253, + 0x06281d0a011a79ec, 0x377343894b28db90, 0xb824ceed9d1d3a5d, 0x12b775513f0f66bb, + 0x55d995174e9db042, 0x076f8b1535892daa, 0x721e532252888002, 0x3cd0f01ae6ae5a5f, + 0xff1abf2b85715f68, 0xc481d98ca5b44a3e, 0xabcf5b6d811cc8ca, 0x3deb89d5eaf5f0d1, + 0xf2cdbe0a72a36963, 0x41a189669dd26a66, 0xbb21393d190cbf21, 0x0b8ae3e152ef160a, + 0xf9b3fb205bc60642, 0x97d961a7fcc17019, 0xcc3bd568e2d33583, 0x3f60b2ea2c4a503c, + 0x9fa174fe0f7afc9a, 0xb4efe92d511eb893, 0xa119057aeae74caf, 0xeca9f5f791eef516, + 0x98575edba7c69d1d, 0x195bd0e47e4e36b5, 0x8c23a24d071ee445, 0x70d2d956d0dd835e, + 0x376811b131acfe91, 0x4c79c5fdbbfd0cfb, 0x99fc3d6eb750d007, 0xeba8b3be5f576336, + 0x477e4e59f4fdc9fd, 0x13885032cd58535f, 0xc1b55d3355638eb8, 0x3d2f615f169d3f6a, + 0x843c29f5b6e7535f, 0x512aa178fa51439f, 0xd65dd85db34c0471, 0x6e42d2875d831f3d, + 0x2a8a7955e2b383cb, 0x1001632aca64cd88, 0x34f0d6c7cde3a74e, 0xe33a9ebf866d3399, + 0x29dd439e559298f0, 0x10ce1d7517cc1906, 0xafdea236b8b85bb8, 0x85c0816a13162151, + 0xaaed4331796c682a, 0xe2c8a792ba1e85f4, 0x0366dac07e900e96, 0x5ea6bba0b16c60ea, + 0x3c940f47c0009c22, 0xe1df5ad747f268ab, 0x3cde1e9e8059b1cf, 0x8cb9fc001026e3a3, + 0xe7ae2474d38d316d, 0x82cd58cf7538d495, 0x7dd8a28255163980, 0xd674bd6d9180b886, + 0x034febe527a380fb, 0x34ddc6f42ed7a281, 0xfe26713067c8fc70, 0x374e84b39b68aa65, + 0xf4c3b526011e7357, 0xd2ce72a2106e6c2a, 0xf3054cc94450378c, 0x37e6d57fe0533fdc, + 0x58648d4cf9a256d4, 0xd29a11fca3e174df, 0x36d8649aacde7f9b, 0x94e19f77059063b6, + 0xe5e89b51b00cf9cb, 0x2c751e818855bd7f, 0x0f89e2c826828dc3, 0x7e891fc8e17d9c8a, + 0x3628bc962ddf6430, 0xdb45c304f8da75f3, 0xf7741893d30ae47a, 0xb291fc7dde5f1ec6, + 0xe7fca007afc3cc31, 0xc70bd6ad2123fe11, 0xbe67528ea9794cf7, 0xcdd223f2d2f19621, + 0x2904b24f15703c2e, 0xccc5ee9f45b57712, 0x227d0b633a9b19fa, 0x35843a8569d46491, + 0x020dc9bb26460c21, 0x238403a590796adb, 0x31f0e12c0eb5dbcb, 0xa38a3d0d861dfebb, + 0xde2fbad1f785501b, 0xee2b30c4f324138b, 0x98ab99d5bfdd9c69, 0x861e82db61d94095, + 0xf01365b57887050c, 0x4035ec826c3acf86, 0xa8e0670e3c42f052, 0x3ac90ee28f7a13e3, + 0x6e6851a2e9928cf0, 0x975aa980363ed943, 0x5d5e5a01730bd6a2, 0x7750c0c7bceb983a, + 0xfa45b7f12b26fa8a, 0x498c63f2ac2b04ff, 0x605601a3321dce10, 0x9bee862b986227b6, + 0xf861fbbadbdb630e, 0x7083e40ce4db97f5, 0xdb681adc2d8a7c15, 0xf681a91cdc681b1e, + 0x268fcfa3224d3daa, 0xb4f63c71b72b254f, 0x540d8a4953be95f1, 0xf9e98bf8957993c5, + 0xde4c584383ce966a, 0xdab33cf5146eed4d, 0xae8160cd7430f54c, 0x7e25be30091b190a, + 0x0eeaba5b899bf74c, 0xe4ec82d56334aca7, 0xa578b137c276bfc1, 0x37b2443f3ee0d387, + 0x6201d379be970090, 0x1e60191c8936e4a8, 0xc479e792f67028fd, 0xffc2702a1ec11028, + 0xc01d455992035e85, 0x87d6a3ade7518b6c, 0xc2d3946ec8e21795, 0xe2e4f33c9237cdce, + 0xf59edb1c6442e9b6, 0x58011d6932fc3128, 0xcfa7495bf1747a29, 0x13c8fdb961187b6a, + 0x39d457d928d21f0b, 0x10122608436b48e3, 0x279eddc8503cc1e6, 0x223d709a37ff2861, + 0x8aa47d71f3e49b7f, 0x849c6a677aa4629f, 0x13073ad393e934aa, 0xf988c87ef3ae715b, + 0x82a1ead4d546ab53, 0x84ca560e15e3405d, 0x6a1e83d44e2a2177, 0x5c374cf6d186c23c, + 0xf38e63022563c0db, 0xd9a7bdaea181fa42, 0x1a2e8604ee7cf6ab, 0xbdc7682cb0ebacfa, + 0x45d3f679ccd1894c, 0x0ac2b829ecfc8c60, 0xc2da590f8f0bbf89, 0xc02cf0f17df04fdc, + 0xd32e8bcce7d404d6, 0xd597346447734f5e, 0x8aec16b04d7de9a8, 0xcf22898783c9797b, + 0x04622ce05bc21853, 0x14b3227ba08a7f94, 0xe92db65a356b90a2, 0x73f2030e32461d18, + 0xe4289c18c25e81f4, 0x8e87c9460626edc8, 0x76af04ef0d37c672, 0xfe4ac3f909004738, + 0x17b6adabb26ba928, 0x34cacba2184a050e, 0x59c0d373d5e2f155, 0x43cb03e0bee6e56c, + 0x014a3d4d03442912, 0x4d64cd9f1dd31262, 0x0e3dd0eda3befe30, 0x379341cdfe314be9, + 0x007672a61fc9f3d0, 0x106aec40b8f0b706, 0x72932430dbeccfba, 0x44329422fd5250c7, + 0xc13d9de94066c03e, 0x9606343f6e8fbb39, 0xad0b36a2023b7e9a, 0xd392718f636e3916, + 0xffa661d8473ed057, 0x8e89a93b64866159, 0xe0ac5d9ef1b35489, 0x9a8e5c77f8e23fdc, + 0x0d69d9d700830b4f, 0x9d4de4d3b2893214, 0x421d36b2b977f44a, 0x08441ddfadf7c82b, + 0x73d5e36d031aa64a, 0x0178ea238f4a668d, 0x41086efcd137c9e0, 0x93815bfa246fa7d8, + 0x2c2c7af010e8e8ac, 0x69aa1ecae6702468, 0x86c7df8792f2a816, 0xf9eaf333564db1fc, + 0xaed38689b13d44f9, 0xed31bea13b137101, 0x86c8b2dc72877b7a, 0xdd1ce9c96c69de43, + 0xfccd5d96c27bcf4c, 0x140142a084740d51, 0xead5b31a3bcffff1, 0x3d33179449fd804b, + 0xb72eda6c6a0f089f, 0xaa28cbfb5bfb4675, 0xfc6e4863dc890a0d, 0x2de3edc7d578e5ed, + 0x27b2c659e7a9753f, 0x32a3d8117b48cd4f, 0xca503b515b39f4a0, 0xa677b99f25bc8e20, + 0x451fd81f76994ae0, 0xf3e3a4740bc75b71, 0x80f74b3b5a91f164, 0x7564d53caba94fca, + 0x1bcb503482da6d94, 0xade40b59f1a695c3, 0xd505ab145c91c673, 0x732293f3a00e0f9a, + 0x9b63c01737b24402, 0xaf081eada0ae6d72, 0xd87a89d52c0039df, 0x6adea921fd87a5d0, + 0x92024529e22929d5, 0x89f394700e0310ec, 0xe49a26d982be56b5, 0x61462514a0de0983, + 0xaba899b577b13826, 0xb6804c2d5ca7934e, 0xa07250312b8e0ff6, 0xda96a95d7b3192d5, + 0x3a19d74fbba1a8c1, 0x97a8361c6ade2a61, 0x84b8958e3c77c548, 0x145de3835d14ea35, + 0x22c98fb2c9f41283, 0x638b9625dc156b46, 0x7bef5679d95ad5b4, 0x9e7181a9d72bee1c, + 0x8e3ec5543ab38848, 0xc1715b1b79de41ef, 0x928e894f6770bac1, 0x4b42c5ba57efc7a3, + 0xb9b37daaedd851c6, 0x522d8e3cf65bea04, 0x0d607f65046c1dd8, 0x91950e1c6339cf74, + 0x4ad019797988807f, 0x9a7aeb1551ac64e0, 0x0564d9ec1415e3e1, 0xe74ba9d93c061c1f, + 0x7ce84a7a41eae055, 0x6d4427bfb4f8d6d5, 0xb48105e0cc573a10, 0xc6af6eed024f5e31, + 0xa8c5202618b757a6, 0xcd1dcf8ed7a562cb, 0x9deca935e9bde00d, 0xba1ff4ac95319622, + 0x004373b8a9c3d68d, 0x63c375ae1c9c995b, 0xf30181926ff19e0c, 0x2818354995394ffe, + 0x34834b4b7ed87b64, 0x15e6d05b73e8987e, 0xd2d2323012f37e27, 0x97e9784f4a1e637a, + 0x77ddecd7b4c6470b, 0x27128f0f10179469, 0x2c6cd115d0eba682, 0xd88a0dc9eac90b9b, + 0x4a6d39b8eb620c5e, 0x66f330eadcb921e3, 0x78bf4bd0aa46fd47, 0x6df84089fabdf014, + 0x2a4ab3428a29eed3, 0x525e0c856c41d5ca, 0x1230c714f17a1519, 0x227e27cb5adb4d15, + 0x2eae0a7c7d0302f5, 0x20e2baf1f2326dcb, 0xe5c9ba92458428e2, 0x23827844e6abc7a0, + 0x8fe92f51c3f08cad, 0x04cc291799d15b4c, 0xd769387e1b0938c9, 0x4d92581bdf1c882f, + 0x51bc6114de8f52bf, 0xccf7264fb4fc324a, 0x71604a70ca496270, 0x0b1d85fd198ab5f2, + 0xe5f7c7fd349598f6, 0xf6f1af235d3d170c, 0x411196355f4cb176, 0x062554f27247fb62, + 0xc2a3d2456635d561, 0x3f5549e9ff5c4361, 0xeab782b5e0676c0d, 0x6d75fcfd8c41e5da, + 0x01d22662b2f10946, 0x8dd5609142f058ad, 0x1e4a47028b57429d, 0xdad68252963b2aeb, + 0x5cd07b22bebc724f, 0x301255351476849b, 0x65426039acc55345, 0xc59177fee81f42da, + 0x6106d885bab39822, 0x34ecfa3eec4ee67d, 0xb2ddf76cf67b12bb, 0x7b8390c344454a64, + 0x1073f8c4519fb963, 0x44f8ab2aa3bf3c98, 0xa5f68ec3e120a9b3, 0x3b10cf522e7a1416, + 0x427becea914a8819, 0x5e9983cf1125e4fb, 0x8bda6b21e34d02e7, 0x307192a1daf91a02, + 0x02c86eabb4a1e657, 0x7820ae0495e1f2e9, 0x2b1ee5aef70e365e, 0x717a5ae0d24ccdc3, + 0x44152db6e842cce6, 0x15f0bfd53b68e078, 0x788c4704f9ae91e2, 0xa434ca03f8f80e34, + 0xa8513ce54077b73b, 0x64c986673b9f6def, 0x3599d1f40408508d, 0x830b26b446b88edc, + 0xfc0c6a59fa4dffa5, 0x6fc9e4da6c59de2b, 0xf9cb100ee5572428, 0xccb6e919f73d3e60, + 0x214675187f1cdc33, 0x8b2088fdc031b4ad, 0xd970b242ade60aec, 0x27937b85df7ae47d, + 0x4b6bc7390dd61eea, 0xf50abb734c7e120e, 0x62bb9d4e2efd2b17, 0x8b0d31da97003fb9, + 0xcebfa2bd08acb9c2, 0xa384915e1df256be, 0x0ec9923e8f5ea745, 0x88db66154bdc7917, + 0xb0e856350c814d61, 0x0c1b08a79b522253, 0x037dc23e7dfdea72, 0xb3164158bb21f80d, + 0x0d2d68cba4327b17, 0x742339e8ff2afb3a, 0x6fd375e66e7ba375, 0xe51519a74635669e, + 0x10cb4d17902183ec, 0xbc778da751d2ca1e, 0x0184561788aa47e4, 0x0fffd9ce36b9f404, + 0xa8271a86165723ac, 0x7d58fbf0be388247, 0x26cff02050246451, 0xe2af042d5ac04a20, + 0x54702026939b8f57, 0x77762534a707f66a, 0x926ff890faa6c516, 0xbdfa778f70aa6f24, + 0xe2fe916086a67b33, 0x3e853cd57987fb5c, 0xe20952cd639ed00a, 0x089fbbad7a113eee, + 0xa40a6144b74c535f, 0x6d1b2ff4a72f2edb, 0x63c4273bbbe83cae, 0x522fae25174940ad, + 0xa558168481abde13, 0xf3e923fdf1b1ca34, 0x99705c81b4b80f03, 0x3ac195454c5828a2, + 0xe95a16217036bc11, 0x5134c11249d2c523, 0xf85a2bb87a0ce21f, 0xcca1e989a4c02765, + 0x86c84b987f500f35, 0xc9feffe228f31bb2, 0x77fb1f0b04eb2412, 0x0af90b7cabc65ee4, + 0xd8838f199adb99b3, 0xdcb238c85754b528, 0xd6d940edf6b0c1d3, 0xf656c851eb975350, + 0x3934fb243828a416, 0xa0d3d390ef837e39, 0x55581690e72c86f5, 0x05d914bd4d69ac37, + 0x53bdfaa2b9a62dc3, 0xe851027c34c08a98, 0x8d4229ff81662c6c, 0x54102d1cf4d40ed7, + 0xf17cd34ac6a8b9c1, 0x0876b3c5cdeb7810, 0x9d9bb512170fc7bd, 0xbb31b0417798a847, + 0xd053d6934cc7e2dd, 0xe02cd0b547f57066, 0xda387485f755e14d, 0xd2bde4818b881fdd, + 0x671affc79b6d0250, 0x8b3cb113006f3855, 0xb341c55a23424b0d, 0xbae2022f91afb021, + 0xff91b3fa9fabe199, 0x4e7c062f25283a4f, 0xe44b1538c68184be, 0x4861571f83399798, + 0x319ee1f3ab051cfa, 0xa0f6111ff699a869, 0x233f85463bf1a5e6, 0x4514e911b249798c, + 0x02c9fb3a13794ce3, 0x2eb4d867ea61a127, 0x938a8260beece405, 0x4415470c32a9a19a, + 0x82d46f8959bbf2dc, 0x13265156a5c6101b, 0x9b779587cdeb1ad5, 0x82e740a33d712be0, + 0x271a2a557506ce79, 0xa6766e26cebe6fa3, 0xeda1cd2229de2528, 0x8ed13b11362a4b0c, + 0x5d78aeb1a576ba58, 0x3df1201fc36a4c4a, 0x30d4c24dd02b085d, 0xcb443eaac77ff647, + 0xd6db42d013c48f1a, 0x9e91c7805e80114f, 0x92acd998e05e17cf, 0xf8dbd74f0d426206, + 0xd698890aefc0d121, 0x457907dd93481c05, 0x9e1a93f457bdeb19, 0xd10c479517574c62, + 0x7cc4d0d71a7c535b, 0xa5ed5a0248704d94, 0xce9b6319482a8d22, 0x4835fcdd95ef556a, + 0x1d9a40999e218b59, 0x867c1c02370fe465, 0xb4e5172286fcfa53, 0xb480b78ff0453c47, + 0xce1b9e334908ac46, 0xcf350dc973c5a833, 0x160da9bc5c80aaf4, 0x74caaa8fa2d99fb7, + 0xba8ba8bd5a7aeeec, 0x3e596e838f918187, 0x7d7aaee18267d453, 0x02bac5efec7edc1f, + 0x8b9bf297183c4b3d, 0x8f6bfc78a9f6c5c9, 0x01beaad60d780fc6, 0xa57d153b0dc6393b, + 0x9dc8083875eb49a8, 0x26400eb8b7eaeaa7, 0x01f5abf61cd369c4, 0x11ea5e244dce5053, + 0x26d3443f4fb33168, 0x34a16af07ecd23e1, 0x66761400ab1611f7, 0x2dc645b91bfd522a, + 0x933b1308b15df495, 0x5e90df16d37d7b5c, 0xe36466ab0fc587c1, 0x03f00421184591d1, + 0x4f158b2535b4748f, 0x4b9f578a8c3b78c1, 0x221e0bc705e4e1b6, 0x219cd523e09a9a8b, + 0x0759052be84a1d4c, 0x3f069d517a0e1bc7, 0x2cfe71531e3c7164, 0x165683905990b275, + 0x4a8884ef69f7163c, 0x158fc4744d2304ab, 0x4f756446b8bfb18b, 0x23e3ef0e2beabe6e, + 0x3e5a721ee1e78572, 0x57a0292e73c84428, 0xbc1be1d5001b793b, 0x4a42ca150853cf0a, + 0x094b5fad18671f8b, 0x9151e6247a85e7fd, 0x15041b5c4d970ee2, 0xd53e821cdee9659f, + 0xe61a3ad2adce5555, 0x6e3113dbf809c9ed, 0x80c819cff8d67d01, 0x66f44c6001defd15, + 0x5ac5a8060b13147f, 0xb58d5398b2864652, 0x8fa928b55875178b, 0xd70f80e5508e85ce, + 0x61e2a0810e4964c8, 0xbb2a4e4bc898e759, 0xb84f2e399bc91a9c, 0xf69da9212176a42f, + 0x800afc6aea93b421, 0x9a0cf748400666f8, 0x947748aa5dde387b, 0x55dceacbae68b51d, + 0xfc4f77fd4f549dd8, 0xbb3597b6b777b331, 0xe31fa57535ba0029, 0x6857c665c89a8d06, + 0xf0150f11feef9170, 0x54b42cb9f07e9276, 0x554df4b53a8cb80e, 0x5750dfc7e428f69a, + 0xc297da095fb40b12, 0x15f7cba9c40dea51, 0x52daeedbf036d123, 0x7b84b56fe6097026, + 0x758512826cc8170c, 0x0dfef0c2d9ac150a, 0x2ddbc1d22a157e5e, 0x7c44d77c4fbe999c, + 0x203e9bd9d5c7172f, 0xa3e39aea24d10dd7, 0xaa66abd16c28ed27, 0x40c62461b35bfdec, + 0x29f51d4c4771a668, 0xf8e9b464c1e88f21, 0xf20f7eb7a51894f2, 0x64a8105cc60a0270, + 0xaadbc86039a9a57a, 0xaf3bac98253c1634, 0xac34a6837f41c394, 0x89368860afde70f3, + 0xc680e452edd995c6, 0x14af5144e7e90a6b, 0x3faec54444bb24ee, 0x3e996fc07138593d, + 0x111401694f223132, 0xc328ee018fef0d0b, 0x67a34c1e66db2838, 0x090636d317f38f7f, + 0xbdd43f561114f409, 0x16992724d4e4c63c, 0x0b6d9736e40f08e2, 0xbeb2b8657da7bd2f, + 0x727ddac4999e08f6, 0x0a6f63bbe834abb9, 0xd9816000f5cf3e08, 0xbccdb57930d6d43c, + 0xcfcd975a99327801, 0x87c9a3f4080ffbfb, 0xd36edffaf3bb9e13, 0xf7cff74b58aea5fe, + 0x6b628e2947c14fba, 0x0aec5255c50c7246, 0xc63cd582a038af10, 0x567a466f64645ec8, + 0x17e59a5735c2886b, 0xe4c09a576abaa561, 0xb29c2c3628aa811b, 0x7491d8b4efe015b6, + 0x87ea356bfef10bc3, 0x685fe0cef59576de, 0xa2e3a56d313a52aa, 0xf0377ca878562272, + 0x36c8e2720f8ecb0e, 0x2d590839618b95c0, 0x0e737b5c1b2a5590, 0xaab90d1d39a153c4, + 0xb3a009eda483f5f2, 0x8c33138f36da932a, 0xf8f9ae975dfc6c33, 0x24ee96046fcbb061, + 0xf115d2e091b5a157, 0xa79621534581baab, 0xac4f1c4a7dd3cc5b, 0x5de3eba570a70f97, + 0xda34ce7a78fb6c6c, 0x319dd6c86eb679d6, 0xd944e4e7f16a0980, 0x066b9bcd51b4ad58, + 0x4f015dd14514d799, 0xf7ce1613739ef86c, 0x9eac9075b26ea209, 0x19525f3c11e83ea8, + 0x80b9ec4d3f48ddad, 0x414834b8d74ea823, 0x4468d596ea2dc92d, 0x5e6154c3bb4ba040, + 0xc6615f2b6d6cd575, 0x39b6cbd0ad1a41d9, 0xdb8b6735ed4f63a8, 0xfc74b12b37856fa2, + 0x1ce7a2da5e023bd8, 0xc898964861a0bdb9, 0x1a7def3a52e5fd73, 0x71fd5a09c22b352b, + 0xe29e055d7f878a31, 0x7ee4eae05a5f980c, 0xbc3e4c0cb2e3f896, 0x0e200f5126faf587, + 0x443fd23624783cf3, 0x0d063daae8925bf4, 0x6d9636600f24dc79, 0xba9c51c1b2a1fd6a, + 0x4eaa624b142afe91, 0xa5db5bb7d79cce4a, 0x3a0821d63c40145d, 0x5efa9404a833c594, + 0xa31a689829413c2b, 0xa93210a99aec8bbc, 0xa41ac15944fd678d, 0x97ba4792f50c837b, + 0x678d22b1384d62d5, 0xab11d38cdc067abd, 0xad088f07c162f370, 0x7ab8923503ace33b, + 0x2a171e096a38c16d, 0xe8e4a918b15425bd, 0x023c10a5625c4c72, 0xf56fc8b9a10d2db0, + 0xde556046861f9d65, 0xb0b6ed784f3f25e2, 0x6e9f9f870fc2ed01, 0x7d98a862bb85e6f0, + 0xdf99dd1ff243df98, 0x5bb5494fcaa4f974, 0x06e97960aa88cb5c, 0x9605364b565f3991, + 0x26db4b055418b2b7, 0x5971bb605ca05b97, 0x5efa9b46c5ec8251, 0xcc19263a40c1108c, + 0xd4e051f82679c884, 0x3860e39c2e6ac099, 0x9f7777398b80fa4b, 0x6e509970a9515259, + 0x8cb8f54e7c58feb9, 0x2f441c50ccd87797, 0x4bad1116649bb530, 0xb6e24c757ee4bcc8, + 0x4be79a48d73da723, 0x049663f4e352740f, 0x5a5b8d8aeb2c3879, 0xa13d7469c70e1615, + 0x5d6ff6c2f018648a, 0x4943109c3f64c7e9, 0xab4a80d4c3a8b0bd, 0x459c668c442712da, + 0x8437b69fe40211ac, 0xda0a84df90132140, 0x9e57ed870cf80610, 0x403cf5adbbe5e824, + 0xb6b574995d7fb601, 0x5178bbef3a757156, 0x148bb00a8400075a, 0x3545cf79b132b0a0, + 0x64b4148cd26eb507, 0xc9fc8b60a10d777a, 0x50d80f1f766c5233, 0x8667e5cdd176df0c, + 0xd30309cee4029ce8, 0x24181059a5d75cf9, 0x6576c840210ab758, 0x3224708589d629c6, + 0xcab6bdb24cbea116, 0x3d677bc0729ef9d0, 0x4effc3b80a7e1770, 0x47fb10ee069ef07d, + 0x7f45a58e0468db01, 0xf26a4c91b3a2011f, 0x9c6a00ecc0a7f1d6, 0xda5d4ea072670069, + 0x8ded69b02d321d06, 0x088614fa8e2fcaea, 0xea6adf01b088397d, 0x50099289e503f404, + 0x9cc533462cbd80d1, 0xd2fb1b6524744887, 0x80fea62ed1f5b2f0, 0x619e0ed78125c15a, + 0xf55ac124084da683, 0x762b33239912a421, 0xf2ead76786439989, 0xb2c63fc0eb8b30cb, + 0xd49cf9f4340b76d3, 0xe3d1be168cc36501, 0x1ddabdee490d1807, 0xd649a0f02c664423, + 0x9565d202b62a2a5b, 0xde4a04c44345253f, 0xff70f3d535ad3ca9, 0x4dcfc9b6f4ddba82, + 0x774208266218206c, 0xde0f1ba36a563024, 0x253acffbe28412b0, 0x06a57b105e037b5e, + 0x0cabf140bdd8644d, 0xd475f9a1e64b3a92, 0x0c0acfe2331d4791, 0x52329e48414ba1c1, + 0x3330392197428a21, 0x817403d59e66a296, 0x7083f346a60ff453, 0x563c187652fb58d6, + 0x997c955b860a49cb, 0xa9a1941d98ea6fde, 0x22199aa5b91baf9e, 0x7ea55f084898f7e1, + 0x97c8bf18c327632c, 0xbb951e749c739167, 0xf12d07eb0283c0fa, 0x9a31212bca52f1bb, + 0xda40bd6437eff8d4, 0x605cd0f796beef2b, 0xbbf20eea41a8396f, 0xadac5b64e2d576e7, + 0x571415862dafa633, 0x1b49edcde2a69ebb, 0xf479d41db5eec567, 0xcd62655e63e2f313, + 0xc95c7c7f38807d44, 0x474ff1962b9e4d92, 0x3d38a5cc25213298, 0x86d820f9c5ccd5b2, + 0x3d7fe6f707780d46, 0x7d2c7236d42eb4bd, 0xf3e65af361c855c3, 0x384b7c1909d042e5, + 0x39d5bfdaf5fcfbfe, 0x0172c1b2fbde2741, 0x870c648e0646e842, 0xa700ab1c5503153c, + 0xca2b419b67da219e, 0x84321b37bc28019c, 0xd59db5ef6c6e1c17, 0xc56b270761566fbf, + 0xa90ae4edc70691d3, 0x8d9dfc844f229916, 0xb73c1ed7a2e78281, 0x1cccd9dae4301c2b, + 0x2504359d4f43a45e, 0xfb15354948dd428c, 0xcafb1d2d26f841ca, 0x7db6ae3004e03831, + 0x53db786afd441801, 0x64f3bbf8c2772923, 0x633310c3703a8bd8, 0xc03bb1b54a4d2fd9, + 0xaa2fc3ccce88e7a4, 0x796500b980c2e181, 0x5d66ebe2c5894bad, 0x9fc140ffe8c020df, + 0x23439d0846ba2e74, 0x429cc47a7fe95d8d, 0xbbb605e08beed417, 0x2886d5d8d097dbc2, + 0xe309bf460fc67287, 0x438063b5c13405bc, 0xf188858454709159, 0x3faff66aa8c39b3a, + 0x60c0dc6b6072715f, 0x683eb5c6685d6432, 0x9d5cedb2319ffdd9, 0x585460f7144f3ade, + 0xd1f3b140b125a1d4, 0xeaf5984d10714b78, 0xcf33a8b448f55423, 0x2dbdbc69445010b9, + 0xf0d249b5ffd3cd80, 0x7f21ae4611c4fbdd, 0xd91f1b15d21fb0d3, 0x1a2edbb9e26b41c4, + 0x6a4098c7009ee660, 0xe18ebda4967b923d, 0xe9de10473a3b4d0e, 0x8037c0346e3f265a, + 0x037f8025bed4239d, 0x4373d6150a43388b, 0xdbfcb1d5c757babc, 0x3f1e27fea50a587d, + 0x90d02e1ca2086498, 0x9b65af99df610917, 0x9f441e6d3bcd7cd2, 0x9016a22081462046, + 0xff1bf7cf7f86142a, 0x04a9f693a634ea4c, 0xa84dfbe7d777831f, 0x3a4d218995e1bb77, + 0xf2db40ace1aa604f, 0x42d934de2e01dead, 0x0c30543725afbc82, 0x7efd1e3f2c9c4d72, + 0xffc0f1cab1dfad3a, 0x8f6d224f1c97f995, 0xff659d3c41135121, 0x83767ab5d2b8a44b, + 0x034580d612ab51db, 0xd9b15e604f94c335, 0x583447d1c315d377, 0xce16b25d25d64750, + 0x4b3e599a181db28c, 0xad3bcc61707a1e54, 0x2304aff5e0e1312c, 0x2775dca215bd4649, + 0xa1df72a526105430, 0x8d8c3abac369df24, 0xe0307819b752455d, 0xd66dcaf92ed7e80a, + 0x40957e2b9d8ab1eb, 0xc3ee067d572c1eb8, 0x98949be7038f4312, 0x1e44dac9cefc0a3e, + 0x6790661b469d1e2b, 0xbfeedea8cc2c4156, 0xb1e37698943c97d6, 0x7a9904c8ba563d5d, + 0x4a518a7e6f8b50ca, 0xa69e67019af3149b, 0x092459dc16374acd, 0x5d3b1fff2da6bd7d, + 0x74c841f4443a18db, 0x9bf8b6ee19dd1ee8, 0xa3d9ffc7a1c69b73, 0x8e7a2c7089077647, + 0x85fe44aca6e3cbb3, 0x3c2296d490990de8, 0x8c4ece1c07040dab, 0x7dd19ab8a9baf65a, + 0x232bb32d97595076, 0x90bf58b35d1abfc0, 0x72d0b2907af66b91, 0xc7fa661133f2a951, + 0x6cf30ef3657e7042, 0x508ad0f6160b767f, 0xb19cb4d4e6abfd12, 0x07e9cdc0317565f5, + 0x20d8c1c51f5ef8df, 0xb990b0a1c734ee59, 0xb14410502b26f576, 0x36bb1fd751cfed83, + 0xafbee0f3cfb81fa6, 0x7f69e91a15af53ef, 0x6e78f569b4bb69df, 0x6a70b4b07d88e898, + 0xe95b7e6d6b4eb64f, 0xcbed9d5d310dd85c, 0xbb6dece954c9887c, 0x6288bb12a18f10a6, + 0x98f871c69dd90ab8, 0x1527fb57661aaa3d, 0x9d6b73833146c0d6, 0x0e0e0ac0e377c037, + 0x23d629997ec20f4c, 0x8a742719a656c90f, 0x945cab17ddc141d9, 0xf9cbdfa93c170c50, + 0x9a3403c0e0dd72be, 0x06564cf2e1eca6cd, 0x359d5c3d173da384, 0x7c7a06ae74ab9168, + 0xdad0da229f4faaf0, 0x5f72912b71ac4412, 0x9b8426fd80942e4d, 0xbb6ae1d0a01a2f23, + 0xbe24dd2c41c93254, 0x2e57c1483c75be6e, 0xd2c14fbcd6d21341, 0xc88522e46072ed0a, + 0x8fdaa0991de52916, 0x3dee502b1d002399, 0x74c92cd78ec2c5c0, 0x1661eea3a1b186a5, + 0xc84484d2af19befe, 0x0da060548459bf37, 0xe8b22929416bff3e, 0x0ca0e69218277d58, + 0xfaddd54a08828880, 0xbef6c3256e22f537, 0x0fb0eb69ddf6373f, 0xed8f8b11f2396004, + 0xaab6757a3f66b35c, 0xab8cd32a13a079de, 0x2d325da303d181f5, 0x132a806299c3b9ad, + 0xb58148425cb8398c, 0x0c5801d22e0c67b8, 0xe38d49cb989c5c72, 0xdf415037e862eb11, + 0x5bf664a7203872d6, 0xd72f7d5233759165, 0xb66473fdee2e03c4, 0xfe0f12ae942aa812, + 0xa509d6464f5d25a2, 0x698db37327aee839, 0xc2a1a8b9c9f8e6a8, 0x0742ef7248c88e67, + 0x71891bf81d53c121, 0xc9dfd8b02bd64f57, 0xdce14bdc7d523e47, 0xb0a2792344b192c6, + 0x37b2a9e0a538a493, 0xeddd5c4b3a398c59, 0xdb8646267de3ba13, 0xadc62a4fd9bd339c, + 0x019f20ab87726faf, 0xde4eda70acac27ea, 0xae749ab863b47d6f, 0xa89f9c12da463b46, + 0x234718d959c5d6ae, 0x70d18e4968300128, 0x234e2324ba311a44, 0x160157cd6465b17e, + 0xa2ed85e77d34a81d, 0xe6a1826e6df88f6f, 0x4796738cc89fe26b, 0x57193fab4d47df3d, + 0xc513a1a0c019a30f, 0x9ca46e1dae1b37e2, 0xef7b12ddb8133469, 0x645467cf5ed69ac3, + 0x52e651f4df02b22c, 0xaa14c0549620cb1f, 0x5746a9335322c326, 0x791225455687c137, + 0xeade84f80c4d2ab8, 0x27fd8a9957d484a0, 0x6676fb2094ae84c8, 0x0267241e40e01f18, + 0xcb03582d818b6b85, 0xdfc22a614ff799fe, 0x693a2e4965f135f7, 0xcc6e9ff4574b75cc, + 0x2b076c3e2e0e658c, 0x085b2b881a7bbd1f, 0x30e0a767ceeb5103, 0x3b3aa94c87699d5b, + 0x30a233ce24e700b0, 0x0e4aa886a3fd6a3f, 0xd1d49fcd5a47fafc, 0xf90b19cd50bb9d0e, + 0xdafb3f2fc61ef2fb, 0xc0929c6d15a1e08a, 0x94ad75c2083ceb6f, 0x1dae43bfd7f2fa0c, + 0x740f3b6b9b5b0fbe, 0x2b40125473d372c1, 0xb5805dd230472b06, 0xd99dc4543a1d1e5c, + 0x099c140c76414939, 0x9dcb1f41209b25be, 0x0dcc487ef6842dba, 0x7def1d2646c52fd9, + 0x4bf44b76e1bebff8, 0x4326327426494093, 0x9e82e53ccbd50c13, 0x27903b5100c99a18, + 0xcd872a62857615ae, 0xac02f6e09c382b4f, 0x1734f4c56d1d02cb, 0x12753fc13e7f4dc3, + 0x1125ade5cd3a24f4, 0x261e2a08ba325e04, 0x337ef78a1f2c3fd1, 0x734cec0f1e32e47f, + 0x22fd3f5fcb925a5a, 0xadcb9ed05cc7c52a, 0xb30a65a8b625afb0, 0xf6e4daca5c105d88, + 0xc6d4a4ef1609da5b, 0xa4b06b8b2f7fb711, 0x294ef523beb48c65, 0x9ec40e3b213425e7, + 0x5bf5777933a74d0d, 0xdd19749213d2df32, 0xbe3190f2e3dfdc8b, 0xbe5d440a790d549e, + 0xe400eeb0a514f118, 0x5741a6879bbc382a, 0x131b6d4fcff0efb3, 0xbcdda0efe16a2af8, + 0xdb730b01d3d84057, 0x92f8aef243bdd67e, 0x129fc4e2f8c0a46b, 0xcd627daf16e57d8d, + 0x95ae1e3b0a2b0988, 0x4df621ca8e26543b, 0x98b819943a038ec3, 0x8da8c26bcb8c607c, + 0x81f5b5fb1767a8af, 0x18cf7652ad0f427e, 0x0824cdaf3721a7c9, 0xfadfa49c9bcb2da1, + 0xe88da2ecce4e5b68, 0x344a37ca56402fbf, 0xae28ef992e7dda27, 0xe0e43c2c0a68acf7, + 0x77e3c0f16ead0f68, 0xfe46928a1ca6c4e6, 0x0967c29c03112f00, 0xfaad9c730965f95c, + 0xc4b6cfd8fde6779e, 0x13fe3796b6239956, 0xd8db75bf1dd50b66, 0x187f277a478e21c9, + 0xed51a5cae48a9d28, 0x6a023b8a6945c553, 0xc2ac098cd96d2239, 0xf0c1074c1583d547, + 0xabcfdfc3004a31d9, 0x7ab0a047d0f94263, 0x4cce30e83f8b7c8f, 0x663a1c6b4fb6d597, + 0x4592fd187f3c843c, 0x9d12bc038458b1c0, 0x5d7cc4f792abb369, 0x9fecf17e30b05014, + 0x73a2505aef71ba88, 0xb4166e80b87c4009, 0x238d324793ade58a, 0xab5fc59a86fad05c, + 0x66ec07f0a90d1137, 0x27760f95cbe33b8e, 0xaa3c8d12191363aa, 0xede2f52644c3b422, + 0xfcb0f99471ab3aea, 0x2c80b728669279da, 0x39c5b67ab2a3b4ae, 0xb8ee4498a14f6839, + 0x08fa66794a3823ac, 0xc2202052921c0c43, 0x378813abbd8058ef, 0xe0c6563f2978bdb1, + 0x91344f646817d7d8, 0x88ab2bccc0841f4b, 0x8634d29394de4e7b, 0xd8a77161e46775d6, + 0x4499f660472c4f23, 0x7b24628eac38944f, 0x96383e965bbc9837, 0x780557b07684d9b8, + 0x03afd86f271a0a74, 0x908e396ef9238bad, 0xb92fd06cc0dd940c, 0xbb045293dcf6f988, + 0xab2cdf4583625b3f, 0xe886fd7283f9221d, 0xc4a05a54478e5a42, 0xe51cab325f7bfa13, + 0xf5f723630efbf9ca, 0x099911f715c4793c, 0x27cba6cdec27fb69, 0xbca037b732de76ea, + 0xe236408b59c78a5e, 0x8f9c80b56db4b012, 0x02d77c317fca6c7e, 0x42fca95370eb02db, + 0x239f22536c9ada6d, 0x88f70dfdef1b8f23, 0x191351f07a6816df, 0x30d67ff2d00a7c57, + 0x2a7d09d70585c799, 0x27b765045cdeb865, 0xeeb532c45821e531, 0x2f015a53c55cb2ef, + 0xfebc565b08ecde04, 0x0fc630fab8c46d47, 0x5e7458e16fc98219, 0x5e560e3a3a93d199, + 0x1e966122c84a888d, 0x4e45af24e0b3aa76, 0x3126f4d3acaf8528, 0x41c02305501b89f2, + 0x1775a35e56225425, 0x345bd20bfeeac8e8, 0xc4fd2670a58c14b9, 0x6e0cdba5f4901b88, + 0x87e905b79969eb56, 0x6d47b1da0987c341, 0xd5ac0085d9a525db, 0x42055449dc20810a, + 0xd379eb4956df3aae, 0x57fe735cd956e681, 0xb242177cb4c7d44b, 0x02157e10a51ba192, + 0x2b23472c86f3d42c, 0xdfb752c6e70df66b, 0x440c53749c109ffd, 0x51eb1d3e92ffba77, + 0x7abf2311203c8c7f, 0xf5c9a9906d15869a, 0x328d57d8b3ac203e, 0xc23d4e465c428841, + 0xbb95c5c513f489a5, 0x202167758c1c462c, 0x3641162761b0d42e, 0x8241254f3cd29915, + 0xd19d8567565d6d9b, 0xf121589ddf4b88cb, 0x296e3e46efb12b76, 0x3ab5000a0ea7130e, + 0xd6fd4d1ac31dba80, 0x6a410fdda6e0ce74, 0x658d14f4778cbc1f, 0x5dadb0a8c201adcd, + 0x8d32f17901a55767, 0xbb4b5bce928fd087, 0x7b616feeb27dc0ce, 0x1e49a26d572341e5, + 0xbb0a1d434cdc2c5f, 0x97724782aa0eca61, 0x7f70f10c098eb7d5, 0x17019b0ba4fbcd0a, + 0x4aa0f6b75317ba5e, 0x96c0c0f39e677232, 0xf2b123c940d1052c, 0x2220d9938ddb26ba, + 0x2eef5baba6b8e709, 0x5e857aedda5e98f1, 0xade8b89d75933075, 0x09e1e8fe080477b4, + 0xefd86b2920c320b1, 0xfc424961a7471965, 0xf2c44396b38f9c50, 0x7223d57d683e9333, + 0xc700e0da3238116f, 0x1dea33243fe13842, 0xd323bc16706a43a2, 0xd5db95d2d807f849, + 0x3d1ec16c575f85b2, 0x8c71719ddb7efd7a, 0x58e3f5a328033faa, 0xbac2081f989aae78, + 0x3ade383fb5d34aac, 0x5385831483718ae1, 0xc79389ec2f676712, 0xe627a205855e5dea, + 0x26a76d76ed73255f, 0x3cfcbe8a36e30824, 0x394916cf9f31c655, 0x1ca701b78097ba76, + 0xf334182a175bbf9b, 0x571a6e2f0bda762f, 0xe0101eacf9bbfb5f, 0xc60af282384b5eea, + 0x87b0affb2a2c929d, 0x2f340c404bb2d36f, 0x9e40556fa8dac4b6, 0xdbf1a2674d3671c8, + 0xdfe064f4859e9226, 0xb66ea881ac47e5a6, 0x62e536de8272168c, 0x1a92de4a36277a7e, + 0xc717d118b4d078be, 0x5014c077b69cc9ac, 0x15b105d9921ba0ab, 0xdef33690123b4d4a, + 0x8cf3d8d71634870f, 0x6842a9f72188de60, 0xa3e718f7bc7a263a, 0x4b49711f6646e065, + 0x5b391ae995e14dda, 0x6c42da131020c85e, 0x885845dbaf9bfee6, 0xbf29c0990d319625, + 0x727194da1427313e, 0x4e6c0ddb63378dbf, 0xb818c3b35f5f09aa, 0x5c17db76c9f32a7e, + 0x2b5ecbe9c52798e1, 0x06967fa08ce3073e, 0xa21379807b751fee, 0x367435c845530e3b, + 0xa2e464f7e5c7ff3a, 0x5234f5d5d7180b4d, 0x2cbcdd8acfd9313f, 0xda5fc23c4d95902b, + 0xefe8da391c05112b, 0xdd269a45cd470d6b, 0xeb0c9bd848761aba, 0xa1405ad04a697470, + 0x636979500c7c29a5, 0x7bd3b449007fbebc, 0x7aea4c9ee3ce6489, 0x2b957cd3788659c7, + 0x3cef4ddeb7171144, 0xecfbcaa20bd096a1, 0x8229c85b09c647cf, 0x884c0ccc943ef066, + 0x1093a6b760a2f03e, 0x8721728d4594c03b, 0x1bd6fb8524a81344, 0x0818df4c5fd9dc1b, + 0x01a43170f8cdac92, 0x9ae2a7e7bd7cbfba, 0xe2bb654c0f72abe8, 0x79314e00b59e14a9, + 0xa59a03a0d4c7e5b2, 0xd6edb8057b5f6d24, 0x4dc193a9d7be0475, 0x06effa5a4c80cb10, + 0xd8143f9af1c79f8a, 0x04b7b53a57fbd112, 0x00feb3f77a841900, 0x69df01dde1a6ebd0, + 0xbd11031bd989f0e4, 0xa169069023a4255b, 0xa5e4e1f64f9c4624, 0xa689af56071f9a44, + 0xb55084c28d7b3c89, 0xc34f82b2c720b248, 0xa8cf3432667f3f66, 0x95635f37ae3ab119, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x608a9a79434d1e8c, 0x2c593d2432d34f10, 0xbf48338b0a121bbf, 0xbdb80209762066bb, + 0xda7250f8a3b78fc4, 0xd9bc25a6960b343f, 0x7990e3b9aa443c61, 0x78bda5af8714d018, + 0x42ed9aed861543b3, 0xa6dac9052bcd9fee, 0x9bb46dc7849882b8, 0x802725f4f3ed580b, + 0xb0315cba690f2eeb, 0x7f4cf904fc0f2e5e, 0xda1e50b7d2bf3bb2, 0xf334dddffeb4112c, + 0xc50e5a02e56e0960, 0x396d29a7bb6ae889, 0xfe4956912f0dcbd1, 0x9eb6bf6c22dd781b, + 0x31a6c534f7b0c9de, 0xfcaad155fc1fed8d, 0x27b7fd72331d5b94, 0x050af92fa9cad789, + 0xec71d451b13c9708, 0x78743df2a256b478, 0x8815a3ad839d37fa, 0xd7b698839ea28594, + 0xbca812700133fe46, 0xf19c4a7077c1dc63, 0x1f94635e6cf1bb69, 0x0941fabca137624b, + 0xd3a79ea98f03c84f, 0xde6d7f5e7ca1df15, 0x02340b4849296a77, 0x139ae3f68f1a30c5, + 0xe963af4494d03602, 0xf1a4f89b7741372f, 0xb5aea277697d4eb7, 0xcecb1902dc515c1c, + 0x0d7a333ad43cbc07, 0x62db1ee2c5baf4f2, 0x6398d7179c719e66, 0x319999822c32948e, + 0x5e0872e6e16001ec, 0x8f72d00606aeb35f, 0x74773ef9c19e9966, 0x155391f8465506f6, + 0x6a175ec3429b728f, 0xe48ba68b212a5132, 0x815a5c6a22bf9a02, 0x80682039591c8952, + 0xf55dd43e9187e292, 0xacb66bff14a03d9e, 0x4098424d81ed75bd, 0x11ce2c210b2531f5, + 0x8f32a33b1ca05c53, 0x96c9670b5d0c668a, 0x258ede25feb6dc13, 0xa11c3324ff6c8404, + 0x7de5b199ab720f1f, 0x61196eae48c3086c, 0x18d3c132192b3be3, 0x13cca2bdbebc956e, + 0xad87993e3b85f761, 0x0815ecbee0d1c607, 0x09d262627efc0fae, 0x89014eaa36346b81, + 0x2efce345bce1c558, 0x0fb8c0c7756bee2c, 0xd2bf0a72cef372eb, 0xdc2ad1bd285967d8, + 0x0805988c101b0880, 0xf928c2d3b1296a21, 0x619642865fb1dfec, 0xa3d2a2ad25746021, + 0x0fa48081cce10077, 0xc6470087a128e9a7, 0xfb66e18200b5e018, 0x129c58d559f07a83, + 0x107b747df0fb1826, 0x681bd67ce21e14b3, 0x632f75616a37e290, 0x1a58659b0a478422, + 0xb3d1c8ea386dbaa3, 0x5424a90a3aa7d2ac, 0xefd15d01c30be310, 0x9a383204cb1a6233, + 0x83b000c9a9b595aa, 0xaeb6fe33ad51ca66, 0x6ad5bf1cd1eb028d, 0x5cc2a834a62e0568, + 0xf746fec622b90e3f, 0x29601624f5127ecb, 0xa1e70a78dfe92355, 0x2194998184ce234e, + 0x14e4404bc5efcd7b, 0x7ea02ab05aaedf2a, 0x425028517f46f92d, 0x01104cc534b76bd8, + 0x4f338ce48d793928, 0x293a0fd99bf1d97e, 0xb1ea1e69b178ce9a, 0xa4187b69fd274261, + 0x992b51c1d6f3be34, 0x9dc3655a10c468b7, 0xdbd6911903afd7c5, 0xe100670c46823e24, + 0x945942efa102aeb3, 0x57060b5b80a4fdfb, 0xff442806e7f43b6d, 0x1ee46a9ce512bec9, + 0xddc73216e54b0d05, 0xcc5809c94705ac37, 0x1140395f15871dac, 0x7c74fb167baa67d4, + 0x80309a17ca46821c, 0x753b22adeda2b8be, 0x55bc184648bf4f30, 0x7c64a2315180c771, + 0x62c8a9e4b2f1e313, 0xade18678d283fe2e, 0xdd2087206af3f73e, 0xead4fb5d2ac47ec1, + 0x18da9ec6388a15a7, 0x703b3f01f009c658, 0x9a89c825254ad7ee, 0xa35756332515aac0, + 0x5f7edb2f08f28518, 0x63ec6907bf887946, 0x59b0c9534cd1e6b5, 0xc4c23a8dc34f0b0c, + 0xfffc02afc5ae743f, 0x39655ef696be9f42, 0xb48afe1a91738d9c, 0x37d839098b71a0b5, + 0x6e95a63ae594f1e1, 0x424f13ca3592efc7, 0xcabaf8b84e6852c2, 0x5cfb09a4b596cd35, + 0x1b9c0efa08e7b3f7, 0x15c2f594554d0d55, 0x2b728dde0084a829, 0x4894e21d9e3145f2, + 0x88a25719270a56c7, 0xd830e9cc31ed6946, 0x9b9e60eff3fa1bbf, 0x7d12f1ff15d85622, + 0xca9e8e6407b602b3, 0x48c36da2fd34b907, 0xc7d638605b149cc9, 0xf419ac68a5d61702, + 0xc5fc7eb87c14ac45, 0xc43c592c501f6b10, 0xadabd24ceb218a98, 0xb3560794f78ad22e, + 0xfb111c7618deb415, 0xf00538d84873dc43, 0xd2de375aaf765963, 0xe6e28b7530f0e822, + 0x7f8499b5d2ea33f9, 0x4c74268a37c3081b, 0x12ada4f51e0a7cd6, 0x0c6f700778729f48, + 0x175c5d0981ddc678, 0xa1f38cb975798213, 0x4b19c49252c673ce, 0xf96e2d3bb5d0d64c, + 0x97801059fea55530, 0x40e2524699294634, 0x13cd9c5e049ac8ac, 0x942e2d839d75b9a3, + 0x51ce2f7d85fdc9ac, 0xfe7db2ccf18ee4f1, 0x213c7bac8526962d, 0x457459efe7b25af0, + 0x6679522d2e046f47, 0xda8558e59c459d2f, 0xaef9af97454433d2, 0x2b2b496a939800ca, + 0x95c722d00675a47a, 0x72c60bf6acfa2a10, 0x9065c75f8ea2659b, 0xf52304d93a3d8f53, + 0x9cc0e7e93bdd7c04, 0x2d4e27995eb0e80c, 0x9f70048eeebafbb5, 0x350fe852c2576b67, + 0xa58ddba50e923823, 0x90af9f956c024a17, 0xa73753eb9d548b65, 0x9b4f9a04e4844852, + 0x590e76585e01934e, 0x82afdfb5e36e426d, 0xd96be5219832f8ad, 0xf6ca328666663292, + 0x89b7c3b7f21bcb85, 0x24ba771d4ede3c6e, 0x86166a40aeed789e, 0x30d5570048c48b51, + 0x4c2aa77b5f774278, 0xecc84d80e7232c84, 0x235e9e55a8a79993, 0x996fc08d120187f3, + 0xce3e6dab771fbff6, 0x564cf64d225cc775, 0x082481b092face1d, 0x5c5d45972357b379, + 0xa90a04e1e0a6ef41, 0xd9a8ee400554e0e9, 0x5f66669b58579a2b, 0xf944e536f190e7ea, + 0x51523bdb9c5c96aa, 0x87a6e60cd7c6f194, 0xa33ecf59bb70592d, 0x06cebaa5178782bd, + 0x3f0cdcd108bd2c5b, 0x8268cc378d7609bb, 0x1aeaf0d3be06b98f, 0xdbcd50282707585a, + 0x3018c1f91d5441f0, 0xd080373678061b5d, 0xd96ea551138b21ad, 0xb45864cc46c9354c, + 0x2a11aedc93ca313a, 0x23b82fbc79237e14, 0xea8d120e22cf578c, 0xe62828d0f0377574, + 0xc650b2e087eea48a, 0x8b7c78d94e50a0da, 0x8c730263289ae67f, 0xa068cfefc52a9cd7, + 0xc8c407e04c8e31fd, 0xc1ba041ec488ff38, 0xdcd35790882f7f61, 0xa832eb985fe10d1f, + 0xcf13cff698fba59a, 0x0ac55194a57f8d9b, 0x6785563015bfb864, 0xae279e9f50ca2ee4, + 0xa1602398431a5654, 0xb958a106ea73ca4b, 0x720dc5b4829e9c52, 0xf1d5c74b398003b5, + 0xcdd3501ca2fc0848, 0xe8d7f062cc7baea6, 0xa4d33aeed07af0b9, 0xe2ba25df8c218fc2, + 0x40d2c08bff99c73e, 0x28f7c0d8fc6de66e, 0x8a670299e6b3a53c, 0xe5b872339b4aff82, + 0x1f71ef51abe8e79d, 0xbda4a46a4b56f5cc, 0xaad69d5b5325e79b, 0xb713cc4a90c68b79, + 0xe9c9386f79a6e833, 0x3ac59f2f3aa5fb69, 0x08d14735898a046f, 0xb59b6cd64b379266, + 0x2ccd376e33a3de1d, 0x1ad8509c4375fb04, 0x340fd8dda599ea43, 0xbef38a16f2effb65, + 0xe1e913c9bca57815, 0x705f5866e9813cb3, 0x0a6245b603a2dbe0, 0x8873f33ebc50b0e1, + 0xb85b10860af17b26, 0x0b0c4f3f26a09cc8, 0xa0f03154e647ef18, 0xf39fd72c3fdddd61, + 0x3ab04214f424840a, 0x02d738b97b432318, 0x1556ebf60fc1ad21, 0x4cb3d337e03155bb, + 0x39123b700d0bd59d, 0x601de96212c52eaf, 0x978de0bd51fcef40, 0xcbb2053519bb94bf, + 0x2d738ae9a8b93fba, 0xd64b7f24cba1e9de, 0x852dd487981891fd, 0x31e6b72e95941d87, + 0x85e63bd52b4caa34, 0xa7579e056353a4d0, 0x3dc3cd685e3a9417, 0x5c8fa490c04ef7b8, + 0x6cc6a846e3848110, 0x21e7ac9833e88188, 0x0cdd9d007147f3e0, 0x53cc2db7febf8843, + 0x0e2c13473995cd7f, 0x9c21b66317e1b034, 0x7fbb018a2ad96710, 0xc01126650331d17b, + 0x982c1988f436f67a, 0xb6d8c62e6fb6e884, 0xad15ce3734c73da1, 0x8b12c7fd557ddaa1, + 0x0260352e9a3e574b, 0x1d419ce76a2c9888, 0xf4f29cb804f96dbb, 0x0a18c43fd40e293c, + 0xc9d79c8b22377534, 0x34b6e729afeab15f, 0xb48676f39e2e57f9, 0x50ba0b8d9d312f9b, + 0x21df423437b3f70b, 0xff7a2cb3362b9104, 0x8df3297c49f4a49f, 0x4af26bcfece1fd36, + 0x8d5c33f5b6dfa570, 0x842c1753cc4b6cf8, 0xd56c19ea9ebb8d8e, 0x7a2f2bcf989e2c67, + 0xae0898b24b2de252, 0x5e4d82804feb159a, 0xd1645ba07bb76b31, 0x5cc6e425d166f721, + 0x3fe787236fafc16b, 0xe33eec70e262df3d, 0x8a7e0cb5db9a4e40, 0x0d83be7869143f79, + 0x16882626c377005e, 0x592ca0753e8ce4ae, 0xf79301ab468c62bf, 0xd5d393476472fc97, + 0xcb27d16af5a79249, 0x518c43db4972589e, 0xba0e01f1aaf10c52, 0x3be086b45378bdc6, + 0x446515092324314c, 0x1efc5dd78c46f5da, 0x1086a856f5f5ffca, 0x7802b5c71cc8bb97, + 0xbc181955ceb20c41, 0xa21a8cbf8d54c4a1, 0x46481c8682c0ab42, 0x7810f0262e766ffe, + 0x92e556967c6e2b87, 0xf14ee6d008625bfb, 0x3daeba4b9910d738, 0x5ad74b806914e958, + 0x71544e4e46b1d49a, 0xaf989938ad4a6953, 0x0f415e1c1023466f, 0x92a7f1f706c0081e, + 0x6bf441519dfca363, 0xc3bb09e8bb163112, 0xb1641475736d3306, 0xead5436f5bc6fa71, + 0xf4e6637cdd7f6237, 0x9a81da094c801452, 0x9935d3133070a151, 0x761653a527ba138d, + 0xc847c40bd343b75d, 0xc9fc46ed8b339d23, 0x77ba68b8640bd91e, 0xaeb5531dd794525f, + 0x5e6c240bfae79050, 0x93ef52936d8e8ecf, 0xc1dc8c960104544a, 0x1315846c38a28f28, + 0xe58b3b8e234218e6, 0xce8a06ea6f869b34, 0x89e015f4a4563bb5, 0x60b59181364aa5d8, + 0x436c7944e2feb2a8, 0x3975cdd411bbac23, 0xa0d8b13657801f56, 0x4e98f2ab64664c21, + 0x2ad76a8737f35649, 0x07e4db37d8f9e0d5, 0x9ceb7809ce56703e, 0x567d4c77f65ba72c, + 0x60c034e43db318ab, 0x871ff6da37c8580e, 0x889478b1a0c71e17, 0x1f343de1e7771c9c, + 0xeb13fe79fc6f8d6e, 0x6020b607e8f79343, 0xb84d26392404701a, 0xd2912f982f434f97, + 0xb73b06b011521287, 0x196cb4e081acde62, 0xa14f961f50cac97b, 0x2c2b8754b0808d9c, + 0xf9270ca3ba953bc3, 0xba6f50199c66f325, 0xf1a3a43ecbd5effd, 0x74be4e553a2cac55, + 0xd674c5334fb996b4, 0x7a7a51f9c2e07ea6, 0x66ee9db53ea67989, 0xe9d9e4d14f5093d7, + 0x18bf3dcf04d532a9, 0x4042826ad81fd635, 0x71d80c0e3790aba7, 0x9b2b525966c111f9, + 0x48f7d235b9a3c019, 0xb9d5de2a0de02732, 0xaf6c4de305006e7b, 0x462d8f0b92781def, + 0x462f5f0de669cb28, 0x8551995bb51347fb, 0x392faf06076bbbbb, 0x29ef642daf46a0f2, + 0x93e0b5051f0a361c, 0x3c642d3f3490c255, 0x479fbab342afbc08, 0xb3bd260f4e7647ca, + 0xf15bf68f9e9827ad, 0xda082eb7467edb82, 0xc7297517a4f92466, 0x019858adf6665064, + 0x25c3f6521f2d1953, 0xaf10275760a4a2a4, 0x2ab0a568447fc826, 0xaa028eeb8919d089, + 0xedb97f4d0326c3f1, 0x7ae990159b86f368, 0xc185d9a903c2fc3b, 0x2d5029a68a567805, + 0x2cc476b8cbfad6b6, 0x8624394338dec52e, 0x88ac69953a09849c, 0xe97dc171637c5546, + 0xf99a4086fef67bc3, 0x3a350abeb59bc215, 0xff18ea4ae3663f69, 0xfa75f329654fe2ac, + 0x76c1a4eadd7ae9d4, 0xbdd64d8f3b5aa482, 0x129868d91212af2d, 0x012e387d6a168c1a, + 0x830fdb67468b411f, 0xb91454392a78666e, 0x87795fb959660ede, 0x24bca94f7b7992e8, + 0x80c3f471d6834896, 0xed42811a08dbd3dd, 0x44891be918e30aae, 0x50cb8027f01702f5, + 0x3f7fef1db984a52f, 0x9a90140dea0c0c62, 0x1cc59d2dfe140abd, 0xfeae9cc1710d25ff, + 0x98d7359596662e2b, 0xa9feb58ab1fb8acf, 0xc611ed41c45af4c4, 0xdf8a84b7ee8b0bb9, + 0xa5c231b08b347096, 0xe09d05b7872ed7fb, 0x4dc074ed7c595aa5, 0x6a9fa1a8a0ea72da, + 0xca2988916e23112d, 0x81ec0732a4fa7f94, 0xa33b11bce96c81cd, 0xe2745c04857e8f2f, + 0xf600a8b2ac798498, 0x778d7e145974c51e, 0x609bb5da371925f5, 0xc5452b018ec72ae7, + 0x2b62af148890eb11, 0x2a26b96929d2dc4e, 0x3bbb95336b3ab317, 0x7636bdbf8e5ba028, + 0x6edce23e6a994192, 0xb4a9ad5d60882065, 0xbbe1e21cd6b214c6, 0x9853b71039c77d22, + 0xa270f29f0fa8bdd3, 0x208b04ceff205558, 0xeb969b6d6747c7f4, 0x2239e9c30648be2a, + 0xd3e0bea65f00463d, 0x16ccfa5017574073, 0x58c98bc20b9f3bc8, 0xdf9e9bcbce9ead05, + 0x013000d67c66dd8c, 0xa59c04ed3366d772, 0xcf81fa1968d6cfb4, 0xf2099e95756ef332, + 0xfd291ec48a6171e8, 0x5349d8dbc2c4bfc8, 0x5d211fa98c96cf96, 0xefe798f524138ba0, + 0xca540fce28a63ba3, 0x40f8bf14964c6294, 0xa8af392b73954beb, 0x3fe7099b06334f6e, + 0x804511335a403430, 0xc73ef3705ad6872a, 0x9e71b7137325c13f, 0x5019e321dcb51420, + 0xb432fa57d756cd3d, 0x2b113a42a29c1124, 0xeaa2252b3d6a9f62, 0x75cbdd29e115fb0b, + 0x30a8c6a7c4e7f158, 0xc7d331ddb4f4d608, 0x233cd0224c5de545, 0x47b919f94fcb13fb, + 0xb455b45dff711a97, 0xc6cdee12f4a73224, 0xc5ac0179d6a5743f, 0x204643bbae0b27d5, + 0xcbe67edc6f15f8ad, 0xf777a811a9d93e24, 0xa6b4c2867d4fde9e, 0x50023795ad369e5f, + 0xd9be587fe5f375ac, 0x9e7622651cd1bbe4, 0x951fabd73a500e61, 0x6bcde4c8e2be3531, + 0xe2945dd6e99ef02e, 0x5ba4d61cc73dd774, 0xf137e8ae95b949fb, 0xb38ad2611487f485, + 0xcb052b70995c195b, 0x450f770bb9869a37, 0xe08f01089abe7af2, 0xfd0042781137a61e, + 0x12ace0d979cef5cf, 0x7428ce6f9d38f11e, 0xfd8725deb3134c6e, 0x3ec0da6ac78e277f, + 0x4e3315ccf1a07759, 0xe41d4581793218e3, 0xf275c01d6d660d21, 0x682563f05091551c, + 0x39f82dd7fbdd9e6d, 0x9457bf9198f782cc, 0x8eee65e567a82c66, 0x413a5d226c6fe4eb, + 0xcab2388de3afae0c, 0xdc5c0218f33f7c7a, 0xc35ac1651408378e, 0xfccc79e4653f0ba1, + 0x74b8d979e8808003, 0x1774591b6b85ca99, 0xba01ef1c2200475f, 0x9ccf66e4f718dfe9, + 0x2400924abf23a9b8, 0x87a66ac38eef1ffa, 0xe6c3bd007b64035b, 0x4af7e8b4909c4015, + 0xdbbff4e9fe8b29f6, 0xe5e8d1d5fdddc4ee, 0x2a0f9a4f1f38f47e, 0x68f19b5f466dbc8a, + 0x3966fc2f49af067c, 0xf33a5ab59b9b162a, 0x6ecbd6eb857080b3, 0xccd2e92338f8e731, + 0xe9906cfed6fcd007, 0x870ca3dd4056404d, 0xb662691afb3c2be8, 0x89c33e1c166e5951, + 0x4625749d10cac785, 0xf8944fbf61e59285, 0xd9a7c321b62884be, 0x16bbf8da1ab78fec, + 0x67144c63179830d0, 0xd9aa6781cd3cfe01, 0xbc01f7feb103730a, 0xd11433638ec32752, + 0x938e628dfc459b49, 0x38249a316f5eaae5, 0x1072a30608eb6270, 0xe4235d57a326a411, + 0x00780f87b08af768, 0xf78fc275ff534351, 0xa3ad1f43cf5fbf0d, 0x03a0cbefe0002e61, + 0xfb68776b1b48a894, 0x4aa5c16969deebfa, 0x5c1872eaa846b645, 0x44aac0e88980652f, + 0x3fef962fbe4c12e7, 0xfb468b875ba88bc3, 0x3d83a4ce4655eab5, 0x8b965a68a963159a, + 0xebb0bfcef035a2ad, 0x217f004472e36321, 0x1d07cca6cde5c9f7, 0x7bb7cae9eb566113, + 0xea0869b2472308be, 0x0a3eebe96bfee9fd, 0x2f105f54e8c93133, 0xe4e40f0b5b476708, + 0xb803689d3871504b, 0x3863f72b37302cfb, 0x7f1b85502f27d4b7, 0x1a0cf302379bebec, + 0xabe7211b23ec7f7a, 0xc01bf7e1278265f7, 0xa09bf2071e30a5e4, 0x9dff886c1c0c3633, + 0xab8896cdda4e06df, 0x0eef4eb73b1196f7, 0xf297a71ab86f0836, 0xc0f3e3094da0594c, + 0x9ef19f94a25a169b, 0x5aa90c72990d6ded, 0xf6ce9542bbdfa107, 0xb1db4902a1f74dc5, + 0xcbebf81a2d72f217, 0xbc253cfb83aadcf1, 0x64a859a56ce69cea, 0x282020b595b67d95, + 0x0e31602364f0a5e0, 0x5f58dd640c86894e, 0x06c74dded9fbe184, 0xa1c2ebc141dc6d25, + 0xe2f85b316ee29287, 0xab81a1818c10c578, 0xa3e54718b9eaf9bd, 0x5c497210acb3d1ae, + 0x3a20377aff1cc1e8, 0x51824544f9965ff5, 0x9858ed5bd9b04e31, 0xf108da5837e085c3, + 0x1ccb1839cc9346c2, 0xcfecb428bb384437, 0x87e5c9075c968464, 0x150397c168f47270, + 0xa17dc0382e417be6, 0xd7c8abbc59383711, 0xfc3b1e35f8819750, 0x09bac79c89a067e7, + 0xb73c170284d50b2a, 0xbee697a9eb976a5e, 0xd12319ec233626ca, 0x717ad4c33a129008, + 0x6a3521f2039b54f1, 0x8e086bc86dc8f1dd, 0x0c189baea4261f64, 0xc1e43cda92632e1e, + 0xddad9e0604196dd3, 0xa2a96c6a200c1263, 0x5c855aa2b489b239, 0xb0cbf1c664da5f4c, + 0xf93ffc5e110dae48, 0xac89842612e0bc06, 0x50903c4b612ccdbf, 0x5b1d64322a7ebf82, + 0x47cafa814b146597, 0x9c95eb3c56e09d24, 0xebcff8184b9494e0, 0x7758adf4357f51e5, + 0x9c00f511e5623e29, 0xf216ec2b606c713f, 0xa80bf74de3560d9e, 0x3b5481dccd13442e, + 0x915755287cfae4ff, 0x2170acca33fbcc9d, 0x9c67b4c53ec86779, 0x7ac286ba9548db82, + 0x795989deaf3236d3, 0x6f167d6d8cf81e3f, 0xbdadedaa3e46eb94, 0x88f7655ba658e213, + 0xe530594c8fe113bd, 0xfcf449cc1781f0c8, 0x376b3ac6a83885a5, 0xefb13c5698e83bca, + 0x6a833af63c17201b, 0x05724137cac030c7, 0x8da81a8f90b32228, 0x9cb062a0788e8315, + 0x2ae3f1cacfa393c3, 0xc453cc041335c05d, 0xd76fd7194cd9aa4f, 0x363929586c4cbc9a, + 0x5566b1352ca7a321, 0x611a013e87ebfe6d, 0x4028b352b49c1ac7, 0xe667c72a01b80116, + 0xd789c93bd50bc8b3, 0x4bc22f71930f68d5, 0x9777687fdf4c5442, 0x7a04400dc8bdb759, + 0xa9e8bb815b828078, 0xaa4e565dbd185f30, 0x9fe3d9a92414be9d, 0xeda72d70f6ca51b4, + 0x93b60ccc41a46105, 0x6249b5ff82c04cfd, 0x1c8a8eb273d864a1, 0xe1e6923651139fd1, + 0xfa918c04ed051cf4, 0xa87c658b4a189834, 0xaf336f186ae81986, 0x6f1526aa5e343a1a, + 0xd70a45378d31beff, 0x6af6c73c1470bcf0, 0xee9483c22da542bb, 0xd55eaf0399a18d04, + 0xeb1b0f52ec5b02f3, 0x5e0627f42f29a026, 0x0072b9917409e0be, 0x1a344e5987936eea, + 0x254db4b5a2000345, 0x106ae764ea6840e8, 0xbade868e80f26745, 0x056978bf063f3f8c, + 0x5bd19f09b63802bf, 0x57ce6b2337ad4745, 0xc6455c4dfac81779, 0x9b632e760dbcefd1, + 0xaa9c311c27ea334e, 0xc567d1c14e4a45e8, 0xee98198895d822fa, 0x8b82cace3f6fbbc8, + 0x304571898c12f9d4, 0x207ae49ccfbae74a, 0xc4cc8d50eeda6ec4, 0x7c1439f6be9aefae, + 0x941d7fe0134d3eb9, 0x4a7e69ec94e93e2a, 0xd871360e79262860, 0x3afcbd8201c221c3, + 0x441d549e31e1d3be, 0xfd270e427322177d, 0x178a442c733c231c, 0x404a23e3ab1ec656, + 0x883932ef89cd4cee, 0x07710e29a2be30bf, 0x7e285d52e45ec391, 0x0f37d01edada0675, + 0xbefaded6ac57b0e9, 0xec7168306271d292, 0x86b9a9a71aba7885, 0xe6a0156074600a08, + 0x91c6eff4329a1e52, 0x9fd277a1d17737ac, 0x5b5fa2ce6f2824bc, 0x8f5a05840c3c6599, + 0x738a58a78c96ab00, 0xa6e510a26a60511a, 0xe86dd6420af33f09, 0x4c2e99506072a91a, + 0xe57f62dda8f3be29, 0x8c6949816c564349, 0x3ad39819aba970c2, 0xf10531a4e679a0bb, + 0x1b0d7e9eb5a80a45, 0xf2aa167377196d6e, 0x85ce596e4b33721c, 0x81c63aa0c23d3622, + 0x3d7a24e4773a57a0, 0x6004759d2a680ce2, 0x5cf28c2d0b9559ce, 0x74857bdbd8fcb32b, + 0xfe33145ac8f62984, 0x8847df9dd9435435, 0x4ba9321fba8db826, 0xbd67fc90537277f0, + 0x666e2ba8123c4a57, 0x65991d339df9a8f3, 0x8d23d11334eb5bce, 0x615061690d0442a3, + 0x17c2fef286a7e44a, 0x461e51673c59a401, 0x2680326ab93d7a8e, 0xf6bd26937eb21f01, + 0xe270972890df2902, 0x31bc4acab8ebd209, 0xc084403d249f07c7, 0xd652c8dcc1de5e1b, + 0xff84d6de85862e56, 0xe50c4e7331b20661, 0xee183b6e4924523b, 0x22602531439be3dc, + 0x5b7be93d4daa06d8, 0xc1fe109c1fd7bab7, 0x2532a0096f5019ce, 0xc123fadde78f0b7b, + 0x8690c3dc9b19f91d, 0xa2ababeeab1aaf0d, 0xf2ba9b2718c668ac, 0xb654f36acf14a645, + 0xfed0d9b07d636501, 0x8c973e24f4f992c3, 0xcde2f745b5e60cc3, 0x2b6fca4781f1609f, + 0x86b054ddd476d3d0, 0x52df8d5a79e88877, 0x88c3e4ed88d7da62, 0x527264be33bc44d9, + 0xf6266a46f4e95601, 0x2a005714f658f562, 0xc2fe239b4301ee75, 0x38d5961a52c2f040, + 0x55424b3aeb6fefa0, 0xb0d20f7a57fe433b, 0x03b2fef3f4258e1d, 0x1a0f7ebcf87958bb, + 0xfd11ee47ca2d2a92, 0x6a3dd7cf0e863628, 0x5ad0283cc148db42, 0x0fff5f84446d2bc7, + 0x24d778b7d75d62f0, 0x97b34e5698dd81e5, 0x5911591b95e47fe8, 0xffaaafadf0c5b64c, + 0xc161f9a3f3daacce, 0x47d2373e0d209b30, 0xd7f85656425282d8, 0x6efff0f4ebef1e2f, + 0xb20ce2642b848d31, 0x0966443ba1d39f22, 0x681417e4cadf69d7, 0x12c04e3b6aeeb235, + 0xdc3dc3520b16648d, 0x8d7d6c1925195036, 0x6aefbe41161d6942, 0x345245cc2100c197, + 0xd9b495b6703a6a57, 0x5f00a657793c623c, 0xae69182e67a2b812, 0x48cfaf64f2f005f8, + 0x0cc27936aaf06801, 0xa1e54886e97210b9, 0x7443f6df088846fe, 0x3a7951f3422a23d3, + 0xbe75e47aedc62b57, 0xbd7902817290e1c1, 0x967d6e81eeaa8243, 0x6ed3d2f58fda0a13, + 0x2f0442203ede1718, 0xac3fca312c2fc966, 0x1607bc700caf16f0, 0x738eada17da464f1, + 0xbd7b9846ab0f3b78, 0xf0b6b4236542215c, 0x48c06b368a98cb8c, 0xae17c7588988c7f1, + 0xe56b7d95c32feb28, 0xb8721b3621431dcc, 0xd1bfa46da7e7c36f, 0xe77c4d105a0c6b38, + 0x6f73afb2a1f27d7d, 0x5dc4f91da2759afc, 0x8e076b75f87638ed, 0xefe00cf0d03bde9c, + 0x133118ad38ef980b, 0x12be809f336814cf, 0x810aab1e45906d5b, 0xebe3d94e29c9ae5a, + 0x925ab5f2122348c9, 0x1faf6935db1b9a77, 0x51bc6b2573dbf63e, 0xa95b0a19f1b85e8c, + 0x8de23b643bc89c14, 0xa3f97d11c798dd9c, 0x8837a69769cd8d4f, 0xa47244ca72ff7b87, + 0xb0c533e4b7f23547, 0xc2fbce36a6dd771e, 0xbfb69023ed016f66, 0x2e4d36714fe56a99, + 0x1d85fe2a612b473f, 0xfbe59dcda5367967, 0xccb433d89c80c8bf, 0x8dce6744a5655fbb, + 0xc24ebc0175fefe51, 0x5eb8c54a47af22a8, 0xafb5cecf089ea7f8, 0xdc5870c918ccdc7c, + 0x33a6f27fdc4a3206, 0x41d73a75dc06ca4d, 0x6a6419e96da71205, 0x999c37b930dbfbb3, + 0x2b5ebf2230defe35, 0x151efe74b36e65e5, 0x1ccc34955ced049e, 0xaecfb297e997f82d, + 0x08ec9edf80aac99c, 0xa129dcfa283ca7ef, 0x96a489b83cc51a46, 0x7cf683d1f1df3917, + 0x8266b2db02e21255, 0x3c321e24a0b43ee2, 0x8912a5d8dc9533b3, 0x6d9f6fc7bda39eb6, + 0x1913d44b57537c94, 0xecd321fdb94463f0, 0xb4c49ef3e89c3a11, 0xef9d8347f0aec1f5, + 0xc43bbdc365a157cb, 0x9541f01e569592e3, 0x733e11103925c4e4, 0xebb901892bac587e, + 0x229ddba738ee2980, 0xb5d00bd68626c32c, 0xd3c5a60917d7121f, 0xa72583c7cf2c9f43, + 0x6d3a923ab1f1c1ff, 0xa2a6c2e8786dd943, 0x19e7e9e595d42e4b, 0x8c60eb8c3108e9db, + 0x604d0bcf5c6ca2d2, 0x0d340289428e00a9, 0xcfd14852ebb17ea5, 0xaa94358ffb0785fa, + 0xa0fb2e7588df81fd, 0x2a4ac67f1d2e0211, 0x1156548a61b82c4d, 0xc869c80c5d260cf9, + 0xb8a54a7ee011f4fa, 0xdbbb48a83a5d1789, 0x52350c1540598d23, 0x436636f81f1fd918, + 0xaecf44bd28560801, 0x70c655c498590a0d, 0x6dd16acfeba7b34c, 0x97036ed7039e7c07, + 0xe05d04bad530f434, 0x2141cf07b90b3fe8, 0x8f419170f3fe1fcb, 0xcffccf4cbbec96b3, + 0x35f30af59e2b2197, 0x01e79f4ec45694b2, 0x07113bf5b50ce4f0, 0x47d9dc7f6714609e, + 0x07bdbe8a10e443ed, 0x037bb1a5b6a4005c, 0x68aff22405e75a31, 0xdf097228806c3b73, + 0x867077462b3da42d, 0x411c7842a75276f2, 0x4a2dfe7037277513, 0x0d784416cf160289, + 0x27dfa461a3ad0f03, 0xadc9a372c07b485d, 0xe779f986d748b7ea, 0xa7480dca02e17eb9, + 0x419fd3e9b8171ac3, 0x4d624dd7f5fc148e, 0x0764590377883ca0, 0x3c2fe4169dbc621d, + 0x64e43b21ebf82f89, 0x63440f1c0fadd3fb, 0x2361039510a8f7b3, 0xb9e596c451c66da1, + 0xef9842b445616147, 0x28565c2b425adaf8, 0x476faa5655e7d6a7, 0xa942d36ec15b5e43, + 0x894cc7435ef42a79, 0xef00f69cb29c4821, 0x2497e5478b49b136, 0x80ba2da630cc64c9, + 0xfbafa22eebe4772f, 0x7dc412736a90d624, 0xea644e10747778c8, 0xad43a4cdf251b173, + 0xd054e339036e4d41, 0xbc3965a4a0bee885, 0xa03c7ba47833c97c, 0x4b7426a984e07672, + 0x93c9c1ae88b854f3, 0x32d2e2ab62074dee, 0x96caa408f02f1fd7, 0x7b0a4e7c3d48eb62, + 0xaa810b23a523a784, 0xce9e4d3a997e4411, 0xa87ce6f88219ad25, 0x96174a23ca722a1b, + 0x1561b090f973dfea, 0xa8d751f3dcef8767, 0xecb93f2c57abeb24, 0x84149e36ce67b89a, + 0xd462fed031879b0d, 0x2e0d4ba18bd83a83, 0xabf559b1e9fe0170, 0x3e81199be544c317, + 0x8ca4dd143ea7b816, 0x76f1bad0f3c1718b, 0x09de81f7e31e1881, 0x4a838c103a69fc41, + 0x59a9dfa77936e114, 0xe9ec59621ddf78e6, 0xbd95469f382eca4d, 0xbb35d28a223d9934, + 0x90d097b9e4522328, 0xf11aa0c380119db9, 0x236801b632c2b433, 0xe3b3f41dcbb6eaa7, + 0x3cac132c4836a003, 0x7653656c93f27513, 0xe2f2bfdce77c1e7c, 0x82663f4251310735, + 0x175aed3063345fac, 0x1ff308eb7341156a, 0x93d59783d255facc, 0x37a9cfca45527ef1, + 0x5a57662af3532dcd, 0x9b2544dd8bb019db, 0x5d1b76bf9402bd1a, 0xa850a5a8710a17ca, + 0xe753f1c6abc25522, 0x39427e829e0f7563, 0x56c23dd3dc33c949, 0xc9aea9da238a1a1b, + 0x03c8c80a44dc67f3, 0x2a47dd74be77156f, 0xcb1a0120aa3b2fb0, 0x59bcde83f3e3170a, + 0xd048ba32815fb5a3, 0xa7a786b4ac4c51c3, 0xf95185b7be4b8845, 0x62af94a9a031cfe6, + 0x77432b283aa64dfb, 0xf2e0da1c22e229c0, 0x418af392252e880e, 0xbf341dbf1411dab6, + 0x59b45922a0be16b6, 0xbcd101d35d5f4534, 0x15ee40528a0efeb1, 0x4902f215fd29fa03, + 0x79bae6018464a479, 0xf237bfa1b01ef781, 0xd4bc4215245b2099, 0xc4bcb8434da0633f, + 0xe4b9b46ff68b1a63, 0x084cc4fa7b478bba, 0xdbfb43c9bb90553d, 0x1854086acdba3401, + 0x542b0d4f457ceeee, 0x5f6d380159097c14, 0xab9d0f613972e9a4, 0xb120304b2124b87e, + 0xc1280d6a97715bb4, 0x8de688679e896d90, 0xd75679d8ec457f22, 0xe8d44f6bc287f4c1, + 0x31e0cfb19b6625ea, 0x19398226f07eee92, 0x971454006b90ab0b, 0xaa6ca3b1121bc1ad, + 0x50742e33f11e90de, 0xed74827777f48938, 0x9d72745dcda9bac8, 0x03134a4b6b73fe39, + 0x21d17531ac6438b9, 0x45874a1ad24d4d22, 0x3f85c291154c167c, 0xfe2600ab738d7164, + 0x7fa99054e893c95c, 0xd2c1f6dc4a75184c, 0x92b546af4dd45a0c, 0xfc5e4162c5216cd9, + 0x6018887a88b20581, 0xbac5a1c2fdd3e73f, 0x5063f7655ebb54bd, 0x62f9658bc17b53ae, + 0xed2c4de8a59b191e, 0x5bc716e4383cb96f, 0x37c5831ebeedf433, 0xe8ea1d41b665c4e1, + 0x793280e3c5856bf3, 0x1a55d37cc6538e3a, 0x8a69495d1e111284, 0xa3d27d793d2bd7ed, + 0xb41e9754102fa2de, 0x58104f50dffa7179, 0x96d8546843064086, 0xf37b1e3bea76822b, + 0xdcc671705b5a3cb7, 0x05888dd91458fc01, 0x95ecb161f00150e5, 0x198603b64ce39e13, + 0x141175241f14d7d4, 0x8113bb902dfd9bb6, 0x870f48adb2db9bfa, 0x0f96a2b79946a3c2, + 0x72bd4a0d6d90ff3e, 0x272b928d92f77bef, 0x0a0b1da5195ff2ab, 0xa42bf43e005a3adc, + 0xd72887c317245c97, 0x8ff412407b7b7d38, 0x6dc1366b9704baf9, 0x5ab28781b44a6bb0, + 0xde08e8afe0705271, 0x59018ec8dd107c6e, 0x23127b86eb5933bb, 0x8f252c9dea513d89, + 0xf94f8cd8a0ef16ff, 0x8571488fa8dad6d7, 0xa6332ac371661b12, 0xf5759fa2a32cc373, + 0x0864a02eb4ffb7a2, 0x443f50620d13f422, 0xb66470be66af826f, 0x119c6488308860e2, + 0x31b5cd3b00e70b2a, 0xf841fbf485beec57, 0xce3bf99668978201, 0x3cdbe54b9ca532e7, + 0x50f49494ad43b1b3, 0x7d9842ce1e21a6ab, 0xf1b45f142045f362, 0xb09aef5995c3bbe1, + 0x55ab89a5343cbb21, 0xf3d943413fb2f9af, 0x9888dccb63910725, 0x5f0e316a1065b815, + 0x1630355cb0022f67, 0xa8f59ee27feb08dc, 0x61cb94f0b691057f, 0x36bc72b86f00fe53, + 0xf17c409293e5111b, 0xd178ca13f655a335, 0xe8000f1a0b9f5b6f, 0x5dca46cf1f5345f0, + 0xa77e941a0c54d2b8, 0xae3efaafb6864fb2, 0x3f160f7ad7e9ae32, 0xa9537aca0d491c33, + 0x624834ac98396881, 0x441f0a519925c876, 0x21ff13474ab1240b, 0x706fd5d80ac1e265, + 0xc901ddda038f6cdf, 0xcddd7e37fa743dd7, 0x5dc714a99a8cd7fc, 0x04eaed7bcef1cae1, + 0xf5c924a8b85e2281, 0x402f82058e6b3ed0, 0x0f6dfc077fa73dcf, 0x2400a8f2363a6eb8, + 0x560e936e0ae1406b, 0xa2f0a82123dd2991, 0x100f2d8af55ef752, 0xcc6f89ae83639721, + 0xd6ef1ee313d82bc1, 0x4d81954eee39c9e8, 0xaabfa24191fe7a64, 0x27c0489d3d7efd01, + 0x0a5286eb6f48e334, 0x0285746d50ccfac9, 0x3f2b14533d368cc0, 0x98d7e0f13e795f12, + 0xf22335de050eabaf, 0x3878e7e4bc0c9c16, 0x64c93d1575ea40e4, 0xd42f6a2b3e5ee487, + 0x72b4e0919983e856, 0x0b5ac7c7945130d2, 0x979b6349e6b70958, 0x49bf5c82b2ce2072, + 0x90b080aadcb16cd6, 0x4c7de5706a37ff44, 0x358d3cf65f3b00c9, 0xa715eb3d34e420a4, + 0x7a2eab13cc2bc678, 0x3c9bc5460cd01b7d, 0xba798cfb829221e4, 0xfc57f3e3bfa2073f, + 0xad57dbda53fa602b, 0x456f395c7c207f28, 0xff3b4c90075b86df, 0x1c45e5898dd93a31, + 0x529b16ea2501122e, 0x9d3c6cc7b807e973, 0xa8412dbdbf54f759, 0xda40f05294ec2e55, + 0x188322a73bebc1a4, 0x99e810391c32dda8, 0xf9c0764846f1d4ef, 0x689e48dac3b3436a, + 0x83ca1caea8974592, 0x6fad0a8c722591da, 0x5f02683e25206562, 0xffbdb93a6f2d1c8f, + 0x2463e3e9d63557d3, 0x3d9f04100f8dff7f, 0x570c531c7dc45b67, 0x44a155fc3684d3b7, + 0x5b29cf8b1be60fad, 0x3d4105dceb36b404, 0xb4f81cfbd989e84d, 0x47b91e75d666ab26, + 0x24171bec298da039, 0x84690ec930b9c1c2, 0x65bc55548d5c8f0f, 0xaafd01edd529dc0f, + 0x44c2cd3b5579b1a7, 0x99a289c9c8883f77, 0xf11fa0a0ef303c10, 0xc14fdaf40717c61c, + 0xd170effc6b25cb24, 0x727115dbd9990a2f, 0x3cdfa13faff6ee40, 0x22ca00dd105e8479, + 0xf3be7c10919fbf35, 0xa3894d7cadfafc08, 0x7536dc915f4b2b8b, 0x2458e60e6228a67d, + 0xfd4caa760b4ae4a9, 0x4a9da57d176df538, 0xabc592522a506edb, 0x4ef92c271de4e711, + 0xd6db0527d8b7497d, 0xb7e5619ddf8b7cc7, 0xf893d0a79b3388a5, 0x852839ad38bd17b9, + 0xf09baa3db12d57bc, 0xd9fd9a0427305bae, 0x7867442dea63d046, 0x6a6d074561ccb972, + 0x84a33479af072b54, 0xbf4330c6b6c536fc, 0x1a1110dceb22a162, 0x8911171d1f17e5ed, + 0xfe1e9455d6aab5df, 0xeedb0cb236a1dfb3, 0xea0654ef9fb0561b, 0x31ea999bcad1e537, + 0x4243301692fb8809, 0x956d022e5ea8bfbd, 0x671f3a9ef085d17a, 0x15c521b2856c0893, + 0xc6408fffa0dd5cca, 0x3ee1546afeeff3e7, 0xba43a1ecad1bba77, 0x046d26f414200eee, + 0x8feb68803849c340, 0xa4d39e3c27251ca7, 0x5e3d493642c8a144, 0x43af7a535bc4bba4, + 0x01b5e19b3fa1ee19, 0x576138cae63535d4, 0xd96c524e3a7da081, 0x964fe5fa3eee22e2, + 0x48df1f0d0e6bedbd, 0xb5f3d58460298bb4, 0x83811186c9c83622, 0x9d80d55e653a5331, + 0xbfa91f8b5584a441, 0xf5eb02a63157dcec, 0x8f4c4933113fa951, 0x560537f4432a7c83, + 0x25b21ef54b733ba2, 0x8530feb4edc6fb40, 0xeac3a93d3e044a84, 0xf501bf5468cd10f4, + 0x14b643b45e7afb09, 0xaefb2c65a36190a5, 0xcb6cf016dcb43f37, 0x1d240dcaceed4221, + 0xe1b4dd3e7696dab9, 0xa8b49fa0ec692eed, 0xef36e5e4502ab5cd, 0x252690d0ae40b446, + 0x8797b9745fae913e, 0x825dcddd5a8334c0, 0x273b649db916f10b, 0xc11197b0dd3609a4, + 0x4cabf16659ad19e4, 0x41add448acd1e1a8, 0x80452a199e21b1de, 0x92635f9c0d6ae456, + 0x0f8df04221136585, 0xf428c139e59a5182, 0x63f5e0b28bf2f8f4, 0x630d690c5aac3329, + 0x73f08bed429e4299, 0x02554ed252f82384, 0x004fff81e33e9e16, 0xf74dc8c0cb9ab691, + 0xb87985276c0d8518, 0x6d5a7a703b7e7298, 0xa93703ee90107d81, 0x8b0bc78b3c6d96ab, + 0x72c0ed04ab0edba9, 0x0a83c83b951a9324, 0xd6aed0b33f199f21, 0x1f0fc281858a0050, + 0x97f3e095d91f0565, 0xa0ed66ac8290940e, 0x755615e192c53c62, 0xf64823284b6f834e, + 0x98346468e242bb34, 0x7712f37e43dfda84, 0xd6fe3430ceb08147, 0x6fb5da0dadf486a1, + 0x463d1e72b3212f49, 0xbb98cbb405e63310, 0x8ec705d7dd705f56, 0x5138dea07ba88b33, + 0xe9e46a6f8290db2b, 0x36cc127a16df4e32, 0x9ca3470be2a2b660, 0xad6dc96260def45c, + 0xe95955e6ec5c44cd, 0x0f4d552091cd390f, 0xc4ea772bb6485cd1, 0xe3f89c7ce7c03690, + 0x18816e8b000830f2, 0xce359fed58527838, 0xb597ed19147aaaf1, 0x52fdf464f4869019, + 0x57b6739453ab94f3, 0x7c2d0f82db20bb05, 0x540553d1c449c0fc, 0x2cee868941b8d123, + 0x89712724e4039b6f, 0xf3549a13bb901422, 0x2c521411bfda2af4, 0x96fa1cb8012b97e8, + 0x0a95024c889edf44, 0x0a326b93261bbd00, 0xc07bd4f2fb23bec7, 0x8c1eb9cbe538f8e3, + 0xe629abdf34628234, 0x793a035e035f5138, 0xb5bb1bc01d82c3e4, 0x2b70aa2ca15746b1, + 0xe23887bc9951e0e8, 0xad6f79dfe0a696b4, 0x2656e0edfaffa782, 0xee736f3b2e489357, + 0xdb49a39e52130c89, 0x0ad26c18ecfc7b4c, 0xd40a256acbefcb33, 0x2bb471024ccf7c2c, + 0x7a622d18fab838ee, 0x86efaa814af51d8c, 0x3a7fe61d15be1d36, 0x90c1539a03dd5116, + 0xaba53e9224fd32d4, 0x11f91a35db9e4937, 0x620eb41a74fbbd5d, 0x2a89926d35bb92fd, + 0xe4d6663b2a8a1d00, 0xb62033a32c85e6e9, 0x2e65df1fe455e21f, 0x2c9b9225f1ca50ff, + 0xc089949dc0c1dd72, 0x799b0005ad8777bb, 0xe126b515229b7712, 0x93a30c959b87b378, + 0x674b93edf00c0572, 0x7ed09379591912ed, 0x98bc9e9681543d23, 0x3bf27adf8e323188, + 0x48162b4801ce3384, 0x49056d2eae8031df, 0xd6d2c4e97aee04a2, 0xc8bca618e0669b6b, + 0x206182e924002003, 0xcdd419c25f0fbdba, 0x1b17a8e96490ef09, 0x151814cae7112db0, + 0xffbdd5629276638e, 0x191cc6f20378a4c3, 0x7c28f3f2fadd0eee, 0xcafc3c90b15cf7fb, + 0x2f6df0f71df982e2, 0xaa2e167f56fcc98e, 0xb25a5ea76556c8b9, 0xe9de9325f6211192, + 0x25133961111d78cb, 0xeaa99f5860db3c04, 0x8116d92c2d550408, 0x3aad86e1bf181e1a, + 0xce2f6cbe29dcf264, 0xb21c215da0325a41, 0x96d633cbee22aa1a, 0xd224114a4181542e, + 0xab0456c282c28700, 0x9a311dfd4b40c44f, 0x8004f995e800793a, 0xd7553b24cb8076a7, + 0xe0e061893ffa0ec3, 0x274c0bba1f246526, 0xaf455bf108633658, 0x9de65a5275eaa4ab, + 0x27ddc024c23f97cf, 0xdd95480eddfb8bd0, 0xfa969572a3783005, 0xdd54926fea5feabe, + 0x6a653b74f01154ab, 0xef8fdba5c2fb9e75, 0x5c397a1236d68f3e, 0x8bb1637e3831a237, + 0x3493a4903ea6184e, 0x6c7a9ddd98929ec7, 0x67329437a791e2ef, 0xbf030f1f678f29ae, + 0x102de7adc5d41b37, 0x551bcd6904371b22, 0x5f81f3b29d304a4d, 0x3b88baf0c43f0f76, + 0x71075cf9526c6004, 0x5ce708d5d157f1bb, 0xceb5116bdecbed2e, 0xd35f93be9383c047, + 0xff0382550b9dc9a6, 0x8a431cf71f4f9d7b, 0xf0a683582281d679, 0x8cb5e8c8f738dc0c, + 0x6c37e7c50b1f9483, 0x39e49236e293738b, 0x669d4a9a206297c4, 0xeee562a4cb6dc677, + 0x8c77dba71c1bd14b, 0xd768bd1b76e48502, 0x041a1795f67ddc23, 0x2e337811c1573e29, + 0x1b0687c5b19e5d61, 0xa8c7e68a2c63ca36, 0x6b15c8bb64d89e01, 0x4e254fb2751cdeec, + 0xce3a13c5eb93ea8e, 0x26b10d71bc47a991, 0x61297fbbe1c360e7, 0xb22f4fe57a756f6d, + 0x8d7ef60778d1c065, 0x7c38b5c47ee06d68, 0xd4ec2e2ac5a4a24b, 0xde463dd6aeeff944, + 0x113ad8ab37f91258, 0x629dcbfc65555e0c, 0x377eb2d6f531de8e, 0x137f4d8ab8c5dcce, + 0xdaf4aebd8e3de00a, 0xe9f0cff67f06a67f, 0xccff83896072e3d8, 0xa63ca4aeeb1d4d34, + 0x356a4e89d93cf950, 0x2d2ebf3c785d290c, 0xf9fa8d731e1a2d95, 0x74011c34e4c59f53, + 0xc657c09a2661a0e3, 0xf5cdf9489c8df558, 0x4258b18673921c7a, 0xad75ea27eb35c7f8, + 0xfa53aba1c0b612ce, 0x43df9edf503a8a12, 0xf3df2e8928b7f35f, 0xe126e903af14a8ac, + 0x448c77627d73515d, 0x00c3f486d29e53be, 0x3c31fd93b469ba5e, 0x4fcb20a5a7529543, + 0xa3707c2f4411658b, 0xa7465250261e466a, 0xe67c4c7914d7bd21, 0x1d8ccb0dfcc16691, + 0xf4f4c8c059ed84ef, 0x3655ab2a8f1f1a8a, 0x4735b28c2855bc6b, 0x477c7d01c2a14ddd, + 0xa5118b68602bbb35, 0x0e83dba8356753e9, 0x48f3469c4f8f338c, 0xe23c95b45543b05a, + 0xe3493c2fe45bee6b, 0x2df676fa625f464d, 0x206057079f750f06, 0x72a93734503eb936, + 0xdf5b08b8f461dc59, 0x1cc511da5837c237, 0x6c8c830e31bdc45a, 0x4690d1d8a194d057, + 0x589d3d45c1420dea, 0x7b32800a5e117c4b, 0xbbb0c6a8ac3dd539, 0xd50570ad7bfdf527, + 0xae2179180a7ba703, 0x686d3b7e6d3a11aa, 0x9f0e5531bb4a5a4f, 0x5e45492bad6ab826, + 0x8d95649c36f3fb0b, 0xa7593b34d8ddf337, 0x6a2ef0ea01e66643, 0x151313da52d1040f, + 0xa6caf7cdeac31fed, 0xb906ac61d44f18bd, 0x0091b6aac33a8ac1, 0xd7047e26c6624899, + 0x54bf3e50806b22f1, 0xcc4e0288d4757258, 0x9b24cfacb00d6f8d, 0x7828930badbf3931, + 0xb27dd4bcfa55f214, 0x30c5580dc0f692aa, 0xdcb9a5e151d6949b, 0x95865a720b3fbc26, + 0xc21ca9a9bea3a5ee, 0x0c6200fd1066602d, 0xc0be40ba165812a4, 0xc311e724a599551a, + 0x592feb7846f260ea, 0x1bc94c796e634e0c, 0xe8cb8aae8e677650, 0xc52089c03b3a9ae3, + 0x6d6f5ca4f0e6212a, 0xdba99209feb77993, 0x9c5610d7d3dd2ab9, 0x43d0a23a70c15485, + 0x695864e7c65d617e, 0xcde022e53b32b063, 0x85e9081c648e494a, 0x5437fd9bf3235244, + 0x42c0574c4c69b673, 0xb494111be8da63d5, 0xa09e0f84069c5b03, 0xf608f1f5aa4d8e0d, + 0x4b5917f9af3dbb6f, 0x876db0fa77f6c1d3, 0xa82080840c5efe3e, 0xe4dcd912641a957f, + 0xe52a4f4d4cd110fb, 0x3c000b727b728f6e, 0x9e0adfd7cf7ffb00, 0x55b06df8e913eced, + 0x776290e7e64e17a6, 0x030e32251192a647, 0x914a039902606d6a, 0x614c04f2f0deb2ae, + 0xed1c5c03c896d90c, 0x81d451c79bf48502, 0xcc97a274280d67d9, 0xec0eaf51d75b35cf, + 0x1eb6fcad5ce66f0f, 0xfdaefd72db579b86, 0x8e5aae3324a5e959, 0x3233195e19d91ecf, + 0x30d9620f6fea7fae, 0xf31fd45e3004860b, 0x0c0edcf81fc88418, 0xecc829ee5d5f2bed, + 0x65b48e75e45a5079, 0x7a15e70a8eb6fdc5, 0x0987ab0872508205, 0x3857b2e4fa044ebd, + 0xb509d1cff02ebbed, 0xca16434363ac795a, 0xe72882e693f8c825, 0x035f7e69a46ef4b6, + 0xa9558e56ed4eca61, 0x8d152cb6270a616d, 0xda2357888c287f99, 0x4374954e04e75bf2, + 0xdbecad86354b644b, 0xc1be06c672d19e30, 0x36c91322cc271dc2, 0x9ed40f4909a59093, + 0x5056b2466d24399e, 0x0e6e1f4789296e1a, 0x5f27183cbc931e22, 0xdb880680ffe5d098, + 0x46df0893c2284d92, 0x3e81a40c36286e79, 0x7061fcde186bf809, 0x46393537388d36f9, + 0xaeb2bd0add3e5b59, 0xd92366c6e15b740f, 0xf1b1c65f25df9035, 0xce5c92f99785cfbf, + 0xdf83bb2c68b2a85f, 0x948b9bbffefa68c8, 0x4eb3e3d987a03a58, 0xaade292c62b1a97c, + 0x2b600e8e8c890118, 0xabc706a9da3124b0, 0x614f9aa2cfcfea12, 0x5732c90755bd446e, + 0x673f39744d5738a7, 0x285c0559a6c30318, 0x6029518c6f69a013, 0x0631fc5c12722556, + 0x55e98ba8c797a280, 0xcb7d9260518e3e9b, 0xf0c0cf17cc1499b0, 0x1bf53625e2c03c2f, + 0xd30c73614915df6b, 0x12d79e1116b59d02, 0x00e9c3801043397d, 0xba9176daa2998081, + 0xd04f8c11c1f99664, 0xdf6a14a7663f37d9, 0x13a9caae8f94422b, 0xd321b54959fbc938, + 0xf81f264e83604923, 0x2a39d22599a7d411, 0x185261ce73c33c3f, 0xbed1025475709ec4, + 0x1f99ea29eaafa941, 0xf80fdb450fe0297f, 0x2caab9371690eb0b, 0xb439a767e537a205, + 0x83657401a60c1a73, 0x47b3c98fc95cda94, 0x8c725deeb0f692f4, 0xa4f0badf18755dbf, + 0xee6c4703b1009b33, 0x66cf202576079e5d, 0x2f9d9931b10debec, 0xbb0d315a6d4c4418, + 0x72e8892188ace8ac, 0x4ba59a8981373410, 0x42fe0c0d94f05b83, 0x1025765af27db7e4, + 0x68242ec1235ddd65, 0x333349de465a4214, 0x4796e203a254476a, 0xa9943ec20f7cdb64, + 0xca62d842ebc0bc1c, 0x9efa52dea7fa81b4, 0x7a943750178ee1e2, 0x7e75bc96d11b3282, + 0xf6f691d6e54979d7, 0xff167e6ade6bdacb, 0xe22d517817b501a4, 0xc3f0f2cfae8ad232, + 0x5cff623658d9f984, 0x179b72f35493164e, 0xc9e29ca4125a7e8f, 0xa57b7073b87dfb38, + 0x947111814469da59, 0x4f726c1bf4f19f59, 0x62f2a9b090b93ad9, 0x1c67274f2b1c9240, + 0x9c54bf30fa8275ca, 0xc02a9797ebd83298, 0xa34b7bf6deccd55b, 0xc59bbdf7cb6db6b8, + 0x601025936e76492c, 0x11cf23352115a0ef, 0x07d6307e827758ee, 0xf9119a7342433928, + 0x5bf3cb63519a6cb6, 0xb3aef6f3ce0dad0c, 0x30a98f4ae0d7dbf9, 0xd54ba528feb44aca, + 0xbac183dd40082f35, 0xccc44655fd44514d, 0xfb201d475c95a68a, 0x2bad58d15f1dbae0, + 0x7a67a4e82aa4a661, 0xc9a9043382c08334, 0xa820836c3f04b087, 0x673e3efce460dea1, + 0x186538b4ec679360, 0xd5d4dc5b85b2a834, 0x654fd0a343ae906f, 0x12c4151dbf17b763, + 0x93f373299029a955, 0x8ec35c9846cef520, 0x1996036f503a7706, 0xd37721a4173041eb, + 0x4adb731975ffd143, 0x975404dd1e4ca03b, 0x75be4eb9553a1ba1, 0x38b5d1b974e44a95, + 0xfeca3249460fbfdc, 0x0d911dc52b543fca, 0x76e69494d0ec7c08, 0xbecbeb3b4051293b, + 0x6c7aa918889baa1f, 0x0eed94d0f8c930ca, 0x9500706287a6d0b0, 0xe0670e76961e0080, + 0x4508847afcf55204, 0xab6d8ae202ea29f7, 0x813361acb8697ac7, 0x54213569bacd86c0, + 0x613e224f4cf431b0, 0x8d8b983bbe52e6c4, 0x2a85d5e738aaad72, 0x5bd7abf48694c069, + 0x0248875ab841cbd7, 0xe81843076adccb67, 0x34648c0e6fc49dc8, 0xad13bc6be34bdda4, + 0x5cbd2d2852261889, 0x903b96294f5d2464, 0x990e911bcdc4a2ee, 0x9517753237983fe6, + 0x3f167f8624f36676, 0x5766b690acfb60b7, 0x812ef4067457d618, 0x848c5fa2351cedc9, + 0x575323a752426251, 0x4472209fe40546d4, 0xad1c9247b43652c9, 0x8256d98202673bfc, + 0xe4ca34106e46bd93, 0xbf8445f06e66e51a, 0x1eaba756e2ce11e2, 0x47e8a6dbd3d1d057, + 0x2694b5e8f9948065, 0xd86adbad206f66d6, 0x89ae618fbc42e9d4, 0xb272617d606d715e, + 0xc9eff4d76d9737f1, 0x8580e5817b8e56ba, 0xc054c28cb73416e5, 0xe8418937c30f89d0, + 0x9422058ce6e0f421, 0x8185208436b84427, 0x9e57f903c9d54f4a, 0xa1da3ad20f21720c, + 0x6f3920470364c70b, 0x7267de41e5d7cd47, 0x951cdb18370a99e4, 0xbecd7d1f7e0a62b0, + 0x1a731ced4facc7ec, 0x6a6478589a8fc230, 0x8e6f57b28032df20, 0xea4dd836b8d3fecb, + 0x37e1017a589ddb72, 0xc8f231cea38ca605, 0x6552302293958337, 0x4290b506481e953d, + 0x1ddacde8d684b070, 0x7288e9cf714f3d36, 0xcf5aa4b2ca9b1fec, 0xc612369c24643b43, + 0x4e5d5fafbf2ab94a, 0x53d4e552bc186d0f, 0xa11c79b1e1e701a3, 0x3fa6e9e50d026cef, + 0xe0275611a015bea9, 0xbe071a8805d338e3, 0x777142776a7cbef3, 0xd1ca68784e718622, + 0x7beb0ecd135f983c, 0x46404ce42f971bff, 0x24bf336ebfcc1290, 0xeb43630435a0166b, + 0xec69c4308ec84c37, 0x4c6ce7547f2f641a, 0x5d290951044c819c, 0x1a2e42ee1c7f89c8, + 0x85dcb83be15aed49, 0xfe2b45cb1036204a, 0xb622d1ff29106f98, 0xeb7d494e19eb6cd6, + 0xe061be72d6551a09, 0x0478d97f943e5252, 0xf610cf18809b1702, 0x3135fe3f9fa657db, + 0xb7e65f1cae7b6f46, 0xcda1555e9af90dec, 0x9f976411eb12b0dd, 0x21269e112fe88dc8, + 0xccbf999057a3682b, 0xb974d9bbfaab3c4e, 0x349d10f77d9b91bc, 0xa2160e7f19e30f42, + 0xd41092d2a3d94a98, 0x859ef19d5b10161d, 0xf938cc3c8be4c82e, 0x341efbd6d6fa6bbb, + 0xd10ac4cd23699c9b, 0xf54856acc30418a8, 0x444af70c7605db54, 0x576fb121056e8397, + 0x6121d56419a02a11, 0xbef739c4c0bccda9, 0x6923dfd76c0b2e27, 0x1ba06db8b35f9416, + 0x27770017fae68c1c, 0x352390ad1fdd6738, 0x6dbb47a15c3194f6, 0xb35f51886ffd1260, + 0xcc2c4cba311f074f, 0x7548409855f955f7, 0x264fd1a4e1f5d6f4, 0x1342979385fa6c05, + 0xbaa78427d50336cd, 0xf96f93564a48e068, 0x0e5b0484f96c3068, 0xde7a01ba132e8bef, + 0x6ec689a5348a3c60, 0x7c84e96a97530a60, 0x379bd9287ef5e3de, 0xc4579349937e0771, + 0x79d25571fbb5c63c, 0x508e18fa051c858d, 0xb721ce76f227e74b, 0xca6fd945a03a6af8, + 0x7ee8f804c032dafd, 0xdb95af1f5f696ca4, 0xe092c16ca2e3085c, 0x591ab06e78e27ddc, + 0x03aac4f937aa88bc, 0x7ec6963d125a801d, 0x81712f03e0e452b0, 0xdcadeaa3f229005a, + 0x3810ee5253f86e92, 0x17f6b7bdd79f106d, 0xc311376262ecde17, 0xabe3f50206a1307e, + 0xdac7a2a68bab66d4, 0xbe0914e326910021, 0x1410b04d1c0478ad, 0x7686036003b45a9f, + 0x0b527bd9e826e01e, 0x29992bc289821fb1, 0x753df71ce8994b8d, 0x6a180d92845eb84e, + 0xcfdd13341cd3e83a, 0x562858feae05e64e, 0xc423c5a12ba15860, 0x4bd34f3fb4029ccd, + 0x38500c984d4fad2f, 0x6903a8d89b94a6c0, 0x6170de4c039631c1, 0xb614adf60d0466b3, + 0xb0bfecbe98b4c80f, 0x597a679c82807d59, 0xc3f8fc73da4c2209, 0x3394fdfcba20f57e, + 0xe44b0bc10a99e77d, 0xdb78a47567751de8, 0x9bd751096b243ced, 0xfcdd6e491aa3154c, + 0xf6bca65eef18f0fe, 0xeae9d07fd41bab3d, 0x4a6ffe28426b2afe, 0x5e970e7f3255a78c, + 0xa4e54566b09e2b3c, 0x363ade46e6933ee8, 0xc57c04c214152b1c, 0x2f2e2b2271bab939, + 0x73817b1f5a5f8776, 0xd1f525aea579e536, 0x480980085815aad5, 0xe6d356a140f76bb1, + 0xa8a0bc3070cfd5bd, 0xc31092e66c35e567, 0x79e2da0ab816295d, 0xc04389f7107a96e3, + 0x7c914cdc15635a2c, 0x6b86d21725e768e5, 0x72e2584504af1fef, 0x15538a27564f28bc, + 0x67cc8d243e224aab, 0x40995dcff1645f4a, 0xf107e2b99228d84d, 0xdf4ddf11c7ae4930, + 0xe17a63055d810887, 0x98ef7ac14f6fb93e, 0x161409e104f6e12e, 0x7c2173c58d841e01, + 0x11b28a03054cf9b5, 0x228be8e9cbf13fed, 0x6805bc0f31fd78cb, 0x022e2fd7a2ffda4c, + 0x566be2c9d4d9c96e, 0xf5c8ea76785c246e, 0x3065f7f6bb78a576, 0x7aaa870c28c99114, + 0x3e84c706230e123d, 0x05944ada658193b9, 0xc1e929e56655e872, 0xbffd75e53659461e, + 0x06ea1d837f0c2f83, 0xe6819115bbeb9d55, 0x592560157eb09eec, 0xcff371fb925b9754, + 0x9bbf432d396e6916, 0xf1bb953242efc631, 0xe4323310703d11b8, 0x0381d3f1f3e50141, + 0xf92c494f8d876aef, 0x692ca186b1c08a51, 0xd10b042555097c0f, 0xdf0e666f44cbb618, + 0x1f93c52266618738, 0x627fbe2d5a6b5737, 0xc6bee7fc416ee1a3, 0xd88f7f4c57e05f88, + 0x337ae0e7b9a93815, 0x32c61f4b522cf347, 0x63b6da1447895641, 0x391feb027add0b35, + 0xb78a16bd38368941, 0xa0c1f196eaa0ff18, 0xaf8a07fea53c1e1e, 0x893ee13636aa6c96, + 0x202ea2215318c5ae, 0xb97334a657056882, 0x12a53b107d97d193, 0xc080fbfb06cc7f8b, + 0xc2d8b463f27b0b68, 0x8c87763a9ddb31b7, 0xcfe0e7dc238f6a4e, 0xd23cd37e3da44e82, + 0xa97d4c62dc6223fb, 0x373f8f780172deac, 0x0be49a0bb9d67509, 0xaaad651220db5bd4, + 0x1546f63e2a1f13ba, 0x8f3d0e8a145032fe, 0xd7f5573cbd6ebe37, 0x291088784f8448ac, + 0x85e4255bf05e4245, 0x644a84307cac03fb, 0x859da1e45e2b75ac, 0x9fadcfcf422e761d, + 0x781449ebbc4c70db, 0xc3ea5049297ca356, 0x577d32242cde8204, 0xe250dfcecaca36ad, + 0xedc082116f367a07, 0x8a6cbb131008e725, 0x2aa6cc866474e2e5, 0x95bc97e3c82e320f, + 0x679f4d9dd88929b2, 0x71124e37958792da, 0x4ab3ebbc695f9ebc, 0xab8f80704ecd9297, + 0xde8e3f052dfe3dff, 0xdac780542c7eb6df, 0x6ab7e8884670bbb3, 0xf563589a4dbe1b91, + 0x58d3a86ee0df7d1e, 0xb30316d424975032, 0x74fdf277548e9be7, 0x626330b5625e1996, + 0xee3c0d808e37ca3f, 0x213f9ca29d8138bf, 0xe4930dc245d2c4aa, 0x1a05694e6b9b7c7b, + 0xa39afbd5ee949689, 0x48b3d1325158eb6e, 0xc78c0ab651e45fc6, 0x32ad9eb09f7b2366, + 0x9704e110323b5938, 0xe04b4dce9ed51298, 0xb6d93d21fa6ef7dc, 0xd4d634e8a8ad5dae, + 0x8433cc979885ae49, 0x8bd938a061cf36c5, 0x07bccb3c4b9c1384, 0x14761a82db6c30fa, + 0x04dfdeb63479eb6c, 0xf77d2d8bfe52960b, 0xb7f3a0c3cd3bef0b, 0x2e8188985379b0c1, + 0xa24b9ee3e34e2149, 0xc0f2a7177d23dc5a, 0x5148da475c1c2dcc, 0x74ba16bff2e1cf9a, + 0x8e73279f56ccd257, 0x31d246f73d169729, 0xa6f056d8818f000e, 0xc37c3a81996eb824, + 0x290a699c1c714803, 0xc10b5f1a5fb805ff, 0xf89050dc1eb91fa0, 0xf62f7431d4603290, + 0x72507ef2d4cbcdc9, 0x62e7eecfbeb72623, 0x406d5df2d538e135, 0x236adcd937de320c, + 0xf537ad192958f8b5, 0xe720429625600657, 0x10075841f5c5f6aa, 0x8b7d5431d1cf6e84, + 0xa8c146bdac430bbe, 0x80b8be51018a3445, 0xe50da522a9c721e6, 0xaf2c2ddb5e1cd8d9, + 0x8e7f19aeb5b404a2, 0xb02c9ac19f308180, 0x4f35d045eb853cf7, 0x7740202596e5928c, + 0x3a2be11e275a4e84, 0x5006379559132fb4, 0xb687de7abc399d67, 0xd0cbd5d8f82c85c5, + 0x67585602cdcf5250, 0x2ded7f38995dec22, 0x2f3a5d7c0789ac68, 0x65cc7774b8f71642, + 0xdc8079ed31b82b05, 0x68502ac6f99f6888, 0x3495dcfe810e2476, 0xc975c5a11c563a3e, + 0x284b6119336e009a, 0x0e034b9abee60e89, 0xd3e2f96fc092829c, 0x7edeb6cc9517ac78, + 0x29273a0fdda9623e, 0x476207fecb6c8264, 0xbf23425d202afeb5, 0x1c671b97a879b14a, + 0x64ca2ce5731f0eab, 0x564d544dce025f53, 0xe32f67379640bdb1, 0x5c9e8e6ed89095f8, + 0x7f8fcaa339611d52, 0x24fb9dbb39f416cd, 0xce620a391101d27e, 0x3a1d0e8f082c79ca, + 0x81439c3862231578, 0xe8c877efdcbe869f, 0xcf7e69883a89be75, 0x4191e2288601c14d, + 0xaa868c8c2f552a2d, 0xcf3d6b58b42ef6bc, 0xd37dffaecef7afc8, 0xa9426f8ee9aec446, + 0x8e39f5fc60e903ea, 0x3590984c05ca08be, 0x459f315beda092f6, 0xab1a7e4827b36dfb, + 0x4a89b6136f22a2ed, 0x74aaa2cf359ef6a2, 0x114f48fb69426ced, 0xfc3d76a9d8b9c07e, + 0xf9125e090e05b205, 0x1abf34d821f56432, 0xd85b0267a003a838, 0xe71796e3df88ecb0, + 0x030ec94db5bddcf5, 0x845f2cc307710e17, 0xf038809e87799bab, 0x9e54826b9f6ab1df, + 0xbeecf9ff61fc2a22, 0x65ca36be408e4935, 0x4264689e0e0013e3, 0xbf86fa3472597f13, + 0xf9db9d08a8c3a50d, 0xfa93b5312e9b3004, 0xf30d04e249136076, 0x75b68ce41fd7e2ce, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68a88405ae53c1e9, 0x51e46707fd558656, 0x71e834cf86896c10, 0x3d251b54e10d581f, + 0x1884d5b0eeb19032, 0xeeaf729853e526fe, 0x5931f6831a8d8c11, 0x87891d33fb98b4d8, + 0xb487b5255ba8a18b, 0xaef785edb2d976c6, 0x8ac084b354d5c019, 0xc714fe0a7e7cb0c9, + 0x272b34204b9086a7, 0x66d421662f652954, 0xbe640374928d3af4, 0x7d3257b3f0553a6e, + 0x4f1d9b4c437a08a5, 0x11ae3d72e0e1e536, 0x6e7924dc694356b5, 0x6e9ecc765f59086c, + 0xde6d6c65d7a5a821, 0xdd931ceaf6a11453, 0x6a175ae7c1e72630, 0xa9bc5474fffd9cf6, + 0xeeaef3b448525ec8, 0x15008c9351c8bd2a, 0x81b3090c5ee3e61c, 0x01767fed76e01382, + 0xb6cfaa3c6b39105c, 0x36e7d0051c456721, 0xdae50f00fa46dbee, 0xe965d41c883da319, + 0xae3791f2103ece26, 0x1ba533b9e8c869f0, 0xa65abccce40c0a4b, 0xfa6915e0b76276a1, + 0x4feb7b7a96c8a36f, 0x7f49425e7e54bbaa, 0x74911044655a6d3f, 0xcf46469a6114d216, + 0xa2f5106e2a65f70a, 0x5bb57bd0c4d8d1ea, 0xf8465cb0f73a0bab, 0x8011828ad5716c05, + 0x2b64be22994f2908, 0x2a247946e673e7a0, 0x87a2f13d788e0d87, 0x0628e8ab5b721f18, + 0xdf60eda1163aa13b, 0x6a3d7af1fa7bc9d2, 0x3f8b712461d47f9b, 0x64363be32bbcb36e, + 0xa0df8815f0f98d15, 0x5e9cd01f29a9b5c2, 0xf5f24fcdea2f8661, 0xd427b3c4db6a676d, + 0x559b2ef1191938c2, 0x0904120044e6619d, 0x9b412237d49e8c08, 0xa9c7b33ecb50d796, + 0xce71beaf6d1a2066, 0x05982d236e3699d4, 0x7ef041f65bdd5dfd, 0x92f71df57e10e1df, + 0xba9fd98804b12e39, 0x3eb4d11bc6597636, 0x74a95561edce0538, 0x364c98dfe633b663, + 0x96331a38044d02d5, 0xea03f85842a6a6e0, 0x7f11713d4acd83df, 0x174cd4862b09b207, + 0x9ac99fd99d293746, 0x829088bda918704e, 0x1e25e23ef32adadb, 0xb36ce3bc545c430e, + 0xca4dbef135fde2cc, 0x7a09bd725ede630f, 0x0a7653425c86d27c, 0x2fefac3ba6c76189, + 0x17f29a0a93b8dca4, 0x087c1e3cdfccc0d3, 0x540dd8131ce016df, 0x34c138326824e27b, + 0xfcb24127d7126e93, 0x9700d6148ea2ce82, 0x7c74c39eb552bf19, 0xd3c48f611dc32059, + 0x4593316f0c9ae54d, 0xc5e9cf2a76cec102, 0x5031874bb39954ef, 0x6277fc4b66783ff4, + 0xf8efc66553113921, 0x922cfa1c2729fc98, 0x87a2bb305b22b9f6, 0x16cc00ce83c32c58, + 0x5a0c119889d5b87e, 0x83386168b33d3709, 0x4725a7bf1ce70257, 0x4a69de1c9053da04, + 0x5a18c5f56e4ff0c5, 0xb7d5bc335d7fec62, 0xee2842a810e1d7f7, 0xf8029fcb04514984, + 0x44097e987d384762, 0x1f670486da26c390, 0x2b21e4e65f6b7249, 0xfa846aee1c1822f3, + 0x671bf2cf4ba94153, 0xb1b00cce1f7b6a0a, 0x866874dec139ab19, 0xe1da0d6b89a9a65a, + 0x45e8480cd67f43d6, 0x472ae5aa72d8290a, 0xd14fb4eebc9b3f1f, 0x05e2dc745167e7c1, + 0x0759c43bb10d7a36, 0x171ced051dc4aeb3, 0x8b8ea8b911fc198b, 0x331b01c9195af0c3, + 0x44b0770ae5e09db6, 0xa5f622fc48e91c17, 0xbda14dc3486cc341, 0xc8cee9fb6ecd485b, + 0x4140fed8ec6d03d6, 0xa94955e3511aa5d7, 0x0d579b4bf974f83d, 0x7507573ecb8d959d, + 0x666fdeacfc793064, 0x6941efa8f1b5ae4e, 0x110daf8ef142d048, 0xd98106b177caeaac, + 0xeee1135cc68e8ada, 0x9a9661094c3b8b59, 0xaaaf6f12b3423c40, 0x08ac7d1e1576e043, + 0xc03c4ac1712d1d66, 0xc14b5354034d9d1b, 0x9b76dc0dcf104c94, 0x9be1a977cb012a82, + 0xc6c1137efe5f27cb, 0x137e94494e276707, 0x877dde2cf9338d7b, 0x518c11d72047a052, + 0x99a4649fd1969cae, 0xe12ad8516f5dfe24, 0x5c7b37f89a048969, 0x154226b3f008c0aa, + 0x658c164a8eebcc68, 0x4dd70568e89ec7e0, 0x4c4b2929b9a9c007, 0x6159bd57c3704eee, + 0xc11792c0c04fc58f, 0x2750e1ec3c5c05ac, 0xa3e8ed0200e723e7, 0x95a8b8b19b536312, + 0xe66ffcc92c3f46cd, 0x91c4fd71f7f83e48, 0x4958d79605512469, 0xe2dab1909168da73, + 0x206ad23714748082, 0x16864ebb5656fb09, 0xcd681f3f66c33fdd, 0x9f823c45f2484ca8, + 0x448cdfde0e625e57, 0xf804766df9c4599a, 0x1aaf20ec9381cc0f, 0x7dc00124d1863e2a, + 0xfa1cff77a4bf3270, 0x8a9b34cf02dd3fcc, 0xe73230cf7e5794d1, 0xb4b6d4a7ceeea784, + 0xdcde4a7169d825e5, 0x2464e3573aae1d86, 0x4fcf1ec8fa532c0e, 0x894e984daec0e65a, + 0x1516b3acdc84f46d, 0x4b5b83c08eccbb45, 0xe9c7852f64a4f99a, 0xc350e55f1a837df7, + 0x1e56f15ac7b78181, 0x19088cc08abdac8e, 0x6270f5f100c2fff3, 0xeb9247065be9cff6, + 0xedc22969d1c97abb, 0xe96361618325e027, 0x0c72b206cc0738f6, 0x3329aaa4346397a1, + 0x8541c9611d60e115, 0xc9c80cbfb4ef3c7c, 0xe9000b60a281ab77, 0x2da579151532c076, + 0xbaca9481a2782c62, 0xce6ee589779b618f, 0xd5cb1989340aaba9, 0xc195090afd1670f1, + 0x2611c813d09b50d5, 0xdc02ca3b2670ad05, 0xdb5a62ee2cad3f18, 0x883f0994bce4ea50, + 0x4638f49f3bb23b52, 0x32c256bf67046a20, 0x29c2aeb570a48f47, 0xcc60711f19e0b32a, + 0x1c75d49f6895f302, 0x8b4bf4d57aed92fc, 0x15b2fedab168372d, 0xc814350db17a4e30, + 0xfde4daa4722af3f3, 0x6aa6e92f01e9e122, 0x6390e377a5bb073b, 0x2799338a6574e8b9, + 0xedd5131cb43fc739, 0x9bdf9b56f2a578d9, 0x150b15947f700c4c, 0x73a15063b16c2cb0, + 0x1a29a94672580154, 0x7bf2e8016a8e7037, 0x63d81bd80cf07515, 0xa71c95e84eb71cb3, + 0xe0ca1c960020fec9, 0xf4365910240825a7, 0x58d457e1bae55016, 0xea58a44649268fda, + 0xc95910b3e9178463, 0x26ca556e98942e1a, 0xd5d9f1db827da3da, 0x9bcd8fbaa47df5c2, + 0x5ab9f787c3c0b49e, 0x9459c256614eef41, 0x03d9c4d007717be2, 0xa65e973a6390e838, + 0xeef59a8e2c6d0400, 0x5903c0e9b3cfb489, 0x01e63ea530389f56, 0x7c7bd36f7c68056c, + 0xede6ca105864a242, 0x12a0924cda935c12, 0xb13fa1ec336f1cc6, 0x3a383db45c2c8df2, + 0xc48689e87fe0bb90, 0x3ad354a4e2041fb4, 0xb43005598d6cc969, 0xe88ce9a3b0a7e8a1, + 0xc8b24787ac4ad2d4, 0x44cf7f2f67646bb5, 0xe58c5d7a31f11361, 0x2be0271f13e8b84c, + 0xd968752ec676c556, 0x2112bedba1fb3fc1, 0x2d138123077fc1b2, 0x6fc0527824c7feb4, + 0xc1ed0b5f443eeb16, 0xc779afc4543bb154, 0x7723661541dc816a, 0x1d6e455db4c51246, + 0xe3f5923d012b4413, 0x3d31546585916da8, 0x77c15b5d5393499a, 0xf735e16b346dddcc, + 0xf350d0d5aaf10353, 0xc2ea2fb3b94dbe71, 0x0653a193e6a96f1c, 0x52f61850bd61acca, + 0xef0090312f32250a, 0xade071ff88a7aebc, 0x2c4143590a305d7a, 0x8d44fcd721daa8e7, + 0xd926d33088977806, 0x936a1ca7a85e29a9, 0x6d064181ddc15b26, 0x3efb8a39359cc3ae, + 0xf092e887ed81d300, 0xb8968b4b8f29e2f0, 0xc6c670166e6d5702, 0x1320e07cc89889f2, + 0xa02d12fec9d43f0d, 0xdb249650c1374ec2, 0x38a542341249795d, 0xa2b6cba8e26057ac, + 0xf57e5cf5c5431e62, 0x7c6eaaaeeb9d8237, 0xa584ff86a6ef5fa6, 0x38fd0ab720a5f83a, + 0x8d09831ac99806c1, 0x810261309bc9e1a2, 0xf2b6c665885111fe, 0x1a2ada0cea61d19d, + 0xed66bf575f3d2195, 0x9720b6d0d916383d, 0x1aa3861ce7c3e810, 0x83c63c49056ba786, + 0x15509e059afb8423, 0xe27fb0ae655af55b, 0xb9ccc95902017ce9, 0x4b99244a08c8a245, + 0x913210b2285dc912, 0x17b2952d51137be5, 0x267165af3028a815, 0x25fc497ba7448a37, + 0xa0c438e81e940b3a, 0x239c637315d9e0fc, 0x43cfb0956874407f, 0x4d925bf477e85263, + 0x8a59448959e6e14c, 0xdd1bfbdc4170ccb3, 0xb60c94c8b4bd266a, 0xe374b6b5dafdfcd2, + 0xafeae0fbd611a889, 0x3a33abd1351447cf, 0x410fd647b3f7f350, 0xd16354bcef59b7b6, + 0x3725b51f0ac33c85, 0xc5261224cf7040c6, 0x2d8d2bd90ea31036, 0x6600bed1ee3ed81f, + 0xdafd1254f4ad0b9b, 0x4547d4bb47ff955b, 0x92923d77dd27f3cb, 0x3fd86bfd2e6d5d54, + 0x3e1370b411e2d71d, 0x12d9f9827a09b233, 0x5c5590c579f8c437, 0x28708dd608f1b261, + 0x635d80066dc9f205, 0x7963478b72042708, 0xb5b8fa60abc809a5, 0x17ad37ebe8b3994b, + 0x1742aa93c8cb3bac, 0x4ac5c070ddce008f, 0x2084a97f81f6e8b7, 0xb3bb55112cedbef3, + 0xc2174a405789a7ee, 0x87f9677d909e4dfc, 0x0b7af2c5df902825, 0xd9a219447a133d35, + 0x28fb55da9cf9b883, 0x31a4cc967647484f, 0x3737d752bbfef251, 0xd31d8d7dc645663f, + 0xffbba32e24f1f14a, 0x686ed5401a22fdee, 0xde531f96923a7ed4, 0xfcc7b3228e4a95b2, + 0x98c7bdaf44a1851b, 0x1f0281277a70c2fa, 0x4107223f6745b389, 0x050305f649a8e72e, + 0xc848f30952aea81b, 0x016233fd3524c5bd, 0x56dda3621f0dc8ec, 0xbf7fb461d4ad8321, + 0x07f13c5900a2f2c2, 0x5a7e401ce67e2fff, 0x591f29c50a1a6a02, 0xd306aad8556b23b4, + 0x1beb83c9a4391776, 0x69878af5ef6b65e5, 0xeba7fc9c9c450800, 0xf66081bb88787c13, + 0x4d8928d2473f1e9b, 0x41eefed7adab87fc, 0x96b2d91c7ac490d6, 0x030f0d32712d7200, + 0x923da55916ad0675, 0x2abb3c0e7a92e6eb, 0xc983d6951262d7cf, 0x966d29eecfb2a585, + 0x807f205a8a263b90, 0x4ab58b3a8888c805, 0x8987eb7da748219e, 0xe24b69cb89abfe2c, + 0xc8b1ed3594476d01, 0x9936f86417a376ab, 0xb9a1e220d4c73b5f, 0xaeabdc57301ed215, + 0xab93f40d8ee8bcd6, 0x18d57cef8d76c4bc, 0x99ceb630ccb5e003, 0x2bf9a013583d0b91, + 0xfecdaf141ba73704, 0x1f1b2727fc548fad, 0x49927d8a552c698d, 0x0e964d3810d60b8a, + 0xf6f22eb5d55407b1, 0x521ca44e9e6f8141, 0x36b72da00c7ac3d2, 0x08bcc8ddbcb8b0ac, + 0x82adce5f095be780, 0x347d5557d97303c6, 0x809fdb82eb872ae3, 0x32542bb150a4c6e6, + 0x94af1390dbd6e6cf, 0xe17b6fc1806c6651, 0x201e35edb4c9506e, 0x2f290f0de69e6bc6, + 0xe4138a63f6c01e17, 0xfbd906a46f6424e8, 0xc7aba38db2f28da4, 0xc8ecf19cbcefb769, + 0xb6a8533d9c7744ac, 0xc2f45bdc87c66b40, 0xe3a786221187073e, 0x1a2e332fe1f49af2, + 0x5c8b724d22463cae, 0xef903c277473111d, 0x2ecfaa108f04eaa6, 0x64021e3fe0bea4ac, + 0x7d9b195fe3f0016a, 0x8349a989cba17e6a, 0x778fa84eb9848b79, 0x7d5b0910a0d1daa5, + 0x099a5a3ed46d0e2c, 0x7605ebaf3b98adf4, 0x44b6712f212e4a0e, 0x7256a2cc104ed9c2, + 0xcab2a696e71328f4, 0x52773cec651b38b8, 0x0c5b020e58a0e705, 0x71739ab7c3e5dd4c, + 0x04bc54f524015657, 0xd80c97aabd974030, 0xfbe0803ba7213b44, 0x885347f8e756d3e7, + 0x7170ddc4ddd41bf2, 0x9f875418829c1f40, 0x320215bf9ca5bd79, 0xf00d3dcfebb21285, + 0xc19c84689053c550, 0xfac80461c1d7f9db, 0xddfc1cf206524809, 0x1caf44508e360343, + 0x1eedc25b6b3b8be1, 0xf91e79c23c591682, 0x8869c24e0574f9c6, 0x84fbba5733bf4eca, + 0xd3ec6e3a79017943, 0x5ac275cee135b8eb, 0x230f3fd1279ed028, 0x7796111faba4ce12, + 0x1c1a08bcd43f1973, 0x88732d942367ab21, 0x01e6f6fa5f065f47, 0xee45eace122d031d, + 0x9c017c86b13f1199, 0xabba94829fab9987, 0x6905db2612d71133, 0xfbc7990ae35b5ebd, + 0xe093a488d0fd85e0, 0x4a5dd52368442e8d, 0x6cfa40e05cb5cebe, 0xfcc30f2ecc5cdfe4, + 0x0aad2f4ba54db069, 0x851eee93183f0058, 0x5674ba1c578d3256, 0x8b3cdf56eeedecf6, + 0x5f34f5352d13953e, 0x9cc34c071ed95111, 0x77cff4d3730fb35e, 0xdab386c79085f993, + 0x0233e4294e5086ef, 0x62f3b2288f05f9a1, 0x2eb73f21143c6de0, 0x95714b93854269ac, + 0xd73eef81cb898ebf, 0xffcf1caa79c9e22e, 0x5c58fbade23d6815, 0x5f04ead32e992f7a, + 0x3d590ea15506cf9a, 0x5c921b706621a15f, 0x92fc778ecf6cf59c, 0xff4dbb69f3f7c5d8, + 0xee275cc8270da58e, 0xb5989ebd08fc22c1, 0xa380338ab1fc4cbc, 0xc27c6ee4fae33d41, + 0x63c3e130e2fcad53, 0x8eb819f33fe7bcbe, 0xd7c6dd9b08dc828a, 0x86d6febb7ae12048, + 0xbcc2c09dfffa0bc1, 0x6d231c8beb49ad65, 0x6e21db7410e88407, 0xdbc4375428836d04, + 0x54b5c871999ddb8d, 0x98847b5cf87371c1, 0x350048d90c58464a, 0xcd88b06d02f97620, + 0x6529d1fca6eac1f2, 0x059eeecec8cb2dfb, 0x41d91847932b05e1, 0x1e7157e1b2cdcef4, + 0xcb20c89fe11fed06, 0x9958e95c96c58c22, 0xcc88b21dc1fb1691, 0xe02419263109b22b, + 0x63dd28130256f643, 0x476760144540adb9, 0x5c5aa45ca95a6dc0, 0x36d60de6a2ebae85, + 0x8ea0e21e999aeef6, 0x33cde8655659711c, 0xa09a6098a27fd968, 0x586793c00628217d, + 0x98e2c995100db5dc, 0xf4f6605b0c4d444b, 0x988c39da3f8866c4, 0x8708f33ea531970b, + 0xd9dd50d2c09fe1a7, 0x64593f962e50f5e2, 0xcdd32fa1e8f5498b, 0xe1f05064b245f00b, + 0x8c61c608aa8291dc, 0x3bfc23d4e79e2638, 0xa17cdcad16680907, 0xbf464ad0f058ab30, + 0x97d38fe2519ccf5a, 0xa83defa9c0ab9691, 0x2a469a3ee422824b, 0x6d62b0ae6b395270, + 0xe3adb450f2d9eb6b, 0x24c8819d67bea704, 0x6a1d3b214030d765, 0x2a1ceffbbff67252, + 0x6f2a0ffde3ddbd5f, 0x108131b0fe3d544e, 0x72e55493d522e42a, 0x51ce07e48936a2e5, + 0xb2fce667b21b5f96, 0x05ef35e3844a5334, 0x0ca52cd5eb3e98b7, 0x2ea9445011d02927, + 0x682d9bff42223dac, 0x9ab62eead52d669a, 0xa71bfefdf7253405, 0x4e1c99333977644c, + 0xd6b72acff8c6d81d, 0x71695a880b0c5ce0, 0xdd8d32c5f1abe8ad, 0x73ac774faf7f7a5b, + 0xba2bb0ac26556d2c, 0x6a8cdefc90555f9e, 0xdab29491a40ab6da, 0x0632fc8aabcaabdf, + 0xd8918803e880fa06, 0xdc937dc4ab6f44e5, 0xb5d82efd01e65f80, 0x7f95393feb9b8660, + 0x4c5bad032cc2623f, 0x9a030c322d633a3b, 0x984e84086b79be3b, 0x5e2c1780eb388af4, + 0xa4d41e7fe5893be9, 0x7c249587365effc5, 0x5d3ee45dad75375b, 0x510abe8f0e5fb860, + 0x6d04173f67c4c29c, 0x42f0d659eae864aa, 0x4decd9d561108165, 0xee4f43427e1a9429, + 0x4927700ce0db95c2, 0x67784819a4540612, 0xfeba597d843be1f9, 0xc7936293f68aace5, + 0xe96d9272c9f96973, 0x20fd99c1bea43974, 0x67d1c6f8a8bf3a48, 0x10e6a50579651104, + 0x9cf2623c1a97e865, 0x0fba96c5f7d4475e, 0x8d963b9baa6bd223, 0xd8a882157909cfb6, + 0x97a217a4714d5fcc, 0xe7cededc7cbbe7d8, 0x539e4f876a685fe2, 0x5bf162fe44c20d78, + 0x8c1c7e2d8f3a35cc, 0x165798ef2d27c906, 0x8ff0ac3d0baea43d, 0x15c6574c6634b946, + 0x8030d54f34e176fd, 0x4cd867028f0a841e, 0x4856fd154d228b15, 0xb23b9d24a8f01d3f, + 0xcc3dc30c0f926156, 0xca9a3d3e69c977a1, 0x9278c6bc92b0c072, 0xb825e59d380aecac, + 0xfc853abf77796adf, 0x576d6f8a66dc0758, 0x1ce36d41d4c04fff, 0xfb795f91b155b44f, + 0x324ef6a30c9d33c9, 0x3eea5f01cab7def9, 0xc20cfacfdac4f956, 0x6f333838edc580fd, + 0x8320bec2fb4ac89e, 0x1c21f074d8bcae96, 0xe861e816c5b2c8ae, 0xb720642b9de41d7e, + 0xfc80b9a54b1c6500, 0x71e0a04d538a944c, 0x22fab65c9968a861, 0x676693e907111a66, + 0x63e6ae888168b7d6, 0x62199b5cc8459a70, 0x832c36acbee483d3, 0x5f7f4cd3ac7a3d01, + 0xb0743b49557e31a8, 0x5a9248e7693808ee, 0xfcb6c30892c2fcdf, 0x470d861e9bc6ab17, + 0x09ba01bd0bcaae85, 0xa9662f2750be63db, 0xec39f037c87cc532, 0x278c7a9e11299954, + 0xaf2bb95712fd1dd0, 0xaae4ec68a753c9b9, 0xbd6debf0d0227fde, 0x9735e7f65b2a5bf6, + 0xc53467e1869f2c5f, 0x8d3d61840239c44c, 0x02c253599c8c0d02, 0xca3a62e38b8cba89, + 0xbb7f2865d464df84, 0x303c156b635ccab7, 0xcfce0b2fa7ec7537, 0x7541c60dc645b46d, + 0xe287edf8277deada, 0x39cfe221e9623cfb, 0xe6f15ee7e8b64dc5, 0x65e37075223bd467, + 0x00191bd826560028, 0x66d2fa787ea37b13, 0x2ccdec590a32f4c7, 0xbaf230752dbf5d2a, + 0x132c05c75c73d62c, 0xc61e235e193dc690, 0xd2c06c30b10cf51b, 0x5c09ed6813408ca9, + 0xd0296a6a8e3d17ea, 0x3d16c66e5901acee, 0xdfdbd806d49e79bf, 0x4e587159a360a03a, + 0x7dd099b6394c1687, 0x62a5371f46b6e907, 0x24f0f7c0a3fa8e4a, 0xc8c4de8477c6ae0a, + 0xbf61ec7e94bfcfe5, 0xd853e18da1ba7535, 0x4690d41e01470cbd, 0xe0859ba0a234387e, + 0x4fbab772cca40a06, 0x91c208b6eaeb0b29, 0x77ccc1604608ef6a, 0xfab204f7d65eba9b, + 0xca3f50775a343ed4, 0x9d5a0d35af2c6151, 0xea85884931f8c2ac, 0xc2461abc3f36528b, + 0xbad58007f5f8d39c, 0xb3a1e6fe12e389d5, 0x018c7201e88fbbe6, 0x210edddd14f0990c, + 0x90479d181530756c, 0x472027681e9299c7, 0xa72cfc66442a2361, 0xc9ddf56011519d6d, + 0x2eb1da33d744b97f, 0xed00a9a951fc2263, 0xb05d5cf9f8039f67, 0x139a3d74b7f6c641, + 0x9023f62b9104ce76, 0x01e76897301b5e2a, 0x9258b7c567d2f3fc, 0xac3df1ea5c4d45a7, + 0x962dc580f6522299, 0x6211d2df146ec64e, 0xa0a30db54e6c3f78, 0xc64a50eed26aab06, + 0x2d5f8cde168ff719, 0xc3f603b25b0d7afb, 0x6a77564d98310a4f, 0x629bfaca7270632e, + 0xe8510b8f0ac97bbe, 0xaaa524dc61ee914b, 0x3f92dbe8cc3a23cf, 0x5904a527491ecc0b, + 0xdec0a8a62f37d4db, 0xd7d023142ed7fec6, 0x487d75f8fa050e1a, 0xb48b067dbae39218, + 0x4ae1e33dbfad74eb, 0x180a1e74ea443245, 0xee6d3e405cf468d7, 0x63b2a55750f19e8d, + 0x6bdcfcf084966d3f, 0x8f4bc9d05b08737f, 0x4c073bddaaafd5e9, 0xb8c7d0e3fff78405, + 0x263d4c6ab8f48525, 0x5c1a61e91536984d, 0xae6c615039505adc, 0x1466872a983a7714, + 0x64afb867a9b983ab, 0x6028ce99ea980ec8, 0x1bde4233183a1ea3, 0x137084c619b97579, + 0x2b5f319849d27ddc, 0x5246cb181bae6792, 0x6c4d680ff2231aa6, 0x400569aded8de516, + 0x167ddb8fafcc58af, 0xddfcba2e8e65a9aa, 0xb621d82f7f7e53f0, 0xdea72947a771dbd5, + 0xb2d295b4603663d7, 0x2ac89daf6c8bc32b, 0xc3df2d217893d5c7, 0x1ec52f38416acb02, + 0xf9622a5a56da178a, 0x669e587f735963fe, 0x685a785f7acb8fca, 0x202b9f331db7293c, + 0x42dcc7afa1cc2c43, 0x9384aeae398f001d, 0x26e51059e3a8d962, 0x034ed2ccf1b040d4, + 0x49d00e77bee4bd76, 0xf6788c4a203471ef, 0x682b4b63c110e26e, 0xcb13003456a4b36b, + 0xdd20575c392f8a1f, 0x8ab3e9ba528a7d74, 0x27b09b5be903e0c8, 0xaa901b2ca5da7521, + 0x239b33b728f8ae54, 0xc44df91f338b5dfe, 0x9e1195bb30d03383, 0x7c60460a98bf637b, + 0x8101f042107e0df5, 0xd7839071462897a3, 0xbe8f3e7dee8c1c69, 0x90ec2174b5d6f6d5, + 0x5bf627049e30447f, 0xd4b71b12a7853826, 0x9e3a92aaf5a6ffaa, 0x589362bb652a86c1, + 0x3cfaed1b97bb01d0, 0x5c1a3f47d2c5a619, 0x84903fb44aa2a1d1, 0x8575fcf52cf99edd, + 0x920f27f9d8352ac8, 0x2cc587f3ed81aa38, 0xc8da15c9fb440a80, 0x1f9eea62486b957f, + 0x16c05590043e2ab9, 0xfa44514256abeb5a, 0xfc148b2b684fadd8, 0x67adb7e0018dc9a2, + 0x3f75a9b2319702d7, 0x748d7166a86cc1e6, 0xf1ea257cb198ccb2, 0x9d2f20e3959f1e79, + 0x0054a40329b34730, 0xf2800309dc4e5622, 0x3e5efd3e65a5670b, 0x3c9f7090ca02f906, + 0x5b3ba8915cc6fa4f, 0x7e9b90e39b3e7f5e, 0xe222341ea4f47b41, 0x999ff3f0ecf13e1f, + 0x7086b48e29d67a40, 0x52a55f492fca67c2, 0xba4a26c8d510e50e, 0x21aa75516560e1ae, + 0x2eb0ae3919d22152, 0xf8f5bf1573837c2c, 0x15b9af0ea1a025dc, 0xf4b2553022db0607, + 0xe0efd93b932d708e, 0xf38683b9ff44e66b, 0xa2b16328bd778d98, 0x1286d5c537322926, + 0x39f0875be9b90433, 0xe0065196cbd861f8, 0x12ee2c7945594680, 0x04e351d73c57dafb, + 0xa602a2723d74c0d1, 0x10267cfc16cfcad5, 0x77e95f28753ce94e, 0x1b4cfe9b64a42517, + 0x9b33589539094cb4, 0xf71f061f8058b246, 0x07e67f3e88ea84ea, 0x9573646d5946bb6e, + 0x17e528ac2200925e, 0x35f3e14e561df567, 0x5760cd7754e245c5, 0x1425f2772d978c75, + 0x1850be44e441f0f5, 0x2ae79541527b250e, 0x90347b425a8f1052, 0x54b483d6bf51c177, + 0x4a3bc6ef5ddec0b0, 0xb382c256b787afdb, 0x14fdb142c1d8c7fe, 0x9645b592804b65e4, + 0x6674748dd3ce6371, 0xc8db18f5d85173fd, 0x43e5895ecb320d01, 0xde27a22f2adc7829, + 0x8a6fa8434065a973, 0xc694f46c9e42eefc, 0x03f5153b4f8d03b5, 0xb2920a7ab09b7360, + 0xac6c0d89aa3375ba, 0xce1357c6de141be8, 0x7a92fb3a5afbe316, 0xb9c06c6748f99f7e, + 0xe2f698dc9466a600, 0xf75fe203aa885410, 0x12f15e085d1c30c5, 0xb0035ae1b35d19ce, + 0x2c9840987fea1dbd, 0x21c87b8c474a53ff, 0x92ad540d46c589e5, 0x5aacd3d96d98883f, + 0xe58926ac3065c818, 0x65fcd82b582c6f77, 0xc828a1bc6aba4ea6, 0xb5937c157934e50a, + 0x1f51624944107f42, 0x7a413edaa22c3a85, 0xfc5d19c3b4aa7d4c, 0x2c8da632b5b3eaf0, + 0x5c8f0d81aa8ae557, 0x154bf81d72b9ee32, 0x423549e63786d4ef, 0xb87e6e325f6c9417, + 0xaef530bda2cf9b4f, 0xda5f2b0074a7242e, 0x6c63e852447c1bde, 0x4679f10571b2bd70, + 0xe54f0616875c662f, 0x1dd0d135386c8165, 0xcd891538eee7d346, 0x1a477b4f503baead, + 0xef891c04184f8c08, 0x8ba7fbdcb0479886, 0xeec534d83ed32f8a, 0x7511b67bade8400c, + 0x258173e0f30e4704, 0xf53eddc6b65be135, 0x1b6701d7b37a938b, 0x7905f1a68684ffa2, + 0xdf4c94f28214991b, 0x1b906c64f1e4068c, 0x38c60fa25ebd9358, 0x5638db78c5a9c639, + 0x5b9cc2830ec95591, 0x7a51120987d1e1e0, 0xebf7cd8bc200a822, 0x8c62f16c5ad42350, + 0xd94902922c304a92, 0xf9b62471a63d738d, 0x6278514fe601ba6c, 0x8273c1b119848464, + 0x59145705ce3a90c0, 0x0863d89499fcf355, 0xfdb429b3f8db3a0a, 0x10e8ddd36729de8e, + 0xc335a2416dbeefaa, 0xf93b90345c4f43ef, 0x702bf5af66c16ae0, 0x9eab7cc8dbb3935f, + 0x5b5f39c499107bff, 0x64799ccfedfa4650, 0x34d72ab4860d94ee, 0x1e3339515d75d17a, + 0xf2d4d2d9bfde7356, 0xadb902f957c6ce9e, 0xf154cc1d9498d24d, 0x1303f7307c59f4b5, + 0x3d3bdc611bd563a9, 0xbb19c5d5934df6e5, 0x45a4911ce13230c2, 0xf4100ebffbdc57dc, + 0x04ec224cf196e56d, 0x535b02eb0bf77f22, 0x901721d87104d044, 0x7a842f8ad299a021, + 0x75284dae9d85ac72, 0xe542e5e7d76499ab, 0xfa67b257d4db06b1, 0x9d31845ddee320ff, + 0x855695a549621583, 0x71bd9794d93a49c6, 0xf7340618a60ed56d, 0x0eff348916c1e55e, + 0xbb80beeb5410cabe, 0xb065dd40238c949f, 0x8a89ad1b1c1288bf, 0xa64b79c5229c2c51, + 0xb864d86ce4539341, 0x1b17265b84dd4394, 0xe885a18c15628ddc, 0x3b5b39aac67d0e9b, + 0xe0f520881827bdb3, 0x659f3e0aadb1b62b, 0xf4d3215e317da4f9, 0xda02faa30f9fa8af, + 0xbb2cd5b70229472e, 0x657524e70fa4d6d9, 0xd153b6ee270b3f01, 0xeec0ae8a56104baa, + 0x327524cec63a8092, 0xcbe599f59941996a, 0x82e3ea97233c32a7, 0x6e4f016fdb703fc8, + 0x2c16712cfeb8e2b4, 0x007ec1be449b999c, 0x4f645df0a1a66d79, 0x7be0d9df08a59ab0, + 0xd73b4049650fae43, 0x98175c902b054038, 0x90fe7aa8f07242f6, 0x2278f1a2a6160c4e, + 0xd9f42f837eb9ffd8, 0x40591660a9667517, 0x82bd841ef3d255d3, 0x38e4a240812d5d4f, + 0xc88fdcab342f8f73, 0xc7398ac206b2d0d7, 0x5fa6c929f8603890, 0xe1aaab335676b822, + 0x9db00ce94c3bbe47, 0x149c8a8ce25f2023, 0x8965cece4bb7aead, 0x2c6ef954f2691f66, + 0x277d0c3c488d034e, 0x013b65cd5ae9041d, 0xf29855129295054d, 0xa1ce2458a684f80b, + 0xfa1f3c969966a1aa, 0x8f71a932834b29c4, 0x81d0c412683ae646, 0x0b7758a483af85db, + 0x05e7c69a32fd38ee, 0xf126b4a0a385d230, 0x9409a460ebb589b4, 0x636e82e234ae43d7, + 0x82dd9ff981b5d96f, 0x4d91221e227d5795, 0x507155e1d597c644, 0x6cd826044733ee90, + 0x2baf2543a4b383db, 0xd5744195291c7203, 0x137a52aba94e7efe, 0x55ef259f455e95fa, + 0x26303478bde0b1ca, 0x1ef6f19b252ee589, 0x43614fb619f4a2b7, 0x5b8f728248511201, + 0x46274c7ca07da664, 0x6caaf0c009c97348, 0x21fe354e60d9e2fe, 0xf3a79f114a28e927, + 0x8c7b2363d408236c, 0xb3631ed744dfd4db, 0x2df81911b998572d, 0x267aeb4158424a55, + 0x6c1a9d2f4b315643, 0x240454c46dc7c52c, 0xeea02b5e11001c49, 0xc823415254f3f948, + 0xd9b944649c0a8e8f, 0x433a15ad7254ab87, 0xb81b23c9a7e1cfd9, 0xc135073100e8f189, + 0x7a273e7519762474, 0xb55194d4b382bee1, 0x830d3ebbd46115e5, 0xca9207c5275147c4, + 0x61ead232637093ca, 0x9e8860c5bcadb459, 0x1f694881cc0b5ffe, 0x617d4c9d2093941f, + 0xa63c48fdb350dc1d, 0x2d986565560a3efe, 0xe23cae26f65ba98e, 0xf419b5bf2ae46568, + 0x10f2053153a2ed44, 0x884797e2a94c7620, 0x62f3f88689a0e5f7, 0x79d78a5af9e66011, + 0x893d687e9883b617, 0x58863c2f53491584, 0xd70902209e0a684f, 0x9bd3440f30bb7f5a, + 0x085cda42b6e75c94, 0xe0d67bb5f5a6f567, 0xf1ce7ce19540d0c2, 0x5a8db6ef336f6f87, + 0xfe01c1f2b957c41c, 0x15400e32858dd78b, 0x6b369c9b233a9b44, 0xbb311bfb3f2a739d, + 0xac95f7fd1e2f5acd, 0xffc103403004607b, 0x5cf5886bb9a166ad, 0x8b8652fbfb2098c9, + 0x81462ed7c0fd5f70, 0xf95e5cec6001d828, 0x8f181b66c1619a4f, 0x3076ca51f3aaf38f, + 0x3407b6de5a8f3d5f, 0x931ccd8d6bf40803, 0x47dbb5ec652d1e7f, 0xfb627469f3fe317b, + 0x449306112092638b, 0x54636bc2c9d1ca6f, 0x8d1c2dc8bed72888, 0x2acbe90f08f1b870, + 0xaec3c9c87fe503e2, 0x03242b7ed3b7f2ad, 0x6e1b9354e353fbea, 0xbb1f06175cd8f84b, + 0xfc477a485e66388c, 0x20dff23b4ba94a81, 0x7e1055c3d104dfc2, 0x687ee6b30aaa866e, + 0x5b7c99dd972c46d9, 0xf27d76e6a4844f8b, 0x40f756542438f0f7, 0x14cea037d4444eec, + 0xb3d22ebcd74f16a6, 0x573a3c8084c9e206, 0x7a9f640dfcf2494f, 0x8fa52ce262841958, + 0x7f6303258a83f0ef, 0x94b12b2ee8076336, 0x5ed50372a4862055, 0xe569b603158a3743, + 0x8912a2edeb93326d, 0x5226ebc15fea282b, 0x81a02d2d37f40ed5, 0xd3c3d79ae09dda77, + 0x0682b6aaf9882c30, 0x2a9fa81cd669e10e, 0x5b63582c5109a602, 0xe96179aa545d77ab, + 0x144f4fdb1b273033, 0xf4414167c7e6c623, 0xd506a64d6e715fa0, 0x2b375347f53db2d1, + 0xfcad4e913d566396, 0x9895479c3f36e6e7, 0x3856782ac89f5ff1, 0x4b1cc042725174f3, + 0xe02d2c940f420776, 0xcb6e96f97d87233b, 0xc0d86a6f563e75a8, 0x94afa2ae948fb45f, + 0xc96ec5bfee3158d3, 0x121e79c3a047f623, 0x78cd1d22c5affda5, 0x22340214e770b339, + 0xa93de594111248de, 0xc027965f0a8e0ee8, 0xa0b4cba44614eb5a, 0x791d6b3dc70e183a, + 0x8939846cab683102, 0x88d8b2f4dfaceb02, 0x808fa981df8f565b, 0x5c703f69c4f11d70, + 0x50dc549197d2dd01, 0x738907194f41c458, 0xd358152d35bf39f3, 0xd7df61065c7c7687, + 0x2ad1ea25e9150244, 0xb41954e82e3ce893, 0xd7eda3a2925d4af0, 0x85283c40dc88cf5d, + 0x8aef1f337f7e747c, 0x2996f94dbe63a81d, 0x7433b18e9494e5e1, 0x6e5263c3d1aa4244, + 0xccccd67d1ef73f16, 0x7a2ea4659603734d, 0xea98ba4ac4240094, 0x3df0eb501b02b971, + 0x02402b37f6d6e2a9, 0xfa8f08d60f245605, 0xb317085fee3fbfc8, 0x309cc8680d99e2a9, + 0x8da0d2c08d600c8a, 0x1abbc6923377248c, 0x0435825f53d2d2b1, 0xd9fcb1c5cae04350, + 0x173cbf10cf117044, 0x1569f7a19a006c66, 0x92fa264103c7c082, 0xf576b231f45fc211, + 0x4afb44d6e1fb3a9b, 0x232ee2b2a4915522, 0x63182a94cbc83c51, 0x67f8b806f9aabe3d, + 0xb82807965c57337f, 0x97ba0fac2e6025c8, 0x5f56c5490df9b7bd, 0x9b5821aefaaaa1ec, + 0x18c5c8ec4f9690c1, 0x6fd2c1e1d9301747, 0x984151c8044a03eb, 0x1cd8de31ccbf66aa, + 0xf244be03330373d3, 0xeb0f4ca97427bdfa, 0x253463caf56af7c7, 0x41192cf32f4b0488, + 0x5de4b902f5a93946, 0xb6397b02e91a7144, 0x749d302e14c79352, 0x9de28617439db971, + 0xf5cb93a751af04bd, 0x43541d2a9f3a3345, 0xd53f539dab61747f, 0x889351b692152e48, + 0x5ceb39c0c664980a, 0x66701f0cfa7d0f9d, 0x458b2806e815e32d, 0xd9b314f1344f131d, + 0xd42ddad5c3b7790b, 0xd5bf9e3ffc554f80, 0xe334bc9a34aac68c, 0xf83c092c90e79d79, + 0xab700f3851cb0e7a, 0xd50cf0da33081223, 0xb2095c1b6222d710, 0x9fd7758d736eaf02, + 0xccc54d6c789f27a1, 0xfa1d132ed500c76b, 0x5af57cb79e542a5a, 0xea2dad9c681995a8, + 0x1152fd728fdaf428, 0x1933d15b370017ce, 0x0c3b8713b3de4524, 0xb6636253c068bc90, + 0x393b4ab1cde3d4f0, 0x9b0ff94658d55fc5, 0xdb74ed2c7e83bff0, 0x825e17aacbe3fd9c, + 0x861e4a10df4a440e, 0x274a42f793ac0aaf, 0x1f896be08b02ae79, 0xad04e0dd5ce3d29b, + 0x21cc491071c39b0e, 0x7208411acd3ebfac, 0x3c0ade46c3dbd92e, 0x3b4fe1e5e8054ba4, + 0x052fab6e6d4e59cb, 0x10e73df4eb1b9339, 0xce9ac8bfc7ea5fc9, 0xb84195f2d80f2543, + 0x666c8b50d1ba647f, 0xe4bc07a528a934b9, 0xcfa2dee3802b1354, 0x7a3bda566e93911e, + 0x02fefa36b7d97d77, 0xad7bd60872af58e0, 0xaf0c12a50af73f72, 0x97136c831016da47, + 0x1f54d98a46137105, 0x6385f1b63f8d5549, 0xdeaf3362594b0e7d, 0xe6fa4ac541a86280, + 0x3d96fa62d610220e, 0xfb06eb2ea51580ac, 0x1b8b0411312bde3d, 0x3536721293601765, + 0x2199d17c542d0491, 0x086842fbb1368f10, 0xf55e0cdd1f39a30c, 0x724100a738703a25, + 0xe3eb3d1bdcc0a70a, 0x4cdde3f643b0f55f, 0xa524e7f0c4712762, 0xa85ba63a01d0b9d7, + 0x59d64b5252374820, 0xb520e3d036a95465, 0x8e2e1ccc8b315067, 0x2ce3e151a791a5dd, + 0x8b2fce0296dabedb, 0x44a0d86a0090a043, 0x8b5df9d21b256ff8, 0x6fa5b7284b5f3b07, + 0xb9f448d4408f663e, 0x21cf7d90ee4ff1ae, 0x2b41ca8e8c9b15c4, 0x7ada58f55afdf730, + 0xe9eb4fbab2e055c6, 0x5ba19c53e98d7fd4, 0x9219a65c80e1225c, 0xd851f26e21f16c00, + 0xb73d37eb3ab42b39, 0x9c75727ddd218189, 0x027a111cf1c205f3, 0x0bd471c980fa0cde, + 0x7324331e708c6e02, 0x88cb30b6ca3c5d56, 0xd2eaeb728a4183f0, 0xf8ed98253559aae7, + 0xfbf90ae24fe2ee1e, 0xa0f4f24f25304eb2, 0xc0e532cca01cdac8, 0xf2689535f1bb5af7, + 0xd2de06b033646bd3, 0xdae72894c62c8a1b, 0xeb537a60ca207b10, 0xb622581fdb02a435, + 0x868d02c3edd440aa, 0x96cd99ffe685fa4a, 0xb909e7c9d944e4f4, 0xe4c0d22238d9252d, + 0x4dea9df25c757b3e, 0x172673fc8e86eb1e, 0x5c3b1ff6ef436727, 0x5a678d066cee6f9a, + 0xd95d1e42832e012d, 0x80a1a9cd4ceafec7, 0x32966bd8b6d43c7f, 0x0b9037c79e9dd795, + 0x96a1015d3ffdd53a, 0x6268c3fb9d2137e7, 0x1cdea59c19d05e43, 0x1b05c6b4f3b3a967, + 0x8de1cc4c51b1c6d7, 0x6fb6aa624499d398, 0x033d2ffeb0e921ef, 0xa74979025fa5cd2d, + 0xfbbf24f65411ca75, 0xcceae9ec139d0c6a, 0xda0665323e453a4f, 0x9ca1317df18c55d0, + 0xcf293e4d9271341a, 0x66804893acd75220, 0x3ddbcf577730243d, 0x356201b348c51a2b, + 0xb950894fa89bcaef, 0x2c7b1a76503ee1ea, 0xf26e19f03fa8d7ec, 0xdeb0f4e8c2c3f6b8, + 0x218fd2169c416c5e, 0x0c2688841e16234b, 0x7bb732b75c9d240c, 0x009e7ad17423c7d6, + 0xa333ffa14bafdbaf, 0x85deed97ab497b48, 0x785247cf054e63a9, 0xe5ea0a98e922e2ad, + 0x848e65940ab1608b, 0xa826472b0a57b5df, 0x4308a118f32331d0, 0x40bfbc8aaa6ab3b6, + 0x57eafd96577cc875, 0x9c51087a194407ab, 0x2c70a410e228885a, 0x374c5c65c4fa9436, + 0x987bf35cd2f37241, 0x4e1e29f7cd0b1c0a, 0x8ed57f7bc704f9a2, 0x246d82f53542725f, + 0x8d9c9329430e4e3c, 0x4517e387fd4ba9c4, 0x24f238d17e54c8ea, 0xa833b9f01d9f3cec, + 0x98e9e4dcca156860, 0xfbbf911efd27e7d0, 0xa61dfdf093b7267b, 0x71ef96d8bfd4fc56, + 0x534d0941a9749043, 0xa2fc80e3957df85c, 0xdce4809338ba0b27, 0x96733b13958a6a98, + 0x1515c3a3e5ec6678, 0x76475102a6e6a382, 0xbd65032a734954a2, 0x6b2bf26209d3d461, + 0x55b8312a516340d0, 0xb40638dd0c824f20, 0x9a9d13f6bacdade7, 0x38ee4ce9cf91ebea, + 0xa3b46b8e8e16063b, 0x381bd493d0135286, 0x05c43fa2ab42cf7e, 0x5a0f643bb5c4b23c, + 0xb8e4d0f3d9af3031, 0x10f4e23e26c6d6ff, 0xa8f3bc02e249bf67, 0x0617ee244efb0d3c, + 0xe1bd0acd083d3ab3, 0x68c4cb0a6096d017, 0xaa7ef58e468fff4c, 0x162429da480351c1, + 0xd27b077798c56b93, 0x034f3a2541d02fc8, 0xfd0b91bbebacefe9, 0x516b0275280f33dd, + 0xff502f62cdd3347c, 0x649acaf6d34486c4, 0xd9fdbc8985332e5c, 0xb4c3983dcc53b60f, + 0x24fde3ececa0a64f, 0xe6411de26fdffdf2, 0x0a284f1c3c7c87f7, 0xda7df903e5a31381, + 0x80f8e52c2c348130, 0xdf8ca81fda5438fe, 0x3034475646f847b3, 0x5a2e3e4d2e72d851, + 0x9ad5d7834672945f, 0x68187f984ff6601c, 0xebbf9d7c6f601688, 0x835bf4b474e52317, + 0x1cf1cd5c7e1592fd, 0xd0264875a1ef5914, 0x50d13fe656a9a65b, 0x88315a08a7a9bc0d, + 0xfef795a3e399e164, 0xbc66d59ebded82b5, 0x4705706128157913, 0xe3d36cfda0338592, + 0x816a614718dbe31c, 0xcfd0f5da4040f1cc, 0xf0e48ab9f135ccd9, 0x6089a225ac961d50, + 0x717ed1cb8a31eb57, 0x0719978575e02008, 0x5dc0099e12028718, 0xfec4e48e30fce0c3, + 0xd8598df282864a50, 0xe6917d204a61cac2, 0x6ee04744efc0a109, 0xb9c568997ec2e7ac, + 0x8157337dea2696ef, 0xf2382785ab8e844a, 0x0e7d138547340712, 0x53c0a964c8f695b0, + 0x4b2a07217f55dbc0, 0xba81997911bdb57a, 0x14c1724385b3ee55, 0xcfa7fbe4e6ea68fb, + 0xf58cb3f615bfb6e7, 0x536211d90ac18715, 0xa0aa2196821e9105, 0xe43c7a8f0f2d2f66, + 0xcea4749cb3493c68, 0x3c519d60f14bc378, 0x625615c48e75184c, 0x2b97defc0038c71f, + 0xa5f674bf87bb0689, 0xad74cdbced6cc23c, 0x5e37d6db1c36b4a9, 0x87ae6ee11c55f1ef, + 0x1a7080365b6f660b, 0x7ffa9ae86b3393c7, 0x89e0094d5179004f, 0x6762096b6c020050, + 0x26e74ce68f776dc6, 0xfea5d61b8ca39718, 0x2435925b416802d9, 0x3ed2b1a778c52581, + 0x215362707b000d9f, 0x5c1199fcd7950a2e, 0x86ea933c7eed563b, 0xa283a0a109824898, + 0xce9749f223fa2d8a, 0xd0ed461fd92f7870, 0x2302ce198617a819, 0xe837580f3607e3c2, + 0xb2f89a91f26d0ddf, 0x2ca0c30e626a7022, 0x342054f2f310f3ee, 0x24e805ddb123c620, + 0xfe141088dbaaaf36, 0x3ab53506b017da5b, 0xff21cec90a2628a4, 0xf48bf1b049339734, + 0x5940716ad9752465, 0x67868406cce0a673, 0xe4058b4ecbfc5c95, 0x5af7babc7e6599cf, + 0x694914d46216e919, 0xe81e1d77f9e99302, 0x0600656063a7efe9, 0x24ed2753dd3e7cb7, + 0xb8fc6c5e14f3dd93, 0x8d7b7e470f27f865, 0xbadd150a4b804ff1, 0xde584745d72b71c7, + 0xcdb625248a3adb6c, 0x411982dd0dc5baec, 0x0859b74cb4eb1400, 0x44e89fbcfc06fb30, + 0x1327169c8bebfc36, 0x141604a1d480815a, 0x5062d3d193397f45, 0x5863e87a3388930c, + 0x46bb8e08f57a646c, 0xb78b8ad506373f94, 0xcbe4ff549cc1fcf5, 0x3306b628d44bbcc6, + 0xe567c7e01062ef5c, 0x81dc47adefd60baf, 0xe120663b7613bb35, 0x04a423aec9374864, + 0x1098eaa7d4ef3452, 0xe1bc2962fdc226b9, 0xa50fbd2669e5e890, 0x8d9886428ebb380c, + 0x45480d115286226d, 0x6beecc9fe7e8b5e3, 0x15fb2be14eccf081, 0xd13cfb44c747327f, + 0x0942457879c35a00, 0x7fba7287dc1e27dc, 0x5d26576f0a913d96, 0x9b1222b33597ff4b, + 0xe36713efd0b042fd, 0xbec94ccee5b452be, 0x45e5f4e913a26b35, 0xfe3f3aa2d49752b2, + 0x9fdd539f44535375, 0x42b0a298336ad01b, 0x399f56deb4f0e8f5, 0x7bf811dd67775d90, + 0xfbedf06cb050247b, 0x9488435e56faeb4f, 0xbe087abdc98f811e, 0xc53a6b5e9d59e6ad, + 0xc57b40704379b2b1, 0xbd3405c6f24fc071, 0x8ff8049195b29686, 0x51452598df604aa4, + 0x69897907e7e99a7d, 0x59b2a44ea560fee5, 0xc53d7a077d91dab7, 0x1c92164545e8bec8, + 0x7cfad2a5ca348c42, 0x048bc6047f3fdc13, 0x9de0123eb0cf42dc, 0xd8ac44081676f5f1, + 0x48dcc9bcec98523d, 0x608cfddf186cc8dd, 0xca363f5618602644, 0xb50dc1160f4c6e18, + 0x29b28c24d49e904c, 0x4381d207a2eebc5b, 0x3d1a6407679d9407, 0x18471c6e42ca77ed, + 0xd0d45054c3095faa, 0x22ed59e0afdc34bc, 0x2a89431a023349fb, 0xba132fd1f97a1e25, + 0x6413cecaeb6fe2bb, 0x1d50605be07e5c88, 0xb02adedc33eb691d, 0x816660e2dfc1950e, + 0x07524dbc2f583bbc, 0x85f4258c2cc4e3b4, 0xff58fed6377f0a65, 0xba3b588dcf68b1e9, + 0xf22669a9564366d8, 0x37990145214004af, 0x9b4a45863e5cf7ff, 0x42301e6270ea0d31, + 0xa5af766e3cbfc5f7, 0xe9b66cb9eb03302f, 0x879d0ac2ac5b1bbc, 0x8b39e3889b96e6e8, + 0x23c1cd2298acc08a, 0xa64ae5423a8035f1, 0x08ddce25138e56a9, 0x91de77ccb5be318c, + 0x18de21697cc9afc2, 0xb4963f35a443e4a4, 0xf8e8b75d3cace7f0, 0xed30eb7183e680c8, + 0x8a9398781da7d10c, 0xc58ce74132f603a9, 0xe4a3e7d5a2d532f9, 0xb77c183be762bec9, + 0x95d533081d7fd1a0, 0x42e9cfd75b760365, 0x727ce748190dfad5, 0x6afe8d5787b2f73c, + 0x120385e1947ca409, 0xbd630494b98b4952, 0x78b71456628d5a39, 0x8d6e335eb773d4a6, + 0x5a39ea26d92f16d5, 0x60c40971eb9649c2, 0xecf6cbe15d5a5cd8, 0xfe96381798d10a59, + 0x22a0c77b1aef6598, 0x85e2f83e29ea7e8e, 0xb0f9ccad71e193b9, 0x653fb1f5874e9633, + 0x9757950901017123, 0xb11ff05b66dac179, 0x6e1402f0cc5d32ff, 0xb398834d33268f54, + 0xadd650b1cdc104a9, 0xfcf86fd3dd750489, 0x3b5ae8b6f8acd850, 0x1bb440cd027766ad, + 0x002d4577042de42b, 0xee1ef14266661baa, 0xfe1525fd7e3d7148, 0x17c6aabd12e5a847, + 0x7658d832c0c61fb9, 0x6a8a6e46a969d42e, 0xb606b8b060f5cefc, 0xf8e1caa96b766bae, + 0xa12fcd3101d6cf14, 0x8d7b9c42e4b38807, 0x63fdcb3eb6b271ec, 0x462bc6072998d73a, + 0xbe671f5b6dc169f0, 0x4ef69196964782b9, 0xd5aa4826f58139d6, 0xc1c32f80f4b189e3, + 0xa0adf716c08bdf32, 0xc7bef5ab7b21c887, 0x54b12e06bdf5167d, 0xdbdf708a33c934e4, + 0x92687138f0941f63, 0x849db988c8595abd, 0x52b8015f79f5b4d0, 0xf7d207f9d6511583, + 0xb496bb2123c57ab1, 0x6e465f0a8a9695a1, 0x4d3d4e536221735d, 0x0772c763ab65c8a4, + 0x563432fa14359423, 0xe4687a2e0294202e, 0x8cbb1009cca4542f, 0x1e873964803d55ea, + 0x05f3904ff9dcf49a, 0x14f2695c1adebbae, 0x44d69434dd7d6e33, 0x51c34e2609736bbc, + 0x4053ea577d8b2281, 0xd096680b6b793f4f, 0x1c54a939b3c2cb2f, 0xac94471c33021ce6, + 0x40b6c60e4cf86bf9, 0x101642b894a1dac4, 0x2418f3cdee1e9bf3, 0x01aca956349cd4df, + 0xc61bdf5eb99b70b6, 0x15f856357c3ff5eb, 0xca038653fa2d7532, 0x68d182819961bdee, + 0xb4ebaf9649520574, 0x33bc86addefac51f, 0xc000be5715aa8f58, 0x93903ab1e2652a1c, + 0x14e0f32d919f5752, 0xdd424885b9718417, 0xb68c3cc207b593f2, 0x4c070f45facd6db0, + 0xf07b0201960fa212, 0x03418093f0f90ec4, 0x30d0a74a7dd522f5, 0xa81e5aafdacdbbe9, + 0x4552442f15aaddc7, 0xb8861366c2c78efd, 0x639f2a7e93ea4e8e, 0x9cb045439e203484, + 0xf7c0e4936d450041, 0xa9a9532ed584efbb, 0x9a3e3fe705013270, 0x7dd873794dfb57b4, + 0xf694e28131a3ffde, 0x9821cde284c9d337, 0xfc5e677aea803367, 0x0cba0e75923b7c63, + 0x3e775ef5779d8542, 0xb0f58795b17172bc, 0x721d1949156e298d, 0xa657b1675375e394, + 0x528b4353a3f3fbfe, 0xb63a21c9b5c62352, 0x576c2756dec31a1c, 0x15fb8c48eada71d8, + 0x2cd3c983a7758377, 0xf8d031f609cac75a, 0xc339942415f1fc30, 0xa259d61be67a62dc, + 0xb4ddd7a0add904a6, 0xbcda3bb2e41e4e40, 0xe230f206f2042801, 0xcf06cf90b25ce853, + 0xcc27e21286f32e8d, 0x73f4159fe1f076a3, 0x5381a41d999c926e, 0x33848e628cc35a8e, + 0xa0cc41e953ff4970, 0xa4b09bd12ea679d7, 0x7638843a9181c476, 0x15c5f2f7ab9e3210, + 0x89c4a176c9cfbe07, 0xe3fcb582d912c8bf, 0x22ef353dc470195a, 0x1d9998e2fa702cb9, + 0x5bcdf14c6d084b44, 0x636989bb7c069885, 0x748244fc7925ba3a, 0xe4c46231619fc8f1, + 0x39e902f04692d5d8, 0xb1057fbda14849d8, 0xd4da22f2ebfb3d61, 0x3ba15c3a205d5aed, + 0xa89eaa6bac803353, 0xc79bffc7b5e2b7d6, 0x0bd84aa7ab9976a2, 0xa17a63bcdc2c414c, + 0x91cd37075f428d77, 0x3aa3172bdce6a7b2, 0x87b5d3a3117e289c, 0x36d3d549f20f8f2b, + 0xb5786f4d02157a69, 0xb8f60336fd297aae, 0xd95081baddc5373b, 0x3af3ae7c2888c51a, + 0xe7bb8eac4e279e84, 0xc70e8ada525e5080, 0xe7facb1f353fbeeb, 0x2e6cf2729b462926, + 0x5ef9e7f338f74938, 0x06d5fc4af2449429, 0xf9b0ae0de7079f00, 0x65da2d7bea4fb163, + 0x4598cf75edcc987b, 0xf1f888304da0e097, 0xd3fc1ff884fe8739, 0x93a3be70679b8f79, + 0x94814abefafad386, 0x803374bb6cf2cf6c, 0x3ddd4ff4c23c2b1e, 0xdd2da3e718369eda, + 0xce0432cbb8819f88, 0x85a2780052dc48c0, 0xd11bb8383c7480dc, 0x1b0cd24812ef98e3, + 0x7f1f86d775e7c50b, 0xfe96402e64d4b997, 0xff82a58217db538b, 0x38a932bb103ef1a9, + 0xc5679f30892e0708, 0xd771edcf443dbd1e, 0xf966cffeccb85765, 0xe5290e52c718e31d, + 0x342363d29fd69964, 0xea7be0ab1c2ecf57, 0xf97ae957d871e0f7, 0x0abd3ff18ee438d0, + 0xb10c669a24245492, 0x73c39a402b012659, 0x2f6d7661c29120fb, 0xf4b897133e8fcec2, + 0xf4c74a715981e5f6, 0xafe55763709497bd, 0x305c049ab643c4d4, 0xb17480bcfe42f540, + 0x985f35e4bd3af61b, 0x1d2e1625e48fd92f, 0xd7fd2694324b3e81, 0x2958f94d77a49fcd, + 0xf75410ce6f3e80aa, 0xeb3af1ba3dbcaa2a, 0x43eaea98bb4f75c8, 0xb917f74fe8618474, + 0x0aca8a3d628be306, 0xfa70b45c0d7a42ea, 0x083855d12eef0c71, 0x64e58826f5edece9, + 0xc77bd2a77bc8c038, 0xed563a4c9a7af32e, 0xb2b3ded2cf70e778, 0x56a2b38c41f63f03, + 0x2335839deb3f4fce, 0xd2fa93ba1e75d341, 0x6efd22a8391d9471, 0x37433e699a7121a4, + 0xe74b02c817375418, 0xb67a1c59279e8c35, 0x5a9b8a05a63fc3c3, 0xed6dcf14ac520b90, + 0x5f76450c671d68ba, 0xd1f63bf6443d7acb, 0x44035d46bfe3ea5f, 0x5d182dc156825af8, + 0x2954163425c01125, 0xd662a677d6a977e4, 0x087c8cd9f2358289, 0x1dbdc745f112fdb3, + 0xf23497c2af80a766, 0xf3ca52929e651349, 0xb3713b768dcc5bf2, 0xdec18944392ffdbe, + 0xa87d7c4c68e7a200, 0x4baeb4782038fbe8, 0x10869dd35773638f, 0xacae9d2a92e81b95, + 0x4b1c2d2388d3d718, 0x419ae5ddec8a3179, 0xc15983e4d426c904, 0x17fb4fc51db3915e, + 0x367dae0c4e1b3e30, 0x12852febb3db40ec, 0x804d2a105a164ff9, 0x5f3b454f997c8d7f, + 0x551d578594efd18e, 0xdac4354132123894, 0x37e9e741ca764308, 0x7fc96e6bc728bd1f, + 0x962c5ef7fe5e2655, 0x484698383f926b0f, 0xbab00a75bb3b7994, 0xb9275c8eb4aa6c31, + 0x0729967323d94d09, 0x639133047a69bcfa, 0x8f62d2d2b3dbd2f1, 0xb11641fbb8e08f7f, + 0x3956d29c26275fe1, 0xb4094332b30ac0b2, 0x30f6f4a6cb8214a9, 0x35e924de91381760, + 0xca20992e0f46eb73, 0xc6ccd5abb63f5992, 0x19e772b7c2e72b27, 0xa394ddaccfcd498f, + 0x40e059259b38b094, 0xe92dc0bff344c255, 0x79834f31d041a068, 0xb482111de857794e, + 0x6a16795c77d762f3, 0x108803688653ccf8, 0xf95784a36a369239, 0x3c62d1ce54080aa6, + 0x95afa0b5df186040, 0x53e6b925bf8bf1d4, 0xa38fb75804e75847, 0xc5f5595d3bca54e8, + 0xe3fcf65fb5daec54, 0x88a685b0c5d56092, 0x050a127412b7b727, 0x4df5585c7cb05433, + 0xc7df3f36495a9750, 0xfbd4e08065d8eca1, 0x676b7201be00a256, 0x2efc46d7e65fbb93, + 0xa6dba7ec408ec36a, 0x9fa4753f84239b78, 0x5679114cf63cfaf9, 0xae9aee7e86c111e3, + 0x2416e0f5ac98a6b1, 0x3891a1fb26eeb795, 0x430e1a501c853583, 0x1dfde13cf4a3aa60, + 0x1e10d3d7bfb6d70b, 0x42ec836acf3c3a26, 0xe59d782da66c97c6, 0xd63d4bcee08123ec, + 0x92465743ea059036, 0x049bc2f80a5f3b73, 0xb90d6bdf8781eccb, 0x60188905eeb43e37, + 0xa16abbe6d4bf732c, 0xc7e8ca84b10ae98a, 0x527e0ef0563ebf75, 0xe2cfec39039380cf, + 0xaaea4f1d34fedcd4, 0xe7058061194e24f6, 0xab1de0726960d928, 0x1acd311cbea5ae0a, + 0x4ca9407e52c5e034, 0xcf53e10f855e8a30, 0x2d3b1b52714ae226, 0xbde90f333f173b10, + 0x211d3bec779e8e91, 0xbfb627137c8fc5a2, 0x6ffe48555ff4a29f, 0xc6a54af4d98a5c75, + 0xc234243d6595ec3b, 0x91eeaaea77dacff1, 0x3597b3dece5779b5, 0x736d231f8ba76735, + 0xfc4a9620e50b0914, 0x2659c1560db2899d, 0xe7692d9ca489af0d, 0xa459c0e8c2f5fb10, + 0xbfe4b4e5f6751730, 0x22dabce499da6110, 0x929984b25b78d8e7, 0x603e37274baa69b1, + 0x790d9e2565f7d39d, 0x9c8036429d29881d, 0x807ea3c2deb895a1, 0x831f387551df3ec3, + 0x296a025686666b9b, 0xedb362c693564732, 0x4957bb38a89fec4d, 0x7f8d9affe10daba0, + 0xc2b83bba55117de1, 0x0e91922cf183470c, 0xce86e813a00d0e24, 0x88cfed84077cdaca, + 0x8d29380f74df203a, 0x4b513e3aa8eaac09, 0x1baa3cda9e9127a1, 0x11716e6a97e603ec, + 0x4ec3c649071e169b, 0xc01840efc4410633, 0x3240d031d06010ce, 0x803a10e29abba413, + 0xfe32b278d4434cf8, 0x6419a23ec2122d7d, 0x09b32ff84d191bf4, 0x39fa3b5134571541, + 0x4cc65ee7a3e15852, 0x73c1e9b62cdc5d0b, 0xae3bc6949fd81c92, 0xc881027cf7a5f072, + 0x33921f5076466b8e, 0x88b7b8c4e1f0b954, 0xd927713061da90c8, 0x295519880617720c, + 0xd29273039ed76bc1, 0xd7fc543789de9d39, 0x85dda2f7c80b67ff, 0xad3dd7cc76193d7f, + 0x64fa9a68b4e64969, 0x18d4a8bb7ddbff0d, 0xa0c75c01cff4036d, 0x6dac61b68cb09d78, + 0x98ad15f5de78478f, 0xd17fe6265171c974, 0x834606efdcd46fac, 0xce272d63e9779091, + 0xf59fb74bbf312a64, 0xa35dac88c54a7f94, 0x7c506804b6c8ddef, 0x9f4299f83166fd4b, + 0x8fdf50639d270c71, 0x0bfd4e1bfc16dd24, 0x5068d1e21b93f10b, 0x396634b6b670c748, + 0xcb569a5aab2e9b63, 0x8e49acdd511066ca, 0x326e0faf97f605f6, 0x36dc5142fad3a6f6, + 0x4b18739d1438793d, 0xce24bcf7c6a0e737, 0x23ab9dacc99d29e8, 0x7ac6c3204b2394e2, + 0xa9b2a399533be59d, 0x85dd82481851c796, 0x81370cb36c842fb3, 0xcb96d602488b0a66, + 0x812cec179c82f682, 0x6c1c969704c068ff, 0xc7a0a7a466b025d3, 0x53e2e03a918291c5, + 0xcae3b7468e15b22f, 0xd864d317265e507a, 0x4455070a16ad3d1f, 0x5271ef291e63645c, + 0xae744d32bd077de8, 0x2bab0a20bc448724, 0x7a7603037defc31b, 0xf1b0d83ee8a784d5, + 0xc5f76fd72eb1ba8e, 0x00ccc8039f52f392, 0xa0551d68ea345642, 0xa63cd992f2b872aa, + 0x70217377f00140b3, 0xe87bf72cf9f7436b, 0x2dd37a4f3a71134f, 0x90649da9b08e73f6, + 0xef789a594789e927, 0xed5736c84d1a9144, 0x539939c978e8b9c0, 0xfa01cc5de74c7bb2, + 0xf8e1a32d576c319a, 0xb09947f4bdedd6ff, 0x2d356a3de988f7c5, 0x75a77333e380515c, + 0x96df85d3cf6969ae, 0xb3924b31f2ac6c91, 0xfd3d6f0b62a3d102, 0xacd27a7995cd700b, + 0xfdb31472477290dc, 0x60b17fee01521f14, 0x738de5136adfdf3a, 0x7c1a26be2b48ef2f, + 0x195e0875b16f2a90, 0x2d2da46515215dce, 0x385cf746c400bc15, 0x671f7853affd8f31, + 0xd1920e68ca62ee19, 0xa0d7a572f70b377c, 0xd3634685a1ffdf35, 0x7e1509fdf89ea8d2, + 0x0dacd804e6d549f9, 0x92b7a0659930a1f5, 0x6ddc4be657b46543, 0x0c357ef54ecc4ab5, + 0x7271925a542bcf29, 0x70fe456ef3e3166d, 0x949b432c58628353, 0x4668339ccd51265f, + 0x971f3d9d3700a7f4, 0x91d63ff7661755cd, 0x2af76fd68d21ae8d, 0xcd15047e7e823dce, + 0x012f2007c3e39a0d, 0x322d256bf75c0230, 0xff4affe8efe1d842, 0xd04e95638db2edc2, + 0x94154b27bdfde557, 0x61b3b7c43b2cc758, 0x222531faf652234d, 0xc355b61c54fa2cfa, + 0xf91565c9f4eac72b, 0xce9d89ce1d742df9, 0x94d2dabe62e8db25, 0x236d2db6f9cc7d1d, + 0x0d295827d74fb3e2, 0x911ba1741054d7cd, 0x143309ae2f1d93b7, 0xd5766f197a45a6c8, + 0xfa2844846bd185af, 0x7bf06f6e678e6c57, 0xe6fc3e728f8f5732, 0xd3d2800f8eb8f0d2, + 0xaa063eae4638785d, 0x20fdc73ad9bcdf95, 0x536ea729d69b9c5f, 0xd9f269eec63d2e2a, + 0x239efdbd200365a5, 0xf2737b81f937a248, 0x6fe629ed55d9f294, 0xc81672814576ec12, + 0xb3ee569e7b224acb, 0x9841e18719b66391, 0xe8f4920d2f3ec8b3, 0x1f2b1c24e0590521, + 0x2156506fdc4d0516, 0x699256830d309e73, 0x71252464ff7e3262, 0xa25a832ef2c25a2a, + 0xb207404de880ef95, 0x45389c6ac80defa6, 0xb3a2f41a82039584, 0xa652df951660f3ad, + 0x5ba15ba20d95e5ad, 0x3d93ce5d8d46056e, 0xf7da323462bc1755, 0x13b7e273159e7d43, + 0x7d1b21f2fb26006e, 0x38ed7c1ca1f46d1f, 0x932569245aa9460a, 0x8ba8a0bdce452a97, + 0xe4397b826f4f4e34, 0x30ca997526bb4425, 0x9d063a689d2fbdfb, 0xd67b2677045d794a, + 0x9a24daee119ddf12, 0x3a81ccb1ee967087, 0x3a5c63064098f1f8, 0x056fc8fbffe74350, + 0xfe4681d2ee112b46, 0x8da1b8edfa2c6a5f, 0x8c00ff94f00d44df, 0x5690bb60f6dbbc88, + 0xc8c92b783cad88b4, 0x5720d5bbfde86969, 0xa34adad079a5cb62, 0xdb54a0de46fb547b, + 0xe1a667286795ff6d, 0xe6bd8745cfd08dac, 0x3719cf0c6b716530, 0x357818b5bcb00420, + 0xe88cdd47a03c2797, 0x6d0b33eaf420065b, 0x7606291325bc807d, 0xc139849c1263cbca, + 0x6b5f1bcab6a21d41, 0x217a33991003460c, 0x3edcbb1377ece9b6, 0x1b8e73053ff35ab0, + 0xb4d2623590a614e3, 0xb13a4c1d79419c02, 0x39f981a92066a2d7, 0x7f0d94f9eade9997, + 0x2cd4e1c04b1f8c4e, 0x189b146a355c1146, 0xdcd88d6104de4e12, 0x43d087f8dd0bff46, + 0x27594c51e6fa040e, 0x7fdd31b5996c7c5c, 0x6b5db846de05df6f, 0xcaab3f9c8c55da5f, + 0x396f113c1562a5fc, 0xc19b63b74aed2ed0, 0x99a4a1e518b25220, 0x4225b3d90312279d, + 0x30e2816c0f54f367, 0x43e1936a7a772dcc, 0xc0cd19ccc21b87d4, 0x314d72bf6d8bb7e1, + 0xb0fd29e477323140, 0x4ec98ede270f202d, 0x3b7af53fea4a0623, 0x8821762529976f6b, + 0xf35dff3813ed954a, 0x722444ec24dfda7c, 0xefb4cb56c829004e, 0x40574b95411632f9, + 0x84c8b1d77f18b7fa, 0xebc9610c3a249238, 0x960731f3b7afa2ba, 0xf61a0a9e13950db4, + 0xaee4fee142d8aea1, 0xbd80b89b4224be1b, 0xe87aa30384a07432, 0x482fe22178851788, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5a8f38d7c83969d3, 0x802e5f11f1fe9d22, 0x971e2233b3706de1, 0x76b6337d587e2bd4, + 0xa06d4dab9d9ac34c, 0xfdd1886ebd1f51ef, 0x753f34e2259078f7, 0x8a15315b0cacf396, + 0x7df39c75450ed822, 0xd4cad8dd05432463, 0x2a63aa2cc7d11117, 0x281a9bae8be8cce4, + 0x0774dfbfc3578f86, 0xb30f0677670e4ad6, 0x9c9c7e0873cca208, 0xaca680550fb6b4ce, + 0x6c89af1a010bbf7a, 0x67ac01e0658d9387, 0x9b6e6d1e14b0454a, 0x97805fcb273874a4, + 0xa01f1cd26887a47f, 0xfd1fcfa70ab32902, 0xa7042e601d1e1a9b, 0xad0ea9e01017a3eb, + 0x6e9bee9009df37d6, 0x0882d06e46d5bbf4, 0x6aa0f3e26f2da5ad, 0x1249478fab46c914, + 0xb9a654c4f58aaa17, 0x4201586ef33c2220, 0xe960e5180d8511d1, 0x446b8c44ad5e8e51, + 0xb3986530d209cab9, 0xec6eb9239e6294cb, 0x6e85cfca53843b58, 0xa67675f0086bd6ab, + 0x10b68155186a319a, 0x05f8a1e9a94b3051, 0x0d9c996c6e481fb2, 0xa24d73b257f7d639, + 0x5fa05b22498059e9, 0xb8695c0809a98199, 0xdcbc496bb42d34c3, 0x8c819661e89bcb02, + 0x3ff9562affd8b702, 0x1e8c09e32d729c9b, 0x1939d65bd3b38fba, 0x871119fc0766d2c6, + 0x8e84a76f246504d9, 0xa0c3a71df353dd88, 0xa19ffa2870180346, 0x656a24e87545ae36, + 0x413da8429ef9893f, 0x05f3ab116db164c3, 0x344896ce075ea7f1, 0xa411c893772aed68, + 0x30297f640172d318, 0xef6784ec9a477091, 0x44ef2ee6203f324f, 0xbddbb72e16f0c0ad, + 0x7d748dfb2957f9bb, 0x17a4fdca60443ba0, 0x67c440e8bc64c48c, 0x58bf85f5bbb9c432, + 0xef308eed0c6b0f53, 0xf405b8138250575e, 0x69d0ab18297bd846, 0xb08aeb90d77f4c09, + 0xb8def247c2d31cd7, 0x905ea96433337d25, 0x57f541d40ddcf9f7, 0x4d5f02a52ce2c2e5, + 0xe48b9993f83fc7a1, 0x04204a46bf0db1b3, 0x1397479620bfa6e1, 0x3f327ccb1a65cb54, + 0x2b52c27fecce31c0, 0x9803ed3a8a9bf103, 0xe4b0508133af5c4b, 0xbf3974f50453edca, + 0x45103933f83e3ff4, 0x6333b523211f9884, 0x8ecb3b2eaec7df08, 0x16576ac0e468b71b, + 0xc8baed988a5df212, 0xb2cddaec863a445f, 0xaa5f8565ca886e80, 0xf0f4a4ff78ac86e7, + 0x4ee4480c11aa0bc3, 0x95ce14f718ed1dd7, 0x6743e3a391c9bdad, 0xd50a217d5797ddf2, + 0xa10c5b3e449fc989, 0x3e1c2822bd392db6, 0x46444223786c240f, 0x7ca67c8fdc61117b, + 0xa0ef242be7370743, 0x14649f37fd36321f, 0xc579ce78f526eafa, 0x4b9e803195fd047f, + 0x329712a3dea2e5f2, 0xe28fcc37f828c360, 0xf77109e010f722bf, 0xfea9211c86989b96, + 0x43c34a4a053fb266, 0x656438a3926650d7, 0xcf2a5fe730c95022, 0x467c0e0e11e8eba7, + 0x69876d6a16560608, 0xa82ddf61798381a0, 0xb429fcf0b6c5a8ec, 0x677ca223b219319e, + 0x2ff3559f66bf2644, 0x111f0da19555f56d, 0xf5952bf6c13c7920, 0xcb90c0292f38776b, + 0x44527e4f7bdadcca, 0xe349d06ec5435a0b, 0x7a8c54bb993b4773, 0xddeb22a41da24827, + 0x1caa15afe0a91cc1, 0x9566f81c81fcadbb, 0xcb204f1770a2b9fc, 0x18fd7e355d8e7341, + 0x42c72db7623698fc, 0x8c509238fcff2f83, 0x132ebc7f799f1e09, 0xc6815e870b13bd80, + 0xa9d39167f9b775d3, 0xb6bbce0669f760f1, 0x007b924931db01c8, 0xe5591a4e0a73ba60, + 0x20b60c96c6ca5770, 0xc412fba9bf8b54fc, 0xbb45ab8ae41c5932, 0x9f9d9f0fa06a6c9c, + 0x597bbd4e4492f2f1, 0x1e7e9e534c373251, 0xe84ac7d44cac8d1e, 0xe52e23c9d9a6d797, + 0xf0ebc7a50049f000, 0xe2085a49d9805ff1, 0x89522e9315dc03a7, 0x9482efdfa99898d5, + 0xcaaa99271d59a2fd, 0xf2b45757725718ab, 0x28b3bb2c718ac7fb, 0xb6abe034e1c0730a, + 0xc0361dd1d3ca1047, 0x3332a34ccfff9ab3, 0x5c3164a35800a6dc, 0xce50182d7221b1a5, + 0x3b0a370b459bfc5e, 0x14e1e321bd2fc7a3, 0xd4cfb094a0ef4d7e, 0x7cf290facc636612, + 0x28da92b1c7245d2b, 0xee440c9382db7ca7, 0x43c4255cf8eef53f, 0x2c746b017a72c9a5, + 0x8189bd8d2e388b3c, 0x67d550f7976bdbf3, 0x17dd654e05f1bcc8, 0x26549bc51624762f, + 0xb5659f35d4019b26, 0xe752652baa8022bc, 0xc18717cae8f7e4f4, 0xf9c226875c1ad55f, + 0x423907cf58a4cda4, 0x11ccc4542d41147b, 0x72dcc4a3cb72b87e, 0x7fa47d2e048b37b4, + 0xd8c52cca81a26ded, 0xc68d9ab477104d5e, 0xf48966245b3e7922, 0xaed2ae4dad6b296d, + 0x2053f2fb4542b014, 0x6ca82c87d680552e, 0xe001ccca4a9061f3, 0xd87cbea55540c14e, + 0x83e3a248e1273cf5, 0xad48e51131ddba12, 0xfefe9a67aa385551, 0x623f96ef8e63f1fc, + 0x79dd24b1c601a870, 0x2407afb34ad7599f, 0x3656065a8e9ebd7a, 0x4bebc12b185c526f, + 0x59ce4a0c01904cb9, 0xde317f727a17c006, 0xf32edf212d30772b, 0x310494c6e448ffa4, + 0x454b1feb93b91386, 0xd88c37b51da79bf3, 0x95055ef4f1ec57c3, 0x25690f62c0a106c2, + 0xd9e1e9b8353e77f7, 0xbdf62b686cfccc17, 0x6bb4600b5dafe3f4, 0x645b4429c72316a4, + 0x5f1b6d13fea0c57e, 0xd49293375bfc4287, 0x8dc9cf452eb315f6, 0x43f02146e402ae92, + 0x64139b4772c651af, 0x76147c1fa134c301, 0x27ec6172ee7701aa, 0x87ff850b5da7c22e, + 0x3303a1be5d9d5a3f, 0x42769b6234557c28, 0x4f12ca2bb28c3b15, 0x515743c347f0255c, + 0x0a16d1ba01c8a420, 0x906d648490444c29, 0xc76f05738039f31b, 0x36dcb048c5e59c4e, + 0x10e38882e9a7cb5a, 0x63bb65256d036222, 0xbf331a8796f9a8c8, 0xc51401129e0cde8c, + 0xf4088affc50183e7, 0x7c81485a28b2b365, 0x9799ebc6565f32ea, 0xf02e9e77fe5fd4f9, + 0xee7435d9fac186b2, 0x2391fefee84317e0, 0xdf3cee7f9f3483d1, 0xe0e36622dae692ea, + 0x2dbc3ccfe6874d28, 0x969b6b2b4f859f06, 0x12527c1cf0e1b0b5, 0xf3e5d5b7413151c1, + 0x0466dd6a317f71ad, 0x713cc3b94342040c, 0x0206084d9da44347, 0x7c4112f4120c66da, + 0x05cdf3a5f2687ebd, 0x9659ec97dd323618, 0x48361608b090d888, 0xe802a74c29d740f9, + 0x2316e647fd34d4a8, 0x936988bf50cb343f, 0x43a65ed5fc0e0e63, 0x1f660b2f34f216a4, + 0xc846e84f339ff9c0, 0xb0a0f58bdb8b3255, 0x58a3d6f0a05181ec, 0x6d850361e04ec675, + 0xbe072db0fd188206, 0x45af81ae1097ce4b, 0x762443e60ba0a6ec, 0x3b81ee490e49afcc, + 0x77b5743e2483a147, 0x0e8ad1158c4ddc8f, 0x842e45257bd9324d, 0x8a092a5d4cd7b6b7, + 0xdd125cef06b384f2, 0xdde39ae47b383de8, 0x4f1a234cb2fe8d6c, 0x0c9ff51c7966e227, + 0x3ecd0b06037bffc0, 0x865259176c28aebd, 0xb78747c05a74a855, 0xed07076603c5b728, + 0x178d9d71fe6dcb52, 0x288e33186289b93e, 0x6f8d5aff98f21e01, 0x5df68436b8887be7, + 0x2708aa6a6b13d411, 0x2522871878c58a40, 0xb1387a348c7e75b6, 0x8b8e1961cc11facf, + 0x7bb26841f5a1200a, 0x20ffc314c2e5382a, 0xed2b2ba4a706e121, 0xf19627f27b4e4f19, + 0x9b9c576226e873ed, 0xbf779d887fdd16bf, 0x927bb722910b05b0, 0x08c06aa16babb3d0, + 0x51340bba2d26140c, 0x7e6ef42585d2db70, 0x66ca5ec0087658a8, 0x19311e73fd5eb1cf, + 0xb73d1ee5a023e750, 0xc28f342fcc290e5a, 0xefd64bc50bd23692, 0xe5c5b0ec895fff99, + 0xc234c5d061b60636, 0x9518e09a68a6940e, 0xeb8d459aa0ee2583, 0xb6f2dacfdef12ec0, + 0x58362c4fe49e0806, 0xb856083b49f57d66, 0x0f5a0605a89738f6, 0x711a322ec291980c, + 0x2d308d25a59d014e, 0x4c4f346d139d3bb5, 0xe70e78bbe59bb1ab, 0x61aefa169367cf04, + 0xc048d5adccf3d1b4, 0x2576956c9110e514, 0x19aacdbe1e1cbb5c, 0x2d43e4f91e103e8b, + 0x7a9ad3342754acf0, 0x9c7b2f45452843a1, 0xc93cd83537076876, 0x919f2bf3faf17f07, + 0x3376c38959213e07, 0x5ed68817877ae98b, 0x7676de6c3a2c5c0d, 0x21ba16cfe41c8d8e, + 0xc364436d4acb7942, 0xc84892401584d42f, 0x5ebfc2fb0bdf0417, 0x74ef38c2081c51c3, + 0x2773b3e1184cff5d, 0x3073f64f41e6030f, 0x653d63b512ad2497, 0x13f7005893cce8f1, + 0xd088db0f22753537, 0x669bfc28cff7d343, 0x24d69e68e4f6421d, 0x696ea37ebcf003ce, + 0x2487163f8aaf0339, 0xd7302fe619c7fb65, 0xa300a75b6c23dc97, 0x794f4106a6716468, + 0xb37caa93463d9e7a, 0xc1f18dec332c899b, 0x1a6df77148a84025, 0x1734ce79d3285195, + 0xae5109918b3a605f, 0x21fc603edf4c4962, 0xc948041b7707a7b3, 0xa793588f1f36214a, + 0xcd2d6b2ab418f995, 0x86b57292a35213cb, 0xb5554abd5022a5da, 0xa74570a84ccb0f12, + 0x38414fda17654f52, 0x3ec3ccbccd924d1e, 0xebb4d22d312c2338, 0x4f141d6fa4f317bc, + 0x53c86326cf34b074, 0x79fce0df3e1f1131, 0x8d5ed8ef6bbbdb84, 0xdaa628a37ff71bc7, + 0x5d9c3cf3cf1e74e6, 0xc5f66eb2c601060f, 0x18bf736b345d4583, 0xd74749c687259084, + 0xa38fe4fbcbfac896, 0x854863f5222f63f3, 0x60de4eb8c2d350a9, 0x9e8b701ff4384ec3, + 0xa6baa14afdb6dc9e, 0x7ed9b30f58ca4371, 0x31c70e5002a41247, 0x07d3fcc787e04d6b, + 0x3f74088dd6b3575c, 0x223a329ff6d0a27b, 0x2b525b9ad8d9e5cc, 0x4023a209f2a42b61, + 0x0cacda59e4a1c5bf, 0x8abaffaafe754ae0, 0x6e0c9a59649076c2, 0x50814fca81ad1624, + 0x2c33bc818a8c71da, 0x5b92cfbb7c5a5bff, 0x4456b8973e1bfb4f, 0x54aa57168ef3c398, + 0xc3d1947f481af26d, 0x505639295fbfa7d9, 0x818343f8e4b3715b, 0x6dcc4a95146ecd24, + 0x19f96eabb6379fe9, 0x906e8407cb3ff96c, 0x7ea2889ee971c4b5, 0x09b9159e8982d450, + 0x7f0153dd5a3e7773, 0xd3481e11947344b4, 0x1d90d830fc20dca7, 0x2fb5449e2c337c2a, + 0x2693a37e1482a6fb, 0x7c47fa8bd018259d, 0x77d8bd52da6f3331, 0x0e9410c70cba0eb4, + 0x33e185ecce5d6ecb, 0x7bc1f5259b192091, 0x40bf012c71063498, 0x2006cddc4c931744, + 0x6356faffb909099c, 0x40bc37c4d27ef756, 0x25bb834160dba004, 0x11062da64c29ce71, + 0xe10b96ed0d6ea6c7, 0x9f4a11d1d4b3d9b1, 0xbe8b6cb9a6420d84, 0xd8b51c38d47ad27c, + 0x1353069334007af3, 0xe0778c8942513212, 0xdbd03f41e283b4b0, 0xc529525241981d0b, + 0xc707c825811c39c2, 0xa225d6315de413c3, 0xa35e67d7bbbd2404, 0xd09da87eb9005f1c, + 0xc59915ab1c0cdf3d, 0x1878fb1b6c3d4095, 0xc66bf3557b7d0768, 0xd262d2f80e19e848, + 0x3bf514dd7a7793e5, 0xe5fbda01c3ea2d31, 0x405659bc5a23b6ec, 0xc876dac24b5fe0c9, + 0x6c0cf720506e3f1a, 0x02530758876ccd0b, 0x4169fb5f48946519, 0xef2168f86dedb9a1, + 0x9072e40c40eadf5b, 0xe46702e0e6b86df5, 0xa4bb530ad84c8dce, 0xd4500beca3d23fd8, + 0x1132f0ca01b2ce12, 0x8967e70952c380fa, 0xefcc2cdd600e711f, 0x49e77942c5f7ec5c, + 0x278cdbcd1815b710, 0xbc2be6a65912e5b3, 0x7dc57eb56897ed38, 0x54cccdbeaa880005, + 0xca029935658d7e87, 0x40d3581995dab3ee, 0x5e145c6c148cd517, 0x3c3072abb35a13fd, + 0x3abdb313a7d27412, 0x28d61f1ae138e577, 0x578cd5ad3b7ffb40, 0x5104bd71526e24b8, + 0x37f50895d3ffe1c7, 0x1777d244fcf50d21, 0xd31e3b0eb559137b, 0xaa9ca1e3e2dfb4b5, + 0xfec8ba5d7d713cbb, 0x0802bfb4b5e508e6, 0x5532a4c4e6c958e3, 0xac0764b60aa4654a, + 0x5db2dc891c3da857, 0x500f3268259916b5, 0xf9f1c5e183bf6579, 0x8e88051966b3590b, + 0xf8514a2114f13889, 0xdfe96cfbf7eda812, 0xb8f0c8ada4891771, 0x303849195b40e0e5, + 0xab12b9f86d64c6db, 0x7c837967f717e36a, 0x6ed11d7f57f699fc, 0xe851c0a451b09b4d, + 0xedac45b6e0fd43a1, 0xeb0e8e82f87f3797, 0x6214d0aef4cc69ae, 0x1fff67c043b8ef86, + 0xab459dd5cbfb4319, 0x40f2a299e72d864e, 0x9a1066002c90d6e9, 0x9d5892fe14861283, + 0xcd7befc7a9bf1771, 0x23f76803e8a6126f, 0x4c2dd1b0208996ac, 0x74b541ea47bbf3aa, + 0x7715056d79688d83, 0x80009d567055bab9, 0x5f9afe349037d0b4, 0x8ae19f35ebacb0c1, + 0xa43402bfa204a95d, 0x268f0d383e9c1b93, 0x1d4e07020801c816, 0x490e29b83c45fbeb, + 0x30e8bd05ff88ab69, 0x1ac9535a65f9a145, 0x080fa85d0fef2686, 0xbbda9395e6d33d56, + 0xfd704455b8317f69, 0x236a9d970f14f33b, 0xa874b98b74cad0bf, 0x661c23055338942d, + 0xc38522030142fc0e, 0xb0666b3cf3de00a9, 0x2bbc83d93c022c02, 0x40328e6352e1f6a4, + 0xb65224ada6e937d9, 0xdf3ece37f2bc5640, 0x258d16a23e6f1a7b, 0x18213da5f118da95, + 0x204e9069a247ae04, 0xcc860fff14d38882, 0x5f6495d2e0dd4d6a, 0xf51382a0c27a4b31, + 0xb14ad7e2af0b5e7d, 0x1465515ec3e8d3ff, 0x1f1ecbc9ff4a65bb, 0xd56bbf8d47594bbb, + 0x00d84f84841fc380, 0x18bc44e5998c7449, 0x1a822ec9feb68448, 0xeb8c07d2883ad17d, + 0xcb6cecbe86169616, 0xea68a9ec6de26ea1, 0xcb59e4e433bde29e, 0x94267594624a02a3, + 0xb22e3ea3e164ec33, 0xa72451ff924f6929, 0xf6ec77a0893c9666, 0x688e46d8f9c4b18d, + 0x7373566eeeb5a523, 0x8cb58b6c7c34c653, 0x586713f10bce5421, 0xf18a85d89927e456, + 0xd1643d38ecfa68be, 0xbfba323f47f0a283, 0x7e68df6426316a9f, 0x284512e196f1534d, + 0x4709dfead3bc3932, 0xad39edca33770372, 0x72c3b5fe34ace038, 0x9bdc1a6a90a0524a, + 0xac4a8b16a0bca00f, 0xbf954e5e019e7290, 0xd933dd98ebc426ab, 0x255525add4fcd6bd, + 0x7a5fe2594fb9fa0b, 0x54241cf2474c2c90, 0x0e0a871d8746203f, 0xe5445d03fbe27d56, + 0x7db2739c87c25739, 0xb1aee3a6c37968f4, 0x2c55a8063a571e07, 0x74f2ae3dcee04210, + 0xad7b7437811f29c7, 0x5e85b5aec474c75f, 0x6c45946b28ea9f04, 0x06b392322121f006, + 0x72f21636e3fc2ae0, 0xf556df5f2d2c097c, 0xafe79584222f947d, 0x613c3c83efaca8fe, + 0xb763d046dc8c7762, 0x5c4691b45d1e1ef2, 0xda5d31692eb923fd, 0xfd291914d730b2a6, + 0x837dccc6b85a3ad4, 0x6e8235314e75bee9, 0xec55cb9f9e9ba698, 0x141f2e0ed7ff330a, + 0x441b3689a00022c1, 0xe6b3af4b35f0e590, 0x237f4a382612dac2, 0xc1c90aaf5db4a716, + 0xec09cdf30fd517e1, 0xe7dbe012bcee6e49, 0xaf644224e25b044c, 0x7de3afb3281108cb, + 0xe33a614b8f0a6a1b, 0xc898ce1a4f685c58, 0x81ccb769d3a234c6, 0x8aba86cf5e2f5b1e, + 0xc04d662dd3f02f50, 0xbe83cf3e09074397, 0x5b446bc638af6b94, 0x7d011d68a2acc7f9, + 0x8e1633f53e3519c1, 0x5732eb7d9c7d8498, 0x92c6cb49de770a30, 0xb01b1a866a0ee488, + 0x4be26820b829c84f, 0x9e41fec37bbc7bf2, 0x667ffdc38d06abad, 0xaee3439f10115c78, + 0xb40bea9328850277, 0x13a974190d983425, 0x85e091ea5e51bc56, 0x9acb103e60362d7e, + 0xed6e667d25fc5028, 0xb404cb49ca842f00, 0xec76e5706af56fae, 0x4eabe8552a3d02b3, + 0x62137632b42b16cf, 0xc1b611bff135b71e, 0x9ed2a71991bdb60a, 0x808289c7fe10ea9c, + 0xc8feeaa13c7f9c94, 0xc48c1cb835476a0b, 0x42fd27c7a9fec5c5, 0x73fd0baba549b816, + 0x7a242770e8249c32, 0x093e8ea4554c5ba4, 0x12059b06b0aa2970, 0x92717a6e7783c3a6, + 0xc629716dfdc2b374, 0xb9b2696bd7a7cdcb, 0xfa32051b4446db9a, 0x1a47ef6c22124454, + 0x8bfaf86efed90edb, 0x9ed8e906be96639d, 0xa480497aa2ec9db9, 0x62bd4168fb61f987, + 0xe57d1eded7404879, 0xbd054fac50b106c4, 0x4f338ea341707b77, 0xff326644b682342f, + 0x738b4861e3fe6150, 0x5a2a74f9960eb4ee, 0x1abbe49f664c95f6, 0x23c51013fe81bd1d, + 0x98595c44c46ce46e, 0xa45d9fcc4978456a, 0x32b5623985087979, 0x042c65da05d6bf8d, + 0xa36eaf84a36716ff, 0x19f88d4d5170c42d, 0xff41b43ffd84d9db, 0xff70026eff81f506, + 0x8e1dadffe084d470, 0xde0e3483646e4a30, 0x78b831fe371279e7, 0x57d212fa85d3f179, + 0xacd0f4a17ba8d7ec, 0x25626805833bfff9, 0x23fbc0a201b94594, 0x44d61f3e0f0ec90c, + 0x4bf165c54ac44612, 0xfeda57e02d889c1e, 0x1c05672eeeac590e, 0x9cc7745a403cf70e, + 0xa26e301fceccc9d3, 0x7c92d5e714294f0f, 0x25a5888684785341, 0x1cd4e8b55757e8d0, + 0x7b4379e33c74d00a, 0xe9e47e935cfdff0c, 0x4420cf14a5a29c7e, 0xd1d925f17bde964a, + 0x2a3a4f0dd47104d6, 0x094fb8df369db2a0, 0x1446eed7c8791b33, 0xc22943f19b3c2819, + 0x5a9067bfadb02a4a, 0x58cd029f630fa3fd, 0x6b80e747a344ee9f, 0x9bbb3ac743fc58e8, + 0x824c576651dd9f6d, 0x244e7073f019f145, 0xb4ab725a5911e094, 0x6d0d4bfa3ebcb5b7, + 0xc62ebc2991eb17f7, 0x966c218b15e332e6, 0x06e7a259c30f2179, 0xfebc0b7f318d3238, + 0xdbcaa9a457f66834, 0x05d70ad551ae7eb9, 0xf133d62bbf0571f2, 0x1d7f4a014995ba3f, + 0x0526136313e8b163, 0x9184c7ecfeec77af, 0xb10c9263ea291425, 0x776b03afe1d01a3c, + 0x054f7b391f74fc7c, 0xce20af538b790e5e, 0xda88cdd75427add7, 0x156f568358b960dc, + 0x3feb26e9c25a9d53, 0x846e9905f3fe80ff, 0xe3ee528ef8cc3502, 0xbba05ac23c64a7ee, + 0xe47f7c43ec2b1d36, 0xa8bd433a9aeae249, 0x70e5a77a4d14a148, 0xb471f597892f7c1d, + 0xc265bd1fffcd8a1e, 0xa26ea2ff459be5bd, 0x42f24eae9cb4846a, 0x1731421e9dacca95, + 0x8a95eab877910a0f, 0x5b46c2849bff6c36, 0x019cc1ae359dba37, 0x989386735920f566, + 0xb4f595fba50afabe, 0xbf5a867bfaf16e54, 0x5956ddbc040967a2, 0xe76d38b66ab5185c, + 0x407083213b60061f, 0x2ff5331f21e84e78, 0x1385f9a2e062f663, 0xe089a5012dfa7836, + 0xd48425899d738154, 0x19a9886481b5fdcc, 0x3d8afb14ec3228c4, 0x6dbf6520721f3975, + 0x529fd4b0a0fd3e95, 0xc12666f91c690f16, 0x013838094571c97b, 0x32b6ea151c258207, + 0xd3081a7593261070, 0xb3bf7fb994a5dec5, 0xd48f08115e60431e, 0x89c8d7b87e75e179, + 0x0c06f1abd7341950, 0x5372de0a0c052f48, 0x042903485cf3cee4, 0x9fbc57cee8606755, + 0x669acbafde5e023e, 0x435ca0c1e7f4563e, 0x81f1df9d33ca246a, 0x64df2aede26ddfaa, + 0x3f205a3a5e1ffe59, 0x7ef7bf95272eca03, 0x16f2db280e97e824, 0xa886d13b9ffae026, + 0xba6b60efe389cc08, 0xe3553897a3c93d7b, 0xd61b32cab765d37f, 0x518045c5336c84d0, + 0xeaba43b306c9bba0, 0x6ac2e9edf51b0d28, 0xfe7d09c07b0458b1, 0x5fab8c351168a5d0, + 0x3f4739df6b6a660e, 0x037059edd077a5ba, 0xbfc4404f56b81e8e, 0x33ba42db8f090883, + 0xf2dc351b24bdf517, 0x2d99b6ee202b117e, 0xf4a72c88bed1ccee, 0x9598993378c910db, + 0x0aafa50fe53120b0, 0xe1191ccf25000935, 0x7e59133c34b8a78e, 0x6b15280d7bb2c9f9, + 0xc93510f40acbacaa, 0x24a90b3d51d866d7, 0x3abd1f613b947a23, 0xc1a0aaf79d38a599, + 0xaa63b2fbe976be34, 0x5132304cacc5dbe7, 0x3c4616ff90a119b2, 0x08ada3d4af83e236, + 0x2e68e44b9de2a20a, 0xebeeced3612399a5, 0xcb0ca7d00fae8fe9, 0xc1d650809aa65ff1, + 0xca82d28873de0eee, 0x705c7d54aff18927, 0x1db14f4ccacb213c, 0xf2183d461a76062e, + 0x24b3a4abad3eba8f, 0x3bd775d4017e7b46, 0xa9999e80ce0d5aae, 0x28223281522e7f20, + 0x952359ae716680e9, 0xae90fc1e6548cd2e, 0xafac577b0390e48a, 0x89bbc1da1365e680, + 0xac581017531d487d, 0x529de57e8531636b, 0xaa319c7c0f14ebba, 0xe85977e3e82a1e7e, + 0xc8dfc65ba8fa441d, 0x0436e9d8cc62da0f, 0x94b538042e33ab95, 0xd8ac919fa145977d, + 0xf8f6c813fc1d8f8d, 0x71aa806c2dfe47bb, 0x386e7e59d9f6272a, 0xc66e0baf95c9f4e2, + 0x8b037a047244c22c, 0x0b9533279f164d0e, 0x1f7631e19f418b98, 0x11df16118ff023fd, + 0xb26d45934baadb3f, 0x1396a135042a20ba, 0x588e04ff0c1cb6a0, 0xecc863ad24dd3f25, + 0x90cd642b8d2d2298, 0x051e49d21c050d18, 0xba8ff0850c4fd327, 0x908fbf331d62f607, + 0x2522a665f93ba253, 0x78ef22d91c5ce31c, 0x0464f0de665ca6a7, 0x7f3d6aa1022e7f4f, + 0x59ee5c01dba4a943, 0x1a811bdb69f7781f, 0xf572f2a04d9ce107, 0x7d0d6d0773bcf042, + 0xfc1fb30c63c6ac31, 0x835003f3d280b7f8, 0x2cb2d8419365dda5, 0x9d66c681d8ba07ef, + 0x2647bb1d49ba2768, 0x5b8de63465bc198d, 0x00a6795b3b51fa03, 0x0d10ea05eb78c0a1, + 0x1fa9bb055e3c5054, 0x289e437ba23e1112, 0x486e80d9c0bf3583, 0x43e18580cc8de7b5, + 0x5bc825de6fdb99f8, 0x7e0dae59fd7c7a82, 0xa270e15266b61e1f, 0xd200c2e375ff89ef, + 0xafbb1c0ce94759df, 0xc08b2ef1a2e9616b, 0x6abc02c7dff91d42, 0x8a4e1a6f3b58204c, + 0x7e55a82dc9ac84ca, 0x022629a8d52258af, 0x39e1fb67b1d5c25e, 0xfd44a13bdfba9111, + 0x9320c444b60d5365, 0x1812473d81c4e7ba, 0xb17145cc882d4160, 0x62965c62b6920226, + 0x452a3a575c9ca854, 0xd171e056eb206966, 0xb89e75c404e7894f, 0x955cd26b7b087efb, + 0xa2229326ca7f8e9d, 0x2cde0e727576f960, 0x65407eb03f603e51, 0xc63f98a0b2f8f695, + 0xbe02efc403b9d018, 0x0d2cf573d88dbc94, 0xd5aee58f43511c68, 0xfc636bea384cd2e7, + 0xc173b35a9f32f84c, 0x79c372aaf51aea95, 0xf08cf8194f84b0bd, 0x9a27134391645d47, + 0xd9c05ac05c41d69c, 0x63295f87db458101, 0x564576229aacac0e, 0xcbe55d5d0aa1f37f, + 0xe8acdfe640f662e2, 0x7f60f951af98676b, 0x4c9f8beea2158934, 0xbc6312069197551a, + 0x2541738968f6c627, 0x4bedb94a827d6b16, 0xe9ab03b64ed56185, 0xd2da92941a1cf040, + 0x1edc93076739af4d, 0x76c50fdb1ab46788, 0xdc9a1960e1adb49c, 0x931e7ac1a013a16e, + 0x850377df32d28d92, 0x601442199e0e8182, 0x8aa6f44707b1fcf4, 0xc6efc079f8949bb1, + 0x682cfd08ab3796c8, 0x6f79f6c65f53c3e6, 0x122b6b77dc6bbbfc, 0x87f2eec4f07132bf, + 0x8514f49ecaebd80d, 0xb4db05bc564a35ca, 0xa162a8d4ee31153a, 0xc9eb645bf966f3e9, + 0xce6cbaf9b862e038, 0x791cb77f15ed7046, 0x6e2cb37ffe7ee712, 0x0227febf9e6a3b61, + 0x6a2128e6959c4679, 0x4f1d813a81424c90, 0xf52fa9df49704172, 0x9fa166d2f65b821f, + 0x6da0943b16ddabc9, 0xf88559bd988e348a, 0xf76f0127896184ff, 0x95252f1ad4422707, + 0x09815eaa25cf5183, 0x46cfc7999ff99e33, 0x62836e6503342db6, 0x4440908e898f418d, + 0x5531d5af9914f1a0, 0x66df770cd09fd3c7, 0x071fe3935e69acd9, 0x0c2d24843199cf74, + 0x07cc5c64a5428620, 0xfbacfe0c1da37fda, 0x5dbee68f873aaeff, 0x04c7243990ebeaf9, + 0x42a2efdc27ff1cc0, 0x3ad2f1d23755e09c, 0x089a6b8ef9f042dc, 0x0bf85598e46f0bd2, + 0xaa2d0bc66c2abfcb, 0x3918667a23a9b953, 0x35f80edf06cbb9a1, 0x19d24700054f857e, + 0xd7ce9a679a9b9233, 0xfbf58fd4f8601491, 0x26274e6dc91be97d, 0xa21aaa9ee84fb5df, + 0x7ed96ec6804c93ca, 0x7467497c6c3eca1a, 0x9071b686d9e94ff3, 0x7c7c05fd0afd2941, + 0xd32265f68cf9c91b, 0x4f69a15be95d241b, 0x6d0e444b739de6c5, 0x887812c45f50f839, + 0xc4066703eb818ca2, 0x0b95ec7b2402ff83, 0x5a849228514e574a, 0x75d4684b6cdb7dd6, + 0x5874cc58a41efdb4, 0xf4c880e9035cc354, 0x28702e2a54d8a168, 0xa88209c224e24e8d, + 0x7ebb3602a8e31f33, 0x9455e2035c054bd6, 0xb01a8668f7185cd8, 0xbd4fdadc2c9eedd2, + 0xa44a6fddd7e3427a, 0x949e31d09cbaa5f7, 0x8774f9a07314121d, 0xafff6fa48d05011d, + 0x10a267c1f4fc9e37, 0xdcfabbe6b20afb6b, 0x14fe314458d82ee2, 0x2108b7b82b6e21da, + 0x4d82823f187b6ab4, 0x5c950756d833e69e, 0x5e42d0d8f3dbc86e, 0x2a2395b30845fcdc, + 0x9fb69e177b3fc478, 0xde37e130dcc17cc4, 0xc5e224e643694a1b, 0xd50175a39f7b2384, + 0xb6152b54dbd3908a, 0x65b6cf1c2f1e5a99, 0x56d63a93000fb88d, 0xbd8d5851b4a9792c, + 0x9bbd779e633b9ba6, 0xc7d0f1b26fae40b2, 0x26898f51edaa4a04, 0x71ff9fdbd6a9bca1, + 0x47c43d2ae7cf3285, 0xfcfc6f8cda2c3c8f, 0x511892a0cfcd7c91, 0xf86d06529830dee7, + 0x39b5e6fd35c1d479, 0xf3d88244ab4dfd20, 0x57625726a2d9718b, 0x9e0b2877d30ca32e, + 0xf0fdf1b1ea5a17d2, 0xb76b8b4c5a4fed9d, 0x3b51e1fce7baca8d, 0x0591f2b2d06e9675, + 0xfe3792673c245535, 0xad6f0291f6393cc4, 0xa7dc3c63d7ba64f6, 0xab76c7fd3fbef7d8, + 0xf6c28386dfaa3992, 0x7ab84be596a6a314, 0x636399d0c840f7f4, 0x3941c136c9e63152, + 0x92af191e855af3a8, 0xba0aab2f37eac87a, 0xb8e137128644abf0, 0x7361b057c5a68dc1, + 0x1d8b8ec4386410b4, 0xd734afeda7e55de1, 0xe53b938ddedfb61e, 0x6df0edab3960396d, + 0x3344ce9a52398f03, 0xe4af4f8b8b19183c, 0x6f3920ceba55ec91, 0x404feb193e820500, + 0x769258611c63daf8, 0x73c2fb7b121d9d11, 0xce0bcc1ada4fb28a, 0x66700335b1880bdb, + 0xdf93464b3b3090b5, 0xa8143f86b03c7530, 0x40cf93ac20e27350, 0x11a6b7b9c9bd8f33, + 0xb11ae12174aaba44, 0x6df5c15d241b1526, 0x26210453901bc0b4, 0x4c09e446d26891a5, + 0xb3af71672117ed27, 0x6263b478fcd29939, 0x731cd17213ad51f4, 0x0f771fb203e87267, + 0x42b2b3d72e154f6b, 0xf6482d16d11beab2, 0xec5563b6a9fbaee2, 0x0a920e157735c24b, + 0x571577d039198db3, 0x919eef1000230663, 0x6a11beef43844123, 0xa9e75a2b9077889a, + 0x561bd98091c73dbb, 0x13cd0132ef8bb3bf, 0xd13e3125037177e4, 0xbb68eeb3fcacdfa8, + 0xca2b44c9fd52e31e, 0xf18789aaec003760, 0xe5fecf334446db4f, 0x73766766c8e467b6, + 0x11a4bf4bf0030644, 0x464443dab5e07bff, 0x879b7edc2bd9fab2, 0x3d6198c188c573aa, + 0xa2dc2394736482b4, 0x95ef17d7909fce82, 0x437f6fe66945163b, 0x896b821d869b79a3, + 0x313091ee36578349, 0x9bb5f920e1a8b634, 0x020f119377514111, 0x2f4e19c9d49ea219, + 0xb54094136171169e, 0x1f56cb7ed51c1f70, 0x325ca7d0ac3ed474, 0xaa880e79900ac4dc, + 0xf92386e8b623bad6, 0xdac9073f5a07eab5, 0x151398e86a7e8397, 0x3f8c7ae3095175c4, + 0x95ed93a654189abf, 0x4dc1b4c37b377ed1, 0x046df154bf4db546, 0xe38bee4f0aaa8020, + 0x4471872210e63387, 0xf8db82de694148e5, 0xda0705a5f4ee7963, 0x653ba9c69aa6296a, + 0xc68e4528934d8353, 0x5c8dde85524fb05a, 0x72ba2a50a3545712, 0x55a64eb6a2918b87, + 0x36e43f19dc610449, 0x5d1d383a4720a999, 0x8af7df437f659fae, 0x64e75e4e8338dc99, + 0xf706793982d889ae, 0x29597f0b95443317, 0x54390ba328167a02, 0x5933eaf4f5f79f29, + 0x0d080e527726af1f, 0xbac6b1cb40a3a50f, 0xc921a49f5689b8d7, 0x8b6adfc772c30612, + 0x45e8721c15c4ba3d, 0xed67b96d9bde4160, 0x48ec4fbcc55c8a25, 0xfe0c43579e09e816, + 0xd6428ca2fa59d0c0, 0x6f34ecd684e1cd8a, 0xa607d15eea7528f5, 0xe72acf0721b567bd, + 0x6813927489c5ed96, 0xe9466b133568fea2, 0x7a11c59b431950f6, 0xdfaffb86826c50e2, + 0x310b389c908702ac, 0xa0835e820d7d2581, 0x2da4480ff1da24d4, 0xfca491fcb67b33cf, + 0x4e1f477159fa8ae9, 0xfd9837b31a14dbd2, 0x53c78d2eeaf597c6, 0xc4f562cdc87aeec8, + 0xd6ae3577eddd97f2, 0x0e466ef38a5a3dc7, 0xf8b57545d0bd7152, 0xcec91bba479b0103, + 0x5f76c2366cd77dfd, 0x01d6dd50adcdd9c6, 0xf3d6e5c217e41c5b, 0x061c765ef74a0c8b, + 0x4e6767db8a1761b4, 0xf6b46bf600122476, 0xdaa86bf838b5a5dc, 0x3af742c020ff68db, + 0x72989e359dd78a6c, 0x6addf861d499b5af, 0xecf97268566a377f, 0xc093bf48a727ace0, + 0x12ea718e66ef41a3, 0x05f36e19a7a83436, 0x731ac21042a99e84, 0xbc9ad524e30c808a, + 0xe1d6534d24bec04f, 0x5cf783fd38065ec7, 0x168f91f83c92e424, 0x374a20fa9ba6924b, + 0xd19dda74b8cc89e1, 0x58e6a9563e8ca842, 0x900936600bdc1457, 0x4bdc076af2d24664, + 0x2ff72053333df7e2, 0x00bb1984c30eeee3, 0xe1c9c3b8d49e7616, 0x13c576c4e216c474, + 0x76b8ef455b215345, 0x8316e7887e9f9ebd, 0xf6f2bb8e9db5ee9b, 0x151a4a7fec7de520, + 0x8ebc57cb66a6061b, 0xaa5a54fa0b3ba61d, 0x2fad664039a69c9f, 0xbd68bcee9235e4f5, + 0xf31c4a0e73026025, 0x151bd5423a5483e2, 0x9d50123c8314233a, 0x3cdfe20d69d5177c, + 0x8355d90500d515e5, 0x4e532429edc16e2f, 0x6660026418cff1bc, 0x7ffed9328ec8224d, + 0x0f7500963d9a9f39, 0x11b0c2f43c91bf13, 0x075b8d5265aef3ff, 0x9acb65e607deb8c6, + 0x3d6bc913babb4390, 0xd6e75a350721e493, 0x40f93a3a6eee0155, 0x0adaf785c8913186, + 0x619c4d83f2e2e30e, 0x3890808f8c0f0ac7, 0x1fbcee0083866432, 0xdcc32c27ffd1aec5, + 0x847d7e75acf2b861, 0x3809337fead1dc44, 0x0eb5e4fb6951638e, 0xdeb7356b149ea4d5, + 0x372fcedb34fb150d, 0xc11d244e475200fb, 0xf8e9549c6ef8bfee, 0x64fe59dc1137167d, + 0x5c941b7b20199cc3, 0xfe96c84c9d460f46, 0xa7be8ea8f6aab575, 0x39ac5c159b2f177b, + 0x2344f7a080e6c2d6, 0x85b97e735dd1dadd, 0x68bfd4867773758d, 0x53146b1cc89d10e4, + 0x0537c51f25856164, 0x296d9a2ba083a835, 0x8f7d7a54fa69bf4b, 0x919d9b99f9a72bf3, + 0xa7ff60209930a276, 0xae8d183f6cf2b9e6, 0x64679511c28551fc, 0x1f211f947d713dcd, + 0x67679a2ffd58b210, 0xa1eac74a1a7f6959, 0xd2846b3cde2674a5, 0xdf5c47e165a51049, + 0x0e0b8d6b210b35c0, 0xabe544e3de2a11bd, 0x8d268cd00033157c, 0xdbf882a0a4e85595, + 0x7dcc08b203d90700, 0xa4ecbd6fac1629d4, 0xee578fd9ee8fbbe9, 0xf9fd2ac49d4e7a8f, + 0xad5dc6bf7496228a, 0xbb8376973dec92a2, 0x2282b8d97d2aab50, 0xecff53b071d25722, + 0x1bfb0a6c1dac26f0, 0x8eeae7cbedd17422, 0xfb233051a240e26e, 0x715885fddcae0f51, + 0x06ba84025dc9a4fb, 0x28a4ae74cc7bb9ce, 0x416b38165c69a9a5, 0x0335c9a572faeb77, + 0x37f404a9c748fb53, 0xbc9a85ec33d837d5, 0xbc1411a6bc24e0b0, 0x2f30cea446f98c52, + 0xa3117eb686385dfa, 0x497cf8b437702912, 0xb4e5265530d89678, 0x919a968fd7d27281, + 0x3d586c14f455bd98, 0xeaa0018a04300f19, 0x9c7aa90cc9480be1, 0x059c7fd3b1c54551, + 0x06a6107c61a9bc11, 0x9ab8d068b4d0367a, 0xac26370b1f488971, 0x5e2b58af4cce77c6, + 0xc0aa0f7392e66780, 0xae5e89edd0ed1861, 0x52a896b9d58b35d3, 0x8bcda04bdf6029a5, + 0xa9be348a16c5bb31, 0xadf1e13e1fe1934c, 0x3aa3382acede5375, 0xccbb661bde129d28, + 0xea3dff45849ed9fe, 0x5e32c5f961468634, 0xe8539d90ba7c70c1, 0x5d16e3ad61e75bc5, + 0x424e32bd67a568c4, 0x83eeeca0a94b6b54, 0x87849dcd93c4cccf, 0xb74e98267119aad2, + 0x2bd329484e38f4e5, 0x9d0f1de5337f0b36, 0xbe58e9be6815a8b5, 0x213ae6d2f4548d8c, + 0x070162a7a3625558, 0x70ff896785c6b109, 0xe978d44adebfcbcd, 0x3f636d9b2e729bf0, + 0x69b897da2c193bce, 0x0782f61b24954551, 0xbf6bedd9a660073d, 0xbc9e855b45aafa87, + 0x0ee8bbc21337226f, 0x6dcbfb9a5dd57fab, 0xdab95f3009aeefcc, 0x1b414043f4a9abb9, + 0xdbedc554ab15a879, 0x3e04d42bb877ae7f, 0x37172ebd734a549e, 0x07d41ace0341712c, + 0xbb09f26b557d43f0, 0x4747166d305c6fce, 0x25f6acfcdb5e9fc4, 0x37c9b4be71a2f8d3, + 0x4947a7dae631f2bd, 0x9e86e6a58c7d96f7, 0x128ee7e03252dc46, 0x556086723aaaa65a, + 0x99534e170fb5ed7a, 0x1249a5430f5d9b37, 0x0aa6e33e8113d4d2, 0xcd312093ad077d3f, + 0xc503bf6c6bdfa6ef, 0xc57367b6f2faecb5, 0xb130efdf07cdc8a9, 0x9635f8c5cade84df, + 0x3abfe4668adfb949, 0x2e511d35df89b99c, 0x2b169eb3b5ee57ae, 0x5087b467ee6ff2ca, + 0x24ff6ea8b59c0cb7, 0x8a03b9600151822b, 0xc6b4091feb0af87a, 0x472020b83d8cf8f3, + 0xc66e299911b3fde2, 0x157861e893bf8da0, 0xfcf30d920288f598, 0x452b2d3a914d51a1, + 0x5e0805791ef14f89, 0x58d919e399c533b5, 0xdc57f04269948bf0, 0xa430cbfdb4dbdd23, + 0x57bde28c7bc18715, 0x03506efd2ada55d0, 0x9ad7bdcd88ae349d, 0x6ab764209fd23309, + 0xaf2d628356b3942b, 0xa65165691fa22bc6, 0x670f5d1d2eb8ec0e, 0x61a5b9e0dd0b9abd, + 0xd1a2fd4132e082f1, 0x7f13d496fd6d49bd, 0x79fef238c5ac037f, 0x559dc1c23a70f87b, + 0xa54e57189ed68722, 0x203bc4f766aa7df6, 0x5cf65f1dd9110bc6, 0x229b2b4fb12a6ee0, + 0x2d420d7ee48f8e50, 0xeb7e8aff399e2fcc, 0x4ad97fdd048bab03, 0x75113873929adf74, + 0x441032f6686d93d9, 0x1d1b3f8a3a700eac, 0x11e824b4205a8ad9, 0x0f67596a124a531f, + 0x09e6a523613e69ef, 0x9e50ddac2bf41ea8, 0x4128bda1f4a531f2, 0x26dc4eb9fdc50950, + 0x6e9de3de8fb94e6f, 0x88d3c585bc5f308a, 0x136c58e5b6a1c549, 0x2b0a8ed634ca5986, + 0x801fe7ef5e9e6200, 0x0966b21fa23ca7bd, 0x8f54bef1e6850b84, 0xdfb90a9326d530e4, + 0x86d364f678ee3e34, 0xd9edbab3d82270de, 0x7d44477cf130e3ef, 0xb6845c99e5b606a4, + 0x9ae8ab71ee87d5c4, 0x168aa1eaec00fa92, 0xdda615718abfdc2b, 0x758e681bc0730818, + 0x5405cd04f975cfa4, 0x635e16099b6191e0, 0x7913112f9fbf2869, 0x63a68348673578c7, + 0x84a724e9eebaf7f8, 0x2b0d14bb9bfafe20, 0xce4a911c5079fe90, 0xab13b105a2b38a84, + 0x0349e6c12adfbec1, 0x2e2eb31ffb75e55d, 0xe9ac3d6679300a8f, 0xc43911d328d7881d, + 0x0a8ef5de52f939a2, 0xb4310516f4d16510, 0xf2fed39097fd3dcf, 0x127567e24159e59b, + 0xb5a5445c42a8633d, 0xf901e287c2d6276a, 0xafc670096e5dfae2, 0xc41b161ce0c2c3e2, + 0x717ef81e8677189b, 0x3ccf9f48c860a3ed, 0x95a504f198e6c414, 0xb3f6a285c436cf10, + 0xb3770e07e1d2ecfd, 0x0f64384831a46362, 0x2c028dfe16339529, 0x4183f12f1f840bfa, + 0x306d031d88e383eb, 0x8d8a4f890e33bccd, 0x0c828285a9d374f5, 0x8b290c4cd8e5278a, + 0x95186d057e5d9602, 0xd19e6a8b6c29dd4f, 0x55ed680ad45a9044, 0xe0bf034973f37a8a, + 0x18b1432cf1dfdcc1, 0xbdf440eabeb0a115, 0x068d070e58829f47, 0x1d8a2cc894bd0f55, + 0x038395bf7bfaaa87, 0x78278b83d4495d00, 0x2f7999decb6be7a7, 0xa678411eb7eb9569, + 0x8a9927bc1ca9ac19, 0xbdd28586f17d7f9e, 0x2c0b6b86f08943d2, 0xdfbcfe3671d1269e, + 0x05b40bc64c6bddf7, 0x785f45d668320adc, 0xa5b3d90424c9003e, 0xe976fb1158449299, + 0x46849e6e305e70e2, 0x6469d13bee0ad7f4, 0xeb287966072ea01b, 0x6d7cdb617f998e4e, + 0x94732e60a03443d6, 0x0d90a95980ff534d, 0xe6c2beb47a6c8986, 0x66d22eb4912c3508, + 0x45ae2c4685e0f4a9, 0x87e039740640a8ed, 0x439d10cf7ee1b7cb, 0x3e5bfddaaad1fdbe, + 0xe3cfb17658bfd01d, 0xb7974424fae704ef, 0x51638743572461da, 0x0dc48307e889ebec, + 0x07e812045160e335, 0x6e4eab3cac4822f5, 0x17927ae77a1f3b9f, 0xea5ed1993fb922ea, + 0x2f5bbe2f5c02b613, 0x045cb8bbb5809d4a, 0x4a4be3af7a00bdb1, 0x84630e81a24f4d57, + 0xd45a177415e71eff, 0xa9f8e70f617562f2, 0xe36b1c8942a06fb2, 0x9296e915ab30c91e, + 0xd82895f195cfffcf, 0xbae2c86ddce7b51e, 0x11f29b4ce4365d98, 0x9aaabeea5bd28c31, + 0x7bf324d98321b34b, 0x7995897e22e37566, 0xc95efad5fd7fa1c2, 0x8c81a4bfeca3718c, + 0xfa072b9d11c206aa, 0x42786b644d3cafa3, 0x8f26c3bd7490aa6a, 0x3d877dfa3692c58f, + 0x068958c95fe61566, 0x6d3a8a70b4a298d9, 0x598678bd4cb8a0fd, 0x78b48b2a3e73ed64, + 0x6a3093ea87cd9951, 0x913c8d4c0b268870, 0x7be8887e87792ad6, 0xef2c9e8b104f4649, + 0x9010892e26058be1, 0x4dc2fbf14d717bed, 0x0e1c143afd83af41, 0x66fb8091e5b8c2e9, + 0x3d3f2a21a0d56f26, 0xc06b78cc9df135ef, 0xbc50f415722f81c7, 0x000064321e57d7e2, + 0x697b8ef04de06b7f, 0x66ac213f321bd8de, 0x598cb36bebe5316f, 0x30f5df2ea314aefd, + 0xfafcba6469eb7647, 0x22bf4d097ddf4e19, 0x75ccf3f5d4524826, 0x95dedc7ee1819def, + 0xaa6837e744b0833a, 0xa759e4bf83e997c1, 0x11d120e7906f8f4b, 0x53b8a64058667d97, + 0x0085507767790df6, 0x69a23b5bd1b0bbfc, 0xe5e8b4b48b0435a9, 0x1c9edecf127f30f8, + 0x36c66e00358953fe, 0x03d69e2816f790f2, 0xcdf8f67ed64fd555, 0x5299c2791c1cd166, + 0xf4f306791b27552e, 0x4447a0df88fd4383, 0x20f4ddf4170f8723, 0x5c03d900444946cd, + 0x9b5c77907aafd14e, 0x7c22d7b11f2e14da, 0xe7854515bf7450c9, 0x137208ee64a36434, + 0xfd27ed7318d7ecb2, 0xc9780e945e333f9c, 0x1d8402599550ca24, 0x80786a12d6c38fcc, + 0x48c68f0bc59280e0, 0xe24a85667f8dc11d, 0x60597bfbaefd4ed9, 0x050173bd7541e005, + 0x7a1aea79da3b7cd2, 0x9243ee1f2b583b42, 0x47d21bf80bfd4d0f, 0xe35d14b1447b1924, + 0x42787d9aa02aa6dc, 0xe902209ce0ee9cd0, 0x5816e6034e082657, 0xfa51f3ac039fdd37, + 0xed67b14bce9b0f15, 0x55bcac07a5155709, 0x30893930574af12b, 0x730bbd04ff750567, + 0x52c147520ad92348, 0x734ca317849817e2, 0xc56559632480a49e, 0xfa9fbc276626346c, + 0x60692110bd413a92, 0x97803993888c535e, 0x868f3fd066c81fef, 0xc6015cce976ba364, + 0x1cd965cc964ef93e, 0x10bc60ef431d985a, 0x3b0115cc9104eb53, 0x338587c191cb1b1a, + 0xf51aaf427b3ca399, 0x9ffbfa8bf1ace60f, 0xf19d48b045de9f9d, 0x87abcbdb20e32ffa, + 0xef9b1d47a064fcaa, 0x84492111223d3688, 0xe9d2c7683419ee37, 0x94e566547fc5ae88, + 0x372bff93ae22fb37, 0x93b1c1d4a19a7e91, 0xe7a314e3d311e3eb, 0xc54386dcc4970404, + 0x266be3285384fd3e, 0xd574257da1aa92e3, 0x7331ebd79d6ba610, 0x2c04c2def0dfc869, + 0x85ce2ebc0f01ca5f, 0x289b9fead4b781c2, 0x4782567254e798b2, 0x4b16165523a317c7, + 0x3db5d38f8fc6e59a, 0xd4cd6e994141d733, 0x891e81a803f1f0be, 0xdeea97782154bef1, + 0x195b3c9318337164, 0x9d0031c8c6cad2b4, 0xca05267fdedccba7, 0xae81f62168fee652, + 0x3472cf0b0dddebbc, 0xa28cfaba3efa4a46, 0xe5747504e62e6871, 0x9c82afee2a061398, + 0x67f720fda968f103, 0xf8b887e1b316cbf6, 0x44d8c036ce887a49, 0xd558dcd93dddce99, + 0x5b51c318bd834af3, 0x8526f60ec2ccc299, 0x87a3eff30affca8e, 0x0ba91e43717b84fb, + 0x3adf44d3760432e1, 0x395ee745ceb5d106, 0xb81032c6c38e5dae, 0xba7aeae0181e96dd, + 0xf854a79456d838ca, 0xe163dcd76c1e4d76, 0xaedbb46659e1b0ad, 0x04376d99900e64ed, + 0x5c52f136f72cd57c, 0xcfb366137e7e15fe, 0x230a2cbbed0df0ec, 0xce0c8b48fb5e5d4c, + 0x1b41bffb8c1a8e46, 0x8621e947d81410af, 0x8565b165356e477a, 0x5f87ba7a836de326, + 0x5eeb50efcc085deb, 0xc62de0b74931b33c, 0xcdff1122250095bc, 0xd3c03b4c7a7a9e77, + 0x416bd0c9da7494c6, 0x367146a26a394e57, 0xe634aee9deb5a5d0, 0x29836afb5b333a94, + 0xcc12406820529fa5, 0x8b8ee237c0dbe52b, 0xea7b598f284c126c, 0x76ad20877e0283d0, + 0xe64d4452a804c184, 0xb9ffa95d4d5adfb9, 0x39fbf340bb589620, 0x0827fa2d6e97bc48, + 0x8e53f04ca8283c1f, 0xf78ae0024a4eb567, 0x4f620bbb975872af, 0x43487ec67891db0c, + 0x390c7518de7f531d, 0x8e13e210b4eee946, 0xc632f48bfd83b5a1, 0xd1fb1b346c4b7778, + 0x599cf3d21841ab57, 0x9cc670eb791beaac, 0x927b41f9d30f5366, 0x7ce93591d7517bc0, + 0xc8f7e93d485bedd3, 0x244fec6d4960ae6f, 0x04214feaafd455d2, 0x5a5c5a85d543c6f0, + 0xc9f68fbeed3747eb, 0x5750452003eff206, 0xced2c7ec38b0998d, 0xa25937dcb42c364d, + 0xd540872e1339e292, 0xabd932ebf08a1de2, 0x167dab5d123704e3, 0x5f75b1928c45638b, + 0xffb4ecc40fbf7362, 0x5dd8340469847c2b, 0xc01a54132fafe9f4, 0x40545ea96cda0969, + 0x877fa2717de5afc8, 0xf8fb4bdb6dc75454, 0x43f62d2c388ce1ea, 0x503f183087dd71c1, + 0x2848d1ed5ab4f509, 0x7e14aa36fa13d5b3, 0x4121804c1e17225b, 0x92c53d20071f0f48, + 0xf0cd147ee18c5048, 0x9b90ac8540018e19, 0xefbfea2de9392093, 0x60b91be6992762db, + 0x142538a433c02a27, 0x61c0dde589e517cb, 0xd7503f62e8f344df, 0x0254a4f0b4db3506, + 0x37bb4a6f6368744b, 0xc25b395c005c463e, 0x19dc39533b04654a, 0x1fc70c2a5b4180dd, + 0xb8d4a7462116e6b9, 0x2d9fc71264ff4afd, 0x6e46a16929cf462c, 0x9671d90ae4eda2a7, + 0xd3c3304b81b8510a, 0x9ce039a2885d5302, 0x7c67dd3b27391e68, 0xdf07fa8f23c10934, + 0xc58d48167de8d287, 0xec9d57035f1c1a8b, 0xdb6cc6bbc0bf75e9, 0x79d5b76e73b7c1a1, + 0x1722754f7c7d937c, 0xeb889450cf1f2aae, 0x1926528f0d42a4f1, 0x7f063bfda112be95, + 0x2464e5bc8e094fa7, 0x62eef100aae9d966, 0x6a338f4abb909862, 0x2e82b366baa2bb7a, + 0xab6cf5bcefbf6ab2, 0x5ba3629fda5c7f7c, 0xdd9e1bf0b7f4822a, 0x42ff2a6eb0d95ac0, + 0xa7cbc5d6c855b232, 0x2b3224668aababb1, 0x7565233455c998b4, 0x43ae43ccf52e25be, + 0x2846d361e6c032e8, 0x03fdbf1c338b572d, 0x25df6aef1feae7fb, 0xef017681e95cf3de, + 0xb2e697747074befd, 0xaf32b9c80a0c3f03, 0x678839067abe41c3, 0x0fdd53151d36f272, + 0x15fc4edaaf4a6fbb, 0xfd16430284e9528b, 0xf3614b96a7a4b04e, 0x45af1acc72453ebd, + 0x43a36616f4fbb89a, 0x7a3b9011b88a273e, 0xa629d90a1c3adcff, 0xb1b369e10c2b48dd, + 0x16a044d6e56a6f11, 0x01bf9e4134253fa2, 0xf7884b87d7114ee0, 0x17ed7f15f448a8f7, + 0x6417a1f9779f788e, 0xdad149d71b9153a2, 0xde0c308202cc9a30, 0xd96a71523e162080, + 0x6324cb30fb28c47a, 0x0922caa86cc2ec59, 0x7cc8951dccb472e4, 0x7f84c9a202c20787, + 0x3557cade4d7096f6, 0xa6d30a9e1f11f8ab, 0x9cbfbe17be102a7b, 0x342d33d62994804a, + 0x1dec2fa6cb5fe821, 0xdca6556377ba773a, 0x7cd8e4913b12a93e, 0x99c25678336273e9, + 0x6077ee7acdf8edf6, 0x7158e061ce06c755, 0x99b5f6ac2da43bcb, 0x62dd6d1adf30d943, + 0x95e3d0fc58d5e827, 0x719ab213bcebc7ae, 0x11ab5f64f2040ed2, 0xda88d59b9687c929, + 0xddf9aef85600125c, 0xaf79cac3f8ba37f9, 0x23c24db74b6a3dd0, 0x77b3175aa1311d22, + 0x3a8ea3914c8b8d78, 0xf04c5489a1709c88, 0x093df9d686d39b17, 0x088e2272b21d3515, + 0xfe6366a5e44ae8af, 0x0eb7839945cd72c2, 0x20f95094ce1bb48d, 0x4745b5566583e0bb, + 0xb311e655b0b3cfbc, 0x1b961ca72b7bf836, 0xf10b78ba77d11558, 0x52fe91498720b153, + 0x67e6285891ae559b, 0x0d9779cbd0049046, 0x983a697dfc334e08, 0x96868c3a92e5249a, + 0xd5149512cd7c4d66, 0x3b0daa00923ea8da, 0xb4a9a6068292ab62, 0x3cb13e42019b22c5, + 0x10d420ce11922098, 0x1ba7fad3a2219313, 0xa67e9a5073bc424f, 0x576258f9b23e21bb, + 0x02ac562bcceb7eb3, 0xe71dff8823b17988, 0x948585759c559f49, 0x7f4d8d1a9467032b, + 0x97cf8e06be507ba1, 0x93724ee59be2d236, 0x72f35d64dab7d6b1, 0xcb009bb946dbffeb, + 0x3246fb862cc771ab, 0x5f46ad9b19fa6e5f, 0x023915751b60fc22, 0x4eb0d10493845cb5, + 0xa7303eaa80b24480, 0x7249baa480eede23, 0xd7384df0f003db4d, 0x8a19ba46f9ff6077, + 0x1f44d8bc105288b6, 0x8778fac5071f13fa, 0x3f240544d30f003b, 0x198ffcea832b2b1e, + 0xc0237367ae54ca59, 0xb6e573c789cf5fbf, 0x39fb4ee76bdb80a9, 0xd3c02a7d864fc368, + 0x657f534754fb7494, 0x587cab36437ed91e, 0x54641d1f93f03b38, 0x1cef325f775da9a0, + 0x898a903cf3baed0d, 0x3116753d4c4fd02b, 0x5a421f8f23e658ef, 0x1bec6ad8c0ae016d, + 0xce11a2be8b4e2daa, 0x24e34a8b68939aeb, 0x3bc8d7b11cf7fd93, 0x887a3bc167708e78, + 0xcfff67c74ccc9f7f, 0x05b75464e08a0f35, 0xff380401e1e15ab8, 0xf9e424b6f064eb4e, + 0x52ec2040ef27d012, 0x41187b8ef53db396, 0xb4487b793a19aec9, 0xc5525628e7cf2705, + 0x5f6cbb1b9dc8304d, 0xaaf545a2c9eac4f0, 0x2a3219a9b3f3a615, 0xd3410d6d12fc954a, + 0xece1b4d443cc24aa, 0xd8091ea31ed0bdcc, 0x0b469c9a4ef07a5f, 0xa33eca769b8a0009, + 0x47f998365db7b461, 0x13f5954c9b87186b, 0x4b7a3fb2d922b667, 0xfc661d6fe148d9dd, + 0xe9e923cabcb019e2, 0xe4fbe73744b47e23, 0xce2c505a6228b5aa, 0xdc36057cd5464408, + 0xb9ac58cddc3b4771, 0xe332ba8ea2e27d2e, 0xa2d82df50e6a9dc8, 0x3884255e884aead3, + 0xa74dd09504b4153b, 0xeb7e5393d7d39b56, 0x6d662fa9481448b3, 0xa9576b2487d57fb5, + 0xe6b7ab871b1ecf34, 0x89012daebcc8366e, 0x26f22a4398912f1c, 0xe0177197638e6d77, + 0x4bc56d7a5fc53ee5, 0xe886fee4458f61a7, 0xd3161c312f11d07e, 0x64bbf81acb0940f9, + 0xe74a618485400980, 0xfac95e92eb109a94, 0x90a6698f6ae1d132, 0x2f3f6f563bee83b6, + 0x3ee0021384dc37e3, 0x6db23230266b871e, 0x4ff691ed02146b08, 0x056113b59714e606, + 0xb139b12bd23e98f9, 0x5c7566de20e925be, 0x9b697910bda9c5bd, 0x462503eb9ffa92d8, + 0xddffaa79064a2511, 0x7481c720773b648c, 0xdc9d99fafb1ce957, 0xb4a25ad1553af1ad, + 0x135ad0d1c6c3726e, 0xb9b09ac29894717f, 0x45238640d7d3cdf2, 0x184082bf7c66ddcd, + 0xc4448ba6c72c0b8c, 0xe4c0b30d6f30213a, 0x0d7b0c070ec059e4, 0x997dd0aa879a700f, + 0xe708690af0a5b2ab, 0xe46e2b9deb405ca9, 0x84cf177586786f4c, 0x8746c5d4669b4f03, + 0x9e8f63b21c30dcf5, 0xf28dd88c0e2df952, 0x8ef7f9ae70cc1b27, 0x7cb39d80ec7dd5ae, + 0x068d076706ae886f, 0x5b20538ef0cb93b6, 0x55a1be3cf5669ca9, 0xf0d9eea3711b5e7c, + 0xfe836b8b1d393808, 0xf92ce56180745a90, 0xa9757b956680c2e8, 0x00f568ab8d2cd1dd, + 0x315ca544b3d35e3a, 0xfd6e2ab416ec0a8f, 0x45e7b5274782bf5f, 0xbdba55ce5084059b, + 0xa41de2ac04d215eb, 0x984b202cae303924, 0x1e8710c28604dfa5, 0x323d2b6253ed5f86, + 0xb5d8379e42a29f81, 0xdb4740ac8d56cd8d, 0x7971017b601c3d9c, 0x71cd3139d8e32a59, + 0x87fcdbffe0c5999d, 0x8395605c664b4186, 0x77ec02bc3b7d4ad3, 0x78d5ad6f4c1063e3, + 0xe28b24b9437aa599, 0x52ae8288bc4693a9, 0xf18de7bee9767d6e, 0x6e55ad05f2cfc66f, + 0x3c6e7c98ffe1ccc0, 0x9821ccdf1c608aed, 0x12ffe74f8780752d, 0xe88fa973860b19a3, + 0x304e3a469702273d, 0x75d16c6d5831594d, 0x4710281b4a96ef96, 0xba1a54451d1fcf83, + 0x7a57af4cd9be48b4, 0x256dffe831f24200, 0x5f6535d5b70ca5fa, 0xfad8bd481074e393, + 0xf786bd40cc03eb1d, 0xe16ea21ce415c679, 0x762085c79be72cc0, 0x57b931e8d7c28501, + 0xfa21443ef4eb0bd7, 0x98c7a0d8e0d47471, 0x12a978f1fa5748c1, 0xfc7b4c8f70130cb4, + 0xfb7493025a145b34, 0xafa60f9dc370c930, 0xbc3f1b24e3ae226a, 0x207f02aa10f5e0f2, + 0x6fe8b366a117a48d, 0x4e4b77088f032817, 0xc05832b23371914c, 0x5eda80353eef5336, + 0x8eeb36bdc4b671da, 0xd80fd6666b625226, 0x42586c95e7e72e76, 0x02e6789403f814d4, + 0xbd988333ef94cc57, 0x393154807bbfe536, 0xddc238b29b027009, 0x3f4db2aa543a7c2e, + 0x122449eb192560d5, 0x04936cbdde017053, 0xdf3d616867318e57, 0x52f3c8b871bcd541, + 0x7ec7efe176c45199, 0x759d9672875cd231, 0xc1dace190b3596d0, 0xce71663e37d84344, + 0xd67aaa73b5cba2dd, 0xab99b279e83c8eab, 0x6f61d6084dd77cda, 0x710d71fbe23a2869, + 0xc0a95aa344ecfa82, 0xce2327e6cec09e9c, 0x22ba865865d49527, 0xabda4ac625b5c663, + 0x639fba1405f3dd28, 0xd17f891563b9ca25, 0xd9108e1465ffd277, 0x8db80a474df18b4f, + 0x09b97d8088df91a0, 0xd75befcdd819bb76, 0x6a52bf5073422746, 0x2c0f5acdb7eff209, + 0x653dc56ad309d0cd, 0xe005c74b266ad71e, 0x52fe1945bc2d26dc, 0xd5a0ee6782c88fd8, + 0x33a90c4ead7cabc3, 0x7eaa0b11710540e3, 0x9ece3e56fb7205fb, 0xd1b24364a776752b, + 0x366873c7aed8528a, 0xdc2adb9291ff0b4e, 0xbba86e4d46bc6982, 0x9004024708a9fc97, + 0x40437d346e642ecc, 0xb5fe0234842e348c, 0x3d8d988b33331c55, 0x4468fed083692609, + 0x69c7924ae7032661, 0x3cb5a272415584cb, 0x71f68ec396df8250, 0x3ecbbeeef5a64f86, + 0xc44c4025fea6df6a, 0x266f36840398ca39, 0x18cdeda71e24d0b5, 0x392e4459569bc044, + 0xd817103eb79d3c5b, 0xeeaf5bd4b34ab48a, 0xb23e366eb02efd08, 0xa76d15efba0ee3aa, + 0x643385dc6631ea5f, 0xf9f3ea4fcc90f774, 0xdf91cbdaea94c9b1, 0x61c24b6e6c529bf8, + 0x2b0ba33a34dd834f, 0x5166437827f0b7f3, 0xb276e6c080cd3ca9, 0xf32f2fd75dc7ef5a, + 0x65301766452a4cf3, 0x9f08589b940806a5, 0x3d5a0448c28d01c8, 0xf8483423db20e1e6, + 0x3b4c41b97a1b9f21, 0xd28c9828667536b2, 0x8b2da57b6eb9c42d, 0x480bac61090498ce, + 0xf672e787a53bffc1, 0x4affdb576f493607, 0x2d0c595865b3777e, 0xb793dc92eab15b00, + 0xfcfc57fb54391e6c, 0xe7a616260ab04681, 0x707521a9cc83bc8f, 0x9030fa3026a0e332, + 0x4aae9d7a5a0f6398, 0xce077c97ede3f843, 0xf11af727b514dc9f, 0xa4d582c2e73aa860, + 0x835218ea5f4f7309, 0x9cea80edeb42204f, 0x1e0a719b74cf86b0, 0x775069db679182ff, + 0xbbb2c53b191f616e, 0x235ab3404d23df0d, 0x786805e2da2a441a, 0xea8615711f8cc4eb, + 0xb7fa48324d531b3d, 0xdcbe2e3711334ea3, 0x395c033f5f1a5ca4, 0x3a48029edae75753, + 0x42bc9029ea0d399d, 0x0de1e43051afcc3e, 0x207da739e84c39d5, 0xe260f451cdc13d34, + 0x292c84ee55da15ee, 0x0f2654d7ca29960d, 0x9927c37d3f2f30af, 0xd2e1ea2c8112b0b6, + 0xdf25c6879e06d79d, 0xfd5b7a727ee9a2c3, 0xce35ee6826e7b941, 0xa9b149e329b90531, + 0xadcbc7772dbc05b6, 0xf356e3d9c1ea96c3, 0x2f4c3f6f9e524c08, 0xf2f9ac8b8c4b312b, + 0x4ef2ba6905d0493e, 0x4920a49717486be9, 0x75231dc0e41522ae, 0xe6fbf92d57aa4d8e, + 0xcb4655f12b362c78, 0x28be05e636e0efc4, 0x12540f7983676ed9, 0x2fb4460db9306f37, + 0x07b2bad10c4b7681, 0x6cc414cf58a6df9b, 0x16e7409a43b1597a, 0x22fa7610217f497a, + 0xa22941424a88b7c7, 0x6cafb5dbaacc680f, 0x7472bf534d96a5ed, 0x5c0b7cb51ea4310c, + 0xc3dae0e5893a81ca, 0x874d074f518128d8, 0xb8325b9efab2c958, 0x43a604dbc2bd0297, + 0xbded34f64fd696ad, 0x93e31bd548e8ba22, 0x7997ba234f736cee, 0x3aa3e18696f9d59d, + 0xa61cd14bfeab77cb, 0xeeef56910e12f7b1, 0x966a66f1e2fa908f, 0x63be60603cb5ad82, + 0x182d4d3ae256dc10, 0xf279c1c86b0b28d3, 0xfc8104a2393a5f36, 0x56c2e5ece6a6386b, + 0xa25c9003753b1995, 0x80f678b3ccd7a54e, 0x54e7eda1ca0dc5d7, 0x1ad85e67a1a6b48a, + 0xe4bbf78aa0140a30, 0x69e14d0475fb8753, 0x3bb8e67f5ea3cfcc, 0x16d3afb3a12bef63, + 0x246915327f73cbc1, 0xb50265f44cfdf8c4, 0x65d23fb3e7fbc190, 0x0dd28999cc30ed6b, + 0x7215ca65469fbbfd, 0x6de8a207f555be62, 0xa77630edec5e31f2, 0x921c1ecfd82b0fb2, + 0xa7bca763df2901b5, 0x2cd4663a28c1f99e, 0x6cb9b5ffa97114c7, 0xf5eaa4c7a653a559, + 0x96584b1424b27936, 0x4b1be5a69c4e1a85, 0xa8e3916bfe6df1dd, 0xd66580508bc2ea8f, + 0x7ea6090fc390e159, 0x16f9d33f1cab5bb6, 0xc892ad2e4564131e, 0xc6bfea2734606cd1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46b305b199233b13, 0x8a1ba49ed975a8b7, 0x4aca364f2fee77c0, 0xda471191557e63aa, + 0xf5ea671c9e1c93d6, 0xec2cf231021f3291, 0xeb1c1908821111aa, 0xae1c9039f3f894c5, + 0x817fb54d40646417, 0x39334647d4f0ee09, 0x47388d9c75fb2476, 0x1e78f60135ea2ca2, + 0xf1957d26e8359071, 0xd7629b1cf9001909, 0x7262c5514acc9949, 0x157a64db3bc9efa2, + 0x6bb34a2a3512f3b6, 0xe09e0909bf519eb5, 0x94cac4aa92c3d75f, 0xd361e2d0ac5f3e14, + 0xd4c32942aed8270a, 0xe9688b4f22376316, 0xfcbeecc1955809ac, 0x861a23f6ba21a38f, + 0xc75f6d924f570b6a, 0x6cd1f24d53508ae9, 0x4b970293ecb82a51, 0xb5d008691e149e00, + 0x8ee79db918181531, 0x32736f1148a9dd71, 0x2978c080cc482d2b, 0xe8802fc47a504644, + 0x6b1c2be52a831b63, 0x8ec6c4dd3d408aa7, 0x1d0d174c6096afbd, 0x34bcfa010a1c859a, + 0x40e198db45391cd7, 0x3014c01cb9f272cc, 0x718c74b6968eed96, 0x63f3c5aeb963840b, + 0xa39aadaf366cfbeb, 0x4918f4e5fe42a6f1, 0xcbfb76e0a356fff1, 0xa636553e88abe702, + 0x1466ae8faa831f31, 0xd49b41ed88f763ec, 0xdf15400c2017b48d, 0x0c1db557d692dee8, + 0x9c530d5875e1b88c, 0xcca2bf7e9bbab585, 0x41569f407f8b3593, 0xa04983abf6d97450, + 0x504022c4cd86b957, 0x45d74d8c8fc38f0f, 0xb109f7be7e0c15b2, 0x4c583cb18f752903, + 0x0a86f15c86cc2b3e, 0x0de2dcce6214549c, 0x86e30a834b90fba1, 0x9229c0f4c92946a3, + 0xab54c2d8a79ff8eb, 0xcce8611ccdfe7ec2, 0x2558a52972fed1d4, 0x6ae9483cd1c0f7e2, + 0x6a4dc943cc767105, 0xf4fbe0043c601f17, 0xfb7439bb0bd88f68, 0x255b3bba71d4a8bf, + 0x0e91731e69f8ad65, 0x59ac414a31e6205c, 0x87d9ccbf93bc14fc, 0xbdbdca4f647e33a9, + 0xb337753f2a3a0e65, 0xd624b61fe95fb2cc, 0xf8dee5a47bb63804, 0x33cf9e1ceb76b398, + 0x33c3fab6ce91f7b7, 0xcef03cc3e782489b, 0xe8f0482a4195afb6, 0xfa27604d59add7a1, + 0xd5ec96073bee31be, 0x168935fc5dffb2c7, 0xb006b7b27a8e5f47, 0xf6be155f8d4c9835, + 0x245ef05dc890aef8, 0xdaf2d982d6b89f5e, 0x2ede41607f7c5d5d, 0xba18fbf8892ef2a7, + 0x93110a39e2311358, 0xd225ff1e7ad96881, 0xa5c6172432d398d6, 0xcc19e6943e762e0f, + 0xd8a506c8c9c8c076, 0x48ef0a60f27ad126, 0xcc555cccb80b8cff, 0x385165df597f9fa2, + 0x1d98b5724fd85f58, 0xe8fcea90a29e9aa3, 0x401ef34367c46556, 0xd48e8a83b33bd1dd, + 0xdfbf0306cf45621b, 0x604512c9bf5ad55a, 0x9e9679f774224aa5, 0xb535214d9c9ecebc, + 0xc869e38a17d41550, 0xbd256584e5ee7a09, 0xb20bfb0515fedd37, 0x459cbfba8d57f083, + 0x28ad3c494459c894, 0x32485ecaf48cd85f, 0xdae598e4edc0200b, 0xc87d30085e2a1062, + 0x8dd9f18abc662034, 0x31da0cacaac31d41, 0x217f78d2480da178, 0xd2aea0f2fde82335, + 0x4ca2a068a2f4b3e6, 0x7795789d574640cd, 0x6845173348480a28, 0x7e0f590204c26480, + 0xa64ee4fc016fba8e, 0xa1b6811a60c947d4, 0x53e55d2db6393893, 0x82555ceb8426e35b, + 0x31814ccf6d101797, 0x1de1c9ae8d5a436e, 0x40cc3f65d5b66d1e, 0x09189d437f46c334, + 0x7f613aaebb332521, 0x1c59d41ae3d1d69b, 0x7b1e16cd572700b3, 0x9e949b46f14a6120, + 0xb1574e0d806a8d63, 0x897f5c8360d16595, 0x00e86eb5f5b6c911, 0xfed5858dee4596ed, + 0xcef1da7156c75dcd, 0x32495703a6ab38b4, 0x59c7b52aafc41da2, 0x4562be8af9bd83a7, + 0xe5652a8454e80e5e, 0x09524c8f8015d832, 0xe5582f0c01dcb2c4, 0xa14425a4cded8742, + 0x1d0ac9718982b8aa, 0x2e150f935435957c, 0x6730954d4e84caa7, 0xb0e2f3f0152a07b0, + 0x53b9933a1e044919, 0xc613700d0633324a, 0x5582213e2fcea917, 0xc2daea2814c323ed, + 0x03c9ac5bb579b8f2, 0x7895638b272259d3, 0x7fc98ee6005c542b, 0x4ae8c4714c58c9bb, + 0xce7cf4094653226d, 0x39e95dbb5a00f1fa, 0x1ee2464c5fe5536b, 0xd3f81973dcafece1, + 0x69c04d0e2dc68730, 0x4bdba13ccc250b76, 0x2357a1a9d34ebb44, 0x12dab8604c50e5f1, + 0xee7c020012da6563, 0xeb39e37ce0dc9a9a, 0x1e7502ad31c85fc3, 0x30c281188e67a317, + 0x1f05b49d22c66288, 0xc1baa152e1c07407, 0xdc69fe1c64e35150, 0x1c1d55329f2915f1, + 0x7c7b2dcfa4d0bcb7, 0xc9be58e0814c10a3, 0x285655927622c5cb, 0x414edfaad0e9e751, + 0xab86e2768cc538d5, 0x417631bad2750210, 0xaa7192bfd7c523d2, 0x69663de0b3dca8a1, + 0x900b9bb913d9af83, 0x2345d6d25703d1c8, 0x27569dffae8c9130, 0x5b6c67f1b02e1640, + 0xd2cdee62845a4564, 0xaabef8b8530cda77, 0xf38b90f75947d1bc, 0xb3064ec69712128d, + 0x8abce5ef04709784, 0x1382a33109f46e23, 0xffd1c46f2e4f6fb6, 0x8d527fe4e88bb4f4, + 0x7d5c76c94f2c1e74, 0xe929f25c600a5210, 0x8b8084fee20467ae, 0x371482d21dd60bcf, + 0xf13d68b1f059fd0f, 0x0c6ad1d9efbaef2f, 0xcd62a5fdd41cbd21, 0x0f0ff5b3d6965382, + 0xb449a199a178d1ba, 0x5ff13cf9d08e47e2, 0x8a9d8ab9b10a38b6, 0xc8aba831173a331d, + 0xac4820f9b580f788, 0x391b5cedb78c3192, 0xefdf95f4132e9271, 0x122db5de9c77dcd9, + 0x2b1f92e338221464, 0x94cae058bfada4ee, 0x12d96aa48c95594e, 0x9970e8c92336e2f4, + 0x6e0c1627e840d213, 0xe6695c5a07cf0620, 0xc13a02c81c020152, 0xac6feace1a36e4d4, + 0x36641eeddaf11c9b, 0xc1fdae299545207f, 0x9a30bed713a90ec7, 0x8285d1b852b1ce53, + 0x5855e062afab5372, 0xc00664841530731d, 0xa377e5b2e31c0c81, 0x51627c9b2c9c24fc, + 0x4c4a7f5535b72e62, 0xc5c97618018a6b78, 0x48ff78f3c47b3a4b, 0x46e0158fd39d5d8a, + 0x67729c89f4b9d917, 0xcfa6726f4206c0e0, 0x034305c84e98ed79, 0xc80f88ec461a82d8, + 0x7ad50987c0a4502e, 0xccffb7b2394fc47c, 0xd1ae1f812704d8b0, 0x1ec53e4863b45247, + 0xb55c13b0aadbde20, 0x7e4ece3e3c223ba7, 0x57b2af82a9384b73, 0x1031aaae59047235, + 0x8ec1e251bc0f9f8e, 0x212449636e00f8d7, 0xbed7fc071f74248b, 0xc8c1683ad1187697, + 0x62e8c8303c33b53f, 0xfbae2fa554271510, 0x5d07e84f28ee3ace, 0x93b5381de7def5d9, + 0x6a310d3823ec96ae, 0xb83a0fdb3a98e551, 0x6b39745e3bacb328, 0xb0722479d4763f74, + 0xcdcdf63348685302, 0x6113607831319764, 0x2180ed8c1670171e, 0x98a0d9785fe1c293, + 0x16159ff14d086bbc, 0x61dad0bff93832de, 0x7bd88a50a8559ff0, 0x9965a2be8e22ac52, + 0x23efc863c739102f, 0xf9ddab1c1ba36b6f, 0x846a7a37ce3a7835, 0xbe67bdea7657678c, + 0x9456c52297f99ce9, 0xa612bc3ce21c5c83, 0x8d2c4ea7889063db, 0x739e61490337bd19, + 0xc9f9fad81e5cee44, 0x46fb0f003ecde28d, 0x12cf216dc9161134, 0x601b3c54aa1e938e, + 0xf464f8cb0e66d95b, 0x9537b4fe9ddbb18d, 0x27526076047c55d9, 0xcf1eaaeb3c5a872f, + 0x20b646c7af6a5932, 0xe4d0a886d2906e1e, 0xff8f5f20aa6d9c37, 0x14a56868734ceb95, + 0xedc208f4979a87ad, 0xc9b0839a79a68cdc, 0x6e63cdada241dfa8, 0x1b981fc6a7f7e88b, + 0x175bd19230eb6554, 0x920a7f6e350b8814, 0x159505fffaf65b38, 0x8af774b97b3181eb, + 0x89b05990ce615ca3, 0x179e6085ab74ab1c, 0x69d817eecfed5652, 0xf9ac26045155e15c, + 0xdd469b3e09c54f1b, 0xb51b49fb43185d8f, 0x6b54dd7e08740db6, 0xb7937788f3a17cec, + 0xa65786f2eac45631, 0x22e20f5c41d1d04c, 0x31f85f479e9f49fc, 0xa322c7ae87d04403, + 0xa85942cb8b1730fa, 0xcc14cce102fb6abc, 0x60188cc78c17a73e, 0x9a48ad46f5648752, + 0xe099ee49717d87b0, 0xa24076e16504e2ae, 0x1a4696427e74de20, 0xf5812abadfff5da3, + 0xa1de791800007c92, 0xaf2f06b77466c97f, 0x18030f9a338c7238, 0xe7456432a35173e7, + 0x423a8c70f0d29ec1, 0x9bed157e2d4d921f, 0xfec5d98dad0103d3, 0xf9efa525bbcd6f1d, + 0xff33ef78acc46c6e, 0x443dfa37597ea9be, 0xaa844a3c7ebc60ff, 0x57d21c347d0c2f42, + 0x0dbf4ab9e3d73bb4, 0x07820cea5f61a1e7, 0xfc1bd8323cdd3244, 0x559fb325795f8c06, + 0x07d1d2252e545f61, 0x848deff76a838596, 0x271e63446226ec41, 0xe9584e7d42820b69, + 0xb2df70cee009ed99, 0xea6d24d1c0f6d579, 0xecd8956ecf0d1983, 0x9e75dcc3c8deb72f, + 0xc0558e13c9ddd812, 0x144e52454cca084b, 0x84c46a70b9a5c847, 0xe938881ae60bc298, + 0x295ae853dbabdd59, 0x175088b793c65d77, 0x7b857ee673eb7b22, 0xb9753586ff085f80, + 0xb668cc2ff32d434b, 0xadb11fc26f3982f7, 0xa2c3341d05ebf4ba, 0xdf57794edc9869ee, + 0x595a581a8a4a0e6f, 0x826389bae9c4f7ae, 0xd722754411cca53f, 0x204f7613de14b56e, + 0x9144e9329087c5b8, 0x7ae84f41ad680918, 0xae1a159aadb31d10, 0xd1d015f2ec84dae9, + 0xd5077723398a34e3, 0x2e075e82008a5230, 0x679de60a1790b615, 0x8d9fba6f8a6b06f8, + 0xba2a99e913cb7ffd, 0xecbd50b4f3300914, 0x92ea853378583b94, 0x4cd36c4be5951599, + 0xccb805b6588cc950, 0x29c4e4abd1f4747b, 0xbe5be0bf94e8fa3c, 0xf43759983e03a37e, + 0xba70fb6f23bb15ec, 0xf8e3d7265330c642, 0xac456e0bf3e19559, 0x5d7023725b6ac1dd, + 0xd9de6d20b6d1ce4b, 0x8bc0fe8cc6320167, 0x56207010b3c47f6e, 0x2b611998882e5412, + 0x975717699c5ac653, 0xbc63190b3aaff821, 0x2458ef963aaf1c9c, 0x6802571a7c4d2f05, + 0x8ac5d472c48eaff3, 0xaae4d25ac00ea503, 0x19d82b46d7342719, 0x30abc6fb49941ff9, + 0xad067ba4f18dfa87, 0x58a820457f1a2b80, 0x5fd971ef4266f6e7, 0x5b24b8fcda63738c, + 0x74c1baa8c6c66293, 0x0189d1449d03fb61, 0x93e47cec34421ffd, 0x5982d13d30c9e368, + 0x510538baf2221007, 0xa3eee0b207be764a, 0xedb41842afd5ef6f, 0x8c7a1b0993fc097a, + 0x23392ee02580bea8, 0x25ce2714433240f5, 0x0d570c178a9ea10d, 0x68f49315f24358ed, + 0x0ccc47ed74a59354, 0x86947d6e197bb6aa, 0xdf7f79f89f9692d8, 0x5f140eb3e2c16a19, + 0x2bd22ad861c2d3a8, 0x423be84dd430d0ad, 0x474ae6f01671e376, 0x803e471b277d632b, + 0xb1935fcc1856d823, 0xae6041c83ed60c71, 0xb462726566a8be7c, 0x4ddc24f4c97a294e, + 0x97f704bf2d5b5284, 0x816e07fe582fcc98, 0xf0c9842726c1770e, 0x6ed7bdfba20e46f8, + 0xd550f54c300cc109, 0xafa09a889fb2fc63, 0x7e7a623edd3b7138, 0x404adaeb5cdcc21f, + 0x6510afcbf0122fa6, 0x332e822f28aa0c9b, 0x071eb1ae3f05794e, 0x1b1eb4e8c36bfcd6, + 0x7613c4cf80739bbd, 0x3d83e128c93d5a2a, 0x195935ec6e89e31f, 0x234257cffcfd3075, + 0x65980bae9a299e85, 0x06a40a0bb5153646, 0x57d0af60d4d93ebf, 0xba5ec40da37945cd, + 0xc1ecf15bd6b5e941, 0xdd92a3a90fa0e028, 0xccec70f1dfe86ac6, 0x16bbda36dd6d883f, + 0x50e721ff309b6eef, 0xdbe9a377f230274e, 0xb8859d52cd2fad92, 0xfc933912bd3c180b, + 0x50f209ef0c3f2760, 0xc5351a048873f8a0, 0x9c29b73d53a0afcf, 0xcd2b9f4836e3bf65, + 0x8972c0183b6376e5, 0x095aae83ec4ab329, 0xb09b31aeced75b16, 0x7cd00dc7b28a0209, + 0x723e0914bd69d026, 0x48e8f877ed2cbe09, 0xff503fcb34a926b4, 0x652291ff80e19f94, + 0x36325161afa9548f, 0xb563d1c671911797, 0x35277877eaaecbe8, 0x475d13e97d46c956, + 0xcc2b0cc4a7981b2c, 0x41207b24a924c504, 0x725fcd05cbb070ed, 0xaaab104a011149c7, + 0x29bb905406426f7d, 0xda0ebc5538a0c276, 0x6e101684c723efbe, 0x7cc3334b9ddda35b, + 0x5a643558d09457ce, 0x68de78a40db6bdcf, 0xc2cd1acf7ccd37b3, 0xf5fdcd247a66f6d6, + 0x5cf5baec515b4c37, 0x7518aa64f8368726, 0x3500c5564f603f9f, 0x8ff59f55494c8139, + 0x1223fedf2ec3414c, 0xf348a9ccb164d7c3, 0x757c90ba2c1378ce, 0x3e034e45c946b6b7, + 0x182fd38faf3f7668, 0x8a82b82aa4dd5908, 0x0f8fd6771cc9f529, 0x13082c51cf2a9777, + 0x0280a97a4b62eacd, 0x161a8683478421ce, 0xfa3c321dcd4e9e8f, 0xded11a646d98e267, + 0xff1234f3d4a939bd, 0x3cbc220fcf389b67, 0xf5413bbd872d1ef6, 0xb8b7f35b0b494f49, + 0xdc5c68c04bbd4497, 0xefc1ac6fdc76424d, 0x57376a8be06687e0, 0x099f66f45b04fdc1, + 0x9823d52a2ed7f5be, 0x5ac97ef071ec4f40, 0x3196fcbdc8f9732c, 0xc688b98001728740, + 0xa386f4a40e3a7feb, 0x2d33193993c41d27, 0xf35caf14ae7df18f, 0xdb4d15702b7426e7, + 0x057feeb14b6f2561, 0x03220c5c905f7919, 0x075036c4543ba869, 0xe4768b46150c14e0, + 0x394c842d140ac791, 0x4566b2d0d4b6961f, 0x20d2c57f9ce03869, 0x750d7633290c93c4, + 0xb55e80de05a0567c, 0x53cc7a5c62d38f04, 0x75bed7598d9a8f9f, 0x3aa58b08689dd8a4, + 0x8b541f99d5eedcc5, 0x2367f9329fb8413a, 0x414e59737e6153ed, 0x36d49d6966f1d70c, + 0x63cde5df104078df, 0x6fc5ce71a0d3af29, 0x4757f4ddb99ad9f4, 0xa3c05b9554a89fc1, + 0x6b0f47c330c0805f, 0x2a8a81c4b3bfeca2, 0xd08665d60c6e65f8, 0x4c7e9d4caeba45a7, + 0xf25e2cd451d39408, 0x615c2cd4a3e066e5, 0x0902453115834ff9, 0x5ff5d76798d7b5bb, + 0x167457d16cb7c4d1, 0x3596599914adf034, 0xe1f335255b8dc23c, 0xada032e53ca95b43, + 0xbce021d049b532ed, 0x27382a3373dfba30, 0x8237820085714a64, 0xb55f046299833950, + 0x0c30ed81a86d833b, 0x677f276aaac773fb, 0xa74bc52ef68eb3d3, 0x71da4c245aea4f18, + 0x4fa365c9af6cb475, 0xf5c346c5ac3dba0f, 0xb7a3cb3b99144c32, 0x8de54cb7e74dd513, + 0xddb1aa169b3c4690, 0xdf789ab57e2fd368, 0x085b8088ebc8bedf, 0x3018c1b373d64e9c, + 0xca8d30912f0c9e8e, 0x5d1eebf13d5bc8da, 0x65673099ec87064e, 0xdaf4a1c6148b0c24, + 0xcbfd66fcfc844c67, 0x5ffdea20820b1173, 0x43cf7f951f687d5f, 0xc413b9759a62b056, + 0x0ce14d5ceeaf0ce0, 0x398fec3f4a66e77b, 0x9e91f04c9c39085c, 0x7e3e0f06a7dccd96, + 0x3bb9a48d58e8e333, 0x04aab0933871f4d3, 0x0b05aa83bdebdb80, 0xf05f9c6016029017, + 0xa5a2b04f3ecd115a, 0x8505fdb06fed3ddd, 0xeeb802489812a4c0, 0x5585e8c2bbb4e3b8, + 0x97b8b32233cb898d, 0x95603ac61e866d53, 0xcab9261ab47c7f9e, 0x0bb8a8e259936f00, + 0x69b9b9a168e58239, 0x75e5246fe3d2a10d, 0xaf46236e0ec60a78, 0x6a91de2e194c9c61, + 0xd3266726766fa596, 0xba5ea14792783a2c, 0xfabebe9dd7f781ed, 0xb51156ba15ae9dc5, + 0xb20f501ead3862b4, 0xf2dd5fdb6cc961f7, 0x5f8426b83c824e38, 0x424a739eda53a9cf, + 0x2343e04fb7b1feb6, 0x3b35733927ee86b7, 0x84c3bad372d9842d, 0xa8a830795ff0b3ab, + 0x25bedc46c901f252, 0x502d2b7e050f277a, 0xc382184d30f17fe1, 0x36a5a23597be6717, + 0x2373429f7242764b, 0x2578ad1297d0e6a4, 0xcfb8c405948cd141, 0x8e6b57f03a0d083c, + 0x7a0d352129b0a8bb, 0xe38965c32cb5129a, 0x4814b99a7a164200, 0x8bcc5a9e0874ba04, + 0x793eb99a908f1aea, 0xce8468c8888e2129, 0x7c3f9f05c52f1913, 0xa362e468c7269bcc, + 0xe615f92b5fd3eaaf, 0x2cb8b7b97fa5df0f, 0x3cd44dcf1cd642e8, 0xa2bc70cc3be24e2d, + 0x1d506e9ef8bfb016, 0x562bfb0506200284, 0x0320d6189d372ec4, 0xc084244470d15127, + 0x80f88cdb6c5e35f2, 0x795ecd96eadf2dc4, 0x9170e3eaf62c2be4, 0xe5aab0cdf25137c9, + 0x4b82cd05b0120763, 0xd5de0b714bcc1d47, 0xfe5867e76128cb2e, 0x5604660e35e0bd29, + 0x8a13c1ffb947ad99, 0x7e554cf960de404e, 0x9eee2b723efa6de6, 0x3c69121996560dac, + 0x4b5ccc1a00e01230, 0xbc19e81a920b2956, 0xf9dde3cdf6bdd4f0, 0x6ebdad6f720598fc, + 0x51c42eac52da104d, 0x5999b713130400ec, 0xdb0649cac39c4d9a, 0xce6a20d591da309e, + 0xe1b7635909ab8061, 0x78d8d0cc7be4e519, 0x7449cd0af3fe9ca1, 0x53cd0c08db64e7f6, + 0x249e5874212e6e89, 0xb98711400886208f, 0x0ea0d5e557c305d4, 0xf0aa3d5478fd80dd, + 0xcdab3e71184ab63f, 0x04237f6beb22721f, 0xcb298c39cf00c9db, 0x212f84ef0ed67d22, + 0xec380d4c50fab479, 0xf190ce3fe629ce91, 0x5a363094b7e1c4c1, 0x75c583bc7b91a240, + 0xd08c593d3bbe8d3f, 0x8eb1fe288be9db18, 0xb6e9016bdf25b0a7, 0xc89da07100063f58, + 0xc626face1111628b, 0x043973a3337faa0b, 0x97be7d823ca8f2f1, 0xfb1d42ff44fe15d7, + 0x22b526ef70ddee36, 0x316cb494b50e1258, 0xa5f2409d444f61b0, 0x01a5abd75d1bb5cc, + 0x7774a162f37fb553, 0x55fbe2594c0c9d4e, 0x0952acefda2efe42, 0x6e0a57707814efb9, + 0x97ff9fa6e04546b4, 0xb1180316f83c5cc3, 0xf20a31aa1b7de281, 0x8cf06e265fac4ada, + 0x87b0292ef4f26699, 0x5d621ec7f145d82d, 0xc4d44572389c1f33, 0x695aecee4e0477fa, + 0x2699febeb996bc05, 0xf5fc994b0a8c533f, 0x48d3c074f3a880b1, 0x01eace10adae1893, + 0xba49c1c25141a3a7, 0xc0d5fb6e31ebf576, 0x8b8d1c1348654635, 0x7d7fe10212ebd9f7, + 0xe399472c3e070ddd, 0x1900e1056689f0f7, 0x09017c0e08deebc1, 0x16f4cc43ef3ef63f, + 0x93736eca9511b7e9, 0xb9ab1c9043cedc28, 0x5720a09b37134aae, 0x0159421e16b8acd8, + 0xd48160e03c7ccba2, 0xccf08599cbbd4aff, 0x9bcdd0b51ecc78a7, 0x9c62af63f1b6ecb6, + 0x32eabb88e76fe029, 0xde2f0c5244c4f7c7, 0x5a152124e885ebc1, 0xcd12e01ef65fd26e, + 0x1dad818d52628acc, 0xf53c45144547502e, 0x747f4b0c5c01c9f4, 0x8816f3fe2fb57a52, + 0x9ca7b3bbdbbd53c5, 0x20804234ec08500c, 0xf102e8fe45dc731f, 0x691c42f9cc9ae110, + 0x8d1b4b2fc130f823, 0x2f5f72f101b1ef24, 0x1e42a3eddf059848, 0x1a753bb9b46dc300, + 0xc7d64082a345c2a6, 0x0b14b0a3230c2c7b, 0x934eeeffb51b0ae3, 0x347f7f94e7e5b383, + 0x00ca7bb8f9f245b2, 0xbcc5a5b4b089cfa8, 0x1244df176ddb33f5, 0x2a25c4f32c84947e, + 0x8280667988f1a648, 0x622ce25bef57c04b, 0xa94eca220dde40fc, 0x5c59813073c8bd21, + 0xdc24ae3fe53a2a0a, 0xa348cdebfc371ac0, 0x55e0497c0df2ed7a, 0x95652248e49a4e96, + 0xd61e638efb9c1bd5, 0x1e8c33500df72884, 0x67ccbdf5d6adb48e, 0x621314f82d999679, + 0xe56c54a92c6e0260, 0x19b6bdef4acb14d6, 0x44ac406a0b469cb4, 0xf242f4b66be46c20, + 0x4936fd6b911491fc, 0x7aa867dcf3f4ddc1, 0x465189f73171dac4, 0x601dcc3af287eb1b, + 0x2420ea0fdc9d074c, 0x8dcfde5a530edbf4, 0x06f43f025d2e6a39, 0x60733c1a72d5b55f, + 0x81c9a78888297733, 0x7bf124908c8056f1, 0xd35c5d513467a75f, 0xbcd4dee1b137cb14, + 0xd0bf9e3a9aa00909, 0x7c1d7cf7bf2c6f18, 0x3d10b718c9af4ba2, 0x4670cc7a0203bbce, + 0x3c33e7fb842a3e6a, 0x9b02b918d4a513dc, 0x0c36c084493180bf, 0x4da8af74afe9c2a5, + 0x9cd88724f430f04b, 0xbdd917946f6eca33, 0xcb3d026cd1f31f46, 0x5b6b2919fbc092e1, + 0x057dc9931c1f6181, 0x5ba1d1cee68fc641, 0x173b1418fd9f5ccb, 0x1eb708ccfdd9f875, + 0x4711c82e3134c3cc, 0xd53f67b561a82721, 0xb802a9bd2fa60255, 0xe024652dc0003c28, + 0x9e0f412ee75bc32c, 0xf61982c7f013c25d, 0x1cdc4e3e8e684d66, 0x9b85a76b62a9316b, + 0x9d2a50548d484d4a, 0xf26af6a7399c13a7, 0x0d0e7441152bde3c, 0x8fb034ec62d7c16b, + 0xdefbefb90acfecd7, 0xa1e1e4d30be7226b, 0x2ae71e349bfcb0a2, 0xce801f56cbbf42eb, + 0x608bd12081cad771, 0x5342f9e593be8845, 0x9ae6534e074e7d08, 0x13e22e52b7a90013, + 0x2dc523be27d3b175, 0x9feb30dfd5f974b1, 0xe0d87925eff0a04c, 0x8787eb00a68e4643, + 0xfc0e96ea22e054a9, 0xcc1701190f3a8f02, 0x1c9663f661507b9f, 0x15c1add4655afcbf, + 0xcde838c421301fbf, 0x531637134f09eddf, 0xb405c7df0ae055b0, 0xe8575e6fdcc1edfc, + 0x3cc67be56793a2be, 0xc9903b10aa0c0953, 0xe041456d9bc6dc2f, 0x4ecb8466a9e6a5ee, + 0xc012c11d372707e6, 0xa3e735527bfa82e2, 0x8e0f248474d44fe0, 0x21b3c85df9f222c1, + 0xaa8135ca99ec4fe6, 0xc4ab4a98a9c18770, 0x6fdb152d7f3da26b, 0x644e478a690c6652, + 0x406a534b71272c2e, 0x219ec3eadd7eeef4, 0xd645ca04f2015d41, 0x6a1d1dbbbdbff229, + 0x5b50490756b0431a, 0x38048f8253d17667, 0x3cf48ebeca2fae83, 0x7da044ecafd2f3e2, + 0x118cd24c7c3956e5, 0xea676330ee67c5c6, 0x3201bd94660e5fb2, 0xb8821712ab2eca8c, + 0x1ad5738ba7fbac1d, 0x38652048ae58cffb, 0x4b2a60b28e78a003, 0xf6ebec5b87cd9dda, + 0xed0481c255f75efc, 0xa755193a41878ced, 0x155696b1dd88b1e8, 0xe99c714bce6a5ecf, + 0x00310b9dba0b94b0, 0x10e683cb9df5531f, 0x3381c9e82c7c5653, 0xf19158123cd23661, + 0xe62deed987bf6b6f, 0x639354a80066ec5f, 0xf214d92c6388ea1d, 0x3e3fcc4c7e876b0a, + 0xc18029f88a4d82b9, 0x1261f31df31f7f6d, 0xa5baca538a7a2a8c, 0xbb53e60d8d668aa5, + 0xed1254a8ef8e37df, 0x5b8d9f15a0e49f65, 0x6832feb72f90bfd7, 0x00a9b55b0ff10768, + 0x17f469e7fc370071, 0x5d033452209f5261, 0x44571757e9b1338d, 0xe44a66858543d272, + 0xcde6ac9a1fdf3fbc, 0xe159620970a6e8b5, 0x2a723883831aef9d, 0x17d32eb35149c780, + 0x1c8e7da5236b5bcb, 0x6ae61aab0d2a03db, 0x1972738816cb56cc, 0x74c6def6facc85fb, + 0x8dc97def32eb8748, 0xae3d45da534754cf, 0xea32e5dfa10b0371, 0xf1b5a87d3d043788, + 0xfd34829eb7657af6, 0xc0e566d735030fe0, 0xe4ed08492dc1cd38, 0x07a2a366f63b0431, + 0x012fa7d4a4553daf, 0x9a8e819a42653e9e, 0xaec6852564f7c1a5, 0x14910e6dde51ad8a, + 0x963b1397f8771718, 0x34a9c7d91283e0c1, 0x68fbf6d9b7107aeb, 0xc9fa3124d0942c48, + 0x9043b293db723df5, 0xc06a25dd00bec966, 0x0ba7ed3066a4c192, 0xf21f6f3120636cf6, + 0x4a4c733bd2f0fd67, 0xdf91d6124d1ecde9, 0x70d83d807b2bf6d8, 0x4bc907f66b104180, + 0xf0747da4be3e84dc, 0x52fb089ab0128eaf, 0x8d15ab8af6a35ecf, 0xb3f5506c835f5e18, + 0x41eca80663db97dd, 0xa22569e96f3344c8, 0x83702d22d3425cdc, 0x57d98a416b9e4bd0, + 0xfe9a57998fd66b47, 0x0a80f508e2e1c411, 0x9399ffe916174b20, 0x5a9a65fc00036081, + 0x20b7360f5ef59200, 0x82ad58207b1ace5b, 0x35d053f927d5d565, 0x2f4adb66aaaad0ab, + 0x621c06675a777dfe, 0x6317515f3d12cef6, 0xe3c539d42e48fa98, 0xc7a9b9f7b9de2121, + 0x562bda3588e92c27, 0x08bb56faae7f0927, 0x0d29943c33c501f3, 0xddb015f8d1a3a6d0, + 0x3a8ff95af791664f, 0xcbb7a029dd7e70b3, 0x52e66fee6a176a27, 0xde0e5b78be59b767, + 0x42b00114e4f4e185, 0x76a771849f369b20, 0xb559a92323537530, 0xb306ae0bd20da82f, + 0x1841bb2a99b6bd35, 0x4c18a060f0990eca, 0xfd5e2bc82af69f99, 0x5d828bc3df22ca1d, + 0xf5180ee22eed0763, 0x7d8d3118615280c0, 0xf73d16c82238ac05, 0x55d5da03262b8290, + 0x559fc8fa523d1965, 0xb4e4aeaed96cdff6, 0x270bf0383069b148, 0x7ef1efeb323ea3bd, + 0xf6095dcc94554075, 0x27c1a7f7a0b72a9e, 0xb561f5ebb1646df9, 0xb5c65725e318a6ea, + 0x109cace70c8ed815, 0x00f4eb2c721aada7, 0x7f0a28ef6d1b26b3, 0xc2655ee52f5b677d, + 0x3e620e3aab7256e3, 0xb0fb61983c4128eb, 0x7b90539b606256a5, 0xd6b924598be38c09, + 0xae819c4e7fe39ce7, 0x438df3ceeb4fc5df, 0xd1fd3a72f1264f71, 0x4a1e60a566a753bf, + 0x73c93734250c055a, 0xcd311fc078d3bb47, 0x7a3f16e7138936e0, 0x652626aacb432a5a, + 0x789937ac9417c8b4, 0xdd273e3949e50798, 0xeae4e15f060dd03b, 0x8e585f054e156d00, + 0xb020f5a4b05dd283, 0x05ee937d4f158b9e, 0xb8fc1c1b9dd5c18c, 0x0f183921118c989d, + 0x79962c492209be66, 0xb1574ac6c5175cbc, 0xf27a061ea93f4ee4, 0xa2e04742ddf6ae6f, + 0x65885053523a1473, 0xca9600a03f869d2c, 0x95f21ca21a561408, 0x9b651d6185ce6b05, + 0xf66ceaa88508ccb1, 0x5e20866a1bb1ba9a, 0x55639c33ab8404dc, 0x05de5b80f5bcced9, + 0xbf9e88989fd51b67, 0xf89e8562229e0bee, 0xf06ac14fbfdfdadd, 0x9d483164e8eee731, + 0x2cfa031eaf5e0367, 0xcbb053427ec593ff, 0x6ccf8beb3da032e6, 0x5ca6902f9c153ef8, + 0x929ca463a210630f, 0x7e21c22f2f4e5c7a, 0x142d9e8a58a3091a, 0xf94d3028b18f4c9b, + 0xea85ca6ee1bffc02, 0xb6d311f00255514c, 0x9905bb88b4c011c2, 0xb99d8fbee37f248c, + 0x4ac9c159cb42b938, 0x7cb2bba4134f3a35, 0xf8907bf4b9b6d0d7, 0x9e41a5dea4024d1e, + 0xf14c5783c416c12b, 0x9783b73ffe8a4418, 0xd4aafc1f077a3b17, 0x8b5b3404a17ca755, + 0x6c650fdebe87d5a0, 0x43b9d80e4a6bea2d, 0x64166e200c84323c, 0xa424343b3c2b71b4, + 0xbb4771a4c205a0fd, 0x7d8ef6034410c09b, 0x737838e8c97611d2, 0x0bdd9fcbab2e19bd, + 0xc6353e3fecb963bf, 0x20433d5def7ebd2b, 0x13056025d6a024e3, 0xe327a1f6bce4443e, + 0xa4b4c4adce80bdb3, 0x71aaafd4a690784d, 0xf0140d1edb1867c7, 0x59d6dd39cd8d9e09, + 0xc9f3b09a5ae3d5bf, 0x7a816bff9b9aa336, 0x6ab12141da863b2d, 0x0d57b64cb5461e09, + 0xc9aae96d66691c86, 0x967c5e03ecdcd3ae, 0x75636b9433ca369c, 0xdd9a1a39c46a437f, + 0x6930f4c108740495, 0x49c94a1b63d59f73, 0x43294bcb38f64caf, 0xbb7a2ee1e2943b85, + 0x88dbbb31ab769396, 0x9b3565fcfc61ad16, 0x3f34afa53b3c6023, 0x3c8ae91fc02d38a6, + 0x087eccba051bdd4d, 0x63db4eae0e33007b, 0x3202b108af3fbd4a, 0xc0363662fa576a9f, + 0xd53da44bb9220b59, 0x59bf6fdde0715921, 0xf73710e0ff3946ec, 0x6ae04ed37c52f71b, + 0x4a05073fa1faf0b9, 0xc3d9df90a36bf1e1, 0xee87e93687107ba1, 0xfc4bd84785dc4393, + 0xdafea2a61b5bb2f8, 0x62c175e61d96ed94, 0x69d3fc898d280d57, 0x2e89d9fffac8c2ac, + 0xdd737fbd8c1afcf4, 0xdbbbcb9200fe9dd3, 0x71926cf90848bc5a, 0x06cea2e421ba050a, + 0xd84c7023f25b4b5e, 0x2bb39653b3848d5b, 0x5083b373235c4338, 0xaeba9811b487ce91, + 0xe7cb02fa8e88550f, 0x71fdf6ad42bddad1, 0x561ffb2678f1136f, 0x1a05b9acafe8cede, + 0x5f701d6c17e956e5, 0x99fc79c6201646e2, 0x64ab46f40de6d466, 0x1180bab91a59db34, + 0x42bbb522cbbf4e2e, 0xd41f7b38edc12fe6, 0x9e36edf9f84a1ac6, 0xedb4ebab7f795708, + 0xe7ba4ef211007708, 0x08dcc0ceaf6320b1, 0x23bd6929c12f95ca, 0x2dc244f376bd94b5, + 0x107a2a3bbeb5116c, 0x458717cf7aed9ab2, 0x5edb6cefeb9457f7, 0xf06e7ecb9129d4e1, + 0x84211638eda4201b, 0x29d00e3640aaab78, 0x9b09bedad5d19360, 0x483d60f38a7ec3f9, + 0xa8863a4ac57d5d09, 0xd3c326b3781d71a1, 0x795452e65afbd3fb, 0xaee1ac38808e38d5, + 0x3e3eb84504f8e2e7, 0xb95b025147ee6582, 0x9b9694b5b201ea6b, 0xb6c146a2139dd5d1, + 0x2c0ba6a4d83e9505, 0x29acab595a97577b, 0x471031b8ba182ba4, 0x2479fa7fb7865d63, + 0x9fc666b91716df14, 0x4d65b078a7946f6f, 0x4b1d699d012344d3, 0xd705bc7a68a694a6, + 0xd40fc82cb867c02c, 0x467afe426945ed88, 0x4194bdd9b2396817, 0xb135b5241575f773, + 0xad71005a084efbfe, 0x6bd3545c4e09431e, 0x17ed2f5fe34bec3c, 0xac209abd795c9f48, + 0x154c56f6da55fa90, 0x7ee9d857637c20e9, 0xe081e46d00bb8a78, 0x1552bc5f3ced9ea7, + 0x334cf982461ca7fa, 0x34adcb0f3092d53e, 0xf429287f123826d8, 0x487b3403279e9b9d, + 0x9b2084ce2bc0475f, 0x3cd66eee693483ac, 0xd85fcf770a6f35b8, 0xf1ae32535668e9f1, + 0x4eca60d72af6b8cc, 0x26a67ce44b0d4e45, 0x92ea23a19aa37786, 0xe28d8385ed95add3, + 0x81487ae6521b8118, 0x1f358bbc23d19ce2, 0xae99913a9f903361, 0x28c84170bf75f01c, + 0x3f752f66574a73d5, 0xf526e369597fe122, 0x583784bd6ad03c0c, 0x221bfd49fd11fc25, + 0xf0f0a685d2fcf473, 0x1e8f897e1f281b84, 0x9bdc2f3886c93c6e, 0x3511a7654986e4be, + 0x56889f045b81e280, 0x0a47a9effeac8264, 0x8a7790991c2b3807, 0xd1355610dd4cd735, + 0x7a2f528e0b403529, 0x15aac3f9edee9224, 0xa1485c671ec58c77, 0xc25a6643430c1e63, + 0x4c44a753ceaa1798, 0x672d769f40746201, 0xb2c7d56047a3e1d9, 0xc42e1372c2459b14, + 0xe4cc09049fa893ca, 0x56bf320d4a60f01f, 0x67b984ae2b62446e, 0x8989841fb624803b, + 0x4c1461698aeeba17, 0x677fd64fc36801ae, 0x3e3cd2b553b17ac4, 0xeccc1b8054eaf161, + 0x5da2ab36d63d132e, 0x220dc943ba3c5acc, 0xe262295e005e1a7c, 0xbde5c26f2bae49af, + 0xd09cce1e89b82f62, 0x96923415a8b7767c, 0xaf107ac806051503, 0x45b3140397d45791, + 0x37f2b446d06340ac, 0x828a9b8067931398, 0x87fca05480701cda, 0x91a8cbaa7fdf69ae, + 0xa1a23a5212727570, 0x747c1900a7dfd425, 0x04e18af9ef6c91db, 0xbec2ed735a5d5004, + 0xd600e00ea1b5d17f, 0x851dad8dabd0df7a, 0x89a5110ea729438d, 0xa36ca01355a09cbc, + 0xa44be2dd3ab542e2, 0x8fa73c70368d891d, 0xe2980d946dabb73c, 0x12b24d1a24b08997, + 0x9e7e92642a28d7fb, 0x55c29b46fada374d, 0x13854b8550b5ffde, 0x01a2fbcb401b7a07, + 0x92f0042bcc3f3a1c, 0xb35986ff1d7436e9, 0x35b770a76403fca7, 0x3ad48e8b978b6426, + 0x62a7c170c46f9653, 0x10bce6ef1293250a, 0xeddb8e242c99f456, 0x3608e044a8fbf3f5, + 0x568e6975703a6c09, 0x3362177c4c5af90c, 0xaa5ce0a76b705dcd, 0x053538eb3d9c285f, + 0x3f3c0f2dc47fd2cd, 0xceac960642c1fae6, 0xcad6755cf051427b, 0x3f4111490943282d, + 0xd3e6bfa20fa02904, 0x691eb5d4dbc6b483, 0xee6c43bb9a5f4b56, 0x52e10557bd5afd9f, + 0x49df833bbd60f151, 0x183f847fc8f65820, 0x1e16e3124f9b0640, 0x7811b51f9e56c0b5, + 0xf0e14dacd42b614f, 0x087e61186b59185d, 0x7fb066b612284ad5, 0x302184ddf4779f1d, + 0x40f96a3c739ce405, 0xea2d8dbd4db0a5d4, 0x97f64bc5d554f7a1, 0xfdce68966c1cb359, + 0xafcc35cb0f76f824, 0x7406fae013563362, 0x773f88bf874dacad, 0x5142fc941a2dc4c3, + 0x17f157dad76ccaa2, 0x168b361a94b78d0d, 0x3c83fa7aa96b4017, 0x660f86a687fde823, + 0xa1b7dce1f7e1ccf1, 0x36bec1aac7cc2392, 0xf46fdd7a4b395914, 0xd1ddea46a15c6af8, + 0x5c16e0b4a6c3c82d, 0x5e9539464ccb7bac, 0x1335d48dd77b0587, 0x2001eb13e7a7bcdb, + 0x3a0aa1a8ddac5f1d, 0x5a7666c67bc9a8d8, 0x6607986b70546ff1, 0x9066572b554cf501, + 0x7af3930a27cee503, 0x10084fac6c99033f, 0x8a197d720ada09a2, 0x1ca50121f93e69c4, + 0xa7e232ea097ba009, 0xc374d925ed190ab9, 0xa7b77cbf5e297b86, 0x68626e49aa22269b, + 0xe42537afd526277c, 0x2dc61c40f85bf420, 0x4023266094092ead, 0x8fecbb31dc6a97cc, + 0x1116febe8806c7a9, 0x46815d3a5162db8f, 0xb09f5743edadb9e0, 0x51dcf8932d9f977b, + 0x03ab57de6cc3f43e, 0xf522cd507f97ccda, 0x3fd85a313a213591, 0x0e90ca8e2fa9b045, + 0x08be11774eb6c544, 0x90ccfd20dbab6997, 0xb97f1452fa062994, 0x31ede623225151f9, + 0x9566387d54ee1d13, 0x26b31583a7067927, 0x780dba0338a49c14, 0xe2eaafbc08cd5083, + 0xf688511504ada1a4, 0xa988c26d9e88a043, 0x76c173e61746260b, 0xddcc85f9f28e8608, + 0x5368b74633e6e65f, 0x670ce025c33fe9b3, 0x67d778babf7061e5, 0xdcf0662b36b8db45, + 0x12d28437399b1b8e, 0x8acef556430712e5, 0xbaa6957f82b81482, 0xed2c284db8e0b889, + 0xf611a9ca5f0bdb94, 0xc3f6115ac847f7e8, 0x546128261727deda, 0x703e6afbf86f68d8, + 0x81a7231cc4c0d7dc, 0xc9accd7b4d30f94a, 0x9fa1b50c0a267e9a, 0xdeeb485699482a4a, + 0x7c5289696a96fe59, 0x08b65acf0e2b4ba1, 0xa4be79d0210a62c2, 0x03409e0769a5178d, + 0x53e06d25b4642962, 0xb2e38a474b3fbd0e, 0x8a60af2381a93fad, 0xbe60ab36e0a08e4a, + 0x71071d8cb0becef7, 0x77dc949745a03bae, 0x965c8c2a1ee74900, 0xd52a3839cb96eac9, + 0x3022d76caa2d4af5, 0x1c80b7ac32d82b60, 0x4035434f233232aa, 0xa676acf564260f55, + 0x13a6a12cc0d04b88, 0xb7fe52f5cc16fc94, 0x70c72266ef12ca0e, 0xcf7c392d38b476d5, + 0x8bd08ad474221fe6, 0x0b6fa4f9dfa978eb, 0xfb7f1050e12db233, 0xd13ca04b30e0d76f, + 0xa73cc9130ab43295, 0x6e2466aa8c29fda9, 0xd4ad1e99f85ee20e, 0x67371b6228e8fa44, + 0x635c3233b83c09e8, 0xc3933fb5a27b6335, 0x170688c7ae17983a, 0xc32802c13c5cde3f, + 0xae31772dab5f1fbc, 0x94e2b5a5d3a8676c, 0xbdf06016b12b4412, 0x6bba7668de2d9f11, + 0xbf6c3adc349df560, 0x734ea81429114e35, 0xa22928bc9a78e9b8, 0xb915ac991b12e1df, + 0x0ea8defa80690a39, 0x5c939835031028fa, 0x73ab9fdae205ac96, 0xb6f8e631a4e0c91e, + 0x2515a575c78b5cf0, 0xc6f81e807d60fb63, 0x76d3fbfc462f6c98, 0x945aeff6c0d13727, + 0x6890fbf6b8623ed0, 0x4fac86b641d21f88, 0x9b7322871b21bf53, 0xb35a67ad51b023c0, + 0x348656d01b82fbd4, 0xdb316034359c2efe, 0xfcadfc3ff12c0949, 0x6196f5538bbde0ad, + 0xba4d863810afdf38, 0xb38542d85e3758ee, 0x9f21a7979cdd3ac8, 0x690751a408d1a47d, + 0x44f69635fd4a8a13, 0x3ab8e1128823e440, 0x6b0494f235d4aa92, 0x1ed3a33180423859, + 0x07ece0c6667ae412, 0x34e22c1aa207ba0e, 0x9aa674b5b0941d60, 0x49a9da78ad9a9733, + 0x586c75ccbcca351e, 0xd73a31e4b7db7807, 0xdb21c961eedcb37f, 0x4b08395b1ce05d2b, + 0x320609d4e28cbcc5, 0xf9319d1e006ab08c, 0x08e066bde96b0f7d, 0xb6b4a72ba463c80d, + 0x22cd52e9e724680b, 0xffa16ab3d2ab80ad, 0x16947f8af9c03384, 0xd119383f2ae37006, + 0x527bef3e8b58013a, 0xc055bb2f6ccb762c, 0x19577840e168962a, 0xaead151ec50cc24a, + 0xfd8f18a9d49f4adb, 0x055517213ed2e3df, 0x33aeb89004077685, 0xd1c97977cd82b6d3, + 0x43dd6c28d68ab339, 0x9def65dfeae1fe31, 0xeabdeec14d875b9e, 0x947dfe4c9e36e380, + 0x899100fb32c7a88a, 0x7fd097aa138f31ac, 0x0eacacf74a8df40e, 0x1789e52cbb84742f, + 0xb4bf1ed70043406e, 0x02d630159dd8f0c7, 0x79f5adfe443be4b5, 0x5ab0d66f2d64d816, + 0x15b163afb596c3a6, 0x65f58bc798097afa, 0x683134e6b8ae2d23, 0xf087942fee100cae, + 0x9513c2f9a3c170c1, 0x32000df3d69f809e, 0x6eeb10fa9f30839f, 0x81c65857d0155b2e, + 0x0083c8e65798035d, 0xe4deb91b289fec98, 0xb561296b6307e877, 0x3bc2951983697131, + 0xe52198eccee429df, 0x472efabdd2d5f26b, 0x3a7e39171a53afc7, 0x0bb22f1da1aeb348, + 0x2ed2c3af4a1bbf6c, 0xa9ace381a6b98023, 0x27a60b43b7b02b8a, 0x07e7717219ade8fd, + 0x0f63f2eef17b5251, 0x6285f23b3e7fcaf7, 0x238e194739a1bafd, 0x8fd260a620b0044a, + 0xddb52bd86d75a344, 0xf450b8dbd8283259, 0xe82de9c7abd04644, 0xc2a18b87f565b036, + 0x59b01c7848c8ea2d, 0x5ac7a874966febbf, 0xdf090ed98287f24e, 0x6ea7aa2b9b7cef0e, + 0xc5197416e1287885, 0x3fa796433d0e26ec, 0x0f33685bf9fe476f, 0xf8cb8c84481f469c, + 0x3cf530446aebb793, 0xf7380e07c075d257, 0xeeb14fadb3ef370b, 0x33545046dd6a53b4, + 0x1245e1e1da9fe75b, 0x76c369049dc8be29, 0xdfa77446d69ee161, 0x1540234fb76c6699, + 0xafe6846ed4a81409, 0x6140a2cbfc4188be, 0x110f8f6d6430a752, 0xa4984711a513d8a1, + 0x2a15f090512c368c, 0x912a67c34b0de4f3, 0x586062bdbcb02fae, 0x628c6141fb9038bf, + 0x715422ad0b9379b5, 0x0078a2ce795c53fc, 0x210232c04be1457d, 0x26582c1fdbf672b6, + 0x5caf43acd1baa06e, 0x99b9e9b37b486074, 0x9615534f88ab5350, 0x1d78bd7d331abab8, + 0xea3e8519d96aa0c3, 0xecef7968776b2c3d, 0x38c527d2e7cf3a18, 0x38af9da6fde0beed, + 0x0c04b4e0a21af30d, 0x8cce3157d2e9755e, 0x54c0ad71e1d2b10d, 0x67ed0cf0f1ff059f, + 0x18b942551e73a589, 0xcdfc68c53fb7c340, 0x1613f99449bc546d, 0xafe1fe51cb4c3c63, + 0x26ef54aaac797b19, 0x3d3d302a4504fd20, 0xce90472f2865cd6e, 0x2fb9bd1228b2895b, + 0x094e4de35046e267, 0xe1eea3de5f4a31fa, 0x3f74a57fdb0d0389, 0xf00f674c3a8a9602, + 0xeb2b786f373b7976, 0x1cf4e637d7dda0bb, 0x69e8535bee91f776, 0x60d5887a41c84509, + 0x2ebd9c94c770a221, 0x917a2e35285919ac, 0xd2c45f8ecfba0904, 0xf4490ee59f6dbd36, + 0x89758084112c5427, 0x3ab8d94b38d0a452, 0x0c2250832119ecad, 0x74a6e3be4ea56ec8, + 0xccf08af81abcea36, 0x55768ae293c98e98, 0x92e9a532c3c34582, 0x511930274d2a7740, + 0xab466f90a713b9f8, 0xf3adb12f5c323c90, 0x915ee582e58f18a4, 0x1f20eaa4873040ec, + 0x1b3f7358c743888d, 0xe49119ec6b3823e3, 0x8172d693336a08d2, 0x34e9e46c3b3eafc2, + 0x01005093a09f5141, 0x4037102d139673c7, 0xfe8fa22aec8b26b9, 0x2768b412a3749b4a, + 0x1d7d17cd76e7f0dd, 0xacfa3e3021a83a41, 0xf7142b4a43124a2f, 0x407935ffa2974aa6, + 0x123f50ea462c2196, 0xc9488ae4681d4518, 0xab5968557b9a57da, 0xa83205bf5f46dc05, + 0x151e4eea6953f8b8, 0x33000a3fadfa51df, 0xdcc1ce0daf3fbda5, 0x7d371271bb7b8768, + 0xaf876bf0f638bf8c, 0xfbc27cfeb07a2f5b, 0x356c93140189e8f7, 0x5b8f5bc77b318664, + 0x5b74fbd6d41f1254, 0xae2f6bea698b9e41, 0x94365509202b40f0, 0xc3dca0798c3f22dd, + 0x184b26e4df1c35ed, 0x9539430cd2984773, 0xaf2d69e1477f45b4, 0x86652c5509baf2cf, + 0xa041901ea37a4701, 0x73259eb1554909e3, 0x7a37c6addfed8bcb, 0xd1cb93fdb1488dbf, + 0xdd2d2d57afb62217, 0x4f7c8d1457c435d7, 0xbb7105343bca4b4b, 0xea1d93ef3040ee2f, + 0xb4e82168574cb690, 0xc8357ed16ebb391f, 0x6f1b42fb72669bea, 0xcb108bc000a371d5, + 0xf400d48e14a9d057, 0x2c3da521a133febd, 0x76510424e78badbb, 0x18094fe0197d3b30, + 0x5a272063adc5899a, 0x476278bc4450c187, 0xa02d79a633f6ecbf, 0x3a7242757e766580, + 0x1947479d44813265, 0x446de9f0e6996e95, 0x5f7ca2bc06058fc2, 0x7ed52bdb4d777800, + 0x10640de1c837e875, 0x63c7555a3ce86856, 0x39371a89992b1ed2, 0xdd61d740f69d0528, + 0x161979d08b7b469e, 0xd8facf1dbb5cb36d, 0x5ca558cb6f3034dd, 0xbbd151da22b8ddff, + 0x3547a8f8e49c77ed, 0x51e08bdd847ee961, 0x64102dd21a2152be, 0xc0cd2deefaf4120f, + 0x9e42789d521c9ac7, 0x536c2f5b6f0db765, 0x9c4427544ba98653, 0x8595169f46fab3bf, + 0x9667b31322bba3db, 0x0370aee42b3e731a, 0x30ab9192cb9287f3, 0x11582d84383f8482, + 0x15625b77e5ada1e2, 0x928042df1e154836, 0xfbf5fd6a015014b9, 0x0f9b90fba44bb827, + 0xfab046fc7e1829ba, 0x34c9363ca080cdb7, 0x06eadf16902def24, 0xa2102654698aa05c, + 0xf0a73f3aefed8738, 0x23d3e51fe209e636, 0x37d6fb8b893c58c0, 0xe07f44673aedbff3, + 0x47ddc151fb702677, 0x0a2f193d8fd58539, 0xc437684f68b3b514, 0x504a27aa2d27cb46, + 0x8604f620d7f43527, 0x040efbb8623447ce, 0xe3324d59a59be502, 0xb5eb38fed8d23a19, + 0xfd71153ea417ded8, 0x25a73a99548275f9, 0x0628521041d8288d, 0x088b9d6c1707f315, + 0x092c5f3f9461d28a, 0x1c441af94b125106, 0x8e1905d7315dc4c4, 0xfd23631e22a3c50f, + 0xd3140c6522ebfbc8, 0xc03894d0305c9fe7, 0xfb20b5b25929fb96, 0x18681f8d368322a6, + 0xb6cb24de026cf8fa, 0x97feeceaa42d12bf, 0x06b649a3bbcc36bc, 0x473d8005b19d9fae, + 0x1f8669e2da459978, 0x0b47eee844e2b4ae, 0x08fe0fcc8d26c04c, 0xae0f5ec2480a64fd, + 0xf54f5c3fec69f08c, 0x27aec32b3c19aa0c, 0x0d0b7104db791eee, 0x50238ec8377686bf, + 0xb77cf3c5c66b01b0, 0x609f7d1d1a489756, 0xd7625de72ca98723, 0x6e0760bde39c4935, + 0x36f8bd89ac3d014a, 0x68c6963ae0261adb, 0xdc9523f224927f44, 0x927337fd3519c673, + 0xad11f6e6616da14b, 0x19705660bd8ab87a, 0x8037f0568ab92537, 0xc6183ddd17bf0d2f, + 0xa2cc5590377a0601, 0x1085853d7f72fa2c, 0x5f2e046f9d36cf69, 0x6091dd1f8a812223, + 0x1372e040bced2b5c, 0x7d9d5c60a7a71ce7, 0xbf6d231a4a39d158, 0xa7020e4829c225ed, + 0x2b969d03d96b9d76, 0xee563af36fe0ad12, 0xf6604f946ddabaa7, 0xb2588f41beae22db, + 0x11cffabc946d77ee, 0xba378ad6c75194e0, 0x0418fe7981d35c44, 0xa7b570f6674db09f, + 0xfc26294761b8f856, 0x5a7f0e51374a6c24, 0x66802d9fd51b9ef2, 0x2e6226e99d02e67b, + 0x36be1561d6f4125b, 0x627da10ad8c0e1cb, 0x3d4616f5652cfcfe, 0xbc2d9692eaf05c99, + 0x1cb24fc69d4ec952, 0x314671982680cc10, 0xfcf45fa682a86a45, 0x6439fe94ba8b61f5, + 0xaed728b2bca7f9d0, 0x212a783db05abbcf, 0xaac4f56b360482cf, 0x114fdf72282d8f4a, + 0x530b4e3a901d9517, 0xce042afeb531b3fa, 0x0fd4c9c33154ffb3, 0x2888ce24eba2bf96, + 0xa263dc2e3385dba6, 0xb7e82dc2ea1d7bde, 0x8b09585f6ab3228b, 0x1e4fe421177dcb76, + 0xcd74e6113cd709fe, 0xdb717f11b1dcf79e, 0x1e8dd13f4a1d0818, 0x13d32f111d88bbaa, + 0x64b5b8d00273f993, 0x80f75100463bc42e, 0x5089dcff2d4d1b76, 0xf15ae1228e98608e, + 0x844f04565e35b0eb, 0x8c857578814529f5, 0xc0842119c25a4899, 0xac84f6904a2b4fc3, + 0x1c864312d2e47e56, 0xb38e2eb706df7cb3, 0xab44b0836162dbf3, 0x14ac55ad7b37e1b3, + 0x67abf8ff3a2d659b, 0x708e8c3718f81e83, 0xd79f805950b8a560, 0x0450116dceb2fba8, + 0xc536a47b45f5f398, 0xa461e9532890b089, 0xb32d6f441b4b61b5, 0x5a1780861dcddd46, + 0xc4ca7bb284013428, 0xc8cfefb7cf5de50e, 0x0b15b5793fb03d49, 0x13d314e7501d8833, + 0xe63f33c59d25d607, 0xf0e6fe74d89a48b7, 0x6528436594328d07, 0x0de0dacdfb66d44d, + 0xa225ee29acf7a5d2, 0x1cfe84ae46fd37c2, 0xddddcf50454eb528, 0xa606bae54c111997, + 0x7f95e39cc27b797e, 0x37c10dffb2e36da4, 0xefba67590a452a2a, 0x24f36a6d50708f0a, + 0xb78bf2ace92bf877, 0x3fec905895ec0fb0, 0xa38ce77988a6bf1a, 0xf1f1fb337baaef07, + 0x4a8e9ef8e644a5e6, 0xbdff0256fe306885, 0x6ac192dc2f4993c6, 0x13cd3f6784ac3233, + 0x91940a96e59d04c1, 0x4273e20062ed4087, 0x9f1378ea52e0d1ea, 0x8e426546d52c2f91, + 0xf31484f00b6470cc, 0xb89b037324c03f1c, 0x2a0af557849372be, 0x4d73f4720b0dc5f9, + 0xa579c7e15a3257b7, 0x8b537d0179f81fc3, 0x4bcca4e93851409d, 0x691e09bff3f51f5c, + 0xc404cbe36275c847, 0x803e8928c1d4618f, 0x2857dfc76df09f9d, 0x2082511c02521bad, + 0x7a80546fc700e127, 0x73834ddba4ca8273, 0x9c21dc90e34dc330, 0x6e850dc2c07dd3a1, + 0xcae7c173bf49ac62, 0x561b6d7fe64b7dc8, 0x55e3095725e8538d, 0xc6a38cc9b49c16c7, + 0x4787c16e9097415f, 0xcbec873d5f30b6bb, 0x1362e2e8dd552c4c, 0x07347b16f28848bf, + 0x4abff3cd59f8806a, 0xc1595f0d01f9be68, 0xd9f682dc6c20fbef, 0xcb094ff00fd628df, + 0xc03062b8f46ac1cd, 0x98fd0f94b058832d, 0x7905d2d8bf45dba3, 0xce47aa2fe0d02a87, + 0xf3143779478bd2b7, 0x81751ee8128f1780, 0xacb0aa76cddefcb1, 0x2ee6cfd9f2a43440, + 0x53ffefbd272a3086, 0x5fffd81b0fec83a7, 0xce7be945d837f09d, 0x8b09427ae24cc191, + 0x045f520c4ce9bbeb, 0x3b70e02a6140666c, 0x66e4f17dd37ce310, 0x09e528bf1f6c2b8b, + 0xe1900131060ad79c, 0x0f9b53ab0bfac98b, 0x1e753466524d3bad, 0xadeecf80af1218b2, + 0x21afe1a444c4c9a7, 0x06d24fdbc93604a0, 0x5c654f1ee4d2e2e0, 0xe74e521055985714, + 0x1d9fff9e1fef4bcd, 0xd5998e718fe97799, 0xede690f20c324c1b, 0x058401fc625190fe, + 0xac4fed0b687bf35c, 0x7be364af4b9244c7, 0xea607e7e969fa48c, 0xbd095d6d09a19788, + 0x57f0d1a5f46b4300, 0x5f6b6faa572d0868, 0xe0aa7ab79d4ef9c7, 0x4e3832c192b0c5e4, + 0x3d9d17566e888c01, 0xebe1107cac4cb83e, 0xa3a480e0b4c9c3e4, 0x3d57fbecf657c2ed, + 0x46eb3e0b1ac4507b, 0xa10a0b89879f007b, 0x2a5f1b6482d46045, 0xae0239d6d79e6908, + 0x2b62259273a28b42, 0x1bc75c6518b25c2e, 0x59555f64a8d3b0de, 0x9e9a20942435268d, + 0xfae9f0063baaa4a8, 0x9c16a806248d4dc0, 0xd212cb26b9d3f9d6, 0x5e577dd2289923c4, + 0xb6e79073b15af5c3, 0xafbcb2ac5405a033, 0x2339839bd4f8a4c1, 0x2a2e7d166b297c8f, + 0x8b6e89ab1aed7394, 0x6ed99d00f13096b2, 0x25bd090211d17f99, 0x4a4e8010126211ed, + 0x1e5c31837fc238d6, 0xaa944122d454e91f, 0x2aa72b5dcdd1b8d6, 0x6399ccd1425b21e4, + 0x159ca2479c5164b9, 0xa522bb2089c286a8, 0x1ae365d2dfeda7be, 0xe79c93899c22e9ea, + 0x4e11cafb97461697, 0x16845a838913e28f, 0x310aad1ecf98fc09, 0x346b0d1db5283e5a, + 0x5cee2089a053bad4, 0xd064a21adc95cbbb, 0x4296ad446bc138e3, 0xa70b15caeeb377cf, + 0xff12ffb137a75eec, 0xbc5809bf5c3be822, 0x160b16191a788835, 0x4d13c212a3a0f8a9, + 0x6ba84585fcc589eb, 0x75215949767c65ce, 0x6e9156489208c35c, 0x194b5ef8852fc631, + 0xb1856068167e4051, 0x7c0e0d6085bd19e1, 0x23164380d2307cd8, 0x7d35ed3ed770c37d, + 0x38ea2cce718f0394, 0x608b48bc39e13573, 0x6e533b991629fc8a, 0x63decc3ade931420, + 0xc57c36d4478cd7db, 0xe5503e2f516322a0, 0xa1942a05307f2ef2, 0xab900abb16885cee, + 0x340e74005ade4fac, 0x76879506e9e4cdd8, 0x9e981bdb6dc1043b, 0x9e178c09e7274ed5, + 0x53d96f6ed451b70c, 0xcf64a14bdb465676, 0x47f15cef07394a45, 0x098908a45d0527a4, + 0x8fc16907a8e2f8e7, 0xaa959d41b64bb117, 0xa57742260431f266, 0xe5bcd5e6bed185de, + 0x222d8f044e616333, 0xb268c2f0be438fb6, 0xb1d8db987d971dae, 0x7133678a953a4b86, + 0xe9760ebfc9b99826, 0xed5a36ec1a76d100, 0x698a95beea0bd0e4, 0x50b7f5c790bf1092, + 0xf3e8e504bcd578e2, 0xf48bb6746be9a786, 0xee9e2e15e7eae906, 0x57771414ccf24506, + 0x0e22e623697eb12e, 0x6a5d8f568b8d1a59, 0x682bd158b531af50, 0xebb8484d5a950d32, + 0x747890722d662f0d, 0x557f3faa11523f29, 0xe3ed35294ae6af26, 0xc577ff7280ca78d5, + 0xe5b300474299c20e, 0x3aafe0f366503baa, 0x251fb73e209e33df, 0x3e28885fcc5193ba, + 0xe2dc3ace8bf069cf, 0x9de1d8d1c3561741, 0xc283654c420213a6, 0x4d4d984d42e2488f, + 0x700c66a393b50f5a, 0x568c9adbc3ff805a, 0xa0f0536cf084512e, 0xe84680c13080a9f3, + 0x90c53f6ec992edb5, 0x85a1a16794842d4f, 0x88a6b99807e765b0, 0x60835a754d24f896, + 0x3f48f4c1e3217aec, 0x3b5e362c04c92f64, 0x49e318f7f10b7a46, 0x245cd6e8ccfc37f9, + 0x00b7b86f5c1bc4bb, 0x2e1095296cd9f79a, 0x503586f3f889a8e5, 0x6f35d00da1c28d5d, + 0xc246156fb25355ab, 0x754341daeacfc3cc, 0xd12c618f1c804dda, 0x0a9f70e4706d1c24, + 0xbfeea8baf3ef43c8, 0xf14ad9914f6a0045, 0x790dbfab02f17c9f, 0x3651435f5c0bb594, + 0xd7c854314e6546fe, 0xe9ae6cfc8d33e9a6, 0xc8583921e0b9dc00, 0x54f75a9e71f6c28e, + 0x71a3856a90680903, 0xd61c95f9461913fe, 0x617d1cd7f4f768bd, 0x5d2c6b7f1652a849, + 0x7bc70ca8682e5da5, 0x3eca520d5ab3d67a, 0x4f9394d44e4cba30, 0xaf79ae35effadb0e, + 0x0dad63429ad0abac, 0xfb219bba29ac2004, 0x67ae855148b15c3c, 0xbea45602b1374aac, + 0xf9464f2fca0cece9, 0xebcfead82d7d95ae, 0x05774c8df003f2bc, 0x8c0c4a09493cf1bc, + 0x9c047854c64cbd23, 0x2e9924483b77a110, 0x29ede04b41424905, 0xbc837fb5d80dab4a, + 0xa0735c613e5cfaca, 0x0975af08f3152523, 0x2efecf0aec4d0868, 0xa9f04f1882d0cc17, + 0x41aec4c124552129, 0x9800fd7667ada453, 0x052aaae7548ac653, 0x78701944c6b3bd3e, + 0x1f37e94739892b1c, 0xc122e6e99f26dc6e, 0xec3a405e977e7e0f, 0x9843767bc4c3c146, + 0x5e5dc3eb8ae10540, 0xe6921a46aebf54c4, 0xfa5267004f77dca4, 0x24794de1b7f562ec, + 0x24f7e67cf814e1b4, 0x7178c44a4ef0143a, 0xdb20e37d5db7dab0, 0x4f168878c2eea10c, + 0x2c3c68ec66cd4eb8, 0xba0da78573822639, 0x77e405cdd736b94c, 0x7f2d25a33c75cacc, + 0xf44481015a124206, 0x22edb111738b693f, 0xdde445d68cb38436, 0xa821a541ec95dca0, + 0x69aacbe181f81d0f, 0xe60c433a8d682db8, 0x8431582d40ac17a1, 0xf0785797502bedec, + 0x57d332cebc86298e, 0x6959b43126f369a4, 0xc8c01d95a693f454, 0xa45d8297f27c9b46, + 0x269e248ecacc06db, 0x32f7b96bca8931f3, 0xc21ac71fb1500147, 0x76c337937ba41bd9, + 0xb92973589f24c9f5, 0xd5226b232e0ec3ba, 0xf4b67cfddacda3fb, 0xab212fd9a48c65fc, + 0xca670a3b9be8b001, 0x9a2ff1cb1624df31, 0x0c5cd280d8b5f78e, 0x2cde847c918d085e, + 0x8297c2aac028d2bb, 0xe0018b981de45639, 0xa4edc759c25d387e, 0xac007a1418d81ae9, + 0xca5a5fc597156273, 0x4e96fa5be40fb1d4, 0x9bcb619c530537f5, 0xbb72562572aafa67, + 0x55bc606376a81e2c, 0xd10c63d88febca05, 0x549c31448dbf292b, 0xa707b15a74daec59, + 0xd20ec952fa53c3ff, 0x8c166b34cdc88af4, 0x5d902b7ab99a290c, 0xa91c0764701f4c56, + 0x8b361ce7fd57d5ed, 0x7661bf74866f8d88, 0x22880b057dd7dec4, 0x1b43fc401034fb4b, + 0x9aa6428cfa5a23f1, 0x2e8f7788cba73be6, 0x81cfb0ed9bdcb302, 0xa234782fdaeefa8d, + 0xbc0c322cd5ebcf76, 0xf6fdd4721ad18a8a, 0xbe6d9de8f6d285cc, 0xb8dc477dbee766ce, + 0xcdfeed13b44572c0, 0x0bf68f12cd7f4a5d, 0xd6e9ab1721778ef8, 0x06dc2d509dd36dff, + 0x02941f233b4e7b9a, 0x8dbfcf7b1858ea8d, 0xc814ce259a5b35a5, 0xab57c04047896629, + 0x8e81cf678e536e8e, 0xee1de6c58e90beb8, 0x75bda7defb5dc6d1, 0x097e91d1c058102e, + 0xaecb4b42fe85c5d7, 0xb7d2e2b6dd609a48, 0xef980a63b516e352, 0x7d114af9bb7bdd4a, + 0x674def540b71e45c, 0xac127e4a16adad63, 0x712d888a7db94168, 0x749b34376039d6f7, + 0x792b06b8a6cf2cc2, 0x27d1233cbb14cbbc, 0x607f5f455faa3063, 0x3b5ec7083ca864f8, + 0x3d6b4f84259432d4, 0x3b92e96fa24d9217, 0x55fd7208dabd4dbe, 0x99971a09756698fd, + 0x555327eb5f412f11, 0x27e954832de83f2e, 0xce3335cdea22d03f, 0x154435f5d65c38e3, + 0x14754df4b4f7034a, 0xd8bbe59899ca03ba, 0x1582c6df61e13666, 0x5ca1d0aa2c836859, + 0x8c53a9ce187aefde, 0xc3c3fa830c5fb22c, 0x3c66ef8a503d892a, 0x2d59c893d6247c4d, + 0x22dbb46652471854, 0x9faddbb85e09a14d, 0xd8bccb45f6e6a0ac, 0x23689d009120c0e2, + 0xd510f9a6986bb124, 0xad515b2d6c8f189d, 0xca274cadd82c7283, 0x2e3bad4cc4820f7f, + 0xdda8c3f3d59b70bf, 0xabcb762114bf9b97, 0xb3561c7402d3833e, 0xc80472bcbdd26531, + 0x9c4312cd3c3433eb, 0x43725a824ebe2c6a, 0x3ae684f91eea02d0, 0xb48185acac74505c, + 0x7f4bc143bc8ab9e3, 0xa95e14512a58e75e, 0x6b9457b7ff451cf3, 0x38488d6e467f61bd, + 0x61cce64fc260a9d5, 0x0968b4ed68a0b428, 0x853587bfd42de1d6, 0x626d92e3210271ad, + 0x5b088aa52ffdfe7b, 0xaf75d430888c8b28, 0x05bc40c8f354c01e, 0x3caab0da3beb22cf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9fef732379de414a, 0x6600847f1838c76c, 0xee8b61b78f6caae8, 0x8b16c28882692b66, + 0x637b94ce46e03218, 0x4a095a74d026b9f9, 0xff2aa6e6f8363863, 0xe5c07e64fbb17864, + 0x28c4a3811251a067, 0x149f38a7986c4eb4, 0xb7111c04a65a0452, 0x3bf79845768e1d1b, + 0x4799f4451a1fa720, 0xe75f63f3698c4796, 0x68bb690a5b08f3de, 0x6083834cd9c1ff0e, + 0x20c3c4fbaba251b0, 0x067c7bdedd6f013b, 0xa18f00c535c6ac31, 0xbc6d15626e922c67, + 0x4f387494da8b4f50, 0xce13e7c4d056a06d, 0x3a23034a052ee7b9, 0xb279297f1e3761cf, + 0xe4eae1446020c076, 0xf3909bd9aa99c3a0, 0xd5e4da44b451ff4f, 0x1dc7a7d49cb8caa4, + 0x821b5665df448835, 0xe9e5c11883be375e, 0x37a32eda61b52416, 0x87f455d74f901759, + 0xa380c9b9f04c76b7, 0xc804a25d87937457, 0x66052d593ebba3e1, 0x87c8ad560b378d64, + 0x9645adf825cb6cee, 0xdd166304d8bddf17, 0xc66e822210e2878d, 0xba763f799afeb5fb, + 0x1e61a9f939351e92, 0xa265dd673c9c9027, 0x7ef019850692931b, 0xb038738417404d2b, + 0x63f1bab3951b958b, 0xd6b5784555a01a45, 0xd4a68fc9939ab88e, 0xa50462b98d424b87, + 0xc0e1ea039102e7af, 0x4d42a6f03addbd51, 0xc6b279c218116a27, 0x20abda844cf047fa, + 0xa5c5dd82895e91c9, 0x468cb72b4f372775, 0xc21bf51cb360479b, 0x617ea7c3560ebd73, + 0x8f41aa242ec6dff0, 0xe4ed121e63656469, 0xa57aa39ef645203f, 0x04b26170917eccb0, + 0xf0ddde3aa4ca36cb, 0x19a649c2293520ab, 0x14c64623b2d91a4a, 0x5d6548975bb88205, + 0xb387c49044dbf484, 0x103137d68995d83e, 0x8537831885090fa4, 0x382a2d3290006bad, + 0x375badb305bcd280, 0x1945e93c37a2e319, 0x89ff8e93c9e75907, 0xa9b085de7fc9e82b, + 0xdb4248b4369d7bb1, 0xa65ecfb136717195, 0xcae3b3ed8d22b809, 0x36816a8a281157a5, + 0x45679767932db635, 0x4f05f81a14cdb212, 0xbd178feacd26a748, 0xd6187c5d1cbad41e, + 0xe8c5cefeb4b2807d, 0xa3e054a4fe1e8e4d, 0x8051e78704e653fb, 0x87318c49cf5eecaf, + 0xf637ff5b63c0138e, 0x3f92dbb745177ee6, 0x805d8fc906af7474, 0xe8ebf957046fffeb, + 0x35f1feab86dd0cce, 0x0af8eebd7ba15f8c, 0x72625d486068c0a2, 0xba1afac055f02dc0, + 0x4d77f1f1930c8b8c, 0x51ea759228c4cc29, 0xa5b44a23a7a2c3c2, 0x31d5b7e72dae6e63, + 0x65f98ccfac0652e9, 0x025c9247f0abe613, 0x1f554763b44be034, 0xe863b9e157bc0478, + 0xfc53353ec40a78d3, 0x38c009b415a4ae63, 0x99a1d14d66b2353d, 0x62bea4be5732cc26, + 0x390bdef4e21d187c, 0xaea8c74a6ef1952e, 0xada2df6888e4b970, 0xd51b11ee6bbb7745, + 0x7cf8b86552e328af, 0x856e262179bf5fc1, 0x12d81ab85c52b97d, 0xced645b221f8f392, + 0xefad7be0febce73d, 0xb7f23c23b144fcda, 0x27abc90aa91c7da2, 0x2ee1908c8f732e6c, + 0x6b084bb56d262647, 0x92b2a663d18b15b5, 0xdbcf358c4d621581, 0x170ddcaf1ca26b25, + 0x12fee11c1f95d502, 0x51cce12a68207a11, 0xbfae824478469bdc, 0x08f49b31507f9715, + 0x0a2144aee2da7430, 0x2f6dbb99029b5aa1, 0xf0ab1af5b1a12fb7, 0x82ef423890fefcb6, + 0x77ea9a61206d517d, 0x5b3e059a2139b395, 0xbc0555a41dbb5257, 0x3cdee8baa209a8e0, + 0xe9bb25c771c04a36, 0x2e8eabdf95627370, 0x394c710c0a848ce0, 0xfe3eaa4ce4bcca14, + 0x4d6b57998af7ca07, 0xbd4fb245a243b83d, 0xb2821b1345a68e2a, 0x4261db3eb338b23e, + 0xbe7ef41e0ee3c8aa, 0x55881f02fbeaeada, 0xc995e317b1b8d0e1, 0x89d907f31f10c727, + 0x9298fed159820ecf, 0x0db6043292cd0014, 0xcdcdfb13b4bf4eef, 0x234df24df94c2038, + 0x353ad8163dc5d2e3, 0x5ecaceff19104fff, 0x32d845e845893b0a, 0x3ca59ff3d8db88b8, + 0xfb8732d99f2408c8, 0x2edb89f356b28e3a, 0xd30b99df878a2434, 0x589bd1d260518126, + 0x056f98d8d5510e63, 0x3559c06c261d8b51, 0x5d4adf00eab0c6cd, 0x776acd6b44560fe9, + 0xf96b5d83df7657ce, 0xa02986f821c647c7, 0x4c55a8151111a945, 0xc1fd6ec0f4d3766b, + 0xab67b3273092125a, 0xce0ef31c5d49c9a0, 0x66e5be8a15c874f8, 0x8d24f695c86ec2ae, + 0x0768681473f84673, 0x6137b98ac1c15b74, 0x2f7f65a88fa5e0a5, 0x338de1bb86ad7496, + 0x1762bd2196284bf1, 0xec2df2926248c5e0, 0xe7dc6193f294be40, 0x412732835815041d, + 0x677dee7699794e49, 0x715fc3dad7ebb2a0, 0x28dd0957510626ec, 0x8de471f9cc7c0251, + 0xeaae6a2fba802b87, 0xaf706c138dd01281, 0xa1b6f02e8c33d126, 0xdcf432b4080a77f4, + 0x38fc91397b30344e, 0xc445c91bf87def1d, 0x8044bdf85aba75af, 0x9ceae19ca32df6fa, + 0x3958ff56cbd28ebf, 0x7905a6e806c57710, 0x25df8f1e88684e99, 0x0d7fb46b0e828bb6, + 0x57f0ce6fa4b42dc9, 0x7bef3041de8a50e3, 0x3841389551395a28, 0x2784340eaaf46fb5, + 0x4d9aa489fba1b683, 0xfea062eddbf326fc, 0x201f08472e12fe57, 0x5b086acdeace4ec2, + 0x4babfc8b18fd88e9, 0xba6934df667af1d2, 0xbde5416689bf13d3, 0xd5b4c826a8e01480, + 0xa46d3b6d93a34a86, 0xf8025464fc9f238e, 0x98b5910a31d9a64e, 0xa9315e9ae8a51a3f, + 0x60aa1d4dbc048af2, 0x9bcc498caa0745a1, 0xf2fc02f1680875ea, 0x843475753f50b39b, + 0x0c792e8d2e6b4a50, 0xd4518002dddf5b25, 0x09b8f6d48f71b80a, 0xb895ffab9abf6316, + 0x1d08095230c14d4c, 0x02165f50740b5a2f, 0xdc30e36684a561aa, 0x6faa8e4cd9b6fb48, + 0x04eba5a776bfea1f, 0xd8a610f555fd3519, 0xe4f6dc46f111f5be, 0xda2ff9ed07f902ef, + 0x12727c15eaa9962e, 0x007c81673a67a3ea, 0x7b7881a0b1a7c603, 0x9157e60be6b57442, + 0x721860d7faefcb29, 0xe885557cd6865d82, 0xab3b5ccd90a1991f, 0x441afc49dbebabb6, + 0xa56f6fd8a5730a5b, 0x866bbe4cc949a1ed, 0x0b9f1b4007fb3ae7, 0xf98cfaaeef289f43, + 0x2b3804d48207607e, 0x36c961d88e728352, 0x58a7a6cc2939ed22, 0x32dd96008fd3b075, + 0xa57d12b422680de0, 0xbed448bb5e9a5703, 0x5f2ac9f14ec70edd, 0xb50a0e15cb7c2beb, + 0x0b8dd681659f68b8, 0x22d46e5b9750d588, 0x078f6f1b85b62eb2, 0x0bdd64205f01ac5f, + 0x57738cd009c1285d, 0xeb9fa56be4c3ac2b, 0x013e2c9cd51e3665, 0xf571d379b67eb64f, + 0xd1e80e990d5df459, 0x968bdb1ebdb0305a, 0x516a8a4123bf0218, 0x67a93227def04119, + 0x130500cc18bbd046, 0x733f717a02901813, 0xc304dd0db3a1f63d, 0x42710dc2da3bb773, + 0x2f68c784ac3b9732, 0x18320ca75d16ca7d, 0xbe69220002af767a, 0x97928eed82d544da, + 0xdf12cde1cda9061c, 0x393b6e43600213e6, 0xfde30bb301aa97ef, 0x7b77d38cb4087918, + 0x39f2620b8c06afd7, 0x09fbf3c5cf1d35e9, 0x81b61a34d6705003, 0xb8607c633c06441f, + 0xd1234a856a4786c3, 0x222b13f3355887ee, 0x4d5887b649a1fb32, 0x13b7d7c810d8acd9, + 0xac43cbf90a62064f, 0x09b6aa8267fdaf23, 0xfc0fdd6fd2a3278f, 0xc1ff55690e60c64a, + 0xd1a1711a1076f592, 0xd09de59a73634829, 0x78ae59d7874d64ca, 0x26f3c52520636097, + 0xab6aed8d2ad5f95f, 0x34f737d2595c421b, 0x848a7e7b251d0671, 0x8fc4be01e1dac188, + 0xc0a1af6e89161355, 0xc3434fe504bd4dba, 0x0127e1834adf3695, 0x4903cee0f08db083, + 0x74f0a13c5948c467, 0x744559a3462c73ca, 0x7278299d145e088c, 0xa57a1ba386a12b8c, + 0x193774a92d4c83a6, 0x2343f12b79368435, 0x300907b9ce23febf, 0xbd76a0ae43d37255, + 0x1569223b374f6747, 0x663732ecae39e5a2, 0xabcaa71d59a37df8, 0x5347f0e321548a82, + 0x07cac5853713c9df, 0xc3a9dc2dd39c069c, 0xad7c5ec78481d09e, 0x9749b01d4f3f4ab2, + 0x3f874504f8903d77, 0x8d2ad854f9ef25a7, 0x3dc7f44653241f47, 0xffca3d3b9574bc4c, + 0xb495e678e28129e4, 0xa4f99e15aea8eee6, 0xba9434e5e8ec5dff, 0x58b8d5f136a63e41, + 0xbb62fc5b75249de2, 0x95252c0c4163e5c4, 0x63b3d6ac6068a87d, 0xbf610fe2a230c694, + 0xfb371e30b6b0800f, 0xbf0c60b8cf46fcd2, 0x5f482ee6fd636349, 0x483cf249ee9c58b6, + 0xabfd792b92c04f04, 0x37ac505a24cd34d8, 0x15b0e1a4bc419a8e, 0xc054d2736de68382, + 0x9664c3eb268e841f, 0x3703a233267fb857, 0xa80503a59dda91ed, 0x9495540e2eb9e856, + 0xa4d325ea30b536a2, 0x5de810e06d6f4314, 0x0eebcea9bf7d972f, 0xa897bd70cf24ef58, + 0x4aa4beccd2e751bb, 0x3dc7bc22436e0c5e, 0x1083c660b40b0701, 0xa429ba1a71506636, + 0xaa9b3d701ba42ca4, 0xd4410dd39174bb6e, 0x4460f2403d1f8189, 0xb74a5b410a66340f, + 0x788fea5eb4b7f315, 0xf5743373cfc43733, 0xfb008910f1f9f045, 0xd95d456bbb7376f1, + 0x98b9e354032613ce, 0x4f5704777390709e, 0x03d18e03e98200b7, 0x07df6cacfc619693, + 0x21a929ae6acdd30a, 0x2bcfecccc49f9dbd, 0x82424cf9b4ae86c3, 0xcd0504d1b894c709, + 0x02937d1875a5f666, 0x8ee35731639ca2cc, 0xb2eb2d22a7c64c59, 0x24635467e1124084, + 0x6781f74adff370f7, 0xc44fdf1749a8037a, 0xf8fa0ede7126334d, 0xd87799babce18a5b, + 0x200d558d4ef6a41b, 0xf3cf45360980d9e2, 0x31c349ea0125bc33, 0x023a3fd256338941, + 0xfad19742c8d871c6, 0x65402f1f04faec05, 0x5811c8ba870e8934, 0xb784c5b428db629d, + 0x9c04c7f3c631c548, 0xe403757813cf60bb, 0x2094d21b9628d5f2, 0x2e3415aa021355b8, + 0x62f586805a6705e8, 0x82fc5c6dcafc6ced, 0x808ed4b119ccd701, 0xedd86f83cc44ccd6, + 0xb598993fe5f73f0d, 0xa25dd22507c4cf32, 0xe7a3dc66eeaece14, 0x60ceafe8f0ed4176, + 0x02387790a955f77b, 0x554b0dee54688c0e, 0x01528024d2330b1b, 0xa065b5c010aaae6c, + 0x65630a0881075bfd, 0xf4d6c3ee80081efe, 0x7ef971d59ce0f60f, 0xffcc24f646da88c1, + 0x5c395a8c7e9417e2, 0x8337287cdf917a4d, 0x24681d122b7e69a9, 0x63fa3be7eec4f8b6, + 0x25389cba26c1a553, 0xb69f6af4aad42b25, 0x6ebf3273b487a241, 0xb63e4a5cda389502, + 0x618c9331736fff99, 0x44458a0d1173de69, 0x633f400283708505, 0x6882cd6263286c0e, + 0xc4b48787b55143d6, 0x80061840d5fdc22b, 0xd6521ab280e4720b, 0xda861a17df5597ca, + 0xb7fe3d834cf3331b, 0x5ad83df37196fb74, 0x67e567e62dc572c3, 0xfea1e44a98cd99cb, + 0x3e894855f605cbf0, 0x9a631232edfa8118, 0x319b51dcf7ac5d94, 0x2b1002ead4c95228, + 0xd5e10fd34c18e746, 0xf7b0a334bd75137d, 0x63659771d0778e8e, 0x87f39eabed1fe825, + 0x46a59f0935abb259, 0x7c6356aa18bbaf11, 0xabcb9bb888fd21ac, 0xcf572c57f4107f01, + 0x4048956956608287, 0x65760b28323a4572, 0x6725e4b3b9faf533, 0xf533038a54477253, + 0x193551bde25ccfd3, 0xb3d16ab8a60ccd81, 0x94a5f0200296a623, 0x04fc5920be1002a9, + 0x30e76362e3e33f4c, 0x1bad458ce0c5572e, 0x1cbb78605a577a28, 0x0ca92a38d5e34620, + 0x7304dd90b6098044, 0x6b2d93f43d2d3564, 0xe0c2cc48d054f173, 0x8d805bc4d62edcf5, + 0xc6d5f0469e3fd469, 0xee3d579f412ffc8d, 0xc3e9b7c1e4b02da7, 0x034e4d3fcdc4b7b4, + 0x7c80f2421549d7b8, 0x000d0947771fb77f, 0x1a230ef572a69f20, 0x1e418e45c28757dd, + 0xc29815a1470ae0b9, 0xb6a726dd9054f3f1, 0xf5e885744cababdb, 0x184d4ba6a8bebad8, + 0x1d0ea6f7fbe7558c, 0xf8cec75e3085ad45, 0x5d0189f64fbc6764, 0xf8061799c9483656, + 0xa2eaa4394c120490, 0x20578b973a93cab7, 0x8444239149b3e985, 0xbe8af5e989f42d60, + 0x32dd624a683b5f86, 0xd4736d9405e9e0a0, 0x870a296be412c177, 0xa4f10b38a633271f, + 0xb5e6bb9a18b6733f, 0x2035d41bc89fa7ca, 0x2e321b63db70fc42, 0xfa4c1192ffdd5b89, + 0x9622f17b3bf0c523, 0x4406bb9af76a8ce8, 0x01f57def82922e6b, 0xe8b38737442c24e1, + 0x3d56ffa85bbb4f59, 0xe30f7432b88014a1, 0xfd2b2922d0551f1d, 0x6d3d0e004158073e, + 0x289fad3dade64100, 0x202ed3ea20f66e13, 0xe9ebb92297569b7d, 0xb3444f3e28413484, + 0xbc6f7c76a5cc73f9, 0x7e1399196e285a02, 0xc9d582ee454b1045, 0xeea3a632383a2dbb, + 0x324611b8ebb85812, 0x20572d18476b668e, 0xa8adb97d4a033b43, 0xe2ae22892ca6d106, + 0x6837e25c5fe3b662, 0xd185d9f4bffac720, 0x4aa3294e68bee123, 0x76dde412cb891e78, + 0xef4c6c79ddfa62cc, 0xb2b478a018a1ff23, 0x3535f790527a5fec, 0xfff10602c871e4c2, + 0x85103d3bccdafc62, 0xba00493118a1ac0e, 0xa76a68f9092ef0ca, 0x8bbed22f125e32e7, + 0xe0e4609827741c24, 0xcd1967cbffd237cf, 0x70e56635c15b6ffc, 0x96efb4f6ecbf4f55, + 0x74262b8f0adaa54e, 0x02a5db2615066c86, 0x8c5a46022c34d6cc, 0xc4bee67758f08a7a, + 0x687e060cd7e3d736, 0xbee0754c13bc47ff, 0x38d9223712dc8571, 0x7f0ddbdc66805a23, + 0x757076d9189fb0c2, 0x38461cca224be48b, 0x97ae19ef42ad2d18, 0x87d63875c9692319, + 0xf9fd145a67c1f1be, 0x29933932e0973fb9, 0x63630891073366a4, 0x28844cfcff118733, + 0xa30bab193b46edef, 0x3591d083f0e740af, 0xbbff7420e363b268, 0x91c6ec36e5f3b88e, + 0xbd5e36423ba6c22e, 0x42240e405fb7cf73, 0xe95d3b3c08b3abcd, 0xf8cefa6e85916c12, + 0xa69b90e9b8ed4140, 0x2637c7c866297b8a, 0x4a5afd1b9106bd36, 0xa93d831890ec4e3f, + 0x15ba9d21108ae928, 0x845a954364e3b3aa, 0xa9398021df698ee3, 0x0c22d039ba9db7a7, + 0x1dc7095ec4dc73f9, 0x6f761db47b77ea9a, 0x838a12a2e1fdfe17, 0xff2c3d3f3ca4590d, + 0xc947213c19ff84ba, 0x8619d4cdd28792f1, 0x77c0f37cff97f9ac, 0x2dca69532efd892f, + 0xba3071f99e822992, 0x9f451fd94b56bb9e, 0x2115dbc4ba1209f3, 0xdbb7681b74f6e69e, + 0x6415ec4b4259e747, 0x593568909be18c54, 0x4ad2a315495334b9, 0xa7fb31b9ad769985, + 0x241f14f42817156a, 0x5cfebc33e3eafcc8, 0x9b434c91cd18a4a3, 0x2a15993048869096, + 0x20350483999fe559, 0x1f3ae7a4d3bee96e, 0x1964f5984e1a9b9e, 0xfb6454a7f0502298, + 0x9795610c1dbe3362, 0x97c02d233b987cd6, 0x50c4a34e92bc39af, 0xfdbf3abeb1e772ad, + 0x916c1f1312876cde, 0x56840db45cd79429, 0x119c29ef39f30269, 0x2944fc2346b645b3, + 0x4a5f59c984210031, 0xa7d86086d179853f, 0x5d49ffd13420d3da, 0x973add78ecf4bde3, + 0x0907646c857dbcc3, 0x8c263361a267986a, 0x7e2949a0fc71620e, 0x141387dee9918325, + 0x2413a74199be80f8, 0x31dfd46bd2155c08, 0xe23bc194d1c65db7, 0xec07b2b8fa95ca86, + 0x6ec72b2195b5d8cb, 0x75410972335ad4e0, 0x4c5b9ba8852ec9eb, 0x983914f7e0d79c86, + 0xdc6b422e6f3f1d80, 0xa3ee8b3305342c49, 0x3299dd69c2b019c0, 0x8639bc747234aed1, + 0x8f95de0765871f47, 0x0ad12b76345f18dc, 0x9bc2680edddcb52d, 0xd423cab8f3fd857e, + 0x7bcd2fbfde6762a1, 0x678229bb6b6c073e, 0x3e2ed9f641a01517, 0x24b895e733fcfe18, + 0x889996d74498c983, 0x11e461ea2cc00fed, 0x706ba390740f0889, 0xf11ca030074160b6, + 0x01e5164bf75a2347, 0x04bd42da11ac8021, 0x661442c8f604087c, 0x5f6077a3c81a62ab, + 0x4ae046b263108978, 0x8929d2ec6d437efb, 0x6f73d5622e467666, 0x465e3a0ba39ff38e, + 0xa1bd0f234881e84f, 0x621afe362ab06727, 0x1b28e2f0a0fe7a4c, 0xe1cb10833ddf3d25, + 0x9b336cf72c35ce09, 0x476d1bad6f14e174, 0xd154f3b38e6e478f, 0x99a33ed98d8e9e47, + 0xa4126b02514cf989, 0xd7adb055f9346b24, 0x3e97fffe373d022b, 0xc29489c58343152c, + 0x50bf4dfe64a906e3, 0x614514e12f1e85c1, 0x3e13113f6b39d15e, 0xfaf36b91e4c230f2, + 0xb629de52c1e2ed13, 0x667da598b9a3411f, 0xd2ab8a244e4db847, 0x866acaccbaee9f2f, + 0x02230d28d934f8e2, 0x2b5301658374ea7e, 0x0fab71421f81b0ac, 0x577242b013f2fa0e, + 0xde7eab69260d9382, 0x1c7a132da2a310c4, 0x0bdd1252e68e07ed, 0xcddcd4e9818a608d, + 0xd74a85b2e44bacbe, 0xbb05cafbb9407260, 0x7ff6eb74a15fad81, 0x43c5be114b667abd, + 0x39e28cb30560d7be, 0x20a09c0e1da7804b, 0x4372ac27af480058, 0xcbf9ae705f471562, + 0xbf8b5a07e5c2f8aa, 0x8e6351d8d5e2ed4d, 0xb3791878fa2bcba2, 0x1e1438e79e8d53ad, + 0xef89e9e1f930c13f, 0x25f035bb1504c5e7, 0x13a1061a3d3b20d3, 0xe04d5d02c47dcb1c, + 0xa895b1994711366d, 0x7c3e2517b54006dc, 0xbd279e703dc6340a, 0xfb8c2421e45648fa, + 0x69f21b883146c396, 0x30761ade5edc805a, 0x7fae01b63c5e9e75, 0xa49bc45a3a12d828, + 0x58761ac1554623e3, 0xd60863c3d017f31b, 0x388cbfca16604022, 0x3684aef4174c3474, + 0x1c41c0e898fd9004, 0x841f102deea2b3b4, 0x5f7c8d1b0ffef836, 0x6e147119ff0fc8c6, + 0x61b4452453c9ff09, 0xb838a7be01b415e2, 0xb72fc03946f8339e, 0x3d3444ef353cab92, + 0x5bbba2374ecab2a2, 0x4d68cd2e21d59bc0, 0xfd6aca5841378cfd, 0x58b0425bb787dfec, + 0x20171a7f29927b5f, 0x10356998303e34b6, 0x83ad7440d1e90ecb, 0x1308b3b699d40af1, + 0xc6bcc1358103a4bc, 0xfbc3f0a9ec6f04e6, 0x077721dc618fbee6, 0xa516d96196bd0ae0, + 0x187308ad161fb1bd, 0xe4cd724e202238e1, 0x1fa733452bf5b3d5, 0x4d3a28c287ff47e6, + 0x2e724d97402803ae, 0x6705fc9ac7210c05, 0x28ff71c27553d7da, 0x801cea05bbd29bf8, + 0xee8d9c565cee5cf0, 0x7da63625d5544aaa, 0xb0b9898b51c28fee, 0x5614515c96500a87, + 0x3e7ec3fcd3c7b8de, 0xb5b6304df70d3bb9, 0x4e51967a36b75a88, 0xed544c3202c19ef8, + 0x80a3a47300250716, 0xe9e0cfa10d17867c, 0x2ad7465bace57593, 0x80f025a95dd7c7f2, + 0xd2ef04d30eca591d, 0xa063dc397ccfb811, 0x9ddcbb74bebbcd8b, 0x88a94374f1c67bfa, + 0x950fff67f2823fcc, 0xbcb1b200cb44304f, 0x0fa29b343dab9b04, 0x6238724563f84e5a, + 0x3f7ec27e515cd3d2, 0xe4d6cbd29fd50ad0, 0x635bc6f0946ed6e4, 0xeceeac0b89981f8f, + 0xb68727738843f0e2, 0x70977a16eb0d5086, 0xf675ff429128e6ac, 0xb2063d29d122d0c8, + 0x78367280611e49a0, 0xfbb53afec9cc5286, 0xed5d984284e865ac, 0xc426e160baa632d5, + 0xda0c7f26b03d30de, 0x0acb933da2e3fc1b, 0x2dcee7ac6260b8ac, 0x12d171567d706e9b, + 0xad58d4d84f10be49, 0x6a03cde7d03cbd85, 0xc0d05aaea248f9ba, 0x05ab9bb6d94beaa6, + 0xf910b641c41567b5, 0x72f4c29142685c56, 0xf16d64e35e0a12d2, 0x479fd9f777a51fe5, + 0x8fee9b0cd5589da0, 0xdc97f62c5f5ddf91, 0x6ac41a9ec61670e2, 0x1be76352443729fa, + 0x8eeb2c2f582b0267, 0xe8b2170cbad11487, 0xac92cf3efb9e8c1c, 0x2f70a7cc43f12256, + 0x87ab2d4206bc3bed, 0xc9b1bd19ca9599d0, 0x6172d7d9fb1716a7, 0x40294a18c6fddb78, + 0xa3c138da881b1932, 0x69c024bc174c8959, 0xf2992df6a1800f1b, 0x6350b03c68bf78ac, + 0x62ab3213f0813641, 0xf998330530ee8e6d, 0xac840221f6421369, 0x7c9e0277daf9efc0, + 0xab7365fe1a2af31b, 0xaff7f31df55030f0, 0xb91c1f713fe013d9, 0xaab51b9cc2377bf4, + 0x6236a954dbe14a3e, 0x2dcc3ef4e86ed5c5, 0x9a83bb951ba13113, 0xcc5f5dfcc8033ca4, + 0x2888fdd747223e81, 0xd89d216bc633c4c4, 0xffc8d99fd45ac8d9, 0xbbe7fedd2ac092bc, + 0x2fc9090510ee3e21, 0xcef1b0191d043894, 0xeab83af140bdedf1, 0x60c74049bf583907, + 0xb1384528425478ab, 0xc760141c34196630, 0xb38ff9a06aa4def1, 0xf56313994f1997e5, + 0x2578331137c0379c, 0xfe7e726097da9ed0, 0x5218a443a9a14871, 0x14e89462ff0e898c, + 0x3a9e469f0513485c, 0x60efc20a6fe192ab, 0xdb26072bbfff240d, 0xbb6c4c4509f1e679, + 0xbd02a35c1bc284c3, 0xe36992d0159c8608, 0x25405aed9d2735fc, 0x6ca396aff2acc338, + 0x03523baee65a6f0f, 0x7a9b225177ff8f19, 0x0ab9eff4f2edf9c0, 0xa99146175cc68007, + 0x8cf2038cde83f0f3, 0x9aaccc2a4ec3f906, 0xd087d8971b893efd, 0x54e8be5a6e99c971, + 0x576e73372fa3050a, 0x5258648fe9b0e237, 0x84cf69a83c3681b5, 0xe97e16e65f202603, + 0x583cc7cd6146944d, 0xf2c1e887fa65f387, 0xb1b274a7554b9a60, 0x456c85111567972c, + 0x2179f035331d7d67, 0x1f727f75d0dfb362, 0x5cc7ca857d97d4ed, 0xa113a416609b636c, + 0x3b1fefd1129c7b2d, 0x02136ec852ce759d, 0xb3c2921541bd0f03, 0xb63e50958a333578, + 0x0455bff44eb99742, 0xed8a38dcb30132d3, 0x09dbc2265ab76f0f, 0x4439225d0138842e, + 0x708636fa22d6cc81, 0xe2b61ed7723f0d2c, 0x82f640fb7a9e0809, 0xef0bc0b0776ccc8f, + 0xd88072fbdcf66737, 0xa4f4a722a57a224c, 0x4b102d19806f7ad3, 0xc1e8f41144a07b50, + 0x48b5b6c09b73042d, 0xd7f9d7855149aa9c, 0xa8bfab5b8fe53870, 0xd40818334b097e43, + 0x5ec751f9277cb4fe, 0xe7321c84a3d63268, 0xa49ddb33e1e24897, 0x9edf0273dc5f5bdf, + 0x371cbed58277a969, 0x580526e03e6cb4be, 0x850e8343c7fa0894, 0x00dadde39b113b5a, + 0xf92c75842fad1fb6, 0xaa9420b9b39801f3, 0xf91d6afb9c5cfa7a, 0x2598726ab5c8b410, + 0xa6fe83f1769ee468, 0xf98d66461a2df6d2, 0x75f8f2befd3f618d, 0x6f3b43d59a63877b, + 0x7019815f3f7f091f, 0x00d5ea8b79035001, 0x550a39ffc686312a, 0x5e70b67b41d5925c, + 0x773d5fbe9a9b106c, 0x3907f1658336e22b, 0xb581ade72a1767e5, 0xb98987bb986200ee, + 0x0de527f1a412b1e1, 0x8301558aad946cf1, 0xbdbdc5d094c91238, 0xbc07fb3c21980226, + 0x60ccb10015a2b0fe, 0xda458504337ea8a2, 0xc2b18b650a26e706, 0xa444c73bd97e7abe, + 0x436cb31f2c2e7692, 0x7488b65d32babb6d, 0xaf0b435fa7777ea8, 0x334f7a71449246ed, + 0x7ff6588146258121, 0x6322cfb8cb44c624, 0x7c41fd7d30ec9c19, 0x0a1b7e851c6fdc1a, + 0xdbe44f5dd47d5aee, 0x7f6492db639a0023, 0xd33b75ee4c230ca7, 0x4302ec8d95af0800, + 0xc02999523cabd7d2, 0x6539b0b2c44e3572, 0xab7be2442cbff7a3, 0x5219602e71ed4467, + 0x63d4d866d6f51f1a, 0xef67e300c694d351, 0x5793494e86588b5c, 0x44a66da0326f144d, + 0x27a528cae343b10b, 0x055faea79a8451e2, 0x5928e4589b8f4308, 0x83e67cba9034953c, + 0x1c22e1a36837affc, 0x27393e3215ede47f, 0x11d5aef3a7030d7a, 0x4685001ab9db497c, + 0x09ab6ba404784ed3, 0xe0e81379427e0fac, 0xb1adbbdfcd29a6a2, 0x6b523991d5d3fd55, + 0x849f890e01046f8b, 0xb76b64b6e4aabd8f, 0x3fba0df733410726, 0x93b30912b88f2df7, + 0x133d2c9358ab0205, 0xe908000a463c886a, 0x1278a8955e86137d, 0x1d42dda914ceec7d, + 0x7e22fe89922a9655, 0x144c3345cdf4c9a7, 0x10f008929273c0c8, 0xd5105f0f71145df3, + 0x0eefda26b8146836, 0x8d5aaeb498b8514e, 0xaac27129ea5cdf7a, 0x3539b8abe5d0173b, + 0x24d2be6b99798d92, 0xbb00a94780acec6d, 0x0db9e5cb566de4fc, 0x3f96b59bb1f78265, + 0x7517d7bd0762d645, 0x9e2dec7ede0a4d4c, 0xa0710a03de8cc0f4, 0x34ec582c98d57d6c, + 0x6b4c1ef15a1902a1, 0x23d448533d568c2f, 0xadb51adec854ac7e, 0x5a49fad59014bb19, + 0x82490c2ca0c68b59, 0xf211e228b24df1bd, 0x8b4c64cd5c1149f2, 0x4fa566b280293697, + 0x2965421ac0c9175d, 0x63804e7fd15ee9c3, 0xa0df2ceaf71391eb, 0x99f318aafe0c0508, + 0x2bf942acb0444871, 0x65a5aedb33ef8f22, 0xa31a8120da0d0f12, 0x72021b1cbc331ee5, + 0x01751d041df1267f, 0x357282823abe1b75, 0xc7e779b369268b83, 0xe826eef79f35bdf3, + 0x53cf452cf37c5d6e, 0x6b67fbe70d8c8b98, 0xfc6668a22db81881, 0x5f10567d90b1a596, + 0xec3402f9bd829b7f, 0x3f46d8d987b34c61, 0xeaec6ddb3ae03509, 0x933a79e5f5a212cf, + 0x8b6ff33074e9e07a, 0xafbe69aca68f88ac, 0x6a98eedc802c3c45, 0x920d891e1279b10f, + 0x52c6b59b2ead195a, 0xcf1fcf310c0e34f6, 0x57edc267e94de68c, 0xbb8b23bfce5ec884, + 0x5bb4792e2b262ec7, 0xf80a0ffc881c66d1, 0x178420ad01233906, 0x73b30338ffe6e388, + 0x859db437bc9eb680, 0x856671d30ed8ac45, 0xa07b1e4e541e65c9, 0xffc26f287b1aa856, + 0x6c150cb36c2fefd6, 0x838ef06a97adf2c9, 0x4adc32828033f45f, 0x6506924144773163, + 0x242bf6b59af8a638, 0x69d69be2d3efb811, 0x063b92b4ab7f384e, 0xa9d7665e499282bc, + 0x0cafe2800a9419a5, 0x2dc6a989a4651d9a, 0x66d3e063a8024bc6, 0x2348c5ad26d87da1, + 0x46689de965067fcb, 0xd22fcc06425a37fe, 0x7d0707145270c92c, 0x70b5d135dc0a67a5, + 0x20bc8ffb9b6f49ad, 0x130e451a4ec90bd6, 0xac947430ee8635da, 0xfd089cc08031e9cf, + 0x25db8e6d71b0da03, 0x38bfeef0c5f0f8e8, 0x9cdb6d55ca5e3905, 0x78d2e38b50dd03ff, + 0xb8bf1b99441abb68, 0xca42ec87e7eae143, 0xd61c53e1abb43c02, 0xf388f7eb83e14b9a, + 0x6164b42fc31a84f1, 0x0126e6c400e35c83, 0xa187aff5248e0e6a, 0xdea8a1e935f117a1, + 0x002926d861971d2f, 0xb6fe415686b0a31d, 0x98c0d5755ebc8513, 0xf815c738ab21d47d, + 0x77219241d086ad7e, 0x5747d5b7373dc644, 0x40f40d1a3bf7a11e, 0x97abd81021596e64, + 0x763ae3cf980fc763, 0x538f09e601b0af96, 0x53d836fd7878bdbf, 0xfd071044951fd869, + 0xfb037fdaa7b409ac, 0x24dd9dd97459ec71, 0x33fdb95b1e4811b7, 0xf5faf3841e6a7ac4, + 0xe86d092b76edc4d7, 0x2854c623e3061c2a, 0x0fb599fd937ca40b, 0x4eef20d9343cd0f1, + 0x26c8b2e3cc2da7e2, 0xeb93781e8dbbbce4, 0xf58538b7173ae8e2, 0xbcc1732e68018add, + 0x8f068b9dcd87aeb9, 0xcb0c2ae33f541f81, 0xcdc817b2e132866e, 0x71efde46046829c1, + 0x9313703558af2c98, 0x019b40abf6ffb62a, 0x2e71f907c2612ab8, 0xd55916e43f0f8dad, + 0x3613a0cbd3247b66, 0xcbc21929b651c8e3, 0x3bf7b6d4328e304d, 0xccb92a98a3feac1f, + 0xac795d805ef52629, 0x3aea792dd673c970, 0xb7a0cbe1039f3ca8, 0xdbab52fd5c14d5a4, + 0x14c81bfba4109ad1, 0xb5874a356aed5f6b, 0x59db68f26dc7c176, 0x31c0d08cfa1b6488, + 0x4df2347994acabc7, 0xe170e07a8650b94c, 0x24a8465def275d33, 0x18a4f018ed4fa268, + 0x59b97ac4464d308e, 0x9e8283d5654fe141, 0x1557b8fedda84496, 0x2158cd9d36d9215c, + 0x9f156744c0acb685, 0xc5906b07b0695d76, 0xa5a98567443c8101, 0x5dea04627814a8a3, + 0xce9f949163b77f66, 0x08b8579b91ec3b7e, 0x3bf1b8c27c90b9c1, 0xb86ea4d1b2658221, + 0x42a8ec970d613a99, 0xd856c9d6a3cf44a2, 0x3541249c994b9814, 0x50c624a99794d479, + 0x51ac98038e4bb1a9, 0x24f4d35bae329b40, 0x8e18f79002951e01, 0x7c12f2b2d2e5d1c2, + 0xa56503d846168ea5, 0x1aa827943a256d45, 0xc8d8d3f44d5c8530, 0x0d9e3ef491208646, + 0x40aecea6994ebec3, 0x3e1f873884c696f0, 0x0a94030375fde069, 0xcdc7b936ed70d10d, + 0xf9e97fa4f8ff300f, 0xe87e7d3870ae6a6e, 0x6431b975d2ca0a82, 0xebe138519be675eb, + 0x08cffa8376b0a3f6, 0x342ffa303b3bd90c, 0x838fb6651ff19c9f, 0x1c625f80ae810167, + 0xaa72752ed0c9969e, 0x686209c30cde7420, 0xfdafb54703d02265, 0xe0c7fde129603896, + 0x87e197da439a2875, 0x3cd074a5ea8cada7, 0x43738d3936ff3acf, 0x607d15d25ea90e73, + 0x176ff04511c7188c, 0xf2a30e44c457a90f, 0x5bab5009f6ebdf0b, 0x471bba65a7548aa0, + 0xe0be5347b0b3c833, 0x82680bf0f4405552, 0x93cbaf577ce1c0ef, 0xb7b0cafdb9e4ec07, + 0x47672f4b601d2d96, 0xe6e00aba4873cddc, 0x9b566e7814f343f0, 0x5d0cfdf2e4f74609, + 0xec304579ed0ba984, 0xf4958117f2ffe6df, 0xe5c6430cc330c952, 0x89a2d1a7cb8b9021, + 0xa0df5cda7327c350, 0xce56fec1c9ed720a, 0x347048f13a7764ec, 0x49545a2e48d1cc13, + 0x6dcbc8b37b715470, 0x305d14c8aa534f13, 0xf28cd936027755f8, 0xd141258f2a3a7ef8, + 0x7eb05ea4fcf6270a, 0xef75f784a6c94950, 0xd8c635a443eef371, 0x83566ba5c4c535f7, + 0xff9a389bcb075a1d, 0x8a3a4d4aec645142, 0x5073ac4a6b78c110, 0xbc28252a5aaa129e, + 0x61357ed3f5632def, 0x3e7403074f500987, 0xd80387f2389e26f6, 0xfd8167081c95fbe0, + 0xa3a59e3d26be9880, 0xc9b80a6f56c5edec, 0x8bd3bf564af9584d, 0x60bcbd6aa1546e50, + 0x92abfaaf21cd0989, 0x8642760b00b74d20, 0x650588b5c5bb38cd, 0xe0bffa237bf11597, + 0xd2bbe6d1470fbfff, 0xb2e6283843a098b7, 0xd87ea5ecef8a3160, 0xa88fcfefcfc50a78, + 0x344ac5ded52bef7c, 0x0097f4908c79d7ce, 0xa354431d491e7e0e, 0x2a05c657362130fe, + 0x0e77259201495e10, 0x3ce5002f63285c91, 0xfac64675d3acc69e, 0xf514420860440002, + 0x1b39dcab8c29c149, 0x17988680f4fbbaf5, 0x6dbc864e5ccb1029, 0xacb819cd1bb19222, + 0xdbd13c2bfbbc98e5, 0x7121042165396941, 0xca010de781bca904, 0x8d1c40e9e07733be, + 0x3e474eaf98e189ee, 0xaf8aaa88bc62a718, 0x5deb4e24dbeb7c4e, 0xdfe4b13c3d7db078, + 0x3a30df45461c8379, 0x3e69ec661e5de183, 0x76ac4a1851c13db6, 0xf3cb0d4974c966fc, + 0xa6644a88d5bfba4c, 0xd840688f80e15aff, 0x0d7adc64d8b3ccc8, 0x7dc204824781df39, + 0xeebfcecf5e4ec802, 0x710d6867d2763202, 0xcf17cb58e9a748cd, 0x9f3de7775c80a6a5, + 0x5e38d52f7269bc30, 0x9a4cc197ff5b795b, 0x88ba66d8ae47dfbf, 0xe8c4ccaf3de36249, + 0x8024d3dcc40031e7, 0x1f44397a585fcb33, 0xf4185ab72a6556e3, 0xc08ffee9c939b9e5, + 0x40118c9efdc86a41, 0x659bae5db968cd1f, 0xe2f419c026037925, 0x206fa830ccb16889, + 0x803c9b8b0bde98d5, 0x10622375cba67f66, 0xd74d2a653001b954, 0xab1311fc41125709, + 0x25e0a7cf20477c7d, 0xa084ce509b78c057, 0xda960101c166ed30, 0x6e3e99632767f4f7, + 0x9b7f73492cd01ee8, 0xf9ddcbbaacacd201, 0x4e299d67b2f15c2b, 0xb6d0d2d06ff812a8, + 0x4050f769c25fed67, 0xd48ee3afcee45de3, 0xdbd3a38851c59076, 0xc339fcf63331cf72, + 0xea1a485912bbc1fc, 0x5f4588f41c35102b, 0x63c9ae9a4efb616f, 0xc617d1f845630275, + 0xd2ec1b2299b914bf, 0xddad170ef0b48ea9, 0xb58149d333e21e88, 0xee2739f4f25738e4, + 0xe475815a18b999f7, 0x229e7d6488411432, 0x442b7fef41a713c5, 0xe79ccbde9a3814c0, + 0xad89f885f9bbc83b, 0xf83ee7fc3a4312b6, 0x63c24d66406f7530, 0xed2d93ecdb9193ec, + 0x04c360f33bd81358, 0x55f12582eefd7cd5, 0x03665f4ba1aa4681, 0x9aac2afd3ae62979, + 0xede1db5a9a92078f, 0x7f649ce48e29ec83, 0x73d715bc0e4a7141, 0xf75f9600690c24a8, + 0x529597ab7ef015be, 0x22a7696c7c1e8439, 0xca56c2561f405e6f, 0x6cbd4a0c5706a954, + 0xf8f97b079dc698a1, 0xbd7ae808cf7a5bef, 0xbcf38705abcf9804, 0x837c0f8411eb3426, + 0x4c9f70764a9beef8, 0x2b8d1614ec49e8b4, 0x942a2484a75ae1a5, 0x1f3a96e04c52e10e, + 0x2a9e6cf2caba51e0, 0xd4f392488bb40f66, 0x3d049f81a14263f7, 0x1efb9779487a692d, + 0xe64bbc741fb90ee5, 0x750cc0a76f252081, 0xfc01af620bb64a6c, 0x03a8bc50607ab4c2, + 0x989669e019c573ad, 0xedc31de4fea1d8ac, 0x88c14a69a48331ac, 0xc4394ea7fd9d06b9, + 0xaa5c37f06d82c133, 0x71bb0ba43cf79e8d, 0xf33e40cc3b14a369, 0x477d5884ac2ec468, + 0x8f0c10cdd55bcfa1, 0x7652d47c7f4b6cc6, 0xa484eb4290e5fc58, 0x0cc42a5346593f10, + 0x05460e3442a86bd0, 0xb93e0ce4852b5cc5, 0x564b2c9ee56fdf4c, 0xc20d817091a1f201, + 0xd0d7526ec2626916, 0xa1c2b8f61a63e38f, 0x0edbb00df5e7ffbd, 0x3dceb1df765be25b, + 0xc4a94f5d8b82ca01, 0xffd3449c9c12138b, 0x340b7d2e8ad00203, 0xef8e8226255e94bb, + 0xdbf7afb91294c5aa, 0xf10f4e2250bd922e, 0xeed3a7f344d7b8bc, 0x26bb405b427e22cd, + 0xdaab9fe34bcaee35, 0x9102466a85464ce9, 0xf07aa034065f910e, 0xd6a588529d7528ed, + 0x9ee581c2fe26be5e, 0x3bd5133eb8cd90d6, 0x3c7ef2a6f11f152a, 0xbb9d0575d9185c23, + 0xd44882bee2c908ce, 0x2b1133213f06e348, 0xbc7a8008e26335c4, 0xeede4a0a5a89b5e2, + 0xf1ff588abd41d9a8, 0xe91defdef7be7f37, 0x23ef7812e603e125, 0x50c488c831074e23, + 0x591f93ff0d0d8691, 0x549aa39567b1b148, 0xbe1912dfa454ab0e, 0xe10f49d0b36c5fb5, + 0x02bb041d4d45c368, 0xe35f0c192d23fa1a, 0x014a42692bc5932d, 0x669e6f2a824f10c9, + 0x87eaab66007bdb59, 0x6a83f986b33d1e00, 0xcad3574a8fa64a47, 0x2dce6e1c5858d170, + 0x02d5b0fee5508e7d, 0xe19356c00df8823a, 0x87d91298cea26403, 0x6ffafa09d4e9b151, + 0xa543dc8d266e52d0, 0x8370e169b7f5eaf1, 0xafad6efd0b675aaa, 0x3e6b92fe3f18c218, + 0x8f825787566de840, 0x0d54e00ba9b44365, 0xd9a6bca439b42e7f, 0xd1836265974fae60, + 0xbb0f622e2ca9794b, 0x441576cc2191ad04, 0xe8de465c5a28a796, 0xbdc5d9843cc5df80, + 0xe46749d009c743f3, 0x4832f2e97fba1bb8, 0x1ee8346d6b1c59af, 0x2fee7325575a744d, + 0xea6ea8bc14f832fa, 0x09921be95b586aa2, 0x9ca27a2e63275cc5, 0xbfadf8dc32b9220e, + 0x20b2e513671afe72, 0xa438f78a19f5720e, 0xb3773e1c0006aaf8, 0x7a3e60ba34b5c447, + 0xa7ed53afc01d385d, 0xbdb87cd72e4de8e7, 0xf37bae30a87c91e7, 0xfd5337e1bd545b4f, + 0xe99c1c8944899014, 0x6c618bf02a04eb9f, 0x9bc39c9a5ed2552b, 0x4f30d0b904156efb, + 0x1fc2f7e2ab3977af, 0x3eea1443727d4873, 0xa16b28e209f068d1, 0xd8ca7a65675a2a13, + 0x9008a855ae6b97a6, 0x4f71c7ceafdbcad6, 0x174bd07a5b10e3f4, 0xdf53300605cf6a46, + 0xd564bbb8ad4cba38, 0x1229a32cb8667476, 0x0aaf0cf013067db8, 0x8279b13f76460e33, + 0x6c9798e58ea1892e, 0x1015dec51527947d, 0x24626c805758e0da, 0xcca536d820d6157e, + 0x779323319b13e5a6, 0x3d34d5274d7ade5e, 0x2580b553862bb9b6, 0xdbbdd72614c162b5, + 0x2b2fe4950434d7f1, 0xc9f6a7b91d0ee020, 0x0ca907d9911e8482, 0x58df292b3b54e54d, + 0x67bf1fd23db1a2c9, 0x14cd54e7ac806031, 0x0880d81c49b33931, 0x62d81bd8523deb8d, + 0x8e0554ff47245685, 0xd1a9d1fc43c7d559, 0x2e484468db0656c3, 0x5a3225a3e3e2a77b, + 0xddb15b9a10a14d14, 0x1c8e87b4624ecbda, 0x1f0c02a737ded2f3, 0x6ef7658d997c8ca3, + 0x22a6fb03325b4a92, 0x99f7b7365f176ade, 0x24baeb560080a886, 0xfc7d201a285f6ab9, + 0x43c2caaaad37d462, 0xdae58c2b758b9534, 0x5a0b0b579cf4fac7, 0xe9f6c9acf902e7e0, + 0xcaba45fe60521b22, 0x1ad5aa47bb7d93c4, 0x9304d47316104f23, 0x4cb665db75d73e8a, + 0x510f27ab7f8e5bba, 0xa3647bff75b32fb3, 0x4b3c688175f26c3d, 0xe595fc88286d01fb, + 0xe20d2f64e2f94c84, 0x85c5faa1d13e8fdf, 0xaa77cfaa03e9b321, 0x94431c6f20289385, + 0x5541bade2ba2805f, 0xdb0c4711eba0f1ce, 0x01b24be6e4277182, 0xd6aa881e8e1ea548, + 0x11be17c668e086a4, 0x7a02fbd33c570880, 0xbd08d491ba1fba11, 0x6ffa057d6550ff7c, + 0xa40746e66af6cebd, 0x4526db2b09c011b5, 0xba50bda98cc246c0, 0x3b82d16101067c7b, + 0xd347ed714cfdf10a, 0xf768a9563f545755, 0x0a94f5e871bde0bf, 0x407b6cae1450d616, + 0x31d5158eb2d1e902, 0xd5b8aeafd4ac2335, 0x8836d90acd1fedd5, 0x771ff10de417a6cf, + 0x781b35bcdd77481c, 0x0e156f8b58d26e28, 0x2a73fbc632bd3cbf, 0x945562a4d6e61fb0, + 0x0c9b97937482504b, 0x8d00db9eca1b5bc5, 0x15cc3cf3a67d1168, 0xe958ad350d2397b0, + 0x5c1110c84a9bee4b, 0x6a53eaf70438ef22, 0x39b8dd62a1a0ae2d, 0xd35629f07e106b01, + 0x5d6e0f6101fbabc8, 0xf88b84ffc7b4b0de, 0x2e93e19f4defe581, 0x8faa6fc837d30f56, + 0x2afe53e336e4d051, 0xaafdbebff4dcabf6, 0x7ab440a7ec5fb90b, 0x6357983e799c2076, + 0x53499a8abeb757f2, 0x021ad2f4de1211ca, 0x73671f7d52c61a0a, 0x30f1c31cd356941c, + 0x6d79743867b0af5e, 0x93440e3a66cbc917, 0xbc4d4f11638949e4, 0xb378722bfd881fe8, + 0x63c24f70e5937e91, 0x9b04c536979896b0, 0x69a0cbdb7451d059, 0x9d10cff70f4d47b1, + 0x6423e9a605dc3b29, 0xee5ed6a1189dd6cd, 0x9ee76ad15d37d6d2, 0x825371b07cf0cba4, + 0xf343c33540dd2f40, 0x167ae2fa35f5c00c, 0xc4bcbc85beb9c9de, 0x176108f0d7da1b6d, + 0xc64b2c9e07a5b776, 0x4c884223a4280018, 0x91670a60f2ea2f9a, 0xac0b2757a357e0de, + 0x416377952afb6320, 0x12257cb160cc54f0, 0x4135242c487456cc, 0x6a5de8f4130a23df, + 0x47ec941026abe431, 0x15a8029cde62e1ac, 0xd68309ef57324141, 0x0031e9caa09accd3, + 0x8e3d59e527212e9f, 0xd158790ac03a3471, 0xb5f590e0a7692d4d, 0xffe1068be1c2c0fa, + 0x5074094a0753688a, 0x90449e3c9a1c45d2, 0xc113df6068ef0b45, 0x838514c108fb9ef8, + 0x2373d9a5116d319e, 0xcff1a7152400ab3f, 0x9df5debee6f93a75, 0x3876465df489bd27, + 0x87f5ff100fc0333b, 0x54c15aa299deacde, 0xe83f537c4cdb8c00, 0x39f8c35044cf4bb8, + 0x240528afcfcac9dc, 0x8d230fd2d5e8b3d2, 0x68491711a442fe56, 0x60914be85c94fbbe, + 0x944b30314eb9acc0, 0x532608b5f5436c42, 0xdcb22c193ede0a09, 0xd0edf5c7de9a1846, + 0x0f0a3efcfe2e4404, 0x791d4bc421a304cd, 0xc324f337e22c2981, 0x89984847a8ed8f52, + 0x5bef9298e67b3701, 0x8f8dbf9a1c108d8e, 0x5ea1867c2a92f67a, 0xe92e37c88957ea4f, + 0xb60b86b02b127eaa, 0x1f4285451b92f882, 0x54b58d6e58f541dd, 0xfa2d804cce156a96, + 0x905f9c4cfef8437e, 0x7a7139153018644b, 0x710fbbf104b1e397, 0x340b67047c7de8b0, + 0xf38fa7d13abe2143, 0x4374414f4ca6aa8e, 0xd280d83f25a7dc3f, 0x7d56917cf067f5e7, + 0x3b1da956532fc65f, 0xae04462c1ddbe350, 0xe852b43eb3a9265a, 0xb1712fb428215f00, + 0xc8f4fa7ec907f065, 0x46e99f27a7ca0dbb, 0x6d13f18fe4a1701b, 0xd78c2e5c11426696, + 0xba077b1a9b30c4a2, 0x1c6286e7d7071d8a, 0x818c17145b5338ed, 0x5ec769fdabfdb6a1, + 0x12405c2ea1a99be1, 0x838f8325f0a20ce8, 0x649e291e073ed8a0, 0x6d59225a4be12c43, + 0x39d58e1e19fffcf0, 0x5f954142442cd1c9, 0x04114814e3c8077e, 0x1e18919041e88178, + 0xe751c607992dfd69, 0x52883c269284ad0d, 0x8d8c1cd11c0bcbe4, 0xffdddf6d42887e0e, + 0xa61626039fbc11f0, 0xa358894101a43d25, 0x15a0e39786dadfea, 0xde52110bb266ffcd, + 0x789cf787c26962bb, 0xa8307193c746d77b, 0x2da298985e57c79b, 0xfb253abeb4af0d38, + 0xa7aa369bc28cb23b, 0xe619dddcb9f67599, 0xcdc779bdb6ea8903, 0x6f7e4a3c3e826c3a, + 0x10dbc2eb9f6577b2, 0x3d0844e07f4e3ebe, 0xacd58279214aab25, 0xcfb3e262c372883d, + 0xebe100b854c85b95, 0x09c1308e870b6293, 0x3ea7b0cd44708a04, 0x7a0019fa0cec4a17, + 0x79d3b45184f2a736, 0x5468159f5b45bad7, 0xb80a87e28892ca36, 0xc6efcaa562dc24c3, + 0x455b590791ad3ff5, 0xf2dc0db5dd191c1e, 0xa2f57ae6ce6c7a24, 0x4185a0add71eebee, + 0xbbb4bbbb764cd586, 0x9ee50324166cf005, 0xac9bc406eb6944f2, 0x47cb136ef0177b40, + 0x90eab1853f9d3817, 0x64159f8f8a7ba82f, 0x0b4f830186dc316b, 0x9f558a730108a8d4, + 0x313ee7d95633a7d6, 0x364418f65f236313, 0x193ba1b06a2aeff4, 0xdef0f7f8a1287c8e, + 0x6b3b0acc6e914d2b, 0x4a304aabe71841f4, 0xa814c767d926c645, 0xa63c960874b007a5, + 0x9fc9ac26c74fae82, 0xc8c539c0e8559b8e, 0xbd6d3449e7cf7b58, 0x9de03081bbe18e5a, + 0xdd3c4c26c7ee2550, 0x2b65d531629f3caf, 0xcc0e0275864d009c, 0x4d7121b1c229f15d, + 0xa14f4423ef690b3b, 0xdf61d843a8db75be, 0x567d5393e91de71a, 0x099ba1bdb7a389e6, + 0x3f88703baf7eff50, 0x1c14d5077fccdbf1, 0x3083ce559861e47f, 0xed4cc8aa155c2421, + 0x3f21ded2b6e86f3c, 0x5b76905eff8d5e20, 0xed7468bdbfbb0f53, 0x40bb7c90942f2f1b, + 0x53afe034040b27f3, 0x2ce0c2a1a793bada, 0x94c033ecbc6e1704, 0xb56d92eb6202e285, + 0xb768af8e184389cf, 0xa523162c0edb9217, 0xe93f9a1e666969dd, 0x1b34ae8a5757d80e, + 0x7ef66dfd633bf2da, 0x489e6399c33a1de2, 0xef247db583920e63, 0xbda35894ccb9ff09, + 0xeb2e51cabb0847d8, 0xaa37dee8bbf2993b, 0xc7afb6930f1ef16a, 0xdd372182c3a8b8f8, + 0x4ebfefe95df3a7b9, 0x089d062711edd073, 0x8e1f6c56434324da, 0xb7ee7e34b4ef3970, + 0x7e09a61052b66d18, 0xade447874d7bb760, 0x09416a6a2f4f3306, 0xa70c4c4824721dea, + 0x88060cb742bf2b70, 0xecae6713dda5240d, 0x176dc8cb5b627afd, 0x668252b6a0cb92ad, + 0xea8dac8df082df12, 0x4f7f3f5175df8fa2, 0x94cbbc3bfb4c23e6, 0x7038bd66dab2b185, + 0x3dc31fc42cbf3765, 0x44c55ec0146650c1, 0xae3b80e29657785e, 0x40735bb3c0e543ef, + 0xde526f1fcc0da510, 0xc1770e33fb14f048, 0xd2d004270fad147c, 0xa0824404e7fbf593, + 0x68808bea1adb89c0, 0x4930fc7f38a0b5e2, 0x717967fdb336cf34, 0xd33aba1357f47743, + 0xa9aeacfa1a8ecd52, 0xbbe36ed730876f8a, 0x606214d70de85541, 0x81b25ffb755622d1, + 0xb2e2782bddc6850c, 0x59943615e04c8024, 0xfdea0d06eb678e2c, 0x3b09d2656ea1417d, + 0x829fc569ff490bc6, 0x0759f0b840a7eea2, 0xd3a4eda95d6ee0e6, 0x674ae465c476ab80, + 0xe70232fc0514a30d, 0xc2d28ae692261222, 0xefda3965c14c1a13, 0xcdfcefe8cfab097a, + 0x5b7b59047b551dd8, 0x90d2de59c7b6af06, 0x915859e7d8e98167, 0x5459fb0dcc16192c, + 0x2d33c6037c93d5b3, 0x7afba33d7da8d473, 0x96eb623eee2792ae, 0xe36a5ff5c6c98259, + 0x2d45baa19f3d2bd7, 0x32825e286e55e33b, 0xe6c72dfbc44a9e39, 0xbd8e3d49f21884ea, + 0x673106cfcb28a738, 0xcdf54e3966b95922, 0x432d0a8cb7850483, 0x373bc56d47437503, + 0x79d997526f61c6c5, 0xfcaca5f0267ef33b, 0x68cf3a29ecc6bd55, 0x0c09f6844ea84d27, + 0x047a3a02c789423c, 0xebe08d874cfec9f8, 0x1893d663191a04dd, 0xb020e8155aa8b9e2, + 0x322de5857ea1f70e, 0xdf3b2f16e5402105, 0x6901782b2075c69a, 0xfb1a15e4788b9a05, + 0x2cd6b928ad50b701, 0xf66428d2342f8be6, 0xfe882ef978a35dee, 0x8bf01e43cef231a2, + 0x67b411e45c3a5fe3, 0x704db88984d316a5, 0x59d2f96fd1bc8f13, 0xa090e2c08753cb73, + 0x341bcce4b9616cd5, 0x2a91b52a6b3ccff5, 0x2882b7a521953d3b, 0x94ae6082a3243af3, + 0x506ae93cba20447c, 0x67756677f2050593, 0x8a6d378deeeaa264, 0x61f9f368706bd9cc, + 0x7ed01ad970ac077c, 0x2e413275c328f2ee, 0x5da8f546c26cfba6, 0x3430e059766beb14, + 0x1cdd081adfa81842, 0x7837570e38fd15a5, 0x2842e6d88ea9ec7b, 0x3103c1e67413964b, + 0x4538a885ce207cef, 0x5e57bd1ff4abb35d, 0xea442e0826c403e6, 0xa21ba01a429f705c, + 0x87038fbc98c6b9d8, 0x77ea999a7a5ad45a, 0x88db71fa5db9088a, 0x955e574d658d2fa2, + 0x70ef36e0a5bbd30b, 0xd63756d8cf58c477, 0xa34e96ae788d6417, 0x5034c33e0458da34, + 0xb03431cc0333ea36, 0x688b2733990a707e, 0x230a6e039ab05d1d, 0xa2590f7479c2c53b, + 0x6a5fb90268a63af7, 0x3f7e9fc6f767e604, 0x00244acd86a98409, 0x69fbf4f853d611b0, + 0x5dc9c1265a332fda, 0x48e06aea43952044, 0xe2533a19deb5ff30, 0x8edf7903d8d91f16, + 0xbf683ce4885c0f30, 0x24ab7739dbb4785b, 0xf84f0434844c3ae1, 0x7a57571faa009fe0, + 0xf1b764eb1f69f518, 0x344ad2ce552f1502, 0xb4bbfa5fba056afb, 0x9a38063cc9316ccc, + 0x257fb13d1ae0ea5c, 0xe051a8d9e9cbd21c, 0xae195969ad6a2d7d, 0xe9b2b3e8899dcf93, + 0xb4c77bcbf642c6ba, 0xdd7ea5a6f7cd4788, 0xef2331fdcfecf414, 0x31f0f3d371d587cc, + 0xbf08ed995a5f8ca7, 0x9e47d0e71e33f20c, 0x72045739700980fe, 0x797c804e72e9a9f1, + 0xe1498b85b9dcb8f0, 0x75fcc08867ef656b, 0x10d111c3dfc1cf06, 0xcce54f66c5ad47a0, + 0x91229d69d5f3dfa1, 0x6b6c3dd4dba8d247, 0x6beaaee41daa60be, 0x07c5a96947ea78a7, + 0x4a8d261a79f55a2a, 0x2eebd53c565300b4, 0x9cea8d0feb6a9da1, 0x9c8b3096abe51517, + 0x00beca9f7662f4d8, 0x8742016cae2f08df, 0xe088eb84b861b1a9, 0x945e04557e7ae8a3, + 0x8bf0ac86f7bd93b6, 0x9796f3c67e2ba1e9, 0x6db54c7d73f031e6, 0xd7685a39b3837a8e, + 0x7869d51b3fbe7b5b, 0x2136bb80b6f94adf, 0x77d593f27de53477, 0x02fc88982fa5fbc3, + 0xebff26da31766a41, 0x0f37d08f485f8e16, 0x00b52ee450384e3f, 0x5f4ba1e7ebab9276, + 0xb381d28a7ef50ce0, 0x56407e1607a2b23b, 0x8712564a0a43f46d, 0xee64d2c21b5be832, + 0xec2d00d71b31027d, 0x036539893a621356, 0xbde22828f3b8bc0c, 0xb5c36b4bae925b1d, + 0xeaefd1171dd1d878, 0x4ddac1434e620296, 0x51a519a7967e5382, 0xe19960915e8fefc4, + 0x2ff2461496f27990, 0x3ed5f03481dc77f2, 0x43c2cea4ae3608aa, 0x3d34386662511820, + 0xb87f3f44d34ab4c7, 0xd6701e8accaa4875, 0x320a0c464cea9710, 0x0f188865de9b089b, + 0x8783d67afe6e3ae5, 0x4e67b56f366ebe44, 0x559154040727a13b, 0xdc1a9424f74883ea, + 0x33625b50c5850bc1, 0xf9f8e555d70078bc, 0x81f377341948117e, 0x558cb4cd13e89012, + 0xa742c995b31b73aa, 0xffaea227143262d7, 0x39882796fcaca466, 0x124132e25d47a7e8, + 0x6d89a6dc37793cc8, 0xc03e275c9be81003, 0xd85c7fa33b00d3ec, 0xe0a18527be8e5ab6, + 0xf10a8199d6f8ff1a, 0x41d12fc74341f158, 0x0262ed3153f47144, 0x962eb7ecb83db07a, + 0x0c725c436d1e53e0, 0x86c4e6bd430d24ec, 0xc4bd7da5a7c1018d, 0xc014dcb56b8503ba, + 0x37181d6be5b32733, 0xa5ed25b2fcb0ce84, 0x4061bc18800ef1b9, 0xb87a58d1cca06867, + 0x5d3fc7848d5a1dca, 0x2f5f04f5d252d140, 0xad31417012bdb581, 0x62e6ef7d668c9986, + 0xc3f4f04e9903645a, 0x0ef7712e898b4497, 0x2249978f9b720dc4, 0x653e38463667a772, + 0x9d814ee832ca02b4, 0xe7ab7e3ae77e2790, 0x70e19f47e0742ba1, 0x7d9e48e011dc63eb, + 0xf20512d42949ad87, 0x8c528d18dde1b37b, 0xd028105e3365cd70, 0x6236dd69990f0d2d, + 0x5f5aecce0c5f86c7, 0x6325fefc48c07732, 0x636f53c055619a0b, 0x089598fe2f75c386, + 0xd5b948d2216f6ec6, 0xb3491c8da2b582fa, 0x32c03a00a29d2b50, 0xe11b5e12e0e48f5c, + 0x105ab17605f845d1, 0xd973949e20816450, 0x7600c92355891f7d, 0x1291d34b06af3081, + 0x5ceda2bad1428906, 0xf05c3bfc4586d2e2, 0xfbc9101200a59f9a, 0x03fafb9c803de789, + 0x315badf62532e34b, 0xa6eb81dc008c47ad, 0x471fab7e1135c1cf, 0x2f4ffa4fd9c8befb, + 0xf6cca2948bca8f87, 0x15362b0c9a434204, 0xd03d6e651246fd66, 0xafa4afc5137ab2dc, + 0x87f924c2fb6e89da, 0x6cdf25c197c99340, 0xa4c19ddc9b91cc52, 0x44a58fe87108b45c, + 0xd15187db2a76f4d8, 0x5d8ee8ef4a14db09, 0x553b5ee2a6a015c4, 0x1a7142bd3ab5b58a, + 0x121b1fee936eb7d0, 0x23cd938ce9dbae44, 0x0720d5e55e9b8ef1, 0x89b3846188c4cd7e, + 0x6e628bf557b837ca, 0x1e16deef024eb4c6, 0xca10bd44c248a316, 0x00b1f4d50753e6c3, + 0x0b2eb02441554571, 0x92149d9565729898, 0x14f7c7657d6b612d, 0x5190e77606e3de0a, + 0x197ca8228b4999f9, 0xb17dc804e60227dd, 0x9b7b8c9f60a64b36, 0x1cfb5c2c88bcc69d, + 0x8ea12eb23ac67f44, 0x08224df34542bd2b, 0x833cc9c84f1e9843, 0x3aad250d667b86b2, + 0xea5ff0333d4865fd, 0x6587f4859efa1f93, 0x19f17fbfb26eaef0, 0x4320ad958f1fabda, + 0x59fd62f570431db9, 0xde197ddc64817f9c, 0x468025723823b1ef, 0xcbdc892f1d0e9eb8, + 0x7eead70a4a27744a, 0xd73d379084d9fef9, 0x65b15882be4cc6d0, 0x16d13b0207aacc90, + 0x3dbfe14350a0231d, 0x5239beed4095a2e1, 0x049f0253c1bd79e3, 0x3a80bc3b75caa01a, + 0x178f3ff3a7dfca1c, 0xd3e3093f3bc654dd, 0x3100ad41ee6b0b0e, 0xce5d66a719fc3587, + 0x1efc393c5ae56b52, 0x67b1e82fa6b26ce2, 0xb1854b4bfe2d8324, 0xdd945864e23ddecb, + 0x68256a4c071eb8be, 0x617b29118cbe5b09, 0x8bb685a12bf7ef6c, 0x32760191db9560f5, + 0x42b8ee06813cc077, 0x1f75bf6a2a9c9ab9, 0xfb9d9261be593be7, 0x79e64fda6930c3c0, + 0x347cb08238ed6347, 0x2aa9e2d7875dbaff, 0x85a02a6558ae9157, 0x0d4536f0f1dbfb94, + 0x07d833605f1669fc, 0xba7af48877114366, 0xab8b9082959761e6, 0x062ede641a5d866a, + 0xe55d2f0f4948bb63, 0x0657ba4f2c0c0010, 0x316278da0f141211, 0x94cdd78c38250035, + 0xeb96eac52b51015b, 0xa22f073c91e0deb8, 0x36a6fb43726642de, 0x525f6de263c5c0c1, + 0xf49478dfb90dcf56, 0x0a77d38c69f40f1f, 0xe93c4bd558d5de0a, 0x383d99eab1ed4b0e, + 0xd3f9924fd86103b2, 0x7869482815b17630, 0xc6a42013a5cb1994, 0xb7c523ae630b6b65, + 0xe0fb8aac618d2945, 0x7fb162a97656262a, 0x8fa3e3f4c6c496a5, 0x22180d485b5888e0, + 0xbb22c7dc20126c19, 0xb4b73350b9b8e5cf, 0xd1c3d0961ac19619, 0x2bd353a2c361df04, + 0xc98d228c96567059, 0x9ac20ee6dd81d01d, 0x9966532dc141caf0, 0x82066f9f62a1d849, + 0xda7ed3a6b79b8f81, 0x6667e3ad7d1320dc, 0xbe19ecdac666ad42, 0x62ed84dc975e5c46, + 0x9be07a8ec67f4210, 0x3309312e68ff91c7, 0xa2ba8a5f6e2bbc12, 0xe0fc982e88137f1a, + 0x5fb4b7bc155c5c41, 0x7d6af5b796ac88e5, 0x0c679fa3ecd435f9, 0xc8e1b9619cafd98c, + 0x5837e249a3a24f1d, 0xd7175b90f68109d6, 0x509a9b2c3cade503, 0x4ee6df4820f7dcdb, + 0x2a08a22249048c76, 0x2e54bbfb2824768e, 0x3872cffea2650bdf, 0xe792a541005d3bd9, + 0x9a53f7cd921238f8, 0x7bcdf18c579755a5, 0x20fe89d41475e231, 0x9a191dd449da2d62, + 0xb1661f7def2cb41f, 0x8dbdfdfa7832c124, 0xc6405afe5c4dc377, 0x1e93fd0c7d481701, + 0xbc8cc115e184e621, 0x174e90e57c0a2e53, 0x9009752d3a9d04ed, 0x2d639f2023fb6042, + 0x139abf98f5b9e899, 0xe054eb324debbd84, 0x74c90f15215a9f01, 0x01f44504554fdf8c, + 0xaea5a3f1c40a6062, 0xc8083d34153976fa, 0xb8f0ccdf9608eb2f, 0x19962765714e7c87, + 0xa5ec37c77a6fead3, 0xbbee8540d09ff300, 0xe3847dfab632e5ae, 0x33d8e83cf33df74b, + 0x21ef53d49a273bf1, 0xb27ac146cfe0f0af, 0xf6a647fdac0c8241, 0xb9795729dea1b6b0, + 0xe23db47b329b6f77, 0xdda420793fe1217c, 0x17fc4f5e926b27c0, 0x749871a3b091d321, + 0x45fb11e75faf3924, 0x97e0962c459f0f7d, 0x1b9755d69aa4cb70, 0xff0f7b03d0508d70, + 0xe3e91dfe6fd7f5b2, 0x635fdf8342771c65, 0x89c9576ff3ceaac6, 0x6a51622275618a41, + 0x4b0cff084fa3175b, 0xe7d03518f230d90c, 0xbdb3cd15c14a5e8f, 0x67da9227ec25517a, + 0x838d4adbaf9f9c43, 0x610ccde46af86423, 0xadc6fd1176fbc113, 0xe6c918f668e88bd8, + 0x752765d5469c1186, 0x74bcd993c4eda4d0, 0x52701883c978a4e9, 0xde489d1e30e3147a, + 0x9a27eaed3b03bd88, 0x5f4613ebbe59b7ef, 0xafb7cfa82305e931, 0x9e540c9a5b93575f, + 0x298a5244af3df777, 0xc651d68ed8484302, 0xa9e04a6de113c901, 0x09b8cf9a5ebcbbf8, + 0x7b89a1fb0648569d, 0x53f34f416945651b, 0x49f1ffc8cf96ade5, 0xa13b5821b5f06601, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe18bd546b5824517, 0x673891d791caa486, 0xba220b99df9f9a14, 0x95afbd1155c1da54, + 0x8e4450eb334acdcb, 0xc3c7d1898a53f20d, 0x2eee750f4053017c, 0xe8a6d82c517388c2, + 0x152879e935811666, 0xaecd900d995f5ac8, 0x55534f24546a77e4, 0x867897622c279791, + 0xbd0e28c622e2d858, 0x1fe1c1cab00e501d, 0x5ebd909551cd9476, 0x2cd775ebbc39a143, + 0x1cae9a5c417c6efd, 0xfb0594f9f58532a0, 0x5d00b08114c05c30, 0x7343068b3fef5c84, + 0x8c814560bfb86c41, 0xdfa792b712d80bc4, 0x09f638d876ba89b5, 0xb53aece24720d42f, + 0x3caf2a97832d7c67, 0x23187c43d8012d58, 0x96306de157a7b651, 0x057df205404fe736, + 0x40b2c634710fe5f7, 0x30eef6c16d867d51, 0xcedb88fd15e05c87, 0x02170597f1895e0b, + 0x2f345b4530cd3708, 0x579d25a75ba7ad1b, 0x626204e0c0db527b, 0xd5522231d41a4776, + 0xf658d663179e4199, 0x4c45e428ad95e489, 0x8518878c419fa87b, 0x2c95824c089acafa, + 0x15254c0a6c186b71, 0x472d1f63eb8c3a03, 0x56e1743be626c3e7, 0x2f8bc30cf926a3e4, + 0x4a18365a3000dc38, 0x8bcdc5cef13fe024, 0x4051913badc2c2cb, 0xd4f54c934af1047f, + 0xb9a980e28b399623, 0x62c9f9a8be129663, 0x59b9749c4d0b7d38, 0xac4ff401e8727c05, + 0x5672a959c3c6031b, 0x73dc92cd775998b1, 0xceb0eea243f69df0, 0x86e3e5abce990f72, + 0x9651896dfc4d7f55, 0x55ad01318c5c2f52, 0x2bf783f58710f8e9, 0xc1fa2978d883e72b, + 0xd8de09f6d169ee57, 0x6991121f0e335caf, 0x439c72af74d8e3d8, 0xe58d08ee72011d4a, + 0x780a09347573843f, 0x041cf5b6f136675f, 0xe9fc3b8af8b89645, 0xed676a9643c03293, + 0x7272ab22be50f4cf, 0x2b821fb6268a0970, 0xdef49fe985160b9f, 0x13ba3cfdfdec3097, + 0x2f6524b7edb163d1, 0x6098f7058032adf5, 0x359f4d13d9d45a65, 0x23c7e15aadabf5d0, + 0x50af4a9b249b4b4b, 0x61040ac6c40117d8, 0xa89490c4ead00279, 0xb0e4fb0c77688906, + 0x15e7312427fb1326, 0x5566b0626f566469, 0x77028b52f3ad7ef1, 0x747e8d2d4bfc05b5, + 0x7b4654097f7f9a1b, 0x49e4df0c78201451, 0xaea37782a8271ef0, 0x8434941ae272b963, + 0xdbde2e5613783827, 0xcb7fe2bbf9d283c0, 0x46f862e0316512cc, 0x3f79a1c5d342b99d, + 0xb77d718434d42e4a, 0x44c7061af94cdc60, 0x039ece5b115053dd, 0xb34f073238b1f73a, + 0x82f60e8c9fc79727, 0x506db4c02864f2dd, 0x646f9b4123c2171c, 0x03b438befe3d8b73, + 0xfa8a9285175cddce, 0xa75d4a13bbc752cd, 0x556a2f039972d1f2, 0x5066c9914887ce82, + 0xa02443c6f48eb833, 0x6733c4bdd1805a32, 0x4637b560fda5a526, 0xff900f95171abdd9, + 0xe3109d1082d34cde, 0xfaa3c78aaeb009fd, 0x92a88e94f87edd67, 0x963cdeb022d3a10c, + 0x12ca8329d6f3dd82, 0x5573e20305879c23, 0x12da11bc02bb47cc, 0xcc3a812307bb06e1, + 0x64c4bfb42d65d975, 0x0cfd9a9c31167bf2, 0x23f6c5cb65f0e106, 0xc90d6a73299ad66a, + 0xf9207cf22553610b, 0xbd67226bf8c6d865, 0x0780901fb50e9caf, 0xb9c274f85e0ee46a, + 0x3900f865cf894428, 0x088cf6170c0e2541, 0xcd7c2ecabd675de5, 0xd25de699c387e64d, + 0xe42f2edfa1976946, 0x86231740f6922a38, 0x3879338a2dfe6ee9, 0x693b8e9f726fbf54, + 0xc0652f06ab132eb9, 0x1f04836877608ae0, 0x79ef07e45327e776, 0x662856891a9c02b6, + 0xafe7f1917a2b349d, 0x3b47767a3a59cd0d, 0xce1c84d0d1dff396, 0x0b947fde7bbcf13b, + 0x6c9910e54d82bc4d, 0x6b03ceb94b14b6d9, 0x8b8057e881a0b050, 0x4c70742606a8b4bc, + 0xf753a4676eed5bba, 0xbbb21622ce427c01, 0x89bc173cf51175b0, 0xcfb0b8f75d6e9038, + 0x0ed88ac4e793eb6a, 0xf8e6f1d305a59386, 0x265ef750572c0eda, 0xb400c4fd06981276, + 0xd04c2825c6ebca00, 0x5a4e8bf8e4932beb, 0x37289429c7aa1c3e, 0x817f59c7a01c7d2f, + 0xb8224f4653894128, 0xabc0c98c158cc5d5, 0x745a4d62df5ec60e, 0x3ec6cae0ee515eca, + 0x2b07afe1caeaa92f, 0xc356f794cde9a011, 0x2980bb7b494d2227, 0x7932073f512cca32, + 0x2fb594e0425ab0e5, 0x6cc7510ae3fd0bbd, 0xbf3dc80c48c189fb, 0xeea71f5a33d0cfd7, + 0xa87e46e6b00a6163, 0x1155b263b6615e5b, 0xbd01811d777cb68c, 0x664521c46d491d6b, + 0x4cd3dd031a927cad, 0xc0d4b0c30b476fce, 0x4444153632d893e6, 0xa9e72bf573afe5a3, + 0xaf55c371112ecbae, 0xb7256d2863729d55, 0x99934eea7c7aba6a, 0x3949053f99ff16e4, + 0x6cbad34f27bb0c25, 0xc896a8efd813e51f, 0x91b0a2a5ed9d7bbf, 0x92817b604faf5594, + 0x6a87de3f9172672d, 0xf8bc1d2b2e3ec83b, 0x7dc74321261e4794, 0xa434fa8a7d31d0bb, + 0x69400ed4c12908cd, 0xfef3b8a2f38145f2, 0x82f74053941ceb7d, 0xbb5d052b0a7d5c9a, + 0x15d290651e3a746e, 0x001bcbbca6acb6c0, 0x83f1637fbcd0e664, 0x8b1ea6e53fab0653, + 0xb72f92382028b839, 0xfcc53918788388bb, 0x635e04bcc0aaa3ec, 0x1cf4fd75c4b6d2a6, + 0x88260134d443ede4, 0x26ef5d26818a60da, 0x7740340f76528012, 0x1594a4cec116fbc7, + 0x49461554665be9a1, 0x82e9e49750569696, 0x92583728a3f943b6, 0xfd4e3526b222a136, + 0x9fd1545f7f24a025, 0xed5a38641f96925d, 0x995b089a731cbf4c, 0x5435169636b30daf, + 0xf57f17ade62875e2, 0x57e7ac71628c133f, 0x6029b713c752f48d, 0xd50724f25a013f6d, + 0x1929f89308635742, 0xb1252aaebabce0c6, 0xa18fcac2824a7ce8, 0xe1a76f96d7f36558, + 0xd9b90d707d7a694a, 0x251c8e4a9b0cae32, 0x1f95e6096e7eac95, 0xda4693531b91d6ad, + 0x61701f9e51b4b34e, 0x32e1f656ac3ef7f6, 0xf6216f20382a35a0, 0x6a46692948a1c263, + 0x915edcec16a079d2, 0xe46ed15af6128d0c, 0x493e7137e8db44f4, 0x32cbbb71028811c2, + 0xeaf1373b4526f49d, 0x3d87e8c73108ca61, 0xd585e1960e074797, 0x3e94551d7fa5da45, + 0x69d95896130464f8, 0xd331598da49d4785, 0x05d88753abee76b0, 0xf2f3e8cf85a165ca, + 0xb3562cbbfffeaa7e, 0x13682c7215a84b17, 0xc9ee56ef2662e4d0, 0x636f129ad53e4478, + 0x9a49b95f948693ec, 0x53a56df039d29768, 0x276c078b4ba47b0a, 0xf53f09881fbf97ee, + 0x1c28b986b3f903d9, 0xdc014aafa8e4cd80, 0xb8517ff49f2dee13, 0xc9e135ad4429d32c, + 0x60e643a7330d0875, 0xb10b6fe468c29898, 0xd5c79b7bf3073dfe, 0xa2a22806719b0e1f, + 0xb99393500ce302ff, 0xbb237d49a5deeb59, 0x06c1dc92250e99d9, 0x80787053329b43f3, + 0x4b3ebe2b5f1f0061, 0x6f23571e051efc9d, 0x96afdeba57cbb6c2, 0x77b380d5e2101881, + 0x953b255b576c3ac4, 0x5389f935280f8070, 0xc09b873c7c3d36b9, 0x3d8a8f633ff746a5, + 0x03ceed72145fc246, 0x86394b6581fa0c21, 0xccb1a1bedabec619, 0xf04a08e84b8d2993, + 0x1b13b27b557461ab, 0x6e645a1589bb810a, 0x1c2ed089b583881a, 0x26e45622c88c1e0f, + 0xb3daf09f222c1c83, 0xdbd238c6b2574939, 0x2c07cc6c31c77c3e, 0xfbdb95546b98af58, + 0x400fb496fbbbe90b, 0xacf4f5394ae9ad90, 0xb9ce6ed4d338450b, 0x341ee8e9239e15c0, + 0x9c8be6b09c31510c, 0x974d589e2a643e44, 0xa4b951a1df326336, 0xb38706ad8bb69f1a, + 0x333ee89499fb3edb, 0x54977416cd9b9f02, 0xda0a3331423c0797, 0x612e1cec46175cb4, + 0xf07d665723f926f2, 0x067574f584c7498f, 0xf4f80e599194d26f, 0xc8803b771f0b96c8, + 0x0ba754ac1fe3cf8a, 0xb4fc7ac7f2dab617, 0x38f86fcedee681df, 0xaefef1e8f04152d6, + 0x251db0d004e0e2d1, 0xc19f5f9e1cddfe4a, 0xa204c7ee1db9a0e7, 0xb093b6b4ee18f7fb, + 0x3ff1dbc877dd8b82, 0x739b54a86bead240, 0x1c16a9561318942a, 0x99f914cf9865774b, + 0x623a9bd510069be8, 0xd37c3272da1cfa25, 0x22fd93d02b541f5a, 0x27f7c60a36166272, + 0xeaa856e77183e0a6, 0xfc40e1094a67ec4b, 0xcd393283035e44b6, 0x484cb965a67f7bb8, + 0x1bc3e7c2042ec3c9, 0x3fbd32549515a339, 0xd8a3872b686f13c0, 0x960007f3b5ff4467, + 0x40d2743c4f6c9140, 0x3d9132aa1b3e24fd, 0xa8abf7700ad7b23b, 0x569be56992ee0d31, + 0x98667697ab8a3b62, 0xbc0fe604366f63bc, 0x4a198d629d973a8a, 0xf1a92b28f72d2958, + 0x2fffcd6a1ad67448, 0x1218407966041197, 0x89d7d5af7ed22b8b, 0x7e706b3ef8508cd8, + 0x055896d0f0deff9e, 0x3126cdb92918c859, 0x1e38fcb1476a5d9c, 0xd1e3a0c92d4a6861, + 0xc816e68d558e87c2, 0x5e0ff7bdc264a1e6, 0x27d4c47f41a287e4, 0xf8851b68a93af89e, + 0xe28aa64a80995088, 0x01c4689ace7bf460, 0xc6376057e894d337, 0x44a6b1ef48e4866f, + 0xab4a0ab3e8457138, 0x5378e9c758e17968, 0x0da8b846ad8aec47, 0x70c394ced5b48b9d, + 0xf008d7aec8ee2621, 0x7caa8472b19fc8c4, 0x5a374a8881cf3f10, 0x59cf7fe66077854a, + 0x3cc5d1fbd14e6186, 0xf9cbf1ae84470aae, 0xdc36654dbbf843c1, 0xb636e59cbb1caf9a, + 0x2e8f0e8f57134f78, 0xeebb48bb07d8aaf7, 0xd02c82d35fcd8bce, 0xf7209fc26f272249, + 0x9ef2961799f45193, 0x0cac99673d019541, 0x66ec5b58d4d13dd4, 0xdc4d253bc0c86357, + 0x902aa34bf03da786, 0x8d4a5bdb79e91154, 0x22289fcd13fb4ed4, 0xb54b84be62e31ed6, + 0x623cf3764be7e051, 0x2ddfc8887f1c2fe3, 0xcad35095c778dc23, 0x1ef5a2aec3ebf81a, + 0x57c8d17e8088ad63, 0x9ce3f3e19d0c65f6, 0x9eb87f4005374afb, 0x62aee4900ae7d053, + 0x9fdd2ec141e9ed99, 0xd78d632908935cb5, 0xf263af92936ec69e, 0xfa9c4fe8e1af11d7, + 0xb65b8bc66351e430, 0x119462cd62df12dd, 0x4d7a800167f9afbc, 0xad7067efac892403, + 0x0dffc39a2a2090c3, 0x37ecc2813254c280, 0x1f131cde3a6859e1, 0xb743bb732be8e124, + 0x26a86fa4ff72cf20, 0x41b584bfb9c2b7e4, 0xc7cde8d15e69b89b, 0xd5085ed6e44f6326, + 0x5e287fe09bed2b2a, 0x420a2a8eda43c034, 0xc960d172f92b0682, 0xc544bd340165599b, + 0x436b6e509e76a3c7, 0xc0b34f2a44427e26, 0x9a6b7018de666968, 0x97a3c534cccc75f9, + 0xd0d79a847d7fa21a, 0x14288bc14906c587, 0xa7b92684133f244d, 0xbdb69a2750b742dd, + 0x99dde9344a107112, 0xb99f071cf3a17929, 0x20c85b899b4bd960, 0x2edd00ee6dd84b8c, + 0xcb86453b16054562, 0x6f7ee5c79ea6a845, 0x747fa298cad38981, 0x11cca68b0133a5fb, + 0xe4d8a00db3333c05, 0xab431c6116f8dca8, 0xed1505ea4073dcef, 0x335409f0a2277dae, + 0x8e5e47b9d4bda264, 0x9b9097ca230dafec, 0x72575d8fa4af2cff, 0x4622878980eb678c, + 0xa2942327e23b716b, 0x5bf2a1c9b4ff0e2b, 0x904923e99736fcf3, 0xeafe6d8ae6e88e06, + 0xed248c09fc41dd3d, 0x6590a57965c4d144, 0x8bc04b979c4bee3e, 0xf59e2e4dee7ac97b, + 0xe6779aa7c9bbd853, 0xf933266ebbaca6b9, 0x66f41467bcb9ebaa, 0xe3272f54be5de02b, + 0xdcc55dab960b5a64, 0x2e3cf65b0eb17eaf, 0xbfa27c2117ff904c, 0xa36270a7545f0d94, + 0x4cadf2ec850543e1, 0x455ebc849ae79ed4, 0x0da4f967d302677f, 0x96a99b3ec9171212, + 0x74327b504eb18437, 0xe750a910f35d149f, 0x9d3f22c390484945, 0xe3c8fb6e36b5431b, + 0x6eb1f8215f871f3a, 0xcbc7938922f03c2e, 0x6fa5d58905272470, 0xe566cde893782621, + 0x295a17cea223da44, 0x2c8a9f00fb2dfd3e, 0x61e490bd4a311a60, 0x8a9428ed33ea0882, + 0xfef8227ae51d184c, 0xb2ced339d60c5450, 0x9d23ec6a32f6d902, 0x13e82060fe0b6652, + 0x455d6df5fa78ef6c, 0xe7cb917a55dbdf45, 0x6507ef8fdf02fe7b, 0x6e2a02adf8c946e9, + 0x805f31a19e4dc49b, 0x04b6b85ea8c558c5, 0xe31e6b1a9421d638, 0xb1f965f23a5f7d0b, + 0xbe7546cb917661c7, 0x5c66b5af967619b5, 0x0fca6dad373e003d, 0x59f93a519831a61d, + 0x2484d8891b5c707c, 0x6665cc0ebf3da632, 0x3510c9b898f470fb, 0x23b1c8225f2d6094, + 0x1923f05f8ecd0d1b, 0xe81908f48bb274d1, 0x894166690868c8e1, 0x3fa4c72768d63279, + 0xdd8fd5067e000772, 0x1586cd7d09f06edf, 0xe36c52b22e89d16c, 0x7199a2bb8a9f6705, + 0xdfe0c6879c9f2ba1, 0x998bc8cab9ca49e7, 0x694ddb746ef23aba, 0x18382b9d14579d6d, + 0xd80cc85665ae048f, 0xa1fdfbfa8f9f255f, 0x07cb129213f2b614, 0xbc554a6a7c439cd8, + 0x07a8e959f20461fa, 0x945565aa30b11d13, 0x46b0c3ca62d7ff7b, 0x291243400630f896, + 0xcf83cbc56bf0b214, 0x3a760aad877b9b06, 0xdb27be97a848b363, 0x9585fe12c144a86e, + 0x770057e646101d2b, 0xe9a73afcb98545c7, 0xa6017bc9b2273f5f, 0xaa1a5eb8fc80fe9d, + 0xe93a7e929bf6f40e, 0x1642317027d69a82, 0xebd8dee408fc28fc, 0x01b0e3a921261898, + 0x12e08a5d06918211, 0xa02d6febd9f2cf00, 0x3f27b7156337c216, 0x29367efc31ac0de1, + 0x52fef397ac540eef, 0x008dd5184b8a16ce, 0x705d57fa7a7faff2, 0xe0848700bdba073b, + 0x8440e45537f27536, 0x1dcf9924d2a26e94, 0x5e173bb7dfbd9c12, 0xeb2b645d24b3809a, + 0x0e806cb5a1296865, 0x5a8c4085fc136102, 0xa20e28e2fa3354cb, 0xe111d064f962993e, + 0x0ff6afda7f70fcef, 0x2b4bff9cd2c74aa4, 0x2c005309f8654e95, 0xaddc7e914ccf1ae8, + 0x36d61d9964e28344, 0xbd168ec382ef0333, 0xbbe75323161928e2, 0xc17b274b41047d43, + 0x74d1629263047cda, 0x1bf53e662303b27a, 0xe2dbbce865c999f1, 0x6f3451f33815bcf5, + 0xd09babe6e5a1fdd0, 0xe0cbc2b7fa93933e, 0x98bd49718c8a470c, 0xb4516ae0675752de, + 0x491bf517c04dde9e, 0x2c8860a8d0eab6d9, 0x1a1a54b033bbda67, 0x559d850100066bdd, + 0xad3a5f817321142c, 0xd257342c29489c8d, 0x27fde435f7dd094b, 0xe16aa4f9dcecb90b, + 0xb64990b25214136d, 0xb7cfe317c913781a, 0xa71720389e8ec993, 0xe37232ad1fa3d9f1, + 0x9515c778ec4e38d7, 0x3ae6d32891b2d1bc, 0xaefffe61927773d2, 0xf3f00c8a5f3bc213, + 0x4d12e04f6cb148f8, 0x60f267ed8015194b, 0x6cb763015af477d8, 0xa503949c1e0aaa00, + 0x489f491716d0d1c5, 0x7a014a7f95969b07, 0x712d9e3da6974e49, 0x3d83f50a787b0c26, + 0x9c51fe2431804738, 0x095a35c59b965f42, 0x34186c65970c459a, 0x7b3c99092d4f65d9, + 0xd804bf942a3498ef, 0x411cdfddf367f2ab, 0x29e234b76f98924c, 0x9dda740b8d91965a, + 0x7f245bc00cd6c527, 0x5cc1cd33087e714b, 0x1e3f7ca0287674f1, 0x1c567ae30b751b44, + 0x74a28c468eee7344, 0x4a8ae0a87aaa9a4c, 0x4c477d6fbf696803, 0x7a0d08c402ebad58, + 0xa8d71d8dad8f01b5, 0x03e960ce6bbe3f9c, 0xcc15bfb2a9772b12, 0x23c7c4c6bd1f788b, + 0x94473747d9b7d678, 0x1afbdc98fcb131f8, 0xf10014eed69a23bc, 0xeb6072976fa20b19, + 0x21fe4a38d8184865, 0x0161cd1a12e703f2, 0xdfb93652f9798a55, 0x7cd03edaa5ae311d, + 0x7a9a56cff176ea47, 0x0afce8838f171538, 0xf223ee6b05f510ff, 0x46315f54e128a927, + 0x0051b92fe82c365b, 0x2cb3b32ff4b3f07e, 0xc763672637c94ba8, 0x3355a30193fd1509, + 0xcc21a7e88f153cec, 0xdfc5541bd6863410, 0x38095657116bf742, 0x1cabfe5a923387f5, + 0x384280ac9824aca4, 0xe43c92eb8c11ac95, 0x0dac6b3d49476b36, 0x6890eb17aab8f8eb, + 0x22a23eccceab5956, 0x5490902d56763336, 0xf32198fd1e30be76, 0x1f38713b67d35c93, + 0xd70e8457b68f60ed, 0x91679e7a021f0bff, 0x556790f0d3ffd96f, 0x10e638c14f1d169f, + 0xededaee8670cb507, 0x57ecbddeceda2185, 0x85623e5ff08e4184, 0x25a908088ef77237, + 0x42ab939cc2f002e0, 0xc40e512f2ef69d36, 0xbcfdd37a106b953b, 0xb85a4d1a712b4ac3, + 0x41cd568e908b779f, 0x2f341eed1dc39aef, 0xadbb972925fa61de, 0xa5fae87c93290bd7, + 0x38813dad5dfd4df3, 0x75e913d56de5798c, 0x97ac58ed9ba51df8, 0x889f0b469678168d, + 0x1bdc52b60f55b897, 0x0e2fa3fb7fa34143, 0xb6af6ee58471e75c, 0x824932b44482907a, + 0x9c23b1810e2d4748, 0xa2ef8f9b52e2a08e, 0x45bbb5a1c9d72acd, 0xd83a1a96afbde5e7, + 0xbef667cc45ecdf2f, 0xe6458713f0a6a90d, 0x087160acab53bb75, 0xa6e1eb1768d9e9ce, + 0x571ed6e38ac7e3cf, 0xb84c3947f102b45b, 0xbeb00fea95c61d7f, 0x5bc5608cc751fa50, + 0x4329ed6453aa9f5b, 0x5ff5d5f05fc5f1e9, 0xabb817f7b532687d, 0x638507ca97ca8c5e, + 0xc33059193b486299, 0xa89a09152ccac8ac, 0x6915745fce4252bf, 0x22b291dca76ca9d3, + 0xf60a2d08b4410f39, 0x213a2f569c2de403, 0x299b6f6d394813c6, 0x545e9f0818790a6c, + 0x25301e7e3f6bfe9b, 0x740cc41235219c3d, 0xaf1c7c372530f074, 0xbbb6bf6c81316e62, + 0xa3880fa9580915c8, 0xa8e4482a33204d79, 0x0b75f81f149267b0, 0xad1b911dd1d43be8, + 0x2081d5f7f1a66091, 0x118be91329ac7633, 0xd65a4f9959367613, 0xac6c934d9d0debab, + 0xd693bf47c693e5d6, 0x2d83768b82c20e58, 0x316ae1060e702938, 0xe020866bcf5b5dda, + 0xc68ccdf29d438cc6, 0xc2b863339618065e, 0x04af45fe7cfffa9c, 0x15390cb5cae665d9, + 0x9f57c2b120362e1a, 0x8eb9cd2f20c5ac19, 0xc995c3a94d3c3038, 0x6afbb0603ca99800, + 0x1c9a7883e402bf21, 0x7e0be01a537bd296, 0x33fce9189c973d9c, 0x5ead0cf07d88dcad, + 0x87a8e4d37d2ba1c2, 0xdb90c75f183520ea, 0x1a684a8973e11b97, 0xd92db7fc4c92d5f8, + 0xe7900620ba280f13, 0x7652b80a1b21e2be, 0x87f6df43491cd49e, 0xd78da3354387b60c, + 0x05f3ea9003f4b985, 0x5c493c023ff25483, 0x48bfc5e4266eec81, 0x1fdf442a23a785dd, + 0xe44fd5bba3c59c0f, 0xb6e60900083a314d, 0x3441ece04b932eb4, 0x6837d3ba86ba3777, + 0x80f0bb5f2b458247, 0x72d36fce0c1f6739, 0x17c64deb89908b3e, 0xa28cc3f228c913a8, + 0xc71fae72ec3d6c91, 0xf97126dbe5a6bd96, 0xfd48aebfe8010118, 0x3a094ee78c6cc819, + 0x1af5a9edd489a177, 0x56a1777a58911009, 0xb7f9403cb9b14866, 0x8c1d82fbe696de4d, + 0x352848c9bb6154da, 0xab9c227a680fcd9e, 0x8686ad05b6745b9e, 0x93a23421cac06964, + 0x62f3ecbc2c381c88, 0x42ed37fa24b620ca, 0x550008f1c292b43c, 0xbb8e71996c144d40, + 0x0b6f380ddab18992, 0x8ef856b32ad94401, 0x0cd6894577b2899d, 0x9204292a0fb039c0, + 0x88a2386ede01e3b9, 0x83132b498f32a515, 0xb91a4a795a23e1f6, 0x3a22f312c945be7c, + 0x3cdfbfbbf4beba53, 0xd2984702c3fda4a1, 0x7c140ae728d9ebf2, 0x56bf8304ac7d5ed6, + 0x407fcff404cfebb2, 0x7e2af89e1bbcb43c, 0x21a777faa2718aa1, 0x4526017bc9ffffec, + 0xcfd65da89d237ba2, 0x527af1b4af567dce, 0xcc9dc24ae0cdbb07, 0xcea8983ce69e8e0a, + 0x3a211929b4a8acc7, 0xd2bffb9423d7304d, 0x632679e00b749acb, 0x5f6cedfd6e53ec92, + 0x22757f202fa88dac, 0xe555dec632efee53, 0x870b6de91bc79998, 0xe63cebb321de3909, + 0xff61093a070097e8, 0x4010c660ca3e62d1, 0xc315ee19bfb557b7, 0xd9f2725efc6b7ce9, + 0xd964bb99679b3b7b, 0x83fed68c2f4117ae, 0x6875f474437fbea4, 0x295d5e0c22e6f040, + 0xa01a24baba478acb, 0x68bc7bf99a58f889, 0x648f83a84777dc5b, 0x4d55f9ddd4b69d0e, + 0xf9f9e9fe20c4c7c6, 0xd045b7395c45ff21, 0x02c4f4dfcecd74d8, 0x840cdae79a34a601, + 0xdf53cc97520b07e6, 0x3b7655117b62bd6f, 0x5907bb57f1623e9f, 0x948d2cbfe625d752, + 0x48c85e353071320d, 0xfcf3b5cff12839e5, 0x9e0179af837dced6, 0x524f8d75fa202978, + 0x61573d42f3393ced, 0xf0d8dff1d35bb0a4, 0xa121a2be71362cb0, 0x214f813dde7b46fc, + 0x8007b3bceed2cd83, 0x667b707656dbcc04, 0x25f03a56ca0e1b5f, 0x29be5ce7ecc72501, + 0x76fb3cf7867e6329, 0x3aa0ec5df00012bd, 0x4078e11617ec88ae, 0x32ab0aa0a19047d1, + 0x091639e2a3b47847, 0xd6ad7a6e4d066f4e, 0x6af83e46c9a1c27f, 0x987600dfc450923c, + 0xadbd5bb11e8b0e08, 0x56c2e0984311ca95, 0x06c7ba302f16a29b, 0xcb02674e2ecbfe02, + 0x95f070dbe78540d4, 0x81e8b77c786b00aa, 0x893fc5e0e4301407, 0xb9b2fd69f7d01e18, + 0xf7d6b9909d9535be, 0x5bbf759c3064ab00, 0xa7acc9ebf69b8e9b, 0xd91e3e93d8eb856d, + 0x3aa7aa06ce151cf0, 0x3518b46d24b0ccf2, 0xad5c39799b72e52f, 0x1ffcae13653ea7d3, + 0x0b5e797f12be6610, 0x49511362e672baf3, 0x84b097e71ba1f9d0, 0x774c7f38887ad2d3, + 0xebf83855a3688edc, 0x8d4796169bf9047b, 0xc68f0de7d9fad18b, 0x4cd24186e86f46b6, + 0x085f8ab97b5a4851, 0xc69006562cdec21f, 0x8c6b7e791cf6a1fe, 0xa39cfd6078564780, + 0xcfd4a44824deb7a7, 0xfe752f70933d6b2c, 0x7b79a72b5471cb3c, 0x7287c8951cb8bef8, + 0x72646244c30041ec, 0x717a2744188b495c, 0xe7aac4606b5ab9b6, 0x2f554e07de97f229, + 0x1fb4ab13a7ea6134, 0xf57e69197f83b982, 0x6451f0db1328c679, 0xd6e3a770126f8d71, + 0x021bc61de1d1b0ff, 0x30d9847e5ff647db, 0xba94982a71364306, 0x2f996c1d9cf4be43, + 0xd648d542f82c6f47, 0xe669d2973695fa9e, 0x0ec438e67f26acbf, 0x1f611823201e1e29, + 0xac49069f53a3deee, 0x9f9a5ed174e3f382, 0x73dabec68efd651c, 0x148f6924b5647cdb, + 0x94fee701d3aa9227, 0x9bfc0a6f8d893a8d, 0xa6ed74a096c4021f, 0x1d262691c1b78989, + 0xbea9e44bc57b78c6, 0x018c087da9252adf, 0x951a07e693621520, 0x200b6aff42b49da6, + 0x38a4acf6c2f54309, 0x291f264a833b5a5a, 0x28e0b13f8b03f290, 0x51c179f66ef9a918, + 0x4d524503be4c7559, 0xaec857b8eb53b4fe, 0x620a9f76a0c78fdc, 0xf477f80165acc127, + 0xbbca30312d221669, 0xca46490d25a284c9, 0xa9665971300b2bb2, 0x9b7d9ae72b040752, + 0x1ead30430518597e, 0xeb9367e65fc69fc8, 0x32a6df400bfad080, 0xe2a8541d1db445c2, + 0xf6d4783950910d8c, 0x7ae5b848d97a9d3f, 0x41a15f8dd1d1206b, 0xe973b7c141fe98e8, + 0xfb115b9ec872a12a, 0xe7601bc09684ef1b, 0x24435ef8df74d661, 0xe99441197722d6ff, + 0xb4338c5734a2fff2, 0xe2f898a5b58fb483, 0x62198f5031b08137, 0xcb2169c29461edeb, + 0x3dcab0d2dfcb5ac5, 0xded9cba5ff085f28, 0x0aba1da5b01750b9, 0x9fc8c17ea304415f, + 0xa89c37ea335cf789, 0xf6491bc32753eeb6, 0x7b933d8d40a745a8, 0x3d174e4196057c0b, + 0xff24b8c09e1297dd, 0x6928f8b07aa2502d, 0x8ac43a4483311e96, 0xb8b5652d6c412630, + 0xed5c6a3180f32cc8, 0xa146e484e53cc8c0, 0x9a7ee9760fedd270, 0x20d4f06c413a6ba3, + 0x28910a836f46fb81, 0xca35e6b848bd0730, 0xdf547045bc65b05a, 0x1ed7f7a04ca4d6a9, + 0x898d2574b369fe54, 0x12afa3eeca130c38, 0xda985b29e3397857, 0x11bf9040eada0fbd, + 0xa19527e47737e89c, 0x71eaf3ccc2cfc809, 0x50a920d8bc83a60a, 0xebceee8275494bd4, + 0x293e3c48b5f49ae5, 0x698a7705f40348aa, 0xc72cccb043c181d1, 0xb490a5eb0b921b2e, + 0xd767eda079a1700a, 0xd6bf09abaee22197, 0x83e8130da46fcc2b, 0x090d44dd6b923f70, + 0x5394d6c1aa81bf65, 0xdb00797b2f86986f, 0x31ee4452a73b8bdf, 0x580c0f17cb00e446, + 0x74a4883bf6846008, 0xf8c4bd341356376f, 0x49d7978372a3b23f, 0x72f8ed728e85b27b, + 0xdf2c6d077ab1aa7f, 0x69af0581d8cdcb9f, 0x713565f5f5394f51, 0x8b4b3e06520b91fb, + 0x05dae26ed41e675a, 0xf2e754964495de49, 0xfd906a7971c00ade, 0xb7c364511ce398d3, + 0xfd701ecf7e811b45, 0xbbf328ed6f12f8b3, 0x49a09c7d47ead9e4, 0x7e6c7aeac51ad46e, + 0x380ed291e099d818, 0x21d757c28a7afb50, 0xb92a67872779bbf2, 0x22910c5d05323451, + 0x3ae9c6adef04813d, 0x2f3c74a512583030, 0x0dd086c10c4513ed, 0x9da9b5b252e60916, + 0xf5a7673faabf217a, 0xa4d6ba743e0e8261, 0x7a5dca6ff3ae718b, 0xb48d02aa60e9f0d1, + 0xa6dd41c9d1cddef6, 0xbcda594db2e6a62e, 0x0956c95e1e0e91d0, 0x21841a8e6edfb9c2, + 0x0cb241b90d042309, 0x28b1b1f9af25a92c, 0x89c180ac50076ad3, 0x5e33dabd392a9697, + 0x0efdbcb4ed592bf1, 0xde15cb0fea225f4b, 0xf223709b20ebc363, 0x79e1c79f4bf1b37c, + 0x26a157583236dfd9, 0x79960a7ad90bfc31, 0x1d2175c347b55bf4, 0x78b92d8c808ca11c, + 0x3337192a6ae5ac43, 0x23b74f86894916c4, 0x164a4d82a76fd184, 0x45eab54b9bfa7d8c, + 0x864950e763559c9e, 0xd9ff52717eec5891, 0xa0933317fc8c4cae, 0x1495620b622c52da, + 0xae34207a978f85c5, 0xd0178970a2b7488e, 0x08d413df3f936223, 0x21e5422e4e099217, + 0x1ce6c0b37b7cd9fd, 0xbf8b8839736155e0, 0x28ff971ca2c5a063, 0xf50875bd4ac3ca99, + 0x8ef854d982edcb16, 0x1e9bda02e2d85d96, 0xeca1d8cb73d60af0, 0x25c1c5c4ea83fbc7, + 0x0190d4b3d57ff092, 0xe554d97151e2fa52, 0x70b9b73537e1855d, 0xb1f7bccaf3506abe, + 0x01163113d10152de, 0x5f6b0f96721e2854, 0xccb5ead1b489925c, 0x9133eb3624a47cf0, + 0x9a6c7eba68df1594, 0x9eec41ea23fa0b5c, 0x3cdbbdf5b98d8b4c, 0xb985dc8f8e9e0fc7, + 0x8facae28ef0ab490, 0xd0bb5b5cb7a25544, 0x774e2fdd5e2995d6, 0xcbbe218c427ed27e, + 0x4f2d7daa2391e3d6, 0x3d788e433af4a921, 0xb828102fa2eebd1a, 0x69de4e9dc394a368, + 0xdc65089391378696, 0x44e4aad6a81e98cc, 0x2d2148e67ae55af3, 0x8f8b5a64113509c7, + 0x33e4cd7c19e9a8b2, 0x0041c875b8faabc6, 0x09abc607fc52d704, 0xdd1688995509d186, + 0x022c31273c90dfce, 0x7714474a31241496, 0x4c63d3aa19d79170, 0xce5622277d47937c, + 0x5781090df672a571, 0x8640ceeb8cdc5a28, 0xffedddbd765d1100, 0xf6b5a990254a354e, + 0xdba0eb4a6c9f823d, 0xc952b52450f289fd, 0x7029e6e0cb17f410, 0x28c3a52b778d1314, + 0xda2ba226420f463a, 0x1a04b80b08dffb9e, 0x95f2ebe7a0ae3e39, 0x0163895911108709, + 0xe089e1cdc0fceb1b, 0xdd7d58b111125530, 0x308d69c2cfe54ba6, 0xaef42d1c276e31df, + 0x27ea92efa48995f3, 0x1cad0906aa24dfbd, 0xd852a9989db95224, 0x500e04c2890e8bf4, + 0x211015d5dcfeb006, 0x8ad4e805b53e46c7, 0xd29bf99b9471be8e, 0xe3b7a5f5dbc2ddbc, + 0x67441f29b5c26937, 0xbfe1c12d30ead35d, 0x7ae1d51d06a171e1, 0xe70e69cf404c38ff, + 0x341441136f277771, 0x32ba8bc656aff63d, 0x3c9de8b0c111ca0f, 0xd9b2001258ba8fa0, + 0x3eb4a3bd1ac64896, 0x2048ec9cb2765cfd, 0xb51b6d8c486427c0, 0x5685d4b4d1a92825, + 0x9a53ce2d78ab2112, 0x81cc626e75e674dd, 0x213f36e563be6bbd, 0x91cd5cd654a4d04d, + 0xa165c8cd02922d2a, 0x9926685a10d67f53, 0x4ec68ebb001d9396, 0xfcaf0eaa0327828c, + 0x01584791b6e5766d, 0x49d2a1f50f0051e8, 0x89d72e85c8ca7873, 0x3e76491ceec661a0, + 0xf998f8eb67d43c41, 0x193e5ad2adbda372, 0xd81bdb5591a38247, 0xdd636bf82f7474e9, + 0xc9b0a0b8950852d2, 0xad059b527bfbc39c, 0x28afbfd73b562aee, 0x34c6e8c8119e97c6, + 0x46f405766e4ce273, 0x1a323bbe5d794524, 0xed5675d9c7710da3, 0xfabfd4f161960c7e, + 0xb52a3e921929a52d, 0x9e7b55dc5b17861b, 0x8b3f7ec97b34b77f, 0xfa63be6376f6ae1b, + 0xe7a04d4bd8ab7fd6, 0xea4b187503d6e89b, 0x7999b2516bfd00e9, 0xf24d7bd65df15db9, + 0xa2da72be4d541871, 0x4cc78155a3dce4d3, 0x75e337c7ea9447c4, 0x94b95c55b9066eb7, + 0x9931014a671fae5f, 0xc81167293332e36e, 0xf6cf02e94d6352ad, 0x3466e040a2e763f1, + 0xde107bcd0bf2d30c, 0x7bb2a4af8928d195, 0x9fc9909aba44bdc1, 0xb69f09a4836efe5a, + 0xb53a3d487a1de808, 0x5558873b25b08b72, 0x2057632b7f963b6b, 0xc57da58dcc6ae516, + 0x29bf44619269e1c2, 0xd43662524a908590, 0x23981aa0f9d50c68, 0x65712ed531b9fb3c, + 0xa0ca71f9afad9454, 0x73266f87baec3819, 0x8322f0acdd77584f, 0x57190270e5ea1cfa, + 0x59e47eadcf2e94bf, 0x284bf97a77501a3c, 0x1cd585e03585934d, 0xc9eeb40d134a6aee, + 0xbcbfd09b1e3d3f8b, 0xa753d649e6b389bc, 0xb97cbe57c44c8d57, 0xebd8ceb4978b6630, + 0x3eb8f6dcf3137377, 0x15db7bad6001419d, 0x8eca34a517f883e8, 0xa80c5e00d1ceecbe, + 0x60d32b2088b97522, 0xd445c93e31e05e59, 0x23cf0ec5100ccdb8, 0xf950efe33a61ec9e, + 0x8749ba66ed240cb7, 0xdc6ce043323c8678, 0x449e0187155ac2c9, 0xd6647132dcef4d0d, + 0x58f1a152b44a9d7b, 0xf5c3481bb733c774, 0xc02673b31d92101f, 0x6e03cf73738d3803, + 0xb5ed094017928493, 0x4591a1b5d038b220, 0x823f20167f714031, 0x44f289c7cc739233, + 0xc3517c06cc4a1dd5, 0x618dc92f70f899cb, 0x8d404bebfb35b752, 0x42c793ad9a4f30b4, + 0xd6cae9fc01da9a1b, 0x3e513e6c94021465, 0x4a0fbf595b75f99f, 0x947bf2268c6fc1fd, + 0x4bf383dbb2abe156, 0xee9c3b40770fad2b, 0xa0f59bd95a635e4d, 0xf52b99e41857b678, + 0xfb5a63a103491dba, 0xcf2fd58f2a057c9d, 0x21836c7f301c6a0c, 0x9932fd6bb9fa6a4b, + 0xafd35eba99b8a219, 0x7cbc1ee48db98b01, 0x035f281c289308fe, 0x58f1e075aebe9821, + 0x4b82a42cd84a709f, 0x25809ddc3df0586e, 0x7f7e6eca759ce720, 0xf025fb3006d2aab9, + 0xbe47add3d3418422, 0x84f79c9da216bc44, 0xa8657d4f01b2c288, 0xac8a6a9c206ca243, + 0xae8ca2feb16caa6c, 0xf9ca74bbd5ce91fb, 0xe1b09ff423a2850d, 0xfad85195e07244f8, + 0xef83fcd4f7cb17c0, 0x8d7e83d25dac0b14, 0xd13e4b1f6bf0a805, 0xadada711b1546173, + 0x81913681fb6ac41d, 0xf2871a7b1d87aef9, 0x79522c6602f0bcd7, 0xfc19b18797818faa, + 0xbe1c711cc2d07039, 0xe282629748973985, 0xbc0ed52dc0f5538b, 0xf11ee382d6e3f518, + 0x8f0bb5a4b6f910e1, 0x9867be165d4f2ad6, 0xc575fff9787a8d3f, 0xca2e094752cead36, + 0xc72373fb1d63f4be, 0xe303ad00705e6cd5, 0xfec75dfb0e83bda7, 0xcbe692e46a934943, + 0x58cf3ff76e3144a2, 0x770f4e34eca9b3ac, 0x331e5bcce115f60e, 0x33636e39eabb9cf0, + 0xd167e9c3b22c5d13, 0x52b2dcc00cad263f, 0xd159aac9c2d1588a, 0xddbc2dda8f6b856d, + 0xa4688f418c5cfd98, 0xecd38a707141ecf2, 0x5b99b1fd6cd27f19, 0xf40b1dbb2aaab56e, + 0xe67f615837f53a3b, 0x54d867ce32d85657, 0xd1ee4830cfa35d74, 0x72e354e9df5b4988, + 0x7a385a40858aa435, 0x18113b58a89ab050, 0x1f333a14d265293c, 0xc1e37f5a38399a4e, + 0x8ce259d3514e0083, 0x5f3547a7571ba2e0, 0xdfd706a79a21a5e0, 0x210f289b04411773, + 0x2e9a0d971296bf7c, 0xcdc67a85cbf4bc97, 0x29f09b85ad54fabe, 0x664f4c4dff7a1268, + 0xc4620a0890a27127, 0x71bd58f0bb0fb7fd, 0xf6a26656993ae541, 0x7377879994b6fc2b, + 0xb0b45443d0f617a5, 0x612517d9dad3ecec, 0x16d26f2c9c235d4e, 0x1153d58b789118f4, + 0xaf6f680c76b3ec44, 0xcce0ebc72bf5b523, 0x5e40f9b52897e9ea, 0x831d7996d9a3027c, + 0x01de7e6708089e0e, 0x0e1e3f5c0e82c623, 0x9230e985fe74f785, 0xd78fe4a978412519, + 0x05ad9657cf84896c, 0xdded432166286643, 0xfb807e7e346d341f, 0xaa957fab164b1c15, + 0x80445c56cba073ac, 0xd1074995a72e84e5, 0xa420e83d2a9f499c, 0xadd5e1abd6731899, + 0x7769bd9296ad66ec, 0xa52c71f373aa482b, 0x3c16c86bd3b112dd, 0xe2737ba27eeab189, + 0xc939ce7280bc1e22, 0x87ff0a09862a4a82, 0xcbadd2d869b08857, 0x317ccd0dcb0cc9d2, + 0xe8b878c2f628e423, 0xdf362ddd8e4ca6ea, 0x766285614471d688, 0xfb6d60b6fd22d7f7, + 0x5ecb3c6542243487, 0xed91fb7932e1ffea, 0x24742c48a7965792, 0xcffc43f315b5c810, + 0x0525d0a1b3c3c7a9, 0xb766b687a4357748, 0x0842107929f41d8a, 0xa6b7806bb9a09894, + 0xe7779cd546c72cff, 0xc0c2e16e881f088b, 0xbf85da98c666d256, 0x48ae1e38a05c919d, + 0x2cbbe4726a06830b, 0xc8d012ff9b748778, 0xbe027b5965f45972, 0xdcead234ad61e6a5, + 0xa08f0f51edbb24a0, 0x779f93688d90b167, 0x97943e1939c1e88a, 0x6768aab84b63c9a4, + 0xcf1be9701f11cbd8, 0x3f21e00d7ce372d6, 0x0a5e70ea4a3cc8c3, 0x7e2347b44d83866f, + 0x097e66a173356062, 0x7d9de4ae0bbde3b8, 0x9d7b524ce2b3860a, 0x80cb7afa7aa08ab9, + 0x595dbb3428fbc614, 0x0af42c2bfcec99c1, 0x93df7a96d2ac55ce, 0xe27648f38fd342db, + 0x87880f53c2edfa85, 0x980a945e77273118, 0x5673e4979e94410d, 0x23861447a4619069, + 0xe796a35305b956c0, 0xc0accff0a109a8db, 0x7f43cfebacf0e457, 0xe978e94658a0ff70, + 0xcd90e94d71d755ca, 0x09b0acd95c50703d, 0x6fdf2d5dca83bde6, 0xe9c13699610e658c, + 0xaad7420ae61b6769, 0x1f2ab89d7944e7e6, 0xa70abf69c1947b38, 0xb6d6c8db0f22ab0c, + 0x4b6dd52916073e8e, 0x4d9862f21348322d, 0x5932576e5a5f4efe, 0x28695e3c21119829, + 0x6d82a8058882d3b6, 0x754d1643bf6fa7a7, 0x64827dd6ece37ac3, 0xfb8ef96ff4c398f8, + 0x9ea7c45bd67cf7f8, 0xac0891d114108f12, 0xac89c63929bf554c, 0xb508b039ab299f54, + 0x9cf1a0afa921f0ea, 0x48bfcb975d4b3cad, 0x2fc8b7086e2f1ab9, 0xbea3d10ca0f575cb, + 0xb212ccd2106ed95a, 0x606fd99127b13ee9, 0xca214f94e65822aa, 0x442b90107f533033, + 0xede22288037ab4e4, 0xad5d2f2cc2845863, 0xb54c58aa294bc19f, 0x64fde41e6505fba7, + 0x998ad11f5c745541, 0x69a4550ff51ebc57, 0x19fba5a7a7be74a8, 0xf5f0fa08a661c298, + 0xf40aa076ba88bd59, 0xdca082482d972783, 0x1b3ff0657399e318, 0xb47c89e48951d972, + 0x81bd03eeb1517339, 0x44b084c8b5ff3b1e, 0xf6724e1830ccf719, 0x1af2086f81a36f21, + 0x7ba34e4b6b6a4a8e, 0x2e60d0c2a1738204, 0x5e1788470d8f1680, 0x02836d08e0fa153a, + 0xe3e706332ab4d2b7, 0x5039f4805855bc52, 0x6a210847dbb26304, 0xdb6dd17205f20986, + 0x74931e444d50eaae, 0xf70c760c3fcaf1e5, 0xcc4970a1a4bf2469, 0xa4cab62a706d1496, + 0xebe00d58e029e2ea, 0x864d749a6dedff32, 0x2a6b25b25232a563, 0x9c2fa00b04a16745, + 0x01886f87e9c77bb8, 0x3dd339b17db90d85, 0x69b8a2a843bfe53f, 0xb13e523b780f1457, + 0x95f8b60ebd145c65, 0xd8d9273b7262d2c3, 0x98aa8b09c2c98259, 0x5ea01dcfa765891a, + 0x102bbb82dc967944, 0xb11796a0dfaf008c, 0x62cebf15175ccbd7, 0x5ba2e07dd4819ab0, + 0x0bc0fbb17875b8d9, 0xaaf39faf1a8adfab, 0x10c397c689a85097, 0x4b0fbe0160cd4b39, + 0x3e73cd18b11ac513, 0x9112f3c8725ec380, 0xfba8a33d9779e299, 0x03464ea71e8e9dd8, + 0xa32dc67996b69e9d, 0x01f17c631cad0ae9, 0x4245f5fd9e3779f5, 0x4e369e48e4be944f, + 0xcfd0b2c37c2c9fef, 0x849d7367ab8cf2a3, 0xf4e8f6043e82a28c, 0x61a38ce6916f5ed3, + 0x4d9023c0edb38633, 0xa302358aedc0196c, 0xbeaf68928345c24b, 0x3710b2de72474619, + 0x5565a9c1a6017f07, 0xcb2766c721ceb683, 0x3e0cec72f4825305, 0xdc07c1446dd817e2, + 0xab8daa43998223f2, 0x23d687796e5dff7d, 0xbbdc3247859cbcf4, 0x9581741bb3cd2f4e, + 0x3262c17d0fb0dc1a, 0x6bbc3315fedd72be, 0x4391bb88d95c804b, 0xd73f83cbdeaacf19, + 0x2455b44718e24aee, 0x7f63091fdaec4ea7, 0xe20017d153f4d7ca, 0xa88579a1c5ac5eaa, + 0xa26cd14e9c27eb04, 0x91104ee07eb34064, 0xaee6bee4f3d84ac2, 0x2924e97966e4bb26, + 0xca1c03dfb5ec8bec, 0x58f932b48c7d4e33, 0x56ed3ad2817bb309, 0x5526d4beb2afa9d7, + 0x6e562d46af276a19, 0x60010660f238d3a8, 0xaa2a9113c9dfd728, 0x4d25e63c06c9b24f, + 0xb7f9d4332f3ed50e, 0xcda88c284a00a470, 0x443f3a5abe0779e4, 0xf90c8f6759e7d781, + 0xbfa48a58c7778a26, 0xc5aff9afaa9d431b, 0x5d5ef444695e1b85, 0x173536fae1d3bbff, + 0x40a2376f7b2aee0c, 0xa4c8a88571c3831c, 0x0fc7776a78b477d0, 0xb53db5cfc724a976, + 0xfec74eeb8eeee8cd, 0x1fdc3a5f83cd7317, 0x57457802c994454c, 0x336a229a06f51924, + 0xa4dc769355ac019d, 0x071f16a06c2debb4, 0xa942786a68dd89bb, 0x730e2a8b7e479e39, + 0xffbfb11ee010d0df, 0xb1d5c00f6cf4c6d3, 0x28b65774b51bf324, 0x2e4ca633f36943e4, + 0x20c561be1285f412, 0x39b140bb7d2867b2, 0xce181e474f9d41f5, 0x2dab0b582861da8b, + 0x9a35828c0a5c542b, 0xe637aca948de2487, 0x8befe3066a97c336, 0xc799e9cce3e1052e, + 0x6ff709740b966abd, 0xf814c052069b68ba, 0x72d6ca05769f8631, 0x16ec2d500ca7e842, + 0x972c946ed6b8f8d9, 0xa60707cedcc88ab4, 0xca50146d78874dc8, 0x40144e070791998b, + 0x947b7d92fbf8988b, 0x95d659b8bef3a11e, 0x54ca6ff939e9ba9e, 0x3177b7a8bc3dadfc, + 0x069fdf99d75a56ca, 0x6b4bdba415de5f08, 0xe96ebde5c4dff05b, 0xa2a0afaa01a2902b, + 0xa2f7f029a7813c0b, 0x7bfd7d83698bf42f, 0x06ea1a1aa3f464a3, 0xf32406a8e004b526, + 0x9f03878fce26e49e, 0x5692f891b51101cd, 0x267c7396f0d123ed, 0x5ea8fbb788699727, + 0xe655798a5e485512, 0x4591d67ec63b3f28, 0xc6da8554b3c00037, 0x343f2103b4d73398, + 0x33b27c1be87936fb, 0xa1314cdbfd98b49c, 0xfd462bbe17b7b92a, 0x0843a924a18f4ef0, + 0x329ef377d33377bc, 0xf7a40bb43720e4a4, 0xf91df778dea7d018, 0x9c2947760204753e, + 0x9c74abf7e8985b7c, 0x7200540d1cc7b15d, 0xbf2aadcaf041b960, 0x22886400ea99cee3, + 0x1dfba390e2572919, 0xab4a516abb7cf1b5, 0x2a66ce81ba02e775, 0x9a22912f15c6ddbd, + 0x8345793c6b48374b, 0x3095f94432f539e5, 0xcdbaa9c65c233f9a, 0xca58a7855a55746b, + 0x0809baccf28e6d94, 0xc84dabf7ceb7bc09, 0xd3b582c0519a8a0b, 0xb2fd73243d2aa59e, + 0x2f1bf72693e82061, 0x923ea17a16de91e4, 0xea60046381c06635, 0x78525df123e71143, + 0xa041d8555c758dbe, 0xf6ff98dc9eb315eb, 0x5cdcbd91cdaaaec2, 0xf86aab56abf3ef55, + 0x12e9ad338f7710f3, 0xf661b3709a7bcf3b, 0xcd003bd0cdd279a5, 0x77c790ddf751ff57, + 0x2a670ca593c9ce02, 0x0443d06fcd269838, 0x6376595d4c7f9db3, 0x936b8fb00f5ac45a, + 0x380279605615df1e, 0x4886d5c0e60da6c2, 0x5a759f5810af2c1e, 0xa5369c4decafdc06, + 0x3dcbb96561d00bbc, 0xc6d5b973729f0a4f, 0x20938c0eb2051871, 0x2fafe912ba443ba3, + 0xe42fa1f23b8c0883, 0xda65f7bc69e8744a, 0xd40b79a8dbd1f74d, 0xb3534e69531f783b, + 0x3ad14e214682bcc6, 0x1b0a143c93bc9cde, 0x7805b28d8978f134, 0xe2137faf17393008, + 0x235ee610b4cd29d2, 0x08e789036bc2dfaf, 0xf81caae860f96fc7, 0xbee5d915677ea289, + 0xbdf23a89b7f72db1, 0x845f28f70e3de092, 0xf82915656ecd3dda, 0x2cb7c062e6b27321, + 0xf9c9558bdff701ec, 0x42457ac2e3e7e60b, 0xa63676263dbb8ca6, 0xe01a69d91dcdd1f8, + 0x39f726a80ba035b1, 0xf2255afa8014a7b1, 0x9489068a399a5f6c, 0x3e212784c41648a2, + 0xe068dcb680152a55, 0x78c0f65fc610cccf, 0x89832644645cc026, 0xda870d1865f3c185, + 0xcb8779948b3c0e7e, 0x82a9652489dcfb58, 0x21631753f8a6ab46, 0x085edcaeded35877, + 0xea33b3c0bf8b904a, 0x44a2992dd9a1c105, 0x56134a80f16a1ce9, 0xa00e0d5a460b7d8f, + 0x7f805b067de63f0c, 0x0eb44b63d3d80b33, 0xf14c555bbbfa8312, 0x2f81cf1f7a5d42f7, + 0x1e400d68988d0fe4, 0x5b2293e0c62bd4ca, 0xd795de5c204761af, 0x34cf4779930d1c11, + 0xd4304e9f6514a8c5, 0x507d7261cd6534ad, 0xc8e1719a09ba365b, 0x1242af4357fe027b, + 0x68d81a6f7722171c, 0x8fe77861d81fda8c, 0xaa3fc32a99ad5d0b, 0x37353b260bdf9f38, + 0x8a2562bd73ce61b6, 0x7c50da0821ac1666, 0xa3190c9ed9750aba, 0xcbe4832d0505d6e5, + 0xdffa227239ec6826, 0xcfa7375f77c70053, 0x2a528663f2fbb58f, 0x5e5e090ec8527069, + 0xd35455dbc31ca917, 0xf8bac820a6593581, 0xa2908dce958dcc41, 0xfddd36fbe476c2b0, + 0x2edb77073c2ed3a8, 0x065bcc8945f3e1c8, 0xa620708ac3447e76, 0xba4efd9f28bb9d6c, + 0x4551c812eb3b2b5b, 0xf379da238289e094, 0x5db26aabf2565fe0, 0x6f6aca809accedb3, + 0xb28c431d118d1b07, 0xfd4feb1c1645ec8c, 0x15740e5e22f8b5f4, 0xbef0e2c2fe58e9d9, + 0x2a51e436dddef028, 0xd0f534a3ae44a12c, 0xa79f36aa6ed5f875, 0x087214f31674974d, + 0xfe35b77caab2ac69, 0x65d6538cc589bad9, 0x25174bb0bfdb7c22, 0xe2ae25979241d493, + 0x0359e221adf91501, 0xa99d114459f67c0b, 0x1d9642476428fc5a, 0xba412ff0166dcedf, + 0x782df8bada86dbc0, 0x638455627a754177, 0x7decfe4009d21fc4, 0xe4747bb76ffcdc8c, + 0x88181a9baec37747, 0xebd3e3e9e7c1c668, 0x186f014cfeea02a3, 0xe4ea9c583cf8f6c9, + 0x2c2836b08143625b, 0x423b2dbe98c75722, 0x058f650e9ee8103a, 0x76c8ef05a3bc6d3c, + 0x206550a78820c8b6, 0x9f6a3ac23e00cb2c, 0x37007a6433d4d107, 0xbc6f7111e9e811e6, + 0x456077076c19da90, 0x2899d37046960298, 0xb337dc76abbd3b50, 0xc07d96d9f7b1b3d3, + 0x7ebb8d5f41a8fa41, 0x33bcced96db014e1, 0x17c149ad5ed3e974, 0xf5b6abefae6d1f21, + 0xf4828cf0227491d4, 0xf2f36bd31caf108d, 0xaae76a1bcbd4f13d, 0xcc64372112092105, + 0x8d2ec50a3087f3b4, 0x3ea245c8a845a522, 0x5d192f998988881f, 0x420237427c1b03fd, + 0x11d608d5a36b78b2, 0x2b6f62038a61ec79, 0x8f40c6e6d2c3ca6a, 0x8263d245b489336c, + 0xd3e01de65f314199, 0x5ebe7cd6dfd69aef, 0xf17405a9311d6b72, 0xcfd399907d9f4ee8, + 0xe4a459d9f96a4d61, 0xfd46daff42ebfacf, 0x01af169ec019e39e, 0xc47c978743500620, + 0xf6b21eb316ddd39e, 0x926d7f3a56769482, 0x2d62c92e0b426662, 0xa0a376e788f67976, + 0x614d12f3ebf1c74f, 0x25451082d842cd99, 0xb0250cfc219f31d5, 0x86a79ab6d666e151, + 0x1bc145b422612dfa, 0x2070aefc2f7cd298, 0xd22de7d9bdc57814, 0x6193d07ea4df45cb, + 0xc4a4b8b2434fc892, 0x5d8a8d620f57061c, 0x80d0104116f12b3a, 0x326f327d7d91e207, + 0xd728320c75e5f7b8, 0xfe6a0b6f5d44c14a, 0x2892486de709c625, 0x91ef2bc668bb0cbc, + 0xa84536177e6a9787, 0x96cbb8cc93383dd6, 0xccd7dcd65655e697, 0xac700e390c39072f, + 0x925f597642e05435, 0x5ffb06b7f900e947, 0x6cc62ef16ee00425, 0xd8440bb44f93f61a, + 0x51e2a0482fcadcfd, 0x3e2a1a9fa47d5ca2, 0xceb8b19883969df2, 0x46521082bc8356b8, + 0xec1f133865f3fe17, 0xc1f49cabb4eadb07, 0x56d3462e5bf36223, 0xbe8aff1000be3842, + 0x7394d80158fba64f, 0x8e1adf811f76db99, 0x42f8a2d073ae11eb, 0x45f44e93ee82abda, + 0x4cdfbfe1a0fa4e88, 0x204d157766c0cda0, 0x96e7ef6eac7a7489, 0xb66c240b5120aa04, + 0x459dd52e1de2c7da, 0x1148787ae5f0ace5, 0x9a094363c877e3ad, 0xef9d3dc3fb791338, + 0xdc3fededdac9a320, 0x0a519b95ffff95f7, 0x6609cfe87b68080d, 0x62959e94ad519835, + 0xb7c449c9bf8afa9e, 0x11f209063d4507ac, 0x0bc42e57bedd2e37, 0x671d39b96ceecefb, + 0x044527eb7b963fa9, 0x48cafa134788633c, 0x4477cb8fff7ca10b, 0xde5defca1a75ac55, + 0x17f64da2dca59ece, 0x40e45455b805097f, 0xa07a0f46a70b5e7d, 0x818b43fb1c043e80, + 0xa6fd8f6ce731a89b, 0x6fc862c588e31d0e, 0x508e1ffaacf2aeec, 0xf8672dfa2d5adfed, + 0xb15b0337c2d149be, 0x346f3388b9d88bb0, 0x70a366c2303875bc, 0x9723d3339afac94e, + 0xfe29f56c84cfac53, 0x5b499c27bbcae71f, 0xa394db10b60e6c8f, 0x2916ca59cc9f94fa, + 0x25d62f78d10b0ba9, 0xf2e0182e07673ed5, 0xd2f79ad35d80dac8, 0xea98b6de39536144, + 0xa183325edccdda7d, 0xb5ca8984e6a0e4fb, 0xbd1c5938f60adb51, 0x9168e8a373882554, + 0x063302444bd90ad5, 0x4c6034d1f1f6deff, 0x1a5d12d9cec2b480, 0xa4cb87ffa55d1547, + 0x4c91b0904d9959b6, 0x86dc657cbd189900, 0x5647a3c5db24884d, 0x20eb2435e06ed220, + 0xb117ed2935a7b3e1, 0x8ac51bc96760a52d, 0x2b2b1843815e6dbd, 0xe7a760726e738442, + 0xe6cf7a538acd37de, 0xb341fe5f75c487d8, 0xcb4bc0b40a49c051, 0x335e7ec90fd44e40, + 0x549e0eba3f9fca5a, 0x11dfccdd4b2f2135, 0x03b1f8493eb1c4ab, 0xc43ac1f92f3bea12, + 0x7207b9dbd930c04b, 0xe83be577d9ea3b97, 0x2db2c5ec823c5d69, 0x25052ca079416eb8, + 0x7e012ec69c8d306b, 0xe0df3d59d012d1fd, 0x4192e8784437fb9a, 0x234c3ccd5b6fa6f6, + 0x61763488625c823e, 0x5b530687d30a3ac6, 0xddf571a200d5d63e, 0x5c5d6d01dac775a3, + 0x071d25bf0ac833fd, 0xac99778eab986a11, 0xe22baeafae9b7376, 0x97b3d35a0cfb8745, + 0x16533bb6fdd41252, 0x5ffeb31bf3533fab, 0x5b3db782a5b8b24e, 0xa0ffea0041542ede, + 0x9b41bfa159e4a5e9, 0x97e3217feab1c2f4, 0x47d7a8c4a933ef6e, 0x5155c6751b10c6f8, + 0x046cadc9fef5743d, 0xbc0456f5eb89fc86, 0xdd3131aa5b6ec496, 0xc9d6a3f206f05aa8, + 0x18623f8f954cb9df, 0x3b8f9c5f3d1ed9b5, 0xc5a8f5342f06926a, 0xe57908213e457ab7, + 0x5c487de33d56f8e5, 0x54f8b13b9064b6b8, 0x00264d60937363f4, 0xee3ddeb08374c5f9, + 0xc7e6c206f411a3f8, 0x1ddf9fcd745b384b, 0x02ef5819d563118a, 0x86d53ad0cc473760, + 0x47bbb48575c626e6, 0xacbb8c53b8e4c610, 0xfe7960bfdedcf4f8, 0x2956a8e2b9dd1d3b, + 0x64cee52115904e65, 0x4e06e12dc958b26e, 0x349bd01196399be1, 0x7e5b77c9d0892c44, + 0xf68f625588054eb0, 0xc094ad20da36bce8, 0x6d9327f0703e1365, 0x946ff5c7973ea1b9, + 0x5d5a19ce90078f67, 0x58d9ded6888d07dc, 0x0caa982ce77ce912, 0x7d7ffef8672f06ee, + 0x26d7ac5f4918c318, 0x5ff6d11ea8b149b8, 0x422745f95d62c60b, 0x7519f778bed8c1c0, + 0x4149149987bf2535, 0x391b7c6aace48d53, 0x01c0bce3a014ab96, 0x596cbabf34195dfb, + 0xf8ce111179bd8bcd, 0xa777b4d75877272f, 0x093befdb47ddfd4e, 0x7149856f41a9931c, + 0xa0935cacfff4bd7d, 0xc0fa2db6bdc010dd, 0x91def746f9e76fff, 0x65b13ddae95d6231, + 0x2c772a1485bd37d9, 0xcc9d721e369d17fc, 0xcac523860f42618b, 0xeb9f8416c18ba2ac, + 0x027c89351a77021e, 0xb13f8abe9309854b, 0x7ee182fa982e25b3, 0xbb49604afb3121cc, + 0xb6040eb7c4123a2d, 0xd7e52e5cdc2e2bd1, 0xa0edad9f12f5223d, 0xb9c50bb75ab2dae8, + 0x747f7ded6d50dfe6, 0x708954d8088caba8, 0xcf3726075efb1547, 0x91b5316a2e4cae0d, + 0xe413b23e66347117, 0xbce2d2759201dc51, 0x05a9d7785c8ebd4b, 0x6b7c91bf45b24d6b, + 0xd70c42c45d1bb405, 0x4d00c6c3290362d5, 0xa4db882996f01bd7, 0x2ce82c1d8eef8832, + 0x3582aeb9aea7fbfd, 0xb29ddcd2cb0d40e4, 0x9761a3ce2259256f, 0x0d54d64a1e2df8a4, + 0xcb88706194fa177f, 0x586cfe4548edde87, 0x77af635bc8757a2b, 0xc8fc480b27d59ac7, + 0xb65632aaf3b8788f, 0x71b607a1e8b429cf, 0x96dd73fc07fff3fe, 0x961c62fc08815bd4, + 0x32a56d92cec14bd7, 0x28c83b02f1b9782e, 0x6fd8d183d56b6002, 0xc7fb5f7f4ca8c2fa, + 0x16fcbea13080517c, 0xdf2defd02860c8c4, 0xf2f212f0818cdd03, 0x551e1f1073641996, + 0xae8f2a08b501804c, 0xf29d4589b75c6601, 0x8190701da1fe009f, 0xe6468515aa457e8d, + 0x8549cb525b366fec, 0xa34280f850b06a54, 0x72455ab8219eb451, 0xf0eb00528aabe907, + 0x409169ce48cfffbc, 0x1f02650200e492ed, 0x5856e540ebe567f1, 0x3ea9efceba507a73, + 0x8d40538f8be37a4e, 0x01dc014d0501174c, 0x550e9c3fee9cbea2, 0x5141e4a22f54a38a, + 0x3d5134f09bde648e, 0x4376958a1b39eba3, 0x8fdc8e8ffd3bf584, 0x1d4f7fcba86b1b6f, + 0x8baf03d5f3895c74, 0x02468d5d474040d9, 0xa69e9c549377cc35, 0x99cefe759ee9254b, + 0x670772236ddf5e09, 0x8419f6e8c15a913f, 0xc8111c51d2897c7c, 0x47fed3c87e5e830a, + 0xd57b2c2597389496, 0x72e03d9dd7c0432f, 0x9ddfb663cb225a33, 0x644407622a42a19b, + 0x36f1c858a8191ee9, 0x5b55eb9a39c79eb7, 0x205512efc9853ac1, 0x61638bbd871baa91, + 0xc2c5a321972e06ea, 0xc2d50ebb51ccef81, 0x00a8cdc815b2002d, 0x35e39c3d85bb220f, + 0xf7cc216ccebdabc7, 0x034d730c94c6ff38, 0xe68d4736576f5424, 0x657f20ae289cb61a, + 0x7587dbeb4543d01e, 0x4ac370af3aa7a2b8, 0x0608fb7b8b38b542, 0xf3aada3f9f9d4ba6, + 0x16a3a0ade12bfd54, 0xa338857ce1c56ba0, 0xea7364c7d14dfafc, 0xb815bc525eaaf960, + 0xdcf48128ebf48ea1, 0x08c31f79e642f874, 0x96eb3af427796aba, 0xf18bc0fba1acbede, + 0x58a601fdcb5d1c1a, 0xec523f16292e0e80, 0xa38eacf0b885861a, 0xcc3b3d9854fd523b, + 0xf36f918352406b3d, 0x43400fd10760c884, 0x933a5c242df16d71, 0x80c922ce4d62c945, + 0xe8f049073d0403fc, 0x4178783a4d8b1a82, 0x90dc8f6ae6aa23ac, 0x54a9e1b221f0905a, + 0x45ad3abb539bd4e6, 0x66d388a54f923a17, 0x6c4f7cc6183bf8d6, 0x4bcb4ba3f6d7b5da, + 0x4e85c0f645bb886b, 0x19475ceabf6a96df, 0x9189ca576d87ac75, 0xcaf7fd78674c5b85, + 0xf007a6c6864ba792, 0x1b50b2b7974a5c36, 0xd951c27823338cc4, 0xa6cea6e5ae80291c, + 0x127675d7f6ac8ff9, 0xab587be3feda1cab, 0xa16a0333181d992f, 0x2a51c4eb17e3aa06, + 0x14c4d94e333d2a5d, 0x3dca8f448e89f225, 0x409d11a4d5257ee1, 0xf560e29949efa40c, + 0x869d8125b8b24ee1, 0xcf3284de7f4dec37, 0x84a0e1b90eb6b517, 0x55d708ccc7d01e0b, + 0xbe466bed445005c4, 0xc790a6a9ba5bd332, 0x3f262db07b7c9756, 0x13fe360480a7830c, + 0xd27d2bbd7df4d28d, 0x40ee0d80122be9b0, 0x04ee84519a7d3704, 0x14415cfa51e2052a, + 0x11c4c53bce9962c7, 0x6e85b45a40101948, 0x8dc219a91e3888ea, 0x4773b03be2516ed5, + 0x4904a0e3693e7b89, 0x3fbbe0b4d143bec2, 0x64ceab586f528006, 0xef22f2545e9d0b60, + 0x882f8241080b9895, 0x8ad1259eba0ae10b, 0x4db7830c3811f62a, 0x4f556432751e289b, + 0xf86d47e71a3fdfa1, 0x0b2f109ce30bc4e1, 0xe3fe65c18aeddbae, 0x0e8047ba359f1a80, + 0x49839edbdca3f7e6, 0xb131a101abd8ccf7, 0xbb403bf586c22340, 0x8fd364f6acb73ed9, + 0x840e9ce2110c44e3, 0x12f2650abb61eefe, 0x4a7ffc89e18b1c0b, 0x32fce4dedd44a7f7, + 0xa4958aa058687c16, 0xd1b031eafba424c5, 0xf49dedfb91512a01, 0xd987e938b0722694, + 0x001b841d8fe3b34b, 0x64df5fba0961780c, 0x66732ca2329ff525, 0x18735ef5cdfce09a, + 0x4597de07aa64a94f, 0x7bbddd549017eeef, 0x760597fd8d2ed4cf, 0xe3766b93e0d0ac84, + 0x21faa6c988d9aa98, 0x779ebb2b615a4e8a, 0x1dcf5a963461e524, 0xeca7f0dd5bfecd69, + 0x75e7888446c9f52e, 0x06dfb3ad640ba6cd, 0xa7ec5bdb9d7ef026, 0x89b0b2c86f106ec5, + 0xd97c364e226490fd, 0xd2af46e1ea09fc54, 0x8862d5a50b98f8ca, 0x4dd09b09544333d6, + 0x2a9f3e95f0215815, 0x5daa5e77756a3b10, 0x96cf900596833435, 0xaf10588115709a5b, + 0x4ee06b4cfd8fcf9a, 0xb234068040000222, 0x062933989e6d6eb5, 0xf8e240565da11cf9, + 0x660f25687ae4e535, 0x1141f1e1840ef44f, 0x6c8c4da79aeb5ca9, 0x83033dd75132b9d2, + 0x1b06bc2b72c6cd27, 0x2006360a1ed89ba0, 0x8bcb42a2a24e2ae2, 0x27dc556bd78fef02, + 0xf76553dd32fb13c2, 0xcc9bf0a27a440aa3, 0xd459cb73642186d6, 0x8d2b4f094ac320f5, + 0xe6f78bfb8aff5757, 0x45227df690929bcf, 0x834ac2cc4791c761, 0xce2af3ad01721f9c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xeedca7e0c951d03a, 0x8c3a63c35a3a74c5, 0xfa8a42505e1aca76, 0x9e0b6262463270e7, + 0xbe5f2c0bbc622002, 0x8bcb0324db709e0e, 0x4dfa15cbf974028b, 0x91f6a4e258bd0908, + 0x39c2322b625cf89c, 0x81a6d586b71f7dc4, 0xb776f914608a477b, 0x7b1b066d9fd38da6, + 0x683d887edf2ad19f, 0x932feda5cd02ec7c, 0x39dc8db7ed59a6d1, 0x1cb57620678f4dfb, + 0xf213050bee21fe36, 0x4747fabea4738f11, 0x23b75fd0a4ea2ae4, 0x33551327e0715d43, + 0x05451167e0b948d5, 0xc12b5141c5bffd39, 0x70564fac026ce2f6, 0x1722a54441718a12, + 0xcfc3834ae99902e6, 0x1308d7f7f19fd04b, 0x04bea6c145ae0ee5, 0xccee8241a570c968, + 0x5294c488cb3b0bca, 0xa62c35eb08ae56e3, 0xf2d1591ceb391ed9, 0x282b3d507f2024be, + 0xa735799795f0a66b, 0x5ef6738449ead606, 0x193c3d5407959e22, 0x8b3834706b4ad5b8, + 0x319b1594dcafefe2, 0x2fbaa5cd2f58bbb7, 0x7fe46be9d546f0c5, 0x476ff0befaaec411, + 0x4bf095df325923a7, 0xdb8ad4bc0cf89f23, 0x42e832b62997c678, 0x2406b889805a4d2b, + 0x98c88904cdb09c7e, 0x0ec51b7a3fec5805, 0xe68070ccf539b26b, 0xfe73e57af33e3448, + 0x1119c5aa330e82b4, 0x493b287c20dad20f, 0x4e05506904754617, 0xa94349868339b93d, + 0x458ad7670acaecef, 0x772f0748b7254cef, 0x86354036a9a1bf40, 0xd6cf2ac9982573ae, + 0x23cddbf845a2813f, 0xe6d5b06f5a65211f, 0x4c73b3fc538e06ed, 0xc3373690b62a231c, + 0x04110e90d454550c, 0xc0cd5bb5479e4032, 0xa5d05b8c0ebd2db1, 0x956fd51a130cf00f, + 0xac1d51907f6751be, 0x8c49ef886759567a, 0x5a001a21694ac906, 0x6116187d67a7abfb, + 0x443494d942f9ca00, 0x948fd111db19db29, 0xd016c93d5bd34508, 0x44641b3e3d8cd06b, + 0x1a6d94a8b3e1571b, 0xd63cc3dbd6056d78, 0x3da0287568f7a771, 0xa06c041ecccccc34, + 0xcab283bf2dfab727, 0x09f64659271aa55c, 0xd125465e53f07efd, 0x9c113cb88f8ae022, + 0xa226c83f10155980, 0x538fadc1cd1724e4, 0xb9009dfb0311d9f9, 0x7b111d860f9096dd, + 0xcfce9c0bebe9e8d7, 0x9728bdc759f9a8e9, 0xd7e016f52f7a2549, 0xe7ba45de23b820cf, + 0x0c5b9051c29c819b, 0xe4d2542e5c3e0858, 0xc571ef54c864f690, 0x1fa83e7eb8c1eb18, + 0x1849e47b4b565700, 0x046614d04e7addd9, 0x1876a03d342d6971, 0x1180d1ab8c8e0a47, + 0xb9101255287a0bdc, 0x7f526e55c5f10d1d, 0x91167b055836ae8d, 0x677c0715bac0ae8b, + 0xc9e76104bf4a3734, 0x062646b4678a529d, 0x204e7f5b643b81d3, 0x6c847283a0f9bc1a, + 0xf8e68cb8d4464237, 0x00aff6fc7a134438, 0x0371c005388581b2, 0xc3ea62ecc39ca54b, + 0xe738af197b2825b7, 0xab0840b3a6cac25b, 0xfa9f3ab8c67808ed, 0xca4fb82d078d8a2a, + 0x25be15a56c7a6283, 0xbc1ad2ab28c3f86b, 0xee50972501c4b52f, 0x9d1745ff6cde957f, + 0x052d0ec30cfa7923, 0x0f69c5dae10380ad, 0x6fd6081ca097d00d, 0xee8dfe85babe2e09, + 0xb4d7449f88cdc5fe, 0xcf29d18e4e66171d, 0x556404519b37c8ee, 0x3bbb7d622176d876, + 0x545ef749cbfe19ad, 0x8caa7998c081dda0, 0xc3c961bb7c6c0708, 0x0806d5680dab22ce, + 0x6f47951c99190618, 0x661f469eb80b44f4, 0xf52ced8b05b59fc8, 0x608c961847a71320, + 0xec1300aa3a3a472b, 0xa4fda54a82d5b545, 0x049ee20ae96b6e43, 0xbaaebd683585ae5f, + 0xd7235f034febbfe1, 0xd81135a204422d83, 0xc83aea2248dcde2c, 0x3d7def57d1e02da1, + 0x63692f4f90110d2a, 0x7855033f4dbdaf34, 0xec26ef59de03eecd, 0x801c1c7db0a8467f, + 0x30e96fe14975f925, 0x4120b50d2695e98c, 0xf5ebcbef2360b166, 0x1f594ab777d4a7a5, + 0x34ba90b2aba42d03, 0x4467d0c6c3f9fe3a, 0x3fe794cf89c4fea5, 0x71b2acdbe872de43, + 0x158e424396f789fc, 0xbb01aa76f1729b66, 0xd04eaec6aa61f15d, 0xa618affc32f48127, + 0x9d98b124d223427a, 0x6df87fa6539bfaa2, 0xeba5c6f1adede360, 0xb55526ad159d94bb, + 0x7aba35d95db81a89, 0x0235c7975a847760, 0x1942ff51922470af, 0x96f2a54607e14882, + 0xed35cf97101055cd, 0xd12d5e2f1713c8ce, 0x552cf6757c6ead6c, 0x530bd7ecc0e5d4f6, + 0xf78d450698d2c5ab, 0x1d91b24edc0cbcc8, 0xb935b39163b88df8, 0xfcb0a9066e15f695, + 0xb91cd79b199aad88, 0x61b3b0c46a597610, 0x1c3ff19b69fcd728, 0xc245f87c8c733a2b, + 0x35c5faf1b9df0019, 0x6183cabe3728d4d6, 0x1fc88253ccc491fa, 0xf056f780e7349ecf, + 0x0f7a570aef71c143, 0x405576874b455c40, 0x05715375ba4cfae3, 0x0b70e4db263cdeb3, + 0xaa2953a9a0df767f, 0x1fc7d20ab046cd55, 0x5ce12921da648770, 0xbeaed8e67d1b60fc, + 0x8301d88886d910e7, 0xa56ad65789b2f0de, 0xdd0a56762fa93464, 0xb5beeac158e8c6f9, + 0x3ffd8c534ef8c327, 0xcb0a3826b5a8add9, 0x99c9cd658d10f2a4, 0x2a5760b13ad79b73, + 0x8fdefe73725d0fed, 0x05147743cf9f8f56, 0x0776f762e2e5898d, 0xa3fd095366bf2682, + 0xeac9d6b14da24bd5, 0x482e26613ae4fec6, 0xa86109b8a2eb4966, 0x789d457de61aa75a, + 0xcf10363d8926c0bd, 0x25d3ade5315962e1, 0x7da5e59de8ef9965, 0x03eaf354831897b6, + 0x0b6926bc526bb421, 0xb94beab00fe73ce7, 0x41b92de25f6ba13b, 0xcb781ab3e278f4e5, + 0x3f576c029a60cdaf, 0x454b07952701e9b6, 0x8e2a04764b5e9492, 0x5d15f0eaa3bc23f0, + 0x5d936e8a7a293056, 0xe5d3d1f4dea1ecca, 0x1c69082e7321904a, 0x04879264f0b8c1fd, + 0xc25edc138e526759, 0x7f266ac53d61e887, 0x6f3fecb7fd7479e0, 0x888c8a9c866c39af, + 0xf1bd55c8cd4c767d, 0x31594fce2f509caa, 0x65072bf074b41878, 0x5c6c884cfdfc8afa, + 0x3c62832e7c323d7e, 0x5efd8b019cb5e902, 0xeec6db2bdfe49052, 0x9b3b12789b54e1d9, + 0xef6442d0045a2422, 0xdc9f647d840a6795, 0xd805956f51c0904c, 0xb2265f8b0f255b00, + 0x528eb333c0d18f24, 0x550b165d3eedd9ad, 0xf1f50f6ad334bac1, 0xd0e02e4fdfe7b99a, + 0x9b833d3f6c6934a3, 0x5a30b168cf4e7e94, 0xc8669606b3e5797c, 0x223e2f3d55c98452, + 0x5d297547f60fa049, 0x80d1297610174683, 0x93e471ae279c4e17, 0x379610eae7171e8d, + 0x46edfe107be63eda, 0xd9ff77246253e46a, 0x601411085976302c, 0x15505db63eb6ba38, + 0x55e879d7c002180c, 0x77fd8e0d27c942d5, 0xec36abc90c9d8c40, 0x9179bc137385859d, + 0xaca981cc12043fb7, 0x9655e80a1611f4af, 0x924e54c771400ad6, 0x4b852cf0a9043cf9, + 0x6e14495be643a707, 0x9444e022daee757d, 0xb6013cdec879904f, 0x04c8649861909465, + 0xc28696e5675f5571, 0xec88526c947de72c, 0x2a185c5efe0bbe5b, 0x9095bf03f0f4f45e, + 0xd6994a228069461f, 0x0e2c6b10f6900418, 0xb6aee5b977c75a0c, 0xfe863c2d199ed4e4, + 0x83f6024fce5f78e6, 0x6275c174bd0ade4b, 0xd4a983cd5f8a5e23, 0x62c17ef4e9006ad1, + 0x689ceb571b996ead, 0xdab1c5caf08b595a, 0x49a2cf1a22921753, 0x1567664576587781, + 0x0bf1f5c29714c1fd, 0x396b4f84fcdad2b9, 0xa3c791b3054993ad, 0xe0ec8ba6171bd837, + 0x580439c27c94095a, 0x5bde22eb19cb519f, 0x6c63f3d7074148f0, 0x234bcccb5d8e3685, + 0xe2d8297abf1aeb46, 0x2fb89975e94882c3, 0x34fd8449def296a5, 0x40ef531ff0532f88, + 0x74c2936215c79631, 0x2bea03393b39d0d3, 0xde6d28f55a68015e, 0xdc9ad0c8b709c6a8, + 0xade1c8f2aa701a24, 0x187588d257b6b6d0, 0x44030ce46f9d0ae8, 0xa95749367447e64e, + 0x53ad95fd69f31d93, 0x9dcdaf159f3447fc, 0x1a2dd5f1e6f46453, 0xfa625ec697ee9e6c, + 0xd2cd0d906f71b0c3, 0xdbc1a14eb5430c79, 0xb9b3f1125daa1389, 0x971c9eed96c94700, + 0xb731e271bcdafdc1, 0x6f7c5123e3f9b76c, 0x3332081be60f26ce, 0xbf0b21f05100c86f, + 0x145838fe97158f18, 0x0b476445d7c99fc7, 0x8aae6516078c6b3f, 0x49d1202e75a47892, + 0x19167ecbd5675bc0, 0x28c6d8bf7be63064, 0x07c0876dd0e5d4c2, 0x9901d9bb0475ffa1, + 0xa4b245bc7e67acb6, 0x77d1b38a3cd33147, 0xb3db1c30e10d87a6, 0x20f626f1af66a562, + 0xf7a03f4583d5b299, 0x5c6b4bd3a83718e2, 0x826e63d3a60fa432, 0xbac7825b83995590, + 0x4370af144fd59cc8, 0x718965e31b440927, 0x25894644dd0ec107, 0x71609e626d0bbc25, + 0x23de302c59a13b66, 0xbcec30b40cad1f96, 0xd8a0f4c04171fac1, 0x5c13531581cf313b, + 0xd93b39fe92138f7e, 0xa032afd46848a759, 0x5040f30a775d1d09, 0x715861a47214ca47, + 0x614f7d6f3b54636a, 0x58cecc1be72dae12, 0x27b61d27ae455ce3, 0xdf9fb8ae5a3eb273, + 0xd1454276a1cb05c2, 0xbab191df3e98f797, 0x35684119f85c2482, 0xd241d81e5744408e, + 0x5b9fbd9c5169ff7a, 0x9646038bea34d844, 0x098505f7c378ce9c, 0x6050399903151a93, + 0x47958b99b21a2ee4, 0xf2661e3533608799, 0x0ba5ebb2dfda4358, 0xf8fbe9ad66652fc6, + 0xf5f483584e94f501, 0xe3503fc5e95479fb, 0x1512fc47f82b7a4d, 0xaed3645653345f51, + 0x321b73054c99a5f1, 0x4a2ee1dcec34b3df, 0x43cbce287fbbb582, 0xf8f98e28fdd88ce1, + 0x4fab29f4e6d7a5b4, 0x264395556cb35f0c, 0x0acf890a5017554d, 0x7aa7dc37c13b1848, + 0x2371f1608ba74a63, 0x903fec755e0aee0f, 0x009fe6c15ec4e0a2, 0x824de33c89ee04fa, + 0x46254790c0354ac9, 0xa9f370a62058e8bc, 0x977d768da83afbd3, 0x42d7f4b8d680f84c, + 0x4efa382ac36866bf, 0x41fcd288ca22fbe2, 0x7d9875c548bd222e, 0xc97cb3762ee57adc, + 0xf530770f44070480, 0x1ab2560990052473, 0x3b5fa3ecc1d933d0, 0x93cc208bed0aaf86, + 0x9c39e3d2a7541ad1, 0x5b093106750a5076, 0x67dc7bb4b7361406, 0x53301bd97e564d39, + 0x17d108cdd69ce79a, 0x434eca4b7bda6429, 0x2a4460d967b771d8, 0x0d7817f4662a20e3, + 0x83622d96686c8916, 0x3e917d557d9232d3, 0x213070ddb0829c1e, 0x4e7d79faed8a625a, + 0x7e9e796feabaf30c, 0xf179d8630c7482e9, 0x234d96985e03b774, 0xf4f427c41d28b5b9, + 0xf17fd9da735417ae, 0xbd2282e466cfed71, 0x95a54f8ac0e815f2, 0x7432918e790f17e9, + 0xe9d1542b88091651, 0x923042039dda15a9, 0x2a3a2854d024a9f2, 0x9c02e5ad6e335b22, + 0x10a9d427f6c85f6b, 0xd254826ee7d89670, 0x8a7a681f1ce57917, 0xd23620e65b1cf653, + 0x63e471182233bbd2, 0x86d584dc12f61090, 0xea6953a7f6cc73b8, 0xec78d41058948340, + 0x0c57022c8580ff10, 0x6e8814354d096c00, 0x9630a01139666f3f, 0x9866366fcc49b3bd, + 0x990abf7024e1077d, 0xc67db297519b6601, 0xde1590e766eac3fd, 0x3d9f4fc409db0190, + 0x1d493170c2edda8a, 0xd38dc9c314a5fa62, 0x8b20bdf4fe140929, 0x96e35100c4cccf48, + 0x00667b36850c4a85, 0x7a57c842977eca84, 0xa7cf6d0c0f6518cd, 0xa4a438711a7ac38f, + 0x9013c6c7d9a59c74, 0x28f0d954f072d8ec, 0x9281955ae6b21293, 0xb49438cc63f15971, + 0x5c31a2eee5f672d3, 0x060b3deca98e7dcd, 0x6908830065b682d7, 0x61a8e0567c3bfab9, + 0x3dffc0512a3b734f, 0xdccdf959c9b09edb, 0xd1c6dc1c01a0e87c, 0x610dae53161e0812, + 0x4d2d0edc18dffd1e, 0x70c1094c6d2668be, 0x78228c7595e3408e, 0x830690cb001ece34, + 0x294593f1fe29986f, 0x97750956f6a473c4, 0x65145dc2affe6846, 0x89677373d2f5cf43, + 0xa1868dda2542c805, 0x5f1e8ebcc92bc7a3, 0xec360b46ba8bb93d, 0xe04c7d42453244a0, + 0x1b39f0a4cada1f23, 0xac6927cef5d61d23, 0x158685c1973f929d, 0x22a01a3db8903bcd, + 0x21ef5669f65d2472, 0xdec89fa413e567e7, 0x9916f6cd1bdecf32, 0x04351f33496c2296, + 0x049ffc3f1407dfbb, 0x92fcf36cf3f1e705, 0xcd2319fd6046ca0f, 0x3b30f68c1b0ba08d, + 0x2483ed36c613c02c, 0x915ad00983df3a7a, 0x68bfb60ca70a3cb5, 0xd8b233a32eebf3ca, + 0x91019006ade73bd7, 0xc738f45ed144e990, 0xa98f0082d26c0d4a, 0xf848d9df9a444dce, + 0x0f4ee801e85e01d7, 0x4cfbeb3fd576e939, 0xaaad7bcf23d85984, 0x45daa3a8c693d0fa, + 0xed5b9a172e495e35, 0x76d818e7ded6b691, 0xc821b413eaf96497, 0x4b9ce6e6fc87a184, + 0x6a48a853d344f0a7, 0x94028ba1588eba23, 0x3d01f2fd2107654d, 0xfbeb502b13e7175c, + 0x8fe7521cc21dc1d5, 0x5ff6c77b2251eed1, 0xb1908c4f73fa9d06, 0x8de670b8040f5f1e, + 0x03f6d066065e1e69, 0x74affb51c2b74761, 0x0a569d7c6c31e689, 0xcb311c8d24ec6662, + 0x83e00e002e69dd49, 0x5f6d8a7a8d161c96, 0xc7581248e7a3a423, 0x73c206d05f1ce563, + 0xaf20860f7daf4564, 0x64aa0da623f08bf9, 0x89f825758aba0b9e, 0xcb5633ff07db796b, + 0x609674eeb2a1e504, 0x2cd638565f222b5c, 0x4af04e8da85a09e6, 0x994413b89736c693, + 0x42bcb97e73a04713, 0xd61131b54f09e71e, 0x3206e5a25da6b730, 0xc4f59f4751f3e4c8, + 0xf3f99500de1fca73, 0xabbd971696a2fa86, 0x7ebbb816255f434a, 0x9420e3cb88e90040, + 0x4956f44faf60594a, 0x01e35c097df95500, 0x301b829dcc499373, 0x694cd2176c87c8f0, + 0xd1af81f166d232d4, 0x9e07e5039a5d8008, 0xa5c1c4b6a2f22bca, 0x39bbc86346e5eef3, + 0xed19a035b46b75d5, 0xd302602a109cca35, 0xa62f8859a1692e8e, 0x1b94f9622c7eedb6, + 0xfbed00befc0b0b69, 0xf74d8abbd92bd28f, 0x0f65aa3fed0e01ff, 0xd025f3e2e9ae4bf3, + 0x4e86522ae27336bc, 0x19e7b4b5f426b678, 0x5c474b6fbd411bb9, 0x0b25f842865a3900, + 0xbe10802a2f6985fa, 0xe9c896f6d31f1b04, 0xc815edcb36a8647a, 0xe795534ccec7bc5b, + 0xad8f53989fb55458, 0x176d6c3fc36305ea, 0x604ac92d29021d3d, 0x3b397899b8295249, + 0x3f5421792baddcf8, 0x6e2487532ae82053, 0xe32ca83fb42c54dc, 0x12a5a565b2693842, + 0xdf5bb9c2675c2818, 0x84c049536e24e16a, 0xc693bba9162f56b1, 0xab89ad7daa4fd305, + 0x225cfc06cd31db7e, 0x38c669dda9bbde8d, 0x162a837cd0189451, 0xb7b67b2a61230abe, + 0xd2525f7f077d1b65, 0xb1731ea0f0f55899, 0xfe141c3f4516af80, 0xf13f04dc611f144d, + 0x4ba25c5196746647, 0x2c5d728666c32f4a, 0x0910d64f0593f13a, 0x74fd544879fdf502, + 0x572381a1b4dcdd3e, 0xf42a914c1abe9664, 0x0fa9e4cb9ce67f0d, 0x52b58781b3fb603e, + 0x71520cad1db65117, 0xbf9f981b47935256, 0xaabd3917dd7192c2, 0x2fc98f8310b3b1e6, + 0x763ecf79485a7e7a, 0x2e9184d425436183, 0x798b15b456b24f10, 0xc50f0f553f211a38, + 0xd31a2e17c57d21a9, 0x9d359cb7034dc79f, 0xe0d4d2c6788232f2, 0xe109e83331e89b15, + 0x2db0848c8f42c145, 0x69e209a189669a32, 0xd6b238ceb614f9fe, 0x32780472f981db53, + 0xa04e14afb47d4c31, 0xfa0bdf4c63ae4b87, 0x19016376ab9be09e, 0xb44e9d058b95b62a, + 0xe5d93873934275a4, 0xfc3ed9a1c8c4887d, 0x0654b73ce23e0614, 0x14540550d8dc3961, + 0x95e9a7c132aecaaa, 0x823cc14150348b0d, 0x11afc75053a0e977, 0xbce93af8e490f0cd, + 0xb65330d69b4337f9, 0x5be17a4cfda9a219, 0x85d2599684eba638, 0x63d0fe0ca7b6979e, + 0xa527a5daf110958b, 0x824f38ca7f3026fd, 0x229217507f26346d, 0xb4cf917bb37c2303, + 0x5b2ab24e47560abc, 0x3d3c6c0ee654554f, 0x5128867c9b5adbf9, 0x07d61123b8afc4bc, + 0x5ce8b94eb5063afd, 0xc6a6ceed33496a13, 0x1a6bdfacc9e25b36, 0x6e5a57c5d3067bf7, + 0x036f32cb0e961107, 0x319a4a1cef386689, 0x8d23d0a98654761a, 0x5f4d928fb9de303c, + 0x4fd9348989fe56d1, 0x8bf81ddcc8b68636, 0x840727876f78152a, 0x7af41e9ebf8733f2, + 0x268219578b5dc867, 0x968796ad3a6d0826, 0x998a02a35a0b2f30, 0x623ed046e001f561, + 0x0ff26d66cd9edeb1, 0xd1d59598059ba367, 0x57aed45d052aa0b0, 0x4013d3f12cca9322, + 0x8f84ab1f762ccca1, 0x55d32a97ef39e2dc, 0xb561727f67d7491c, 0x16f112500cd1dd83, + 0xcb3e9a2480036b18, 0x1c85e3a9cfcbcb06, 0x7e6b4a5e720569f6, 0x3aa960beac17014a, + 0x1e07efe5ed7583ce, 0x6f37e1f909f7ad7e, 0xdc3510a4e3ff2bb6, 0x62caf8d624891132, + 0xb6b82d4d5bf20b0e, 0x0718d04ebfa159d6, 0x8fb03d6abdc3c502, 0x2489203e90249ca2, + 0xd65e81d74f1eda6c, 0x0036c8583360bc66, 0xde20fb216d94ea20, 0x5f88e95becb5121a, + 0xb35aab96e20b0ef3, 0x95c467af0f1c18cb, 0x327a852397ad9ef7, 0x16879d7b98361c52, + 0x0ec50bc3457cfaf4, 0x48d6017ef0f013cc, 0xf962704ab5e4e56c, 0x5340e80c374b0d58, + 0x3b3a8659127cab35, 0x09125ffa12f7ec79, 0x08a9ad56710a76ba, 0x6483ddd616389fca, + 0x54645c1924316d5f, 0x729f22451934063e, 0xa7675de5b111d262, 0xbd49f4fb9ed52be3, + 0xbabb549481ac64ce, 0x29f77467e02d4f8c, 0x2c7fb915e461d6b2, 0x2854b544b2ab3da3, + 0x52a817c81ed5eca0, 0xa747859e1e88ca60, 0x2fa81d34d023fbe3, 0xb9dfcd89947b98f3, + 0x4dc60be5ff88a7b6, 0xd5ddeb898454e293, 0x6f66adf6de5c4c9e, 0xc79e508ed3bba1d6, + 0x465e1a49940d8363, 0x8dfe3f6cccb8fd2f, 0xa9ee7869d85e52ac, 0x4ed79e1efad22402, + 0xb355182660c67f4e, 0xca4897da6df223eb, 0xf1c345157a656ee2, 0xb206e81c824f5ea7, + 0x29b8c040f071a234, 0xda174d83dd78a82e, 0xb5fa8a0b95ddf173, 0xdeee03b0a6a1d4b6, + 0xc1106005f8199f51, 0xbf4dc0cbd746b65c, 0x916d314a0a3f1507, 0x5520e7bd2e720374, + 0x9d5ae0058396f203, 0x887387852c63c969, 0xe5ab872c3ef90004, 0xd8d5fb35585f1928, + 0x74dfdb82146c69da, 0x6751b673d3225d6f, 0xf2ac98801b51d515, 0x01bf64b441ad3cd9, + 0x6f1a90518be70bdd, 0x81937c5c9fbc78e4, 0x6b6b66a9c322c6d2, 0x5923d45d78f2b1f6, + 0x71a153dea87ee760, 0x7633cf6769c86aa0, 0x2ffe0c18a2f71d3b, 0xf141d6ff24794911, + 0x606bc90e3daa0cd6, 0x70c6b3e8e41912e1, 0x184d898657e98393, 0x98a3798770e1d251, + 0x98acb0a3f9ffbccf, 0x9a7d28091c1a6565, 0x4f58611755cf196c, 0x3d3c0d93dd24d551, + 0x696cdca52f629ad5, 0xdb92ef6a360779db, 0xe55fbb8b3e05d929, 0xfeb5de5e075d1ef7, + 0x5082480214462f50, 0x8fb42d9f5f8f7f6c, 0xad816d33e83722e4, 0x299ac652f5c6dfd4, + 0xc09f941425e8673a, 0x4a1a70417629ed0d, 0xc06d6f2088feebbb, 0x16e62194b0edcc1a, + 0x9ff09309d5927e98, 0x5dfc6122fb7e6e3b, 0x1323ea44c789a8f2, 0x03d23b37b7f4103b, + 0x7ec3772172fed47a, 0x661df689e073abae, 0xdfa436d5db06a55e, 0xa10c8dd313c66ffe, + 0x93d7596342ba47a4, 0x53ba9f97113c8fe9, 0x608a5562d2fef37d, 0x4a2910ff78c914cf, + 0x6f503f67fb72d363, 0xaddfb8f733b41f23, 0x43a136d5eb1d9e31, 0xdbb9094cc9208ed7, + 0xd521786507fc7464, 0x1d8c66346a280b77, 0xa6299b261217f3d6, 0x8b8e5e6bc1bf7b51, + 0xf10c90ec08eb37cb, 0xc710dc8bc2e454fd, 0xae6e231db40bd41d, 0x4abd666261b4658b, + 0x4f4df38a427b71aa, 0x15db07f309b2aced, 0x8b2621e212752172, 0x331df8b78e724176, + 0x7bd6d185c7ab30c1, 0x6c0508c3eb628f4e, 0x3c9091ebe141ef39, 0xc74218f8104a1bd3, + 0x82c41768a57cee94, 0xa872e76d1983054c, 0x4061ca7cc66b8a1f, 0x02775e41d1afadbb, + 0x9754414efe90675e, 0xdbb16d9430acee66, 0x97698c3898fb3ba1, 0xda5583297383a667, + 0x8caf8fcd27993c66, 0xaeb42ce539c12063, 0xb987751743316e92, 0x3ba61194a1b90e0a, + 0xd7c771b0594a75c7, 0x311cd3c95965a477, 0xb71fa9c317be67af, 0xbe3fe4cf49cfc4d0, + 0xdca3b5968c565d52, 0x2734760dcc663ca6, 0xf850f9f76ce89c6a, 0xda6de7879a382afc, + 0x8ea94bd2bfddaecc, 0xe2d109cc3194f01e, 0x13f51666b74a74bb, 0x5abb96cb14de095c, + 0x9778177974021c0b, 0xb1b31ed058d51815, 0xb7811e965cfcf017, 0x3ee104e5bc9e392a, + 0x4cc01b66eb138fae, 0x33e2569061ba01b2, 0x22671083924e1154, 0xeba6a9b2843a171c, + 0x97771401e7c383de, 0x03f119c6d32895ae, 0xd8cf9e1670f45c0f, 0x581bf7c4c827d53a, + 0x37929df9916e1d3e, 0x0d1cdbc872c54143, 0x4f5a0b0e957667fb, 0xa1f7ee131bdc9476, + 0xa99d5c7f2791c16a, 0x162df6f2ddf44229, 0x7f0a15723ee6b3e5, 0xb89f4d949a4c5a29, + 0x97cfee78f67d9d16, 0xbf95d34d502994a9, 0xf9043171bfa8c476, 0xafcbf7291a637b15, + 0xa44b9953bfc57766, 0x558889c7c822708d, 0xb1094c1c730da66a, 0xf741eed8519766d1, + 0x6c2c899a86b9f01e, 0x5bdb6a47098a63fb, 0x4a2fc524f9d01cb4, 0x391bfb85f7104bb6, + 0x0394ca7f694bfbc1, 0x2082d059e0222a21, 0x33096710a5f35f01, 0xbfa1f455b915dfc3, + 0x5d2213054b495c2c, 0xab47a5129c2706b9, 0xdcbbd5464ac34c37, 0x27988c6e5da28bef, + 0x4a911d95a831b1cc, 0x1dcf408e1d04631d, 0x9ae718519067cf9c, 0x866df4e1f5f2cce7, + 0xcea33a3eb7f4d7bf, 0xd38ef1feb64c1c46, 0x4f049175bf92b6b0, 0xce102b429ebfd959, + 0xb54b18f5ddc40a16, 0x72fc7511b987e566, 0x59f78f9e674cc0bf, 0x83b7892549cde1bc, + 0xaa4816154824aefb, 0x86009e4bad967cfc, 0x48b01b746ec74a62, 0xa62b949a5a9e1881, + 0x6774930b2885bd13, 0xfe90c343acc89e3a, 0xcf995e0de019327b, 0xf7d8fca81e039490, + 0xd9a8e72d5840b430, 0x85554058b69fd547, 0x521e0ebfa0d5cecf, 0xbfb087bdec1024c0, + 0x4e1624b38ad382c5, 0x7295b35c6d54d976, 0x6af2aab549212009, 0xdfbf0c79d082b7e7, + 0x150cad644f708045, 0xcee3efcdb73d8cc2, 0x58e41853c844023e, 0xb43e36eac83a359e, + 0x7f501ca545415131, 0xac0ec5593f4352cd, 0x1da892e6b2bf03f6, 0xed071367713f1687, + 0x03ee02fe7191b0b0, 0xbbeea80f84c0b7f9, 0x15489036a4c7502b, 0xc1b4cfd0a689f4e5, + 0x737c82ea8f986886, 0xc6c314dcfa6aa07e, 0x4404477fb3039e5d, 0x83bd77e5d0e6a2d7, + 0x35689dcaf811b4fd, 0x2c49607406d0e301, 0xa3cb22ce202e618f, 0xd4fa03c35e15cd3d, + 0xbef0315d95556403, 0x78aae6a13ae6c74a, 0xc18f1b0e98a32f5c, 0xc95644d4685abdd0, + 0xd173dc63f67333b1, 0x4ddf840e77184811, 0x41766b763dcfc03d, 0xef2d5b5dc6287ac6, + 0xce131e09945630fd, 0x45d8b4f64a074ff0, 0x9db9b492858a73e2, 0x8a18661007eed33c, + 0x3c13bf69d0129ab0, 0x5aa172168859d905, 0x6f9ae89e7ffd2fa7, 0x68489ac0e049cb5a, + 0xa08f58469ac6f6ab, 0x1205233c4fff0b0c, 0x518d8c2f60e72b9b, 0x3bbcc200c202c7be, + 0x185d7e1843bf49fe, 0x3f3c410fb8af9350, 0xa8268036cff1d81a, 0xb8474f46cfbc6b8c, + 0xdeff0d2828966f89, 0x8b696bcfdbfef8d4, 0x27ca60bdbe31dbce, 0xc98de7283e071089, + 0xeda065307f8c59c0, 0x083809b1ca74fb30, 0xa9ec33b810f54806, 0xe42f82f83e602003, + 0x2ad61666d7a323f0, 0x16276307cf987737, 0x43605ec58cce8bbc, 0xc9d1b6f2fab5b074, + 0x98cfbb789f690a76, 0xed7f9aa0793b8073, 0x838a8eb62319c1ee, 0xdbe1d3c0c7df14c7, + 0xcd2d9fb60576d36d, 0xa3219929a3f84c31, 0x9bf273f053e76922, 0xbd6da3f1cc3c00a6, + 0x1d9693ef2722001d, 0xf88991358f3e38af, 0xd69ce63a779a7a38, 0xd56e3859c923fe4a, + 0xcc908f819f7c94bd, 0x392e225ad433cc70, 0x19a2cc2d5bf7b419, 0x65ae962c83ec4530, + 0xd3c62b59d6ce908f, 0xe54a64a39155e773, 0x4992759134b76db5, 0xf47971a612e7d0a3, + 0xb31a2bc4dd4f36ee, 0xfc3f147d357cb36c, 0xf59c6e329735cdab, 0x6b948f479535add1, + 0x75f8136c448a5b4e, 0x2d24a08c87a5e25d, 0x5db4e1b6da209eb1, 0xf0b61946741d8480, + 0x80301c91820dc0da, 0x34ce9d4fce2b3142, 0x0c79eb766e38320b, 0xc84d59f5d9153064, + 0xf704522f67df3255, 0xfdb28ed3e5eeb5e4, 0x11e52dd58a9f8b89, 0x5f06352b79f16867, + 0xcb3624a0a073b527, 0x0882a16d3019e395, 0x1a045f7a9ab99f83, 0x08bb5ce34028de6b, + 0x58c7439f9c12ce5a, 0xfc4a47ac96f98221, 0xb993b660a80bef06, 0xe986f25392855a9a, + 0x91e97efaef4ee77e, 0x339e3969d4df25b3, 0x6541b68f14e67aac, 0xaa576612d21c6235, + 0x909602d9a39a63c5, 0x3970f6c236df54f6, 0x7ed39295d15c858a, 0x8a36bfa9541078d4, + 0xbab433f16cd9ec51, 0xa3ee596446c059c9, 0x6001622b3db480cc, 0xb377fdd5ec92c01a, + 0xdb999a15aa758978, 0x66f97bb674f8069f, 0x0b69e28eee2aa7aa, 0x366587b5baa8a836, + 0x4f55bfdc9e03fad2, 0xe64aa89f664c6e9a, 0x900094edefc2dc83, 0xa752531dea2e55cb, + 0xde90b931990c3faf, 0xf2c88fc61241733c, 0xfbaed1b4f8cae927, 0xa4fc7a08ba1ac7e7, + 0x57c4b52b1532605b, 0xdd6d151d93420ace, 0x5094b2ab2ea36af8, 0x1cab5493ffaf08c1, + 0xb5f57f5a322f3bec, 0xfb00121c0e86e0c9, 0xf398f1ea352e6a23, 0x54145f197c95b418, + 0x1805a2c0d74e1c2d, 0xf8fd3a7e58cd8408, 0x5ee83d3381ac2202, 0x946855c0eae16a3c, + 0x128d8482e701c84c, 0xd71570e66ede12ce, 0xbc4c8075b5e44e6c, 0x9d1dd08ca1575940, + 0xe56fe27c8de09450, 0x2a1da8c15d9d971c, 0x143d415f2aede9d4, 0xe1bac1dae2b9189c, + 0x5ad7b29c6f7a4853, 0xb9ba71265253858b, 0x339105d5cc13b190, 0xfc8f69baa4fe2f7f, + 0xf871bd72a74a7e26, 0xc59be755aebe6343, 0xb1eb67f9d751c90e, 0xd816671c3c833cd9, + 0x69923c6d42b27b34, 0xf2afe5864c582b82, 0x9ea4ab8ca9addb06, 0xca8a33a96308d88e, + 0x9aaa39d49ed7927f, 0xd7fdc6e094ebb325, 0xe6e63e16a1014974, 0x6f2932f4da08e002, + 0x9a184908852f8495, 0xd087a2c0abba2d1b, 0x898b3675112a9259, 0x68ae771d493ee36d, + 0xaa10abaf62acd23c, 0xc253174ef5844ec2, 0xe058f1c95fb5551f, 0xcfa1c4dfe5a1bb4c, + 0xfddd03b28ab83808, 0xb42a2842345f5fc2, 0x6bfcaf3d7e2be9c5, 0x6a52542e7cec0502, + 0x08bc4bb0f58ac762, 0x108d462884add97b, 0xe0b21aadacc6d5ed, 0x1410c20b566b9c69, + 0x61ea45520230396c, 0x748f100c73dc1836, 0xb33bff810e1566b2, 0xabbc97e0b061d86b, + 0x61a3fd66f19af4b0, 0x431574cd597ea6b4, 0xc7c526fe183b72fd, 0x872facb8e070d346, + 0x29515670c32659ec, 0xd5e319a730ab1253, 0x822a0aa4acd3967f, 0xdc1c6d57500b15b5, + 0x430c440a1a8f0da6, 0xaa2ea0228f03334c, 0xd291c3442b39ef2b, 0xb5a590f4a3696316, + 0x3c8ee9586b63e23f, 0x6f66c6ee971eac36, 0xc386af2c79dfbe92, 0x052a5eb203f8e979, + 0xe08986f8cf8d712c, 0x0e7312c9ce83ef79, 0x4685715de68b9943, 0xcba54fd096d4fdfa, + 0xb114c600cddf6ca7, 0xec802fe022ef290e, 0x48cc89b96baf1405, 0x856fe3c273fd1ddc, + 0xc3f5a1345ea30221, 0xc79ddcf9ad98b32a, 0x9ef0b2ec67942c37, 0x5db6b9bf62d9ee39, + 0x18cf423fc2f183e4, 0xb42c0d925790b338, 0x909344c530b0511e, 0x2c31606eae65b05b, + 0x41b5f0d576434d83, 0x9d6d9fe0d8c91244, 0xd4f9b9d65849396b, 0x626a7654941810a6, + 0xf5ae2ba734ecd9b0, 0xe2fcc14528bbf66f, 0x36271a15ca6ac7f9, 0xb7caf9f39f1e08b1, + 0x7ce5080dcdfacb7d, 0x22d2ae93967675e0, 0x0b6b87f08c53d821, 0x9191eb2d67a3f775, + 0x5d81b8c604d5ed21, 0x8bec6abef22af58e, 0x17d9985759a7d1e7, 0x656ab558c584b803, + 0xf4cf334888ebed3a, 0x3aa42fc704339810, 0x3f9b1d479e7ea337, 0x8d0dd1ca03868cf9, + 0xaf641e168602d056, 0xbf972c5a2d378aad, 0x8c0a1664714ff859, 0x74f370e0a6185f27, + 0xc279189ba1d0391e, 0x8b1322fd07cc0709, 0xc6d4bf2fceeae1a5, 0x7f829806215af5a6, + 0x83ea1a5ce8fd47fe, 0x4338e0d7f07ccde6, 0xd42255ac454211e0, 0x5320b4fc47b37160, + 0x47ebb541b657d84f, 0x37c6b79f9bd885cb, 0x39542d935cf8dce1, 0xed3a4f960f08c63d, + 0xd2d10d23beac7d25, 0xff29153fa8e97250, 0x8f989cfde05f90a9, 0x3fdf0313b2ed64a8, + 0x48b1f8649cd4dbc6, 0xd98004fdd75ece8f, 0x693da7645b3d7752, 0x746ac6f281fa59b2, + 0x84648b7533b1d334, 0x27fe4619f11db66f, 0xaab9849cc1ecd61b, 0xb59264ef426064c9, + 0xefa788ebe8c1b7c2, 0x7f4e4aa02d827dce, 0x63e7dafadfb4e68c, 0x6f2fa99cab3b7756, + 0x093b73eba6d45fe8, 0x6bdb627f072ccde6, 0x158289e847bf3409, 0xcbeb4eb2144bf165, + 0xc096eb59e7176d4d, 0xa452efad7c48b107, 0x470c35fabc02da28, 0x711fe80571ff0583, + 0x9d4fbf024490f208, 0xcfe0def981b77204, 0xbc46b43161a37c75, 0x6f4955a97c62b4ba, + 0x67f99ef9e9c66453, 0x068663152bf57dbf, 0x59d2852af5ce7dda, 0x15ba63b14729a5f3, + 0x16f025fd5088ef73, 0x0f5d55c4126f2ee7, 0x2be56f25e364a8bd, 0x1ea53ece05bbef1c, + 0xcdbc8de2f35744fc, 0x7972ddc5943c0bed, 0xfebd6793ccb1615f, 0x9f855182a99651d4, + 0x37a3b078098483af, 0x670195f11bc92f6f, 0xc864d91c2ea75977, 0x909a3490db009aa0, + 0xa776b75c697b4f35, 0x3697c858549e1c78, 0x70b8d1f10f4433b7, 0xefe112f7cf636588, + 0xe0a0557c1566ac67, 0x4283d26df4eabfb9, 0x2c1ece6be1850f7a, 0x505ff9c375415500, + 0x6fb7be86432b5297, 0x1ef404984fd4bf52, 0x7bc081ab7e098c2f, 0x4cf4733b316baf7c, + 0xc3e14c983f08d70d, 0x180d5d6a5486ed7a, 0x4bbdb7924111dba4, 0x163552b72c662ca6, + 0x56c9fbbcac602d99, 0xab56141d66d078df, 0xc43941b6329faa15, 0x38c0dda0d241fdec, + 0xd9e7d8bdbb7a25f2, 0xe1d5c57102c129b5, 0x5abedf6daf898df3, 0xf951766570b8b7e0, + 0xeb44617c5aa319a1, 0x7c8b1c48a42ba6a2, 0x3575922d1983744a, 0x90a15e63f8859ce3, + 0x0ffc0c9a615f5fbc, 0x4d3d6fc9407943c2, 0x65990f8bd8b03fe8, 0xf4099781f6524543, + 0x5c1727b84cf9d98e, 0x40edff69dd1b3036, 0x49d2393afd383ffb, 0x5257f27e809a9d8e, + 0xa4676d56c9ab12fc, 0xf72d2b8bb1b84b22, 0x40d432fa00d31869, 0xeaf742c1f653dfbf, + 0x382e263397295694, 0x4a97b71b0c3cb02b, 0x3f7f28b621da4c7c, 0x1d5d0b35acc37a74, + 0x1008e34ad7b3589e, 0x2a0684134dd320c5, 0x3699d57b560bb633, 0x600e70cb36e573ee, + 0x93565693d204b289, 0x81158c61693e677d, 0x7c7df1e72ff3ff51, 0x9a2f32101049b427, + 0x3fe9b312d26241aa, 0x14d11bd76bfc0102, 0xa3c6f40d1a6d05ab, 0x9cedd63eb4e1aeba, + 0x7ba51527a389f40f, 0x9b56f7492d1928e1, 0xbe98619d8142627d, 0x4a59f61439eb01e7, + 0xea0b445908c7a153, 0xd220210c666138df, 0x79d68ea400996442, 0xd0387186cc468759, + 0x97203bc1fed798a2, 0x2b71ea290942c128, 0x4002bb079034f2ce, 0x4829b3d8ce0091fd, + 0x8ffa064bfff0bb72, 0x80dd54ef9c1cbb92, 0xef934c45b23cd0db, 0xb3065f98fc7aa1a6, + 0x79aa883c2c4cf989, 0x0b1f281ee7dc2311, 0xc81d492554c3c0d6, 0x147108c737f00fe5, + 0xc2e39e19401e716f, 0x55c5bf20c72e8fe1, 0xe7cb803f6dd8c54a, 0x05b5b9a9aabdd52d, + 0xb543eddf0295d1d7, 0x8c483ace1f3d62f4, 0xb8af82ec97f8c6a5, 0xa3ed7ca97bd2d462, + 0xa200091a2b3c441b, 0xb7951aa443460f06, 0x0dddc5191280b1e1, 0xeda3a94fab249fb4, + 0xa5313c5e4fa3f278, 0x273e7fc64c568053, 0x0293bbf9ca4a208f, 0x8beb212c6580998d, + 0x2f38c061131caef5, 0x75ce1942cf6234bb, 0x3ae9ad33b53817fe, 0xb8a0d8f820bbb7c7, + 0x1eebe62a083b4177, 0xf5df93554ec4c065, 0xa9670e88e2ed8bf4, 0x52cd4ca465e3a1d9, + 0x65f3ad88fb62e131, 0xf6aa413892942cf1, 0xf3f87ef79d466e9e, 0x5d1a2f2130270cbe, + 0x26758076578e7bbe, 0x8e07824fbbbd19ee, 0x0ea72eb7f22e1f28, 0x719e48f5a5052dd0, + 0x534c78cf20c015e2, 0x0bec9d43b33042a9, 0x1bb9f25fd3e67866, 0x129806756b068737, + 0xad843a6b86a7dde0, 0xea5a72059adf7c00, 0x12834ec13423cb05, 0x7bd07bb6266b69bb, + 0x814e1962f6fbae04, 0x93f6fd8ceb51d8c7, 0x92309d88be07b2be, 0xb277d7f8d8768e36, + 0xf9ed8ab32ee6aa8c, 0xabff1260dec23d7e, 0xd751a13757709f17, 0x4d0b15868092e21c, + 0x6a8b8e130c099ec7, 0x5154c2ac8035dda8, 0x2e9ce6ca625fd4c8, 0x20f9c14f2b5341d3, + 0xdfd00390e363fc31, 0xa3bff3f27fcaa882, 0x8afa12e46cea34eb, 0x6d17162cd88fa97d, + 0x46dd1382ec452d84, 0xdd1108b44f660d23, 0x1781a147c7f95f15, 0x81d78c46edc0068c, + 0x2d2e4081f36be050, 0x5b9100ba921f30e7, 0x78eb71f06364c184, 0xcc4030d6bc56e93d, + 0x0d98def85ffc5265, 0x252ae6111d7d718b, 0x34805a3fc6ea2aba, 0xaa40cbb314dbd620, + 0x5015e2cdb9cc8b6d, 0x67ce2287b14ba54d, 0xf9c01a091808107a, 0x4cd8841e1a9cf36f, + 0x9f32d7f32e26b8c4, 0xaddbb5b199cd439b, 0x784e97d804a700de, 0x45e5730f8eae3b46, + 0xd599a15bf5e00c64, 0x6209588210388596, 0x3e4456701ceb2ce8, 0xe41a1ee48e045b32, + 0xc4760085b5c767a9, 0xbace70a4f7c79c8f, 0x229bcd695ce7d27f, 0x366e974495ff877c, + 0xa739b99f1998d192, 0x92cba1444fd1c02f, 0x76bf4afdfbd17d25, 0x9bd27487d02def3e, + 0x0363ee035986a7f8, 0x50e60d1a77074e10, 0x96f974bdc3501c74, 0xa98ea128e1febf5d, + 0xf9b4a7fcc1ecd7a7, 0xb92e054908486aec, 0x588fefd4bc828f1b, 0xcdb443cc321a5f72, + 0xc2f81ce712497f02, 0x2d4bcdca207c96e1, 0x3a0c089cda89e09d, 0x1e236d130a953f4f, + 0xffcba29786d519d8, 0x54d354fe19326abf, 0x7f9ab7cc916018dc, 0xc1679b60b4ccc58a, + 0x82256a4a9155f8fd, 0x8de35c7c3c5e5d4a, 0xe04c46ce141bf8c6, 0xce735fad2ddfeb2f, + 0x08a29884a7e57c83, 0xead838a967b57a86, 0xe920a402a9d07cd5, 0x14fe988497d280ff, + 0x232c06de2bd97b99, 0x5f3da36554ad309b, 0xba6e4d6b0ab1a6ad, 0xaaf6ae4e71cddc26, + 0x1efa1def28c60d60, 0x5cace05e0d74175c, 0x1ff7cf004a23d3a3, 0x8b0e6346e885cf86, + 0x73c3841830b9d951, 0xa621ed616e0452e6, 0x96cfc73b8e22787f, 0xdb95bbb26003785c, + 0x35d183a832119df1, 0xa5bbfc582ed91496, 0x6a307b7b4644e1f2, 0x0b155a0a00ef83f1, + 0x6d6b1df25ab36ed2, 0xba7bcac2bab4059f, 0x9cc1756f9a61959e, 0x526f3e0567a55bdf, + 0xc628890258f3d625, 0x6cdcaec39e4ad5f9, 0x9f8747028056f003, 0x6d203230f0679e7e, + 0x276d80416e38bcba, 0x5fe0c0d21c67fcff, 0x3f1454a1afe20d7c, 0x6a89922a9bf58194, + 0x988fdd0c791d7d4e, 0x21542dc0e89dffc0, 0x95640e0804d9bd42, 0xd293313d73c36243, + 0xd1eb5d623816a2fb, 0x49fd83aede3c4bec, 0xd85efdd79590e04d, 0xfdfab13d5eac8650, + 0x094993dc42f2a545, 0x1e747349426bb19f, 0x334e033d6f60df7f, 0x9f8e4e3057f1247f, + 0x8f1d9fbd47768a9b, 0x3f1b7c050812a0e6, 0xfbd4503879404304, 0x28bdc7902af38c8d, + 0x915d4d73e319d378, 0x4828c458ff2a04e6, 0x0a0e207e2f6c88ef, 0x988bfcc1fadae1fb, + 0x257c02bf75a1cb95, 0x0581739bdf9c2ca5, 0xec82a097c043f402, 0xd6646c69a85212e1, + 0x9b79f56a7454b5b9, 0x8edbe557036ec6a5, 0xb999eb216eb41e15, 0x8b1abecb0bc4d2cb, + 0x46ab884895a3d549, 0x41e6b6ba02bae974, 0x173d6cf00f75c47a, 0x1ae3eeb76f868894, + 0xe72c574d18f2fa98, 0x161264b981ffc1b4, 0xae13b2a780181e14, 0x4a756d841e8b150e, + 0xc7306e678aa3237d, 0xb14601b94eb8b4aa, 0x5d0cac7cfe624945, 0xabbd0b0e4a8df71d, + 0x8a02109cc686e463, 0x7bed4cb0a554a2f2, 0x15ed7cfee9dd866a, 0xd39084344ff4efa8, + 0xcdab05ad641079e1, 0xa9e77164eb9874c2, 0xfc98cfbfb0f63e37, 0x9f3024825425b7cb, + 0xb393dd09e408fa74, 0xbfda28911e6ba757, 0x6cb292dc8ab30c74, 0x800cf9ccd2d1c3e6, + 0x19eb46b92686841a, 0x581a84678f2f0d70, 0x9869e4ffd3ab475f, 0xa325cf03a8359e62, + 0x0be5731491c6916d, 0xb2487e94fe1eae17, 0x13ae351ada4e10a7, 0x7e8574d323398582, + 0xeb2b0cddbe40162d, 0xf49d69374776f02e, 0x251c3da8988a7760, 0xd1de0ba881a00927, + 0x2526f1e0c75f2c1a, 0xb2425247bfd31eda, 0x1ae3f56acc0c962f, 0xc0089e83486deb4b, + 0x695089752ea874f9, 0xdc5ffe2766a018c5, 0x884332e9c9cffad7, 0xa16b9f2b6827be83, + 0x591a5f38d3ca8a7d, 0xf56691b745435e67, 0xa9a8b6b7e97c4d14, 0xc4d578bc81ff6005, + 0xe46d7321d39f76ab, 0x7e88e34bcb8b5695, 0x80a3578057dac824, 0x17677de38154b11b, + 0xd2a301b7ebba64f0, 0x332beb69593b7a1c, 0xa0865c6496e3f53c, 0x552728145e6d3bf1, + 0x570f5d76348c1b0b, 0xf846416a4fe11d8f, 0x8f7c1d0330f56a0a, 0xf19cfba6bfa1d5ea, + 0xa29eec9e9640ba7b, 0x8c6200b98529728b, 0xfb4c1f66decddaed, 0x263a4c57adf58de7, + 0x87555120e2bc958c, 0xfe166d51cb6c4f77, 0x0f62cb402f8829ea, 0xeba42d427bb7e847, + 0x3494d9a11cbfdb1f, 0xf0406b3460b12d21, 0x7e9fbf2a36def8a1, 0x29bc090be9420f39, + 0x41e98e0417a91996, 0x0bc0d14e0d6097f8, 0x20c7daa66c81f80f, 0xebcbced18f806cca, + 0xfb4c1d8d33b0f075, 0x3bae4461c95eb9d7, 0x37e0748642f92d8b, 0xdda9442a59743ba9, + 0xa97a06d3e5f19267, 0xed6347f1fb581ad9, 0x0048e7eebc224cb5, 0xfec026e085a7e955, + 0x0cf80e32977589d1, 0xcab7287374af694f, 0xa22ae317c2d60243, 0x9eae39215e8735e8, + 0xf851968ac74d6986, 0x8cfa77cc1388e514, 0x34a7d3a94edf8cd4, 0x081029dd1605d572, + 0xc359d243cdf3328a, 0xb19c733864084207, 0x3c4a1c0555d3a92f, 0xe904abb0419d0f4a, + 0x4e9768d735e087f5, 0x731610d8ebbedd11, 0xd235d9064f5a96d8, 0x3f6a55a382e19a8b, + 0x086797ebf703b1d5, 0xd0e861affe695688, 0xf6256b2f2ef418b1, 0x94f703276dfae1ea, + 0xa4b406eb29ef47e8, 0x6e084cbbff234678, 0x2b2715b11c1516bb, 0x771ec0fb02d9054f, + 0x9455da5bd449dd65, 0x6273e035afba263f, 0x4ce959fbbc170d97, 0x51fb6c20f2ddf20a, + 0xf6e36e7ff9fb1379, 0xc0d79c0647e31355, 0x6dfdfb649b0e568c, 0x6c12d30e7dfe9ca7, + 0x4715bfcee76b9161, 0xc05ac23ea94d7204, 0xe39ba750bf41b7c8, 0x41f829dc2404e528, + 0x0db8c1fabe47fe40, 0xb9b66a2bfd3e3a9d, 0xd72a79a6b20e5604, 0xf81936d30dc051b7, + 0x3fd94dae0fbcc1d9, 0x9a3464de87d11e54, 0x4243a1dc2d22f602, 0x0c59871503b45ab2, + 0x878aeb23e5638317, 0x5ad4d623499ddc68, 0xdb73e8086660a411, 0xa8deeecdd65a0439, + 0x8b50bd4678e98720, 0xd396a0edf277aea4, 0xfe9dbb444dc30f71, 0xb120a86bdcbd60f6, + 0x7ba5d7608cc6d70b, 0x7f4e541c2d5f1608, 0x5dcd52aeb586bf22, 0x8a01f048b0f1c7ca, + 0x5d01dec5f13874b8, 0x33d8f4945b8d12f4, 0x907d0deb271446c8, 0x2958f10ed33c2f86, + 0xc252c3f8106f046a, 0x20e61cae73996492, 0x78c6630e2e262816, 0xfbfe65e000aa1b0d, + 0x97e9e884bdd47141, 0xf6a8f717dab16ce5, 0xb1dd3f2f52e04539, 0xae40b48e3544b724, + 0x2d5884bfed904926, 0xe63dfdc0acb6ffd7, 0xd404c2abc6c91fa3, 0x3868467a529e43a5, + 0x13a4bee482497153, 0x6378dad607b5c657, 0x033aa9ed88ef8bd5, 0xa59d62d71dee9ec4, + 0xbfdbb309378d5343, 0xaf84483a46289ab0, 0xb05c320187922fc3, 0x22b76e4f7d2b6621, + 0x3cbb43bf565ccb88, 0xfbe1301436b65613, 0xa6d93098c591d6a4, 0x260613f99923f95d, + 0x43f68aef5b308127, 0x8e3cf233603746d6, 0x0c06820a7fb4e02f, 0xe14144cc2ee0ee51, + 0xfc96d00191e4aa6f, 0xf78d9d41f812da43, 0x8ed96d94b2a70090, 0x4b3eb72d0a698ec7, + 0x4c3458c9000031c4, 0x4b6bf7a07284d93d, 0xee606586de67803c, 0x4558ba515b6bf076, + 0x40238b921b756c0f, 0x08636a403d533a12, 0x5f50eadfe50274a5, 0xf244552c897a3c89, + 0x95c3d7a1428204ae, 0xd72614cf3d34fcc7, 0x231aecf96e3c96e4, 0xfdb487fe8de365b1, + 0x0fb06be1dfca0632, 0x09219787e18ce5ba, 0xbfee26916ae30bfa, 0xe13554d7faf99f8f, + 0x82fd8e4dd45a8531, 0x2d0fdf345aa85d46, 0xcda1342ec4173820, 0x4d9ecf51fc83fe80, + 0xc3c4ae9f2827d351, 0x504cd20a0d097754, 0x8fb4e3905eed5435, 0x86565f61010f699c, + 0xbfd0c4e53f88575c, 0xaff209f9955b55df, 0xd2ea2b05c672a186, 0xe208c086bc865942, + 0xfd991a2a9ecbba5b, 0x87bd5cb9cb50d5d8, 0x988359e2f322c826, 0xf4642b3cdd1d3156, + 0xc95709a538afeefa, 0x33aa117ee04b21b3, 0x895a4aa2e1072ad3, 0x7163ca6f2b0661a5, + 0xe3562211332502cb, 0xaa7f033a994be37d, 0x1b918388d13492f3, 0xf8984576bba7c0a7, + 0xfd815a1327f232b2, 0x8f83d03953292c09, 0x2c3725732ca9aa3c, 0xf4d4e427a8096a28, + 0xb7b05a36b1ff9fbb, 0xf2286e083c618f92, 0x1a9a5b30bfb2a2b9, 0x2c40faf1a1226bd0, + 0xc87e2c0a8bf71f63, 0x9d5c98a958797b2a, 0xc4a30d5d101aa1ad, 0xf9dea4cc71073ee0, + 0xe825841bb890e29e, 0x392500642cbfa549, 0xf0ba0c7604ce38d2, 0x953cb89cb8dfdc11, + 0xebcf1d092022e4ad, 0x22e990fd5cfdb481, 0x94113a8b4edf23fd, 0xa5dbefad1a3da796, + 0xa43d3a3233c361c8, 0x23998edb7ed62773, 0x362e89c4f4618f67, 0xfc4329fe6a027c06, + 0xfc50152466d302fb, 0x7f902f9f9f07b9ae, 0xed6a4cbe42a53a0f, 0x54e00a6e97a2319f, + 0xab12abe9d036e730, 0x713286425352350c, 0x359b23ba08c18a8e, 0xc7d0b5e46b4e58d1, + 0xa5bf74b56edfbc9c, 0xf9f982fc5aa95860, 0xcc23a39c01e694af, 0x6ff29156c128743e, + 0xf33d71d07b375d6e, 0xdb595aa83390c13c, 0xe35da7574f0aa3d2, 0x0291829f94abae0f, + 0xd5c0e19cd80bced2, 0xe9ddfc8ce8f595f6, 0x500b94a630688a17, 0xd427108208a9cb09, + 0xaba674fc9abb6014, 0x79fba67ca938a2aa, 0x062cefc6f6ed0fd3, 0x5d26f4ee250cbd7d, + 0xd2edf3266aa0e9ce, 0xb1d0679e227a552c, 0xb45d8d6b363d0e7f, 0x666ad35982bc0452, + 0xe7f427e2f2469769, 0x976987f17ce8f2b9, 0x0f6b01ff8d9da2bd, 0xc6bd42964de88659, + 0x27104ee45a7ce2d6, 0x2af7abc8cb24956d, 0xfab2d53731993674, 0x8ba7519b73de9a6f, + 0xa76fa8bbb1b92cfe, 0x4d6568fc604df256, 0xd93fe94f7b7748ce, 0xbeccad63b1543c34, + 0xd85a64cfd686a511, 0x4bf6994801a6da89, 0x4325374f7ef6656f, 0xd38ff455bf316f22, + 0x8613ecb8d6b05c50, 0x73c262cb6a92eb5b, 0x15904daad10af77d, 0x945286b761e54941, + 0xa68e03cda62e8b07, 0x6b2b256d6d667396, 0x03e630a2525bbd72, 0x0f55826b38d6885f, + 0x8281f02ddb4b4659, 0x21e5a221f0b61cc6, 0x3f48470bd662543a, 0x4e1704f44444fc63, + 0x158fddb513f7d2ce, 0x0fa121f41998da98, 0x24738ad3ed5ff91e, 0x7de86659ad0bede7, + 0xd06fd4711bc7f9bf, 0xa1d074ad36b4f4c9, 0x107630e6cad92dd6, 0xbcd990cd89b84827, + 0x066a0641383552f7, 0xb24c3e0d691f3f3e, 0x4f48aeafbd1342c0, 0x22a32bc19303cedd, + 0xce1cbcb4f20c2a98, 0x885ce40b163cb050, 0x6df486865c97e562, 0xe59c4ab5318f231c, + 0x1ff82d01f235ef77, 0x446237491d021b76, 0xf4696bc1ee8e052c, 0xa63e045bb3c2a016, + 0xa64ca533656880db, 0xd992c692f222ee87, 0x5d294cd30cf4ea20, 0x1af689e0fc98d344, + 0xf58cb5d4ee86e5be, 0x29806654d2d42da2, 0xf5cc0c79765f1c10, 0xf19b19f26bd2c242, + 0xe23a77dfde0a1377, 0x120d5d238ee2f9fb, 0x4c6bb1b7cc8beefc, 0xf60dc61be225f7bd, + 0x98f7b3ee3728182f, 0x2c7dee764021e2d3, 0xcf9b7adb5f746c39, 0xc4eb2a7139f9d90f, + 0x30882bfeb38ea335, 0x01f1cf64fc4e2772, 0xd96a0ab184fd53b6, 0x7a2a8bb8badaa8af, + 0x9c5e3b15e95f9a1b, 0x2d75bfa54fd95422, 0x4a08ba8cb2b436c2, 0xc628a7496bd18beb, + 0x8b4ebf3bcdafb81f, 0x0b76c770f7b691a8, 0x2cfc3d92c6695345, 0x85ef308bc9f89e33, + 0x07e4ceda8d40d737, 0x5f76242d10cd3f3f, 0xf6ed74931e7cc998, 0xa39aa5ac3a25f686, + 0x1f0cf42decf20732, 0xd88f8e3de4414814, 0x3227b21f254676f3, 0xd8796c528b4c5681, + 0x77db4714593ae219, 0x950fd9af6e11507f, 0x5531a4ed6de8e1be, 0xfd557a831ecfdac3, + 0xc966fc4867138a39, 0xd470240d6af46951, 0x15eed74ffd98e899, 0x5fa0557c884720b3, + 0x92e7756e5c143f44, 0x629f09470db890ab, 0x2b4be37fff93b482, 0x03fec57b8de254dc, + 0x26a83dd0595452fa, 0x89c9326c2fe44590, 0xbe9af785b02cca55, 0xd47bc668dd69bb5a, + 0x4c0ec09638a54c40, 0x4211a6a43d70d0b6, 0x140f766e4567a0bd, 0xb559c0ea5ef87b99, + 0xcbe638e4a765fa00, 0x6fa4df7133f21b8c, 0xc4e974f050acc440, 0x53e8a9bcfd868513, + 0x590b8dfc2bfc6b13, 0x4414f990baf099aa, 0x404985c77d3ca692, 0xbdf3c1203a3510e7, + 0xef699f62dae5de45, 0xfad0ed792dc6a5cd, 0x50ccddf6401fe12c, 0xe0b7c8c8cd526df8, + 0x757703ca8caeecef, 0x05a6a61e51cddc85, 0x3093ee2174053b93, 0xe6ff6a6555f43433, + 0x70b242f83bce0a5e, 0xd429e4a699bb6b42, 0xa4ece1f507bd6181, 0xd9efe01cf453f046, + 0xf96fdd1068c01bd5, 0x9d003f6a34e338bf, 0x0ea8a5ce57b1ed4b, 0x7a38f8a1dc7b2218, + 0xbbee019a48049eee, 0x7c6f4aa6720aa908, 0xa23e8849060f939d, 0xbccbeb38c3de88d6, + 0x696e58cb348f2fbf, 0x18fe8a848ae5a532, 0xa4f1f72bd77f0d86, 0x1b4ed6b08f877cb5, + 0xefb8fad3f04aa24f, 0xe6c23841ec01bc8e, 0x0358d076d2ed0520, 0xa7cfc0940d94f7de, + 0x56a27ec0484bffb9, 0x13d622b73d0d70e2, 0x40707216cd97e8e1, 0xf5ef41f52eac5605, + 0x1504eb2ec7976f2a, 0x7498a370267dc0cf, 0x981ec4753123c28a, 0x4a36a5eaeefec56e, + 0x668e5392f4e28d70, 0x1ac7002e137e3908, 0xd014e80473387bd2, 0xf429b32fff7c197c, + 0xd06d479c8870d8c3, 0x5c87c08cba3eb14a, 0xe199092c4bc604eb, 0x9e0a7c9338e25f2d, + 0x9ee1429d4d92c145, 0x84137eaacafa7a14, 0x9c12ea935af6a60c, 0xf02a35a6dcab69c2, + 0x389836696d8b44a2, 0xc8a88ae6887dd62a, 0xbf00e738b934b5f9, 0xbca43c2b3a76c608, + 0x68ce9201508e385e, 0x101031fd5f3c20d6, 0xdbea723f81939d2d, 0xb8c792fbac8d8028, + 0xbd991a9ad71d6fe7, 0xc3180da6243a78db, 0x7bf38b35afab17fd, 0xcd869686c12b9ede, + 0x126a720f79f4081a, 0x9fab19cf026b01ef, 0xbd1cfa4c0a5d896b, 0x9cf88e019bf30173, + 0x1f692d4445a89665, 0xac1585683f863c92, 0x99c074609c8c051a, 0x950ea6bc65e6e416, + 0x90635bd043d57beb, 0x9d13fd7b3c63ffe2, 0xd4a555939b00d03e, 0xb4c0c567ea072cc5, + 0xfaa3c632849b7fe0, 0xdf9da469c7bc8321, 0x94b29edf7e1e296e, 0xaa50a1ed34592b13, + 0x78894331ca9e2f86, 0xe6771a420cd188d9, 0x44acddebc0855dab, 0xc7989b3473730065, + 0x72af8cef7600b8d6, 0xc6670e23cac76768, 0x6afbbc70a9ba9d2c, 0xf2c29ab4eca28ce2, + 0xfc7843facf509dd4, 0x92bd2b64dd601ccd, 0x88954c3207b70848, 0x2caf5438614466b0, + 0x8ce14cb8d94af7d8, 0xfafb9bdd3004a1d3, 0x742ed44e1c099b40, 0xbcb28f0462a98b24, + 0xece851f92cfb28c9, 0x6af702197eae7ea7, 0xf05284a7881358f2, 0x5ffaa1ec67ff59a3, + 0x4622284f6607c08a, 0xdf0c10735c3077d2, 0x47f26dd39bc52266, 0xce5eea3a84308012, + 0x203638fff30b3f45, 0xab67ef64112fff6e, 0x07e71ec03ba44faa, 0x38200d6f68be6b26, + 0xf78de414d2aa86b8, 0x5638894ccb5e2e67, 0xf14bb932e3a3c894, 0x6732a756e70fb2b3, + 0x649e67ea44b1e6b2, 0x42e471ba60bacf31, 0xc00086e02e18f194, 0xa0d6fa5a66d508d1, + 0x950879943e839b27, 0x3a2e94a44603963c, 0xecdb5067d6ac6b83, 0x1ebf2cedc26e361e, + 0xd8f04b89355ccaf6, 0x72058ba72aed16c3, 0x8ca5377c0603aa5d, 0xf5b356ff277b9499, + 0xccf24d0c9cfa7bcc, 0x636c422258a1e9e6, 0xee1cbbb7a3bc5d03, 0x97b79828aecee94b, + 0xc83f35f9d5aab418, 0xfafe35b83d90a1b3, 0xe9293244b9b203e9, 0x3863f148df6f9d77, + 0x8640c9537b787c2e, 0xc5c272812cbf57a8, 0x4592c0deaa544589, 0x65d7761d2f5a95a0, + 0xf506032b1d974808, 0x8ece539ecfa8d692, 0x825a0ec78698714c, 0xfe34e841355fe0a1, + 0xe1a4bc08b5aeedea, 0x61fb11a986cfa642, 0xc78df063156ed08b, 0xe4316c61c0f7419b, + 0x94fde2539985ae18, 0x2527f9ac04dc49e8, 0x4a0fffd55dee63ef, 0x1c445ee2054c438c, + 0x678f93b86a322876, 0x6393970a4bd462fe, 0x7b1f376aca979630, 0xd551dd61120bcc11, + 0xfb3caa8be7478902, 0xc9d138416c25bfbb, 0xbf1ce96c11bfb19b, 0x86766dfa170be6e0, + 0x29d158c4c9a725cd, 0x07ce8d2a727b0eae, 0x838b9537931e4adf, 0xf525290bcb3229b5, + 0x0007a289ca61fb35, 0x3b7962ef6a162ba3, 0xbf92ae436d55ba93, 0x478e257a24b8acf6, + 0x3c732d31cacfa014, 0x9be9e85b32ea867d, 0xf2290937a2d61bfb, 0xfa524df6bbdaf3b6, + 0xaa8e0ae5e5893c11, 0x854c633ee3d6bf73, 0x5c04b295f48de69b, 0x81ac467bdb768c02, + 0xed7e41e3f797606d, 0x4667475d8757f000, 0x4afc108d8af07dc4, 0x8daaee376fc40828, + 0x08c16bd16019293f, 0x95f1aa2a28bcf37a, 0xd3ee6c72241957e7, 0x3d12752087db1dab, + 0x0b89a07e89a30481, 0xfea5b9d9f777e733, 0x2c07d14b23cfbf83, 0x284349d2d50c3a08, + 0xa88767d969846393, 0xd8cd369f05a5ae05, 0x8684e79c0f7c6a93, 0x1f88ebb4b6ee9179, + 0x03c255310876fe85, 0xd442c6e9cd60f0d6, 0x0706b467d9c07d6e, 0x010a4442889adf88, + 0x0fe8ecb5110ce157, 0xd5c8b62e629a1fe1, 0xad70e97ed383c59e, 0x1f4e1c670897af9f, + 0xbf178e34f9e8ac70, 0x78382ae4abdd1341, 0x83ec86d1afeacf06, 0xe4a7cba03e902ba6, + 0x0c3484b9d9258174, 0x6a8d286e9050101d, 0x83b86c81ddfec840, 0x72387f3e3277f91c, + 0xbadd75730d723afc, 0x37d101ef2e81caa5, 0x8b10c02e33098950, 0xe6ac9e54e6c5fccc, + 0xb4cff2e97d24e1d6, 0x5e736e0763ef3ac9, 0xc8c6301c5b92f843, 0xda82f0ee968c0d02, + 0x9fded2098580ef6b, 0xdf8bb1924b849f81, 0x0488bdb1dd6ca3da, 0x6b200fcd1ce32bef, + 0x374ac3b50212b03a, 0xc12de6e38364499d, 0xc16619cbd1088cbb, 0xb0cb13fd873bc392, + 0xe8df456d650dfbc1, 0x7bc2041fede00437, 0xa24e6ffe3a5a216e, 0xb338a180f2da6a8f, + 0x9265138f5fec9e52, 0xb677672209dee73b, 0xf42b12736469c042, 0xb3a47450ab34af25, + 0xf741b25152e1632a, 0x61443720405922bc, 0x24991bdc2605bdc6, 0x0fc7682bb3aad669, + 0xf8caba191b7dc26e, 0xee4222b011292f1d, 0x3749a1349619c89f, 0x2261a98aabdac4e2, + 0x99c9bc8fd4f60e87, 0x254686c5b7969ad1, 0xda5305be3680a8e8, 0x267e986f6e237ec3, + 0x30810c2e9caa2b7a, 0x86c8349a8e7ed5f6, 0xb480e607df2e3f22, 0xefabcbb2a86bef44, + 0xef3926083baa3ccf, 0xc42feefdd9041037, 0x6f490977bd008b7d, 0x3cb1d8001d34f061, + 0x45f194c0f26f6e4f, 0xd0db70cfb5ce6a8d, 0xde1bdcf7c6349644, 0x643a181d8dc6550b, + 0xdfa2d557f50b0c92, 0x28e9b7b500bd7c39, 0x26cf6566595110eb, 0x8b43d54498056cf8, + 0x4eb351ec706dbc9d, 0x77f693ac39fd8c98, 0x63cdfd6e3b2fd027, 0xd3a0e1cfd0733280, + 0xa688846341b509a6, 0x880ff11ea7e0aadb, 0x140f4b7bfff86b1f, 0x46305047913ba35e, + 0x23dfa5fec199f953, 0xd8e86994439fde4d, 0xae0203df0807fa75, 0x68324fc6beabbe28, + 0x5def14d5ddf9fcc2, 0x3cbc9bf0c28a66a0, 0x5dd3a2695d4ba855, 0x21e39a77dc28a0ec, + 0x0bb1c6aaa0782f3a, 0x3796285be4c80121, 0x7265421b2aa8ba42, 0x2f303bd6672b7aea, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x92ec9fcbc11d186f, 0xa82acf836455f395, 0x141a0d74be00af09, 0xee6dffb61a7255a2, + 0x6ea0ffd5c784268c, 0x0d75990fb8f5dd63, 0xeba0e4eec5f89aa0, 0x98d85a17a1e82ea9, + 0x5cb6ccb6690ff870, 0xb979cf0ebf20a814, 0xd56f941bc595c46b, 0xd7fd1913a9f3d5c8, + 0xa53ecca6aebe8ca8, 0x275a25e61667fad6, 0x2afc1e38a8de4e8a, 0x3227742d4ecb16a5, + 0x64e77dd8e7ab72a4, 0xceef1b141bd3fd7b, 0x163f1072ecf92040, 0x28c1ecf47e3a913e, + 0xb47f7540df359169, 0xd95dfc929b5ade69, 0x5ce277d1efc82867, 0xa6719a66ff85aa87, + 0xf1f976428ce3506f, 0x4e784129ed984779, 0xf7f628a70c3c1ea2, 0x89c7f6a5216d2963, + 0x4f7e36d84c0cabc3, 0x800fc714cda7eb1e, 0x5dc5f1cbd59bc028, 0x1895708fbea6d4f8, + 0x45b1478f270fd036, 0xc9c5c5ae101609cb, 0xdab6ce72e2a1463b, 0x1d8a53f480eafa70, + 0x7698237781ac5ca7, 0xe2d4f1e4a7369ec5, 0xd60d5042966647b3, 0x75d663cfb5bb7edf, + 0x3ded53e095b83af9, 0x4793b9caae960871, 0x6bf5a0c201cda80c, 0xcea2dc43cc9c9846, + 0x74aa61989bc5b274, 0x349b8c6c044a65a8, 0x7e7f94853888a8b1, 0x275116c0ba0e40ab, + 0xa8891a981b8fbe88, 0xb5a39fc41facf310, 0xa0e72226a9fb2d53, 0x09f4796d6901f049, + 0xeb700af12f8aaa66, 0x56a53aca18b432b0, 0xa95c6ebf55df3e2e, 0x48b8746ecbbe7501, + 0xd50d13cda7bf5210, 0xe3d6de0fac99e865, 0x8f2a710ce66dadb5, 0x59b796da1e66e383, + 0x8b4124e02a0824e0, 0x0416a768374d565b, 0x1e4d58242da77e4d, 0x070c21bb7bcc63bb, + 0xeed971b575113bcf, 0x17e7c5c733c60757, 0x0141018c2c9dfb2d, 0x78aa32652038bd05, + 0x1b42e42f4e1a4ba1, 0xbcd8a43fc0833a19, 0x1721502546e543d3, 0xb04c540b0311ba20, + 0xf652c459e39fa1a7, 0x9fae857efe593477, 0x05dac0a4b63bf3b2, 0xf4d63bd9a38f2631, + 0xd118e163c04964bc, 0xff8d054d555ac624, 0x3c40c6615783e948, 0xc170ed8c99af1d78, + 0xa41bd5577f51a4b3, 0xc9eb4bd6b1406f90, 0x6da11442c29c3481, 0x998e6e2de585d096, + 0x01afc0bec354fc46, 0x6bae53fd46c17bcf, 0x45bdad66264e16c4, 0x62b77da2d2056c03, + 0x6d3975c05ce31ee4, 0x8d3556c9d022abea, 0xd73101d75c33a66b, 0x721c5c42622eb56f, + 0x435d8b24b689109f, 0x9fcf332013c39a14, 0x51157c4f3197732f, 0x897fef32ef84c965, + 0x539b4e4d13a263eb, 0xde2d8b519280bba9, 0xdab673b83f34a5a1, 0x39327e231361417b, + 0x965e1c0b8cb2890f, 0x95e9780d421eb9f6, 0x5e401c98a0782ee2, 0x7459e3e2685539a6, + 0x02782e569eac3034, 0xc585db7f4c65d96b, 0xc94dd0efe89fc473, 0x15c04a3adf3ab997, + 0x0ea10c76e442b58c, 0xde284afdfb55ce7b, 0x933c0e4c8c9b6788, 0xa68e16599f73dbaf, + 0x373c6fe05cfa8d70, 0x57e018cad4bf2300, 0x02a3fd645f150846, 0xa39be7591f58e298, + 0x7412260f04f5bbca, 0x92592a3c645db889, 0xb335fe62e2f13b40, 0x97c04761e5a16e08, + 0xb3b1c279fd4f3c1a, 0xe93d2e9d59d493c5, 0x3e6830903f5c2186, 0x8af447cbe5ee83fc, + 0xf32a087d959159e9, 0xa5562fb86cb24485, 0x1db9f60d6be4b506, 0xee1e3a7f883c49dc, + 0xb86722e6f6972142, 0x1a62ca6e4cd6618d, 0xf2ea685ffd442c2c, 0x1d1c38fe0be2ca64, + 0xf21e1e76fce80610, 0xc9e759bfe4eb4214, 0x86bfb2bd4920c5ac, 0x4cde595b9ebfa223, + 0xd57ec5b20d8cad09, 0xfa98fb76990d7efa, 0x68f1ac88e8a5ba91, 0x75766195761a8a46, + 0x103f26a8f45e16f0, 0xa593141af399ba7c, 0x1739d91122e49f8d, 0xdfca8cc8c352ce8a, + 0x4fe7e0a4e4090405, 0x53d6bd169822cef9, 0xd0af15b873685f15, 0x74a33df666ada48b, + 0x5406ad022b38f8a8, 0x669cbcd879909cf8, 0x7e41cf5a10efd51d, 0x02dad13eb2fd4d22, + 0x269d6571310de2da, 0xeb50151afb34c857, 0xd004a857c68af74c, 0xe5ad25025ed8f8e0, + 0xd6ac6b3ecd320eb0, 0xad1f36df0cb37994, 0x39ffd36ebf3f022f, 0xdcdabeb1bf165bdd, + 0xb92fb5594333adc5, 0xe5f20b4e862ecc8a, 0x1a133aafc60dca50, 0xb2b8c814ffe03393, + 0x57fd275c316525e7, 0xe5811f95d22fa6ca, 0x87f2e97594e2167f, 0x30e3873a4398aeab, + 0x1c0dae0ef085596d, 0xcc7f09749b369ddc, 0x2a28d5e93a3fcd69, 0xbbf9780743e9ba89, + 0x22790d8d1921e478, 0xd7bdf07c7dd59315, 0xa0c3388ba408b20b, 0x5cea764c67a9cb11, + 0x8eea573f2a73463f, 0xce2356cefb445f98, 0x12549ef755537867, 0x534fec11267dd91b, + 0xda95b1b7f2bd83fb, 0x66439e3acf812dfd, 0x5abe4c448bf48a55, 0x32dc56f5a3dc1830, + 0xfdf1cab3a63772e6, 0x5092921e1944e7c4, 0x29c8cb607bb643f8, 0xa54bbcf28c7f1bd0, + 0x2d5e396f95d2bb9c, 0xf77be0690f7b7cf8, 0x9f3a1770b4d9cfab, 0xc411123fb458fed9, + 0xd51928fe8adf6828, 0x55fdd0707e1d642f, 0xaa1dcc49ff8d2ae6, 0x076d85c09cb1df2d, + 0x74cf1f5572108216, 0x526ca26be7dfce18, 0xdd1d00b37fcf95de, 0x31df0f3094d89ad6, + 0xcb72ea21ab886337, 0x459b150481ff39ed, 0xd5b76762e58f9fef, 0xfe75418efbbea107, + 0x1f9bceaf6ee2b1c3, 0x18d92c664d183b77, 0x09664c0b4ccfb4bf, 0x1f7e4a8a5d4056aa, + 0x8ad1a9db48550927, 0x06e3d3fb8213fcf1, 0xb4e71790cbd80a55, 0x8d6f782fd4cbd51e, + 0x8e6419ff2fded883, 0x3fc0f826b22602b1, 0x5db983f83593e459, 0x2108cb2479a38498, + 0x1d2b2cf8dc1411b0, 0x7564ee0bfc75499b, 0x613eb7bfa1a12f3a, 0xa939f5cdd60fdae8, + 0x7c9eb8472316632a, 0x8b36de01372e6935, 0x4077c04b18c122c3, 0x8e10f578d62b3541, + 0xa30589e84e86912c, 0xb2ca8facd2538cc7, 0x0134bbc09474d1b2, 0xa61d5ee38f0c9cbd, + 0x62926c33a90f3a63, 0xc15a4daf7a1a3804, 0x322c3540b11102e7, 0x5fa0ce4b03f6b9c0, + 0x4c4ddc8e4f6d4192, 0xadba225136fb2d7c, 0xc832d28edf57f24c, 0xe4dd81026eef3ca5, + 0x44c02a2b17ce5fe4, 0x1be6ff7d149a7ba2, 0x33e4ccbb6380f035, 0x982772192bbe32ec, + 0x9c70dbb9d969ae17, 0x71fdad4d9ca95c64, 0x975118228722e8ad, 0xcb148776982701be, + 0x6d5ffc93c6ac6c25, 0x97ec4bfcb3e29fd0, 0x16a6248be081447a, 0xca564efda3921edd, + 0x48bb2bc36f19abca, 0xa3d46a50bec6147c, 0xcafc107410d5d8e3, 0x541346c77632efad, + 0x8dc5cfee5d66948e, 0x41b69047b76466dd, 0x7b098a7bb5f9a93e, 0xcb365d004bd1c525, + 0xe84bd06a7c905de0, 0x58f8d7a88684a88b, 0xe2222ffac1c97f08, 0xfbb64e35e5890f5d, + 0xf6f34495ec09c759, 0x048116b2973b0aa7, 0xd71d4e0ecba6f768, 0x3f61898b5a0c9265, + 0x2049fd988bb4b241, 0xa2d099685b7a5e62, 0x3ee61b9a9a612f7e, 0x69fafb182d97b67f, + 0x755938d08674283f, 0x060182337779a4cc, 0x195276444eea3c28, 0xf20dc31ff0b26b4f, + 0xf344902e63a6aeb0, 0x9056e9dc6b3647c3, 0x54fcbb33c8d4d0de, 0xd27935803df96908, + 0x30f3aa3c0c56c816, 0xd03b1d75a60c2a8a, 0x70919c8d776202a8, 0x14b7150ed919545e, + 0x89f8366cda0c539e, 0x7ae6e603fbcddaad, 0x8e5c4e52848ee528, 0x4eecf115c37852f6, + 0x47d9d3821e7f242c, 0x789414c6a146b33b, 0xd68c075c0781d165, 0xc67f7fa36c422541, + 0xfc0cef71d532090e, 0x3fb7e794237fe526, 0x90ea4097a1a6a893, 0xab339f2f767785cf, + 0xaaeb388a016b272d, 0x90dcdd7e837ca33d, 0xe0deb35a2bea84b6, 0xa5fd4d359dcb662e, + 0xc72e99571d05aad6, 0xb5b5cd2bd1b0b999, 0x8cc8d9efd7738ed4, 0x49ae09fbd0b0b269, + 0x585c4207dbf8a17b, 0xc207eb08b4ea131a, 0xdc9cd45e0d344412, 0x00885d26e7bd30a3, + 0x8ea5e5b8b1deec3c, 0xe7ce5a3fab4e43e1, 0x3f43e98488203221, 0x8d839cd47d36bdfd, + 0x21da96b698a50a30, 0x54577d9319889adb, 0x67a52972ac057689, 0xc0579678500165dd, + 0x1c7453b1bde822a6, 0x192dd52707b73197, 0xac9941fca7f9d763, 0x9f388f25021a3f46, + 0xa4182c9cac58617e, 0x25acbfb2547a5335, 0xf5f26e8970007ebe, 0xff715b7c27aa4976, + 0x77507ce623d4bd10, 0x55d5eebb8e2ae649, 0xcfcbe39cf5dc68af, 0x02be69f08db85585, + 0x658d1851af915e55, 0x7540670fa4fd5ad7, 0xae92b8557e0bba6f, 0x8f76f151d5554f57, + 0xd1597399bc8c6f2a, 0x77e921e62009c019, 0x0a42154320e623f9, 0xef381ff06100f57a, + 0xb2aa841eabe04396, 0x1c364ff8222cb82a, 0xf579cadff2d1d7ef, 0xb9d95dc9b9533ad7, + 0x1359d1b97df7091a, 0x5d539ca02710b668, 0xf20524fd6191f277, 0x704eacb8089633a1, + 0x876ac6916f0f44f2, 0x2a7a2e54aa4c4e9d, 0x4f1bd1d7c30ea717, 0xbfd421ead4ee0fc2, + 0x3fcda7017b0e4aaa, 0xc4793c28aa4772fe, 0x2ac182fe03697128, 0xc1bf656c3e782e96, + 0xb510aa46d5e60ca3, 0x7da6072c8fd709a1, 0x04cc93ee7c8075bd, 0x80a230ef597a1248, + 0xbe2fd9d0368f8efd, 0x4ea4fd12e48248a2, 0xcf185e6051ffbde7, 0x7fbb4760c011e11b, + 0x89cda2e74d658319, 0x46cadb2395f3c118, 0xfa8bce607b3fe6cb, 0xf38efdd4a06de989, + 0x3e6b03ea65788008, 0xe5e0a638c9223597, 0x766101c0aca788ba, 0x121b1292b5f2ae25, + 0x2da51a7121f39bd4, 0x0c8862041c02cb3f, 0xc5913b690bc601fc, 0x421ff23c75f73cdf, + 0x635d30a19b4e0bc2, 0xd5b2f5e0fa40c5e3, 0xfebeb65b4993a843, 0xeab8f0aa806257a7, + 0xd1c717ff288275ee, 0x9e83434cac015192, 0x2a209212014bc128, 0x68b8df0ea435c919, + 0x9c82695c20ec5860, 0x6171ff9a182fe75a, 0xfa6c3b143634b33c, 0x5d1d8ebf2f14f13c, + 0x725b93228e5122b8, 0xfc104ad8526c9c87, 0x8b155d4cc31b6d57, 0xf14cc8e48dd58e10, + 0xab7c6ee7cd75e281, 0xf1f243c204e7e0bf, 0xa1ef2c756582aaa7, 0x73aff865b985923c, + 0x1b92a85b3123dfa8, 0xa608329f529015df, 0x56783c9cff63b3e8, 0xe76c50266c9772aa, + 0xab99b637b8718490, 0x1bd892f22477faad, 0x0f4d6a3d4176024b, 0x8fd2bda2c4cae0dc, + 0xf660a894e5b4d0bb, 0x55813f1e0574479c, 0xb9934ab037354e94, 0x3d806c28d1d36831, + 0x5135c61f431dac8d, 0xf4a836f62d104d83, 0x314a2186b0df4011, 0x2f44edbf0b022417, + 0xaa0d8019f8c30794, 0x1b03b10080d0d62b, 0x6643f358e293c3ef, 0xb8b9c12a062c02f3, + 0x0deba631bf1064eb, 0x4d43944de57c1a89, 0x07e125a5f535331f, 0xe35ea671428cb65f, + 0x05882c6785ea7d90, 0x08b7a0dcdc2a2948, 0x0319d61cccf699ca, 0x9c6037b52bb514c0, + 0xcd30f1c9accfbb58, 0xae05af5390dd11d3, 0xaa3eeaf82b2c5458, 0x49f16dc7c5d0abbe, + 0x652e8cd21cc68ced, 0xb83f47716f879430, 0x60c5a4e61eb261c2, 0x3d4c8a86c2de6c23, + 0xc0da7c2a4f351e9a, 0xd3dee073cbf26b0b, 0x9f1ab8a12cbfa5e5, 0x8aac649848ab6f28, + 0x0c4f20529b94ff3f, 0xfc34643143a78d0b, 0xd8fa1d7e776fa6e0, 0x8c9ac5c0d9a68a5d, + 0x38d7c6efd9130ba1, 0xd82e2f0d623645e3, 0x2b1a6395072d217a, 0xfed85931a886f05c, + 0x99f68c1865d284c7, 0xe3f5a551b9d05f75, 0xdd9a4db563f49c33, 0xa1d1ffd7771aee36, + 0x94543a6fdd8964d8, 0x8dfb3fda7d2a9b08, 0xb5198c2c84bc353d, 0x10ac97166f0addc9, + 0x92b7ee26160db51d, 0x3aff4c3c5bab1fef, 0x4502edc24e81b215, 0x8446e8c85e5c59f4, + 0x5a40102dcc502e87, 0xb5dee15e247bb2be, 0x511920a726801883, 0x737bf5387f53e887, + 0xe469cae14d5fdeb0, 0xbfb312d3d36796f5, 0x39a37b317e907b73, 0xe4695d37b7fc15b8, + 0xd9c0e6e28f82847b, 0x56759569ad5c76b5, 0xdf50db76c7103bea, 0x7ca3d864e7d0629c, + 0x9c7432b05922cc1f, 0x87facc61155e9e7e, 0xe1c780b3a2b1611e, 0x75354ff21102eb82, + 0xe8826cd68121aaba, 0x0f185570dd159f4b, 0x27bcd004c062bfe6, 0xa3cec636da398a60, + 0xed3a6fd0c41ef229, 0xf06dd740cf3a558b, 0xcfa201da0c69ef52, 0xfefc4df2b1df90a7, + 0xe11d719f20f712dc, 0x60e25990c816fff6, 0x96201a1b4d3c2eb7, 0xa26561fe88992962, + 0x9ccc6c20406aa033, 0x14388855b3dbfe81, 0x1e431a663af246b3, 0x0e8f343d2361d697, + 0x86b51e283edd031d, 0x264a4bb511a930af, 0xa55271c6d250b0fd, 0x6be8567d8b5d1093, + 0x63caca8edf0176be, 0xacb0726844e9737e, 0xa8ecb17314a8b05d, 0xb90bde858ad97dba, + 0xe48836c661904bdc, 0x3521752117de9a02, 0x51aa92e8df7f3de6, 0x9ebb2c5f7b59bde9, + 0x050c10c1746eb858, 0xbca6ff69ae16b238, 0x0053e5af09df1c70, 0xaa22625301c11b9a, + 0x6cc52ac87abe13c6, 0x27d0a7aecda5960e, 0x2de6d322ed4b172b, 0xbda4ae4b38294c3c, + 0xcade95e521dfe3ab, 0x525e5e6b58960821, 0xe2721e5e8a72384f, 0xa4debc1c2b07f4b9, + 0xbadf32318c218204, 0xc915b83030bee951, 0x08172c75e8fcd723, 0xc3fd77aaa834c8d7, + 0x4a3759686ddd1a8d, 0xd17459393ef8dfd0, 0x9eb6112e0f059ca5, 0x419a3cb9895b4a54, + 0x92d8a23fa002b93c, 0x955152b75d5b3c9c, 0x46d401e281822e3e, 0xe24f9af9be8958a3, + 0xb06ad44678cbe9cb, 0x462cd7801b72bc90, 0xa35771b132de9d27, 0xe79b219cdf17a7ec, + 0x76273ddbf88735ca, 0x5eecfe2534b22306, 0x9a8de88bcd5cea00, 0x73bec6267c32a070, + 0xb3c2c4d9065139f0, 0xa750a684f0a56256, 0x72f67491e704e87d, 0xcb39c7e03b69c15f, + 0x17e9cb56b64c3bcc, 0xbd8f03ce615f2449, 0x38e140dec06cb9b7, 0x02399eff003f7819, + 0xc0df1523bd1e8e6f, 0xbb00fa8d0dfd8588, 0x26cf82b535dbce55, 0x18d0c4f5c67b8f4a, + 0x82359c461f029e98, 0xa1dea83c053d14e8, 0xb5ed1fba2d9cf977, 0x4997be9dbee46755, + 0xb43be5ce4c38b9fa, 0x8fce7c432394a26a, 0xecd884797fe7a6e2, 0xc61d7381330792d9, + 0x2727d047c973fca6, 0x8c5c17812d17a647, 0xe56b033af58e9694, 0x0332b2b87819276a, + 0xaf149a42177aa270, 0x3de9d0262b38c57a, 0x16b155abef9aaf09, 0x3fe9e602320c2ef1, + 0xcb0577a400cbd8b6, 0x4d123296442db11d, 0x67e679ac4964b001, 0x5f34c6b9a45ddf3a, + 0xc7d3539bd1556a08, 0x8d8110ba11f06d29, 0xd5f068401fc707e3, 0xc3e099bfb9a0eab2, + 0x9972eed53c5a5d1a, 0xd7d4ba223c690a6c, 0x3bd4eaa7c2d60fe3, 0xe166de1d29fa0a89, + 0xf3f200474c5a200b, 0x5963879349e6e255, 0xded17cc891ba2e02, 0x7b04c79adf28f12a, + 0x02f08733e7d80886, 0xd3d235270b116651, 0x3cb8f8e7eb874fe3, 0xdf0b2f95594774ee, + 0x407eecb1592d22f0, 0x2e192f9cda124d3b, 0xc8ba5cb4301ec7ad, 0xeda9ae1ad2421e45, + 0xf7c9c727e2b59387, 0xc3d167ea4e3ce845, 0x20d68094801c5a74, 0x7105578c3ddf8b6c, + 0xc429adef0d65ca05, 0x0f002b2f985666b0, 0xe484e5c9d1dfda15, 0x7163ad03ce85ad75, + 0x1f9e81f22bd40684, 0x3d65468d3413c842, 0xbe06a5306f6d59f9, 0x0331ed2fee31b8b0, + 0x19d0e317b3ddde2b, 0x72544e3179c6a83c, 0x41e80093823ad543, 0x7aea07fac613754b, + 0xa1d728cc54b6df25, 0x7621cee012881b22, 0x14f496a5e17becb8, 0x351c66ae87b016ee, + 0xded046c47c8ee6df, 0xd50567b119abe949, 0x462e2cf8e7479554, 0xcd6e1c527774607a, + 0x59dbac841e619dca, 0x4e2962cdb4db9fed, 0xb1a37c05a7e1ebc6, 0xee495dd50edb59e1, + 0xd0ece16bf34e2f1b, 0xd517ee8f04fb5b38, 0x6fee015023819778, 0x82faf6d788da640f, + 0xb1b591f8b3e6c737, 0x555b707ecebf723d, 0x12a4672f581364c0, 0xff004c74f7f295dc, + 0x314c59afe93acb66, 0x1a1efd9740ce3a52, 0x5d66b29cff054ad0, 0xccfca59f6cbdcb12, + 0xa5c8d13f3f1d4f64, 0xc2fbeadb04273ba4, 0xa1107c88ac9e9fde, 0xd77ba13b26b4c8f3, + 0xfaafa93fb0c24e35, 0xe669513ac456734f, 0xd1291dcb26f5d23d, 0x0f56bf5d37360e81, + 0xd075d264935c616e, 0x5a92c7406fe30ed1, 0xb546ba759462d507, 0xb0c2c3657fe199b5, + 0xb1d41571cb848ef7, 0x7109f513d4cd1ba5, 0xcf919bcd631c931c, 0x898c1d33c5b48074, + 0x5555f330665a1f33, 0x338486167706e878, 0xb74e42e669f42643, 0x0534facdcb57ea06, + 0xaa2ee0cee0138851, 0x1f8c4834b49cf609, 0x7798c2c5c97dc4c0, 0x6436c47274c7e933, + 0x9bd9e3592c7b71e6, 0x3b18dbfc9bf7ac9b, 0xe13b00e5e1aef412, 0x3a15b29fdceb1223, + 0x5fce4b1680639448, 0xe2a0bd9cee8b35b8, 0x4363f5db29cd0f31, 0x90f8369f218e4cb1, + 0x7005a41f049602ee, 0x902a098ca50aa1b9, 0x8d1c81aa0a3ebc85, 0x252c5bb4db3a88ed, + 0x55317f3af06880cf, 0x5fda76c8c7de0726, 0x2b5ddd4a314489de, 0x6e2aea480a18d19c, + 0xa8444229097ec8ec, 0x29e6a246d1f12a1d, 0xbedb4f3d5ec883ff, 0x1b07a387f2763778, + 0x78a5b122c3a61937, 0x98abd6ab57cf893d, 0xc47f8271c0ac60fa, 0xb46155629c766488, + 0x2cd2d28f0d51559a, 0x7e442b9daa1b8889, 0x68ff812fdf8277c0, 0xe9e5199d3e6ecfab, + 0x2697c46ad8796ef5, 0x9282b0f5983e0916, 0x4795caec398cba09, 0x43f20bfb79381939, + 0x5c6f0a151e2f2afd, 0x8453e722d403247f, 0x6142ef16af08567f, 0x8883338f95067375, + 0xa485c3c95837829d, 0xdd71542df12c5b0e, 0x5e1503aa1d94dc5e, 0xab89cde3b700a472, + 0x80a1b2666bc83a8b, 0x8bc14a056e7ff925, 0x913cb47293aaf8ca, 0xa6e0bdad1c3fd2f1, + 0x6fd52b141a249618, 0xee1b3815618dd3fa, 0x27f1999d828b4c3f, 0x20a71df6000d7fb4, + 0xf573b48a2ae60ee1, 0xd86c9f410b7d86fe, 0xa2aec6523eb474fb, 0x1c7ce55ef55bf45e, + 0x81d42d56b2c6c4d9, 0x5ebc5a090d5935eb, 0x4c67729f311b1b2a, 0xdf47c5af78d0cd3e, + 0xe0296ad6afa54f9c, 0x3a90c5189ac4188c, 0xbc3a16f21ce76183, 0x744d4f70497f15a2, + 0x7b54dbc3ad1248a6, 0xfdb2baa345c63b8d, 0xfa66a06424f94de9, 0xda13480398fe97e4, + 0xed1ad5262c7133a8, 0x44a71c0c162235a3, 0xb62c7b01f908010e, 0x2fc8cf1fd19b00fd, + 0x3e905fb36b90c768, 0x5bf098e651f998e5, 0x01f537909059fced, 0x04aaae08626fd701, + 0x58763a277d4a7f5a, 0x9c1026a505db0599, 0x89830d1917f16886, 0x29674702a3b9cfe2, + 0xc6235b01d18d3814, 0x507384791bd9be65, 0x6a7d2d1bc475fd72, 0x2db3709e6d642e5a, + 0x83161c4f921778bf, 0xd78961d296658a57, 0xeabd3f456c870e15, 0x54cda079d87c5bd3, + 0xcaf5de89b56f4c9e, 0x3aab89586eaa7c09, 0x97226f283c1f6e91, 0x63dd7512c5e470ef, + 0x15119322fb7a9c53, 0xe972e17f01e2710e, 0xcaad4d700c5d137c, 0x5e389a8e844a600f, + 0xc8d030172ac318ca, 0x05ce808abc1c499e, 0xc1e7c3bb31350837, 0xd4403f8b3fd3f9dd, + 0x8f60b752b14b47aa, 0xe5d0c292306104e4, 0x08848a3e6cc8b600, 0x12ac166d07883ea9, + 0xea4e6aa0ae570ade, 0xe7192d752817e167, 0x7a4ea8e544e493ba, 0x7d93a8ae89d186c3, + 0x6e3880118c862401, 0xb371faa7aa5ae53c, 0x76aa09eb29fe70ab, 0x9957b772f51334c1, + 0xc9951046d185d7ee, 0x705c521932996b85, 0x698d051ebb062d9e, 0xfa5c4473e2e558e5, + 0xea09bf6807fdc4f8, 0x38c1274e7d8ed381, 0x1e5d067fbe7a39c7, 0x90aaaa61a104739c, + 0x337c5edcd131df51, 0x9a4de380d1da823c, 0xce8b0989787fae45, 0x74bcec3c9c34a864, + 0x84c9fb0b13f759e1, 0x08e551e06bfad8a9, 0x20b613bf659f7c37, 0xf881bec7b4ebb44e, + 0xfd30ba9f1741d72a, 0x21b7e350a9c25f0b, 0xc8254e1ef6038991, 0x286b669065b670ec, + 0xc1b2d9e15abae138, 0x6e2c84100e6c6690, 0x35b06390741bcc17, 0xdfe4fb675f2e4370, + 0xf937d490cfee1dcd, 0x595f44d3ca8700f6, 0x467bc4b755a18c87, 0xc6ea5a208cfa5368, + 0x33101d8256001628, 0x2cc7d058444a171b, 0x3c55b8f9c6fed656, 0x9bc343425e60b490, + 0x7c9ce72065a653ee, 0xbdcc745f06c4479a, 0x1a77a6309b72520e, 0xf195ac44f4ff4444, + 0x6162ac2cd7bd6069, 0xf9cfe2e5e60ab149, 0xca63671a85d33dc4, 0x019a4bdd4ca5d0a9, + 0x94ef5e3d7ed0fa72, 0x380b527200bd288f, 0xe46cba8c810febf6, 0xbcd3701e4d747262, + 0x43bdfdf75683de2c, 0xfd84db74c35351bc, 0x7484952296479867, 0xbbd05e27ac1ae82c, + 0x09a5ff63677948ce, 0x1c16bf210742fb78, 0xe819b3023a72147e, 0x603e827dfadcd057, + 0x9898f6868dee0a5f, 0x946858357590d28e, 0xd5f8d75ed25ee90f, 0xf50809b67a4438a5, + 0x8e45f5f3d9ba2b14, 0x8e10c0087dadfb9c, 0xc93c1110a296ba20, 0x83ad934525e661a1, + 0x438e1acd81540cba, 0x025d47dcb0456151, 0x9c64c1f3e0f538b5, 0xd0c8869af0e46de0, + 0x315a1192f304622c, 0x0ce81115520cfa8c, 0x609443d12bebe0c8, 0x25e00a01757bc1e0, + 0x0ce41c10def57914, 0xda12d9f3a943e197, 0x9286a4f9e679ab77, 0x73c002ca500db876, + 0xf3c022d386013251, 0x4e5f8a2171025111, 0xf2d089cbb543eda7, 0x00119cd17a35a1fc, + 0xc7e24787b52c485d, 0xeae9f71848f26271, 0xd85e2ea6b0aaf778, 0xf4478a7fc40ee2e2, + 0x7f361a5bf1a77d99, 0x03d68d7dc25a1229, 0x4693c7b8a37e01d2, 0xf7d060c9acea088a, + 0x2186f4b24dcf7ae5, 0x81df0953bfd640d0, 0x5b5e6430a51dbfd7, 0xc16c98efad26c6e9, + 0x6ec0161ff0f1f1e7, 0xff28b9bb34a21746, 0x374526fbafdbedd5, 0xbaaebbc2049deb01, + 0x22ce8a71c8acb364, 0x60c8d6391877c40b, 0xada073f73875d7dd, 0x9f31be6311b6772d, + 0x38b199763481966c, 0xd2d8cb7d7ddd2d5a, 0x7113f7fcbfd62e50, 0x6d39f2b5d5c8e9d6, + 0xb02c00f648435960, 0x6c4fc4346cd44fdc, 0xd1353b8ecaf12d8a, 0x8dc5f4627d35a336, + 0xf9d3594ec9935a4e, 0x0b5be26c5c7f7628, 0x7d7d4802d0cd7f41, 0x54932f3506fad863, + 0x9d5f931ed998ad7f, 0x6fca2664d0e360eb, 0x86a45fe21b140ca3, 0xdb776acd850c5b2c, + 0x483cbb36d882c769, 0x6302391a287b3400, 0xa99aa484e510d2ab, 0xdacc2e1c47f6866e, + 0xd22459dad0ba1bef, 0x0d169f97312cd5be, 0x94df81b22af45158, 0xadca34cdfd0236d2, + 0x0f23c710c79ad65b, 0x16286aba54b7b365, 0x239c06757741ee24, 0xa8ba66ac0b74a497, + 0x549671240ff95a22, 0x4e2e27fe50430ba5, 0x817a17de8b3a6a7b, 0x2ae7c35e791b0064, + 0x529f3f64107d4bc5, 0x3e4ec2ae1e97ce0b, 0x37137f4bc94ca307, 0x89f63655fbcf8fde, + 0x01cad2072bf83ba8, 0xcca036821c1c46e2, 0x12c061eef3b6127d, 0xa60035530a9b1ee5, + 0xad3945ccb49e3be6, 0xd4e57682c09f3f3b, 0x14c43e197e0754e0, 0x2dfaecdd72464169, + 0x208571b1bd02ab76, 0x06ee7c8f6c1a97a6, 0x05ac17cd8113f0bb, 0x746329d4bd3a2610, + 0x0ab5267b56289508, 0xf5ea63ab960a5499, 0x8845a8185c5531c8, 0x028f71d7d9d4281f, + 0xc16fda832de219d1, 0xdb315ff727ad6719, 0xd552c6234026850f, 0x602b175fb3f81f6f, + 0x61db21e60f804ccb, 0xa57c5da126cffe4e, 0x273873a94ffbc545, 0x00e6790fc073bd27, + 0xb5cfca4472afb2b9, 0x9e5c7f98214dfc3f, 0x084998669d180719, 0x21d10542fc6258c1, + 0x5f4e91fa4a2c26cc, 0xb32f156e96812048, 0x494e76347bf04c11, 0x176dcbc7c23aab57, + 0xc26d9402c6851fde, 0x193796483062b7c4, 0x90441019ea5a22d2, 0xe557709fbc8a8bfc, + 0x7e9844f04b9e9bf5, 0x39aeb8b9551a4283, 0x0bb73351d16f27b3, 0x1c985a894e8d0ddc, + 0xbad8488d0397c8dd, 0x5139b1591c5a5d74, 0x22d10159e65adb2e, 0x16474f7a122ebecc, + 0xe8f5c65256fc4737, 0x814d402692d42087, 0xe2d20d2e103bc9ea, 0xcb622eed89e9ee45, + 0x652db640afa79a42, 0xd2b667ff95d0158b, 0x55f779c0f3ca1236, 0xaaaf33d79db3cd71, + 0x6c97048e04b0ce4b, 0xd1fcc941bfb958c6, 0x5323363a4ba7cdf4, 0x2212b2211c21bd43, + 0x0b052c222a990b7a, 0x1adf04a5b10d4486, 0x2a8c3e5aa32f3c6d, 0x304320f82613a9d2, + 0xb5ea6ce470908c33, 0x0bc14cced49aa821, 0xaf71720fc74b92f8, 0xe9060a2dc020939c, + 0xafe122062870afa6, 0xb2791c460e54c17a, 0x7e6c97bd0d8e2d3c, 0x4fa632c83b62498d, + 0x87f81c74569347ac, 0x8341229dbd22c9f9, 0x7d86f9d3777175b9, 0x948e272c8e873fea, + 0x5087d53f854e599b, 0x9150d8e82b3204f1, 0x6c138b56bcefe0ac, 0x76910455d3769131, + 0xec413360d4909877, 0xd6c82ab06e245a04, 0x786b763a8c2df863, 0xbbca5c8dffe8d0f6, + 0xeeb2baa4318f4a4c, 0x45ee27584c202dd5, 0xcbf85ab159585587, 0x2f6783bfcfc80177, + 0x282e6d3872e9a74c, 0x211ee409086cfed8, 0x91952f6edd702835, 0x94553c43c2de6b1d, + 0x9b1406ff08d8a329, 0x13c103c35b469b51, 0xff32db78f16e8166, 0xb38ca3043b1d3dc3, + 0x3b46535e21f8b654, 0xf6513ebf1975f057, 0x92289b8ac2a1afa4, 0x203f861a8c40d3cd, + 0xfe3ac691e2698303, 0xbcd193fa507b1bda, 0x691da99d0c832cb8, 0x8db9246298377078, + 0x843c6e1ac7b7daf4, 0x924adbb91bd0d536, 0x945f2faac316be47, 0xd603341875df2d27, + 0x78210f3ec8fd9403, 0x329c3aa1e2914189, 0x730fe9d7d7dcf027, 0xcad54c49682371ca, + 0x288e1e60a7637940, 0x7ce8659d18fd0497, 0xb7af43b951f53d74, 0x3eb5742701686376, + 0x2af2ae55ae302ead, 0xbe2eb3de4052bf41, 0x8271bc3024fd974c, 0x2fac4c3ada675c30, + 0x66c1717075ecd181, 0x6f55e6c692fe9be8, 0xaf28d4bc2cea9734, 0xabcadf5fc11d469a, + 0x38aae8e6751d8c86, 0x368bc397df5fa858, 0x4049c232d5fd0bae, 0xce295d9190db99c4, + 0x8ea8eddbd9841358, 0xa86fc12202d8dcb6, 0x10d36dca46c45f82, 0x73e4e0f23992a8fa, + 0x9f2ce47859376622, 0x7048706310936409, 0xe6c920267343b522, 0x2a391a2758598cfc, + 0x153770cf214040c7, 0xae8979bfc4da0a44, 0x70d08a5e52ff2909, 0xeb45ed1d4a55dd76, + 0x7b63c2c4febe7060, 0x9d9fae40ba131e80, 0x6160f621c80cfb2f, 0x7b71cadd2bbaf7ed, + 0x384fe44e144b1e15, 0xe043ca2720a06220, 0x9f536f5308a1987c, 0x9df59d18a9addddb, + 0x3708a2040abaf01c, 0x72206aa39bdb49e1, 0x3a27e63413ef1a13, 0x1fe99a935f3b6421, + 0x6b28e6e7fa5727ee, 0x339bd08d03cc6368, 0xe7a100aacaf114b6, 0xae7f8462e3485acc, + 0x0a09cb489613a369, 0x9fb9644a44f7f763, 0x2f2a8fc8b07b896e, 0x1e8e1af672303ca4, + 0x60ff8c2f4e694866, 0x8c4ae1db88694e20, 0x9bbd10a657291e1d, 0xa0209b2a95a72cc0, + 0x528bb712440cfe6c, 0x4a90552b726bc344, 0x9c5e533d6ad1a09e, 0xde9586c979576f8c, + 0xc3fb4aa5c3c3a016, 0x35575b710e95be3f, 0xb425184c275d13cb, 0x7e4db6691368f84a, + 0x928f975c5c3d7044, 0xed80b078a435f1b3, 0x807c4ef963511e9a, 0x8af76dd46c565dae, + 0x9862df40069378cb, 0x56684e87f9ca6b01, 0x6e4438c9dd1fea10, 0x1ef3e6bc58e5088b, + 0x163b3efeb210a7aa, 0xf1a23421cf489c3e, 0x1d22df33dba97581, 0xd84099d333f23817, + 0x3f7cb2347ca134ab, 0x45105390b272005d, 0xaab5662be8366bee, 0xb90f9476e1b65e32, + 0x7a573dfc1ae4d1ee, 0x99c5f918b0af652e, 0x3a42e45fb5bf3ac7, 0xb694812df84d30e0, + 0xc2a1dcb79a8488e4, 0x6240741d451e4270, 0xe15273400f3a09f2, 0x951b1322706eb67d, + 0xc411b9dc4377f2c8, 0xf103d4274ecd1d43, 0xb8b0898f39552a65, 0xe94ded4ca5e72349, + 0x17f0aecfe8922abb, 0x045456787be4b6c2, 0x103780c1c335ecd7, 0x556279f2a1e5abac, + 0xcd08ffcf14df5527, 0xfdd84094a180b1f1, 0xea30faf0117413aa, 0xc9f667111e685f95, + 0x3773e2598f695ed6, 0xbc0b1d103ed27a97, 0x51b36c5ba862413a, 0x9fbdffec571c4893, + 0xebc9c1be46648f91, 0xb6edb7843887c04f, 0xa7ce6f2867701e78, 0xb9a9350617e521fa, + 0x812e75ef018f9aa1, 0x7c5a872a99cac922, 0xa5341cca0fc2dda2, 0xe89e815f0a3f006e, + 0x39b5ce55b9ae49f0, 0xbb2e9ab2d05b83c1, 0x605ca0ca691f15e3, 0xbfb6aac2cb7b9d63, + 0x9f89434addebdab5, 0x6289f97b55fe25b1, 0xd493d7f32171208a, 0x6598c7e3a72ed5f5, + 0x3a3dd7e867a0b2a2, 0x31bd932cdf7d3457, 0x899eaf5a85d58a64, 0x46e48de0ea303e45, + 0x1e208e260d85db0a, 0xf585c62c4b677b60, 0xdafb7b015f342bd1, 0x143f841aaeeb933e, + 0x4e57c98754ddf9d8, 0x32ad9d5a201d84fe, 0xbcfb1d9a852225f8, 0xca8fee9f9c79e9f6, + 0x5237e4626a0b7b6f, 0xc808c6b492db16c0, 0xc77cd68995563304, 0xfc9cfdf0e9369edd, + 0x23d52a66404cfc29, 0xa7b2b6e4e750050a, 0x9f160ba2423be3d2, 0xdeccfe881a818248, + 0x4a944652c326b649, 0x700db299489e2eaa, 0xe6de20736d8b94ef, 0x533959c5640b3045, + 0x4a8f2109f488efa5, 0x40530de89f44e647, 0x654f1a0785284c44, 0x16a7eafea7d78f6d, + 0x426056c9203b1697, 0x73b12751e84b9c08, 0x03985cba93691d13, 0x71cf3e4e223ac323, + 0x5dc87db669a97374, 0xc1c21d0e9d8f3e27, 0xae46691357edbfc5, 0x92dda301351ed190, + 0xb96ad9b88f077855, 0x1921e4aee69c0a1d, 0x40177ec46c0c29ac, 0xc9f869cec12fd253, + 0xd7412debf2239a8c, 0xdc89fe5550b1ef03, 0xb7d60581d3ee4cfb, 0xfde08fa2813b22f1, + 0x79033561a71e3767, 0x05df4be385cbed09, 0xaafd150f3b5b2bbd, 0x4b77e95dd4b0dab1, + 0x75dc773ab579436a, 0xd04b9dca0eb8d58a, 0x25725610b0bb9088, 0xbc14eec8ffd61260, + 0x3443e8681ef7316e, 0x34976fec0557118a, 0x1180dcbe6b6dbba7, 0xc58b565ab832bea9, + 0xf738e5fccbaf95f7, 0xaf3ae87f2c220cb4, 0x50387103900e16f6, 0xe856a2ef4986ef31, + 0x89ba2e0032142a28, 0x5957c250698b393f, 0xe71356446e6d6de2, 0x31e4f223acdcf926, + 0x941e6af230d58dd5, 0xfd7ebcae1b213259, 0x99f6503312dad593, 0x5f14119683b53b8c, + 0x91156161f1855e12, 0xa988c81743b2fffc, 0xbf58fb274ca611f9, 0x22c8676cd473265d, + 0xc1703a12d4d04981, 0x3fa0d4fa4dff7a55, 0x197d831e0d22713c, 0x1fddb57be04fdf45, + 0x08662dd0a8847b0e, 0x043ad20b76855ce8, 0xd696ac6c2d481f3f, 0x2b9148a25b35361b, + 0x6e7cfc9a62ff5c9d, 0x5b71fccf789e0ac0, 0xe8d3ee260fc896d4, 0x80272974f836f14f, + 0xeabb5867c35f6ca9, 0xa8255a79f2503033, 0xa28bb1f83fb120e3, 0x5f703c1fa401d781, + 0x714b123ac88d456c, 0x05c54c68ff17c5ba, 0xd64a4b3f1e516c5e, 0x2f7f94bc0d42c213, + 0x1d58c2b779f487b8, 0x2448d9c8c57a76be, 0x07d163c5eb43acab, 0x309d6f0deccc76b4, + 0x96511a683e7fb9c9, 0xa39e4c7b6dfc13c9, 0x4c85db7dc557fb5a, 0x9e266c3e3fb1e1dd, + 0x40834a718db08d57, 0xda7cfd7647829733, 0x8bc970a1b750acaa, 0x395559f7847ee4d3, + 0x5458d840cef87e64, 0x29409fc0c7df5f2a, 0xd2e0e782013cd37f, 0x4c5f40b8474bdf3d, + 0xa7246a6e7a7eb61d, 0xccdbd4b73e6b397f, 0xc5658be7057632b0, 0xfb87dd8214c272cc, + 0xf4e9d623ed79e7b1, 0x706be8099bf421ad, 0x5f590cccc073750e, 0x3c1dc743d2b6e723, + 0x60e000d0eaccb4dd, 0x8b670ec910de6a0d, 0x1d95acd708fbd139, 0x114643933aeb7f30, + 0x5b1a9456c747a1df, 0x6c3d65bfb9eaddca, 0x31433feb1e564c9d, 0x6fd6d6072436dc33, + 0xb4c9362581601820, 0xcfdf5d2aa4c2ebd9, 0xb758e105603ab789, 0xc37adb13fdb4418f, + 0xda45cba27c8acd4f, 0xd624660fddcf471b, 0xc287708b80a31124, 0x04d64f520682b650, + 0x2192ba0917cb504c, 0x202b31d33d95b344, 0x83ee79ad1f91e2a8, 0x075297fd56d43fa0, + 0x994ab39804c78963, 0xdaf4e71acf11719f, 0xcb6c57c4a8700dba, 0x82e7a9ab0561cd02, + 0x1aded4c52766afd7, 0x8413a899ca576d7a, 0xbb5910f3aa40eb0b, 0xb24a4c7d413652c6, + 0x05d25b7444a5ebb3, 0x9a867e74e997b1fa, 0xdb5b9e03b6fe385f, 0x2b95963f5d721b5a, + 0xeab9e46670b8e263, 0xf0df63629fb72877, 0x49f619e2d5e8203b, 0x80f9b9b99191334a, + 0x067917087ec4dfad, 0x6148be814548f734, 0xd7e76199065faa77, 0x8cd44c33225f4247, + 0xb965f2dff8947ad7, 0x638b66f45b99e998, 0xe7348488dfab511a, 0x8f224dad126923c0, + 0x706f0f04922d2714, 0x6ae1d7d62bbb2474, 0x9f0e309ee0498579, 0x287e22de2dc452de, + 0x3996661c3b6f811e, 0x7c8d902d2602ff24, 0x1950ac372328737e, 0x0ff921152757dc60, + 0x7cbfbefbb14f1593, 0x2d557952596605fb, 0x7a9dd18b7fd5c74c, 0xfc823fb54000f963, + 0x378b1a68dcda7786, 0xc97ea36ce340a4df, 0x13976db93457a7f5, 0x02dbe618e9c24f93, + 0xf91f7ef12a79a72c, 0x215df089d2aab3ed, 0xc94aeca03a65bf12, 0x42fca940d8f47f33, + 0x9490ebe3a70ec214, 0x3060b024aa44f987, 0x2e3a58656152fdcb, 0xdac96028bbc5bc0d, + 0x50f96c7a77f6393d, 0x8f26a898ad17c39f, 0x6e22ec34015bc3c2, 0x10fe7c3a9da4f0f4, + 0x7735d8e93d887c8e, 0x9c72490fa970b813, 0x3f688bf1b009a651, 0x0ca8f32a767fbbb2, + 0x8fba22fb50ad2c21, 0x9d03e3216a6fa3b7, 0xda04817036fa7aa3, 0x20ad60c4989893d8, + 0x605d08919fb75f54, 0x451f497ac9c15c32, 0x1978bd4cd8479ca2, 0x2f17735ebe2188ec, + 0xbae9d66721ad7a90, 0xce700d1f2e2d1c2a, 0xd5898877d9c87f2e, 0x7a00ae55a40508f9, + 0xe8b98dfaceff3cd5, 0x7e8b1d6bf0f43d61, 0x2db3db13e904638e, 0x41db614c48b29c99, + 0x0b227c64d5b9fba3, 0x964e7285f8dc461c, 0xc92334a5fd53026a, 0x27511338ac6c71d9, + 0xbe09415c3a8a6416, 0x0455c6d269f628ec, 0xdea4045907fc8c69, 0x4547aa96fdd62769, + 0xb9584047b85ccec9, 0x715b30a35798b7e8, 0x51000d3c93f4bf4c, 0x360d09170121b237, + 0x5d11bfede3511c50, 0xa15fbd78d9bdc30b, 0x21d2774be2807eda, 0x6d2919ce4a8e9390, + 0xa4cd90c5c538bf47, 0xcbaa4ac0cae2203c, 0x4b2ee15900781c82, 0x0fb11b1173a3cf64, + 0xab897dec7c447534, 0x9d092cf18a07c368, 0x6f18ca32934dac59, 0x67026f48949c4f2f, + 0xc689d8f293613bb5, 0x5e67a6fbe213991e, 0x92429b90f6996912, 0xea7f13884772eaed, + 0x39bd11680d44df75, 0x395640f6ecbf36cf, 0x9071ad13a61446de, 0x80ca035932d58927, + 0xb417d18b117ad802, 0xd1f8b12680122c57, 0xcf48c1d4e991bda2, 0xbd1c34b4e4f79789, + 0xf47f965c16bfca22, 0x86fbb0330100afb7, 0xe1a632b40f8df09b, 0x93d793260a887f18, + 0x997579654484af4c, 0xe5420615d98477bb, 0x2956a9f4a8e41621, 0xa5f7291efad9cf7c, + 0xdbce736d7eb64c77, 0x43e246be93393fb6, 0x30016776051ffd83, 0x6973dc4a341d2cdb, + 0xce97ebc49b17d710, 0x640f2b195e23eadf, 0x57d1a7e5940ae014, 0x44f4251d738364cf, + 0x9a677ec483e624ed, 0x29a5c1139a23be02, 0x3ba2272615dd3108, 0xb7493efd927114d1, + 0xf6405a1d83266fef, 0xe37418529ed24265, 0x0e2a242ec600fa03, 0x05aa0bca789d807d, + 0xf34dfa098ba1574d, 0x6d731c6c730fe91e, 0x8a910b24494beafc, 0x17acf76602dd8ea5, + 0x21aef0da1c452807, 0xe1f3bb1c887029f3, 0xdfc2f737c81b88e8, 0x94371e46e34ed838, + 0x9d896791a5d61b9f, 0xb149268a2b7f1241, 0x10ddba716b542d16, 0xc6d066c66df26a7e, + 0xd0b6343e36c8e84f, 0xa38f8389b03fc0fc, 0xdc0c1cdf60d6604b, 0x73bc679d7c846659, + 0x9dbb7cfcc9591c47, 0x9ba66b408ebd59f5, 0x477dbd61ee8df194, 0x03ebb9460ad59c0f, + 0x7e78fc8c934098f5, 0x254bbafc8d6727df, 0xf426ea1ac256c248, 0xcbfc76774c3bdbe7, + 0xbe4f97464aed8b05, 0x186086dc18a5b961, 0xfd9ab4f368c31fd0, 0x00365d1f7db96185, + 0xb5309d35f2f68e23, 0x38c420731150765d, 0xffa055dbc4eb7c42, 0xb198876cf3d38946, + 0x83aa1c989315a1cf, 0x26f1a06a94973086, 0x6451a80c8a46b2a0, 0xc92c2dbe2b5a22f8, + 0xe258f4ba3c5b0809, 0xadc38fad1a6c2c92, 0x9c4fa8cbb62b83da, 0x0f96163e0cbe99e8, + 0x4028d95fb4b42d89, 0x342b1ab6286171a3, 0x4188adbfe7ac8931, 0xbd9f343c9ec2683e, + 0x84e519ba2c1f22ec, 0xa732822ccace90ef, 0x1ecdda3f09d296fb, 0x3237c4ae32e70395, + 0x0f096f53c2cd3f4d, 0x96a34a2ce21efd46, 0xd78db462618caa7c, 0x8b3ababd1ee7cd66, + 0x4085e2aef38e1af5, 0xf57501e5819e22a3, 0xc21b1e1bc1c6bd0d, 0x177ca29689bb8b53, + 0xd97848dfb447eacb, 0x52a7916debed6210, 0x332e2693a49ee362, 0xb03cf0221c7ae54e, + 0x49cb81dfb178d2b6, 0x8add6c72622021aa, 0x4feff3e7e7dfb9db, 0x6d0bc767dc840bcd, + 0xe8c0c052820a2c6f, 0x0bda6f94608365dd, 0x427f3b1d1c11cc6f, 0x3f62b362c60b0777, + 0xd1bfa232852b0b80, 0x264f51d020bb5882, 0x11dc3ba926d1563a, 0x407b4bd5f77e0275, + 0xa81f362bba062636, 0x60f5922210987abb, 0xe78cb2f2b0b1de0f, 0x483135fee7e8bd4b, + 0x91a25225894cfe9f, 0xe0f434b740329067, 0x06a5cbe1f2405ae8, 0x610e9ff0d0c7ebab, + 0x0716a976bea1a48e, 0xa28c12da389f0813, 0x9d5b20ed9e4106ff, 0xdd8e08e716651c8f, + 0x794539c542181c5a, 0x07daecca4cc20e7b, 0xa44694b00220be3d, 0x61b24c38fc468649, + 0xccfd9305776e8880, 0xc095d50b72217018, 0x04a2becf673ccabb, 0xa40c1dfb6102a4f1, + 0x7477bdc152f5a89d, 0x1e56660f2cc4191f, 0x0e073b4725506834, 0x09fc4d6a1ae73446, + 0xe8498661703fa9f0, 0x91efb1a5f0ea4902, 0xa1dda0f0236ef0bb, 0xda5dc6cc75c59a91, + 0x9697ed68c75a4453, 0x6b3e1f9f365e3823, 0x3570e76da5f1e1c2, 0xd417ae9441e31bd3, + 0x7f8c580a2256d7d9, 0x0d479239cdbe2c87, 0x2bef8e771ef43882, 0x7b7523d22c0a740f, + 0xebe043c45f687ccd, 0xc635012134fda0dd, 0x141c34c7dbe90318, 0x248389085a8af2fa, + 0xb5826bafed0a71e4, 0xb32e644e2dadbeaf, 0xd7075804e2015a4e, 0xddd475680b32ad37, + 0xfaa0fec564696df4, 0xbc0bb0a7011009d7, 0x03c4d3aeaeaeddc0, 0xc7bceac25c2f7739, + 0xff4c9b0f7affdf42, 0xf40810a8f11f873a, 0xa6c8b67b547bc894, 0xec8fe88bbdb4aa64, + 0x77e07ae8dbbf0e90, 0x222f30bf842db487, 0xf9dee217ff274d73, 0xbd792ec7d1cd92dd, + 0xf2e6104b97432a68, 0xe57c299dce056260, 0x96f40c86a150e6d0, 0x061e3731cf0a3086, + 0xc802ea5b144929cf, 0x13c59a72845d9cf2, 0xae7b6a693f0ae30c, 0xfc2d83b328288d91, + 0x8b0e4c6f040cce8b, 0x08b7588582b9322b, 0x348c93cff7849da3, 0x1b6e6dfcd6857c48, + 0xc145dd7315effcd9, 0x29fc95209c619a5e, 0x3bf44dec5e195a3c, 0xcb980ecd064dec1b, + 0xe80a9c2d52491604, 0xd2f28159e1b5098d, 0x6329e761fe16f39c, 0x69cad58eb4e920be, + 0xe0d854122380e2bd, 0x0a64c596fc29683b, 0xcde63737a1b99515, 0x1b65338b3860e90f, + 0xf6a6a6c75ae026e3, 0x36445fb703e785e6, 0xa3970982596a5aa4, 0x98112112628b2c64, + 0x0abb071decf7e885, 0xc37b841b7493513e, 0x47c93bc89b5eafe2, 0xbb11895985dbd874, + 0xb982c458617cc54c, 0xe53748353da6c825, 0x932d71b9a4e8930e, 0xf9381f6ac1f750a7, + 0x1e6e882ee3e15530, 0x368f6292b6dce69a, 0xa490a15fd9d89c05, 0xa98cd7a37c317e8d, + 0xd5ec1390eae2e2ee, 0x3434479e98c560d2, 0xadae0de05af244c7, 0xb2efd76e1a9306c5, + 0x5dda21a7c1a852e3, 0xe7df187daf1c9cd9, 0x765e0c125fd634d7, 0xace47294e9bdf8f8, + 0x16f095db8fc43856, 0x6a20d420187468e8, 0x181e3fba8ecc14b4, 0x666fb2f855c6cf43, + 0x1f53aac42aad7c11, 0xdbbfb5431eba8c18, 0xe4177151e01a4fcd, 0x9c7d1dd8aa9c0c28, + 0x89d5ed0575ca5fe1, 0x5e4d2f97f234a3e0, 0x8b2e7b4697a1731a, 0x4470e94e89b57aa8, + 0xe7a0b475662efe5b, 0x40c7e93cce4e7976, 0xbf053864d6249fb6, 0xdf1716b7be57d8b8, + 0xe0e5559aa9e8bd20, 0x3923206500fd552f, 0x9e84edfa318d7f22, 0xbf39ed52afbef286, + 0x14aab6f642d44a74, 0xb0a62fbfc5892235, 0x1a366165f7688490, 0xd2e08073c7bf45ff, + 0xa2d0e4c4c76cb6ba, 0x9f4b26244eeedbd2, 0xaef7d3ea371a5f2a, 0xc332763a928251fb, + 0x27ba32e191791c31, 0xd9c4e9fa0ceae1e1, 0x8a20645922d83bae, 0xe5398283813de7fc, + 0x4bff98a3422693fe, 0x9c039e9d8a8bf724, 0xe749a5cb250e2e39, 0x0fa6eab35f791333, + 0x72a7869640c1e204, 0x7d1ef8afee6dc328, 0xba36a840bf4f1aaa, 0x60b1862617df2f3a, + 0x48311dc258f6eb3c, 0xcd9cb32476b4ce2f, 0xb6dd7305fd97ed1f, 0xdd0ffd076511fa58, + 0xdecd394ca0ce296a, 0xd860373adc891518, 0x5ab2986bc355d49f, 0xee2649f41ab3ca80, + 0x3f541112ffb94f2c, 0x9f2e78aefc4ce245, 0xf400807e090b5c22, 0x3f68634ea47a6666, + 0x0c4092fa24184d24, 0xae83816f3e802aa0, 0xfc6c91cc37752a95, 0xf2459acb362c0bf2, + 0x1bb3e2abd387d84e, 0x80819a92e4d3e560, 0x3816b01fc0bdab99, 0x2607ff572720702b, + 0xf54272b250f3dd35, 0x0ba051fae77a316f, 0xe4a112cf58d2adfd, 0x9c8e263d82687016, + 0x2c9e53f5bbb0833b, 0xf3f5b98151fa8144, 0xe659b47342a503f4, 0xf6ab3a4062fc2b98, + 0xc6636e72271b9f94, 0x93e5b8032d040c1b, 0x60ff003dcb3e3d53, 0xb6ef2a0fb09b4e79, + 0xbcdd177ae7635cf2, 0xecc641394b4b4fbe, 0x3e30ca5f9a396716, 0x8fdf9dbb6fa5eeeb, + 0xe3c26acce8829780, 0x067a655315b7479c, 0x9423f280c13c40e8, 0x591b708cc6886a62, + 0x8467877981665f70, 0x3dd84fb9b0bf9d3c, 0x0619ba0ffa2fb3cd, 0x3c0279daf68bfd95, + 0x66df22b793e24fd5, 0x6aa1fcc8caf415d5, 0xbee73e922bfd1009, 0x8352368d9e053109, + 0xb0af8ad0e8b2cf12, 0x43f3d64291b5d1f8, 0xbe934fa98aec9e4d, 0x0e8e8621f735398d, + 0x57691d31e0aeeed5, 0x6f9fdfb2c77ad2fc, 0x9ff658c7991127d9, 0x2b8a90193bf378cc, + 0x469db0a3b183380f, 0x08afc274aeae39c3, 0x86638543ab7b2090, 0x6d8f4075235936dd, + 0xf314b42740a14d61, 0x7176be562c4bdb32, 0x659466e2de0c46c0, 0x37274c53add732cc, + 0x491218b323b2322e, 0x05d4dfefb3eb3189, 0xbdc5455c5675564a, 0x2b0670d558e56a7f, + 0x005b11ad29d7f580, 0x21a6336d7681cb51, 0x5d299f7ace7e1c44, 0xf376beda0cda1865, + 0xefc432133f963a1b, 0xad2e9711b91f2a27, 0x6e494c89c7655ce8, 0xcd440112bb81592a, + 0x41415fb1da5c87f3, 0x104bcd3cd4198a7e, 0x008415b4e6c607b9, 0x728e143643cdd79d, + 0x3dfabc8980ba1cb8, 0x09b126664710fbb7, 0x9e8d877b93e6562d, 0xcdd85a537bc2f4a4, + 0x92cd1512ab36cac5, 0xfb81157b9ed0fa24, 0xdfce2825f63ac7f5, 0x8eb4949d7c5449c4, + 0x026807bc80cd2f4f, 0x07b36f639a1b51a5, 0xb42c75313d1f6ead, 0x26511a245bfcea41, + 0xb1518a4088630458, 0x3092bf803e823a73, 0xe14047f410cdc10b, 0xd6f6d0e1c197858e, + 0x4477d03908e91b94, 0x3c9fa57383bab117, 0xef76f78b339a789c, 0xf3ee93b50538e108, + 0x3aadd5426afc3f23, 0x2b414eb936128dad, 0x4e3be797dac570ac, 0xc0282665fa849ce0, + 0xa1d8f8bba0cf8ac0, 0x395fd4da82b1374e, 0xb56aeb0a5cb26a75, 0x21642cf1ea575a54, + 0x79502e72c1dad50c, 0xe561df05718ecc20, 0x00d8b260bd8e5374, 0x764ddc5609a5ae5d, + 0x2fea1382d89a30db, 0xd8f4568b81ef610f, 0x76da90fc745a47e5, 0x342a6e541e9d0417, + 0x1a152736b5c5e31a, 0xb350bccf6ed30a47, 0xef9b31897c1cbfa9, 0x62ee149c3721a54b, + 0x7f582bae5d0bd0cd, 0xafae54979aaa48d1, 0xb5fd1870ab9f0b4b, 0x42bda68a81149cf4, + 0xc6dee9e9f076c19d, 0x954bcc961d4de9cf, 0xabd0cbc8e8d9d9a1, 0xb4580790be9b7980, + 0x784452821d47e832, 0xd79df172ffe433ac, 0xbfd4b86c15e55501, 0x7676603bb4880371, + 0x18e6a5d2d5577571, 0x9fab856341d54d6f, 0x12cf2e87eb12db42, 0xae9bfcf91028c85d, + 0xdcc366489da06b88, 0xa3827452f135b9b7, 0x9d163161fdd46ff4, 0xaf67c71f33eab3be, + 0x02ffdfff0f678591, 0x9d678a76110cad89, 0xd38d2486376bd009, 0x6b634baafe4bc3bb, + 0x1951a5ae48d308a4, 0x5b96ac3384adc05c, 0x2f07bc21790aa79a, 0xd276a51447486815, + 0x1b145e9b79d76658, 0x76bba0b4ce5049fa, 0xa2d07ac07770d788, 0xbdc0d5ecedc8e4ef, + 0xf46310c492d77bac, 0xba2c55aa4daa7a2e, 0xe37b6ffc2573072b, 0xf21972bcc9e2c356, + 0xde741bc07222e6af, 0x2061faeb99d66cb9, 0xa6126c03c6991817, 0xad3e4f95e403b0c0, + 0x35760a41b3e85db5, 0x2dfdfbee70a314bb, 0xa163ef61d1ba2da9, 0xf8d8ec41e251c1eb, + 0x76e11618235afebd, 0x438002db719ac14e, 0xfbc1578171521697, 0x96112dd18a6bd3c3, + 0xc1c9ddb7041d0650, 0x9ae7527fd9919dc2, 0xaafdcdfd74e078ec, 0xf71a70d3c52736bd, + 0x4cbe3600ccdb9cf6, 0x1f02a52c59b2be74, 0x5473482c3178312f, 0xc36ba15615dc9803, + 0x7dd8bd231f1fc0da, 0xf9291df737b537fd, 0x16de34376147b0dd, 0x6b1fc8e9ea8e8e81, + 0x5ef81a47717b67c6, 0x7038a9372fcd04db, 0x13126d6d0ba6c131, 0xf6cae068fe5a0c94, + 0x9b0cc4d8a7f98920, 0x979d179fd387e569, 0x8a74214862a9170c, 0x45f7d20fb7766029, + 0xa2f5fe86d87c47e0, 0xc26d6c27793f0d23, 0xe5b540046fb4f388, 0xb5d15f7d9e1b7ee2, + 0xaabfa187ee69f6d3, 0x076027ecd309d4dc, 0xbe08ff62e5a461ec, 0x201b91ad4e52384d, + 0xd312f0f39357d868, 0xde11041766eb6f9e, 0xe3d102b1035adbd5, 0xe3128eded0ba04f1, + 0x951000f1c9fba7c9, 0x39c6ed7edcfc35ed, 0xaea312a98376a855, 0x7a6aa72a5103a212, + 0x26b2c36358189b2f, 0x33d2d991a1b71c58, 0xf2dcc15b58c9a1ef, 0x3b56f5c731986f70, + 0x1a079f0e4bb5d9c5, 0x4bfb48d09919b5c9, 0x8826ed2b6dd3094b, 0x8b064b7caa428f97, + 0x95ef2497ca3b015b, 0x791265a8c4e96e56, 0x073724879c8c6ec1, 0x3bdc9cab5fb4a4ab, + 0xc4b38ae3cef98615, 0x495747e29eb17227, 0x3fa0f98dc4819bee, 0x917c6c66a69f736f, + 0x4fde46ae358b06d8, 0x2eedd383b092b1c6, 0x5d6d20c48404e018, 0x9979f406fa73fc22, + 0xc723fe61334eb916, 0x04cf48a680b3165c, 0x122ab4ba8ba6a967, 0xb0aad2bf607b07f7, + 0xc3e593aee88afdcd, 0x70a3b1dc9d87a3e4, 0xb3525636c03b4ade, 0x7a648a4c6eb5f695, + 0x5535916bf2c041d6, 0x685e4e85678d581a, 0x95d3e30c4cce25b9, 0xf2005369eca9c3fc, + 0x6d22463d8a760895, 0x3ba0b34af5cda4a7, 0xed2111e811b364cd, 0x6d100bf7cd920721, + 0xed7ceb85abd1e184, 0xd872c3786ef49fb8, 0x1d9015f66450d242, 0x6ffe98a91fc5290a, + 0x6486d9b82aac8260, 0xea290975ef381e71, 0x394e1b2f7a6e853a, 0x43d30943b2ca4b31, + 0xb6e7963ead61b1eb, 0x71fea06959c3ddc8, 0x7097db1db429ec19, 0xe4ac4a7af5061bd2, + 0xb46038f19cd05ab6, 0x31f90ae5e51e141b, 0xe819b8468582433e, 0xe147e2935921a50c, + 0xb503656ea67c5c82, 0x9278ad04f1ad89f0, 0xa21387c32b2c7765, 0xa5ea577352aa4184, + 0x44895fd59d61f926, 0x07b4267107b23302, 0xeb2c929fb29062f5, 0xb3606d6fb8042363, + 0x8d771fb68159e975, 0x3a4eca522ae02123, 0x82377672389cef26, 0xc4ffad7d01e0f7e7, + 0xf15c752cf76ad395, 0x2467d844c6e53e5a, 0xd96428a7f814a14d, 0xb876599d58c55752, + 0xef458f4a3216e716, 0xd4e874af35d20d5b, 0x88d444bd9f5ec741, 0x7a61a66f036e5d52, + 0x1a2055a0b4867eb2, 0x61ab001cd8e79ca5, 0xa02458f06b7587d3, 0xfca0656a588757ec, + 0x5bb1d1a62febcc7f, 0x039bab1fe708f85c, 0xa3133f4064f3067c, 0x6c10775c5039c333, + 0x4e34bb1fedb1c239, 0xc7b713d7843ca040, 0x53720d4afdf108d8, 0xe875341166e40bee, + 0x3775cdc55a548ade, 0x373710aacf98d4b1, 0x480ec684828d2846, 0x4acc2a3ce4aed95d, + 0x4416bd9713827a6f, 0xc5657bedc52ca85d, 0x2b7bf9a5c4c5c4c3, 0xe165efe664cea75a, + 0x7e0ebab20683b301, 0x3d5fd2d21542c584, 0xfbbe0d863322e79c, 0x1ea69ae0a21a6355, + 0xfca8f86d86ddd59f, 0x12de1aed13e6e13f, 0x050b0745841ba09d, 0xe7243296aea1a094, + 0x63f1a70a15475146, 0xdeff6afd1ca7f689, 0x08b2b01ca6336ef7, 0x1092b68187d87499, + 0x0f862a5c4e4bb5ca, 0xf789d66611cca518, 0x99dec34affd3840b, 0x4536c12f89790e40, + 0x67d072a17e1ec793, 0xa9ffb5b9073dc52e, 0xe82320cb5e34733b, 0xa57fdafca2ab603e, + 0x69726ebee805108a, 0x71f92f565487d39b, 0xa7d25c200e01ced6, 0x9b6ec8b2df4b5eff, + 0x46bbe1b46f71223a, 0xab58dcf32b3945c6, 0xcfe9a923fa30548f, 0xf17a3e528c1b403f, + 0x54f647fc1285574a, 0xaa2b2938d21b7b78, 0x76cc5022eb531b01, 0x3e79bf70d265e70b, + 0xe77820f85ecf1310, 0xcff89a3e49c990eb, 0x69d85c4d40d8f406, 0xa8017046a69dc12c, + 0xb1bcd418fa762659, 0xec576ddede953559, 0x178dae0125c13de7, 0x29c0771245769404, + 0x4df70525bd2ec33c, 0xdc32bcb3888a33e2, 0x3c48df959e1e86d8, 0x356ad9cd2e9bce13, + 0xc5757c399cef23f8, 0x8c6c15e67e2d8c5b, 0xbce611f2ed2a3f53, 0x08a2430396126062, + 0xecfc7c3e8baed266, 0x7156a42041e4f3e7, 0x3c2be02d9aaa8da0, 0x0269357dc4fca78f, + 0x301e9c823dee0e0c, 0x96c588306ef9e330, 0x452b23c9455e20c4, 0x9829c7c98ea86d06, + 0x1c779a551b3e66b7, 0x9a6e75fee7f1853a, 0x9d555c25ae2c180a, 0x5af4bb86318e2116, + 0x8b3425a634a6f0d8, 0x0885a23babaeb2ad, 0x719e10eadffa24be, 0xa1535e3dda36c28f, + 0xb70f842b5af8435e, 0x37a8d30d13bf843a, 0xda3d76d8ad1b5d61, 0xe2431dc31fd8fac8, + 0x4ed70865c392f94f, 0x89f3596e01245a21, 0xac5d432b604d5ba8, 0x6586dc13b0de01d5, + 0xf247169161ff3f2a, 0x579ffbcaf62ae1c7, 0x1d6a3f1cafc7e1e7, 0x820dad0c1f6dc67e, + 0x4c1f57bb29967bd5, 0xd09a2ca91aa55c6e, 0xaa4151c9de67f6dd, 0x87c3e646d414d653, + 0x634425b3ae877ebc, 0xfe6e67342f746b48, 0xeb8de2f05794ab82, 0x9a446ccbb3c84839, + 0x93349b75a338e5e6, 0x642ba855c2aced4b, 0x79d0571fe5582bb1, 0x334543300e63836f, + 0x20523b929a058022, 0x2e7bcf5ab0756149, 0xb3f520d6d1103c91, 0xfba5755b4feacdf7, + 0xc12bddfe1f253bc5, 0x7acd8cb202b1d9a1, 0x53dfbd82378798e9, 0x4a406a84d253bc2c, + 0x183f0c819b7c29c7, 0x9047354e786c44b5, 0x4a26540b61515bc5, 0xa9015a150c32c3a8, + 0xd1022fa5afe67462, 0xc2d4f0019074f297, 0x13f0a4cd55376b36, 0x1e6afe2e85feb815, + 0x51242e1de5638e78, 0x20cab0ec110561da, 0x73393aa3498cec89, 0x30a6a6d8759c8cd6, + 0x10c7219f12d3f654, 0x736b4bd4aa2643f1, 0xe7be54207fc95aef, 0xfed62eb5c7c877a1, + 0x2f18579c0a5b32d7, 0x954f0c82498d7977, 0x2670fd92b3943d57, 0x80436bcbe40dc0b9, + 0x505dcbb69b69e594, 0xe347bb418fcb7f3a, 0xaaf5b4f8efd9de56, 0x48c2c3ab5c35595e, + 0x44a1241197f6bda3, 0x2ca35f40fb68d85f, 0xd3f023250f3e4297, 0x9ed86826952904b4, + 0x695eacd5ddd9ac84, 0xa94001bc2d23e89f, 0x2c427e95c9ca9897, 0x68650d0077f6d2e6, + 0xab95eaebb03bad61, 0xd74a0c0a60e100ab, 0x5ba2bd69eccfdf63, 0x7ae89826231a2966, + 0xa40c9463cdddd7c6, 0xed228ec6528fb423, 0xd33ddd7e8ed5c5e8, 0xe4cbc63381644900, + 0xebed3fedb59f68b3, 0xc2d7504b8c123cc9, 0xff2b7a600daad47d, 0xff2daf312ae6e8f1, + 0xb631e821a282811a, 0xaaba6a171954114e, 0x2156d5efd072f89c, 0x6cc090fd8ccd6298, + 0x7d83358207a00e60, 0x7ffdd930ed5b393e, 0xbc85f92d10c3ae33, 0x0488e182fe76d6bd, + 0x1c55488b05bef1f2, 0x38d2406c013c2e84, 0x35de9a1970c11810, 0x2b7afe93f81a3d56, + 0x8974a9f85dba4963, 0x5e26a39b700917b0, 0x9a76f45979b13d91, 0x84d7a8c2b330cffc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9fff63056ed06552, 0x16f7b4c87092131c, 0xb90e9bcfae4dab17, 0xb8125e9e658252fe, + 0x8c25dd13a076c9a5, 0xbc07adf736a65241, 0x6eeb1e51349beaee, 0x26bc797fdb9eaf2e, + 0x2f5669b3ce11a3bb, 0x4fdba2b7c198efe9, 0x2ea8ac251cbd028e, 0x7f9376badf0a7d72, + 0xc5e86cefe0ed6b8e, 0xa49090bcbd540085, 0x62d4801a6355db10, 0xa1aec9f3a4f97c99, + 0x6d4b570bd67ad062, 0xcf1e644453990169, 0x80c17889229bb302, 0xc52a351d68069c14, + 0xa6ecf2981286716c, 0x47db518c30741fdc, 0x2d012d9e8165b952, 0x03db6b0164ff0eab, + 0x96613a86eb60f15b, 0x6de318d4ad689e96, 0x89845897fd3acfe9, 0xf2e7a57016a222f3, + 0x90a6d777d2968fec, 0xababa0d2bcec00a9, 0xa6e827f2cde70f2b, 0x288ff0e0f4bbea8c, + 0x5b6e4586ab850111, 0xd00bee510d6ddd4b, 0x35bb071ac55515ac, 0xd6b7f46fbb52ac47, + 0xb42e6eed275a748c, 0x17e1c0bf17835ca0, 0xc7532e72aa9f8003, 0x29ba4b5952830987, + 0xf1f5a3149fd03037, 0x156fd2793e8e0bab, 0xa4ced5e273813cd8, 0xa1e1175534f851e7, + 0x05f87942dfeb7f8d, 0x4302ccca16515385, 0xed723d4bc59b08f3, 0xb1b1efd6f89f11d7, + 0x6df08d875cae343d, 0xedda1ac9d18dbef7, 0xfa00d38a5c5a7c1c, 0x954ff6e3bf041b58, + 0xe9bd8be7e499a0fe, 0x8006a49904804037, 0x66b6e12c6b1c5172, 0xea98d1b45f4f956d, + 0x6abbaed1f5a7afab, 0x3d7be5124378e684, 0xd0620bca2c096241, 0x1dd75e559f41a0b3, + 0xe57497cc44d3119b, 0x47efa81985fb7a06, 0x6d3f76342a2e3309, 0xb46cb486c0d339a5, + 0xc7dac5f0538f219c, 0xce4bd4db3f948694, 0x014cb2bbcb80867e, 0x50f554ac56480123, + 0x042d8cf693c43868, 0xf8f001f337c85159, 0xe59338a51532d75e, 0xadcb8e25551bc121, + 0x49ef1791f5f2db36, 0x09f71f4f4d410864, 0x7ce2684eac6d0945, 0x9f36b07930708ed0, + 0x0b19aade7024e138, 0xc5eaa9c3c5bcecf1, 0x3f382a80edf41c9d, 0x3d123999223a623a, + 0xca17149f536e4b58, 0x0ef3bbe61b8b4154, 0x9fe3de8a4a096f8a, 0xe240d31c5de91f91, + 0x54f7abb0d90012b2, 0x04b29380d9fc14ab, 0xeb5f2def99af763c, 0x17ce75da5f058922, + 0x2cc4aacf32cc9e79, 0xf58d07461de39059, 0xa6fe23fe175e98e3, 0x9a023f88079a1a53, + 0xd886ee779ebd052a, 0x3e5b9a57ed495d9c, 0x1f3623cb56d3c78d, 0xe060005c487722fe, + 0x3c8d5f406e81615d, 0x5303d43bc8cbc36a, 0xc9bf2977458e6657, 0x4d51f825128a5911, + 0x33ca342ed031b2f9, 0xf665c2bf31d7989a, 0x07cb93953484b9fa, 0xd108efce983fda8c, + 0xcb4c4e27f473ae87, 0x2e08ef3e05a1b1ce, 0x00c30832ca11ee45, 0x6bf2f66edc60519c, + 0xc874317aa8b8e68e, 0x52b929eeabaa14a0, 0xe63c33659b399724, 0xf83bff706f87eaa8, + 0x6256b57275b19f1f, 0xf28505ab38af9596, 0x3bc8ef6a6773b215, 0x90ae2be7a3a9b6d1, + 0xaace2c0e6d8fcca3, 0xd05eb86b2620c364, 0x81ccf3f44063530e, 0xea0cd043440d5f2e, + 0x5cb05893f8ac9cac, 0x3b65c9e05161dd4c, 0xe9065bf23ad831e2, 0xb174d89c538fbff0, + 0x737c6c0931c46098, 0x34e2d54eae146f85, 0x8dd310957e5e8301, 0x4f366f390feebf69, + 0x8be452dde3250824, 0x5ee0d5d41e8e2068, 0xbaf5235908833c7d, 0xa2d51a0244f94155, + 0x3c9c6ee51284293e, 0x9e99e8209b0d6ceb, 0xae91ae643bf62a68, 0x218f2137c7b4d2ea, + 0xb036224a9ea361dc, 0xcd3b72467d671abf, 0xcf83c3699cc590d8, 0x7e1849a5beb578c2, + 0x412a2ab5c929e418, 0x44d556fb61b0fe5d, 0x70730310c9347d2f, 0x9aa3014e040b5bc5, + 0xcb151db8726a2df4, 0xb67041a1ae4022ec, 0xf255f699461d2428, 0x2e0955329cd0a099, + 0x43959a9d57529c37, 0xe0850ff2bdfdf267, 0xf28cd6d637f3379c, 0x1a42d8f50fa07c2c, + 0xc032a7f786aceb7d, 0x4f98709b053a3091, 0x53e93f8427406cd4, 0x7235ab69fabe0947, + 0xd0008cd9b53b8cb3, 0xdc8c3e533794d7be, 0xc6e2baaca5e9e49e, 0x2b5e8fecffedcfcf, + 0x5a03cb5ed5466d69, 0x04a0bb48b9f2d766, 0xa6e0bcf91906fc94, 0x6831c726cf0f70c4, + 0xce7be139ceb013a4, 0x2c186eafe6b0652a, 0x6c7f2ee803e1fb8f, 0x22b588314099b565, + 0xe8633df8d65f98af, 0x3a75f378e79d02af, 0x449064d142620038, 0x76fbbdd44ae367eb, + 0x7ce79605138593b1, 0x4a0c4af1f1c47d0f, 0xc80a65ae9df38419, 0x7bae43063576a3b4, + 0xff13d8c6542b7327, 0x20100e30057152a0, 0x0befbcbc7c08ada8, 0xfb609617a8e026b8, + 0x28ef02216fc3a9a6, 0xc2589b50dbbba5d7, 0xd50d584e9255bc1a, 0x707c09e31b1b5f33, + 0xaa258172f67bd62e, 0xbeea58a36695b84d, 0xc67a93000c0f52f3, 0xcad16445903beaf5, + 0x8153b5e3d0281db3, 0xe31fd3403c11cdd0, 0xfdda8df73d567bad, 0xac489db919a719f0, + 0x83d2bc8bd8e0ebf3, 0xccb8fd776f55a173, 0xb8abc54624ef1e71, 0xf2342bae89e745a8, + 0xcfadd9198c735374, 0xfbd2e115ddf7396f, 0x143d3176f865c6cc, 0x51d134587be1d336, + 0x76efbe8699f73149, 0x78df0de3d73d46a3, 0x19df058861e6a36b, 0x622621bdf84a3abf, + 0x98ebaf3b7f444afb, 0x94cb8297adbc2ad6, 0x67df6af749f1f833, 0xaef23c3c3a2b5a0f, + 0x6f717e8aa86ff80a, 0x1802af8496dcaae5, 0x36d66751c1071163, 0x04d51219daccb2c2, + 0x083f6f6de650c23e, 0xe0a2be9919946909, 0x3e76c4f9beff9441, 0xaa638d8600472e6d, + 0xf54fa672f3713565, 0x068fe5a532e5309a, 0x6782a8dfbec4d79e, 0xf55fb7c29a64195e, + 0xe4cf927096686149, 0x4c0b85fceaf31cab, 0xd893f18d82bc5292, 0xbe7cb406246129d4, + 0x6ecadf9cac9ae262, 0x67cf722a4663fbdc, 0x527e295332a50dfe, 0x3bb2e87b1e8a46bc, + 0x772769469b37047c, 0x1fdf6a85ff10126c, 0xaa319b9e3674cf43, 0x9c853dc70c64ba69, + 0xf0913cc13789fa71, 0x305c8eb03a2faec9, 0x33693dd35a15706a, 0xe23f265df187ac5b, + 0x7b4d5c35fe979fcb, 0x505ac0f400dec5cb, 0x9527ce1bc5e5f0e3, 0x4e4cc7eb6a55a2d2, + 0x78013649cf6c5273, 0xb43dcf8501e9c054, 0x5bfa2caded446e52, 0x21eee541f12ea717, + 0xd820d99ff5c1cd81, 0x34dc3edd0a51e418, 0x0922799f21981cd2, 0xff7687ff28da2a4b, + 0x0786f8627c665e1d, 0x4ad48ee2ebdb9e6a, 0x3f6c31355fb5ab7a, 0xf27593687352ab42, + 0xc556c002772525c2, 0x710bf2d413efef50, 0x070428bddcb5fe15, 0xb69008d569788ac0, + 0x3d2e61ac3c61f03e, 0x808e1e752182050b, 0x98edc6d052cdcdea, 0x4f2524d15e633443, + 0x9c3e4b5bad23fa76, 0x5e66063f9bf92dad, 0x44d552c2b3a746da, 0x8a9dc7a1362ad566, + 0x3fea0ae1c5cc6d3c, 0xfde76b07f981d666, 0x2ec8af109d628916, 0xe699c9e3027133c7, + 0x68429c228a7624ae, 0x2b98e8344dec9055, 0x2fd109acbae8b57d, 0xfa553dd831847525, + 0x7f24a2c356e2e081, 0x165d667dc6e3038f, 0x1924e2a67ec76f95, 0x6606d2cf05e14780, + 0x4549a82d0f9b9987, 0xe8fd72fd398ebe4c, 0x40b9bd22890b0801, 0xade91a571cbfcca4, + 0x998d91a20bf33ea0, 0x58d5377df803e54e, 0xd987c9e03176a770, 0xa736a18b9f91a55d, + 0x845a26ec07a12116, 0xf8811c2541b100db, 0xd99596f395f06cb8, 0x579fd8cb3b9c15b5, + 0x2f526d3f84cbe19c, 0x8b7635dc7030042a, 0xa2152bdeb0b256d0, 0x0cc163ea16760fd9, + 0x813185558748185d, 0x637d54d223be7bea, 0xa1d450591482adf4, 0xee7a9a3033a5a447, + 0x9c74d83877c3eea6, 0x416c3abc0d255eb7, 0x608acb406e6fd8e3, 0x695c2b91d163c73b, + 0xc1fc481a2e53ed04, 0xa1ebfcd69a28d53a, 0xade8bd3f872e82aa, 0x4e1cc2b0f73b40cc, + 0xc6b669c9943663df, 0xa9b7d27a3c7265c4, 0xd4154759ffe4fd10, 0xc6d26030b64716c4, + 0xc4193f18efd0f586, 0xb183a700e3dc81f7, 0x9589d916358822ab, 0x9ddf785e5462c282, + 0xc322cdc08f8fb49c, 0x749161d3f66b16f8, 0x0bc8b22096eb6f6b, 0x9994cf3176525f74, + 0x22dfb2ea8e332160, 0xf98703b6550aeb76, 0x884251bd16288281, 0x8a8136d0339ed5b9, + 0xa09f9c250a303164, 0xd17903f68a42a7c7, 0x9608f7fa9bc473e3, 0x130b63a6751fbdc4, + 0xece962a593657e83, 0x9bc03499057b817c, 0xafddb8387058e06c, 0x20fd27fabf02764b, + 0xce68367a84b23e41, 0x19a01c270872aabd, 0x050c2e5f35911cf2, 0x0d48290908056dd4, + 0xf75f6e273f4cb9c8, 0x5947bf61d4f4b26f, 0x7633490523f4dfe3, 0xa1a5c901b2c43ae4, + 0x240113e3cead4194, 0x7adfbf6e56d0f2b2, 0x8fbbc241e1e8f0df, 0xf537d5cea6b86a5c, + 0xc7e7162632b224dc, 0xcaecc485a8bc94ff, 0x117e6fb42762fc72, 0xb09b910051c37d7c, + 0x14617abe1c20b2fc, 0xa2eed56ba262dfae, 0x4d7443b749b793a1, 0xf9a49c97f03ff980, + 0x81a52cea6e8011d6, 0x52f0def20961df7b, 0xa965f4024a72d675, 0x6d87063d3f808e03, + 0x9165e447a625e892, 0xf431316481e1507c, 0x099956f28a58f74e, 0x89854be970dcd251, + 0x56e58fd75f15d2d9, 0x2e19af097a2e8471, 0x244f9488e3e63ba4, 0xea72d13010d6fad6, + 0x6e87987d1bf2a70f, 0x01bf79f6d9a53638, 0xfe047e0e3da19c26, 0xfd6fee1a809a5676, + 0x8a6c1da89f8ff555, 0x4146e879251a771a, 0x8cf748f79e4eb8b4, 0xb2992bc746a33c37, + 0x0e6335f9cbc0912a, 0xe517caca432b212e, 0x90937b67925f8a4c, 0x605d7a28eeb021da, + 0xdf6eace1e89d3c11, 0x422f81cc954e9b81, 0x523347df21f19c62, 0x48833da49e46a93c, + 0xf0cd96910bb6aa95, 0x5aa425689e99c112, 0x5e7ae2a4eb9ba102, 0x0bbd99327e9cd31f, + 0xd9f290515d0a16af, 0x0aa5602eeb618d74, 0x862ef84123c4fc93, 0x97b1ff397a68b7ea, + 0x58e16e6c61682643, 0x901f5b0366f83ec2, 0x3adc437adffe3a7f, 0x9246aa53f8a74134, + 0x16f72d0fdf3196db, 0x6c4b99463b6894a3, 0x95b23b3842f9b6b4, 0x76615ca0af99963b, + 0x617d2b25b67fa765, 0x1cd29cef9fd64bca, 0x3f93518612457e40, 0x7b66e0fd857eb150, + 0x81f67416cb319528, 0x401b4e96a528106b, 0x2a393ee9660b19ff, 0x64ecbcab3d59ac4d, + 0xbb2dab9255ccac14, 0x05ceaa5872412de4, 0x98a67a78fec304dc, 0x0f8452a74c537c37, + 0xd9ed7c1ca64e61e8, 0x5b50b348a83493d1, 0xde82ea94c5550a3d, 0x947e8bcb780b5e7e, + 0x1ee5c9a9e2b44b92, 0xd7bc9cda779a5df4, 0x78b2b38a17104c60, 0x824b41051ea46aaa, + 0x0e1fd4ff44c69bb9, 0x00117a5a17b6c97c, 0xdfb8a6e612d458c3, 0xb286213354c0d4ad, + 0x62a2cffa6762dba9, 0x5298013edc3d78f1, 0xbb4b454957ec57eb, 0x8f5add22901728d7, + 0x52a8cd17e89e8618, 0x9a8169d9cc7e7aef, 0x9b08cef191a82a66, 0x089da7756cc0e0c9, + 0x1e60986d89b98f02, 0xf7cbb5f3a511ae0c, 0xaf471f027b7a8794, 0x55e55e08c2242914, + 0x99713e7333efb198, 0xaebf60b429af16e9, 0xe97d4e473677d197, 0xdf26db7813321518, + 0x92378410d973166c, 0x2c086b4a98875fa3, 0xd587100b7c2707f9, 0x3f06cc904612d53b, + 0xb5154c8668b9cb28, 0x2a6e464d0f7a538e, 0xcde86bea4e6b6c61, 0x8b4e6d8ee072a8aa, + 0xf4082770f628ed63, 0xf1628f5c8f639ac0, 0xe12156c890fc5aaa, 0xfcd98a8e3db3cd11, + 0x70b886bdbb71323e, 0x591334c42fe35516, 0x4ccec87479c49a4a, 0x9312fe5d25636c42, + 0xbf0be15e1f0d65d1, 0xd04884671aafe2a9, 0x172c5a6559f716a6, 0x2a0d3de8470794b4, + 0x62a9679d0d98691f, 0x4799bed74a75f788, 0x58b1d9cd893c5086, 0x0abd11f76a2d4ae1, + 0xcbdc0bf75a38b630, 0x8727e93672765d8e, 0x6056a2e20265fcbb, 0x45e6609f5e21e9df, + 0xb6aefccc0b00b726, 0xc7564d3056a01f4e, 0x8d7c695e92b84ec6, 0x64a872266cd06204, + 0x44bc993b6e5f4acd, 0xfb334726fdd30657, 0xaa0780a016ede5a0, 0x297e9c7940d6db57, + 0x506c2af2cdf607c9, 0x2c74106c7b796afd, 0x00b758fcda17d6b0, 0x279b06468e816a8d, + 0xe45369e9934961c1, 0x8e4b29457c799729, 0x35c55e87361b3e41, 0x6cd1b014dd7fb686, + 0xfe9fda934eabfe5c, 0x7f57bbca71adf5ae, 0x72ec124b019f8089, 0xbeb2b9ee9b4d4af8, + 0xc6a646d10ed357a6, 0x22579964ff32f607, 0x68231561b7402873, 0xa18ad9f63f0b36b8, + 0x04832342e20876a1, 0xbee5943fa804e547, 0x4406ec8b17f63af7, 0x9d07615aaddd13d6, + 0xadb8fa68fa01522d, 0x390c27a285f21d7f, 0xd6a6312730c9cf8b, 0x8cbfca2994d6b379, + 0x4476b4082c6aa088, 0x02b5ad55beb98175, 0x9424f5bdfb53999a, 0xcdc9897b272d81f6, + 0x99b47cf98729e809, 0xd20844676b22b0fe, 0x41af442119291c6f, 0x3cbde034d6397bb9, + 0x4d8820d5118ffba2, 0xf1663b1dbba3fc1d, 0x739189d5439702e0, 0xaf15b3e45550c2ea, + 0x64d585bc0ca6cdea, 0x87ae19cca8217158, 0x5625c8522ebb325f, 0x801ef90088d8851b, + 0xc03172173ebefc6f, 0xa369e166ecc34af4, 0x8be4f434b7e4c69e, 0xd5e77d909ea9d2d3, + 0x9c6295b568de2401, 0xa22aaa960e9ebc0e, 0x40e3bfc59ca0c3e2, 0x9dd56217fb4c5923, + 0x32dcab906878af52, 0x720322437d6ebed9, 0x823aa90118b3a706, 0xb21c66b32725a46f, + 0xe49a8c1b1ae22f8a, 0x77ac50f69d5efc29, 0x761bd53357037257, 0x9977ec61ebbbf102, + 0x6133137eafb84a6e, 0x5f56651bd232b449, 0x7c5d7f3c5603f0ab, 0x5d0cebd196cbc2c5, + 0x9db8e902c03c80a4, 0x947334ef8f318866, 0x3438b99ef1599c20, 0xae442bf025a5d26f, + 0xede5d5f1dc53f0fb, 0x91f2e0054d264692, 0xafe7ec8cd6b0202e, 0xae1d6e887407dc32, + 0xe4320f849542343e, 0xa8e5ae1b12b37096, 0xde6cc0cc5fee0789, 0x1e8709aa68913788, + 0xe188178375c63d48, 0xd29f3d0d125573e7, 0x8484ee99d4fd88aa, 0xe905e1cb0ce0849f, + 0x07ce9e7059120857, 0xfbfee51f67d556b6, 0x2759569a7ff8c9f7, 0xecd6185945eb780e, + 0x058c6a5247b9d9bb, 0x0abf9ef2ea50708b, 0x940a6eb145ae0907, 0x99c0355247019e83, + 0x9dc961c5ccf21fc7, 0xfd9c9a094d47088b, 0xd58544fa708724fd, 0xce711325e966cb7e, + 0xb5a53a9e83f39e63, 0x5352bcf288153c7f, 0x20244e9ab46a611e, 0x88f9d3f9725a25ba, + 0x82f5b6b1a47d478d, 0x0a8dd8e05e13880e, 0x15caa05baca9b42a, 0x0582e8fbd3af6e9f, + 0xe7c34f70ad5acaf8, 0xc67f44a1660700bf, 0x86df10840eb9616f, 0x972fbe7b6a6e2592, + 0xbb3a9a8cbb994687, 0x4d0fa82cf8451d8b, 0x8e55093312c0d866, 0x4495b5604a155ed7, + 0xe74df3842b1323f4, 0x4bdf23455c482393, 0x7a9bcea31f687d27, 0x5514bcd3938cc06c, + 0x5cf2ab700360159d, 0xaa0d5750b2365b0e, 0xd49871205c927f81, 0x6aa5e5a4b943ecbf, + 0xbc19aad54882556f, 0xb980361691c04cba, 0xf7a589d3441c558d, 0xdc4a3279c16832d6, + 0xb1eed56d6ce19714, 0x9eddf1e1512c8722, 0x4e0059574dc39510, 0x72240f4843b140b1, + 0x5333c92e6cbb77d6, 0xf747d44cbf0c95d3, 0x80f65984a5957cd7, 0x0cb2b08a8c843d46, + 0x607c65a950034731, 0xc1ea51c0353588d4, 0x9f0232364bdbad8d, 0x3ae60690f3071ace, + 0xa24a8985fd98cfda, 0x6159a316f7719249, 0x827abfaeb7b28eda, 0xa6b36013efd0a178, + 0xc80f89a500763bbb, 0x28d98645f7df9918, 0x0e155da1d912051f, 0x176a3ebfe61b52ff, + 0x6b8f5224a181419a, 0x4903a615cb4d2415, 0xb8806e41f2634145, 0xc934e8045b420074, + 0xa4e02a16453e032f, 0x87a1bfba42536bb2, 0xd15ffdcb28c71bf2, 0x8ac28ff6891e13f1, + 0x8cc53d29ad2e0776, 0x20b73cc39c1914d4, 0x8d5cc999454f6268, 0x4301e02401d91af2, + 0x8720c87768a44d72, 0x7d04855b63f35a33, 0x754f85ae33b52ee9, 0x43c05867307b55ab, + 0x39a582e2c90100b8, 0x039d184991097fa4, 0x9beb296d9063a43c, 0x85eb829f960971ee, + 0x167ce75e8513eb1f, 0xb1c5f6044c2e0c5b, 0xc0f3543fbaeb27d2, 0xbe7a3aea58b7df53, + 0x3926aa324027f01a, 0x706d554fc628682b, 0x5a468d6b0eceafbd, 0x20f9f270128b2456, + 0x678c0361e3af38b8, 0x8e0b251d56d9fed9, 0x1dba11620128beae, 0x4b2543d8d7924b2a, + 0x56bbbca83ff47a0e, 0xb7296e1dccf77788, 0xe1d8a4ef3a69fb9e, 0x36e917d5c5d03257, + 0x4e13c8fcc7f923c3, 0x26a3d3c0e0818e16, 0xaa4d46749d29e0c0, 0x329cfe6400c1b95e, + 0xde43e96243e84a5d, 0xf8cfcc93bc35013d, 0x8db86e3ac1b0aa49, 0xc28683c1f9a2e395, + 0xb7e2361c646ac7f6, 0x90e90b6fc8cd7b47, 0xf9dcc995dd264a1b, 0x7776b1ad0532221b, + 0x8d3b80bee584be22, 0xbf02a0f6b593596c, 0x5949ad6370e81b5e, 0xf595994983843344, + 0xb9c3c8afa549a196, 0xcbccb44ee508c4f3, 0x84f91cac0a0f0344, 0xd9da5c8de0b9cd3c, + 0xfc6563da12570137, 0x79a516966238e478, 0x78558cfc20e7d312, 0xf3bfbd22f82dc259, + 0xefaf6a62ea0b0977, 0x7e2585b9d8362644, 0x6849d743fd03cd3b, 0xcfe1bf1e97811c01, + 0x507559e441a0ccfb, 0x319d14bd390216a1, 0x372a82222d9ee3b4, 0x8289dc0cd04a090d, + 0x9749e9439abfbec6, 0x572c1bc13130c8a2, 0xdf35d7c556fe8032, 0x83baf84f38531e5f, + 0xb1f21236040c8ee2, 0xfac1555c52766850, 0x810e4a5d3eb8e57f, 0x8335afc4864db238, + 0x6bc938556129ab4a, 0xe53e6e18e8420e6d, 0x16e8d84e6803a018, 0x62d5bdec8e5fcbf3, + 0xae2b57c86827929e, 0xbf03d1eb0b406ba7, 0xd1b3a633e03ac0d6, 0x1f9e439fb4ec51fa, + 0xb629c3469adeba4a, 0xefa11a93271dcb3b, 0xb6df0abe0924f6d7, 0x3d7cd9d5d7a48680, + 0xe76c2e7b10ff70da, 0x20c82b7924c25a81, 0x599be27ab017c943, 0xb1305ff11b9bd871, + 0xdd791722c5420313, 0xf63d4e7f286b28b3, 0xeae6a8890df45b18, 0x8582907264f4c8bf, + 0x85e5971f9368098a, 0xfec637e1968510fc, 0xb92b3406267ae475, 0xbd112b6183379ab8, + 0x704107677fa9a439, 0x595619008502ecdf, 0x109cc252ee3c2b71, 0x4d67283869a90deb, + 0x58e454367ec946b6, 0xe985406a3fa8a49c, 0xeb690e74fb08d4f1, 0x068b97eabdcc2e3c, + 0xaefa3a903f32dff7, 0x541f669d0d3f9e60, 0x5188ece0f95dcb26, 0x9a6e9834c2e12535, + 0xbaca7da307848aad, 0xdee41f1b2ee7b66f, 0x22db4bf842626fca, 0x95956038f2304e2e, + 0x37743e1f2f6fbe64, 0xaabed7a3d403ac8a, 0x408a2d4deac13698, 0x9cd3fb5e48c52777, + 0xa3fdc85671411185, 0x59c1823600667555, 0xdb56e3611e6b306b, 0xf8fd973cd8866a31, + 0x7331fd81be2c6cc2, 0x49ab1e27eea27211, 0xc68c58d60cb3a585, 0x8231e5193bdcdbf3, + 0x08c4f8349d267c83, 0x3ba9e2a0b6b45664, 0x3f13fc1837145133, 0x83821bfd0072e721, + 0x28de8915b4e1159e, 0xf9ef394c2586f09c, 0xc8f06bf70969d334, 0xd4af5ef796700106, + 0x0f92c4e0228ea439, 0x2829df2c0e48da56, 0x0c91787214d31d99, 0xeb3a315da0bf5ef9, + 0x875c1d45f3279741, 0x2ca30946742fcd4b, 0x4a43ddbc954da493, 0xbd2b788f2cd9fb24, + 0xe50f906f8ffb59fc, 0x1fe75fa82cc37604, 0xb60c41d399887631, 0xeaad8686a74cca3b, + 0x3bf38a88a4a31cd2, 0x82821f5444b5175a, 0xd4ef84b9645665a8, 0xcc3394e720472443, + 0xc3fd2ba530465829, 0x34e97a0ab53ce3cf, 0x8faf199b8a5699b7, 0x7c8a7b99fd979b68, + 0xea6b8faa1444881f, 0xaa1e600cfb60420b, 0x26f47384d70dc6bb, 0x47e8868b7bfe20ce, + 0x328fbdfc969fd182, 0x68bfa18447f1b24a, 0x8a030dd7921d7ca4, 0x73dbcb29329caf83, + 0x9f0fdb9c45b11634, 0xd8d8e88a2c8f46e8, 0x10c2f67486e10ba6, 0x75f6f1826e367956, + 0x1bf576927e586af2, 0x66933963990e8833, 0xb799605ab472c3e6, 0x88a324bc7e8b6162, + 0x7bbd2ac2e43e4b5f, 0x545233c03201e628, 0xec0f87d30badf223, 0x6d2f52461c051a50, + 0xa712e4cdab1ece5d, 0xf3354a689b2b091d, 0x39bc0f8831782b7a, 0x085411c03e52507d, + 0x316a427fbb094db7, 0x6cd2792b3b050926, 0x629fc555b860cc9f, 0xc0156a6007028225, + 0x3ca1e9910bd3138c, 0x5d63254142ea6fba, 0x494a3a9c63c8f776, 0xb26f5ad84210217c, + 0xd199876ea746f5bd, 0x49b14fe820107374, 0x99e407220d210681, 0x3a216a6e679793bb, + 0x8bba7fc95ee699fd, 0x48f7cf2b23cd3b9e, 0x1ec23384148e2681, 0x61e1d210f6441241, + 0x5853b56be2c3e925, 0x1b980acef7ab3cb0, 0x86de1f866c288951, 0x3be462f4ec6cf7da, + 0xceec9ff0c30b6da4, 0x321cc9abb9b974de, 0xe070ae7dd00a0c3c, 0xa9732653b3973301, + 0x990ce16d01770fdc, 0xe2f7edcca107b01b, 0xccad43e030010e24, 0xf6fce5d080908e31, + 0x7bceeb9344b1ec56, 0x38069c19ccfcfd3b, 0x08c6836ca798c6e2, 0x654c8064ac567a41, + 0x87b9513a66c899ba, 0x34f3f3665bc5cdf6, 0x16a6e055957c26d3, 0xde658c38f03f3651, + 0x97199b712e9be779, 0x3855210e438d191b, 0x07c9275d4215c560, 0x391fa47eabc9aaf7, + 0xc4cf37a5a247cab0, 0x492c1bf81981b196, 0x708ea5037560533c, 0xe5be547ead25e33c, + 0x7abb312f97ebc95d, 0x0bfc46916b589cd4, 0xf0cac89061226500, 0xc092019fc767913c, + 0x552605531b64a68d, 0x9c6017cde505474c, 0x1dbc1b2c7e65f2c3, 0x69e20ecca1fc5835, + 0xd4bc910f2a15d1c1, 0x75ba7f4ca84e8b39, 0x78818a6fec3b21de, 0xc30996ac86f1e58e, + 0xc12e27c9e77d0fe3, 0x58b9031a59cb3fd7, 0x925288a6eb9e358b, 0x0a34f57be5b1788e, + 0x6fc1876fe07828e9, 0xa0fcd6e291b3bc04, 0x31cfa3533eea0704, 0x6ad113c7ab419564, + 0xbb65625b13ab5401, 0xb140ce96528604e1, 0x04f590eefb401d6c, 0x3811ec178af6e917, + 0xb843fda8e03bbaa4, 0x9a05fa62e20ca281, 0x597488458f8f366f, 0x26c4efdfde40b2a3, + 0x32e53e9f16484a2e, 0xfcefb96ea6142f4a, 0x40f98d8d0be5b82b, 0x0ff86b23bf6b8758, + 0x7cc2e75280d0145d, 0xdd1fa456b29487e6, 0x510335ec7a7727a1, 0xbebb2c7b31ee4ce2, + 0xa59eb113f5701bcc, 0xe772e89000f76c27, 0x99629970a18ea142, 0x9d1553f3b2a0a401, + 0xab473f6bb149946a, 0x0a14d6af6fe56a76, 0x885ec1fd9ce5f2b4, 0xe975527957020c5f, + 0xceba8ed037ea1059, 0xffb498a2f537816b, 0x2465bdc000ffb3a0, 0x282dbc90fff083c7, + 0x552f9ae55f539cc3, 0x6767141fffbdd05e, 0x2b600d2a6c62e538, 0x46e2653c71395737, + 0xa3eb1e0f992f6fda, 0x10303b4c07ec5c43, 0x0c33668ed412dad8, 0xed6f376afaab5d63, + 0x1816962c3e952801, 0x9ac40cd85ac9b4e2, 0x489e39922c41cbc5, 0x0827d598ac2e21bb, + 0x06d3b76a298c45b2, 0xd2cb9929a46cebfe, 0x4bd020b85ead85cd, 0x848ff6f07a873f9a, + 0xa5c302501af2e55e, 0xd3ff788b079ef8b3, 0xd6dfc3757cf4364b, 0x720e338bf657beab, + 0x999656c2241a5745, 0x715dea9520e9623b, 0xf9e8d40622477b3c, 0x3fbaa7806fc0d3a7, + 0x0fdc1dad6722d0b8, 0xd34cb4a18532eef1, 0xb37ded46b620b0f9, 0xa16b4b4f708b9586, + 0x0fe8fa4777c1a78f, 0x8b9733b78da26be7, 0x4c632811dce909eb, 0x16a093d884efaf56, + 0x239704f1bbe4b757, 0x769a003cba827580, 0x52d240a7a2f003f3, 0x2d6d9112f509c899, + 0xf69f3aea26693bc2, 0xa594c3cf013560a3, 0xc7caca5ba87cf3ac, 0x801342ab9d6a2ff2, + 0xfeec5dcad9c772c4, 0xeee901dbd7d5c5fe, 0xb5472fe8bb252bc9, 0x2f1c2c8037b14915, + 0xb82e0db42c1c9026, 0x47b1e1610d4d7fd1, 0x8a00f0dd1e089dcd, 0x4f9596c1ceb8e7b5, + 0xa02996a478a38feb, 0xfce1793f32e96f5a, 0x5b3fcca31da4e596, 0x596a73f831c875ef, + 0xb65198aa20147148, 0x01c6dbb4445c318b, 0x867426fdd0588d9a, 0xf1e1fb01ab132e53, + 0x975ec7976017aab3, 0x7986011fa500ba15, 0xf50ff024fd34849a, 0xcada091ab329e7e8, + 0xc6366a31fa5ec4ed, 0x8efc2680f0f349c1, 0xda3ccd5a4526e85d, 0xac322f6aee1df187, + 0x4aca5c28ac0e7209, 0xf789d85e58e7d0d5, 0x7d82ed034a4ab206, 0x05269ec75fc7ef10, + 0x34473760efeaaf06, 0x84f49c5880d991c2, 0x82a07f1f1b69807d, 0xca1edeb91bfdefb9, + 0xaebf8371cb58fbb7, 0xd641eb80c05a9ae7, 0xc4c418faf2cb3d6f, 0x4b0955bcee4ced55, + 0x8f651d63e98da60d, 0xdca8d0628c575507, 0xb2df84ba8dcde049, 0x495442052b64bd1a, + 0x1205884daffb23ce, 0xd5e41a03238a4571, 0x187a62eb7f96c5df, 0xefb28c5bf15cd18f, + 0xd8361382ba4949e7, 0x146b048b68fec98c, 0x06234198d4d18f9e, 0x72af49a5d13408f5, + 0x43a4a16444731e00, 0xb67c18fd11e9317c, 0x647094ee94599b74, 0x90ce5aa4ed513535, + 0x3226691a04ff7308, 0xafdaf190f3988cd8, 0x58f3c46e7db9ba88, 0x54b5c41edca0413c, + 0xd0ff3029ff70a694, 0x23a33c7fe5509322, 0x054a78d77dbf528a, 0x27dc97c39c64404f, + 0xa8116ded920b1796, 0xed7ab63c678ca8af, 0x7b404ad6924dea39, 0x823fcdf42d9e8045, + 0x9f7588a978fdf07f, 0x07758e66ef3313a4, 0x3aaa8ac0627ab5f0, 0x2abebff0ff0139aa, + 0x3437f9479ed4c802, 0xdd3b84c4da55d3a9, 0x27b9344a5bb14d45, 0x2e1c6bd73feaec76, + 0xe8380f9b95a6c146, 0x4bf989ad70963cc0, 0x6fba5498ed87d769, 0x5c24288c7af84318, + 0x07d157ee29e54c0a, 0x1df9e390a4802e12, 0x765364ffda4e6813, 0x244cb8e65df37c6c, + 0xa767da3c4207caa1, 0xe29c4a1aed3cf6e7, 0x26266bb56e7bc8da, 0x9657c29419edbf86, + 0xe2c2a2a1cb487df1, 0xbdfe6c6f85cbd3a0, 0x827fc2be36a7bb21, 0x383f45234b681e08, + 0x5e04daacc0d8b5b6, 0x149bcaa40bc3b207, 0xc7bd5011099f6c80, 0x3f9af18ac0be9b3e, + 0xa8f066a5eac34d75, 0x9260cc0ff1c8d34f, 0x69020d7a5361d391, 0x6cc6e3de1e93d6d0, + 0xc70021f33ec302d6, 0x5896bb30a38b28c5, 0x59e52eb04e9eee0c, 0x664916e01ca501e9, + 0x5cd1a736a1ebcee6, 0xbba9f2f3532fe3dc, 0xb535fd248f5f9bbd, 0xd65b2f39a2aac0a7, + 0xad5be0533da27799, 0xb5c846f41e8c75ef, 0x4fc05fe4da228245, 0xeab41a97685a3530, + 0x74e0c29969beb1c9, 0xb59baa39371b7adf, 0x6f0cadab66105bb6, 0x0c43f1cbd897940d, + 0x6e5c89bbb1b2e70b, 0x4f334e81a9fd31a1, 0x5dcaa8633242d778, 0x08d44c3d4b7ead5d, + 0x9d74c73b2833bbc5, 0xad33932bd78586b8, 0x2f6f3a983211c3c5, 0xf8cf4709361d5137, + 0x604725ee8bb33190, 0x3b3d9b919ef4ca05, 0x1b0ae3e23b01abb6, 0x10d14d17405634f9, + 0x469f42edfc65bb99, 0x2b6dcf18e6e2c503, 0x1b5f7e3447648c5f, 0xbfdc777a994b050c, + 0xb54278a4769e039f, 0x2996b8b9ef87fcb8, 0xc83b83c6de49b922, 0x8be8f792de0b07e6, + 0xfaa33c2d2b6de01c, 0xac3e15274a312aa0, 0x9eee85abaf283923, 0x97769f6858985e47, + 0x33c213f7830ff1de, 0xd1d84b843c10d0c6, 0x8b611e2ceb355d24, 0x27e1735eeae23f72, + 0x144a1730cb935c3f, 0x4f14210c9c20a2a5, 0x900cb58ba8ebbcb3, 0x1578d49fe24dbd16, + 0x121aa314ea6d37c6, 0x1f9904b8948c5751, 0xf6c3521e68c74e8e, 0xeca2203e2f9f6847, + 0x4672d5beb197e7a6, 0xdf05b184ad194fe5, 0xf5e3e7b4c9dacc01, 0xed071e5d81abd956, + 0xa85b2e41ae264934, 0xee11dbddd2ee4c93, 0x28ff8ce45b43aed6, 0xf1f694a7b1fb7520, + 0x5f1b92e517bd909c, 0x4e096e8b49275bc1, 0xac9b185d8d34943a, 0x38262c1cd4cef2d1, + 0xcc242753581651ca, 0x3c69f58e17b2fb5c, 0x3614e52193c5386c, 0xd5b66e2ad5f6d3bf, + 0x4a3601d8517a93fd, 0xc08a0db5350b593d, 0xe6a983df7722335c, 0xff27a0bb09e81b4d, + 0x70aca3db006205c7, 0x45af8e2cfe38f335, 0x462c584580741a32, 0x2dfa6a0a7d11075f, + 0x205312678dff6a51, 0xe9dd76eacff76d27, 0x3ca8a3a9a554bd2f, 0x82571d7ace0c0d3c, + 0x05cfbad6e6999caa, 0x3ae0c0490f3a7420, 0x29dc4d9e68ff0e38, 0xe4e3a519d8301fef, + 0xfd8f8e918460e5bd, 0x1a78b52eb830d1eb, 0x360829c56a60b77b, 0x588786d4feb605bc, + 0xd7bf0bccca749119, 0xb8ef7b9b50cd91ff, 0x8c828af8ea8605cd, 0xddebc5f168b6bf6b, + 0xcb12193cf26568b5, 0x7c27b060bda2ff75, 0xca32e999b23db52e, 0x2acb6176f2ecbf6a, + 0xfaca13ef16ca5bb6, 0xb7d5595188edd9fd, 0x28636e651aa71a34, 0xc606cb2caf3d6c75, + 0x38a4a883950f4a53, 0x5f77fb0de3126589, 0xe1bec50c602fbbad, 0xb73da0aedbdfc019, + 0xce782f1afa15cbbc, 0xe6d1d76fa2aead58, 0xd1fd713d55891459, 0xbf91fd37f603eff4, + 0xda70a89a2e041ec7, 0x4598ba9d0e3a83dc, 0x72553c0149ffc263, 0xe8b930afb24b3259, + 0x7998c1a51085c774, 0x08fd65b507f3f68c, 0x70dbc9e22d78a30f, 0x1d222fe6069b655b, + 0x76b4929fd3921cba, 0x953fa38dea759538, 0xdada6ae58251dd97, 0x04c3ffdae12dd29e, + 0xb9a9d8efe3cde8ac, 0xcfd609c8c9f881c2, 0x59722f8f51572edc, 0x1a26fcb6d9fdd73b, + 0x1f149a030a181d2c, 0x1017f491ed999b3b, 0x535c7547db2a1544, 0xa04b28bb86b3ae10, + 0x76f501506607e2d3, 0x7a71bb6a66009ef4, 0xfd03741f3e6fcca3, 0x51d4eec2b52d1b5b, + 0x073541a42e7cd472, 0x85f1a9db461cdbf0, 0xcf86c472c17ee155, 0xdb575f551fbd5811, + 0x6beee48583b86c90, 0x8b7fdc6417104dc3, 0xdeef019d38fe6882, 0x163b50e956d6e77b, + 0x381922066f2e851f, 0x4e6af2df98f18221, 0x5221bef4f5b57c4a, 0xc8d6ea9ce2126155, + 0x232ef1e5df4cdaca, 0xce275d47285a6478, 0x64e8bc6d0a98d3a5, 0x51f57571d1cd6ca0, + 0xe3ccd76179f9941f, 0x1f145a50e5802719, 0x0005acc495c82230, 0xd7f64b316b12d83f, + 0x8cda90ebedc86806, 0x4f736d91c47fe2e9, 0xe27656535e9f6f09, 0xf2b2da697f9c0e77, + 0x5343f8c0c7aaa07f, 0xfc76910d262bd14e, 0x97f8278ce9846137, 0x6b2558b4938b9d36, + 0x226109e730c0631c, 0x9759a6f0eaac1387, 0x8e77b52b67a64c3a, 0xd75c58f243ebccf3, + 0x2a850e97fcc41382, 0xd853f63824a2c4e8, 0x057713d3c0341474, 0x604659ad6ce78e09, + 0x57b5939877e2e998, 0xc226b55d553bfb4e, 0x846f0a7dee794c11, 0x053013a2bf6bebd2, + 0x8bf07927b3f8e3a0, 0x91758fa1c4cb529a, 0x878e0430a4139a5b, 0xd095e358e0df995f, + 0x392373d5b30d775c, 0x3d8fdfa90b41f300, 0xe600905df87b0a2f, 0x499ed1479da075f3, + 0x0e2a55c98a1628b7, 0xc344c05c8173a765, 0xd5d3d0021048a238, 0x17a3ca0efe93c608, + 0x23182f232d34f7fd, 0x4ad2e5000cbd41b5, 0x5bc59f0635ea7078, 0xd01d41195bace36f, + 0xc1978af5e4263ffb, 0xe3ac1f051ac8d86d, 0x54ea33595a7ac7b0, 0xc8b4c9900be1fee6, + 0xaa71a51abdecce95, 0x5709cff0f13c00f8, 0x742cb76c2bcd4db3, 0x8b3b7ea2aaf2343a, + 0x650f17653cc0ba79, 0x742eba9028d92167, 0xbfeec4c2b49ee002, 0x35344b15ab446d09, + 0x6c161402a175da04, 0xb15df1226bb590be, 0xa2bfa36b8dd8fb91, 0x5d2b3abdae96f6d7, + 0xdc4609910830c92c, 0x3162dc69ce707a8e, 0x6f3ddc96e6c83606, 0x00707e47619604ee, + 0xfd970ec2e42d91cc, 0xc7abf0e077db4def, 0x1c62a972cd6005ab, 0x836d5dfa6767cbf2, + 0xefc2d53800ae5d4f, 0xef75efe8ba8f7b13, 0x59a435ffddcd3ec3, 0xbb3ece6dd45a6d55, + 0xdb0523391631fa66, 0xd662a0682a3d75d0, 0x820c6154facd67af, 0x0cfff3b431c7b607, + 0x81497e4176a93d61, 0x6e453865d397d157, 0xedcc715f50507d18, 0x61626982bf818067, + 0xe382f615a1d4ded2, 0xc183af47f16b9e72, 0xeeb28f1cc597b79d, 0x4132b505ab6d63f8, + 0x5c1106abe0dc3374, 0x2101209ed9eee34d, 0xf9fb57c209237d05, 0x1c382b0b64d2c1ef, + 0x54f89881f3a8c0b2, 0x190df8d3a2307b34, 0x6952688f222cdf94, 0xe9c83d0fa508c042, + 0x34bf602074019c5c, 0x58f64bdc0dd56088, 0x56c9a8dea34fa786, 0x867984e5f0926e2d, + 0x454636fd4fecf7b5, 0xcee84aec4a11cad3, 0xacd6f88b2cca9e65, 0x4cddfc4a6e624cd4, + 0xa813b951706cdc1e, 0x3cfa682584240e5e, 0xa1e5ffecdcbd78ec, 0x92d687f1927a8703, + 0xec8066371f9875f0, 0x91e36e446a1e3849, 0xaee35a45e145af4d, 0x3a90c2c7d34ee428, + 0x83d99072f50016db, 0x1b69da37310619d0, 0x3754ac49f343b6d7, 0x711dbd1b3f5f63b3, + 0xee2be08da4b3cc0b, 0xe5c5c366ab9e266b, 0x0b2ca7aec0f9537c, 0x6a1590f73390b0e3, + 0x6e7d1b3bf82987a0, 0xc55c8cbb82a8fa32, 0xfe08f7a4eb594093, 0x53a2926acc0aa38f, + 0x15c80f4181b078ca, 0x5e8e24be9ff1ea84, 0xed58e99bc9606b9e, 0xe3dddc1274d5d571, + 0x52da2316a8530e09, 0x7335e514a196ae1b, 0xab6892ebfc6ed293, 0x50ebd74cd2795e1c, + 0xc13873186756abae, 0x92d32cd9074e5b56, 0xb0d5d0f342e240b5, 0x846ab88374bf93e0, + 0xcd5ed721f2f40277, 0x84dffee26cd3d1c9, 0x68c0437f0c238d06, 0xd5eb1c120781880b, + 0xcc7f8080fe9ef950, 0x888caa55f6d2d73a, 0x7c730ea467066db5, 0xeeae843c589ffcfb, + 0x8a9d642663b883c2, 0xf4431463bac58685, 0x4d6d237a6b954806, 0x0c26287f17a7cb4c, + 0x7d586a62409ab38d, 0x942e28cb654c60d7, 0xc66df1a5f7f63168, 0xbe1ada5199f63c6a, + 0x797bb5be10fb9c20, 0x62fce3883fd0e0c3, 0x6083ea23d0f32003, 0x6a6d7e7c86f66b24, + 0xde1629a883d02b25, 0x5f7c946de31ac3ec, 0xce89ae4a0fd74a02, 0xe111d5ac76925e2d, + 0x8d81d00c03ac3d5b, 0x0c0ed13a0e582272, 0xc54be40e28af5761, 0x4cd0572cb5973d51, + 0xb5d223d400197b15, 0x647784e215daf73a, 0x9948e164299118f5, 0xe27dfc3596385d97, + 0x59a247076fc5c2e7, 0x6eddb858362a7b10, 0x10114433dcf2bdfb, 0x72460c1c2881dc00, + 0xea907ee1a06b3470, 0x3b97bb9d681af6cc, 0xb478183ee431b461, 0xef613c0115afc950, + 0xef7a0adc5462afd9, 0x8faaab7312663ca4, 0x87675cbb7d7a05e9, 0x45382daecabcada0, + 0x17020dcb04fee655, 0xab3ec291d0ab1327, 0xcc49704bbffd9e40, 0xbe97e1652957b6f5, + 0x760422c50de47577, 0xb07df651f5dd48b3, 0xfcf513c4b3744628, 0xccab180b2066918e, + 0x5ce86612c1b03ec1, 0x0a93fff351e3d389, 0x61ffa52886af63a3, 0x01b927a7e38cb0ec, + 0xfd2331330bbe6289, 0xfdeb6206ed6b8a71, 0xbedca7b4ff9ccf34, 0xbad79abb970a032f, + 0x2e1dd3864837bf8c, 0x113c14c085320816, 0xe8945dd407fe99cc, 0x48ed3b11a81267d7, + 0x4a72e9f3159125a4, 0x08117e1aa0cd5298, 0xd70777b224e50038, 0xaf5701cc12048a10, + 0x499165850104b65a, 0xf7947ab62d94668d, 0x22418360cb233699, 0xa1b52ea08cb59ed0, + 0x38239f7ebddcb5ac, 0xd873f0b6db8118e9, 0xfcfef97ddc56fc22, 0xc75b8d1324914611, + 0x51d3bad5d378bf32, 0x3dbfa01e914fdf02, 0x4a449831f36ae56c, 0xc27e816f7de5d9bd, + 0x76018ae54b895f17, 0x1932e8890b604dae, 0xa2809df5b614901c, 0xab31b3e4c7368ed7, + 0x281ea8612b3a1886, 0x902f72fa0a132a06, 0x75da545fed4b0e0f, 0x3afa68ca0476795d, + 0x72e44152fa7c5686, 0x5f550efe5379fd2d, 0x2ac0423ee3ecd87f, 0xe37f5ed6112c7581, + 0x5eed3ab728b6f993, 0xf3ba844362cf42eb, 0xea0fdaf57923e0b0, 0xf9b8cc5885234282, + 0x64f1848af81ce39b, 0x687a4497219c1528, 0xe0f0a906f2cdb1d1, 0x88f9480c70d6d687, + 0xf76db6d594c94361, 0xfee4d5e84c7018a0, 0x922e90e355814206, 0x57006a89d1339e59, + 0x3c0e893b39706490, 0xb6c519d59167f451, 0xf7ddd60edf332d36, 0x968141207d2ec8e4, + 0xc16ab07335814eef, 0x9acfb32f94dbcd5d, 0xc4a834230c8cd921, 0x2c50ea3ee7b38d83, + 0x46ff8f1438c03818, 0xca901081f14675cb, 0xbd55a448e2652b2d, 0x261beffdbb6e993b, + 0x5805af86bf3d34e3, 0xd5ceecc4a9809a1e, 0x9317baa5b16cec63, 0xd85d4df7e7c9b684, + 0xe4177a404f5fd291, 0xbfd99e0c6e7f5450, 0x7bb87eaf42538e06, 0x8403a4e6462d3a34, + 0x2ef3fbbca9a4a317, 0x9a084b3f7e410e06, 0xb143f64210db5f57, 0x02b161d36ba99ce9, + 0xf8f354acb112d000, 0x359f9fa65f2d22c9, 0xdd34e32af13c4b69, 0xb095b2a711eb7b3b, + 0xf5a24e18c5176949, 0x5119c6f441c0cf13, 0x887d88ced2b194f4, 0x8dd038726551f7da, + 0xe9a61bc62999c5b4, 0x7f2d54bdfafbd5dd, 0x73d617d7c2fc57c9, 0x5000622e23ba305b, + 0xd42ae65d55f75afe, 0x9efeaed46a53e9ac, 0x632a3a3b95818193, 0x6e88d3c2c48cff61, + 0xaefb9b9c5a9d4998, 0xda16fd443ebcff9a, 0x902c8b6e66523aa0, 0x0a53d0e35a7d5685, + 0x5f1f719cb4da6424, 0x03b0977e9806e260, 0x702662b8d78dcaea, 0xb24a194446eaf7bb, + 0xbf69873cdc647cb3, 0x39e886bcc1cdcd41, 0x1bc22abce6ba1c5a, 0x315b3955df3fc818, + 0x951d0ab0216085df, 0xd914cc491438ab13, 0x1375a2a767334efb, 0x29402a9cba62afbd, + 0xc889036dfae9746d, 0x917e2984e7be3d7b, 0xaa7451a5624da045, 0xdef2e0b9fc16075e, + 0x954ad6b178b297a3, 0x8243532361710b70, 0xa4729aace0de3b1d, 0x8c7d567099b6d80b, + 0x32052d0327f0aac4, 0x614fc675dff83d6b, 0xdbd83b12a31b637b, 0xdf75f194513651a6, + 0x20662b3e70845ad5, 0x6b5de9c6eadc5262, 0x15729378c91fa0aa, 0x7070517cf138e9bd, + 0xc1aa52e03a868035, 0xd7874f50b539e594, 0x6e7f37260dd86e02, 0xd78886470bc58ba7, + 0xc7b5b6690ce8b117, 0x29dc066aeb14d787, 0xa67c20a533748a8b, 0xf1758f17a0bcca24, + 0xb7ea0fa7b4dcd809, 0x5526d9578ffd1dd7, 0x5d2805c6d98817b2, 0x8bccc935b447a023, + 0x92371bb02f9ea2e0, 0xa464d4de1addff2d, 0xfe7180a21c8e1bd1, 0x36e4c01f8005fd5f, + 0x39da62284cc1172e, 0x9f032d139116f2b1, 0xd9139a80f0184080, 0x5a8d6f60de16720e, + 0xd3ad78b8f469cb73, 0xf1ff00520eacce91, 0x2e4e95d6a8e76042, 0xc68768a17df33be6, + 0xf27fbd831665cb6f, 0xfcbfb1ca57ce6045, 0xed389102a306f86b, 0x204947a7f0de5c06, + 0x1166209c56c79ff8, 0xa3ce3e66419b8f2c, 0x4a3c7c64794f1442, 0xd2632eb5fb662b52, + 0x91ef7e56b696fdb6, 0x7df1b51a117e786e, 0x855ffb90aca755a8, 0x4da23c8af2f54e71, + 0x87c5c88d9dfd2b2f, 0x75fb54142d353363, 0x957e247e8c00ee17, 0xca8e6a442156693e, + 0x68b681ea202918db, 0x237ede2cf15100fa, 0xa495411c16a15f1a, 0xe88b455a0f862e3d, + 0xc3c28e2f1579f24b, 0x67232d6b3e54b666, 0xed11844314a0e60e, 0xc224773722ca60c9, + 0x36dbe697ee2d7dd2, 0x76652e79684d2085, 0xa1cef157fb8ce2cc, 0xd7df29bb7e03110f, + 0x6496c6d22e545314, 0x1338673d1a164490, 0x3db9cf48591705ce, 0x19c760d015f390ab, + 0x34206c7f7c971db6, 0xc5b3e00e35b0f9e2, 0x0f503360f597ff97, 0x35642f97d1d83643, + 0x0010fa1dc824ae7b, 0x0870e6618681e977, 0xcd45a40d55235f6b, 0xd89a1a2de58e9efb, + 0x5991b7db80f3a972, 0xbcfc8b150e0ff97c, 0xe6b012aa9017460f, 0x1353d522bf20c7d2, + 0x6883acb1c086410f, 0x95d1fb26edfbb9eb, 0x2d98dcde791e62f1, 0x9e0a0a7b0f9ee82a, + 0x0fe5d4470ff767c0, 0x73ca1a2274ad36dc, 0xd41f65c3509bfb78, 0x9b1b4c7c32c7ac51, + 0xa3efda8a19edd0e1, 0x45fc9c0576d49384, 0xc99a6dbe6dd38bfb, 0x83e58701a29e8c8e, + 0x515221fe1a012637, 0x4e3ed995e203f23c, 0x312e5b722a9d76e6, 0xc9f0de9a4efa4b56, + 0xae631e518c202bec, 0xef7823fb57828cf0, 0xaaa463b7ccf2362d, 0x815a3425403f95ea, + 0xe6169ead672eb0b5, 0x77066c1b6f196bb0, 0x7c2c2eedf3ac84d2, 0x43f968f2fa0b6337, + 0xc86ff5fa71619540, 0x9790559e56825ae9, 0x76620f49b5e4be1d, 0xbe8b9bdab3ed26d6, + 0x6ec5987738734d7d, 0xafcc34832e8fdd32, 0x3d71b5c721e7fc48, 0x68dee549a6fb714e, + 0x37bf93f4723e0b70, 0x3a3e68a808586d7f, 0xc91149673e33245e, 0x92cac9da577088fe, + 0x6d495e8b3a7c5558, 0xfe2bafdcb54a4734, 0x6f049a91ed1313d9, 0x7e10a03b7132a702, + 0xbe62ea0eb4d7c99f, 0x54a506d50e10cfe4, 0xb009678ad4ada076, 0x6a2c4206f3bec9e9, + 0x347e7375960e2ea6, 0x9e412d3d7f26a136, 0x58d32a80537ff4e8, 0x75125a58fb56c3d1, + 0xe6f15f5abf437d65, 0x0fda7998cc004f14, 0x11c35209411731ac, 0x04ad89fe669905d7, + 0xc19b043f49da2d97, 0xa8e165967245b5d7, 0x1060b3c45890ccd5, 0x86233b724861eaa3, + 0x7a0c95dc3cbc4ed4, 0xbb4f565074f786a2, 0x44c8f157b9cfce9a, 0x249eb2eda6565f95, + 0xd84c660a901e05ca, 0x062a13c2ed42b65f, 0x7492eb250a8aea1d, 0x5a2673df7c810904, + 0x4bc5b0f9a3d1c77b, 0x6779c106b9997281, 0x94edb58126cd1437, 0x40e34bc020d96732, + 0x150166ca4bf4b2c2, 0xfaebbd0975109cdc, 0xc830d8ef909c6dc4, 0x9060b55b38eafd81, + 0x9de246ea380969b7, 0xca5341007c9d8203, 0x1db6eae3952bfc84, 0xf3b5c74c1783f85a, + 0x4d0d7a6b26e7aec3, 0x9cb9e76938a05b3e, 0xb83f9428e7470091, 0xe793c6550e251499, + 0xbdda4e5993c28417, 0x75c92544222d8eb5, 0xca8fe4309f557dac, 0x50259f8d866a551f, + 0x787c306dc946bd81, 0x7b1eb668beb33124, 0xfb8ef11830bee372, 0x2450cc4f6892232e, + 0x85db68d6c6b46990, 0x9ee25c9577212fef, 0x923db814c5d0fbaf, 0xe8c5e6030f68d42a, + 0x31762eec73ab953c, 0x2edf9db4364c2d8a, 0xd89b7cf7d6b2bb5b, 0xc6ea595a0f8d7bd0, + 0x1f49b9b46c540e5f, 0x593280a0014e1853, 0x9df7da33f2c97c44, 0xee4cea1132990811, + 0x68d97d7be0719ef3, 0x4fb07d09d9a71914, 0x6563f8d23a04199b, 0xc9bcb42d511d41e5, + 0xad8518f9119bdbb1, 0xf5eee74d2c083ceb, 0x84339f3983bf3821, 0x77f38bb799e66f72, + 0x6384836213cfe568, 0x31b19272b7d6e282, 0x8ebcb989427274b9, 0x83ad16a35ec01c20, + 0xe40d88ab034bd5be, 0xe5d98304c6b8f902, 0xf3e1b6b085ee44fe, 0xeb69024b8c67c3e7, + 0x871530b5c9c379d4, 0x3a6136e94490a298, 0x74d8ac991c2fd663, 0x56b017fa40f23688, + 0x21d0835b0b4e5d30, 0xa4e6d23c3230da4a, 0x3cf627e6983fb667, 0xe07422ac44e5d0e2, + 0x7ec487eb1cb40a8f, 0xbb8b5c00b214e189, 0x5f7f653fb306e234, 0xacbeae08d54981b6, + 0x8bbf553366650bfe, 0x4fde25e7de1b76f2, 0xe58d16b80d602865, 0x8dd89fab086ba83b, + 0x2d1be0be2e4c8431, 0x3d4a1c578f464e43, 0x8f02467892d9e9d2, 0x07b4664d65392aa9, + 0x9542f599b8b876b8, 0x2a3f6592f6437e2f, 0x2ef9198a465f1f51, 0x52af5475e8457409, + 0x53ee06241ae684ba, 0x35172fed1a2265d5, 0x86f474792f0cb1aa, 0xc59c3b4efce83068, + 0x6a82c258e6a68e0a, 0x2dba97c21c5d9243, 0x3aa5f441543f22b7, 0x233ab0786acf0391, + 0x710c431056a6f7f4, 0x49eebc3f2f077317, 0xd8a39a2a416e30af, 0x109653581fabbd49, + 0x0ace9e201bc67e75, 0xabf33d31ab0e76f4, 0xf981d81ee0baf61f, 0x7f538a85e55e4588, + 0xbc263292bb777014, 0x6badade602f7253d, 0xec1d6c4c67ac5cc5, 0xca1b6f2c171a9e4d, + 0x22c2b608506c3cba, 0xb4caac4cf2e79a01, 0x0d52531f6c218b3b, 0xf8923bc043421983, + 0x4c3d0e0cbc4b1d18, 0x9c58c72bb5f8c5fb, 0x989d65d1b04218a3, 0x84c85da326ffd5f1, + 0xbff6b5fc5b65d3fe, 0x6cb7e8d83f8c24cc, 0x872d9b0af4f66868, 0x2f125c9d067993c6, + 0x51877cc204b45518, 0xb800d0be947d42d8, 0xace70520fc99126b, 0x61a17e75a5336b82, + 0x67cedd49f48619c8, 0x2f9673a9afbb71e6, 0x5073db71260cc292, 0x448c2a1b55570b56, + 0x77da32f818a3b50f, 0x7f36ff2fefa9af64, 0x12cdb18437b3f33a, 0xf247edce222115a6, + 0xa7eca54b74369245, 0x795ccb5735878a5f, 0x38bd04ffbfe19a28, 0x7dc35ba872f21bed, + 0x66d46e400b12aa6c, 0x70df3eecb5bfa9a4, 0x1cc766ca209c6c6d, 0xfbe65164b5959189, + 0x5862439edcaa33ff, 0x9821ae06f831291c, 0x71a863f41e5117fd, 0xc8013b44bddbb7be, + 0x27c83de2ed61eb6a, 0x48321bf0c970d33d, 0x284fe987fdc8d7ef, 0x87d565f1896c1f10, + 0x661fd2074afb3cba, 0xd5ec27d77918adfa, 0xa89f1e0c97599d20, 0xb1b4a89648840dc2, + 0x75b40b8c43eb8a20, 0x9692678dad79eceb, 0xa8c57eb5b490ef78, 0x21268036a1c7034f, + 0x9df3d1b875b65c85, 0xd3cfdacb73acea3f, 0x9899dd26f0aa0d3d, 0x2aac0078858de882, + 0xa8fc21d78c2aa62f, 0xad6d95591710d5ed, 0x2419c6674433e4d9, 0xf0c6456734332146, + 0x9f0de4acb7c1b412, 0x03ec90e1f8bd475d, 0x72120555863283ab, 0x5a89377105536621, + 0x4368b8f2134b88a3, 0xd19d63c5b77ab4d3, 0x15f6da163b056797, 0x0e1e63c4591e597f, + 0x3bceab2ecc5e2c21, 0xe61f0028cdff61d3, 0xbb434bd614517d65, 0x1b3fce3b1b36aece, + 0x8a336878642b503a, 0x526c3bcc62fe601c, 0xdfecea72744eb429, 0x0e5a0be0d29463c3, + 0xe65fdac84f3d49b4, 0xcea1e678f0ef59fc, 0xec5e745b3c0f3eaa, 0x15e3cf8f87f1ddb7, + 0xc92b969c306838dc, 0x88bdd828e0a00bc4, 0xe95aaa92595dc625, 0x50e3ddb8f8fd0ff2, + 0x676dd39c72a6f6e1, 0x70aae36bc2a655a8, 0x951a7addadbec8b3, 0xb7628ee42ea0021d, + 0xa4fdfc540267dc30, 0xa96f05029667e19b, 0xba27caa9677ce9d1, 0xc7493b1160b713de, + 0x320cfd057d6e7ed5, 0x62fdfea4d6c6d807, 0x1d5d8548227f2242, 0xdee0ecde21c3d9ac, + 0x3b13039fbd8fe244, 0x6496af2762d7f528, 0xe9619223d95a990e, 0x5d2d2093255a4a3f, + 0xb4ebca36068f5d86, 0x5ab0a31941cb92ca, 0x6f2f9323abcd6fd9, 0x6f67f1256e879f60, + 0xd6e7ff72b3aada6d, 0x3762b2cd2863c4d7, 0x1d603175b5655667, 0x946bddbc2dc19226, + 0x987de35419a7d933, 0x7d86f2f359a85c2e, 0x450de71132c8869f, 0x72e8dfa0df411c77, + 0x0b6db364959c6fcf, 0xeb0e1888a10aa490, 0xf565e98e643c0641, 0x3f7c448ad5031d81, + 0x79df105e5b5af95b, 0xa1e8abce25cb142f, 0x5a35cbc1d9d3812a, 0x10d611a06edd15e6, + 0x9f77babee4c306ba, 0x3d7d172180c44c6a, 0xd2c4a662d3a5f01f, 0xed7a03824fafa873, + 0xc185ee2dde59d635, 0x99cf0e20c270cfb8, 0x426d2677850798af, 0x1322a9da827e310d, + 0x4196090440dde507, 0x30811e41ad8328d7, 0x7ff0d0c4b74b3202, 0x72bf567558123040, + 0xde14f4f17aa16d75, 0xbdd846139dc8f34a, 0x0549450383d120fa, 0x729c5700047fc5dc, + 0x3c8ae593d1210821, 0x230e086feeac20b0, 0x45ebb71fef0bf7f1, 0x934b9944a3af517f, + 0xa879eb545059240a, 0x751a2b418ea29a18, 0x777d20d7209e9fe0, 0x843000d22df88271, + 0x7085bf26495a94b0, 0x61b03e8a2a054e4a, 0x6a9515af372925f0, 0x0e0773f837758d0f, + 0x12eb6ed4121743ae, 0x378f42a1771e63f7, 0xe027ed7c29fcac28, 0xdac893d266f2e5d4, + 0x9b0d4d31595cb3b8, 0x1506b405f17551c7, 0x493d624887a927a7, 0x662051e349462981, + 0xb64a741968f9eb27, 0xbba798e9c0d9ad1c, 0xdf0625d211feeca7, 0x5a0149772504331f, + 0x15071dd0075d94bb, 0x689f489d738d4144, 0x42ae02215bffa3c6, 0x987ebe22d4daa7c6, + 0xf1cc775c5d41cc97, 0xa0b38fad2cf85e10, 0x84ed45020f1171b2, 0x3cac1ce1730c5e9a, + 0x7db1804767f617cf, 0x217f281d4a4eaa7e, 0xe3d133be49a5b74f, 0x5a1a3d1496576532, + 0xda8c285a5ef97169, 0x14745ce23041bd9d, 0x23f088c890ed51c0, 0x1029b7a723c3e53c, + 0x674bc5e89d6fc5e6, 0x5017a0459a179ec8, 0xe6198bf005593bb1, 0x0170c1be39cc95b3, + 0x468ce14573353f2c, 0x9203f3267670b7e5, 0x9993040e9e285b72, 0xb3033c9f3996e6e8, + 0x0695938e2cf285ab, 0x47dc35edd6c03aa5, 0xe0c0f9d611806230, 0x60f9b86f2bf5aee4, + 0xa33fa8e0c7e94ee0, 0xc94a517a5f02ad57, 0xd628a4b6d9c5dbfb, 0xae4c2ab7c039cd4f, + 0x87728f5fc31b8c3a, 0x3ed6562586f1a3f1, 0x7c1d176d442e7443, 0x5d50ebb54fd740de, + 0x63c018fcd9da2b70, 0xd19decb3c062cd24, 0xc7b7dfad6269b530, 0xdc299db355fa188e, + 0xb1db4e37f434cf2d, 0x168d77ee00d049b2, 0x0620c9eb28ee7514, 0x5098e90c072e2f8c, + 0x53973099e7ba4aca, 0xff1049c572e80f29, 0x7bc9c4319c383680, 0xfff57ad7c397a35e, + 0x04825d90c248c6e1, 0x95b1c05eb2e5d575, 0xf4affd2b3624a0d8, 0xc5210ce0b88cb876, + 0xdb4120df79f2d5aa, 0x5c95632fdf37e5e2, 0xc38e603d3eca6502, 0xd891ca5dd3389dc5, + 0x9032425229f651ea, 0x1531987eade0a9bc, 0xecba3582be2c9a50, 0xb59d49e01aaceade, + 0x06719e86c1d755a0, 0x2ca0ee64963639f6, 0x39dd706d4954ed74, 0x7006848e29e5060e, + 0x01bfdad962e6e9a4, 0x65dbb414cb2e9a02, 0xfbab422aa46297e6, 0xb456c38b6c17a3d6, + 0x63d6505083c9ebea, 0xb20234bf09326171, 0xb7cf62502d4e0214, 0x7ea2412281370864, + 0x4c81b1bb9447b8ab, 0xc3cebd5292277aa2, 0xb15e2827539b0742, 0xbcc1da131cd046be, + 0x8168d8b4b7437723, 0x7ff3d4fd2d4079d5, 0x87025a684d81e2bd, 0x799afc37001114c2, + 0xfe2b709fdb49f0f7, 0x1b91f75559b9ce5c, 0x3a74c17f8a6b86a2, 0x6a4f269c516cac46, + 0x1b1267d908ad7193, 0x1da280637b37aff8, 0xea347f02c6316af1, 0xde7b9c4934391524, + 0x7ffc891a7b2c28d0, 0x4c08ecc51a5d6ea9, 0xad3fd57d07e3d524, 0x1ec017537694e4d8, + 0xb825996259b81d99, 0x74cd9ff02dee6568, 0x001d5e9aece59417, 0x9ccc29d9a60d1c16, + 0xae7fc1716c901a72, 0xa0ca327697e59f5f, 0x851cc907aa906f76, 0x4e4fdf0b5e9ab95b, + 0x39b510ad035a4e2d, 0x8f1d892503124ad7, 0xfc4ef7e24a5bfbce, 0x5257999a00896bca, + 0x825d29b7c00038e2, 0xf82117045f12b2d1, 0x6f4acbaafe27cd0b, 0x686f3c442062a08f, + 0x44aa982b433bde56, 0xb3ca460b8e8e180b, 0xa29ccfdbc571b4be, 0xb430f59defb18a14, + 0x9da759d792ccfd27, 0xbd4c59d878a78764, 0x2afd8783dab73b5c, 0x571d7a4d138c8dbc, + 0x7f15fc05b490bccd, 0xeeedd768aff18a1b, 0x2f0fcae6a2f25f80, 0xa6ca90d5c966995b, + 0x13289e032e6fb38d, 0x8490ea970c0d06c3, 0xf52a61f2011a9447, 0xe91fb6694e53ff99, + 0x84399a0413af13f4, 0x893900a9ff1cd650, 0x5be096e2c2058cf0, 0x66fbf75ae8be8fbf, + 0x5330484ab2a0a22a, 0x5b8e052207fd5775, 0xedd78e9f0c5d30f2, 0x6ecff2fa1502daea, + 0xf75c33b5478ae11b, 0xa74a96a247b52fa6, 0xac5498070996d7d7, 0xe8a8cf79fc2b4473, + 0x8b73199e324e9b9b, 0x349cab8ff252b192, 0xed738ba23742f1a3, 0x6b6e1f8e048894c3, + 0xb07433b2023827d5, 0x4e4cb166f163dbbb, 0x3dbb80b56b3c3231, 0x6c6d3251355e83d2, + 0x03061d1a414bd749, 0x8c61f7ec974cd6ff, 0xb68223c8ab5a894f, 0xe6c52550bf90276e, + 0xfd163238aa076a37, 0x5f40f5eee06af68a, 0xb821c1ff45b876e8, 0x4b1e9aad263d8451, + 0x41680eaca3692281, 0x7d2dada50e6fdbac, 0x0113a31d85c17f4a, 0xa189c5bc75afaff9, + 0x576885b1f6e611fa, 0x7778585cefb260fb, 0x5e71b49148be1cdc, 0x29fab567e18a9bcf, + 0x72fc86e88bea8836, 0xcb37bafd31b208f2, 0xc49af8ee7812a44e, 0xb1e76ea72e945ab2, + 0xce6e9922821e49a1, 0x0d6221ae508e6f29, 0x41342d026a6f7e06, 0xc258f087b6b260f0, + 0xf4d74dc8d0b2fbae, 0xb890ef947e9f0d66, 0xcdcdb785f113bf6c, 0xa252454ffedad13b, + 0xd40f4beb7659e1e6, 0x67aee41fbd7dd50c, 0x896d151ea8db9182, 0x2d34b792ef05111f, + 0xbcca99caaa6f7db9, 0xe775ef2082276b2b, 0x8628144d29e9eecb, 0x499308ff64a4859b, + 0xedcaf1b2452319fc, 0x6ef705e743a46f68, 0x684ec82718a7fbf8, 0x0b9e4c93fe6d6d6a, + 0xbd7d723e4a254236, 0x483504af05e28494, 0xe2f72a26d7ec7b14, 0x8d725a203384bd62, + 0x73ff3255f1b89758, 0x922f9cd027c65750, 0x41baa8bec165e752, 0x57c496c8677274cd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9047673fcac14893, 0xf5df5d83bfb58659, 0x0a6230c81642e71a, 0xef14b33800777791, + 0xcf1e99afa3386fca, 0x7ace937791313d53, 0x36fe159b6dcd01bb, 0xc9bc50d02e2b960a, + 0x040bb31b201676b0, 0x0ec2968aea11f66d, 0x2fc408da505cca19, 0x6c832d1443ac40b7, + 0xb559db3ef08bcbd9, 0x4619dc5b7ce37c35, 0xcc8f60bffab8676f, 0xc1bcc30c926719f7, + 0x97818696139b5c07, 0x1352b3710edb750a, 0xae8aa5c49b0bf7c0, 0x5d429ce2082b25cf, + 0x9cfcdb8fc65053d4, 0xd1f5167196f4ee2f, 0x276839e56f27db1d, 0x1d3ad2c90bcd7a33, + 0xdc353dee3a27c81d, 0x2d3b38e3a6976aa3, 0x0813bfaca25c1503, 0x96cc64bb5525f09f, + 0x239651d5384e2ae5, 0xeaec1df9005315cb, 0x7d16c624608eb63b, 0x12e5b07506d70308, + 0xde13703bc0292e87, 0x08731c61c62e4f0a, 0x207d168cd9483f9e, 0x1fd175d47f6b2ac9, + 0xd03f37e8553c8ad1, 0x1c6b60668971f140, 0x1b45dd6e969e03f9, 0xab1ed433d819eb09, + 0x3b85cecbe3df3f1f, 0x7ee7bdaac9e05a8f, 0xa33be189a0c420d3, 0x8d606d1b0bc85b78, + 0xd7d839fa60937c1d, 0xf319d371cec541f0, 0x61c68906cd53aad2, 0x7b0446d5ca7144ac, + 0xd661e4653aead29d, 0xffaeea7b44ecb36a, 0x2ee6e08d79dcbbe8, 0xa3d5b7421ab10e4b, + 0xf5087cb539f798d8, 0x5901915ad5fa200b, 0xe4dec474b6f7d54b, 0x9dfcd9a7ec9a34f0, + 0xf28bc64ac939257d, 0x79808cf9b66df416, 0x7efb5643731ea788, 0x88875d45971ae24a, + 0x4fb8bf9dbbeb3662, 0xe736648df00e1cf6, 0x0ea8079220656459, 0x83c449c0f1ebe005, + 0x5ef0b6a9c5467b79, 0x69403e0541a453b2, 0x4fc2adf12672b1bd, 0x7c21cbec7ce687ec, + 0x2c92997d7c3b7f12, 0x99a46daab6b1f1b0, 0x6e2dffea854385cb, 0x936b02f71563286c, + 0x84284d45fafda110, 0x8c721ce865fb8903, 0x408ae77f74d383f6, 0xa2f2741356c91dcc, + 0x913941dee5b96db0, 0x690159ee0257c2a5, 0x6f8fb7db6432fc87, 0x087439128197cc2f, + 0x6f8b341061eecf61, 0x260fd718bf5c0365, 0xc2e619502f7236ca, 0x6f9a721b229b2184, + 0xc3f6c8141648291d, 0x6e4810fab9dedcaa, 0x0f10a86948a16410, 0xf34948b3e17e9c87, + 0xe87101ea0f9655e7, 0x44002ab99f3bbe06, 0xee96c7010aabaef8, 0xd14a8243cc6af2fb, + 0x003a859b2fcaa60a, 0x3b2dcd4ced18b81a, 0x13953a4a3021bba1, 0x27f7d10393d72815, + 0xe609b75c79a37e29, 0x99cb26cb848eb000, 0x3fd7ac040c35ee00, 0xf9ede507eedb57ea, + 0x7815e8aefd8f34fd, 0xe27d86ece1ebe20d, 0x154851fff7881b22, 0x8032d036a7beec03, + 0xcba350c0bb4b1028, 0x2eba4f9969ade796, 0x58449949fd0d6097, 0x17bf307f509c09d9, + 0x8773671d5065e23d, 0xd0fdfe265cd935a9, 0x721e1720ba1846d8, 0x14ac94bdc7525ee2, + 0xf2e37fcded0a86f7, 0xf992c715b4e8fd95, 0xb84bec2e6ff8206c, 0x97d4c50e0c566aad, + 0x0846292e0aaa92ff, 0xc12509255198cbcf, 0x7e8ba7d812f9e2dd, 0xec377e69daf3d788, + 0x60ac0d9044d11582, 0x4e70869ed02f01e5, 0xd06cd1baea488fc8, 0x0f9c80bec6af19b8, + 0x1193af79d861b588, 0x6b20b1a03ebe0aeb, 0x58204d8f5698176c, 0x490239ba4ea59823, + 0x37fe263d715d646d, 0x45f1d32e98d64039, 0x6b0eb2eabc2463e3, 0xbfd88608648fab65, + 0x5a26e5b192db6e20, 0x945c0433dd1f5e24, 0x5a4f667ccfae0e98, 0x6120ef6b2a01d270, + 0x80170a58acf6217e, 0xd9eb4d58f5a4dc75, 0x1e3cc79cf142ff9a, 0xd72d95fec686c8c8, + 0x664899f524b3c9aa, 0xf3fc08338f8cb900, 0x54b810514e704f2b, 0xe188019e4edca012, + 0x7fd4614f0a6cd109, 0x9b3604bcd2938cce, 0x5e73c984c45c2db8, 0xdc32545c788abef0, + 0x167ff4246298f598, 0xfddee40ab4708649, 0xe6222358a95ba704, 0xbfd3677a87f72d39, + 0x8ac68566d599fabf, 0xdbe08e867eb26d43, 0x4d405de2b1dd6c96, 0xa6a536e0ebe2930e, + 0x4eae5928cfab2920, 0x657f68def3b1c442, 0xdf2796ad0afa8840, 0x9e7c7eec3345bbb8, + 0x1c577ae5ab675c2e, 0x00715e8eb344fee9, 0x1f2086d06307505f, 0xa95665b4a4e623a5, + 0x9b24fc0615ad16c3, 0x4a2f3e2f6bdedec0, 0x3d2b08376e528343, 0xabe8b21c18d5dc71, + 0xadc99d655cc19f51, 0x42eff4a6a1a8599d, 0x043d1f8da90da7ab, 0xd721af08ff1a71af, + 0x93db3595496b1830, 0x9f4ccabc4c96d827, 0xb772df07557cb467, 0x88e079cc16360047, + 0x2a1f96a73a90f4fa, 0xf10db5ebd15ce239, 0x87334237ad7d1bf7, 0xc155cd2cf8059a83, + 0xb55d40740ded930d, 0x06f9098294132396, 0x1736fee40746d597, 0x4ac16bede818e107, + 0xc320f0e02eee3284, 0x2a9c909c50ae29fc, 0x83ecbd32fceec5bd, 0x4ab0fcbe1cb8a7f4, + 0x9a00fb20d47d4ea0, 0x416a8e3524502589, 0x1ae65970f42fec71, 0x5475afa54e43aabe, + 0x764c7049a72b0b56, 0x46916300a697b1c6, 0x2fd02c10bcd0f0f8, 0x49883c08c9341738, + 0xf2b5feb32ae187fe, 0x6ecc5e14c778cb64, 0x3f87fd93e64f5dee, 0xda2182c9580f8267, + 0xe00aa84df80755ab, 0x85fc4189db75915d, 0xe3eeec60bb608a2f, 0xf837a0340af77ebe, + 0xe53dce5ec75c7cd8, 0x50cdbb01b1bff896, 0xb5fcd383265deda7, 0x6628288aa932d676, + 0xb80e0160bc747ce6, 0xf9d6ec305dd13f3c, 0xec776301fb36efe6, 0x038010de21f50046, + 0xa544ebfc9a938ded, 0x732f758186bb6344, 0x97f506b12647a5ae, 0xb7ed31a650a155eb, + 0x7da4d67730b426a7, 0x9c153fb31233e5df, 0x71b406ef7b1b8e6d, 0x549bacb3c315aafb, + 0x6535f70f616d4f7f, 0x5ddc1992e41d46a4, 0x3547e4ae524d4859, 0x064bdc6dfc64f41b, + 0xe01dc74278dc6417, 0xd7db16e4bd4e5bcd, 0xe5d42ec7791d8f71, 0x42b98a92a58db944, + 0x92dae5d3231b4f37, 0x0cd0c91b3cf9dead, 0x41f9c69f0510ff38, 0x516a3aa8df57197d, + 0xddbe0c9059b84803, 0x2c0289ce6ebc6725, 0x96ae36415f4126f4, 0x7c1602bab0f22a23, + 0x378569bfcb1fbc68, 0x9c6a46d8686ecf2b, 0x71fc617cdc9efecb, 0x2a74bf39da0ff7e4, + 0xeee33823afae2f62, 0xfa591bb0dd1b2335, 0x17ab2165d29696a0, 0x4b90400013c938dc, + 0xa9b3d40b9d6110e1, 0xdbad6acb7bf9de11, 0xacb1a1775bc23161, 0x4fba68b236217116, + 0xd97654ce38feba31, 0xaa2e546373c923e7, 0xa44442ef7c540bd5, 0xde7abb2e6ef6d26f, + 0x73e4a47c3b1980b7, 0xb5bd2c144799f4b3, 0xbc6686128484799d, 0x8fed99e39663d286, + 0x30171a6a383e1a23, 0xffd8bd559be558ca, 0xf00910862b7a1470, 0x886470f922b471cf, + 0xf42a90c4d6922f9a, 0xe0e65b5cce61c367, 0x7506a3a58ecb7103, 0x030a3f4f865e9254, + 0xc74576172bac8f38, 0xe07d0ed514139ffc, 0x6ee7360351d5b871, 0xc36e68fb175aa029, + 0xb78fd72588c8ce8c, 0x4d2262ec66fd1c2c, 0x71d087160e59940d, 0x81b315613d76f3da, + 0x2d07fb33f46511e8, 0xaaa1ca308dca5d77, 0xa817cf48b1eb132a, 0xfe0f97f0472a76a2, + 0x0b06cffabd597dc9, 0xbf77aeefdfd14b9c, 0x48762cff0a40e19e, 0x5689eff225edd4a0, + 0xb631345cea83f8d8, 0xe02818f70faddb59, 0x676ab534fe672577, 0x52085247b6eebd1a, + 0xabb2eb1f5d1aaf5d, 0xf261c9da69ab7a98, 0x0a92ed4cf1640a60, 0x2b6b686273a8b9e3, + 0x82f7739d23384a39, 0x089d7ed37d6610b5, 0xf159615161327d6f, 0x42e1afc32d9d5e5e, + 0xf2017bf6018a082b, 0x64b692a5c33e2810, 0xee7c90603920bb75, 0xd57c3489e40b26ef, + 0xd24d0ddfb23a85f0, 0x82a2d2dd8b08f1af, 0xab9f183893c4b3de, 0x18253a427c5ebaa3, + 0x97d6ff753d374466, 0x10832a04f230200c, 0xb4f668dba53bb26f, 0xb14b464fa5fd5f3e, + 0x749d3b51530c8c71, 0x9ad7e8fa4714b195, 0x5ab792dff70b9331, 0x6885e36cda049ef3, + 0x89f6279b46d5b992, 0x06533680e4756496, 0x7b4fac7a4020aba5, 0x61ef8e3c9706c90a, + 0xceb2aaf6bed362ad, 0xcd4fc12e1d88ba50, 0x657f8f0ac852c790, 0xaa75b507f35cd87d, + 0x3f5c255bcc15a840, 0x3c3deb5262ac07c5, 0x98806d16aebe4228, 0x5e3407d96651df66, + 0xd28356e280b59efd, 0x4ffd556a3699e910, 0x5b0145955d6c9bd3, 0x4bb63c3e5627ae71, + 0xe249211d1aea852a, 0x89dbc36b34e29feb, 0xe3587ced0fca9b7d, 0x4c95b345a43e57f5, + 0xd0fa2c0d4c32bf4f, 0x767fe0c9702082fd, 0xfeead6cd028c9df8, 0xaddc351d8a975a0f, + 0xe12a4386968e46a4, 0xb3c8e9b1412b4bd5, 0xa46dbc415163adb9, 0xd8141016c331fc22, + 0x8407b287b8e3ef49, 0x8e030203b6605de3, 0xff92723f624215c8, 0xec0d04f354187b1e, + 0xbc851fa11a5663aa, 0x9916cc8ab0fb1a4a, 0x7e45bd0f23e259f5, 0x2707fd2b2c61ccd8, + 0xb9712ae0570710f3, 0xf5c55bc9e756d801, 0x34a11080cd2b83a8, 0xcd151f3359e1c7d4, + 0xfc64d7784ee7d42c, 0xe6540dc8225418d4, 0x6f2d09e0d522b641, 0xe833e108bf792163, + 0x081808dcd2aad2b7, 0x73f752b43fe33e9c, 0x48f08457f4dd0bc1, 0x1c108a76247aedd6, + 0xf0a38308a452c91b, 0xf5ce33fd5625cd76, 0x17b049b6f178a34a, 0x8fe94b4e4c86bd2c, + 0xc8ae5e3f64f4130c, 0x0b64430df344de64, 0x5c4e3f16d96c2ce4, 0x267a6ec044538071, + 0x19cd5c40f04fee03, 0x190b95907aaa2522, 0x081898ada943bf13, 0x256112ca5bde7cbb, + 0xf3f9ef81364d15c4, 0x079dfdbf65eed65b, 0x2b30006177d32ebf, 0xe584dc9984077384, + 0x41340a167edce5f5, 0x21234cd5b9d08fa2, 0xec37663b6234366a, 0x2e379b41de33d8fc, + 0x6bc76d7b90db7b08, 0x755ae85383da07ea, 0x7d35c83c8e677068, 0xa998c5fd0746bc3e, + 0xdca7a223e6d31ea4, 0xfbfe36d124722355, 0xee5af95c7ece7923, 0x338c1178fa5704bd, + 0xf82b1b1504ae6e3c, 0x89394552c02f6623, 0x6f1c2ce702ab5ffe, 0xb754866aefdacf19, + 0xfcb6fdec00f28435, 0x175080b1bb6a7c4a, 0xa0b548d4b93ec592, 0xda53c7eec16dcc2a, + 0x710e11c460eeb380, 0xa4b5c59f3b1307a2, 0xf796264ffe6e2b25, 0x9c759cfe5815c886, + 0xd765ed041a702d92, 0xdf7db56d650151be, 0xd4e4c6412eaa2086, 0x8bdcaf80a45d5ee7, + 0x375be23e9a328196, 0x872869e151ee76e5, 0x0ae181edc59ab9e7, 0xc851492cafd1f757, + 0x96d5cada42e77ba8, 0xcf2c3d67a7ee8153, 0xd261876db8cb0b94, 0x26e80f5dc8c0e602, + 0xeb5d96b5c0bbb4b6, 0xcdf05b88ea104572, 0x587c877cdb82ff3c, 0x167bd6422f0448f8, + 0x3388cd9e4908ad7e, 0xfd0ef48486aefae5, 0x9a1b9d755ea0fdaa, 0x5f7bd2b427417aa5, + 0x59eebae112c291c7, 0x200d4e72610b7db9, 0x6755b2c42685be9c, 0x75515a0b0f648a7a, + 0x98d502c0deddbaa0, 0xb0561bbcfd5807f5, 0x5b1ca5c48a34f7ee, 0x17325bbdf6c659fa, + 0x69cad76e13d49b97, 0x6db4e139acfc1261, 0x462f0731f240985e, 0xbdd35c2b6ae2bdd9, + 0x38c401746f686e69, 0xa3375aa966f6597b, 0x0331af7ce06cebb6, 0x5409b343e1eb2ae8, + 0xab6d51e69d12c63c, 0x674c2dbe84c5c870, 0x69d394ab58d924c1, 0x3325e8d6d32d659b, + 0xf9a3a84ca9d037c1, 0x7f6b27e2e2878c7f, 0xfc004c1ec135dbb2, 0xa1ffdb8a8ebb8176, + 0x9a04ed00f9cc2e66, 0xb98ff91cbb39c793, 0x1462f86071db87a9, 0xc0eac4f4ea6b30ad, + 0xf2f49134b43e1436, 0xc370f8931936a64f, 0x7b9d852bf8b50d00, 0x4edfd99da790719d, + 0x2ff12982da305ac6, 0xfdd8368d2c0adbde, 0x00115e3ea4be0254, 0xdbffacf4eb40730c, + 0xe38ad75138fdce99, 0xf5e7850d56a4e003, 0x993257196d043658, 0x95503cf966029f67, + 0x23689c9b1a3d574c, 0x2cf177999c9af4ef, 0xae2c32f12205f9d9, 0x574de0e37c6b7c88, + 0x78a8afabe6b2d06f, 0xdd6a2d80a9a7056b, 0x2376f8f9a2b52754, 0x6160c5fee51348b1, + 0x20a318cd7458c874, 0x48f37465fc005859, 0x49b3207280c4bffa, 0x4f8ee277e21892f0, + 0x63dbd578961696c0, 0xdd794100ed20a014, 0x330d304c3afd1f22, 0x9557b6fd1fb1cc3a, + 0x0ae0e85dcd63ea77, 0x0ebcab4dcc00f616, 0xa839e7d9694afd2b, 0x0ceacc614a359de8, + 0xbd19268dade01e56, 0x121b33331be7e9c5, 0x371feea5ebfbac35, 0x13949281c7c94de9, + 0xc3aec0bd5bb9db20, 0x389c0270b5613a39, 0x02fa85f10c1ffd73, 0xa44e64c3e41eea65, + 0xe877d950290abfdb, 0xe49782dd124d9dc9, 0xf3dc8a21032cd01e, 0xf20a9ee77abf34c7, + 0x4aa5177e15fc5f07, 0xaa75ce560be57a82, 0x38dad4f3d2249aca, 0x4e9104384c74d0f3, + 0x00d62508aa60b6d9, 0x496bdf56036e944f, 0x62da10dd30bbd8f9, 0x157861acaccb1e59, + 0xc7686eee005fdbe6, 0x86881063b072906f, 0x267273cb7a569b23, 0xc5a733d9f71596da, + 0x01ecb9e91d932421, 0x1071c7b321f968d8, 0xfcdecb42e044c3f1, 0x762032743215e3e1, + 0xdb9815ac6e56ab28, 0x76518c8356bc0193, 0x7284107f42820171, 0x905390d72adac3cc, + 0x85091fe4b98fe45e, 0x33eaf559079874d3, 0xce151f26e904494b, 0x79a296806ca41c54, + 0x7e735eb3d64fbffc, 0x7d2994b3aace2643, 0x509fdd5b4f5502da, 0x54b5260a2f269c9c, + 0x9c3b3fc85903abb5, 0x5d32c69a124cd715, 0x18ff8d2b8d2600fa, 0x133a04d3b63eb6b4, + 0xf8046076fda2950b, 0x019a9cf0c7cda9a1, 0x4739b4f393663119, 0xd7a9897fa25f61c8, + 0x74bbc610a675656a, 0xbff1f87f963466d9, 0x4f1a104a67167f41, 0xb414235dc1fa0392, + 0xccd3a69d2e5a7db7, 0xd04ef93cb6149ba9, 0x4abb0f17eef19d12, 0x116e38e6bc26d4f5, + 0x6ef4c0d0f7d45dd6, 0xad04036499e68ead, 0x8d36766959ec5776, 0xddf82e7868fed989, + 0xa1c4f95f31d143bd, 0xc7c20431e10374d6, 0x3085cdb88e7dfe7d, 0xcd4e45c5134e814f, + 0x3928df7666729459, 0x952221b37ac24ffa, 0x70eae01d6bc6814c, 0x7bf3b3c926b59b02, + 0x6912711c73c40099, 0x74b7b127c452774c, 0x487de688fa263700, 0xf7f7eb4723f89ee4, + 0xfa0d7ce654cf50b6, 0x173a0fa491298044, 0x3cb431296235b2ff, 0x35a47c0fafa5648e, + 0x6602fbc3f8b4987d, 0xb8e90610fd126dbf, 0xb451552602f208cd, 0xc32399a43a4bbfd3, + 0xe2b28b2d9a657d46, 0x96bf93d367416718, 0x277a2f8c21a5c41f, 0x91cd6817f29e6f56, + 0x9e0ab8d663668355, 0xac4cb913cf9bf0e3, 0x9a714a8ee63544e5, 0x32023aca9a9e7926, + 0x420abbd05557ffb3, 0xbf33f91590d0bcfb, 0x57c3e9d22a2f9893, 0xbef0306deb15abf9, + 0x1d9d1fa99c39614f, 0x389dd8b38f179997, 0xd0c642e3f662f0ab, 0x8ae111b61e4dda14, + 0x6bec8d8f02e2ea38, 0x537114315396945e, 0xa29d05afd17f2a69, 0x28bb1981ebb348c8, + 0x53c74d3d4923a880, 0x81ae4405f813880c, 0xcd7878159be2f9e4, 0xb261482e8b0a77c4, + 0x43b04310c6dca8b1, 0x6c6b72e057dd0587, 0x4fd5323a6cae0894, 0x787a3b7a98d143f9, + 0x33275c30e096fa03, 0xa2f33956b8ed7358, 0x3f5611a025269192, 0x67ccb469b569d3c8, + 0xe4cc519de140e2b9, 0x74d825f1cc0ad969, 0x609882ff7a7d4efe, 0xf3999457451552dd, + 0xec0a9966a38cd73c, 0xdf2e09d5cbe737a4, 0x1bcd6e30dd37b800, 0x9a1d255293e141b2, + 0xf8516f062012b17b, 0xa52dfa41756c393c, 0xd7f16314cb746823, 0xc348497dcbcbd9ca, + 0xe24253cffdab5664, 0xa54495a5e7479269, 0x0e90de2bb508df0d, 0x31f2dd61d0fc886b, + 0xc6899e44469aabe5, 0xb57c7fd64720f1d3, 0xefb6c5bf66f8f4d5, 0x3e1d4a6abe4f6a00, + 0x0b910643b6e239cd, 0x94b0d6a1cdd618c9, 0x093212d61dede103, 0xda593bf228bb8d45, + 0x04d48fb647e19a3e, 0x94a8187683113bb3, 0xe7780efdcccadf47, 0x597892cb5f39e7df, + 0x79a38697afb51437, 0x9ad60aeadb42d0ee, 0x6bbf99cd2c902ed7, 0x8f2684d36c8dcdae, + 0xa8be8718386e785c, 0xb4a0d5d260b1c6af, 0x4d1cf89405cfc52c, 0x0e16a1bd34f26032, + 0x61d3f841354d7b5c, 0x7719e546a276a2cb, 0x0996c7c672760c36, 0x6c9120ccd7aa7f5a, + 0xee5504e1ec78a23a, 0x68461a6d8fd02984, 0xe5806402dc4bb5c2, 0x34c889e638d4459a, + 0xa016cd97a98017e0, 0x58073ac817a9ded5, 0x978db22b7424afbe, 0x534bce48e9dbebe7, + 0xf95605185351fe4e, 0x3c0c6805aca0da01, 0x4a20b5efdbbce17e, 0xbc8e87ccf43cc8d4, + 0xb02cc35858065281, 0x8fe079608ebbd641, 0x287ccd0c84fa59aa, 0x09df7772d487570c, + 0xe2097fd4fc63878b, 0xe3e3b39d50c710b5, 0xfc94fc002df01826, 0x6370c3839c5922b7, + 0x72cac6edbfa07561, 0x21d5d210f2ce876a, 0x08afc84c65087b1e, 0x2b6c3ce9b4facf5d, + 0x79ce72ddddf98ed6, 0x2118a9d5718ea663, 0x9dc1da7fb2d1f121, 0x2ab7d6264e129b63, + 0xeaeedb2970f4cbe2, 0xba3c0339c33a3bed, 0xf313ed94c23a206d, 0xfb93488880bd28ea, + 0x9139c530fcc2190f, 0x459885676868ed7e, 0x0914b7d3bee447ab, 0x361a6a47ff2deda6, + 0x63c272ad2f3a3e8a, 0xeb81d9da896e64b0, 0xfd5255554953db67, 0xab70df9766fb99e3, + 0x3045e540ad6d2bc9, 0x118ff7e43de73ace, 0x132aedb7aa773627, 0x8cbc604da58bc253, + 0xd0865d5c1fa63111, 0x346754e6444d8555, 0x2e9d69fa4cdc8c1a, 0x21c0810fe2e82e89, + 0xd957b1bb7a293fd8, 0xa6c850d75a07e806, 0xf2e73a4313cc652e, 0x5b56b203bffee30b, + 0x69c8718700b12d95, 0x57d7bb6ace06fb70, 0x656dee8f94227e69, 0x74ec5936de02820d, + 0xaab4fbbf903e35b1, 0x77f818762d97d594, 0xbb69d5f758d452ca, 0x908e2df7157ea4b2, + 0x449057d807f41fed, 0xcb6ac2f12aa07545, 0xa8be2722d28a6b95, 0xf8671ea7092e76f6, + 0x925b50a22aa38ccf, 0x624eba124ad5a87d, 0x3ac7b1b2e6460422, 0x5e18e8e6e77342a5, + 0x613ec3c930c8e031, 0x482ec7a3082e0896, 0x0d7a84e5353e1797, 0x5de2a00a176b65d8, + 0x9eb6966a8cee7649, 0xf526ccc038ef43f7, 0xc29369890fc41996, 0x5e9f775597e2bef7, + 0x374644c5e7bc0af6, 0x846bdeada430cec7, 0xc7b4bda64e0666c8, 0xe24917e9d33fe50f, + 0xf584773618b9f9ab, 0x4f73a1bdae884a8e, 0x71fb850cd7d853cc, 0x63ef08ca54b99c44, + 0xf9a85db320a3c22f, 0x6d0627b72d074ef7, 0xdac5d5de845ff721, 0xa2604a8b5869298f, + 0x5682f7eb49f1ba4e, 0xace85e78a76350d8, 0x272f6897df79d9d2, 0x151746d5b9f7dc15, + 0x88741c16d75e7244, 0x32dd2bb82832f4c1, 0x45ce6199563e9ed9, 0x6cf07ead5dd4aacf, + 0x5c6b777802f22691, 0x1798686649e27e14, 0xc4db501c08980bdc, 0xa960ae87a3083375, + 0xccf65a028ff15848, 0x2463757d986554c4, 0x1474027af782b551, 0x8e822f3b45f982aa, + 0xf6f9f02522ed6e31, 0xe1b220310b6a6ce3, 0x128bc35d7f4fba49, 0xc7b3da87a3bdee2f, + 0xe2b570ea49bd9e99, 0x2d5b00c0fd982625, 0x2ecedccd5fa00907, 0x4d3aad864c2e7ed8, + 0x1ede941fe7133473, 0xab3dde2a21fa8df2, 0xcea088a761ec7660, 0x7a012f8a113194fb, + 0x4ba7182851566ef2, 0xbbb9edf4a3175b7c, 0x5db5d154453c5e78, 0xf9d1cf8a354931d4, + 0x683228f881cf7055, 0xbb7942d1a8f673ab, 0x57e6e68be4d29688, 0x7169c1468645bf64, + 0x9ffb798c7d9c6962, 0x3826101e091418f9, 0x136015f47ff06c13, 0x97adcec5738d7b63, + 0x126d676f0d45ce6e, 0xa7fba10da6b5b84c, 0x44bd57eb069e009c, 0x6721f2e295187c9a, + 0x547160cf3182b14c, 0xa807dff9b3a34f95, 0xeb6ca6ce36820742, 0x6bfc1ff1eaf6d6f1, + 0x526093199f0c9889, 0xc9f5cd3ca3f7f257, 0xcff422ea53b0f082, 0x0653e31de2bc9e17, + 0xcdb7feae875f72be, 0xf6ecc1005ff93ac0, 0x2541a0c8e9719898, 0x9b9e0d49bc2b82ac, + 0xd6fb1422cdb47d2a, 0x0c5d5f0a2f33fd1c, 0x816421b5d067b790, 0xeefde0023ac74e4d, + 0x65267f5851f19c76, 0x3a328eb8db150775, 0xf59e0ccd25e19614, 0x2364a745ba132ad7, + 0xfcef6a6fe9d5592a, 0x581669a8cf66f002, 0x904e1e3ad4939ffe, 0x3d6037d71d61f379, + 0xe053b27b815d868c, 0x750b387070f6a4fb, 0xe3e2386ca0a967bd, 0x224faff36b421409, + 0x7a223417d217e426, 0x4966c63d690bd388, 0x596f15dc2d80014e, 0x6ca22012ff7559be, + 0x3632136a72b1135e, 0x19c0c8da9acb2c03, 0xbdbdf8c49f3f2eaf, 0x369a385adec88694, + 0xc966acd4b4c5afaa, 0xb52eaab4552347fb, 0x50e7bc4835e2d0b8, 0x69bb697ae8083795, + 0xad88fa20a5caa602, 0x8ee3ba7ea8763c97, 0x90e91a78284f9a7b, 0xb92bd1bd1e29889e, + 0x1c8828b48978a4e1, 0xf9c2c7065cadd02a, 0x413564a6bf660c8c, 0xc2e026c6fe56397f, + 0xb4c1276da5712e91, 0x64cbcad64f53f498, 0x3cc5f29dac77804f, 0x72deb443ce26da48, + 0x1e13ab533cc1cdc0, 0xb00ba869f81da3dd, 0x27ee4146027d4550, 0x9fbdc389b05bf8ce, + 0x3099d9d080fae68a, 0x431723c2090613d5, 0x4786bee900a827ba, 0xa9590dfce9851b97, + 0xbca3016ba0950b1d, 0xf6ae4147435e92b1, 0x630fd1c0c317a3a4, 0xd5a1c1bb8c8d10e5, + 0xb3bc9fc0575e335f, 0x3862682cecc697af, 0x144a8cd1f8b96183, 0x6d18b1abb0c30772, + 0x7b05f3c6773cfe82, 0x7263348629b14cb6, 0xeed7b96a9aae65d2, 0x5bb0e463b322b047, + 0x7a7913b41b02eaeb, 0x651b0fbe0c92090f, 0xfc22605d223c8669, 0x34747217c2faf57a, + 0x4d21dbedf61116c8, 0x3055d23128bd3de8, 0xe86b221ab4df7c4b, 0xc04e3337fce58071, + 0x0efcf24f8defce26, 0x2c9513b745d883b6, 0xe39c8ac4470fe585, 0xe07c4705b83ae512, + 0x10a605249157f52e, 0x19e813b5e666979e, 0x8b1086bd3fae0b9b, 0xb5508680eb8b0571, + 0x4f0a0d595f383988, 0xb0223823903c49bb, 0x3cb9b655bb49be4e, 0x452cc9f7a2ec2676, + 0xc2bbf19945ddf5b2, 0xfc9a0dd906318117, 0x88b0a6e992207378, 0xe32a4bf390c02620, + 0xf970efcd5d4282aa, 0x7c4296a98ac6fac2, 0xa10493197dc60cfa, 0x7fbdab67a87de5cc, + 0x5a09559ba29ab548, 0xc42b1d1275f2a578, 0xb094b489c57abd00, 0xd93898d383308317, + 0x1677a8c805d04489, 0x3fec2d7b062aef97, 0xea625c8532c3e30e, 0x4cb34b80c3f1508b, + 0xb2484a9621b505ef, 0x5217c30c9cacd22a, 0xd2090c432c4bec76, 0x2194375edf73ff42, + 0x0fde1c4a2fec68fe, 0x9b3667255fb45553, 0xc1ecb44dfd7406cc, 0xc4215ca1dd232ae6, + 0x810fa41a02df5e0f, 0xf8ae08b7a4ce46de, 0x329ae07b7cc049cc, 0x52e3f1cdb3c8a14f, + 0xfcb71af2d630965c, 0x9f1a6cf17e2cc7b1, 0x64a0a49aeff1eca8, 0x0e67a842d9a1bb05, + 0x2bbda8b58c75abf6, 0x46fd1318eb1bb3b7, 0x2f71ec6a93e792b2, 0x519480bf922f29bb, + 0x7f78634cda266a60, 0x1be77643a069608e, 0x93b6168efc30b8da, 0x12aa01a3c1187bbd, + 0x8b1bc8cd7cf0b3e8, 0x34441eddf6a4bd20, 0x83704c39b1ffc847, 0x7d4f596ac3876fcc, + 0x5b50c7c4a0e33784, 0x360ce82614fc6a57, 0x79bedc5e920fe657, 0x93aac902b115df7f, + 0xb6e134fd159f25ee, 0xcfe73871ef4579e9, 0x0d0253d63b1e3ed3, 0x76e8c0db3137846f, + 0xca8877ebc5cd4fc5, 0x4385c08e93083e12, 0x8d19fd140da61ea8, 0xe14762845751c57c, + 0xfaa166142199cc1b, 0xf443e4e3ea1a6127, 0xb30d9f01899d508d, 0xebeecfb2ce48495d, + 0xc82138006faec8d5, 0xd5eada50f9a8a0e8, 0x1148de082947f234, 0x5c581c85b683a06f, + 0x15db1a44bf48f6b1, 0x3a2111ccd233afbe, 0x224683c0065efa3d, 0x7e3832f96d5d01f6, + 0xfb7980a198a060fe, 0xb44362c8168191ce, 0xad7d6b14a8abd7f3, 0xfe5aff274aa1c67a, + 0xb6e60ce8bcb3c3b4, 0x94869d20af096500, 0xa87b1959f91ae852, 0xb425434f366089bb, + 0x667062aac308c3f9, 0xd54425fa3bd92ab1, 0x9339ed5ba656b7ba, 0xe501a85688d26334, + 0x91702e9536d9b8c7, 0xacf2810aa8a9e8b9, 0x3636e2af905c0ba3, 0xae2e82f774d0a2e4, + 0xe73b71f1e79d4854, 0x56ea2e9ae6ac12b6, 0x65b62bb6978c06a6, 0x6f39a9f8a2ad4807, + 0x429ccbbfb8791543, 0xd7c1e15144f4aae6, 0xb0b026ef827314da, 0x0bb918a52be310cc, + 0x64724f99fc51eb2e, 0xb8b0ae5ce45254f9, 0xe297f13836b0a941, 0xc2ea17281d9b1b70, + 0x2c928f985b258445, 0x1cf17bd61f660b40, 0x17f1fc0598bab389, 0x8bc7c5618ee06d53, + 0x2da1fda8dad078e8, 0x80662f2b688cd223, 0x4aaceef3546369f4, 0x737a994a67564597, + 0x4e9ec68c991b35ee, 0x336cc487ad18a998, 0x0deb76bbffaada08, 0xa52dd72403192c7e, + 0x53cea93187cdf6a1, 0x6831b92e592717c6, 0xfa7b796ddf9cb926, 0x341f33f10e90b77d, + 0xb2841f160c260a38, 0xa93ce7aaa860192b, 0xcfa320105e884ed8, 0xe3c4f17745e83cad, + 0xf4f82acae5dab534, 0xda336119c81cab70, 0x14e50724040ff8b5, 0xf0caba759c8e9611, + 0xa52da2bf0fe2205a, 0xae5a5f4ee55136d3, 0xed79904198719de3, 0x3b89edeef6e685ce, + 0xda21aab61282f771, 0xf9a4774787faf43f, 0xb1f9ca2d842e7775, 0x2ace9b8af82881f6, + 0x97b47161652b55bd, 0xbf182b87504504de, 0x915131962a8788a2, 0x1c00b9f2111991d1, + 0x4f45d80c2b7fed5c, 0x7979b7a78ddf8df9, 0xdce7f74513b23f9d, 0x6f90577c84c68ce7, + 0xc879faf1f48d0171, 0xb5b26ef3ed96fc36, 0x8ce49b100d80305b, 0x69294b47e96f6566, + 0x70dc39b7296166a5, 0x465b49f17b8964b8, 0x20f5293d1ff425f1, 0xa69552930b717ed7, + 0x2a4b4e4d3dcba846, 0x42ed588de4a49189, 0x5c661c7ac8de3d98, 0xcdc15e47f4c25186, + 0x21f742361c02d2d4, 0x564890f6f0a39b30, 0xdbfc98f6291afb07, 0x6b84ef3dc87fcfdf, + 0xbf55f953cccc5e63, 0x333fb470f0b933af, 0x884728b501d1e5fe, 0xf0b3740105c69f58, + 0x54ce6d3301d1d086, 0x881bbedb3ae61f5a, 0x0814aaf6af352dcc, 0x10dcb94852329589, + 0x59b909df614401a7, 0x329d882df0303681, 0xd60207cbd60a21f0, 0x89758e996b566f90, + 0x4ba2aaa99953cdbc, 0x9e80205927952ca8, 0x4f486c900d6ac698, 0x90527c8acf39831f, + 0xb1ae20baacf84c6b, 0xcf915493e8c5767d, 0x11a7fead31d59538, 0x846c005bc70163aa, + 0xdbb8c3288118a8bc, 0x5d6fe2aaf1762aa1, 0xf275925d377b6007, 0xee19ca724e7fe5db, + 0xa7a431ea3405d2dd, 0xfde75946217c945f, 0x11b4ca868588fbb3, 0xcaa1675164bea266, + 0x2c29663aefe147d8, 0x970e7171d65af6e3, 0xf5c457f0fb7dcc07, 0xf9a29dd9c3d2d88b, + 0x317cb1d3cc05ace0, 0x1ef7bbb2aedd42f0, 0x975c5a0bc00da175, 0x1d5f9fd0f4c43081, + 0xb196d8f8b941db0c, 0x4e74422ec71c372d, 0xe22eb62050384597, 0xc8057fb3328becb8, + 0xbe4e0e5a5d2563df, 0x74b87e42dcc105b8, 0x2496d077c94dbccd, 0x9513bf4cf67c5145, + 0x77dff44018c40b36, 0x28997be772a0b7b4, 0xb9db161611c52922, 0x5da72dbc41074141, + 0x07e613c7eda72a89, 0x1fb26d9791443c0d, 0x6fa60b83e685c34a, 0x721b73625a18b6d3, + 0x4fd8fcbe8abfc667, 0xbe71be35b0a81a23, 0x8b4ee76679d3bc1e, 0x3ccfb67406faf026, + 0x10ec89c384505fd4, 0x448fb314305f58e7, 0x3dfed3c02cf17c71, 0x6a0c2fe8c05cf678, + 0x6c9adbc4bc741ff1, 0x9b2484d4f8af2e60, 0x82bf4550a51de79e, 0x792ae8aab2d8aa38, + 0xd28d08be14ef2ee4, 0x25cce0cef9ee514e, 0xc4971db048b24d97, 0x08e2f8e98930624e, + 0x41add91310343f13, 0xa785cb576a4c33ed, 0x0be57b8d46d44abf, 0x1e37106e51eee1cf, + 0xcbadd5cc65f65e25, 0xee6fbb2d0136f8f6, 0x1315474f5bbe9b8b, 0x85af2ca4d469732f, + 0x99b61e48bdfcb4a3, 0x02d5ee1c36791fbb, 0x1569fa216a94bb67, 0xb6cb53e494c7ce5e, + 0x2861cabc4fcbf60b, 0x5b192ce5eca8922f, 0x030f6aad9cadcac2, 0x7d4f0544264d4838, + 0x97a00c9291242167, 0x9e79f06af0192a9a, 0x3cedab6937ae681c, 0x1580423bcad5dd63, + 0x2ef7c7670bf23a0c, 0x9d5bd2f1b6e2dbce, 0xdfdd8667bbde784a, 0x02f79c7e8d9ac441, + 0x23885dc9f26355ed, 0x8a38a3134155d591, 0xc7e34bb26866e7a6, 0xc524fd28602dd5c6, + 0x37437aec3224a102, 0xebf061e3b1f64184, 0x97cb33662662fb3b, 0x64d43974b564ffff, + 0xe71484dca0b94ad3, 0x4f43044d56d0a32b, 0x46eae24732f233f5, 0x75c910369aff78ad, + 0x7da6d10b75443d01, 0xb2d76d35c4033d38, 0x67dc4f04f690885c, 0x131568cf02c74672, + 0x52e8dc89161d9d16, 0x3ae7c7a732e52a57, 0x78e1b9697f4e59f3, 0xe8fa1fb7e0213b9b, + 0x0e5b0049c96dd48e, 0x87956e1d8e2cafb7, 0xfd35f963dc92d855, 0xea5b4a4d12abe178, + 0xcab6dd084a22cec7, 0x7ce15cc5d29a81c8, 0x77e589f161c1db9f, 0x7dbc1a6d4eb6a831, + 0xc4cbdcb9d392dbbb, 0x3dd256e4426a08bb, 0x0e2a1efbfc685122, 0x453e49d291a4e930, + 0x2404994f0995a327, 0x0e88f460095331ba, 0xadee07fdc43a3067, 0x4d877bffd7eb019a, + 0xdfa2cbdbf104464d, 0x8d385d79012114d5, 0x81a48bc2fa460db9, 0xafa87103124a8e29, + 0x244c694ded2aa66c, 0x1f1946781cddfd60, 0xaf1cd25e36bb382c, 0x7233672194a63a5c, + 0xa8362d8a3be913e0, 0x44f5badace4c3088, 0x2d390e9563993ef5, 0x5d2fdde2930d6acb, + 0x9596eb7ab5690462, 0x6cd352a166f8741b, 0xf0c8a52be85dbfe7, 0x41ce696fd14931e8, + 0xde7e88219dc73aa0, 0x3580481fcd5929f8, 0x93ff41374fce0eb6, 0xbd532ab91db0e533, + 0x864d1d294c4068c2, 0x332bebcfb1daf918, 0xbdbeb51fe52c2ac9, 0x7e60276b5e61d8ae, + 0x16c60a00a12bb404, 0x963b9d3ea27e24f0, 0x387030fa925ef5aa, 0x52148d71892d7bb7, + 0x82e47efd6f669f44, 0xdaaaeb054f243b94, 0xb38472e0ddd960c5, 0x7cc73f77ba78657c, + 0x86a3885f7fd3c673, 0x0e087c85d93cee23, 0xa212f0e452d5be40, 0xffa4f4cd91b51a9c, + 0x1f6c9b047e0ab63a, 0x903acce001ec5f1d, 0x42cbce91b1b9f1c3, 0xc6e45d5054463e25, + 0xfee11e956d381cd7, 0xeeb4da5dd5ab2ad6, 0x7a0ac2090f09c2b1, 0xaaee43fd7f6c74d7, + 0xd197a3134e3c0181, 0x18c629e2699f7f77, 0x2273479923b3bb79, 0x3759131c568f1ef8, + 0x240b470664175a3d, 0x2e7b2c7ba7e26c59, 0xc7a2b4e1fd6535d7, 0x5647c73c92e3aa7c, + 0xa1ab07bd1a95e94c, 0xbe89e0aa48de9782, 0x2fca24c421653e47, 0xdefa3b60dea5aae4, + 0x06d4a3e1374bf6cf, 0x60465c2b532b1ccd, 0x46d0f782118e3feb, 0x30b226b6eb8247fa, + 0x8140b8a2823759b5, 0xdad89a33a0d02c2d, 0xff6379c997b33234, 0x9145d90c8830f2c3, + 0xc533ff7c8097e665, 0x37d2e089ff79ad90, 0x8182338df9cc5fce, 0xa9f43cc3aa42aa80, + 0xe61e03931606e3df, 0x8b3ee0a38fcf0e3a, 0x8b5078cbf5559735, 0x6109da7d2f05121d, + 0xc955d5711b923fc8, 0xa4baf0c235419a63, 0x094eee1d4adcac6c, 0x39d22478ec6cb36c, + 0xe34397f46adb768d, 0x0723d49866e10282, 0x510b1c2ce93c3762, 0x68084ad1d611771a, + 0x2166a2cca108c67d, 0x8f46da440b793e67, 0xcfe68e151ff413bf, 0x23a65d54ac8809f8, + 0x87e2ad6a5e9a6f52, 0x7b88e1ec0c75a5eb, 0xfc3081463247998e, 0x9189ce148ca1c8df, + 0x540bf3a145fb795b, 0x43c937c1a90116d0, 0x75a699ae4c51c62c, 0x67b39972366a135d, + 0xe4f2cb4036147732, 0xec852a3a7c4d7c4f, 0x91f382e542ddf515, 0xd92ecc8ecdd0c21e, + 0x8ccf49a93fb6c4e5, 0x39b48cb730f5e26f, 0xfdc93778858e46bb, 0xd8c9bfe9cdfb972d, + 0x314ce22df1a38b30, 0x694c3f4fa03b9543, 0xf37aaec4c12c6be0, 0x13bd201e6de19020, + 0x9685e7ac2c83bbf4, 0x3e44dfa771b2105c, 0x9b794fb251eb7d8f, 0xd3344ff200d8de46, + 0x99c002b7e816074b, 0xa2939cd29060f5d7, 0xbc0fd37d91c28eff, 0xc66da1d671234729, + 0xa5521d4258c8b5a6, 0xe9b203cb4f897063, 0x9aed1ed067b8cfea, 0xe14e53b2019f9d9f, + 0x5ef7af36bebf7bfa, 0xefddb95022ed0f51, 0x2d7e1e7780b725d3, 0x182c9faa056cdbc6, + 0x63c1fc15a7bd2a54, 0x516a95f2ba040192, 0x79108d77ef69130b, 0xc7384a218c3a0dd6, + 0x256396790b34da2a, 0x490959200fa176d9, 0xb69eaffaeb202d9b, 0x7ff84d1cf506383a, + 0x50048a2fd1015e1a, 0x520514d2d61449f8, 0x481bc85f1c695827, 0xd8e7aa31a21acb9f, + 0x901fbb7b2edd3c1d, 0x130da25ab14db223, 0x9912c245889ac947, 0x43c69865875b319c, + 0x59615cb0ec2a60c5, 0x8dbacebfca89a39f, 0x06483d9be414e0e6, 0x2325fe656bb05124, + 0xae4847ef71c44a21, 0xf7f7add047a5c5aa, 0x9fa1ac7dfc60725a, 0xe46faa355308cb56, + 0x9780850af3f57f56, 0xa87c3bfe263f38f5, 0x37cff25eac08ebc7, 0x53f287aff127ccf5, + 0xe5f1e3859183fa76, 0x91b83311f18e7619, 0xd6fcbd30444a4e01, 0x0cdfab2c1baf0d4f, + 0x1e17af95943451b4, 0xb24b06a876daec08, 0x1ca0ca381373143a, 0x38312229094b9587, + 0xe8a5d548ac56d69d, 0x2bb4b98778bdf780, 0xe6f6a2cfebd4cd82, 0xc0b74dd8cb51a469, + 0x813e7401c20b5276, 0xda08ff30b49c7cb4, 0xdd87ba9a5a494ea0, 0x25d8dd5a1ed19d9f, + 0xf786b3d56d76ee8b, 0x6337fe12913b8b49, 0xcc048655757ee4cb, 0x8e804f8afb4775d7, + 0x2d6757369b2be13b, 0xf64204708875e7a3, 0x6a0ac8f1f93fabce, 0xd7c867f405658052, + 0x3f8ba8b988ca8bf6, 0xb3580788119552ac, 0x3847213008fa9c35, 0x558c2e3581c5ca18, + 0x37692098334c777a, 0xf1bf582dfed8fe37, 0x47f42df2adde9772, 0x77b172a47e6d6398, + 0xcf679e65c01d4bfd, 0xf6b6db4897a38592, 0x79b67cf3f8e4a556, 0xaaab94e52ccfd931, + 0xa6566b80a61da572, 0xe797ade632065ac8, 0x04bcc71c99e69400, 0xf13fc369713cc54d, + 0x77bbfd1d5628b1dc, 0x782946c1fdad04be, 0xda92eb4fa9f22ca3, 0x6c4e2601d509f661, + 0xc3762d7eb3d89986, 0x8f50130966a6d53c, 0x13d1827323197333, 0x9598c33944f0a49d, + 0xde761bf5946efed2, 0x3ccdf95cd2c975f4, 0x0258ff5ac03da83f, 0x24e77a62babed354, + 0xff657fbe14224a93, 0x0b37a828b9cef567, 0xfea69b14995efa72, 0x3b800c74d47e38be, + 0x0b3455e2c673caca, 0xb7e634e980d9607d, 0xfd23af57858bd5c4, 0xcc149f3e9db9dab4, + 0x5eb0bc53336307c1, 0xd04a63edd46de8f6, 0x747d65a62939041b, 0xa8abf10a80d964c3, + 0xfa57f51ea6de4a6f, 0x00ba7036ed7dc386, 0x4b571ff391c8eb47, 0xd0c7c9fa3c0bc401, + 0x69c6345c903d9daf, 0xfb9d313329ff0b5b, 0xd2c1bf32732b9420, 0xa98a78e331480ef2, + 0x75be0f695208fd68, 0x317380f8724e7679, 0x5fec9037ac0915f5, 0x512f36dac61d3f71, + 0xc1b526d21f12641f, 0x0d0728016f1d597a, 0xcd8f9a2937b1bce8, 0x835a5f03df3c9089, + 0x19ecb49b43cc71e0, 0xdb73bd1fb71682bb, 0xf9edadb8c35dd680, 0xb898f966f9e0be14, + 0xd11cf62c0b0f9da2, 0xa2d567b46c96e19b, 0x5f1a42c3152b0598, 0x8ce0467bc0033b56, + 0x1f10a87eca72ec57, 0xa720b3e18034c4b4, 0xca3288601bd803e5, 0x280718c1b0eb270d, + 0x45e3b3378320e53c, 0x38eb8ff616dc1844, 0xde777c0917d6e048, 0xaaac9b8dac1fdc0b, + 0x1f054466db74363d, 0x3aa721dd755e0f89, 0x30e1aea711a061b2, 0xdf5bebe55cddbf93, + 0x36216e4430e1b438, 0x52c9f096f0eac8e7, 0xd8a841e76298a9d7, 0xfcdec447c5c419c1, + 0x83b63d70444faffc, 0x4cb47c5e4736bc3f, 0x76832cc3b97b9d24, 0xe067ca46b2ae5e20, + 0x8f60c46b8b8277a5, 0x660bb513581819ec, 0x2ced1740f6e6cd00, 0x8f40063d7d49a605, + 0x772df024ebf00c99, 0x17615b186d086035, 0xd6491375b0cc892b, 0xaa407d8cd5ef6418, + 0x51112b32b13cc2bb, 0x0df85d5f1146b42e, 0xd94faa35f3665250, 0xb47663f6e4e1b79a, + 0x60837eee56f62150, 0xd6bcd6609f280fcd, 0x6da80abf4670377f, 0x97d02dbf9b5988c8, + 0x0e12dcd7b0ae11dc, 0x7606baad49b96b2a, 0x1826be922d480024, 0x09baf41a70440458, + 0x062603cc9fcc2750, 0xbc0f406b1b76b0f2, 0x36ac92b0b5841071, 0x0e4d9da31efb6ea6, + 0xdc38eac21cf59f32, 0xb0de4e96651f7c81, 0xe3c090b2df99769f, 0x26639c4c369c4243, + 0xbe07f6ac649612ac, 0x8d4325000f2cf6b9, 0xa89e32a016cf1889, 0xb289048d36228840, + 0xca508eb623feabd7, 0x88e02ec2516c18d0, 0xc2fc805027291101, 0xaa1e81b3a731a75b, + 0xb4c70a59c69a0785, 0xa63eb20b72573d90, 0x7fbc6149926a48e6, 0x20d5f628c85c4d72, + 0xf3c743f2657929b9, 0xeca9e116a681142f, 0x38369a1159e6d895, 0xb4bf146f16878ba8, + 0xb7b68e4616bdec2d, 0xc84101d01e8096f4, 0x675fbe286128ac25, 0xb9edafd8e7ad4f26, + 0x74a20cc86281bd4a, 0x4a466960c5e804b1, 0x8a149687ad2b7285, 0x64b9a06d8ab0f22b, + 0xbb991bdd6eb514b2, 0x4de3fcffcd428b8f, 0x2464484e3fcf6d11, 0x03958b859f2fc0c5, + 0x89a394c6c16f24d3, 0x5b161805fe71982e, 0xc391c4bb906d2b35, 0xcd7241ceec63bb9c, + 0xf1c314f6ac195b52, 0x8995d87e707fa1b7, 0x54baf1d358fd49fc, 0x3ccebc83ec88d7bb, + 0x0f874698aa98cb61, 0xe43d68c2164b1e07, 0xcfe503d8657632eb, 0x428c670ff6126436, + 0x0b9baf2d7a465132, 0x755737d4ed2d549d, 0xa824be4c7bb705e1, 0x95858a2818f035db, + 0x607fdf6d0971b06a, 0x7bba426ee3884444, 0xd7f10a602b1e59bd, 0xa16f3f1d79281aa9, + 0xb62374200379ed8b, 0x6e5fa3e8dda32580, 0xc6273eedbca700da, 0x805f27f6f93c1270, + 0xf6321aea00309f31, 0xc71dccef85b5298e, 0xe646119436e8c4de, 0x9164c94f72d4d384, + 0x55ac60a41c4a98ae, 0x19dc3da7485b4dca, 0x38c4162c44976caf, 0xee7395d903139138, + 0x29c31eca0be80180, 0xc9dca3e61542822d, 0x5df6c961c92088c8, 0xfa80d04cf20097d1, + 0x99f0a9b237f645f2, 0x36aa4b1bf2372ba8, 0xe9c2736c11193517, 0xcd62644a1f66d4f3, + 0x53340648851b2b8c, 0x854a0fea838faef3, 0x13f3ab9f4c6ec43e, 0xb82d4bcd2941cbbb, + 0x26d085d6f2c0263d, 0x65099e06102cc17e, 0x8c6c6422199400db, 0xc6552aabba8c5acd, + 0x1dca32d98243a4b2, 0xbf6e8dc24ce7daf4, 0x9f791fe7dba0fc1e, 0x8ca23ea314d70f90, + 0x3aefa7b9f4901e59, 0xf69e7b03c46c4a8d, 0xd2306d5987d5a14b, 0xacdc21d16202078d, + 0xdf425d3756fb471f, 0xfe8e7bdbb7009a91, 0x4feea68ed3dbdcdb, 0x9193630a62694bbd, + 0xb0fd4b4c920bd48f, 0x373515f1b4992ff6, 0x71924ade1955f80c, 0xef830e145c0397ed, + 0x35af4208735aea5c, 0x1ca603e1582e95c1, 0xe292fc34368ed5da, 0x96dbc7f046abbfff, + 0x7cca2d61ecaaec9e, 0xcdbab55ac0c9bc9f, 0x95621f83d8755585, 0x7660c6def794c0b2, + 0x99da48951632ebfe, 0x387c2fca00e09e73, 0xba761acca450f79f, 0x4b45f361c444fc88, + 0x38f3b92b86abe63d, 0xe44e18b5d92f112b, 0x9a3782fd954fc7cb, 0xc37efa5b713fafb5, + 0x42eeb1b69c8def09, 0x95cf4b8defba9377, 0x0b8ae887246cf645, 0x3e32667467064a73, + 0x34d819c823afb687, 0x19d0f4c3ef8e299c, 0x5e470535d9523234, 0xbf03e5bde23d85a5, + 0xb98a764d0151e671, 0x97f0f80bd63bc9a3, 0x488d3af3e3bb4fce, 0xc4eda71a90d4dafd, + 0x23908d0c7c6081f8, 0x5583c6cde544764e, 0x9c119dbbf8f7d2d6, 0x1dc9d1fd7a040acd, + 0x7fb889a1688fcd70, 0x396a3b776709a8ff, 0x987a8497c7ab08b2, 0x02d9e487a6e0c28b, + 0x830aa7338c3382bf, 0x7795154efdb9c497, 0x9e344af73ddcb490, 0x061cf4d028416c62, + 0x4e59fb66ade94729, 0x2ce7e175f4eda33c, 0xf3d7481866d57df3, 0xe47b85278045db6c, + 0xbd886f72773d9236, 0x0ba218015ae0c02e, 0x621afa8e1bdc9ea7, 0xf25a08ebd5aaf451, + 0xd19dc33146c657fd, 0xb560953b5604cfd8, 0x8c2146bf46350377, 0x9a7ade60831255d5, + 0x402d1e2a680f5b33, 0x3d96f3388d24d1ff, 0xb4db88530a32abdb, 0x974a344238dd4793, + 0xa36736a076cae2fb, 0x1c98f3004c9c0d64, 0x1ef88f44edc13d42, 0x590c42eae2c64122, + 0x25672075b53dfa43, 0x601f7dee29820ba7, 0x5d6e0cb216306637, 0x5f9bbf3d7b7c3fbe, + 0x6795a53b4f3e1737, 0x20002e8aa88cb6b1, 0x1cfb6a48ca9dc709, 0xe24f387a2c6c2a1b, + 0xf7af223d9c79a57c, 0x50612854876564a6, 0xd51c43874406c5e3, 0x77b87dedc58b046f, + 0x6bdbd07949a0e99a, 0x20270594ac02694d, 0xaa1446dd1dca6ee9, 0x0d8fe41a9fbf3c8c, + 0x99be8b1545396d5b, 0x4f39635dd99652b7, 0x43bbfb2bec8bc187, 0xce4789c1e735be90, + 0x36981fa7233aa06c, 0xf5d1e8bfd865213b, 0x057a529eb951bdb6, 0x106fcebcb38d2109, + 0x61d131f362084247, 0xd236b1376dcd11df, 0xf1cca70aad94154e, 0x85d3d9bc0b853958, + 0xc84a3066624cb409, 0xdca5e985a70f9c87, 0x789160ae49f8b5e0, 0x2e4c503cd55eca5e, + 0xf07f6b15f4f89cb4, 0xee03452169ee2f68, 0x7340761cedbaeed6, 0x329306166ad8e41a, + 0x32d4eaecb8b4fad5, 0x0e46204839ec8b8d, 0x67b7ff2bff382159, 0x1407e69b569f826e, + 0x4fe4ac790df30a9f, 0x701117666ce619b3, 0x2a00503d24729ba8, 0x2ffbde4adc505ea1, + 0x0e8e75538d746cf0, 0x100a33595f1ac082, 0x537ebe7016b7e1ba, 0x99949be7136ac56c, + 0x8167bce74c6621a9, 0x2752080060f9ab76, 0x3096a9f374f385ac, 0xd0674caf5a6f1cbb, + 0x27002fed7eaea9b0, 0x1679b5eee6b50b25, 0xedc20d513c2f32ef, 0xf2ba508181c85bdc, + 0x6efb4655eb1043c1, 0xf40aa347947531e8, 0x4dde175551aca7f7, 0x61df266112ca688a, + 0x59b0c837ffb81c6d, 0x16d05f0e45822a65, 0x6daaef7bc9350c4a, 0xaf7a6c87f6393c49, + 0xc514e433645537e7, 0xc3f12aee7e01d0d3, 0xcfdf9722d0028722, 0xd67b6741b2f98b20, + 0x5ca31126d24beb6d, 0xd76635268fa0198b, 0x1595c39a2a50650a, 0x5354c6fdabca5651, + 0x25f36840eb3eccee, 0x7250161b5133ee71, 0x36dcb5f0eff058f6, 0xb5264dfa74b1b0c1, + 0x5e0a94b8e3882037, 0xaccf1a937f141aa1, 0x82dab4e4abb51083, 0x375ab20edfda88bd, + 0xeec79d35ddd69de5, 0x9052f7cd99b2c06d, 0x0ad859c9fc8a9c8e, 0xb6b3d3b20702e798, + 0x135f026dd2fbe058, 0x3eefe45553dd0085, 0xf732de799b8c8c4c, 0xbd4911769e4eebc4, + 0x3b18ab8b4c671c4d, 0x47e1e3589d47dad4, 0xc2a3e3277c608506, 0x56dbdc58c8d56898, + 0xa8357d850096288d, 0xcdba049ef091ad4d, 0x1bc62190aaa1e0b9, 0xe5097f207a3e1ad5, + 0x089ce2191c02708e, 0x6474d72b03828acd, 0x4aa39f11005a1031, 0x05c067e5a388e345, + 0xe9ef6c784ef2267e, 0x751941aba1778cbc, 0x54d94a09de663b4b, 0x2cf11762b4b5a7a9, + 0x49c82dab8abfe606, 0x4ced20152b67af61, 0x3bab3edd19059a1a, 0x2c0076a10bbc2833, + 0x089a9ca50c5e14a0, 0xac6fcd5f9df3311d, 0x567eda14128e22b4, 0xd0226172579a152f, + 0x142a67450a1c4545, 0x681f8901ad715533, 0x0d06f6f9da1ea9d7, 0x661e31b7a718583a, + 0x271b2ebf035077bb, 0x651e09e8240fb017, 0x91f95eb3a1461485, 0x00b44c6d06d9a2a5, + 0x4f19e198b6901ba5, 0x86d580c9ce49ced7, 0x664ddc7e92ac5622, 0x40661be1707fc4ed, + 0x6cf7237eebc4886f, 0xd6f8133e42703588, 0x9e7d06d19972a6f1, 0x09c05542bde0da74, + 0x0fe5a1b6b82799e7, 0xd35efc393ae0f23e, 0x8bc4251286cc1974, 0x297500ea151e4d6e, + 0x3f32a5df428cd8e8, 0xf8bf933bee1b2201, 0x16597f18f267d6ed, 0xe710d43c90673b39, + 0x25f02d8e20850744, 0x2957f8a732b10d76, 0x976af6e29dbde167, 0xb7ce41c9d36d12ac, + 0x20d1505761dc62bd, 0x0dc3ab4900cc5b19, 0xa589e0bcaa247075, 0x531cbd93b7a7c44f, + 0xd50c8e5e438bb1a0, 0x1fd673b978cfb9ac, 0xe80ae2d54787bcdd, 0xb56e14dac275d28b, + 0xe4fbddd66fd370cd, 0x0135b63537932984, 0xee872df90ffec0a0, 0x0859ba0cb6430855, + 0xc5e177664b02af91, 0x5bb286fbe4699249, 0x815884bd47555df9, 0xe7d70ccd2fcd7628, + 0x2a8bdca4ada2a67c, 0x19490274aa037759, 0xaac2c469d76c0089, 0x2d1d5ec1ad0b1373, + 0x0cb208a497828dbe, 0xd24935af0cded5bb, 0xd0dd4c04dde0e35a, 0xd2733ab7a3acf6a9, + 0x0810fb6ec6828899, 0xe978d4cfb5b9a19e, 0xb5700d40a394ef08, 0x3778e05853b99e8d, + 0xb7efec0672a23a8c, 0x21b07b71cbc78e64, 0x9c6fa0dd0b685cae, 0xf8a02f1838c60b49, + 0xef4e0b62f291bc4c, 0x523347cee91766e4, 0x9b8a4c03c8153b2c, 0xdbfa8a07251b1ace, + 0xa561b66923590668, 0x16950e8116f9b7f8, 0xf00c290190d3ff7b, 0xcdbdf6544c4c5ed3, + 0x24453422dc520ee5, 0x4e71767b2be83239, 0x7f46f609661f759f, 0x7574f2bdde733313, + 0x6b7f973a8dba93c0, 0x700e182a24016599, 0xdea646d384cae0d9, 0x9a9357b8a9f54e04, + 0xfe8e415c52016a26, 0x956d0fe2a10d88d2, 0xedf6b31e2e72da87, 0x5d52ebbe1c9b1ba2, + 0xcd871a427910627f, 0xd78db306283b45b7, 0xc1abeb3ae57fb02d, 0x575005bdf0c0f425, + 0x0b80f1f9a0d59a1a, 0x700b4038b771a281, 0x59784779cb70c918, 0xcfe52f015cdf968a, + 0x6e0e2e19724cc02d, 0x7778d905899e2226, 0x5f8fb412a6cb0bc0, 0x931d2d762aefd6a0, + 0x9fb0d1a3ea23a91f, 0xc03890ab5cef7d6e, 0xc119ebdd4948d76b, 0x42a92c0a16a399f7, + 0x79617bf36a202312, 0x0ca2499ed9919300, 0xb360d811a987bccf, 0xeeaac9eccd5507df, + 0xb172bf14cc15504c, 0x440ee0542baf8b80, 0xc3c6e37104a19598, 0xd4e7774647dc769e, + 0xae71865543746ca2, 0x58f89d86cbcb22d1, 0xab811468ccb0e740, 0xff9fcf3e368bca81, + 0x54c4a4393dea48d8, 0xf02ac04aba9ade99, 0x905d161c2188bb90, 0xeaf1a7bebe6f03b5, + 0xf38bca616d7f9bfe, 0x8525c10aa5f50eea, 0x292c54d59f0d9bf1, 0x78f0b1b1f371ef23, + 0x91fa38ecc9dd5ea5, 0x72a6fd65f132602f, 0x8e7483cb1639b1db, 0xf47e80cc11dee983, + 0xd51b087fdbc0610b, 0x22a3eb273c3baa35, 0x2920b1dc0d718938, 0xece5cf9caf6699f0, + 0x40206488fba573b5, 0xeb2cc57dd37bac0d, 0x26eb9b8dda7cdd66, 0xed5cd452e785584a, + 0xcffedc5cd3565527, 0xb79e3deb7a340c8a, 0xe01f37c73729094d, 0x3e5e17ff62f06df4, + 0x5500ed0148226012, 0xc754484b4393c7bf, 0xb7d032f0805520ca, 0xe386b8d51e460132, + 0xdd5e3d0b1f520150, 0xe9296af3a652983b, 0xbe721beea5067b12, 0x5674fb4d39f43784, + 0x99686b64994cd3a7, 0xaf80e8de9b71cc99, 0x0855c005a1d1e765, 0x6f12a6f0c2ed124f, + 0x1deab1710f4dd43c, 0xc7a1695f21a6f5d6, 0xd8ba05ded95d00e5, 0x94fc77f5842f5cff, + 0x7a01dbe295fe2278, 0x3861c5d888a1786e, 0x78136a63e2507e7a, 0x44e19ea5d0be81e3, + 0xcf3638c994ac39cc, 0xca7d29075ed949b8, 0xfffd73ab10719179, 0x0c0786c2004ff8e7, + 0x8e550eae7ea4d2f9, 0x369bbe11b7793d8d, 0xadb9dcf0ded8d287, 0xf6564061966d8df0, + 0x40007e2f668869f4, 0x89ecc996bbd1fa1f, 0x17243ed53072f0aa, 0xde05d87789ecfd1c, + 0xdf3a02709025ebfa, 0xe9af6a5ab217f05c, 0xc9e2e2897c7d4155, 0x2e6a0ed7b78e6949, + 0xf2fd442173d7e5ee, 0x95e551cb26d4818b, 0x78181b7f88fb21ec, 0x8a2306fde58644d4, + 0xc4169ba7990149b1, 0x50b2403cc17f99db, 0x780bd6573b61582a, 0x8916fc82bd75715f, + 0x79f0c0167b1ebf83, 0x5e6c0c6f40587f5b, 0xd617b957d687fc5c, 0xf3b8fd33f6367591, + 0x5aa436da519426ca, 0x56ac7eab2c2564b5, 0x3d07941ef30605e1, 0x9bfff7347fcb4284, + 0x82ced7ce89d608b3, 0xcd11ac44be2a9e55, 0x648ec33bf5d0c40f, 0x6668a6846322d18e, + 0xb4bbd5d87bfb9aa9, 0x9ccf30f91f654829, 0x2e78b20621b64b33, 0x66110106bc7aac37, + 0xd874f7285f04a246, 0x7b3fd95ec30db1b4, 0xc850ef605c8426f8, 0x7815adf69e763e99, + 0x2c58ab20d5ba27cf, 0x7c2fa05f78893615, 0xb0285f230f9b90d2, 0xf4abf33b340da595, + 0x586b16a5c9d7c76a, 0x7675388529313c5d, 0x6adaff4b1bc68c0a, 0xf09fcc58437717e4, + 0xfd9821d19d28a6ba, 0xb3b1202bf4d4d793, 0x92b89e9863cee0bf, 0x1ffce81f602a13b3, + 0x840f25dcae9d589b, 0x8fa8bb0f876110ad, 0xa9b0c1bd8a5e8a2e, 0xd66835574190fcd3, + 0x3cb7cf9fa0a0f07a, 0x186f9eeb4e13e68d, 0xfe803fbf6dfc17be, 0x38aa2e7ca2465215, + 0x30f2cc949c4104c2, 0x8d200731c746319b, 0xb7d7003ae11eda3c, 0x38506c984d3a0309, + 0xe1c6491824c66794, 0xc73e54f2c9c14767, 0x8a7e2ca9d5481151, 0x893fc892a8079667, + 0x433828fdee415bbc, 0x8fa1b4b2d8f7c848, 0x0c5a1011a064f996, 0xca5421353702182e, + 0x43841debb3a70963, 0x19f640bb488a312c, 0xeb69965a01560873, 0x460d3cab23466c13, + 0xb23554017c3d6b78, 0x39602cb82cb04c7e, 0xa3c5272478279b4f, 0x58bdbf706a74ade5, + 0x85ec70da3633d1d9, 0x117dd59b79626827, 0xbe67ede736a0b3d7, 0x9cf5b071c402c1a8, + 0x6a1e84c7bba1ff3f, 0xadaf457198e6753d, 0xe10205f6e8c05cc1, 0xc1c9ac4e3c5d729e, + 0x92582d8f2db2342c, 0x3fb3cd2f8c8b55c3, 0xe7cce95f69d2a33c, 0x3089390ea5879321, + 0x1eb6a8936400eedc, 0x2890ce537fbdbbb1, 0x2cca7dea90ca2584, 0xcbe564c4ff2d3dd8, + 0x027b16242817fbf1, 0x5d7becb82bc3619d, 0xa183e4dce6c2a1e0, 0xa4301207d052a562, + 0xcbbaa5eae852d28e, 0x9539e4fb1daf9525, 0x4d4598d994fb734e, 0xe1d0cad3d78a17b3, + 0x55bfdcdfb65a8aa8, 0xc82555359fdcb348, 0x9135a05a24efb347, 0x70ce9358da719063, + 0xc651f0f2cfc97d43, 0x2a9bd238779e179c, 0xae2fa722861f52ea, 0xb66505d290d90eea, + 0xb0d1a90f4008b121, 0x7cac97ee252cdc27, 0x1d94839f58bcbb4e, 0x11e2527ca193a533, + 0x97907d982dcb5b0c, 0xe2d142bfded54991, 0x77162a02db980573, 0xd90c6642b503159c, + 0x1885adbcf1515aa4, 0xa941777095b695d5, 0x4d698071a17b153b, 0xe11cccee0f7542aa, + 0x22538898df0fb857, 0x65e233a375e76a1a, 0xa079e239db1478b4, 0x7b33d7f0c9c6eb1b, + 0x726f2d8fbf45fff0, 0xfecd76d173ba35fe, 0xb3a8967ef36cfb49, 0xc5d9f703f7d509df, + 0xb3ab36c8eef477fe, 0xe84c68dbb957597d, 0xa7e76322d8b35fa6, 0x88c80bec280e3fe1, + 0x07f3e5108e2d8da8, 0xde9cb039b3762596, 0x1d1acbe0dd3c9748, 0xac6ca3cc453fa9af, + 0x057ac800f2ad54cc, 0x57006358171b2096, 0xe76a98a2e6ea2966, 0x0ed88ac00b15adc8, + 0xd767f633d3649bad, 0xf86f57ff08c0079c, 0xed6a17751802166e, 0x09f5f561ac302ff8, + 0x33dc072b372f64a8, 0xaead1a02891bfd56, 0xce53b1a4834b2253, 0x82fbd8982c006436, + 0xe0fa2e82f60426e4, 0xcdc732dac6e88e41, 0x99bb6a8966973b97, 0xa4bd5446aa480d1b, + 0x500ca9cb7e493ea5, 0xc12d766e94e16b32, 0x0b9ab609d2e2361b, 0xf5e2581360de01e5, + 0xd858383309c178d0, 0x24625a428927e6e9, 0x8afe88fd23e26c5a, 0xaf3e936ff1b0fe3d, + 0x29aea6dc67ddccfd, 0x0cd1d0591ffdc3ec, 0xb7c2e4f87795691d, 0x1db6a33ffbdebf08, + 0xd41c06d2ff34ca2e, 0x24f99d2668765759, 0x3ff4b7ac7a822aea, 0x58eeba464d861fdf, + 0x5eb7381f00826fe4, 0xf9232ef5e3126145, 0x0f1885f10b4a1089, 0xe0ec889277a9d93a, + 0xa524af930dc87100, 0xa9beae59a0cd0399, 0x18367d49595e780c, 0xdc2fe288d3fce039, + 0x1a468c82bfe3c965, 0xbafa8efdea2942d0, 0x089c7e1d53f9b84e, 0x6241ca20b201f56c, + 0x2390d9e811475c76, 0x3512aa181017180b, 0x433437881b926f2b, 0x79d3de4069f86308, + 0xcdf2efc517b28c3a, 0xec1cc28523ef0b46, 0xef94066fded0c024, 0x98650d2aab484a04, + 0xd246289256787cdb, 0xeb76d5341d6a7ff2, 0x1760287a41813922, 0x1dbca9910706b6b7, + 0x7c60d555360aaac3, 0x132c3b511a430052, 0xd8e58af0980516ad, 0xcdbe8409d927895f, + 0xd17618bdd22969e3, 0xd73f3d6b7509db9a, 0xcf2d0613cb90308f, 0x551ed304bbe87e24, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57012b7623513003, 0xb9d53d3a262981fb, 0xe59152cde65c47e0, 0x9e923f46001294a2, + 0x5c7e821de003ecb4, 0x7a0136fdb5c08b9a, 0x1f739b028ab288d8, 0xba787c839e8e6241, + 0x2ea81495dc7e14ba, 0x4e693ece3030a628, 0xf0dd79876eb1b895, 0x83758ece660b60f0, + 0xec1d55458d59179e, 0x59365825e63ff5be, 0xca9a4796f743eb07, 0xe4abe3091e998f38, + 0x6f16fa584f945f41, 0xb85f2f62f74e53d2, 0x851ba3f9cb61f7dc, 0x44bb2aab08e53136, + 0xe208b02e8d0653e1, 0x870ab2907cf00697, 0x74540958dbd4d8fc, 0xaf3b792717068107, + 0x667f86d56f5bb7ce, 0xbf5e26cd162c0be8, 0x2d6cd78ed4c823ad, 0xdb20a247c92ff2bb, + 0x7daabc09fc5e7192, 0x0919e5db33883db4, 0x2db0f91ddd0c26c7, 0xfbf0b05a0fc80c35, + 0xe93cc23f3a99e52b, 0x66e144d33f88e47a, 0x2a9eb42d1d9d07de, 0xc7731d33dc47a241, + 0xdb87ec6e7a0ad0fc, 0x244e79f4edc06e2f, 0x8501a00fcf08f60d, 0x3dc3f696f724d3eb, + 0x8f30846e89f43c42, 0x7202a854ddd95d05, 0x0c18a89f5f5868a8, 0xff42e0142a9baf2f, + 0xa7e29dc3f192e73b, 0x8d72f26266a19b04, 0x72e5aa54b7f6d00f, 0xe64b10de6cacb419, + 0xa5baf0dc702bd928, 0xe1a0275bec9b219b, 0x166a720a7d501d76, 0x0301e1c365cbaecd, + 0xed4dfc985238d838, 0xa03abd75da120d3d, 0x5cf5b5d32f4958fc, 0x4960fd5fcd324eef, + 0xd7e7a9e831bf22f6, 0xf7f930f56871ba4f, 0x9ff006f604086bad, 0x1b6852a09a32a20b, + 0x855b29d27ecf9a89, 0xd930528872825802, 0xa442f602a66488a2, 0x66573df39f8b7703, + 0x1fa3ddcf2e78ae49, 0x530845061f003d25, 0xff61c31fd81b4f6f, 0xcf22b01a93b89545, + 0x3c0fd53621068e5f, 0xc8cd6bd1d4905028, 0x659dfe6c250302fb, 0x30fb94af9b51de71, + 0xeedbeb7389f46cf3, 0xd0e669dc2bf62310, 0x805b4d45558478d8, 0x786e3686f6554732, + 0xff7ed48b460b496b, 0xd45f4d88f4483bf6, 0xe1e5b82dd4670fc8, 0x48cae852971bcad8, + 0x018db25069d90454, 0xf6437e41c011ba54, 0xdd945f7a880dfa69, 0xaa548af614f01827, + 0x16ca278d860d0793, 0xc239b3de9e6f65d8, 0x59a203aa1d86421c, 0xa6d854080824da11, + 0xae5fb74b636d4112, 0x8e6b01e2a62b751d, 0xa4c73b21e331a967, 0x46cad2db229d92e4, + 0x0463fdc0931c33a8, 0x184cbb249590e13e, 0xa572aab17b604a44, 0xd57e4c28794fc965, + 0x73f148ae7b1b9541, 0xa5f7a4542e0a25ff, 0x848600a5f91ef667, 0x895e7ce4e5a992e0, + 0x7e5cea23f47e9afe, 0xf81d58699d6ab1d2, 0x1d5c044a470f822d, 0xab63aee94922379f, + 0x532b2a346adadc83, 0x00a9045e4aa69554, 0x4735b6bf8b2c2335, 0xdfd4f47cd4dfe6c8, + 0xb168f826d6d9c090, 0xad1e41ae7179a8a1, 0x65899abf5063e125, 0x5a3d2700e66471b9, + 0x393ac11d52e483a4, 0x180a7e1b691e8c35, 0xd650e93ad125ad2b, 0xd96e18039b0ba5af, + 0xe0bb9bb0baa93b6e, 0x239f8b304ea320a3, 0x23f56cf7917489ad, 0x9bfc411d7538e8b9, + 0x093a02e51e95d12f, 0xc7a3e63cd19b8134, 0xb16c5d5bf0b7b2bc, 0xa9a11e907ad6c4c7, + 0xd0b5e64080fbf169, 0x9ca4a0ced302dc75, 0x3ce9fc15eaa5e606, 0xf5bf367dc2db11ce, + 0x8c33b0d4416f2502, 0x7bee44a874bb45a5, 0x9f6280b43737a5ad, 0x5ff81c6bee599166, + 0x5a43ff22d23268f9, 0xa86f555f6e403e43, 0x4d6088ebe31a0f2a, 0xce14669459d57320, + 0x0953d39a06833cc1, 0xb65c0691432845b7, 0xfaae751a908acfa1, 0xe68c92ab15e2f91b, + 0xa324295921f5aacf, 0x69884066a075642f, 0x04efbecc03725374, 0x6f8fd8ddb6347149, + 0x91066ff90e7f6a49, 0xbdd7211ecfd3aa61, 0x7b7492eb9b67e45a, 0xeea0825bb26a3770, + 0x325d4401091b77a6, 0xfdda0a36fe9bcb86, 0xf7b69a0a651ab8d5, 0x46bd511534a5e7c0, + 0xc6d2f8ea03c4b209, 0x95c2e3d055fad576, 0x75b95e2ea2ac61a6, 0xa75f2582ef061a7a, + 0x4fd9d93b8e400bc7, 0x007ada1bde8c15ca, 0x98546ed6b6446554, 0xb913cf73516c4779, + 0x3ce35d2acb0786fb, 0x74eb9fcb49bf4633, 0x79064bdd3c5fad14, 0xc8634902a8f844b7, + 0xbe9e04c7ea046e83, 0xee308bb287e34ced, 0x043c226982253c33, 0xe80d36bb6a7d39d8, + 0x39c205209f258df6, 0xed0e1bcf38c52a46, 0x7567f3b074f33cf4, 0x938dbf723de1eb16, + 0xe430e24bd8fbdf70, 0x47d7065294bf6467, 0xd792f73ca4868280, 0x3decfa6f831010b6, + 0xcec684dbd539bee7, 0xbb4f8817172e7665, 0x55ed72c64a07c6d8, 0x81fa2669c3f132ca, + 0x1162de6fbe8e16ec, 0x66dd10122d3f979c, 0xfe2a7c187aa41419, 0xaec8b041452da475, + 0x8b6d482a30cf8472, 0x3f3f2dc7e2e6c4aa, 0x210b2710945f2807, 0x78ed418c296e9939, + 0x826cb272f991129b, 0xdadc82a245dd3444, 0xf4fdd75856554a84, 0xf930111f1f32b5af, + 0xe075922592834b72, 0x14004ae0e90e7496, 0x624bbd0a6b5721ef, 0x60396b37e330a4dd, + 0x5aeeb7d5e470a347, 0xdf0c0ad51019986e, 0xdf9c50cf239bab57, 0xc7a63486c957cca8, + 0xf8bdd98cee648c3c, 0x281d8364bc6467f1, 0xa8ea359ce68d0c86, 0xbf2bfa9ef8f7228e, + 0xac73b55f0a88ba57, 0x711adbf806f2a375, 0x65ebede00ec0a445, 0x4445d19b1f3e8a49, + 0x2a1ca9421cc192cc, 0x602c0dd9bfef1b50, 0xba06031487f21850, 0xf421fbf58bcc43af, + 0x44c57d9ad72b496c, 0xb95de6f949d2ed95, 0xe8cf11d005d847d3, 0x2c15d4d4c71dc750, + 0xaf91c7e734ce897e, 0xd5b1554ecab1ca4c, 0xe55535ffd08cbfcb, 0x845fe8e460d90b9b, + 0xdb6f0ea18982a569, 0x5338101edfb7566f, 0xdbc4fdd539bf3919, 0xf4f546513f6059f9, + 0xf3ddc95456f90417, 0x9c2652de428c6d7f, 0xb892a77b5ffb40a8, 0x572af6c44579f34b, + 0x6dc40bc71ea154bf, 0xa8790566aba46634, 0x652dfc3f8381a58e, 0xa7509d7b7ca90beb, + 0x14f057af088b5b97, 0x831799f09602183d, 0x2036d3d151165db8, 0x576fe9855865b246, + 0x01e84d4822ea9d75, 0x2fbdaa6beef003d3, 0xb24bbad76466139a, 0x872475faf54d1f11, + 0x4c43012676e12fc8, 0xf531075961f2483d, 0x86433eae7223a4cb, 0x483c40aa18f38a9f, + 0x5abfef21901d5b2d, 0x5d960db5de10e565, 0xafde6275fee61aa5, 0x62533396b8aee586, + 0xa906b40eca1fde62, 0x9a58a16a7564a5d1, 0x47fa05ebf1cad9bc, 0x3b280d37416a5d57, + 0xfa07785c838b20f1, 0xee4312f78e4294d0, 0x8d60a0ff056f34f1, 0x2fbd5e42957e7d87, + 0x1814ebfece7a41d5, 0x42fbb057798b0a7c, 0x353fa598196897b2, 0xfc09d081a6c72e5a, + 0xc8b88c9f7445068d, 0xd659e4cfe6884c7c, 0x57059f24c6c6b875, 0x269fce9992f4b8c3, + 0xc0b817d15d7022fe, 0x1c76c0a649677bb7, 0xa54664d824b1f876, 0xab005c8c1a48250e, + 0xf3778760c5d91193, 0xe3e6a6b38465fbf2, 0xc12dfe9d31cea2b6, 0x90312ec1063fa356, + 0x4ff4389318dc1616, 0xe80680b5c20c6389, 0x9df376b58f45e6df, 0x28162e74a8ac60bb, + 0xc66e10dbfd7f7fc4, 0xbdfb9addd1547e2d, 0x6327fa331e5251cc, 0x2cb1113e753c6fe5, + 0xe9e8c71eee4202db, 0x8d32e09d3d0abe7f, 0xb87281bbec6a056a, 0x8f997578749f1005, + 0x22c766242cb50b0a, 0x75493ca1565cd19f, 0xe679f9c97f214d4b, 0x0849148d17c75c6d, + 0xb0e519d98f2ea7d9, 0x565d9f53516c1da2, 0x204f0bfff68b5310, 0x6e04ed1c0c155c00, + 0xb2391a88969b7a8b, 0x3e31fe5be6d28356, 0xb7e83ca196e9f3db, 0xd97f4ebcd551b175, + 0x71112d36f72a5952, 0x9b650daea6289d5a, 0xfa8740aff1de9206, 0x2adf02d058ad9200, + 0x71f27d2ef6788d25, 0x35d6a4e2b2ab4247, 0x182dd5ec8c753449, 0x80b09c4df1c9c4f1, + 0x8feaf81c2b64039d, 0xb20d97158ff59250, 0x40309695c6be6c40, 0x465de5e5ed205428, + 0xc650abcc2545e4ab, 0x0366c6a58be9245f, 0x63c1d1a29267d6c7, 0x91af1b9819c1198b, + 0x3966eb999eeaeb3b, 0x47bfa36d98b976b6, 0xbfd55fdf23db7115, 0x694fdf60ad4f242c, + 0x4d674c438eb6a791, 0x1a93c54b6206a228, 0x472b44a8758569c7, 0xe591ef7d86b9519b, + 0x073b2f2886af1c12, 0x7444a5e8bad7a5a8, 0xf4dc4018a017811c, 0x5c10af685575195e, + 0xbf7e0d59181d63b0, 0xda84ffb372e72d73, 0x69a8f8e72137f141, 0x8928c7dd580afc5e, + 0x3ea5ac0f49563bd7, 0x9fef5bd4f7091f62, 0xdc5befe242fdab17, 0x7ea1543168470de6, + 0x4d42af84695e301d, 0x3c4a3323e19e5740, 0x3e30e46cdcc25347, 0x3c1b1218d5cfc084, + 0xb98d23c733ab894d, 0x4cd31a7aab1b2dab, 0x4484759d45c90163, 0x4e07297bdbf220e8, + 0x8980b99791d042b2, 0x6ccfb3c4fc39b902, 0xebaf4f10c12d8876, 0x7a502e7870dfc7e5, + 0x673ac34b8fb06e49, 0xbedc9b5a356e3835, 0xf169c3c3655b2843, 0x46441bb30a6d9169, + 0x0cc15712cc2dcc44, 0x7ba5bfa2ce45d3f1, 0xa2b372fa5a6f1665, 0x39de81417e43d829, + 0x2dfcf473778e2535, 0x8d94f3e693e23849, 0xa798beaa31e2f0c8, 0x3b3caa0c395c1fcd, + 0x31483108452ae5df, 0xbb6612034fa9dd21, 0x2fea393a695884a3, 0xae05e43403e3f92f, + 0x8de94abc71a28db1, 0x824ba00e8b16d119, 0xef003e1d844d6927, 0x55530bee2ed65047, + 0x8fa949d85224d14f, 0x0c82cfaae962185d, 0xb9121a587cbd8968, 0x7d6900f64fc472d4, + 0x7d0b4cae00e07e8e, 0xd83d89f6d0d38432, 0xd6eb3d05142d3a40, 0xb16ec50dbaa80824, + 0xd83a4d2a878d4a00, 0x9625a5dce49b6237, 0xbb486ef1c4af5865, 0x3077135a7b4dc4c4, + 0x0cfe3477d05b5b7f, 0xeb9e1cd0d4fffe40, 0x8d5b751fed9c83a0, 0x51855d2023390ba4, + 0xa9d95e25d5df5ec7, 0x10bea39e74a53536, 0x302b6b39ff4fd4d2, 0x62805a9536abb932, + 0xbb4acbc8694c21d2, 0x3e46f37a27eacf4b, 0x9c2279b32886148e, 0xe785a392a7e1abb1, + 0xba1f353c056fa979, 0xed85965049dea9f9, 0x8959c1bbf58ce555, 0xfbfca8b8b78ad553, + 0x25d224d534bcd2e7, 0xdf350385039bb872, 0x1e5330c5c9e6356e, 0x3baaab45a97dac57, + 0x73acc59ad6b4a039, 0x81b72873922f1ec0, 0x86307e881f5dc965, 0x50ab9d93ce618fa7, + 0xb56a82c31236399a, 0x925322cbfb61f582, 0x1c3badbb7d63c638, 0x2c3415e986ede3fc, + 0xb319b9d5ed880ea5, 0x9d6a00efeb105386, 0xad8bf4bf06e083af, 0xa58e07c3bed1a2c4, + 0x517c0632c5a7c6c2, 0x9d89aa8f0af2f949, 0xb1048c53c8c588d4, 0x4098c3833eade047, + 0x10a2a68e10248827, 0x8cbb8b90121a6aa6, 0xf4e667a8bed5e67e, 0xbbba897d8b561fc8, + 0xc0643c049879fb18, 0x345a6854efe2cf1b, 0x3509674116a484e8, 0x2b7b5ead735e2c2e, + 0xc8c0d3246949b122, 0x729a881301fa12b0, 0x5692d6303f1b7053, 0x88b17b15bf5fa163, + 0x0e6ac97a56c78042, 0x87fe29c9566b55e7, 0xc104f8981d0608b5, 0x103f626cfd68ac9f, + 0x77e4fa487b6eb752, 0x5dbbf7adf144e13b, 0xb644e466f7683b5a, 0x6343d5c78025b914, + 0x43e02a79b7372f23, 0x65d044df048c9bff, 0x7816e630e023602c, 0x494d032b44d47bd8, + 0x0909f24cdbd64ac6, 0x9fa1a36938d625f6, 0x4c57370f1dd70004, 0xbc04bb5b6592941d, + 0xdbbacfd279a485f1, 0x23dfef6c200c41e9, 0xcd9df86865565978, 0xfc9d88fa098302fe, + 0x398382a387b63739, 0x9570a9561ab8c57d, 0x6b91e65cd9bae003, 0x3c8eb36ea5968624, + 0xcd48d4b4edcba055, 0x5d3c2f729a4c2f64, 0xae2c851f3ed26fb9, 0x112842dadf8554fd, + 0x6d006bf3fb875a9b, 0x608d849912581cd6, 0xa6c171d124943ccb, 0x759b8a1fb0d19df7, + 0xf0ebd6a1d0e774de, 0x9a5811323349fbc5, 0xa775ad0c30374b51, 0x1be49d5dad4a121d, + 0x3a054173fa304b44, 0x89924789e96b5481, 0x1799b2939875fcfb, 0xffc3444c7d784008, + 0xcdc9d1a42ac08561, 0xa964047feca73809, 0x4b49db547ecfd2cb, 0x67ece48188e13e1f, + 0x3bb94e12d6ae6d60, 0x95e287ad4eb0a2a1, 0xfb6fa2404b6145b0, 0xf9d681ed27914a66, + 0x1d90166d00acfb26, 0x1b50e0977a09573b, 0xf1dacf74cc99285e, 0x0d02482a190e2be9, + 0xa39611e04103197c, 0x9c77efcf9bdede12, 0x7fad23f4a8465660, 0x493d32d9c18d907e, + 0xbf4e30b5998e6421, 0x424bd628fda6fae1, 0x64ac51bcc4dec712, 0x38eb6b9a8e468016, + 0x107ae6a6cba998a7, 0x2aab3be94a810a36, 0xa54bc2682e20252e, 0xec7fbf3060ecfcf5, + 0x10a701da722b558f, 0x3eea5c3074d89347, 0x2cc28b3ab611e713, 0x7b6dc4e5fb8808aa, + 0xe7ceb58d34979139, 0x478b5986f8f1e520, 0xf5af9c876728655b, 0xe3ca60ab855b905f, + 0x1478586a61e31370, 0x5d8156e42757d983, 0xaf3044846eb06235, 0xa01178ba4df87c32, + 0xb216f58359f77c02, 0xbbc82f0cf2721ac8, 0x41199a3f8b8a6e54, 0x08c17d9003a85540, + 0x325986c29a03b666, 0x54706aceeae151eb, 0x6a6e73be7613f0de, 0xbaa075cd5fc17c47, + 0x6fffcbc8add29bf2, 0xfab07d54375d8c1a, 0x20d95b9ac58af7b7, 0x6519f8201f4c7f39, + 0xf5c571ac07e2b34f, 0x958d05a187e1f909, 0x90694ef6d5515b3a, 0x209bdef95df89bf7, + 0xbccb60b34d995690, 0xf529d968f7a341e0, 0xd5932a77e1416627, 0xc1687a9cdb4450b1, + 0xc45e9aa8e15ff353, 0x8e6828f6a3294daa, 0xec76c31c742c1dc0, 0x1f119541cb67862e, + 0xec778c9290654911, 0x0c68fee761ade7f0, 0x57b667c3a7a2abba, 0x156871374fa1634b, + 0xca8722c4142903c8, 0xe0190366cf38ffc1, 0x4984e6b50d387ba5, 0x5d41d9046e573292, + 0x8f32b9d1374449d1, 0x065b8d9c1ce863b9, 0x8e2e98aa837b30e2, 0xf920783d944177bf, + 0xf721f6344f86d4ea, 0xb62fe0633c236b1e, 0xc29c7b8721660ba8, 0xc6ca25205429820d, + 0x000508ec8c3b9ce0, 0x025769fbfac7032f, 0x5bca89e18d0978cd, 0x302fa6dd8d8b97d1, + 0x6dd5279567a46e9f, 0x71f5ad753e205505, 0x71d668e841d58897, 0x48bd5f8f85374404, + 0x3bd378340f649884, 0x06d0ec1fa222a38c, 0xca39527ef3002808, 0xdffb4491bf27164a, + 0x3a7b0724d2f83309, 0x672df76bd93b22ef, 0xf728e8a75454f8b1, 0x10290a3096941c37, + 0x144a4c87c9ee0c0d, 0xedb15fc1ecfcdd39, 0x44df6cf6a26bfeda, 0x997609a6b7b8d23d, + 0xa07429ae1067dc8c, 0xea6e6884374549b7, 0x976984c329042c72, 0x4db88cae728aec1d, + 0xe3368aee461dec8f, 0x4d6a884191038861, 0x3ee2d7ad68c34d12, 0x32285d89f6390344, + 0x27f22908b8e1fbaf, 0x609676b991567d7e, 0x236a39b4f7695282, 0xd32e1e584d8f7fe3, + 0xb74752f975caeea3, 0x9ae7db66c19ed965, 0x5427673a3d58837b, 0x79bfa05291cd96fb, + 0x52cabea1d1632fbc, 0x38458fb7f1823163, 0x2a07dd1f44d2c7f6, 0x55e34f86c2b295d0, + 0xf588af0bbce09ed2, 0x07036247d8fc47c2, 0x8a2d6c2698984d11, 0x451a8ef3629c0182, + 0x11ee1a2ec5de3f57, 0xa764b654996a0332, 0x0fd303499408ca71, 0xf76ffc82fa36022a, + 0x399bae21bdb4c2ad, 0x1b0f6045d840ca15, 0xdfdcdfb6abff1d92, 0x706c14b6ef605b95, + 0x1861b70f36e75d00, 0x12e714d710c6af86, 0x971c7a89ddbff262, 0xf79431f73ebf4854, + 0xee28e53f6ea16654, 0x76f4a1feb1cf4fe2, 0x7b7ea402968141ab, 0xf872c7b5d0af1bfc, + 0x49c73157c1f18301, 0xddc972090426fbc0, 0xab112f1ce5c5a68a, 0x1af2a1c8f135eacb, + 0x57f44acbc78c7606, 0xbdc030802b79a903, 0x83b9ffdd0678937a, 0xee72cc6db82d2b42, + 0xf71a3585b194b3fc, 0x2ef030596cffb6cd, 0x4e5c16be945802e9, 0xdaf07126be4106d7, + 0x459a7ec76e5406f9, 0x079a958227330ac4, 0x900c4ba763dab213, 0x71b93cf3046cdbbf, + 0x0c452a8248b070c2, 0x35fec0790342c6ee, 0x48ac57836e1908c4, 0x073e89c8f4edce34, + 0x6ecb6a2badd62a5e, 0x171f99d2f330561a, 0x01004c473fb69407, 0x98b05f15e492500e, + 0x3c0910bf5b6ecf41, 0x7aedb95863f5b229, 0x76fb9a37e929f2a8, 0xda1075590c673529, + 0x8835dfe275cfdf88, 0xe1dc686664dd9503, 0x1edb23640d30e9f8, 0x78fb09c4715e9f7e, + 0xa4974b3e20a1e356, 0xccd510b9f681cd65, 0x9e9aa92fcfd375cd, 0x31ec608392512a82, + 0x82b79656961c7156, 0x01712a4ba4cf352e, 0xea891ffbabd2af9f, 0x97b7b09c24289115, + 0xbaa151ed16b1ef96, 0x25a075304964bb1e, 0x957a82c5dc4f79af, 0x625908de16e8be15, + 0x8eb34fcd5756d9f3, 0xa47d1f331dde50cc, 0x84702a593a720cac, 0x58e56563577d8779, + 0x722fdb6c49a1959c, 0xaf0926b371747a14, 0xe2ee90798977f1cd, 0x35afba3336a4e6b9, + 0x38779a9f23a60892, 0xc7bbc3a37dc8cdf2, 0xb45a26affe67f713, 0x65bba22ef6b92f64, + 0x14f4c865c57ac7e5, 0xeb3130065542b9c4, 0xcf5ee5db79cedb61, 0x47c5da2bf40292de, + 0x649e3da3ce2b28b2, 0x4e7b71ddf8b23fdd, 0x070f74eacbf4338e, 0x3f15779b4cb5aa16, + 0x2d1c26ec3febfac2, 0xaf38ffa4e5137a83, 0x6847b6f5b48c41bf, 0xcca0dd6e09525ce0, + 0xbe051ee8bdd07ca6, 0xc9acebe544707d9a, 0x8073c472692dbe3c, 0x4f8a5bafe2528d7f, + 0x37a3a2ff47d04bf6, 0x6cff881602b6082b, 0xb951882fa38e937c, 0xed81e065e8bcf06e, + 0x003c6f146c127710, 0x19807ea0423289ad, 0x150cc944daab6fed, 0x74fd3b1ab70c42f4, + 0xcdecac3d9b3faf97, 0x2b14ba4dd141bf46, 0xc4af6686965d2c12, 0xeac952a7729df97d, + 0x9600ebeca9511565, 0xa88c1f6af2576874, 0x4f513fdb0d05fc85, 0xb40c0d9c7283c06a, + 0x88ddb40eeef1afb6, 0x173e397eb5b79971, 0x7d41b69fd846fd0e, 0x6728a6fc0aaf7be4, + 0x80054837d60dd909, 0x6d0e6449c7573a69, 0xc818190280c5cac8, 0x67bade86f03eb7fc, + 0xd6dabd341fdc61d5, 0xc95051e335cbc381, 0x4df99b96bbf06a09, 0xc24e14c8b4e16456, + 0x1f20e21f1d2fa3e5, 0x265cac30f70c904e, 0x7e16fecab711c3e3, 0xe6ccd3dc85a01811, + 0x85d866d0c09325b2, 0x6ef844d4f76df0a1, 0x901caec1727d7865, 0x94a002b720f7a4bc, + 0x939675bfa9117442, 0xfae6eab0a30e5c83, 0x6639cb38a7e57499, 0x04521005e1b08979, + 0x462d2f6560a37643, 0x6aceae0c8969ef73, 0x08adad0af6e8ebc2, 0xb25253da3b4f4bb6, + 0x7b083547a7026971, 0x12310d41e71469a4, 0x1a22c4c36752d5ea, 0xa030a996fcf9d354, + 0x078ad216996ce2a3, 0xa5f65b09fc18d7b8, 0xecb1ab03dabd1cce, 0x4899386ec242ea6b, + 0x587493b7b78a4a16, 0x662b9df844f54def, 0x3750ddef0b1e1f95, 0x87eeebe2bc246de9, + 0x907b9b69c2acee37, 0xb9da549545f357b8, 0x6c89ad5785f60f40, 0xec7eba081691b5f6, + 0xc51b72030a104a6a, 0x7b3a415806a8f0c8, 0xe1082cf323cf4d2f, 0xd4b2b895250267f4, + 0xebbb34c78bf139ef, 0xd4e35fe25fe67f10, 0x61e460da796fba3e, 0x8ba1ae68aea2fc04, + 0xe83334544bd00781, 0x20535b252f1b3652, 0xc8f93c7a0e2f4bf6, 0xdc75ccfa838ce01a, + 0xbece06e00d6b8d96, 0x0d177c4f8ed59e2e, 0x5f234f0537c69e95, 0x0b2b5a729439922a, + 0x4c258f7fe293f38c, 0xdaee0b624ea9e8b0, 0x7bf341615781d045, 0xd2cf4901f284a4aa, + 0xa6ec8a077d72b83e, 0xaf3791798a74360a, 0xa1d80b7df41a9aef, 0xf26860bf40e71dfc, + 0x7eb05ff7a75ed12d, 0xb36850e6bffd810b, 0x3180ee15c93643c1, 0xd83305d22fefb789, + 0xd56e972ffccd9ba2, 0x4ef116b1442570b7, 0x9f99c5bc1890414f, 0xe4c70b1ffbeebc49, + 0xe473c4346e7a98a7, 0x136e3a2afd4228dc, 0xa39a5e60daff0b2c, 0xe0a06630c1ad47d5, + 0xff6b1eb569d417ec, 0x04f70ae08b401696, 0xe4b306869db853b5, 0x8e08b1d39109e01c, + 0xff6667b7603d2379, 0xb647a549a9130efb, 0x3dd94a96bc864514, 0x57538405361d6843, + 0x461a5ced91ac0a04, 0x604c958c81d5675e, 0xc74a8dfee8a238bb, 0x27a228160f096f2d, + 0x7f2fc94314b025f5, 0xeb37df86e0ee3381, 0x086621594fe10cab, 0x66d073c004aed1f2, + 0xd152adb9d6316f4e, 0xefff6a3dc0947650, 0x7ebf6d2128c569c6, 0x5c100a397e31b9b3, + 0x9e50ba0690685af8, 0x0817172fac5c35b0, 0x28fcf6d1f169b78f, 0x7fffe961aa66c2eb, + 0xc0aac6e163eaba45, 0xb84712730e8c77fb, 0x1bd790edd9d4bacc, 0x8a23160c5029a2b6, + 0xc1903cbfe44a4826, 0x81108fb4a609fe6e, 0x375581aae77803a9, 0xbd20609afcc63521, + 0xf97e45fe77987f01, 0xe7e87338da885596, 0xce2a6bdda1369a5e, 0x2183597d9e776ad6, + 0xfed5146f67e00647, 0x1cd3ae2f1c4b23c0, 0xf34eb0dc1fb281f0, 0x47d04d6729e480a4, + 0x2947a779df8d6c72, 0xf27c881da14c3811, 0xde1a3150e4dd9fa5, 0x11c90fc9f610a8a1, + 0x1af6efa06f77b91c, 0x6471a9a272ff2f9e, 0x5afc0a78eb9cce6b, 0x2a0646a9ebf7f6e0, + 0xba4c06ac6e11271e, 0x48218b1bbeec4da8, 0xe0e81070a20349b5, 0xac9ec3fc5d1f33a8, + 0x65886ecaebb85891, 0x38b41336d8f1a009, 0x1aa73c4f953613eb, 0xf4b1d0fa64db429b, + 0xf4b4e653b66ddd04, 0x1c8dd2613fd2d8ff, 0x994b1643b3e2a00c, 0x33854e09328b86a7, + 0x0259880aba215dfd, 0x18bc56fb25b0d6b3, 0x8faa28d7d21f5fff, 0x3bf79f1cb43b4177, + 0x73c225265109b906, 0x31f123ef829a728f, 0x076b6b083e10cc3d, 0x1480eb3c48f62a7c, + 0x34f2dc60a7a289e4, 0xee80358d422c59f8, 0x97b1fdcd8c8eb6d1, 0x678297701b2d1a2e, + 0xfee205f69433c230, 0x2a0e40e1cec20faa, 0x2908246baf2ff684, 0xc85013e1ae99b16b, + 0x73dd3bbd77a4ad77, 0x74b7e1cc8fdc7347, 0xf007b3c37c347ad7, 0x6f64f83d3206d13c, + 0xfb0cb16eef2d1540, 0x5bfeade7ae436926, 0x48eefb48e5e361fd, 0x50d3fc592eb163df, + 0x5c08dfc0b981ade2, 0xa2533b3a08f3ba24, 0x0cfec60ede8290e7, 0xf61b3426d3d5cb11, + 0xe1319f2f15334194, 0xf6d5797982406f2a, 0xd8a0e66549a831c9, 0x0347ea1599d5e455, + 0x4fd9e3920947b6c5, 0x14e44ea4a414cb23, 0x8aed5f43b296777c, 0xef0c03dc7f5b30fd, + 0x7056190689ee6260, 0xf7aacfee33c68a89, 0xd9a29a5a9a3cd216, 0x56568922104a2ec2, + 0xbfb6777c7bcbc789, 0xd3a61554d650d809, 0x9268359a9d9a7ad2, 0x693f0af0bf4d48d7, + 0xa5158b84e520af5a, 0x20b479788d588449, 0x8fb152ac308ce01f, 0x3726147316df7b6f, + 0xdeb3db1af1c75b25, 0xe8de6c73d03189ba, 0xc72de9ce66cca884, 0x2b852d4ae3edbea4, + 0xcaf9ce19a2911a0c, 0x6383b35e01424ff2, 0x1cad8056b68a21a0, 0xd1d18445d48c836c, + 0x7bb0e25f2ac58da7, 0xb1d7d1947e1ced3e, 0x23ed975c7c501fe4, 0x86faeab83ff5d558, + 0x1edd6a8f9cfafc63, 0xef254f7e01b7a1c3, 0xccba349eb30a0509, 0x486b72b0630bb2a7, + 0x422f104f834180b1, 0x4009b93eef760518, 0x81ddb055f428a7ba, 0xcb597e188f5247fb, + 0x2d936aa9e2f74762, 0xe2db4f29ced59401, 0x8788800ffd853c1d, 0x23c5a65c22709d0a, + 0x3d315ed09eb82838, 0x8fe9e5d743f5b40e, 0xf50aff377c1a1657, 0xa4c6c5817e8e30b7, + 0xdffbb3f20e998962, 0xbe0925a47a1a50b7, 0x0a040c2a3704ba24, 0x7bdc6939150a08cd, + 0xf4b3faded34ad6ef, 0xee3f831f905b6604, 0xb67448bea334574e, 0x7dd500a94f29ea47, + 0xf4b372026615c2d7, 0xc289c17384e3603d, 0x70bc80a6e80bc10c, 0xa73e8783c5a0b265, + 0x8501011cf55f741e, 0x892c477c84d26ace, 0x6e121f6229e4667d, 0x61f69ff87ee5a6bb, + 0xab35195078a8de2e, 0x3b46513598fb6df4, 0x2069ce150ad40238, 0x00db239126eb17f6, + 0x06c1ea30d13e1880, 0x2babbf0c0fa6ab4a, 0xe0940fe57336d1cf, 0x6e55abfe899f5a61, + 0xfada8d72ff8197b8, 0x53a54de87cc1599e, 0xf6ef14d9d39b00a3, 0x626cbdaf89cc33c0, + 0xa5fa6e036d7175ad, 0x1bc1858ae5fd6ab4, 0x0227d66f30e4fe8a, 0xe19a194974f70408, + 0xdf433f09afb06f6f, 0x2d6b76386fe81650, 0x3f80496e98ccc40c, 0x32ec4687f9213635, + 0xc33bd5ad8c640251, 0x0eb94c6219eebb02, 0x80f85dcf3dc8a139, 0x922f713aa1d13ea6, + 0x5652c6d5f5f138bb, 0x5533eb06a48fb1c2, 0xa6aa8b2c61115c44, 0x46846298b64eb75a, + 0x5f96b764d7920da9, 0x9cbab8afddd84545, 0x66e72d04aeed6a35, 0x734739602896d038, + 0x104a37cfbfbc58c5, 0x8a1e96286f1691d3, 0x2f7fbe15e4a37f25, 0x148f0de3b08ee080, + 0x4c6de4a2f323e06b, 0xf662e191925a00a6, 0x8c6a93240b4305df, 0x65dff271da8dbe2d, + 0xd4992dd6c574ad76, 0xfb925de7641df566, 0x91d8357176f544fa, 0x4396c1e8c25e43f4, + 0x85f05c8ca4be65ed, 0x1add1c386b776660, 0xc8d8caafd06a993a, 0x3f1d3e15a77c8e00, + 0x14cd10410e9227ba, 0x18956d85fd369ac0, 0xc9fbcb52cee29a5c, 0xafdb40a075270c9f, + 0xe0f637552547e10f, 0x87631c67f08c710f, 0x43cf47409eb5fde5, 0x79cfcd50fa494035, + 0x1dd6db07aa64893a, 0x9eda42304c1ffa7b, 0x3d077ae0f8539e4f, 0xdd1e2075d147dec0, + 0x5e700cea6645dc86, 0x7e71af1eb6e0f5c1, 0x7e1d68721bf5d07b, 0xd29914c67bc31e80, + 0xcdcf94c2f9785d80, 0x3f8c772226087efd, 0x791564b535bd9d7a, 0xb5db0df96b9406af, + 0xa5730fa1b5140b8b, 0x7947229a2ea366ae, 0xd743462c0c42979c, 0x6145b0f9410f9934, + 0xae0981e9c512e1c9, 0x4332419f1c083508, 0x7df9937e124e3ac3, 0x7cdef42df9d95a05, + 0x179e16d09d3a63c6, 0x94d1af2aa68bfe20, 0x5ee19c3900d28727, 0x9cca6e1446d20dd1, + 0x732b6069159c8928, 0x4493c711829c380d, 0x4259108c1506bd07, 0x9d09b96634448b4e, + 0xe75bcea40a0c7348, 0x5c238d2f1ed998e0, 0x4aa894a36202b878, 0x8622d098fe74e6de, + 0xb52f25bf5efab5a2, 0x86a6667676243fcf, 0xecd6f632a9d32b44, 0x907f3be53ab4e8dd, + 0x5dd2d10fe40b7b29, 0x9c2de720e15e1d98, 0x1e07320ab9c63ed7, 0xb6db65cf4825f287, + 0xf6b42e6fe65e9d8c, 0x83f8285fa787ddf7, 0x55d98dee36fbedbf, 0xea51cfd937d4a0a8, + 0x97018c762ed80f76, 0xa0d4e078050c5bf1, 0xfce8ae2c509b5a77, 0x9d2a417e265f2aa8, + 0x1aa973487d323174, 0x47e26ded1e39aaf2, 0xc69954da7af0a139, 0xfcfa529f7f2ef3e0, + 0xd1b0ff1caa3af1d1, 0xdb18c11b891ef5bc, 0x4c975e10e7042356, 0xaf1ff6626b2ff96c, + 0x3110a17a2890ebbc, 0x24511e1ddd26ba31, 0xa29a47a88c278905, 0x7cd3b6884a0d57cc, + 0x84a2a2b5f4f08e19, 0x9bd9410a923669d2, 0x6d7f897ce23b93c8, 0x306467677df3563d, + 0xac8065cfe1af1f5f, 0x38dc36578ac69965, 0xd14dbc2f9cf4d0eb, 0x334c4bc69f958ee5, + 0x605430f1be7d9968, 0x47e8e4a0c3ddd375, 0xceab5e929f0c56f0, 0x2b6d821a04a00bae, + 0xfcdd09e7a3b995c6, 0xe0a5c2b03a57833a, 0x442bc7bb3c61cbbc, 0x8e90a880bbe8fade, + 0xe5e6327702fe0fe1, 0x7a41edc3f4b33923, 0xd6ca1c9e2b0d65d4, 0x919368abc0692833, + 0xe73d6c00b9b5cdaa, 0x5db2a35e6a21b6cc, 0xc14d14b1db1238d4, 0xe1f654bda75eaaad, + 0xe0513db4ec9de2cd, 0x5c87ffd03d270994, 0x9829f0150028cd06, 0xc091edc5ca579832, + 0xf1a8ddcb1c1443c4, 0xb9c6123929f8b96d, 0x6fa16bbf4e6df1d8, 0x8cbb904f6411de06, + 0x9ef60a154811f124, 0x3b94949e80dd5629, 0x48cdae9380489f99, 0xfd5e41b3de3a37fe, + 0xa6d507da8636bffc, 0xb7315d27f9014c0e, 0x9c3ada89880bfcd0, 0x9aa60e3f9c5dc914, + 0x8a7dde8d431afaf1, 0xe0b75f4063b1cc87, 0x869822d38abe70d4, 0x2ee10ef7b293698b, + 0x16067980c0e5669e, 0x42b1f1eb003aa6e1, 0x0b7d73154a0909f4, 0xd34ed6a5f3aa47bf, + 0x3165da0cac593a5c, 0xdf7f280b6ede5fd9, 0x7740916fc0786f7a, 0x033e14d8a5293331, + 0x2f1b96c640ca8462, 0x224ff0cf2deaab18, 0x35b00469e70b37ec, 0x5973d0f91638575b, + 0x1327897a1a7629a8, 0x95855cc1a2b025cd, 0x6b326f11d0f48a17, 0x0e324561272126a6, + 0x0784c01fa6bd5cf1, 0xa3ec62a70128a0cb, 0xc69cda8a5d200aa1, 0x60b7249e70d9065a, + 0x83f07c23cec63ead, 0x4844058f53cc9dc5, 0xbb017718d0224953, 0x52bd8386fd76af7d, + 0xcf35d88d5b3f6952, 0x6809517e7624dea7, 0x8b4b452d03bd25d3, 0x0b05e9591f5ce862, + 0xd76242c79b254fd3, 0x5c6d8928fe27efe0, 0x6c0914f89300e5c8, 0x984af1ebf0022093, + 0x049308388973db9d, 0xc32aa685764a30d0, 0xec6168ae7da684e1, 0x4f43ef4824207f44, + 0xa8432aeee90bf88d, 0x7d2a87252a3c77c8, 0x42bcd0c04fdfd7a5, 0x561952626fde64c1, + 0x8caeeb9f1a7fd79c, 0xf5d2670c4416c5ca, 0x3afe6a17b29f420b, 0xb6f67508b20a8358, + 0x2ea099b4c78fa5f0, 0xcc8b299bcfae3105, 0xcf2d46285f47b4f8, 0x602da559c703deba, + 0xcfef2d0c7dfa1d93, 0xcbec20f8c0f93c01, 0x38eb2dbb318647aa, 0xf5b27326a99df90c, + 0x84400c8b0c53db55, 0x029b85555747cd43, 0x10dc4a0ae9ad3f98, 0xbc96c4c9029f9c9d, + 0x7eea105f81a59439, 0x1ffed4f53bc67fdc, 0xff97d47d04e2e3df, 0xf550949cc5466ed2, + 0x37937d6b36f40cbc, 0x5008a2fff2eeb1cd, 0xf0f89c6a312e5af3, 0xc28d4cd84197f9b1, + 0x98c2abe8976c5a98, 0xf04d7fc86613db76, 0x7f94e9853d777fb1, 0x974bcd3ce97cb7ba, + 0x65d218088eb18ba7, 0x2c58fcbe253e57d6, 0x6ef388b0b976a679, 0x398c98487a2d14c8, + 0x741d365a08cf079a, 0xa64c2412f67fd93a, 0x368fec5512858ab7, 0x8ff779d1c5cef2ed, + 0x662c7873a309dd08, 0xcdb7f33175da152a, 0x49f61e5750179618, 0x9ff5a59e8cfed1ff, + 0xb401a3cb2834cbc7, 0xc8d6d84ecd245244, 0xfb0a423ca54a1ddd, 0x610c0547d464cc17, + 0xe13969d12ce2783f, 0xbbb92c6010b8608d, 0x07922b75cfa9fc26, 0xba8907fc1ae5b9f1, + 0xe155f8b12016b72e, 0x58f87df47ab7104f, 0x75112663d571ebc6, 0xa62bf3f43694c233, + 0x5b162c07782a2c35, 0x0c76c9d6ef3b3db5, 0x10033feace7a97d6, 0x8b6132c705de40a9, + 0x2830b5d1fe249114, 0xc0994db49808f8e4, 0x97ae08cba87b4bc8, 0xc209b4affd71ad62, + 0xb5330119a5765665, 0x93e0a18d8a445291, 0xffb54a38e8291b47, 0x4679e81a466c9bd6, + 0x50a9f41b54a5c5ac, 0x41ce9e2b5117fe7c, 0xbdca22887075d968, 0x7ce3f32fef105f84, + 0x0af59a4dd2a8b6b2, 0x89e2e2bbddda54ac, 0x6fc9ee94d7a6c3e2, 0xe33eb7897c0a189a, + 0xcadd0fceea828ad8, 0xe43aa64c96d6e5cf, 0xaf0c4f1a97615e5b, 0x6df6725084ca1b4d, + 0xab1037dea2fd685f, 0xb146e3aad0496947, 0x70fcbde893aa18cc, 0xdac77166aed6ffcc, + 0xf0d5c6238541f499, 0xdffacf8822a5fece, 0xb5a781a6d3a26087, 0x91e6ab8e182a5664, + 0x65ef06c6e7f58085, 0x758fee4e0037bb24, 0x36c2bb9766b44c4b, 0xfe730b24751e615c, + 0x3a189f2e0a20e417, 0xf67534aff003d7ef, 0xd2248e5a22ff8919, 0x98407f69f63a3587, + 0xab1bdc58ffeaf7b5, 0x08ffcb2837cb833a, 0xa420fd3276ba862e, 0x22547eb44856968e, + 0x83e647ca3d07f368, 0xba6a74b7c4703536, 0xf1bce45e5a796531, 0x4a1ae853df5293e0, + 0xef56854ebedd9602, 0x07b370530c44712b, 0xadf11e023b570738, 0x5b5b8fe8ac45a1d3, + 0xb4ed5b8078a92dea, 0x06c2925bdd492390, 0xda3a0fab8c679adc, 0x6e642df50d13c22f, + 0x69610fcc7f18b1c2, 0x9f53b5f09112f5c2, 0xff70c82ca3e6563a, 0xfecf70c22c17b9dd, + 0x32283eb731206df3, 0x83e48cc878fb47d6, 0x93f9471ccc00eaa1, 0xa4f11979a515f28b, + 0x99a210e39f1baef6, 0x20b417776954512e, 0xa2f95ff6e3949c36, 0x2555c37bb36739bb, + 0x627cc9a5ac81e071, 0x74b86293f7539cfc, 0x7a709be31ce42aa5, 0x4179339c7fad27bd, + 0xa20b8ab12e02425c, 0x42278d2095602980, 0xee63838797a88b40, 0xf9e7b547bf182227, + 0x1c8673b369e8fa80, 0xc33c3256e0c5b0ad, 0x27b1445325e3519f, 0x2d67baf42e451b97, + 0xee03fb130490ec9f, 0x6c300943fca8c65b, 0x72ec73a072dcfc2e, 0x55494394b19ef5e9, + 0xab50e40e21a18122, 0x2119d92f745695a6, 0xd52ff433a5f4e652, 0x4bfea2183e187083, + 0xd5c7afdaf8562648, 0x8b70d174bf9b773c, 0x28519071bd6656ed, 0x43cdf73aabd59a2b, + 0x72119d2ae41cd844, 0x1c23751987ce00f2, 0xffe678f781a9f177, 0x7c0c7af12ed44f20, + 0x8c40c59f2ffc7ae3, 0x5335377913cae3d1, 0x7c42046196f07d48, 0x8db5301e396f4d92, + 0x1ec19ecb003e9460, 0x3a735f22284bf7b2, 0xee8a00452d265f92, 0x513c039175b7f5fb, + 0x17593c3b344554b0, 0x960ac95981c8a1cb, 0xa3fb500f09539d91, 0x2045335476ac5355, + 0xef75f7ac46f1c7e3, 0xdaab1a3469df57f9, 0xccd1e8876d4d914c, 0x3b2933144ac69575, + 0xe5c61d4ee366a51e, 0xab109899ab009683, 0xdd52b1af0300cc0f, 0x3b50d2206dc872a3, + 0xc81a12ae49871df4, 0x4c161cbb9bd52085, 0x33560b58d344d076, 0xcf69534a4ef85b3d, + 0x35206edbefceb527, 0x35ae3c2b23d7d88e, 0xc3d3a23fc8052a33, 0x3c7a4dc3deef96c9, + 0x1c6c26bd2bc2d26d, 0x79fd0a779ed5c0f2, 0x7139d1e7a0fb73ab, 0x95f400a53d2331ea, + 0x3bc0ec8e4b15f06a, 0xaa0850b77573a978, 0xe0ea4d29dfd39b24, 0x1433f346b4205063, + 0x35adb5ad8e055f1f, 0x7d99dd2fd6aa2ff5, 0x183655954736f1b9, 0x6776a81dd8615674, + 0xf56b93e86881c956, 0xa92cf2a6ec8453c9, 0xaeee9d304ac6cab4, 0x7085debc963b6e0d, + 0x9c29adf11395b548, 0x83e40fab023f1263, 0x51169db811013980, 0x67306742f93ad248, + 0xecfff543c6febd74, 0x7c7a366c221005d8, 0x6df75277ae8ddd19, 0x4b14f84c5953da7c, + 0x3c4c744353fe050f, 0xe5f0c54b4816317b, 0x046f5e0b13547d7d, 0x71e5f645009bcf62, + 0xc974991b5cf66e95, 0xb35f04a695694b2a, 0x5a5804eb646d9bbe, 0xe9164997638f4088, + 0x44b020c7c8253352, 0x279b9540f2fb60a7, 0xe5d34b0ad3ddd390, 0xa1903c6fecd5fec9, + 0xeda4f189fc2052f8, 0x19018f3ef771c637, 0x17d9978651671ea6, 0x2ec1badb62c1351d, + 0x5bbb0af8ea63d098, 0x3d37389970d9f381, 0xd920ff7363e39b11, 0xb8e1c51ccdc130c3, + 0x0be866461502c7af, 0xcb1451454f052a70, 0x303dac3f38d4f6cf, 0xf41fc007b2387bc4, + 0xc3883c5f1950eeb6, 0xf2a45e8d88d0aa9a, 0x8a17c49508364a54, 0xcafd3ef0510cb140, + 0xfc03351bf69c94b3, 0xfaa1459a7d127784, 0x95a1ae8f2de269bc, 0x6553cd60c2b04be7, + 0x586d00b187243079, 0x4cfaecfc974424c4, 0x8235a40bf3b4de51, 0xe7229efc1cd0827a, + 0xff2737e40e5a2735, 0x061bef99e5ee36b4, 0x881d9e4dde0d8da7, 0xa7849dbe1551ad19, + 0xc429a96c720e3821, 0x8aaf44c1b0dad3ee, 0x69cb149c2bedd342, 0x66f6a588db2adb9e, + 0xd3dad551e343033e, 0x17d8483e10abe300, 0xb392844983bcd31f, 0xf143d37f5b467187, + 0x794a915a05dd8a6c, 0x0d2da82d2efe48d1, 0x7a36595daa72c78e, 0x70323a0b290c9bc4, + 0xe8b53f89a31adaf2, 0x98fcd57d1d800a09, 0xcfb0322d8567ed37, 0xd77df207093b5097, + 0x4e0987e3687348fc, 0x4c3362de480e121a, 0x0b5f44a2f9bb95b9, 0x8a3a5f7a847e8bcc, + 0xb77525cb3129ba09, 0x1fe4bc8eb613f0e6, 0xcab70d559896e460, 0x34487901e49db96c, + 0x85008ca36752e7b1, 0xfc0ff71b1c78f238, 0x209a32088937e0c5, 0xef913256abda6559, + 0x45bd38a91b07d9fb, 0xf6b05c7346da3e92, 0x19ca569411650ae0, 0xd662e1acb3ba4cbd, + 0xcf3fdfd2e80cd675, 0xabf7cdff6a44063c, 0x37c5916dc264867d, 0x73e3f6949653ea50, + 0xf5488e7815bdff45, 0xf6499a2038c4b88b, 0x8faece05e43b010f, 0xac4b08dfc61644c5, + 0xf21278dadfd45bce, 0x31f5a73c05de6510, 0x3eae03f858ad8ca3, 0xb284730fe003fe98, + 0x1a2da6b830caa083, 0x26ef5b44f6915f78, 0x71f9afef1928ed59, 0xe5926678d02f0700, + 0x313ea3af07e19d31, 0x686e49294c645c83, 0xec34054a45ed9d8e, 0xc2faf8c2e99c3487, + 0xc0dbf0732a2d6b17, 0x312bb2d05d527302, 0x62b7031cea68def9, 0x93204d182e62cb46, + 0x09a88264ecec3cb1, 0x5ea34d5c887b30a8, 0xc1c74e1405e20e7a, 0xbbcbcf82b131ec0c, + 0x7cc4e7f6b83a2207, 0x1f80e6ff0ab1742a, 0xb02ae4660e619b7c, 0xa3d29f04b9112516, + 0x0d404db8f948ea52, 0xe1cc7dfec64d90ff, 0xf912e586eed8ed47, 0x7cf3f1ad0dfdc464, + 0xddcf6663f7011938, 0x1ff8b05251352459, 0x363af9cdfe67678a, 0xcd99ec9801e0411e, + 0xb424f800014e1e4b, 0x4f089ca0fa9faa1f, 0x10c9aca6b2de4e2f, 0x2a67baa55deae676, + 0x1b024dc2546f530b, 0x8d1ab50bf8d796db, 0xe0a2e1059a7f55f6, 0x6413b34e43239782, + 0x4a6bb5110cb6ca86, 0x59f7ec41ea761275, 0x8de0470a24ec7743, 0x9816ec7a9da0cab5, + 0xab9d87720042c080, 0xfd7857f64d9be0b1, 0xee1320f4b293b05c, 0xa2cb0290aff6bc28, + 0x451588bf14950dae, 0x060726bdfb707c2e, 0xacd73a3d82b246e5, 0x7724278a2073f59e, + 0xd4dbf9cfa8dedbad, 0xa317751d0f8667e6, 0xb94217565c0d8cdc, 0xf5136ad8aad1d6a8, + 0x193ce8b42ce6abaa, 0xbd0dcff1991860f4, 0x78d6a189b702b330, 0xb60e8e3a1e332056, + 0x76109c00e6ef6bfd, 0x386f1dd6eeb35ae7, 0x4f6d48b857117f9e, 0xaf315dfcbdbe10b3, + 0xe21f313c65ec1dd5, 0xfa1bb2c06e6934fe, 0xe38ccc8b7dafef87, 0x30b7c4639e9788aa, + 0xeaa495430e860a9a, 0xa48274bf62a1fb6b, 0x36107fad7d86a96e, 0xa6ade127cf4d038a, + 0xd17e3c2ee6ce15cc, 0x4a3722753efdecb7, 0x3630ce08257a9e9e, 0x15a3bb7c62f6ab68, + 0xc3de60931e83fe9e, 0x17d46bbb0ae54913, 0x2051e4773d0725e1, 0x0df39bf1531d9f84, + 0x583d2802634372ab, 0x1f17a415046b94ab, 0x95c33b2d0b871c63, 0x71afac4a1a534621, + 0xa29d49d4a7b95984, 0xeddf0ff1be1de240, 0x09a39d9a4b27ed3d, 0xe6293cd1900a56f9, + 0x27c01d045d3f5a77, 0x66b43f0151889dbe, 0x3e1c61689f950619, 0x92f4b074e27c783f, + 0xea27939121580a2d, 0x8534146fc6625186, 0x403506977b759fb6, 0x9ad768dac735c111, + 0x80f8fe3f3e24e608, 0x82b7351107a57fa5, 0x45409305fcd56b80, 0x3db307370da492e0, + 0xf6808465e018f83a, 0x02e824e37887fe00, 0x29a7f802e285c430, 0x09ffa35c45438f9b, + 0x5209b8423193ad59, 0x643484538c72c576, 0x5313feb27743332d, 0xfa3618dc415769aa, + 0xe1af4add99475938, 0x0ce72b028aca74ed, 0xd7a01986607991f5, 0x8c07f6b7b0836b93, + 0xf1c11dcb9367a128, 0x542e031497465725, 0x1828e7d6c479b14c, 0xca72204cb1a50eda, + 0xeef0670e42800eb2, 0xe7348b42db5955da, 0xe7f6c3a2a92f4e69, 0x84a845cafcb9ec27, + 0xa7eb2d43fc2202d6, 0xaa3f507dc067040c, 0x60b78246b0dbfdbf, 0xaa72e2a520cb49e2, + 0x25135fc22f9d5f5c, 0x2245469fb8411fea, 0xb987de4b931776ff, 0x45ae38a753dd049e, + 0x3b95b0142a76964f, 0xd41d9faa037771d2, 0x7386ebdaf7381652, 0x27676f6106c8d4eb, + 0x78a0d107245604a4, 0x287ff513daaa017c, 0x3d606c135fc984ac, 0x4554b122fa930f9a, + 0x04fda6b0dca62578, 0x6267419fe1b4c69d, 0x93ff60895b281dc4, 0x3f64ede669a66bdc, + 0x83de63aa4aea2819, 0x974b40177f54a639, 0xf4b912ddce00fc66, 0x1ea0339b722e120a, + 0xb2608e9fcba3b1f2, 0x4393cd9ae5bd4a3e, 0xc26e71e42396354c, 0x6bee4735f2af252c, + 0xd14021fa8a788aef, 0x4a8471a43763306d, 0xbeb09e424bfc6f43, 0x27694eb006178793, + 0x3535698169914310, 0x71b6a206914caf27, 0x5d497991cfe55794, 0x4de3dedc1ade58ea, + 0x824c95cbb22e4f0d, 0x0836aac46cc59428, 0x47c5b71bee0dff27, 0x11eb25f13ac83377, + 0x680dc24780802d21, 0x0fcde91d3fd1a0e1, 0x58e17c40eef3cc58, 0x9e5355288ad139ef, + 0x929185c99818f04e, 0xa6e8646ffd3c9efb, 0xdfc0117bc22891c2, 0x04dc7727532b3dd0, + 0x49a1b7b674ac273c, 0x912555f09b9628fb, 0x4f1a9bf7c26e056e, 0x609fb6c2406eeaad, + 0x77e3766b2d2b1bca, 0x8000002d215744ba, 0xcf76dabf6309fd2e, 0x0fa8eb1f62f285ca, + 0xa924d0b0f7475f7e, 0xffb5091bde082684, 0x9202d6e0e0de09cd, 0xc86477d5e9adbd0f, + 0x59a1073747adb6ca, 0x64edc3e7cf58f325, 0xf620ee3d4a357d96, 0x35fd4b69ac4d2fd3, + 0xcad2eaae87315c23, 0x598c31c9a882641c, 0xdbb0b78a3a58ccd3, 0xb50937eac1c9f811, + 0x7132b0bb847f28e4, 0xbb3e344b8c46b750, 0x6a7fef241462754a, 0x026922f6ef9b188a, + 0x6cdfa708ebe6cc06, 0x901fbcd30eb060c8, 0x31a680804129ab54, 0x054fa6e9a521e2cc, + 0x027956170232225b, 0x4f41e5ea9eb932d4, 0x5effe2eef3b7437d, 0x5ea89230fb1f2614, + 0x1f472ba91645f9a9, 0xf395c32c6e3b40b5, 0xfac7c83e6ded30d2, 0x949a55b2a068f65e, + 0x2d8a82000b870af5, 0xaa48e65fdce4863b, 0xddcfe03e3cbd8d3d, 0x612f8b57330599fd, + 0x382cec36c813716e, 0x95055265347241a6, 0x00cd6a8a3358fd07, 0x312ee103e457d733, + 0xb7806fc255e3b975, 0x1b197d06977ec858, 0xebc385df52ebadbd, 0x98c8ec7db11e8eae, + 0x0f9194f33d2f7e54, 0xdf1809aef30d8c07, 0x66802e00ce2c0a77, 0x06a1ef55cf005f04, + 0x3d1eae65dbad4776, 0x9f7a666085bd9295, 0xd31cf67644f81cee, 0x26545440ef0c49d2, + 0x4a7dad778efc1c57, 0x2ae7dd1da3b75e00, 0x161e72bde5e25237, 0xa192f07c516f7eee, + 0x4ddd5609ab38abfc, 0xb49c79d2545673b7, 0x7a5996778212a61c, 0x76eccb4754ac2129, + 0x130ec27bda09bc7a, 0x95101557dee990bf, 0xb3ccdf1aec16f4f8, 0x1f30968d61ac74d8, + 0xce841ad002d6d401, 0x48adad5547489e0d, 0x0fa3e57f72882d99, 0x169f8ab842f26e25, + 0x3f5dab03dbdf25d9, 0xc9283a91ffd4093b, 0xc852704c60158c53, 0x4f1536e8b411c00b, + 0x3d5c5d8bff70352c, 0x4ee2b4a8360a368e, 0xe246a46f86c725eb, 0xfc9469c042ed98d6, + 0x102ab194a220d885, 0x07e90b6446d55a85, 0x2f9992df72d86bf5, 0x396d983c8061f255, + 0xf58d232f68506826, 0x221bd594af273d6d, 0x1811dcaabb79edfd, 0x461a995a04ef8f69, + 0xeb4a74e68dc2e389, 0x5eec3898736ad0ac, 0x4baf35e9972fe792, 0x4dcaae7730651c1d, + 0xb326e776f9604af1, 0xa75afb93f4c9985a, 0x71e11f0aa915b864, 0x07b7873df32cdafa, + 0xef66a0d973ffe5aa, 0x75827192e2620ffb, 0x1e42f2ee73345ea7, 0x9d70213507050491, + 0x2763fff868879f8f, 0x2b708af607c7a3d9, 0x4c8d0c799bde769f, 0x6c8ce8159d0e4f98, + 0x78f8a0d4aedc0313, 0xe6d5524c3f7b0b98, 0x55823a0a905c0d14, 0xf08398fde98190e2, + 0xabc8b56d5eeba4a6, 0xa138fab7c379c3b9, 0xeb788d4172cc145f, 0x3de93dadc6fa12db, + 0xfe490b1ec223485b, 0x6b8b9e4f295fb4c3, 0x976a91f9d764100b, 0x7ccd1dacbfa2f73b, + 0xc493c69380912c95, 0x32e0ac02ef19c39e, 0x1574d945e719219b, 0xd4f1b2892e667795, + 0x12dc8a60d36eb807, 0x5e29d229ad21144f, 0x49208551fcc9ab79, 0x47f122150dd39eec, + 0x22eaa3a2c25170b0, 0x094a4331fb1ee0de, 0x927bb4141d9a5190, 0x5a0d27f208b26298, + 0xea228584361e0a58, 0xd2551b0871780c42, 0xdb1a77245557f532, 0xfa32bac560e67488, + 0x6d99f50a588126f3, 0x7049953f7774a409, 0xd488b2e305eab72c, 0xc204d13b25289f18, + 0x193642c2b386d742, 0xfe2cf4780d5c9295, 0x4a540fa21794e85b, 0xb888434486bedacf, + 0x4db9df92a1974851, 0xb70a374fc2091b24, 0x0b339585a556d452, 0x243fd66313cffb94, + 0xf8ead7e804b0868c, 0x8525956e07a2a426, 0x3ce2d2ef7e8eaede, 0xa52e655586b0ce63, + 0x4a176b21cb855356, 0xfb7ec6621f6740d9, 0xb44537b4f0a43862, 0xfce2c0dfdc2b2605, + 0x551d2297828d007c, 0xf1b04f778cbbba79, 0x026b331bb21bbf56, 0xbaf1f314d1c085af, + 0xbbe0d8872c98a2a4, 0x0b4a3abe8ee63041, 0x18fb743e82ac9bc8, 0xfe186e5df8b073eb, + 0x8ce360995b2a4fce, 0x289c7e5b24a7303f, 0x16bc5e15aa0690a8, 0x968445b5572e3857, + 0xe102d2c7d9f93821, 0xe9360f3d3f5a0f6c, 0xf1c3f26261d348f0, 0xc74ec5d834d335f5, + 0x317ffabe55476d35, 0x3a2aeab6959d4356, 0xdf70dd232a3161f3, 0x46514f7cf6e70152, + 0x1f6ab0283e56477d, 0x1fb8474a056d4584, 0x0fe8b9c832f04c7f, 0x8b597f975ebaa629, + 0x1b93323286895a10, 0xf557ea111e0ad909, 0x974c10fe6dd4c832, 0x014309683aae9632, + 0xc80cc1116b3b1487, 0xa6670f3f80c47dc1, 0xd033ce374d295dcd, 0x365e0300dac3ea8b, + 0x34b1de0b52439586, 0x485980cad9d34276, 0x2732abfd8510fd1f, 0xde8214565686af7e, + 0xaec5254050da3419, 0xe576d161025ed285, 0x9ed77a97867ef425, 0xa3331a4d138e349a, + 0xa2164fc42a09a077, 0x9799f310785d7226, 0x1ff548c2cb69531e, 0x8ee874fbc900ac69, + 0x379310e716f1b967, 0xc8464f3824a188b0, 0x3d74e1587a60428d, 0x425e164b169eccc7, + 0x0d4a4cf40466f244, 0xda5f77ae7f8fdab2, 0x62ec1ccfb9456f69, 0x08cb034b58e273fe, + 0xa81d361463fdf695, 0x079ace3cb10186bc, 0x8c3a19449fb311ce, 0x1a5664f6a2b51a23, + 0x190d4f5bdd472f1d, 0xfa85e03b4f0987cd, 0x4f4315eca842a185, 0xcd8d278445c50ecd, + 0x540462c7ae085a9a, 0x3d56f2f15e8bdd31, 0x9b5be4ba8b1c6382, 0x8e519be4a5ca0772, + 0x58d01433e10bfa9b, 0x0ff463b413a90158, 0x184819f35bbbb1db, 0x5f2b6ab967252de2, + 0x304f86d09d146610, 0x7d1bcb68291b8b3f, 0xb03d28df19da97f9, 0xd94682837fa6fe08, + 0x7696f34b0affe0ec, 0xcbc827e777a3aa81, 0x4f14dfbfac51d5be, 0x1e1326ef581b86f7, + 0xc43c52c16ee3d8d2, 0x279e60852489c309, 0xba5f69d8a99e00b8, 0xbc88e5b3744f8170, + 0xefcf7198c4fae2da, 0x5f09923891a903c6, 0x1c0bb1e1a7684e30, 0xb2f1dd50aa1633c8, + 0xaebece010b5d1131, 0x9e36520d425de096, 0x1de867f14a02a37c, 0x37c49b2d6d5a74bd, + 0x708e41c6041b63bf, 0x2af420f11b22c51c, 0x81f73cdfd3b0552d, 0x58c1395062a1612f, + 0xc40d6153abe1e8dd, 0x88971ceffa5d69ef, 0xf15b6fcc4dec59ef, 0xc86077d72d737b20, + 0xa86b9a30456d5eec, 0x4b8a3e9b42759736, 0x267442d8cc0a7e12, 0xdf4b08371a2ff2a5, + 0xea5a4f2db2a5ab71, 0x4ac640289b9c41a8, 0xd12ea2797153436a, 0x7ba239299abb0c46, + 0x662ce9f937a5c531, 0xbea053e1bb4f5d89, 0xfccc54658c15e02c, 0x420281ff3ec48dd3, + 0xc0f84ad0e973d1a3, 0x74829145a83f48c4, 0x65bd98829c57d3ad, 0xb8027108d7a2fc46, + 0xf4251b738dc47076, 0x2bb283b058eb8a96, 0x5a45d4a37d3d8b7c, 0x8efced6bf027dbdd, + 0x834c3b4c30477970, 0x4d44a429218c9bf8, 0xb0b912b54858e90a, 0x918c86eedc1540c8, + 0x44a79ea3469a323b, 0x5b5d87181df68c16, 0x64fa87ff4904fe78, 0x1790dcd6323b7f19, + 0x82acea9fd5936e11, 0xa6350c5c22664490, 0x3200c84ab9ae3086, 0x8e6c00397e564a9c, + 0x49eddb52aab2f42d, 0xbd495a6f7e84e917, 0xf2f42e00d84a7b82, 0xbfb4c8a1f6d72edd, + 0x50b70f3bf6f193f2, 0xfee06187928bd065, 0x6387e91a00521895, 0x47838bb2607d04dd, + 0x569c187e0658abec, 0xf7b85717e7e6c044, 0xec511d0b8a6db8bf, 0x8039a9bd7502013e, + 0xc7dab95256bc8965, 0xf7f70c5f8d8f1cf1, 0xbb4391faaf02b310, 0x0f840145e9d03f53, + 0x298c350ae294cbc4, 0x6699b62564a80a5d, 0x64e3936e10012fd8, 0x5ece6ea819842f11, + 0x17eb6f99db4e1f0a, 0xabe5916c4e98d287, 0x9ea543543d93e7eb, 0xaead23151d48beab, + 0x06660b3ef9408972, 0xd001fd3f42d254c7, 0x8f00958d80ad8041, 0xde48bc56b1ba0b87, + 0xb4f4367f255cc613, 0xae6b58528daf72d9, 0x129df342d762cd22, 0x4572efcf53433140, + 0xa5b94dbd30fd87c3, 0x62f7fa9ae15abc5d, 0xf1065594dd10c968, 0x0cc02f562919d362, + 0x99bcd97ff2591eee, 0xf4cbd1a3060c07f5, 0xdfce2d01398bd310, 0x97dff7e52c7ddd2e, + 0x2630972534141c7b, 0x88de3c795ac50d3d, 0xf64fbcdb13ef6af2, 0x04fcc2cc0347055a, + 0x73eb0736c5be3746, 0x63190725286553d4, 0x47165e264c03e815, 0x6275e64d6b9567eb, + 0x7c82b83e1aff620e, 0xe5684f63ac5ada94, 0xe2c7ef71feb0df29, 0xe78635f2588ebfa4, + 0x652711d5260bd147, 0x2056b2917aa07836, 0x8c13d3ddce7e31e2, 0x2d7119788a56cde6, + 0x2dd4a43ec1bb6f2f, 0xbc25517fdea5b63a, 0xec7e7144c8795e85, 0xbf95810e90f3753b, + 0x61cf15a19480b91d, 0x6896fc47232c876a, 0x0268323998c69d19, 0xc0f2f17e9ad88206, + 0xbafd903f5458d81d, 0xceddc2979f5dea0d, 0x6dd8a44622973d49, 0xe890cce8bb1f2677, + 0x3fd64fab693c3f61, 0x12c06efd29140492, 0x1f9a0755e07c9e54, 0xe72f78c5f768b18c, + 0x4572469950053ce4, 0xe880b142d80684ae, 0x5388c3ff81da3616, 0x6be6ce601cd1465e, + 0x986f36d9e5fc6814, 0x938d2a9ad959a1b0, 0xa0b6218fa77f352b, 0x7a35ebcdf2630023, + 0x70541e2d66c4d508, 0xfbc9864782a96a65, 0x9adb28ffad168265, 0xf8b920ad8899be4e, + 0x45232bd10610c0ad, 0x65fa338ad5be7bab, 0x35b86cb434fb648b, 0x7478ec88bab2c708, + 0x505e0ed619b6fae5, 0x84ad76c5a761f202, 0x07c362748d11402f, 0xf31e8eac8aee9fd1, + 0x816f2699f15af7ad, 0x07611aaec129bcda, 0x6f604d45b3f16111, 0x7937ffd72328e7d3, + 0x6b0a696ed8dfb2f9, 0x142f4a57df64809b, 0x1c53d7392859733d, 0x6560f0597f7c311c, + 0xd7d9902ef496f60c, 0x02678bcd95a9ff7b, 0xbf63a7986979c18c, 0xeb9918d52813600d, + 0x4cf89b27fdd74535, 0x7bbad9c4038123c3, 0x376200a95c720b12, 0x5173ef1dc916c246, + 0x732db4fdab8c3f31, 0xd431132eaf7da249, 0x21b605bddeebf7aa, 0x62182bbb26089ff8, + 0xf3c12805db628002, 0x8a720fcad8bc1cc0, 0xf2c08e8fad7d8bf2, 0x1b04b6e38cc81cba, + 0x3ed6ce6369067dc6, 0x8880b6ae8810cd1a, 0x8a4ea967c11974ab, 0xcc15eb397ecf22ec, + 0xa5138e0b64ce548a, 0xd248ee7e2552cd90, 0x1ad7bf2f341df1b9, 0xc1710874b23bd5bf, + 0x62e1b4623a9a9c8e, 0xa61f9c08c6f32532, 0x77c79c8716b73519, 0xc99356df93e74bc3, + 0x3d39786fa0c504fd, 0x9a3a758dca40847b, 0xa8d8c3b3acb965c2, 0x8d5b6d8d9fa512a6, + 0x690763471434500f, 0x4fa4d04274a087cd, 0x44f18c850f2312c5, 0xf977796dc27c69d7, + 0x05b6d37ddb002638, 0x6a2ff2c394ea32ab, 0xe98003bb3a79a974, 0xb3d2ad204cb2f040, + 0x6124e2a75553a347, 0x83a93ba6a4cfdb1c, 0xc2dcaa0e23b6c930, 0x3af25c98a1ee7550, + 0x7aa032918ed03837, 0x4301be5d8611769a, 0xcb7a72f5031ba450, 0x03b76735ec2266e2, + 0x70f7e3e285625e2f, 0xec879dcdca1ba27b, 0x048771d348265839, 0xf26eaee52c641522, + 0x26e150b78288646f, 0x056764f9deda116d, 0x296d9afc4d2af749, 0x8da214c276add899, + 0xc789666613aef14e, 0x09cc75bb7cb07ae9, 0xafeb80cfdf65b6ba, 0xc3d1c21eac0b0706, + 0x9c9c69a72b529355, 0xd575f73fd715ca17, 0x9fe21e1d77a498f0, 0x18fc6edf60f01267, + 0x91a54f5881a8c62c, 0x812cc651a9be7ca6, 0x1b5926e60ee20dac, 0xee8b5cb6c8ebbcdd, + 0x89fa637fc7cb0097, 0xb5c93aaacb869135, 0xb4049058bd6af8e8, 0xd9a42499d3ff6f0d, + 0x8542fd6e3114270c, 0x653d900b3f7bf9ad, 0xed059c741952ae2d, 0x0b1b7c09c918e2f5, + 0x14f489a6e3c392fb, 0x13b569699b325bb3, 0x2e7f8c8162215c4c, 0x626ae0b2f7c965c2, + 0xef9db9339a145ac0, 0x83cc0d3b58c3c34d, 0x263af87c9f7fcc04, 0x7471f7870153c709, + 0xdb4a6523c0be463e, 0xb7e548d8a416cb6c, 0xff11a4c68e17aca4, 0xf97692912dc4d01b, + 0xa31b35cbfbcc24c5, 0xc2af0099037a74a9, 0x410ffc39ee031f13, 0xb8f2eba46dcabbe7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e541c70512e770e, 0xf34cfca15ffcd925, 0xbf6badce03ce057d, 0xd328f255dfd4a0d3, + 0xd440845886860fe3, 0x1845dc6fbea5d62f, 0xe44184dc9397c052, 0x421bd496560fcc71, + 0xa963851e3897b4e4, 0xc98faf814d82ccaf, 0x5f7b4d99a83dc58d, 0x0d2b3876bf9b3dec, + 0x6dd3d11c72044dde, 0x3b3f7fa6e895c4b7, 0x25730e7cfff1498e, 0xcbf89220ac5e87bc, + 0x6c715f2c172fd5fc, 0x79e3c02e028c7ba6, 0xafe7a734a1aac2ff, 0xbeb81b5073920251, + 0x3703b400527d1beb, 0x39b034a4f848fb3c, 0xf2b7e93618866ffe, 0x4cbc8379c4c27dad, + 0x5366b036eda202e5, 0x9d6bee6bd8a59fa8, 0x9695b156cf2d4291, 0xb8185dbc153c5e3b, + 0x41100d00ec504d29, 0x3f8d071421221cb3, 0x0518d7024c75c3ca, 0xb0da09ba69535bd0, + 0xc12e743c9ac84d63, 0x344d46ad2d270f31, 0xd6f63ba444fed01e, 0xc45f7c343f880ec5, + 0xbb19f82b6eabf83f, 0x000691f0aa711bc4, 0x8801a326147f95ab, 0xc52742c2e36e07d0, + 0x7a0403889e35a607, 0x3978e2862ed501d9, 0x3a509bc997d58d00, 0x2dbd9e21bc0997b4, + 0x181914fb064c3e10, 0xc4de01a7719e8513, 0xc58695b752a8c875, 0x83b41fcaae89ecf6, + 0xd2e1be83b8a204a6, 0x134836135c212046, 0x619d74ad44aaa43e, 0x9424da5ad22a1051, + 0xd16f73b9ebb6f2ff, 0xf1da2b65a4cb0d43, 0x316ba6ffb2cc31b5, 0x28f86ed52846db32, + 0xf9627435d3de0466, 0x02b61dd62617e30a, 0xf9b733a022dd8d6f, 0x9b39925259549c34, + 0x4e7e4707379080f5, 0xe5c7094057ec3f59, 0xdcb3d9a65c54a538, 0x565d0fc11d5942c4, + 0xf5c1d6252353269b, 0xeaf7fca851a0e2ea, 0xa6e774e639ebbeb6, 0x85cb67edb1d95387, + 0x931780678122e952, 0xf4f0858f7c4710e5, 0x739b608c7212ac02, 0x7051abae72e8e2a6, + 0xaa788e7fca29bb82, 0x4b77c20f0c3ac723, 0xfdd61248c77108e0, 0x6097ee514257c879, + 0xa25eb0e336258923, 0x3843d016cfc38124, 0xf0f92e335e868b83, 0x4463b85908c0dccd, + 0x864aed4f71de4687, 0xea349574f6d69d50, 0xaceb75cf52bc2588, 0x84be6fb4baa41613, + 0xfdf9f4da6ca6261e, 0xfa8cd5c7dabf90b9, 0xb565e764988684d5, 0x0ac6962f80cbf39a, + 0x60b0fd7f587d7270, 0x849ce0c71be03ad5, 0x0389a73c69943371, 0xc3424d63624c9755, + 0x858912bcaeb64bea, 0x1aae596e126501a4, 0x6f5ed7b3905d2ba7, 0x5da907ff6f15471d, + 0xe5515a5baeb526a8, 0xfe1e8a61ae1aad62, 0xa1d0b825b64a38c2, 0xbe32b5d3a9d09d25, + 0x0d16d261e3f9ea7d, 0x1d81601b86bfb34e, 0xc8fff99fe2ad145a, 0xf0dcf2f3afa6f743, + 0x22a617d06715047d, 0x80d7678d2d1fcb92, 0xdce7b2bc4efcb2b9, 0x47ae2b6829e6bc2d, + 0x070864b1a0f3f8eb, 0xab0751a4bc34f5f3, 0x2e05674b68329c2d, 0x33cf5af1b412a5f8, + 0x382d6ccc38b54cac, 0xf2bb38fc47b570b0, 0xc2321ff5c31f3f06, 0x5b549d1e53336c48, + 0x1301e958d0f25d30, 0xbb6effaa77a645a8, 0xc988cd8200f34c38, 0x8f531168cc847d03, + 0xac5ad122bcb6c4e0, 0xdb26ffa1fa9bdcc7, 0x03bb8e59e6aef529, 0x66784deb54136fd9, + 0xd676bdf650a0a25d, 0xd9a74948e1de3fea, 0x48fa60fa804e6aae, 0x9489bea84ba2af2d, + 0x191c19423ce59c21, 0xe523398fe7bd0b5e, 0x815b75a2a53d367d, 0x904b3b41e92c2b24, + 0x45d36fdf654a29fa, 0x66795943313a9923, 0x5511b914a0c020d5, 0x9fed5835f76164ab, + 0x8c16d4dc0d0cee97, 0x2eff99150df844b9, 0x5fd5ddbded52d673, 0x8bfa8a7ab16797e7, + 0x1665ed5c53e3e840, 0x8ecb01dc6340f4fc, 0xfbeb0129ddb00021, 0xb5db4a553eb3a5b2, + 0x55b5d9e505907d20, 0x730acaed80c74591, 0xdb8cce809cb29fb4, 0xe962d819179248e9, + 0xa286762a183282e5, 0xf8eb767d478da550, 0x0071d5e908821fdd, 0x73fe4ae3122d4804, + 0x8b637d8b332eadce, 0x607a69efa1dcadaa, 0x6c37b1bf224b0016, 0x3cd5d2303de0c28a, + 0x72f2528210d2b8fa, 0x992418cfaff23eb1, 0x78cf2f99f81d302c, 0x0cce368c77f764b1, + 0xe1e66abcb2f027f1, 0x200b8fce0e6786cb, 0x265b44b27002e3f1, 0x99f967e9279cc9dd, + 0x8a139592525e0469, 0xdfd34d3f4ef811a8, 0x26926758b0d58e21, 0x454ac56a8e41b191, + 0x6320da54a8fa2c2f, 0xfa646bff105ce816, 0x2bb72bd14ee1bc86, 0x0e3fc6013de2dcf1, + 0xfe8da67fc1ae64a7, 0x4cf4c3dacdabd19b, 0x9306677aba9064b5, 0x931e55531ca3c89b, + 0x4cece606c98a94b1, 0x44e8f727eab00f99, 0xc66a90ab7c35ebd9, 0x5af83923b1f0c894, + 0x3f36eeae51e90d07, 0x7e6f41094ae2bfe9, 0xf01d04b80aebff52, 0xf0610d0e4219c28b, + 0xe262bb76b2619930, 0x11b21ab1da21a0cc, 0xfd3a0fec6c179ec5, 0xcd64afed80a33424, + 0x561ecedb948f3ca5, 0x66b684fb62265ed2, 0x9c440479d77e9863, 0x3e92adb3c92ec938, + 0x92e0c573d198f32c, 0x12b850360ca74e06, 0x19056c53044fb6e3, 0x208b1b50fb916807, + 0x93678a562d39c00a, 0x643e47b841c5f338, 0xb88d0bf1be352dc2, 0x67ba399af8224505, + 0x2b942366edab800f, 0xa5e6ce0493ffc19e, 0x0742466642ea3de8, 0xdf1338d047f5776a, + 0x4744a7b545e9e5c7, 0x389d420224df59a1, 0x75686fff51bd8f08, 0x2090c089a050a741, + 0xe67b650808c4ce00, 0x07b04952ec1620e9, 0x14b2ce4513c7d9c1, 0x9f17b36e5480097a, + 0x01ca00bee1339a64, 0xbaf097e355c4e8f4, 0x7bae613b98876789, 0x1752feb84e4bd147, + 0x74baf4be5949b56f, 0x7718c967362bc28a, 0x3a072e42b9828d2d, 0xb7dc021c09c24b87, + 0x699a36631eafdb0b, 0xc34217d01e827629, 0xaab94763618ee828, 0x3d3bee6a1f27737f, + 0x694034c57ecfb8d2, 0xb916115dab74e9ef, 0x21eef37a366d86c3, 0xc6a293829394d15a, + 0x9179a5024bd44300, 0x9cbfe112e041088c, 0x04354bf412a48283, 0xc27dac51a12632da, + 0x82ac69910a87e305, 0x72b2023aa3f9aea3, 0xac6a98f63a142b49, 0x2f4b25a6ec9885af, + 0x21cecf62f8195955, 0xfbd1d9deee15bb75, 0xc360e27524db145f, 0x31fbf06bd27bbc12, + 0x9895b0f64fbdce52, 0x973abc2ae2b203ce, 0x4c84a9d9a6244af0, 0xaebc14fb688609b9, + 0x13056c00abecd144, 0x9ebc4cc8cf18821d, 0xe7c1de477a371893, 0x471a7c09a30fd8a9, + 0x3c064388aebea5b3, 0xbfdc3693f3cb9953, 0x1d9f687826dbc9e0, 0x932c8254711ee1d7, + 0xf81305ff4d398f77, 0x4a0683867a2802da, 0xfe4dc202a7812901, 0x7bb440636a8b5e58, + 0x7da29b93f58f2f54, 0x6e54b3ae7322ae1f, 0x70825360df68b67a, 0x8646f65fc3ea25f5, + 0x7b6d92d6850d4462, 0xb1e1c3bbe7aed2e6, 0x7f07470fdb23b58a, 0x2c8d110490ffb7f0, + 0xd4d121783aa8bb84, 0xaaed8667c84eb7a3, 0xe94b55b9202a7714, 0xddd07baef0bd7cb1, + 0xdbbdb74cb14e9d6c, 0x0551ebab9ac8013e, 0x64a17501c592a1b2, 0x899c52ff612ed117, + 0x919587c8c016b718, 0xa94cd5d3c4437f1e, 0xa3e72cd1cb0cdc3b, 0x0466487dcef02035, + 0x34f699c32a04884b, 0xb2fb582739d39363, 0xc9aaed0441730d55, 0x8137f29b8b2206dd, + 0x6017a8157622b990, 0x762e5693b88f1237, 0x51d6fd164e7da128, 0x619f3ad7cdcf074e, + 0x7a719d00e60ddfb9, 0x0af3cb60a4c38215, 0x717e2def522e99a4, 0x2954c6a10e360e1b, + 0x5081a8878ec2a0f3, 0x0776e7cb432b61ae, 0xc89b0aa8444e51e3, 0xbf5c4c5be5ecbc62, + 0x66556f5088a1b2b6, 0x99106fa54e848aa3, 0xd6c14c76c50a6b56, 0xc5092b8651fd40ec, + 0x10dbc0a985031712, 0x87e358515c6cab91, 0x8e9e0aed2c144c5c, 0x303be589027aceef, + 0xc1473bb075a8cc1d, 0x81cde03b541a2d77, 0x8888815522d927c0, 0x67933ae8bd8419c6, + 0xc9e3b27be48751e6, 0x976a51f051bee480, 0x79e056d92b2b0f89, 0x6ac7d54931407464, + 0x405d2a4ddbe3bf13, 0x7a7a78b191d38d9f, 0x60015d8ef4ee9a1e, 0x6f07b752b967e788, + 0x8a462078fbe95166, 0xf18a710a6d547d97, 0xd897bf7165091c94, 0x381fe5024f737fdd, + 0xa760eb333ecd9598, 0x3f1d5b1331164393, 0xf8c78942a35ae8db, 0x70d95bde0ec4c165, + 0xab0984717010b18d, 0xa9cb559104d92737, 0xe801738f8f7868f6, 0x4641705b5b111477, + 0x91acbc620c650c11, 0x326160d46caac6bc, 0x32f31e8c001790b8, 0xca0ea62d7824d0d0, + 0x8b867097098d7336, 0x03704c71aab8b803, 0x177c71c080fce233, 0x9155e6c6ee4b3b88, + 0x5cb8ada46c25f7c6, 0x93d470871015ce26, 0x9b324e38d877cfef, 0xea46f0cd940f8bf7, + 0x6cb93d193a796cef, 0xc3044b160736a255, 0x118f1a8d9f6fa813, 0xb4733baa4c03c36b, + 0xfc77250f9a3301c8, 0x8e0db793aeec34fc, 0x7eb088ecaf6bc67f, 0x9d4f1e8613b5fe41, + 0x4ea5eaea136661d4, 0xf118292a09bd90b0, 0x490333abdc30e152, 0x44601924a3acf26b, + 0x5448748c33ee18f8, 0xd8d025fe6fb48c88, 0xb0dd0067a61570f9, 0xbdfe5b3a0290f137, + 0x603cd98838e83b3b, 0x5c4dfe7f628e587c, 0x722fd24e3d633622, 0x147c023fa96d5f54, + 0xbba570222a42ea5e, 0x7a97c38ed935f6a0, 0x975a0dcaa6db654b, 0xfe9e7f6fb8d8aba6, + 0xc1fb4e5ec51b1a1f, 0x85a670ed76a8cc4c, 0x168593cc9eb7745c, 0xfcbe04349d4b7dce, + 0xb946ef3c39139147, 0x82bee50ca4e9b2e0, 0x84b8115624d76a38, 0x23a8edeb092207d7, + 0xbc349393248f5426, 0x855e3a337f38ebab, 0x1431b148d3de671e, 0x3e1e446494742251, + 0xecade1c34edd370a, 0x7c5f1696d2101e00, 0xe581c6c5b22c59f5, 0xe6534943b390bf73, + 0x78473c4948a43672, 0x0ff0d09d9f8fe852, 0x3e81725d3e4af88a, 0x5f0e4f583b588f22, + 0xf8eaf58e13804a0a, 0x1f925f00ff68425c, 0xe4d8037f6120f13f, 0x9ab38384d63189ab, + 0x1f8973744bda0eb4, 0x789a378ab86a4506, 0xd1d01fafdb8c2fea, 0x8fb14f62155006d2, + 0x53aec8d8cac80b74, 0xa33919849998cea1, 0x686a5d3c95b73e7a, 0x4019dacbf2fc12bf, + 0xed2c9aecb3c9f848, 0xb3158da7c7a41857, 0x5fc01dc846509570, 0x1ed6dfcca392b6a8, + 0x2a17523c12db9b17, 0x14c26525dd98e226, 0x9098ff293bf2b4a1, 0xcb6f78be8a08f47d, + 0x20eb9a528480d87f, 0x12fa2e00b3122f98, 0x82ad3b3a2af47935, 0xef8ac4055875b8e7, + 0xd1c0abc003f3bba7, 0x7d91c428252fb6d0, 0xb039686270d5e111, 0x69cdf780af4f4085, + 0x47668f566aee2b72, 0x5301376108c13f5a, 0xc4d41d4388ea1ff7, 0x63cd7c933b0407f1, + 0x1bd44807ad73c679, 0xe5581cf9d8983d63, 0x5c74f87df555eb8c, 0x23c0358535bd2d9e, + 0xc6a7f36d0694d3b0, 0x58b967273df30a88, 0xb9d106194f451669, 0x0cb6df68807af75f, + 0xc652a461784a947b, 0x4eac38d3eaa39b6f, 0x656ce67b35ae7be6, 0x89e83414e23535ea, + 0x9b900fa31bbbbd5d, 0xc6890bc42ebaf04a, 0x60c365ed72edeea0, 0x25e8dda2bf5de7c0, + 0x66da97d8f0982b1b, 0xeadf0738181d59b1, 0xba39b6f4e62a4785, 0x08f59cc2a71b879d, + 0x4e4d2a7ccfe55bdb, 0xc8c044e28c089325, 0x964d502de167403c, 0xf50cfd021f345d33, + 0x6fa9bae7bb6d9b4f, 0x2c11f6a3c6ddad47, 0x41a8d6db61650e69, 0x1b68a05c14b8b6e0, + 0xd4a45339bb1a70ac, 0x739878bebd3aafba, 0x485584d02ac3c425, 0x88cabae8109fc73e, + 0xb305dd89d2b34b57, 0x1d4967992a8220bd, 0xcaa9da90ee842684, 0x8a0af57dfce8dd0f, + 0x74b932c8639c2191, 0xc3c7d09e9016fa08, 0x09980871a6cdd54a, 0xda5743084b31a986, + 0x9c9b9c1550f4d89c, 0xeeb7c995bde780f6, 0x1fadc3944584f289, 0x80d356117ef33496, + 0x8b615e9ebb892d68, 0x12cec03341a06dc8, 0x4338add790ec464d, 0x0e96266c5369605b, + 0xb0ed4061b3827f40, 0xd8817ca7245c7635, 0x30dafcae107ebf59, 0x5961f34b41321ce7, + 0x4e24e74c156d767d, 0xe24579325a9e2b6a, 0x35cd3f2be4e9ba6e, 0x8b6f199f5e5e08d2, + 0x418df8e67d9bea69, 0xfa26895256ddf23f, 0xe9e9e31c77f6071c, 0x2569410986138acb, + 0x68f1866731cd2bcd, 0xde03a73c98486f24, 0xc3c00619f74b70f8, 0x94915df87a3b6b08, + 0xcfa04937bc3da9b7, 0xfcab4fb441553eea, 0x4a90863d67f5f4d7, 0xb70daf5a15d03e6f, + 0x15781d4c262f0054, 0x720763b46eff935b, 0xf12d0d7d936a41b2, 0xe03073fb0f209025, + 0x9750c372edd61d6f, 0x15ea303a88334d66, 0x532b9ed0601a80e1, 0xc2e2d8e88765e7a8, + 0x3ff957613800382e, 0x56e0aa88cf27f7c5, 0x5a2dc464432ea411, 0x5a3a05347ac00522, + 0xd76e41e4970c188b, 0x13ba4ed0621932b1, 0x92f54c29b983025d, 0xaf7df48c8f8014cb, + 0x708cdec450947cff, 0x7ea8fa9f7ac50dcd, 0x299c941ba0a16f4f, 0x5295f6684500d75a, + 0x4fb1750a20e221f8, 0x0f1497f42616c22d, 0xd04cf88db362d7f3, 0x3e856650449349fd, + 0x497441eefd9b798b, 0x3a18c35deb7df212, 0x79c55b05428ae55d, 0xf2884831f02097a0, + 0x27b3bfbb35b57e1b, 0x2f600694febf5957, 0xe4e141044759654c, 0x29020673bd3f18a5, + 0x89e9ff811a8d5305, 0xc111e3e15007c641, 0x7221fdb90e0ed04d, 0xe4b2ec9d81de4ef6, + 0x9d1ccea6cac48e55, 0xc4e3af64e9f634ef, 0x2e2ed293fa14e6cb, 0xdf213806e4f03f70, + 0x530ec1f6f826bf46, 0xdd584cbcaf16d544, 0x5811c4640398dced, 0x42cc4964fb7758ad, + 0xfac016cd76401ca4, 0x30eaa07ca301faa9, 0xee9cbd31c2b796b0, 0xeaad1ca417c73c3f, + 0x2c4784dd7d402790, 0x2c0cb6902bfc34d8, 0xc4df4866d25d574c, 0x05c5c33072bd369d, + 0x0e4b163246aaeca9, 0x7e6ebc1c84f80692, 0x38de40614ca24244, 0x18d79a460f38ef3e, + 0xd91696ed3e41a84d, 0x8676ddf06ddc68cc, 0x26fd1f72bb4dc379, 0x764eb86f0c67e224, + 0xef7a3660faabbfb3, 0xc67d6f21dc99a89a, 0x2acede7067f7f25f, 0x1ac5e5e23be3de71, + 0x08dd05affc1840f2, 0x8a7623470bbdb4d7, 0x03871265fe9c49f6, 0x1c84462ebe457105, + 0xf88c7827c0751197, 0x267ace53518143df, 0xba9e9f783f4bcdf7, 0xda780b4a349d6353, + 0x0a163c29556e5851, 0x3555b66f9e1be79a, 0x461c9f5929ac2787, 0x30f33fbdd2bdc323, + 0xf03b3a769602134f, 0x3da0d451fd76c12b, 0xd0fe782b376e6ea3, 0x9563e3e19fbcc438, + 0xbf21074b6c4d29b7, 0x24e102aa920d1ee6, 0x3d58f94654a91ae6, 0x87e008117d676724, + 0x294a1eeb4f6d6844, 0xb15a658e3de9147b, 0x341d7c4452aa90c0, 0x1ee6251566e20220, + 0x0358076a3c262b22, 0x128a96bc2a9f8116, 0xb6e0f026ef4c89d1, 0x1be88c2ee2d969ac, + 0xa595f30b1822d76a, 0xbaeb4fd81008698c, 0xc83dcc656f957dbf, 0x69105d54572ee642, + 0x8e609c68b0be83a4, 0x63151149865fc266, 0x36d4e3e60b3e64ff, 0x033f0cf8aa007281, + 0xa44fd7064191f1bf, 0xd5b0716a5ef36fa0, 0x1e687ef4a3f0e37d, 0x43ac9acd9bfdc4a0, + 0xc1ce6aba9c1909a2, 0xf4b2d2bc1ca7328a, 0xb509e3cbb5402719, 0x31cd90edb45c85fe, + 0xd0b068c8992fa28d, 0x268763c6441f9098, 0x80808ed8fd86ab6f, 0x62261e5720efe5e1, + 0xe426ef8fc5694249, 0xc2ed11760c34e710, 0x78c00ab617e75d5d, 0x8d6e513f2adf1ab9, + 0x2e706c376047c275, 0xc81487ac75816ce5, 0xb28b0238003f8942, 0x4175b39de9567e82, + 0xfa81d8c78715ffe9, 0x805b2d431ee5994c, 0xdff7f515d4090db7, 0x82e73352f2007555, + 0x41e1fbe052953923, 0xe860774973dcdd7f, 0x0b5c6610cd3cc2b8, 0xf988f184eeeda5ff, + 0x583f66dbc97ffa11, 0xe8547b337c80a947, 0x82e3d89fb588fb44, 0x4ee536a17f027166, + 0x8bac2f4829b54f39, 0x1e6e8fe1bd0210fa, 0x4152f6bdfecefab8, 0x710485bde7a5ca64, + 0x01aae79712cedf14, 0x3f7a5cec651c0c44, 0x5624de7366e6aad3, 0xe980c707f674aaeb, + 0xe529237f2492e3a6, 0x5d6bfe2f93641043, 0xb57376e3b3f32d6d, 0x24afb802cd90c018, + 0x76225270e2521aa4, 0x29e5e51c83767b9d, 0x53b4f32e454e7d87, 0xbb0ca34ae019069f, + 0x25b0b27a4e6cbf90, 0x646d152f46bb9777, 0x8461d5419dc5609f, 0x8f1f31c012e497ba, + 0x67bc6af80e8a2182, 0x7a6565809a50e429, 0x52e66080f7df4620, 0x6ae26b01e38edcdb, + 0x66c12dbe36e03009, 0x0ff0c07cc4d02255, 0xe9fbfef252bcf469, 0x49955d97cc49bfe3, + 0xf70c22eebc6be4a5, 0xe35dfe6c0c5db0a9, 0x852a033da5b1cf99, 0xda5bda9961cfcb7d, + 0x5fae57c1ecceace1, 0x0bf75732dc66de02, 0x58035f5372dc54d9, 0x8a3adc28a5e1a46f, + 0xb8f564e171bcf5de, 0x25427b1b1a83f791, 0xcaf50e714b539d43, 0x14792da8b9ad445d, + 0xc5f5fa532cea0c87, 0xf4d66ea7436663f7, 0xc6afd726b9094860, 0x1219d329d326e009, + 0xd54f1d4d08ca90d5, 0x0d82b638953ff0bc, 0x41f87dcc6a5ae42e, 0x2bb8ea8ea8509038, + 0x6c091f9cf22597aa, 0x9fd68df83d09441d, 0x5cdbd4f614de9d9a, 0xa4196d7615266075, + 0x703a2e1b8e1ccb24, 0x15084ab4ac295a10, 0x67b4b7e4d8ea0940, 0x0481c84ef1dcc43f, + 0xf533fae486d4cc34, 0xfa4cdb26692f0f14, 0xe347cd684e90b1ad, 0x3d2888beab886ca6, + 0xf7535ec6d55ed6f1, 0xdbd7fb4d78ba5275, 0x2173db9633ba2536, 0x6f86641ba0076df4, + 0x5f4053179dfd860b, 0x0fa07aea481ba7cf, 0x8d39df2d19f4d6ce, 0x22441a58ff6fb864, + 0x5f19faaeb072dcbd, 0xcd4d74b2e4aef1d9, 0x651177167ca39d4f, 0x7e6ba7e0a7bc8546, + 0x10b7233502b50231, 0x9253297a13d8eefb, 0x3c2ccc3877b1e054, 0x0199dfe9c6cab929, + 0x665623deef6e6e04, 0xf01626a8e43de6cb, 0xbbb7f6eead316557, 0x85be5103051137a7, + 0x35706c57aeec6494, 0x1b69384e00ca93c3, 0xef49785b21496ec7, 0x1d5b446fb7b18e15, + 0xb9ef53f08e17b87f, 0x3c5ab22030d4766c, 0x00a6813d4d22ad0d, 0xb5a638c70218cfb0, + 0xea9ff995ab0ed45c, 0x3c8d21a64910ef69, 0x73ae3956bf101b66, 0xbeb299763572b968, + 0xf8520ca4bcb1248f, 0x17af46fd102a4eae, 0xbe0804f77ce606bf, 0xdfc296ba8427cc88, + 0x730eacc4a67ce0be, 0xca0b7ffbbe158bb8, 0xd0ffb80de9a3cf2c, 0x91eaf0602b3e4c9d, + 0x1409fddecc86540f, 0x139c7c9d40fff489, 0x3b95f913b542da26, 0xbba01781e551c246, + 0x34a12e73a2f09b0f, 0x32d26d8ffc259dcd, 0x6956370419f9b683, 0x499ce59ccce766ea, + 0x619538bb7c47adf9, 0x42b115dd2bcd974e, 0xf47a11a520cbeaf8, 0x6dd9af5d6249ef76, + 0x7ae9fb5692f1fd45, 0x0e0ced7f9e9a6037, 0x5eec4583f161079a, 0x97c2aba122572df4, + 0x181a48b0ec4c9336, 0xf59a3e8ab1c6c371, 0x0c2f7eca629993c5, 0x035cb54d31bee461, + 0xbdd333ce047150c3, 0xd3d2bb990bc1e6e2, 0xbc1255aeb480c891, 0xddc30ebe83e67e8c, + 0x971d0651990fafaf, 0x935f3215bcbed194, 0xdd6354dd40ec17ec, 0x87441e6354405db1, + 0x006ab909d044f912, 0x801c8231e9c76f8b, 0x009d3998e67d2b5a, 0x8fc6d7565f33ff4f, + 0xd14a25c0593b1567, 0x324506d808c432e1, 0x240e8f9bf4264a15, 0xce7e18cf9f49626b, + 0x3a218641f1ad13e5, 0x430483f1408d59e2, 0xfab57e70bacdc32e, 0xfeb7dafb0ed09d56, + 0x5fe484dcf3e97cd5, 0xde516fd6911c094f, 0x0bac2b10625953a7, 0xc46dd1508da134b4, + 0x494a37851c815066, 0xb998a81107a1e81f, 0xbc172637319d186f, 0x4cb6bf20cdde6dc8, + 0x80e4cb1d264fe753, 0x13a61d9509b44caf, 0x32c1b469779b31be, 0x46feb69582debb34, + 0xe9c4ebf07e0e290e, 0x2ecf63b4ea8245d5, 0xe93978f561e086d7, 0x4b973a34a25a0e65, + 0x3e1fb008cacb8c0d, 0x3c0a1158887aa8af, 0x25ebb10567715d30, 0xd51d4a2a59d97b87, + 0x45eb04e72673c0cb, 0xe32c602c41a0e7d5, 0x395dd07564ceb9b9, 0x94e66615f6a8eac3, + 0x6c75bbade252a0b8, 0xaf21545653fc761a, 0x8c07471ec4564c1b, 0x5dc191b6b6d4032f, + 0x2f7bbb64c2fe332c, 0x59efb2ba5ac391de, 0xd95363ee215db7d5, 0xb705b39227c9c5ca, + 0xf8e4cdad206258e6, 0xd4cca59bd071f967, 0x3d74d6a89245a0e8, 0x3a7dec4842bd8805, + 0x614f3f332074c509, 0x46fdefcb31bf736c, 0x7a854af7bbc99f27, 0xf2820f898b9ecbba, + 0x3bd05cd305e8aa03, 0x4de1c78da5a6529a, 0x6df59be4cdd47d44, 0x0d530106ade8fa10, + 0x6672b5019c037c77, 0x7c714a78d94889ba, 0x90a135c47561d549, 0xa313ba77622226a5, + 0xfe671745bdef3146, 0xc8198f88ef63fe99, 0x0a84f16e8f587794, 0xa236497364aa3626, + 0x5fdf12e527941060, 0x94f564db899d3314, 0x85b73b7fda972f3b, 0x722f67fba576e60b, + 0x251b8fc58ba65458, 0x34d3f41fe3135e74, 0x2ce3dbb91ba91b1c, 0x1f5b2858b370dc71, + 0x069e45ffd4aa04e3, 0x122a6fcca4cb6aae, 0x788ec91eef474018, 0x35e3ee811aa42cda, + 0x5f4af759bc379fee, 0x4f226389be8e1220, 0x98b37df945e6f6f4, 0x5e77c46f24171a60, + 0x28d145da70a66ebf, 0x89a3c010851c6784, 0xbd802dcc381c5645, 0x30c99eaa44e7ded6, + 0xea15f8e3c1f021f9, 0x9b2f5651da33886a, 0x9628db308757c890, 0xd23df148708570d8, + 0x51e0e641e53704a7, 0xc84ad76247fb8471, 0xc3248960fdc52d7f, 0x4a6a7e2cbe1628e6, + 0x0da13848348fb3ca, 0x103abc968aa7a1fd, 0x9266528f01e98b8b, 0xa3167e2de040ce80, + 0x7fee8b9ce123abc8, 0x759d87a3088767b5, 0xefa8c43869808567, 0x64d9a2b071c226c1, + 0x0c8702e8263d9114, 0x0b99982d13e29d94, 0x63478fc36369e90a, 0xca4353a652be1d10, + 0x9391ebdacef57042, 0xd8e5bf557b8a953e, 0x61e81bc66cd61e73, 0x8f6a88a5d7e5f031, + 0xfa69742ee7fa4546, 0x9da43f846afe3b61, 0x80cf658d601765f0, 0x1f1773b83f86c562, + 0x050c0b49d8092a88, 0x416f34fb5b096e6b, 0x33b4c705b0f5a748, 0x9bb1c3b10466ea4b, + 0xffb4fde9d6398349, 0xf2d337814985d67d, 0x6bc1110eb2d9743a, 0x6e33c52f52e2bbd9, + 0xfbc0516a368c6bb0, 0xd0d7c491da0fa9c9, 0xbe6d87aeb5da61b7, 0x869198f6194a509a, + 0xaec75544e0bf1319, 0x1b0027e004b11d34, 0x31f99df8c12f272e, 0x0372651f52707e00, + 0x12d33cff35e698f4, 0xe257b2fe3b3e574c, 0xb98c5048badbc401, 0x5c8488924a5bc662, + 0x8f644cd678be1b42, 0xaab9ca5d98d82a75, 0x1abfdfce32ba2714, 0xdad6a5804b980714, + 0xc0024dc1230eb6d4, 0x0a7c147af4b7802c, 0x6b8283a3c7c0997c, 0x3f4de1de62b2266a, + 0x0bf19c5dc9db0c6e, 0x5841a5e3cf3bd0a1, 0x195ca7f25de69e7f, 0xd74db663b52d2925, + 0xeb31d8e67205c760, 0xc82d4b9782d632ba, 0x0501100a99b3fca2, 0xb5033f2b1f565bb2, + 0xc8ab6b5f87482e62, 0xd181833b98eb36ca, 0xd9ac858f43b0f7d5, 0xffef6f3d770f4218, + 0x24107e4f77627273, 0x06ca7272af4019fb, 0xc54c84eff5466af6, 0x21ed775d63a12c89, + 0x7d87f415338d1917, 0x28bdd18198d422dd, 0x0f707f505110847d, 0xd9b6c99add8a535b, + 0xc6dad3faf9b41bd9, 0x423a969f9dcf6e36, 0xd9a596449673924c, 0xfbe6f174fbfb03d6, + 0x8032a524bb720f1d, 0x515d1b73f9aa3b11, 0xab24f5485776d709, 0xcd2e2f3c5c142296, + 0xce1b8879912a90f6, 0x14daff1635115015, 0xe91bd0080b815e36, 0x8abc88c5c4387d25, + 0x979379c0b201a74c, 0xac3e724239f66bce, 0x8d1bf64cefea0470, 0x470e4d07262c0eab, + 0x7ebdac56f530be86, 0x2d90084f46c19143, 0x4fd7d652f8255f37, 0x529b2e918d6050d5, + 0xbdee549b7b3669cd, 0x7d8846c15f3e6e6d, 0x702b57415dabed3e, 0xec7bceadacce247a, + 0xed0189d08a36b2ae, 0x061af6607feb3c3c, 0x2e41583708927111, 0xa9d2d98e142dfb61, + 0xf01f693ab83b3086, 0x86797984636586cf, 0x16ad7ea60417e597, 0xf54bf08087f83a60, + 0x44dddb7048da95fd, 0x7cd8c9ce9ef8c869, 0xf1e9dc98b13b4da4, 0x180778ceb5e93f60, + 0x65cda16a2ae68d05, 0xa7e3239afe162953, 0x2becd78990cb321b, 0x209d1f7d571b18ba, + 0x3913e4da104a4603, 0xb657b2a908186289, 0x1103a1188d5c753c, 0x69beac8e2e044a15, + 0x1191cf3f6d7a7571, 0x616af591004ce866, 0x562c0d4cb03c7dcb, 0x25e9e69cea598abd, + 0x9c893bf18c34026d, 0x5cd4a026ebbccea1, 0xb84f9d753f5561fb, 0xcedb2cf26617dc20, + 0x25355cfb6ac8eef8, 0x41e89054ba149109, 0xad709449f744a536, 0xeffc0c31d6c1c3f0, + 0x811b8d65e89689af, 0xd3ef14243d457d63, 0xc17b089e086e905c, 0xb7b2d8dfda59e6d7, + 0x39c11e96bafc1cb5, 0x437fb325d5be53c8, 0x044d23f96c61bea1, 0xb9e1b5a25fc39431, + 0x7d3ae7d3c39470c5, 0x7f3ef92beb2a7cc1, 0xfcc4027d0cc683d5, 0xc2d98ec1ba81b000, + 0x605cc703f37f343c, 0x21bd5e86826a8def, 0x3c09ae2a942cd7ad, 0x9d815b4200880d29, + 0xdbf6299819e6b95e, 0xc916e8e2899bbde1, 0xf6404556e8014e83, 0x3786a2d596b9cf5a, + 0x7f5d67c8111d7139, 0x4b622a58f05041f2, 0xc1b00721b471e0e3, 0xbf468eee70943f1f, + 0x93c4490009d794d2, 0x4cf2e5c461a14ca8, 0xe829a2e0321e8070, 0xafc54c729f58bf46, + 0xcba58adb57142efc, 0x24acc6137f140075, 0x183ccc3e95044bed, 0xcb2e690f69b0cd50, + 0xacc6355ee2fe5c90, 0xc7cfa445d7160f5e, 0x248136af915ac344, 0xa0c8d29247db50c4, + 0xe6b663bf799a9e6e, 0xf379be1fd46b5b3d, 0xa3fce043684956a5, 0x8ecd5c722647cff7, + 0x6e00a6c81a3565ef, 0xf2e41efd648dd079, 0x677cd643b842f654, 0x5c1ec690285cc86a, + 0x1dad5afbb90e6bd6, 0x1b8edc0672092aee, 0xffecebe968c2e030, 0xa1106037c9b85a10, + 0x80106dced2497cbb, 0xaf668dc37d149d22, 0x0d6ae0c681727a9d, 0xa32b7e26fcd42569, + 0x7f2d82059d7e51a3, 0x2ab0b823c0b549d1, 0x203e9da862831ad1, 0xbe344bfc646e3a33, + 0x2f8347f299f3c547, 0xdea019d472dc1aa3, 0x929a38d1b206b81d, 0x30ecfda394d4b391, + 0x5c45f4188a995190, 0xa552c144465450e7, 0xaafce7c6e680e7d7, 0xa883aa1aca89589f, + 0xa50304173c3dcefc, 0x3ad1b86e1faad144, 0x536757c5f2f312f9, 0x1bba998c0bb0b863, + 0xd5e2791d5f06f554, 0x264de3bd5d6dfd5f, 0x30af2c0750e55e56, 0x16f1d67f5a9dad2e, + 0xbad5885a539aea9b, 0xecccda8c8f36568f, 0x90fa3986db7bfca8, 0x7f8d61d8c0535b59, + 0x854d191d772cf0a3, 0x112c948e4260443e, 0xab88aa44d854de61, 0x108bce9fbe48618f, + 0xdbf35fc33772ac1a, 0x5ad75c0aba4e1ad7, 0x423c368b23720e68, 0x9bd43dbb2c238ba4, + 0xd32206d188b28e2b, 0x862c50611917763e, 0xf0def702ee240b2a, 0x62e0d22b004c1302, + 0xf7cb3574564354da, 0x035b010237fb29a0, 0xf4e4c357ec476f1d, 0x3d7fb8be522cb386, + 0x5fbeb46aac5e7ec3, 0xfc70b12cf77dbdfd, 0x3df9d6a2eb6b9c48, 0xa2216840b6c51ac9, + 0xf9c5e0caf98fb263, 0xb31104c9ed0a5303, 0x6eee780133412869, 0xb0c8fa7be4e01d38, + 0x93edd2b4065e9ac3, 0x1d2c9d2e2af35007, 0x8efb80f36f437746, 0x3cc721f11b347c2d, + 0x608fd166ca1aa805, 0x00b7c196cd2639e0, 0x3ec65b54a84f9254, 0xebb06c7f88ada62c, + 0x4f92e9afe8db1a51, 0xc51cc40612a0c9d3, 0xcb5919738de5e537, 0xb86620f001559801, + 0x5c7ff320778dd5d8, 0xb297bf16075ecf98, 0xb79f5b56f4c9cfa9, 0xb352f500b37c6308, + 0x79b25e792e799657, 0xfa30a53d9437713a, 0xf92578d2848ae371, 0x6797f7c86291750a, + 0x2738ebab8902e8b0, 0x5d12368d03534383, 0x5844e8c0a65708e3, 0x6bb36fc5dd463c57, + 0x48bf02528b31fb77, 0x10350538b8c4a6ec, 0xe44da9159186884c, 0x5fba2bb34da050db, + 0x396adc63d26a0dbf, 0x5360e439f959b314, 0xc14836cfa19e2490, 0x82f7ed6f01173edf, + 0x046701aae6a3578a, 0xe09510cc79add4eb, 0x2fa01e8924eb5cce, 0xf650e2a079b69e7a, + 0x6ac42f4c81229c6f, 0x4e9f1c2087b6e40f, 0x47a5d10ff7cdfb2f, 0x7a5eaaf33237eea7, + 0x24d1c41d81ece71a, 0x19ee288347fca6b7, 0x7a6c32c1dde60002, 0x089d3d5f47e04a0e, + 0x38f50ba39c99d80d, 0xef588c60412fb536, 0x0f5e6713dadc4a15, 0x97f8addf24537e10, + 0xe42607936aaf1074, 0x18a3e1ac01bda0b2, 0xbae19df96dc1e17c, 0x9fc44fff5701b719, + 0x3739577c572c70ff, 0xec8625d0532a1f8c, 0x948eb18cf5b6d59a, 0xf0704c23bdfe535b, + 0x53284faff6ca181c, 0xa34afe579ec841b6, 0x33349aad9b46748c, 0x2d7f1554691fd165, + 0x307621e8e95def3a, 0x2032fe24e7ba0e95, 0xf8e912374b480d42, 0xcce32cca00a0e645, + 0xed9b55868ce1b444, 0x2720e93103c9f0c8, 0x9dc946f8b6dfc60f, 0x39a6a8ec87622b8f, + 0xcc4c758e5f4cbb1d, 0xf4c3507637c1d9b5, 0x54285447abaf8caa, 0xa17e99de2376a99a, + 0x6a8417d3ed67fbb5, 0xce09a551c62f2407, 0x874221cfc9fb0535, 0xed715c7f335e10a9, + 0x0c5b46ca481ca52c, 0xd018f048faf5071d, 0x34458f6c08a30c4e, 0xcdb7052513e9ed8e, + 0x91e8a125a71ebdcf, 0x8535a14bdb147f44, 0xaec1c8f586f5ac5c, 0xbae0b7bf99a3dff4, + 0x63ec690e40be9c54, 0xff9ed3d27beb7e52, 0xa01869cd441edd74, 0x2d6b6bf959c9670f, + 0x34f27ae68453c98b, 0xf9fb0934921334c2, 0x19aa0432dd347249, 0x4d3dd7a1febf2a74, + 0x9ef327e5f74cfb51, 0x6baefa034ec26115, 0x7140ba3415804359, 0xe2466a3c371414e1, + 0xa5a62195e6923b40, 0x898baf05eb4d9c39, 0x3996b3a0f33dcb62, 0x8a1bb1620eff8950, + 0x1c53be39f33cf50b, 0x257096ad1adff1ed, 0xe3505a4aa666a7b3, 0x013d6134ba7ea3fc, + 0x6bf1c89aaff525d9, 0xa0fc0e736f736000, 0x34e55f3f1f3e392d, 0xc0cf114f54590022, + 0x1883e0a50ef489af, 0x2f2b9a58ed1cac9c, 0x44a12be7ed36f3ff, 0xd6e110a11207cf4c, + 0x9b5d5d222670af7e, 0x12e8c886987f63f3, 0x5e076c5a90cdeec0, 0xa72d9fb919ace8f0, + 0x520519661edf0d2d, 0xf0e6a4a90750a054, 0xbdb2c441fd2a3f74, 0xb872d9d9e4776049, + 0x41d75f0b290c1035, 0x4f06fc001bc708db, 0xe381f601a2b76bef, 0x2629a472fdc84af1, + 0x52ff42a03ecfb4ae, 0xe5dd6ba8acd5122d, 0x1af68b4433003501, 0x6db024179e96ed70, + 0x2b9ad5db44fe10f9, 0xfddcb617d95b943e, 0x02bdcbcf2e147139, 0x44afc5dac6a4caf9, + 0xa009608bddf5fe05, 0x5978803cd0366d87, 0x86a428e6252358df, 0xe49709b8e8db8e9c, + 0xd5deb751baf194fb, 0xd5902cb05ec7ef2c, 0x44787e411c521184, 0xddbcf7d09fc23cb3, + 0x643310603a0802aa, 0x32ccf135e62ce182, 0xcc7df710a3025b2e, 0x611e505be4206f88, + 0x23cc5978137eead9, 0xcbea00fb135ce56c, 0xb29de0e04cd38312, 0x8c1308ad32279a66, + 0xcd3e2459e1ab0aef, 0x216a9c9611b627cd, 0x98bc251f7eca2ad6, 0x9f4f1d5e89d71efa, + 0x36c637858ab5eae5, 0x305c532c1a79e6ab, 0x238457ecb01afc37, 0x5478cf7737698637, + 0xaf3257b917110270, 0xc8da149b7e6f45a4, 0x30186f92727482b3, 0x081f403a4ce80c8c, + 0x42a4b9cd81a07db9, 0x6ee93d3bf6d1657d, 0xf5bd8b3994033b44, 0x8faa1c39e00beca2, + 0x191faa12c20986ef, 0xc4147a8c23752e2e, 0x608d2bdf814e3f01, 0x5d794c4cffca8113, + 0x2f91b82ebbe33b18, 0x3fed2044689fef2a, 0x0ab76806b4f10d56, 0xf787c4a2b26fc3c1, + 0x49f2dbe75d97957b, 0xdc6a7e884df4d2f4, 0xc4675624785eca0a, 0x10cf7afe7804daa3, + 0x4d966435ff491393, 0x61dfac6a9e55e0ee, 0xde3879d94db709a8, 0x9ef0d863662f8257, + 0xf56def24c498c0c5, 0x6ced2b1f7970d8d5, 0x20bb1a43ed5acecd, 0x91ebf0263cf74014, + 0x03a6bdf43e88043a, 0xee49f7dd5a369f39, 0x076dd4bcef99fbb9, 0x8aa06e5947b4699e, + 0xa200f57d8a93d052, 0xc8c84b478dce8e9e, 0x5f80d5ec20ce3167, 0x436a51f5b9d42d73, + 0x5bc0a3233d44b16c, 0x9d4be201e1745983, 0x0a7c2c684f1abc18, 0xfd02f132754047d3, + 0x151abb02a164fd5a, 0x76c41044e19513dc, 0x1a495d8520defda0, 0xdb38bf832f7cfd87, + 0xd5595a0ba7dfac34, 0x7d73721c77151f6c, 0x3d94cdfd9ac740d9, 0x1f30dd516678721a, + 0x1e1ddd998579ec51, 0x2fae0d16b519bb97, 0xff8108ddfcf892cc, 0x33be2d63886e6a4d, + 0x76ec3569e2419dbe, 0x2e8fe6991bd65185, 0xd21fc89f0f9aea76, 0xc4527479fff574b4, + 0x5e6a3350ea9dea45, 0x2a632685da3e2fbd, 0xaeab719fdf07c663, 0x0b753b179fc15019, + 0xf3f5a8a3cdcc902a, 0x65a0bdfef8b1d605, 0x58d68aac1e5ad17d, 0x2e3c5060d4bc3bde, + 0x7dadb3439b6ba82f, 0x5c279953f49f6223, 0xffbc7021e3adddcf, 0x6e4e36dfb1efd724, + 0x6173345379f7ad00, 0x6ace8d0917f57d85, 0x755434794ca3337b, 0x6fddd67da818853b, + 0x92fe6a49aae60643, 0x07a5d11c02798e55, 0xf03e282173c16aba, 0x709895d4a19606f0, + 0xb903efb73967be35, 0x4277847ec748173f, 0xfe00d8baa8381c7d, 0xce4fe4832dbb327f, + 0x66e66ed36b3d29f1, 0x55c15ec18d8f0dab, 0x9b78987c211547b5, 0x7276dd142c3c8179, + 0x8af87b41155573bd, 0x8bc80d818fe6cc62, 0xbc0247b9b0e99905, 0x6953e198813fe3e3, + 0xc57c535afa4b6417, 0xea35384510c44793, 0x9ff7248d6b9f7f18, 0x7edb43a68b26d13e, + 0xd2afec7cabcef686, 0x58e27b88e4999de2, 0x93f507b934ba815f, 0xa3bea24c3b2bcaef, + 0x936bc3cb74ea28fc, 0x1049034976cdfc08, 0x5ffa567755a6f3ec, 0x6f246ef4f0f9b7fd, + 0xd4cb878e65ab4d92, 0x33cbf37816c69315, 0x8578962dcec8b94b, 0x4e8744c1e9b91e04, + 0xbb5f2acc3333654b, 0xead375507d82b21e, 0xc5bd36b91787f7b1, 0x99e2a9abe10c3d48, + 0x5b8f927facf76d9d, 0xebd075a29a58937a, 0x1a2aa08358abd181, 0x3c442d9a564ff679, + 0x4856acae05de0547, 0xf1c3a136c13ac915, 0x4e77e29156ddb629, 0xa22d4c8860b44341, + 0x959b8a4a097e8315, 0x5fb9c1b5a66d0d71, 0x1ccfa9c23b737713, 0xe818493bbc436232, + 0x03376127aee296e1, 0x5715ae4a5df418d1, 0xe3fcb0a8ec00d617, 0x43f9e2669b446dee, + 0x56b55c3f9cc84f4f, 0xe78ca292dff31bcc, 0xed5246042dd588f5, 0x438968aee1f139b0, + 0x08365669ef102388, 0xe04c70e4916e802d, 0xa32c6e76673bef96, 0xd3cae06130e8c2ea, + 0x9daab43cc7cd9f8b, 0x8fd6145c40a4d438, 0xacc6b2f7fbbe3c65, 0xb34e2840bad9c7e0, + 0x0fb4a33846acaf62, 0xc3c3924479179a32, 0x5ad79428d9a5a083, 0x4881d3f99b803cc8, + 0x4b8c584624e818f7, 0x47f6691a0b9e6e8d, 0xd7d8771cdb2f8d3d, 0x1a5a5989b5381fd1, + 0x7998ee467f1efe81, 0xac02d1c33fe261a7, 0x332d5d71e63702ba, 0x922172db372da20f, + 0xbc25fd105af7f302, 0xbaba8cecb5e8961a, 0x358e7bfc84e999eb, 0xe74813bb1f364914, + 0xe16327e58ab2028f, 0xc7f7c76397c927af, 0xd6e11f74422cecc7, 0xcbc56ccfc0173fcb, + 0x740551f173246ce8, 0x0dc4ba18247800f6, 0x7410edeea18dd3bb, 0x37d82984b65d3cd9, + 0x844c40f233cd939f, 0x353e8e2fe3122269, 0xa9e884e357a51aad, 0xad08a43a002abbbd, + 0xcb9651aef059546a, 0xd51369c33efa3902, 0x9bff1f325e7abafa, 0x6edb693ae94065ef, + 0x17b39083db27cf42, 0x74f318c81b61d013, 0x3d379e1bb021575c, 0x42a047b500b09525, + 0xa18c594383a064ab, 0x2fd502802a71cada, 0x2564268a5a6a975a, 0x8492edb0fab8045d, + 0x3afe3fb3b8b16036, 0x193f0d66cbc88695, 0x94f1f2ed33882863, 0xf206f47b7a4febd9, + 0x6d2d77ab4c8d9fcd, 0x722328087827f6cc, 0x6b95796385c74a0e, 0xa57d45ad50382344, + 0x8de7ed4a217234f4, 0xa8e53d32b0158058, 0xeb11b0fe23fb037d, 0x879bef4e87669b43, + 0x148d4f3598ebc21b, 0xe4b566a9e47372cc, 0xda424e7e105c1f8b, 0x1c6ba65609042d78, + 0x932a62b775e356a6, 0x5f3d1de668b71dab, 0x4aa37159a80a7f80, 0xc2e847785eccd0f5, + 0xf505763031cfd353, 0xe54b8c25f891d30a, 0x346bbd0e6285a422, 0xe881092ab69e9319, + 0xad007973bb1caa5c, 0xd6b84c9d3b720764, 0xc35538e1c491f47d, 0xd621863b5dac5502, + 0x05eb6818f66dfcb9, 0x6384db36e3b3fbdf, 0xe6ae277b14a6959d, 0xd73ff1b41b6bfbf3, + 0x6297cef45d246cd8, 0x3cda64e84bebd99b, 0x80c5bff15ee5c7da, 0x342b55b4b739cc78, + 0x8564653e1ed7ea27, 0xd934eb7426ba2305, 0x9b2d6ee44cc82c81, 0xf6c2b89d5c1cca10, + 0x762cf4b1ba5619da, 0x19abda57b2cf51f3, 0xb173158954732121, 0x103909e6fa5a19a1, + 0x93bf27f5b03ba2f8, 0x8af419fa775d0611, 0x680b5a80d88b084b, 0x9d072d85a1c12019, + 0xdc181af3c2eea2ae, 0xa9bfcaa8ebe2c9a2, 0x69758853ddb7efbc, 0xedaab665c71da2f1, + 0x920a1da9d39a47a2, 0xc3a1a5f93ca2df93, 0x86a5a8ca12bda254, 0x6e1ad3ef7f55e4cc, + 0xfaaa66e13edaa7e9, 0x6e5ddd9c96f66c26, 0x2864c17aea2b7e29, 0xbab2ba405f6373ad, + 0xcccfce4b309ab156, 0x537ac8940592bff5, 0xe3c5e009807fc5e2, 0x156cbd7eb477a3f6, + 0xe6f9f10dfb0a0e55, 0x9aa6f4fc5664f2d0, 0xc282d86703523f3e, 0x0d866f100297c057, + 0x96271a76b8b85bec, 0x220ee9c693c7358e, 0xfa47f8b10c93c613, 0xb4fba10fff4390a1, + 0x63165b47063289c9, 0x395f03a242cf4af2, 0xa5b6c713ac181df8, 0x41d2f17efa58d9c7, + 0x50fdf5ec40e2b376, 0x4c77f025d92506e0, 0xa96f6f22cbcfe05d, 0x3c18da2177c52c1a, + 0x48a975ba65a2e1bf, 0x3bb086c0b07b6626, 0x0bc61a75cc2690a8, 0x3f5374633debcb37, + 0x360b219fd9dbb2e1, 0x3e1eed006207d5ef, 0x8a7a98a7b1a1c5c7, 0x28909be1ac7b48ee, + 0xd986a2f79e30fc97, 0x12878ac8e96f4170, 0xaeefc88149995f22, 0xcd0276fe5f26eb9e, + 0xdb5d423e2aaa46bc, 0x1edd91b23397010c, 0xd6aca77eb717fde7, 0xdb18f1b78e1ff7d1, + 0xeea1d95b3177c539, 0xf0cc9c85af103f7b, 0x3cb167ecd3923702, 0xd3f2a5a5b23bc179, + 0x13e21d46f2cb3f65, 0xf07d5cc1f321fd6a, 0x062c86312a4c7f07, 0x615ddff7f2970df4, + 0x65241783135029e0, 0xb101f721763c50e5, 0x4202b8ce089906bd, 0xef5d1570aad6665a, + 0x294db18714531e94, 0x7b6607a9a561c8fc, 0x1f580c18220cd459, 0xb23b9d691f8324b8, + 0x4aafbff9023c8df0, 0xe362350850cd3b5d, 0x8091aadd6467829c, 0xeb9798233a9a81ad, + 0xade8f49c225d73a7, 0x8c5b9908be4ec85f, 0x0fdc05d8b043bbeb, 0x563136f4e1050ce9, + 0x6ab29dcad125cb64, 0x11061ad0651a2362, 0x4c9b7c2933866073, 0x86a704d539e9541f, + 0x98c397bf90168d4a, 0x99ad03023406bb45, 0x4f329c4f82842e91, 0xc02ded3c6964c15c, + 0x6f5a182f0081c8da, 0x7805dd8633f78d42, 0x95cae82533c6d1cd, 0xbe4846508b648550, + 0xa71d8f622b54af50, 0x4baa7b8d2c8863d2, 0x9a089de4fecc8638, 0x9e29146ace0d1f57, + 0x272d9903b4cf59f1, 0x0f58f4628450bc7e, 0x226194b91d99d0a6, 0xa66770bb2b56bd89, + 0xda1d0210505e1cfd, 0xb5ac2893a624ffea, 0x2fb0b85aa830fb2d, 0x6757491e0509aa95, + 0xe4c696434742469d, 0xc0cd6f059d880fc1, 0x307c2a2a6da4e3aa, 0x60dd2949cad0e0bd, + 0x2a5298038acf4ac8, 0x9fc566dcb1bffea2, 0xf65fc70fc6ab132e, 0x45ce107d03829e0a, + 0x33d21576eb7fed70, 0xe57f35d14dfe2f12, 0xe76645d9f3b75b17, 0x6651f5077ccba481, + 0x8b9ae360daee58a8, 0x8552573e0edc7ee9, 0xd80dfe83e6c86e9c, 0xb26e29459e61e79a, + 0x818b7f9a7f93c276, 0x4f8137c31ecc9d70, 0xffb165b23a9b2a70, 0xc25875ddd191789f, + 0xb3625285514bb82f, 0x8f1273bd2346316b, 0xdafeb11694cc28b2, 0x2ec1894813e07f0a, + 0xeee61d38ed1b6aa9, 0xae7c9e7a5cc85d3f, 0x3785e7b4f7742af7, 0xc8b224bed3f745bb, + 0xd4b37d583dbc42b8, 0x8660726ff6f25145, 0x26bd6a404e1804e8, 0xe5ac91cc64a147fe, + 0x3985bccf95351319, 0x999458ac899eb4eb, 0x6a6ac63f7167e315, 0xd9e162a06b4e7036, + 0xe7eff0b30195c8ba, 0x07e74a3a0a9dc0f7, 0x889507bbe7bc4f3b, 0xba92d036f2a7bc57, + 0x5d9156aa97b2d908, 0xc91109d1f306fc43, 0x2b6514c30ace3f3c, 0x16fc59a56fa11ef2, + 0xcc664c2d18b83e82, 0xb297972dd36ca51c, 0x265f2daa31369729, 0x1e3a2f5a31842e10, + 0xdd6ca4635d4aa6d0, 0x4ca6779902250192, 0x27d8228666525d39, 0x45f59acd15482679, + 0x958f894c69386f0f, 0x1abdfb8c1f6e5756, 0xc69c1f045458a346, 0x38b3afe2052f8a2d, + 0x4078d5ee1feba16a, 0xf1cd4e923fd45df3, 0x69dd3722dea6e351, 0x158f3c258af81211, + 0x8d2bda807ebf6c21, 0xb8c1e6c894c26210, 0xcade84233568ff55, 0xe56c96e63d5109b6, + 0x2945b8751c0ba49d, 0x051f802f1fc88fe7, 0x8a75dd211340207e, 0xa8b92d8f2a8707cb, + 0x9644db650cdd2fe4, 0xc3d23cf03977fe01, 0x6313e1bb71dc2ec8, 0x246551ac3d8ec019, + 0x5b4a6c9528601bee, 0xfe75fec1b28c5ee5, 0xf72f66737b86f316, 0x7e641d40b204e42c, + 0x483ff8ea89e82039, 0x561a2303715633a2, 0x46719e9415a1e08c, 0x956efa06711ddc74, + 0x2d35ff2c23b9e65c, 0x4357b87531889ba0, 0x0a07811281787917, 0x2213ba4a2cb9b5e2, + 0x2b4d8bc6c175c597, 0x5be555e25a12c7e7, 0x6e18d7121915f99d, 0x853b74f588396a11, + 0xd093260fbf5f1f40, 0xcb53772dcd478dfa, 0x1302ea7a411dd070, 0x53f5068f0eb39908, + 0xb07cd5c3411acbd9, 0xd387e108ba20ce4f, 0xe8134b53e92f6f88, 0xc91dd324da5ee045, + 0x48acbfaef216ecc6, 0x86497dcff9b3c6b3, 0x112b22cea4bbdf2d, 0x1b70d2ffc21ceb21, + 0xcc158766af268566, 0x5d2032b51cd7da99, 0x4b30323c2d5cfd15, 0x2303a5a2aa2c1a27, + 0xb2f3374f6e67f51c, 0x28d0a0787fa49ecf, 0x9988874205a5fc98, 0xf2533549ef2b440f, + 0x8a7381ee3a0814ce, 0xa583db2a4d46ec8c, 0x2c5014909e04066a, 0x14c2aebbb2a7ff7e, + 0x66c1fb4a678bcca8, 0xf0fbe3adb69a2861, 0x1282af346cbc0204, 0x72b63c7d1b3170c5, + 0x92cb8940e7e6fbed, 0xdcd7146983b485bc, 0xabe59a87e152f788, 0x3dfe716b4775acd2, + 0x0f6aa6d15db1a1a4, 0x06a1b1ab965efdad, 0x20a1fb80b7010acd, 0x44c86034b4b4bcdf, + 0xbc145f8e5305e97c, 0xadaf6b26a18d6219, 0xf5c7291ba26290d7, 0x3ffab8a27a8db052, + 0x693db2ed8607e8b2, 0xc7e23d342e30d934, 0xd3488f4396b3ea6d, 0xa33b65aa667eed1a, + 0x8850ff59d62e729c, 0x0768907c70d5ab7b, 0x164ab173f43c6dea, 0x636ba832f1a21915, + 0xb1c57941918310ce, 0x4273508cf4cad76f, 0x13e1d3a9aab7e837, 0x6e92703feb9dee23, + 0xe10372de74e5f6b0, 0x48df1fe29f56d2da, 0x308607440f57f6c4, 0xff576bcd45645482, + 0x615c242c28a03db3, 0xf1c754bbcb2b5715, 0x0ea7fca5d3598bfd, 0x9fe34bceb9148ecf, + 0x51b8ff98c6e10c7a, 0x8943abec8e83bb57, 0xdc97e28a6f686122, 0x1ce3460a7a2afe2f, + 0x0ee0e9fb4843b9c7, 0xe5e9e9a943d18cd8, 0x640d5b5b25f7d5ab, 0xb81676035309fdd7, + 0x2b4e26aa6399404d, 0x70854bf02df5a358, 0x395d6d4db7f237d5, 0x2850189822c95984, + 0xd7ae9188d35e597e, 0x029b7566aef51ff3, 0xda9c9d207b36db37, 0xdfc9a89c2f358218, + 0x8c2cad92d5a1a985, 0x7c3801339827505e, 0x747302134eae3985, 0xfa4318c56ec0f773, + 0x388c4e7deeac0d5c, 0x394dbb17b16a369a, 0xf005a583ffdc4a27, 0x29954e8940b373b1, + 0x672bdc54378e354a, 0x942242ac97be2ac8, 0xba805662716cc7e7, 0xe5d67e0ddd2b1f0a, + 0x0f38fc56cfce6b30, 0x8935e4ce4b26b1e4, 0x88dfdc890a4e18c2, 0xad2b208bdc49e390, + 0x329eb6236ba0cbef, 0x3895d7a424dc7f8e, 0x8244bac2a36eae52, 0x28c3b33458a663c5, + 0x3e5cf117677841cb, 0xb42f3253c6cd1f86, 0x3e4e870bd9da22df, 0xa96c8ed9a585f0f0, + 0x3d00f92246666fca, 0x3858bc5803e19cd1, 0x4476d8fe1d390e14, 0x0d062e1c57e7e670, + 0x15702155eeed580a, 0xe91f5a8901624989, 0x1e7172ec72a681d9, 0x56b8f3e859603611, + 0xc9a997c286777135, 0x0331adbda5d96c36, 0xba3d91628358f466, 0xbf604ce7cf8e7cfa, + 0x183ec2b2815db517, 0xb83a079b7ddea6b9, 0xc66dd7c82bea6f62, 0x745332073b8c092c, + 0xcc806155f6441760, 0xc04b1806d6841186, 0x27a9ee4401e83103, 0x0d7aa2167cad5bde, + 0x883e309ee57d6571, 0xc0b22063ade52c3a, 0xaffdfdef083b7e3f, 0x01ffe2c38ed30c13, + 0x91aa83258d1ae08d, 0x5268c1ddca3e676a, 0x7f05f24d383aac47, 0x5a9fade0e33fd84e, + 0xac62336b9dc0a58d, 0x08475c00611b82bb, 0x25812e21f474079e, 0x3865ae99daf7d5e6, + 0xef5a1f19529f7238, 0xbf7c32bd1324ef6e, 0xeb7990cdd591354e, 0x0b7e9b3568c9295b, + 0x9b6a819ab48f66df, 0x447fc94665ebcbee, 0x5fd1f03c1820cf4d, 0x55be8c7a1c49002d, + 0x4f8fce645fd9e856, 0xfdd1f3a1179585e7, 0x0ff84dfe5538dff2, 0xd86cfca818fd5e29, + 0x5051a6f4cb8f1852, 0xd83099f031edf12b, 0xdc706daa54d16236, 0x6733c541fc554412, + 0xdbae200a9bcadb00, 0x30d6e2b46d1154d5, 0xfc7636afe105231f, 0xc5efbe0b8eb5c691, + 0x2fa645e788f9185e, 0x91551a05b32dd160, 0xea66cc726f1ed338, 0xe85005c70e5270bd, + 0x5b0282fe6eac99ec, 0x875f17d234da5565, 0x76f1baf856a378f7, 0xacb6eda56d8308da, + 0xa3faebab6fe719e6, 0x3193fee2814307fd, 0x12ade73dbe2e1cfa, 0xffcf5218052b80fe, + 0x2230127dd53288e7, 0xe3a1541c84e73ee9, 0x86e30597eb25fb9b, 0x43ea8e9e03580663, + 0x940aee3fc662a354, 0x8bc6247708cc2014, 0x4441142c9f724343, 0x66ec0c9038c88f34, + 0x2d9da13e78e5dccd, 0x37c374f0e412b225, 0x972e29a2b8d77113, 0xfbe2c8e22810bb1b, + 0x692728c169b58302, 0x366ab521e3db6756, 0xb2eb35735acd6096, 0x32e4b3f16c650eaa, + 0x6e303652947e2566, 0x2586049a9745f841, 0x5c28b4155238afcb, 0x960e7c2aab1acd26, + 0x1249f7ac43cf4ee0, 0x46220bfa88530db0, 0xe0e52f5cb657df54, 0x7a7f9d7615453d49, + 0x218574431ac3d76d, 0x36e51e9795e0ffc5, 0x8aa6663adfbfd091, 0xa116d08d09023191, + 0x51ab88f25e2149bb, 0x52c7435c768ef4a8, 0xe89cb1028057e2d7, 0xbd0543cea8e0fe24, + 0xaddb77fd1c72ce94, 0x93ed9589d3061377, 0x1f47f77afff3106c, 0x87daa2162a22a1b5, + 0x6e3e3527c8082abd, 0x800a6727ffe8a64a, 0x320ac9a4211d027c, 0x884337f730ec7d96, + 0x5370fb653a989feb, 0x8c64ad1fa81f87bb, 0x52d19955969af256, 0xa0a067470800a975, + 0x680c4fec6b788702, 0xfbb999858af0a498, 0x7848d5b86a9a11fe, 0x6939d3440cf72108, + 0xfa401ed34e48c849, 0xa5a38c9eb063adf0, 0x12632c9eb3b1e9ea, 0xba77e48c5fb1cf34, + 0x6f4291d533197e1b, 0xfa44065fa55b5536, 0x0a7ce048e22d4482, 0xcde9174db5f3c081, + 0xe73d378fa5d27c5f, 0x97e219909976313d, 0xaefbcb34d9cbdadd, 0x5f8583bb43266ec8, + 0xcdab1ca34f92926b, 0x575714eb73339bcc, 0x4a419d4a4d4dc3b9, 0xde33777e8e8f3e17, + 0x6044ff9d22d88560, 0x7d8bf7a6cd9a9d2b, 0x1ba6853ea2ea2f98, 0xe209ab75d012d925, + 0xb9a915efda8a090a, 0xeac7d5074c7adeec, 0xc5d31bca566340df, 0xbf77e4e09e458553, + 0x90f0bd0267addb93, 0xb322c412ffdc1721, 0x1ee2b2511ea85175, 0x3a68585b0f064e3c, + 0xf9d6ae07dfa30ec9, 0xe18282eca1ef9f4e, 0x702b952c95aeb29a, 0x111a774e8aa644ba, + 0x3ea15a430715143c, 0x0b81af2c78cbaab8, 0x31f3775db062ce0d, 0x9765017ded5e42ed, + 0x7f60536821ab902a, 0x06c14ed3e061f4bb, 0xcb398f5a59064dfa, 0x3d0d13df88740a02, + 0x51f55de210a2d733, 0x0df3166f909b5024, 0x7a3a913a9bcb153b, 0x4e9761541f28125a, + 0xcc5382c1ae741e9d, 0x1aee13d030dc97bd, 0x77da261184de2386, 0xfd9f5e4201c16cd4, + 0x31b6b8d02137a5a0, 0x243b7d5dd6922fc6, 0xdccd5ed34cfdf97d, 0x4c42a290733d094c, + 0x81cb64b005dffaab, 0xceedf9b0fa40098d, 0x77d66ca2919555ac, 0x5bf6d382bbed5b35, + 0x339d9e61a19ce4a1, 0x2021d282fd8da982, 0x0b22a0520fa29817, 0xa5f34976ae5e6dd6, + 0xbdc5155c0bcce6e1, 0x7e76c4b391f58bfd, 0x1d931d8f70f02efe, 0xd7157b1f9fd21320, + 0x6d615f9ac3752867, 0x0bf5ec331b7113cc, 0x30687c33af4d2792, 0x41fbc90331db3475, + 0xeb877a26450bb3aa, 0xdb4fef64835a5568, 0x1fbbcd70abef7f89, 0xda260446f2420d9d, + 0x4cae9ce772878a80, 0xff2cf3871b4be1d7, 0xa8d4eb3462ee279c, 0x467b706c5974af82, + 0x706555a72cc72f41, 0xcc1930f215f68005, 0x24ed7f635128e3a1, 0x68fd517d0385592f, + 0x6747f565375a2bd5, 0x69298f19e725c64d, 0x3cbb04d5e08cff53, 0x22794035b9e2c5ee, + 0x83cc3a05cda514f0, 0xaee0aa787caa608e, 0xb28b1442d53f59ad, 0xa86e1e51c1d9931e, + 0x795ad288689053e6, 0x31a8b13cad9577c7, 0x1c65400b1135ebb8, 0x5775ad86bbae2ea0, + 0x0584e703f6601337, 0x5a3518e6aa7b4c53, 0x8be31e21ce178141, 0xa67123ae3e53bd62, + 0x376ebedd521ffc5f, 0x6126896b4462aca4, 0xe09fb6a4da052f9c, 0xdada8122c9f201db, + 0x2cb076048551c57d, 0x7d082d365f84ddf6, 0x5add57c23da58b88, 0x0486d2a14560c05b, + 0xd4bebdac1df9b632, 0xefa448508476a8a7, 0xc011ca1dab569b7b, 0x2cfee31c3a41b44b, + 0x602767278f18adb6, 0x09e29c4fab06f23d, 0x1337024e5bf88022, 0xe21c1d17fb2f69f5, + 0x4f73f87e46b83b48, 0xcce3116630c17144, 0x419ac4e68cdad0ef, 0x6277222fdbb2cc81, + 0x21df68ad27035d3f, 0x6988a930239217eb, 0xb5327c50b965b9cb, 0xda106556517d8071, + 0xf221356608e871c5, 0x808265814ca8c000, 0x694921435e917dcd, 0x736ffc7b8d5290cf, + 0xdc222713ae236980, 0x873ae7df3e82c147, 0x952ecddfe474373c, 0x7f359e5b3d37ba48, + 0x97aae065f981e945, 0x9838f7271e38d48b, 0xfa6cb6b6775a2290, 0x34838de76b7be32d, + 0xb66bc528052eb0cc, 0x21328da6a3095607, 0xaad40ee65a661eb5, 0xc993d06eabd017e8, + 0xb63bb345c9d42405, 0xd7bce8254f75985b, 0x01929ccb2840f45a, 0xcf6b5d01a952ce02, + 0xd27ccae375229c65, 0x05a329ddf3a4f801, 0x399d2c0511e26eec, 0xbf0c6ed6ef76c219, + 0xc73c191c0810a910, 0x9aeea91be26c912d, 0x53566c9f2e26508d, 0xbfc9795a52f24a43, + 0x2a223429d28f207d, 0x10c75713c533c581, 0xd957dcf08527955c, 0xfda8a222d361eaf2, + 0x8866391cd948dd4c, 0xb032a7be57b7bf02, 0x729c073e996a61e6, 0xdc59b997046858cd, + 0xe9f91435e50eae92, 0x1778f3ddb80fdaea, 0xab346f663ef8e4cf, 0x9b6f5e5a3b02dc75, + 0x758a0a7ead8ed235, 0x2db90d15c3188e72, 0x50f39b5604ee576a, 0x65716847b8ad6629, + 0xe2aadc7947dfa9a8, 0x87fb38b0108ecb18, 0x0fa90a6125d31363, 0x12976fc4b5de242c, + 0x7e85f33aa17519ee, 0x65c91f8f42b5262c, 0x4a593245a36ad9d7, 0xfeaa9c71cdcf4442, + 0x20adcee064915a4f, 0x6b90a0c5bb62799a, 0x3a845f65e2af0a01, 0x2ddb7957fe6bc200, + 0x1601822c27493a1d, 0x94d23a0648d48a1f, 0xa6dcba0e0fed7693, 0xcb901cbd11e22bd6, + 0x2618b164f2762955, 0xf1fe2f884ce2d364, 0x01793b19600d5a3d, 0x0bc26b926b33ee75, + 0x4b7425346a7e533b, 0x05a4ac22ff302965, 0xae95661ff258f2d8, 0xb61edb9f9710343b, + 0x5da5d7da84112530, 0x2678f20158d5278c, 0x8cbfa163d3b22b8b, 0xd864ab3a2657f88b, + 0xf6b1cf066a96103a, 0x6cd75dc41f6c2f39, 0x3376ba9207423d32, 0x434f12d36a7153ad, + 0xad106df268673835, 0x880233bfd965a543, 0x6b1b21ce97a5de03, 0x61ad8ad7d6ac367c, + 0x88ce317dd953a182, 0x4a4dd162b6f0f5f7, 0xa82d7036142ec365, 0xaa72a4b4f1034a0a, + 0xdbb642fb44debfca, 0x4e8004f207df3da1, 0x3181642a5b29905f, 0x1481e9ba1981eba6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07c355675c42fab2, 0x415bc04c0bffe00d, 0xf2f7b28bba0e588c, 0xa78eafea783a3766, + 0x7ba2defd1316e511, 0xcb726b9ceda99eae, 0x35adac35c3c8baf7, 0x9a444260de1e5c0c, + 0x38a5261df7dd51dd, 0x1818f3a3a5a448c3, 0x4a9589257431c6a7, 0x8f6bb5274656878f, + 0xf952d8f932b512c0, 0x9712b336a52eaf07, 0x4d77d00a8060c5c0, 0x8ee0313f86442c4f, + 0xc650ab2105e8ff50, 0x0e39578ea735a125, 0x40fb887db6cf0036, 0x996678697a2c908b, + 0x6fa4f7d521bbf86f, 0x2bb7a675a06ce37c, 0x279b005eee88862c, 0xe468eb075c2ade64, + 0xbfbe3e333acdc97c, 0xb17f3a57be9eab3c, 0x4a322ff5c8867d10, 0x5b0fc19feca71c7b, + 0xf3f5255c51834388, 0x583cfa4a30aeeb4e, 0x81a3f1735b37fd10, 0xebc9e1c5d9a52aa5, + 0x4177bd7ef2e19c29, 0x850b0b3d28278698, 0x515aba5cd0ca9cc4, 0x1b638370496e6fcf, + 0xe7ddf6b5767c33f8, 0x9ebe1ed303f766be, 0x3561dc72a9d2d615, 0x06300d506939c4ed, + 0xc64799108eeb0a28, 0xf0bdc640aa68555f, 0x55b09b540757b2e0, 0xc9f54ca0479fae68, + 0xb0c8ebe4fb2a196c, 0x595fc1120f48328d, 0xbaf7a7ac23cc683a, 0x2ce08eadd56cdedf, + 0x3fc04d1823b876bc, 0x1b1eabd616f7e531, 0xc344ac3cc977e397, 0xfd2e2a4226db234b, + 0x5efac9a8f35fd1f5, 0xe4e2adcacc5c23c2, 0x8f6bcc33172f3e8c, 0xe97d2c45de43d2bf, + 0x61272acbd27b0d63, 0x1d99ad61cacd114c, 0x2f8c6aa1b4263b79, 0xf38173e91d8a52ef, + 0x2b52a08292c6d063, 0xde6cbb15890a6f49, 0xc29e12089f6d3e89, 0x11017bb09b5b3d0a, + 0x604cf274c0dabee2, 0x06281cf056306d71, 0xeb25683416837013, 0x3efdf365065781ed, + 0x4c048b86eebb7307, 0x22ebce902c95ca77, 0x67ff2beff123389f, 0x8e00d97138303f49, + 0x0f9a3971fedf4eff, 0x5cf538931ee9c824, 0x702c8ee3d3692d45, 0xbaf431d3a40e2e35, + 0x1873d77c3cf9da04, 0x804436aaf411acca, 0x78df47745a9c94b4, 0x39193503c95b65ca, + 0x95b5789d6cd3be5e, 0xf26388cf4e58bdf5, 0xcbecbed37ae91a12, 0x15a71279c58642e9, + 0x4ea9f6d4f035b778, 0xfdb71a80117f85cb, 0xa635e2109693e2df, 0x73cc95e6727b8aa0, + 0x93f49bf32e21559d, 0x5f8cbb71816ef6fc, 0xf72717722c62c102, 0xe6d07262e61d08c9, + 0xb2f8025846140897, 0x104d26c40529e9e5, 0x4427cfdc868d1f59, 0xf2f4c776091471e9, + 0xc8ba33a5434fbec6, 0x70d05bea9d943e3f, 0x41f3cd3a4e611642, 0x1be5336513a31c5a, + 0x587c988c859bd018, 0xac8be99c8816d54f, 0x0782f11bdfc8b61b, 0x43e37966f62fe707, + 0xa459ef2ca99eed37, 0x120950a1cd6c4082, 0x0eba43f8769b9b24, 0x093f5b9728079866, + 0x10a31805eb9fe4a3, 0xf5623fda615becba, 0xc969827680a0de5a, 0xe48c5f6bbe8f79ac, + 0xdf7b7603f7c879df, 0xeba5957195a1bce1, 0x2c84c1a809b35a3b, 0xeb743509c03e020e, + 0x82ca882448ba3758, 0x1a701fd756b5bd49, 0x14ebc45f46e2c6db, 0x5fa632b6c7d25918, + 0x6e8d3647a2c533aa, 0xae185268d8a783b8, 0x2b9d21af357aba26, 0xad6761d4d9acdd45, + 0x681572a35d43f08e, 0x7f104649952dce4d, 0xfe03cd3122222823, 0x5e33a7308c03cc0d, + 0xbb9e533bb63410e0, 0xa9f50ed80534405f, 0xc22cccf7ca434395, 0xa63ac45cff253864, + 0xe22fb5ecbb86bc4b, 0x6e8e1c3dea533654, 0xed9ad8f832f74468, 0xe87489c372c1dbc4, + 0x4a774799fdd71a47, 0x4a9a13c3be7a52ff, 0x3578a08d273a3195, 0xb509aa247289a1e9, + 0x2eb496c15e4bb70f, 0xcb97c42bab1f9b4b, 0x313389d7379df07c, 0xe32fe10a752996e0, + 0x833ba3b3d215c15d, 0x6da9d57dd0beb94d, 0x082d2acd84f2987b, 0x1907967226330448, + 0x9f272ccaabfc6431, 0xa88455770988b988, 0x407d6756fea62d99, 0xe82402b6a1551a72, + 0xf987e9c446fbddc6, 0xd96fd5b7e14fdbbd, 0x628bd803224c347c, 0x5be59b172a33656f, + 0x65a156ea78a0e57f, 0x0b34a6c35f1245c3, 0x51a6eeb210f30699, 0x119237f79bb77234, + 0x813b118050376d79, 0x7009ef7af96c4278, 0x5e95553aa30072b6, 0x5a22ce9d81f0f0da, + 0xe77107911afc19c2, 0xd895c84226884c85, 0x0b745d9e0d33a9c4, 0x52fd08ce7d29172c, + 0xa977d0b453f25569, 0x7d0460ad054ac996, 0x2665cadf2721248d, 0x1d8f1fc28b8ebbff, + 0x7da1692e579f1090, 0xe51a12e6cf183f68, 0x8d94b629e0a72b87, 0x9420cacdfead4271, + 0xbabbfca149408490, 0xf5af3b29ec2c4866, 0x8aa6a38bd6d08567, 0x29978736d48e5a59, + 0xc2e91e3517abe42d, 0x864a2302b2014b97, 0x37adb4b01e8b817b, 0xf05a507048d54105, + 0xdf93cc4136da60ad, 0x5321fadac1ad528d, 0x9d71bcbee0ba3d3f, 0x85e85fc20b17181c, + 0x5d2e8eadffa6224d, 0x924e702b4512cc6e, 0x7e4a8fa73b802773, 0xa63913abf4347ff4, + 0xdba52e31e991a09a, 0x712534969197a3b0, 0x5e96017b6a1cbff0, 0x17169280464d4319, + 0x9e48649cdad72f79, 0xc534dcc994d27ba4, 0x854220b067052144, 0x4dfed5000f59165c, + 0x1e8d9c98498f66e3, 0xad9baca8b5bc557c, 0xfcce4f3193440dca, 0x2e9e46de575999d2, + 0x3380e58860c7b1b1, 0xb01093059fd45b69, 0x0c83a1431da204f5, 0x2bf91e140d67f500, + 0xa1ec5dc3e03dc8a5, 0x6484df47f8934bb2, 0xe81baae6fe3f74d0, 0x4d1227530181d2c9, + 0xa856048776c54f39, 0x294025f08c6405b0, 0x02b4099f219e0d5a, 0x40f5655c31c1cda9, + 0x4455445d0f00ccfe, 0x0d6bfc09b49bb1c9, 0xdbf6a5e31fb5e260, 0x2222595835789ecc, + 0x154c92c18cda4e3f, 0x93565048d1be433b, 0xa3f528b7594266d3, 0xeeb6901a479c00f4, + 0xd51f1644b1072c9c, 0xda3b674a45728d9a, 0x89a0e380905e1d54, 0x860142b2ca1b057b, + 0x20d308af97b4a6c4, 0xb9599a5cca0fa37e, 0xf5b304089d405a43, 0xfdbcfbb63667f524, + 0x650cf5ca5d47d37b, 0x2bc4d7e87e3b5f69, 0xc86eecffbb24304b, 0xf2f07e4f74f0a46b, + 0x537538d1aa74fb91, 0xea958783d52a3df8, 0x324b85d9e5cdfa5d, 0x3f773ac0b8d8ba49, + 0x7efbe8ab3de15e88, 0x65db5222f09689ee, 0xcf2320b4c2eeb19a, 0x7b2bd444be20a1e5, + 0x360a2d43a7fa82fb, 0x88b70933b5c438a5, 0xf880e93ed7229a6f, 0xca8578d2197753f8, + 0x4cab1d53a14dfe2a, 0xca10d5abf29d5576, 0x169782b524220f9c, 0x36f84412c14d72c3, + 0x1d7d56517cf7efa3, 0x9643ee22e4edfd1b, 0x10f770e4ff7973be, 0x2a4501b56d1d597e, + 0x0ce73a61093f13c3, 0x288ba7d721a24b07, 0x41bbfc11d40f7e9c, 0x767ff8cf99d9ab7d, + 0x927b5382cd3e1f3f, 0x78edd79277cedf71, 0x9b6c1629bafcb03c, 0xf634e4da4f05d22c, + 0xffaea0499c12af43, 0x8e2bf3b1e8ca23fc, 0x805ede7228784585, 0x91fe25c2b449ef93, + 0x8248706ab8bcab70, 0x141b8580d5762e9b, 0x4daa29811599ff3a, 0x944e016838872565, + 0x6991a864ba8ae4c5, 0x5d32219ca425869e, 0xe684e448d7df0754, 0xef82d2c5363fd631, + 0xff3fad20c90f53eb, 0x08784eb4bf18ad3b, 0xc2047f72f07c06ea, 0xb52b33735ac55c86, + 0xf0537573a3658463, 0x894fd435d8d3d7dc, 0xa2c156b06d940a9f, 0x33235d40d70ab16b, + 0xebc9cdbf4f195745, 0x5ba562c8f83a75b1, 0x1f93fae34bcd7e82, 0x121900cb80b921d7, + 0x7b136207c520a6e5, 0xf960a391e69e634f, 0x13756b54a9c56361, 0xe21aa9129402a215, + 0xd8f6ead1e68763d5, 0x032a7092fbf14856, 0xf1d731f09aed09dc, 0x82c539df5e1925ae, + 0x15939949fc1475d9, 0x54c0a9f1810e85cd, 0xb890c5fa9a602565, 0x606213b450b25b39, + 0x4ceab2aef2643062, 0xfe062d5a55e42963, 0x653b7a7342a33dc0, 0xc38f547585302db7, + 0x1f3c1f71b5716432, 0xe4239ddd68bbb00b, 0x0bb2b79dd4250bb8, 0xa31aacfcecdfcfab, + 0x4631b3ebd8d35ff4, 0x30c023048a8f1058, 0x8e6df92e790bceae, 0x3885e3c85d036784, + 0xc63e3963f96538ac, 0xe454febab149738e, 0x0764ad5867cbc61d, 0x280218082feefab8, + 0xa6c1fc96a5f5739b, 0x9fa17ba32f881eba, 0x5b81234f418dac84, 0x81663bca6cdbb158, + 0xfa59c5e3b61677e3, 0x86a0ee54c5a235e3, 0x94c6422c035598be, 0x6578f84714001e15, + 0xcaba42b552a144e7, 0xb5cf4ce124a64262, 0x2d87eb1356597a10, 0x27773e324db78105, + 0x36ea6baa0ff9c0ca, 0xcd2f5eff3a43385f, 0x91f5420a3717f1e0, 0x4fe3e5b871ef8542, + 0x7e0e9268b7498de6, 0x371ea7ed24463007, 0x504919ec70981d9a, 0x62c6a4bd16fe59ee, + 0xc646ea6aa3a2b03d, 0x5a077f2f74f05a69, 0xcb33377858f403df, 0x832529aa61c5a721, + 0x90dfe467cee0fbe2, 0x20210b47144a75cc, 0x0b1ae992b2db5f6e, 0xb4b8dc39b0234849, + 0xd9a1afcad1702386, 0x0bb296ec2b07d462, 0x3d45dd88dae776c5, 0x51155c5c1fd3bf7f, + 0x44671ff960bafd57, 0xb55121f954d1ce00, 0x4389b94ff4e66537, 0xd6233fbfb29ab8f2, + 0x9f6611c511d46c71, 0x812cbb819c985f32, 0xc317d13502202202, 0xd0100d32ab2e25af, + 0x740f59f3eaee3d95, 0x0bbaf1d3c4ada2f5, 0x3fbbe3f0c3a4fee6, 0xe05d60cbfcba3d0c, + 0x7dc3646bec437eb2, 0xdb7ba9cf8e91eb36, 0x8fd9e7efb69f539d, 0xe4846b1099cdced5, + 0xc89ab850265eea44, 0x428f15e5aaa1f7fc, 0x31b09d06c49fd9ac, 0x6b9676b2fea38953, + 0x4f666f11380a5c24, 0xd5fceaf072de8a09, 0xbe30f3d6392e5e4c, 0x339bcb1751e6aaae, + 0x5a59a592827b4e5c, 0x7ed2e18ab6a9ea9d, 0xeeb6b982701abbfd, 0xaa0d5954c88d5ed1, + 0xcf66cd880d05ec75, 0x42cfd6b82a452678, 0x862b4c8cc8545049, 0xfb6b3b8bd9d06600, + 0xcf8476e93ac4c6e1, 0x6573c3d8bc5eb462, 0x121b0511c09e6b4f, 0xb8c2a8b149569f2b, + 0x054195501710b6ed, 0xc6a301d95f12d596, 0xf3647fe7fa71a154, 0x35c415615b1dc213, + 0x58dfbc6448257ece, 0xe0b0de4d149f1a31, 0x60f6eb813cf3f33e, 0xed0ab8658909395a, + 0x3f660f27fb17f9ba, 0x2f9a57b3855779f7, 0xbc7f38942791ab02, 0xa80f0fc16f1e6520, + 0x25eb3061a5e64884, 0xffe6ab993b893902, 0xf5d4c997ae375324, 0xced84c1907282924, + 0xa118f129900ecd1b, 0x713c1f936858c36b, 0x4b32be890d9f187a, 0x4c5b8d717d24e693, + 0x7466eef52da63196, 0xced99b862954b7d3, 0x341ec59fb5cde422, 0x48044f6490a76e04, + 0xb13de393d45c8f19, 0x3e301c6a5529f642, 0xb754964d9fca33b1, 0x8070d4ae753346c3, + 0xc7d132879aceaf22, 0x27bf4b619df7e7ce, 0x48afea1d5d9dbc12, 0x2ca19fc4be5f637f, + 0x0300e4b37eab631e, 0x991b33e4c712dc6e, 0x9b831a3f8b2f1d58, 0xc4f693eb59f7fae6, + 0xd0c92b5b392d6ad7, 0x5c362abf8d8f416c, 0x0a9d89f12be8cd12, 0xc649a656ca63ce25, + 0x75edc46ea6a39f7c, 0x14672a6aec4b1037, 0x8a3ffa4a87bf9299, 0x086654859e6ee318, + 0x2c60941cca72f33c, 0x97f8d4c2dd2854c9, 0xa21269d0abab0b92, 0xd3904841739f0ba7, + 0x929064dec9b9e751, 0xc5ba0b8bf665e166, 0xb3f4d04be94b1b57, 0x4bb231305763ae2e, + 0x3677f5ef041b3dd3, 0xea71091e90cae7c2, 0x7216fadcd99901ee, 0x68fb0c04b258ae44, + 0xc176deee606b1cd0, 0xf8f96992b2abe13b, 0xb3b822d0195830fc, 0xfbeeefe2f3cdac1a, + 0xf5b092b453ebefb6, 0x9142a8b4bc0600cf, 0x536d707ed12d8f64, 0xa61939cd1c67080b, + 0x174ca8a00e3dd5c2, 0x31dd2bfe5502123b, 0x41b675d73907fc2e, 0x075e60353f1683c4, + 0x7059aa41411f91f3, 0xac391c66cf314a89, 0x1ecd25bfc54b2a15, 0x527af4a4a01e89bf, + 0x6090a22818136231, 0x28db578c9d29653d, 0xc6ba5026c2217f6c, 0x7206aaf2eb528e7a, + 0x94618a7e05b9106d, 0x87cab40fcd9d5178, 0xffa1d3d7ce7f0aaf, 0xb8fa7a4c50fc65ff, + 0x3a9b129d1e3926e0, 0xea75978b12adf712, 0xc8c7339d535f0405, 0x051da5ab572acb02, + 0x6a5fe72e5fca4f9c, 0x84c8759994ec3548, 0x3282fa94e565793a, 0x894fee1c2021d2dd, + 0xc327ff53157ab5eb, 0x495ff167aaf6dffb, 0xa421fa71d4ae79be, 0xfc5a4ab4dc6a4c8d, + 0x7d4c8d1e8b49a21b, 0xf602d260536ca99f, 0x597b8cd0223af094, 0x2a2fdc6c16a115f7, + 0xbf35c485a8483955, 0x4bda25d8e3136ff6, 0xc05328b5dfeca9e4, 0xab044e5aa14b3c09, + 0xe9e1b45b7ecdf9fc, 0x13c13542b624a9ee, 0x13bbdd1d99a8c26f, 0x89ed324b5a61c4d1, + 0x84d74677b200bb7c, 0xaeb67feab084e765, 0x08bd2cff1f7aeff4, 0x1962f234ff964946, + 0x0b71598f3a352366, 0xb3d53df4c3fdde66, 0x9bf0c89627c33a6a, 0xd6254a82379ba58e, + 0x69d7d51f8ea08f3d, 0x3d025cbaecfd3dee, 0x29433c1825e798eb, 0xb78810d216912054, + 0xf49332cb438929f4, 0x1d251b8acd492d1b, 0x0a27d52c54c25411, 0x873c7f9f119945f5, + 0xb5f2901ecfd20343, 0x83735779d5bde027, 0x57ae2bd5938582c8, 0x79b28c12e4b2b528, + 0x2be25f50c0f4b7f5, 0xecfcf074008a21d3, 0x8d2acd4b31871cbb, 0x33308183ecc5e4e1, + 0xba3eb07e964ea665, 0x1b98ccc528363656, 0x167a4df346e596bd, 0x2b5eeaee31df58c3, + 0xf65ad1f5708f1d64, 0xecc45a9374e16ce8, 0x9460cce80439f790, 0xa6b99def7a0c8f76, + 0xe3ccdf10e3c8c1d0, 0x83a71537c937ffd5, 0x8dbe5b99d1b4236f, 0x447712fb9ee19fb6, + 0xa8c54d97bff6ffa7, 0x503d42ab2e813ec3, 0x98a328a75f11fff0, 0x31f4a4d2f4b51626, + 0xfa2f59621b55c727, 0x873268c77407da08, 0xbc092d739bf6717f, 0xd14a4d03eb1bed74, + 0x2fea03c691f9a08b, 0xb79b8c99f7a6a0a4, 0xea9c36cdc6ace8ec, 0x919c66534ee26c75, + 0x49cf948404c6be62, 0x0b85ad377a4e7f12, 0xbc4f637cc8789ae1, 0xd883507a53ce8007, + 0xdc203ef504371570, 0x081e600efa273f98, 0xfa9581421f24bdb8, 0x9ba6071abb4c6787, + 0x6ca17d841eee09be, 0xee16d1e5bded2363, 0xf7535a48e1772500, 0xf51845b4914d0907, + 0xde8aa3a8829c1c94, 0xff0ca8198347cd63, 0xfdadfadb575fe47a, 0xd81c1d94e54e02fb, + 0x246180c975975ff9, 0xf74a905583e268ae, 0x3f4832758a70dfde, 0x37a5b7f242248754, + 0x50f16fd99f754094, 0xb7945668450dc17b, 0xca3c56f582a97371, 0xb492de090622d8b3, + 0x7da03e49d2a58069, 0x95122e3449350cfe, 0xb10001bba01564bb, 0x74a2f09dd90228bd, + 0x44add4182cda37d7, 0xc79160f70e8f2ef8, 0x5935395691c82c0d, 0x7a196906e3cdc4f9, + 0xd609b71ce22c12d2, 0xcf80adcebe87a19a, 0xfddd329521e68110, 0xb923ff8069517f8d, + 0x45912f1d0a5d829c, 0x6171963b9088836e, 0x61802ca1a49b41d1, 0xa027581b5b6c9641, + 0xab1abb4660cdab68, 0xe69d7cff31c506bf, 0x61d4415d05f582fc, 0x87f3a6a022865735, + 0x4d0f9749157a9d02, 0xf3fda77c8e7ddd33, 0xb57deee4fec80d2a, 0x1cc39570bb3d3e8d, + 0xd319ce8f78d517bc, 0xae594278f9b320a8, 0x57b36633f1fd3898, 0x3575de7e454e8712, + 0xe9463a06e0ff1122, 0xf94ca1b51cbc3cd9, 0x5f75407a837bb827, 0x97e1bf1b54005bcb, + 0x4a9a1773dd8585f1, 0x0564290c8316c467, 0x2d18650babed7ff9, 0xd541c01078b89ab6, + 0x77ddb08ba50b3271, 0x8c56d6e4ecb2e0c2, 0x4b930463a8693929, 0xa934eb9718925005, + 0x6ff57d30224f4b07, 0x37c536ef1652eadf, 0x6061e51cac1febba, 0x0aae7b44511111bc, + 0xa9f24dda6511f77a, 0x7e19c9053bd340c9, 0x536e05193aa44d06, 0x27ecc3e976fde127, + 0x2f7fd90b91dcbcbb, 0xbbc1526489b43190, 0xa83c45ea3c86b21c, 0xd360e1924f94c12c, + 0xf501401bd420cbc3, 0x15f00e071309e990, 0x74aac7fdb0fd6aeb, 0xef958d5c7ba3ce11, + 0xc27338015b2c96db, 0xd97e6f37bc6269a4, 0x57442e207ab0d160, 0x7c199d3175e62dbf, + 0x51c9391b43434ddb, 0xc5dd3cbbf0196e96, 0x71106b773d68a77b, 0x5cd10e8f5c231da0, + 0xbeac7af35b880135, 0x9e6b8b9bff5100cd, 0x27f6acb61f6ea89e, 0x06a1f9c54b0bd35a, + 0xf388e07f2a7e5913, 0x9dca48fdc96b077b, 0x944e679752a33b14, 0xb50c3c6ba63c16d8, + 0x98db08bfdf8a6b92, 0xa782f30b5d4e2616, 0xa961adfd68ffc76e, 0x2299c3135a7e57b6, + 0xe90b4c46dba76b98, 0x29ceb64ca5a50a05, 0x37ae4d1bedbc9e12, 0x1bc940b5caa7649f, + 0x2ccd4c936be4500d, 0x8af64be5bf28cf33, 0x70ad6ac769cb27c7, 0x619f51de21c853ce, + 0xd24da5b0ca9b17e4, 0xa7ea3abe3857cbd3, 0xd8f8d06f4f3cb52c, 0x51855699896b8456, + 0x1311047fa2cc62fd, 0x53f18146434f8cd7, 0xa138488f4bf0aec6, 0xe45842a1fd77138a, + 0x9afd87e4c4593df2, 0x8d03154f03437eea, 0x91f187cd9c43b2e4, 0xf2ace27367cac282, + 0xd681710bc087aa9d, 0xfa75c5d8d8c2dbc8, 0x7a9472f0a2fb234c, 0x976bc1c19ebbb386, + 0x40643036296787d2, 0x9e9554d49965a5d7, 0x7e9c83c8e3666804, 0xee7edeabbe4e034b, + 0xc9ab6e54aa53e876, 0x38e3133387c9dca0, 0x2dbc3ea5f51b8038, 0xa85f96d5043e765b, + 0x314f4f1f438c1c1c, 0xc2814797055b0b09, 0x896f440e866bb908, 0x35c0a3d044a4b28f, + 0x1d396280104aa135, 0xaaf643afc9fe366d, 0x6789bfb61abc89cb, 0x8768c654787ac6d8, + 0x999b2f60ce2e09c9, 0xa9f3f84e9e995b3c, 0xd8cc77eb086d73bf, 0x0aa9cbc52a559884, + 0xf569e10d77358644, 0x2d01110fc1345106, 0xee49f1615281dcda, 0x484344a6c8146345, + 0x9d85f2196f0574c5, 0x1b2d5296618a6649, 0x316b3c5b14ebbfc6, 0x0a2e05b3cba4804d, + 0x427beecdbf0d6968, 0x1c7c7ad2defee37d, 0x9193c1aff049e3b6, 0x649f64f95396c262, + 0x1693d43e919f47cb, 0x6112481e72b7052d, 0x9b4c36c12aa0e0b5, 0x2602359dd8069e6a, + 0x682168faf88612ad, 0x4779ea1701a833d8, 0x404b6efce94b4ea4, 0x7868743585b323c9, + 0xf1c557b240831667, 0xa46b4ded73a9a7ed, 0xdd3b00b4a4aa5519, 0x4ee8213ff33accad, + 0xcb296ca84cd03e56, 0xb04cd70cff4d78be, 0x8f2c14ae182fb9e0, 0xa3774b41cd6c4d10, + 0x94f3a26cfb5bbf6e, 0x60dad561801714cf, 0xb37934e75c6bb046, 0x7954dbdab4f89242, + 0xcf5030e1bdb916e7, 0xff2d38a70aa40484, 0xc69afd71cbc56d80, 0x4c67b9d74d7c6e28, + 0x360ca35f01d07f77, 0x5020ecfb3a6f854c, 0x7c4b1b321901b909, 0x92d28bfe21dc2ce4, + 0x73eb188f8d116d42, 0x47862288c6c6bc80, 0x45749d12e5bd5446, 0xef0609cafe8824c4, + 0xb8dec881a5af9e0e, 0x521c4757cfea7080, 0xf01ae16535340db9, 0x7b7fb42c62c788f5, + 0x1a02db39b3f7511a, 0xb6411340eb09a82a, 0x8664ddd5b7a94275, 0xfede2776edc35e88, + 0xef6b78141132ea7d, 0x01636bb7f3148707, 0x74426c4f97b418c9, 0xf18ea401e22ffcf0, + 0xd00261d5833b3f1d, 0xd8608f49bd1fc6ea, 0xc0b5e9ab19e6111b, 0xf33ef5f1f5e79eef, + 0xf360da3b84700ab7, 0x10725acdb3b3c000, 0x23b636a137b8f954, 0x44072441cd9b8ce4, + 0x4607db3007ffc6a5, 0xa6b4959db19ae477, 0x7313ff7f35f33368, 0x1449b39ce55fffb7, + 0xea0d9ffa7c52b4eb, 0xf75aee7c389ccd62, 0xc65a816fd263d6b1, 0x3489c54fc097cdf6, + 0xeac356c3f510a73c, 0x9f11b59949d18ca0, 0x9731acf2f32e100c, 0x381a90b5895ed19a, + 0x66ffa6801f24fb14, 0xff7b2c1826805d51, 0x1d6aec61d3d1a920, 0xe8fb7010eee15dd1, + 0x51627650c042e2f7, 0x09c3a4345d399849, 0x7f7307f0c4e3b823, 0xa1f5a5e41a8f4aa1, + 0xe8a3e536aae3af83, 0xdd789ddc1df0325e, 0x1e3e6092a34f433e, 0xe8880bd3dba2c85a, + 0xf530ec1d4af3a25e, 0x77129d050c65fec5, 0x3f36b9056ac66028, 0x939e85a2ed5622a0, + 0x1885aa46e475de71, 0xd577d25b1305a0d7, 0xc153ae257863f8ad, 0x15990063a8b7f2e7, + 0xf8642dea7eac8cb7, 0xac72333d6d8a64a7, 0x9a3fbe907e1dc8b8, 0x5623fdd919d6a209, + 0x0b477ba3a4d33f12, 0x15eb8b67682dc072, 0xdf78bfb375ce6b0c, 0x157503212f873f52, + 0x1d779bae4a2e2214, 0xf5b763c3a2126cc1, 0x0db66216b3b2cc5f, 0xf5d0b11756bcf1f0, + 0xfd6d6c9f71b7fac6, 0x4d68a5d82964b29d, 0x8ab701d4200e47ca, 0xaa94b0803b3f3013, + 0xd26203a231c2081b, 0xcef69821eebb98fa, 0x097a91f788d69064, 0x2d507cb462361ce6, + 0xd6e924283fb06639, 0x8858a75c1b21cf72, 0xde9b9c572ee5c6a9, 0x83c9e7b91cbc3a21, + 0x14b9391b20e2de17, 0xd500d1af6931370c, 0x8c284559f0af8f37, 0xb6864ea0d5b6b247, + 0x1c530e657e71fcf2, 0xcfe282725f930620, 0xa17013dc143ae448, 0xb4403388fd3b5d6a, + 0xc289aee6d6d27ec6, 0x8bb9b8318166716a, 0xa0e83244ad610a88, 0xaae90e0d8f201f2c, + 0x2526df94de1b947d, 0x6bc49351adb0c090, 0x71876d378229bc05, 0x75521250085bb724, + 0x1a3f265818192b92, 0x8c2cbb8d57571867, 0x946782e2aa3977d2, 0x4bd1292a43a43e82, + 0x79b3ec406e040850, 0xf2aa3affb22f9dd7, 0x6b34d0a0b0639871, 0x2379f306750546b1, + 0xc181ab4c6a076192, 0x43bae37d638fbd74, 0xedc672fcdaae9f71, 0xf694d5b8fb58da7e, + 0x0ad18626dabf46b7, 0xddd6fea5c6cb25c8, 0x1035e0947c98aa5e, 0xea29c7bf6d145428, + 0xa3fbe7bf55c3d175, 0xe0e8f111ab5eae8d, 0x0e6ed5bfd9687fc3, 0x28cffc9882c6d13a, + 0x25f5249a723199ec, 0xd4a3ab18c9dd62b8, 0x060f1a6ef5726b18, 0x404ee876a4daf918, + 0x8f2f2e61017d731e, 0x11177f56286807a7, 0x78ea1a33e2ab2090, 0x122ff745948b4eec, + 0x6d2d191a8828436a, 0x30f793149e8f2d92, 0x2b5f88f5698e241c, 0x93dfcd50e53b36ce, + 0x0c3d9df357b83db5, 0x97b82a1889291278, 0x7ef4c1771a758f11, 0xa8c5e82c296a9b7e, + 0x7a9ee8834538ddbd, 0xa2030ce002f0aab9, 0xb6b3a5018d5a99b7, 0x483266f7561aa58d, + 0xb79c7a87fc1cb226, 0x7edb227e8a208f95, 0x2ad247cbf12442ca, 0xb2b1e890102632a9, + 0x4d73bff89d59935b, 0x995d93552678aa4e, 0xaabf1d3dce82a61f, 0x448dede27bea8ff7, + 0xd363fc77bb7f4dce, 0x7f6e4237403d3f7c, 0xed05209675517bd5, 0xc15a779dada4d7d8, + 0xe5efc52b4a405e5c, 0xc5a0204d0fe5f7e9, 0xd27c4f3c5d099030, 0x2ddc5140f77de47a, + 0x004232086e0fc7a1, 0x005fc09fb5cc6c4f, 0x4131a64934a4488e, 0x0ba0ba1836e8595e, + 0x57c824cdddb6794e, 0x04b16e94fe9aca3f, 0xe972c410cb99f56a, 0x639f43fab3280e2d, + 0xbe1abe315c8c7513, 0x13a1536d603805a8, 0x0125c01650de251a, 0x172ef571f64e8d89, + 0xe9570c6b6ad807d9, 0x54d06b31c88750f5, 0xa34efc63e3e2886f, 0x43450b8e0686af39, + 0xeaebaad8ef9ea28f, 0xfb52d7b4160ad076, 0x7d4f588481a5eff8, 0xf6509c4670b1f84c, + 0x8edc54a7a47ddda8, 0x50dac7fce0cb61c9, 0x34780bb80f0d75aa, 0xeb4e7389128aa491, + 0xe370abffeb18f495, 0x677ae6c03051c241, 0xb52b664f75400499, 0x4cc0c8aa4c3e487e, + 0xae40e7040bc031a6, 0x12fe650170e6e720, 0xbef268accf5c67ed, 0x0701f966ce8edad7, + 0xbd516c4468afac41, 0x8c5b5a82a2dab696, 0x4e0e1eb1795a8ed6, 0x78f6e3ad5a00eee0, + 0xd7cc9b7d5b212454, 0x5598df5d03824d94, 0x9b601143e93f0ebc, 0x590b504570e608b3, + 0x9dbce71fc31c6de4, 0x3bb039a859b0ef86, 0x997258878cdd6030, 0xb978eb476ce42d2e, + 0x55da05f107ef7f5a, 0x6bb0ea38b6d69b7c, 0x6fc71b51b2567bf6, 0xd377adf3b6ac828a, + 0x5ed21ccf2cf7e8a5, 0x3292f14881a89c23, 0xe97e17f63b786aea, 0x8aa80bcd041d5a5c, + 0xd1a7603b8e9fd20e, 0x601189afdd3d9fc3, 0xf250c7a7bd5ab342, 0x7c69c3f9bc4e1ced, + 0x185bc39e80a7a3e7, 0x4396ed5f0b9956cf, 0xd202722c63e08ff5, 0xe584df94ccdc38df, + 0x304251a5c1ee32eb, 0x01b17e0f300ef383, 0x274211af9c33b2a1, 0x4448914d9d6af202, + 0x21e5fb3f4535bd1c, 0x8a093a31449b3bd0, 0x148562d53b596caf, 0x36f4f185af6f5f2c, + 0xbc30ae54754991b5, 0x4d93cdd49636da1c, 0x7a5e728d74ce6ee0, 0xa02058d11467ca07, + 0x16f6127d29a3bbb2, 0xf2843f42ed6706af, 0x8d048506d42ddcb9, 0x68f022052ccb3178, + 0x3f8d96c146f5b28b, 0xc028c6aa4a8b1bb6, 0x2b3d12192a5e576a, 0x293a742544e966bf, + 0xc4e85429678c5dc0, 0xd57523a6d1b67745, 0x26bbee597832de0a, 0x56419cbd009d5d69, + 0x9389892c0f601189, 0xa5a743d56f1da381, 0xcda65e1673f41e0e, 0x1cc593bf5f0c7b17, + 0xc2fafbdb6c9eedc0, 0x3fa14081a06c6396, 0x68734c567acdc2a2, 0x171894be9eaca8f4, + 0x51b55b1b513828a3, 0x5f3421331bac299b, 0x57dcb6f1ef8c9502, 0xe351444ec3f9d1c2, + 0x8167b21ce6985bb0, 0xfe9a2550f12d3db5, 0xa641511ca07b6ffc, 0x05da8d888372e911, + 0x6d41d90394f6e962, 0xe2d097bf48b63895, 0x5cfe19c5ec930260, 0xb6ae3f36932ee5d0, + 0x7f1531ad502e2266, 0x43b790e41636e3cd, 0x7dc6e7bf9258770d, 0x63a33ee8e0aeced8, + 0xf9cc7500871fa7e8, 0x4c7497cf9f83047b, 0xd3fef7148855bcf4, 0x6eccb952443c4ef7, + 0x6ac888065d97c1c8, 0x1a89aff375ae83d0, 0x7785a23644841015, 0x037f6b63b0e6f8b5, + 0x89e4000781faff18, 0x77befe5d372c7edd, 0x1ab197860a57f695, 0x58153fa66faf5663, + 0xe951342e5b79800c, 0xfb511b946416e9a9, 0xfb0c662920dd23fd, 0x8b5a8a49a21f03a0, + 0xd6f1b879c81fbb60, 0xe8f60ead3cd62aca, 0x6e2f2bfb41305942, 0x04dd22fe89a4949a, + 0x41a847ed884b34e0, 0xfb8755857979a98c, 0x02fc30f5ea41b037, 0xba7ed475caebf079, + 0x88b2ee91dc22907c, 0x55a78fccdd43caec, 0xa120011a3eb21496, 0x986299e8ecaad90a, + 0x64ff2e577efea1ee, 0xd7e68c3cd75c6a88, 0xfed1cf367ada46d7, 0xa868bbea2ebd3211, + 0xc5795b5b7ee1a080, 0x01da333367c62f33, 0x05331456ec03e666, 0xff1c165034fd0bfb, + 0xfce9c21ebc30ed86, 0x4731569d73269820, 0x7bb981fb34e1ee6a, 0x117f2735358158bc, + 0x0f73b935bacdfabd, 0xb8642dcdc1e59341, 0x62b5a8639ebfc8ae, 0x0cf342d7239094d2, + 0xeab177cb5bed1cf6, 0x9c9c1d1a07b1cc49, 0xedb2a9ac8bcfda68, 0xdff0ccd208335312, + 0x7de6d0a9eb70571e, 0x9bfc0401809a726f, 0x856f4ca7b861f957, 0x15b2311ad9140289, + 0x81239a118404e0ce, 0x1447dcfd6f8740f8, 0xa58c9a6a6d7cd7d5, 0xd53c895eaaf0d616, + 0x8b6256a3ee46107d, 0x52fcfb6980c3563b, 0x439dc764ebd0bef7, 0x03bacc73eda935e6, + 0xbcc153c9eaadcf20, 0xa60633d86c79c051, 0x3d6c50cd8f52cfa9, 0xd146162e1bdfcc6a, + 0x03aecac15469fb11, 0xc99c26ffd9030ceb, 0x35e9edd2ecbf8c76, 0xf06cc73592bee959, + 0x8017c6f713d7111c, 0x64c9ecaabb7cba07, 0x23b1bdf4433065d1, 0x61fb4d8112e01db1, + 0x15042ffbd3c19589, 0x79f5d043303c20f9, 0x10c918feffcfb206, 0xfc9b81a82969b4fc, + 0xd4ee611f94e4ee75, 0x339373b001e745fa, 0xbccc5a2a97dd33b6, 0xe99965c23907dd33, + 0xa53ee25909211297, 0x37f074e407bd4a63, 0x60e5badcf6a0d5fc, 0x8983e358cc9d8a05, + 0x33dc1c8bec586b64, 0x6447492c217c6389, 0xed89f18255a0dafd, 0xb888dcdd08f08318, + 0x8ec6a6f67be2edea, 0x2954f3e8c14a96b9, 0xe436a39cd53deb38, 0xe1ffd6b9e4651bf9, + 0xeaac449460585ebe, 0x247aa3511ed40e30, 0xedb61d03bc48bcf5, 0x348ed81ed0a2b4af, + 0xa0d8240aba4cf8c1, 0xf2649e21195415ce, 0xd719775990ac82da, 0x6e170832d3aaa08b, + 0x55b38a0c52651c31, 0x270536c77c80f9e4, 0x817eeabc00c86ce8, 0xc1783ec713717889, + 0x4a73b469ab7e547e, 0xdaede620ff51f2fd, 0x2b935030450410c4, 0x4e63bd923e5a213c, + 0xcf43396052ada4c7, 0x65b0a601b176c838, 0xbd75ac1acdee2db6, 0x1485d84a35cc5ced, + 0x3928db777e3e2942, 0x8cea210888ee2355, 0x4a109349b31f2d5b, 0xa8c6572bd9918978, + 0xcc4dbf249e5e0dca, 0x53c20716205bcd80, 0xc4b8cc51d8e303de, 0x941ada77b253fe96, + 0xaf64e9f47f272040, 0x84b4854b134d0e26, 0x3af5f271d1204c81, 0x3788a5ade08693ce, + 0x3d4297593c2e60f7, 0xbb61f02ff444b1b0, 0x9f119bcf3e83c746, 0x281291e6860437b5, + 0xee70ac647b1ef93d, 0x7d0f85557cc68d54, 0xb784debeffe6a18f, 0x003b14e977a56c5c, + 0x3914a79eef4476fa, 0x3df92fe33f938059, 0x0e3e533988c66ca6, 0xda7982728096168b, + 0x18e67e0812dbaf42, 0x004d827b6d9079ad, 0x9e7dc26473112842, 0x46da68611570481f, + 0xe17a1c91d75b78a7, 0x0d3e0efff9035b1c, 0x4f8ef3a70a22f6c3, 0x8cecec8e729e1e20, + 0x201dbdb54a033229, 0x8c5ae49d6970f05f, 0xe5f61d0d00c27431, 0x5721952873a03b65, + 0xff563289cca9c535, 0x13e87627c43623b4, 0x6648335860854f6c, 0x7b7b3a7a5eb4ff7c, + 0xf9efc67c78eb15e6, 0x7c78ebec7c274d7b, 0xa9648c1ef64335ef, 0xa942a5681255d9f5, + 0x1805393c933ca7d6, 0xa983ece8fd1ec82a, 0xe671bd4355f35afa, 0xea0893299ac041ad, + 0x6a2715b0295f402e, 0x56487ce77b30972a, 0x4728f7ed6eba8356, 0xefef13bee61d5b7d, + 0x34d4256e67ddf960, 0x94ccaa12c3e412ec, 0x7ea32b73b566936c, 0x75dea816b4bf00f4, + 0x6bc0504a3f9f8a7d, 0x244453602feb470c, 0x83f2156980a6cca2, 0xa94773870e16bce0, + 0x2a9d2a77dd10abe9, 0x562e54279e4b3edd, 0x6354986f3249fb1e, 0xf65b8665150dab74, + 0xd7cc0465795f5f04, 0x9d23bb539bf16ea5, 0x282543591b54cc29, 0x5b897ac34ff789ae, + 0x242084c41a45765f, 0xbba90b841e9c75d7, 0x2938511d6fb2f070, 0xd89ee3e3d6ccb855, + 0xd1b4a58629cb9735, 0xc269c9a430b24104, 0xf38b4d2a49244eeb, 0xcedfeb6c3f96849b, + 0xef7f3bd1c507cad0, 0x906c8b8802f7e0da, 0xadc92bc8ebac8cc9, 0x4a4a578ad76c4d59, + 0x8c5e6028dde04dae, 0x44bb36da160466cd, 0xcdffbeaf0fa17ab0, 0x3055991b0b524b4f, + 0xb6f45fb682effc1f, 0xfccfd005ffaf49be, 0xb10d7b896fe48a3e, 0x9084ecf8fc3bd73f, + 0x1ccfb3bbab2e5503, 0x5dc751af02df5390, 0xafcddd397c49357d, 0xb0e435f148133e1b, + 0x27fde5bfe6ac821e, 0x30c858fe31232417, 0xfab29a818838f00c, 0x9092d7c52748242b, + 0x14f783eedaf79490, 0xdc8e1067d77e38a2, 0x9fe1accc6731074e, 0x42bc14b746c8b9d0, + 0x1eb0cb7b723a277d, 0x867287214641d236, 0xc2c9d17129f9be1e, 0xb802945975da314f, + 0x5f1ebfcdd121c039, 0xe557d65a0ccf5668, 0xb502e751db58e13c, 0xbc76152d59516b67, + 0x194fb2d2459ce81e, 0xed5ea24e1fd9525b, 0x936a5acbdf8c4962, 0x21dd0d1e2320236a, + 0xa85f41e52490f3ac, 0xf0807a677783e259, 0x76c7c99a9b7bf52e, 0x2edc18fbd505863e, + 0x740d89ab0d64df51, 0xb79bb8aac286f233, 0xd74c11411cdf719b, 0xdc8697ede5026c4b, + 0x609cfc280a2f376a, 0x11cb4a7d13ab29bb, 0x393534be1b3abe59, 0xddb913fccccf1788, + 0x06c30c6cb89e20b6, 0x81812aaa56ddd84f, 0xe80234684bfde488, 0xf2b0a42585e39765, + 0x61995a793132f5f2, 0x0e2d4ab5d1c9f549, 0xce90014e7a1471d1, 0x62f5ef2dfb81c050, + 0x951bfb8dcac29ef0, 0x2aa19d813bb73532, 0x495ad6addded0211, 0xd72ba2db89fa2549, + 0xcae43402853cd08f, 0x222cba94e245919f, 0xb2385e8de71a02f3, 0xa9e670056c7f89c8, + 0xd91ebe804f8a01f4, 0xcb878af7c64b5caa, 0x6d2386037453789c, 0xb73830b8e0fbf3a8, + 0xd0bf573c957440ef, 0x2a054f9b8aa14945, 0x4f54273a2b6ab238, 0x1e38b47d6aea79d9, + 0x9b65f7bcbf25a716, 0x6676703f34cbab1f, 0x49046e2562eb70dc, 0x461778471c103c11, + 0x063f6f192d03e19c, 0x135b04e2ad373563, 0x77ae6afec5a8dbf6, 0xad50801ab90ee4ab, + 0x9fb156edd25288f9, 0xb4ad3052a0cf5470, 0x0f46a9e66acce657, 0x69575566f44dfa0b, + 0x7f2504f991e00973, 0x8a58f288647f3f0f, 0x35553c4b1ba45d4e, 0x3782e5eda3fae009, + 0x09c4dd7ff3dacf87, 0xed3cecc038cb397c, 0xeb94823c2ee57f99, 0x4b14f4001b9a400a, + 0x63956ba83308573b, 0x526cb5b68d705970, 0xb453ac8d3408960f, 0x261979fe4336ae00, + 0x16bd76d36ea4b011, 0xb3271d5953206b10, 0x1857dd60de074176, 0xf4ef9963e48abd83, + 0x2e540c476bfbf6e7, 0xd7737a0ff4da2861, 0x6623e4c263ce8219, 0x3a516557e5ed80af, + 0x0737cdb03d9c7939, 0xf1ab5064cc1b6cc5, 0x91fcd4e0d815928b, 0x96efa390a5382976, + 0xd68dbfa2596186f3, 0x8e2e3c035bea839d, 0x2750f4f4a4ec9ea1, 0xa09f9b1a052e76f6, + 0x4794eedf23256de3, 0xb9e2c6739d3e92fa, 0xf40e01fba736554d, 0xe30504f4047b6636, + 0x1839d1e32f950823, 0x89b29bf43eef802e, 0x2267c949fe13fcc6, 0xca434c9dfe31372b, + 0x16b03c0ff36aff70, 0x885151031bfa6d69, 0xec3e0d9f4acc90a9, 0x579c662d9448e8a3, + 0x16c2d36034f87be4, 0x151bcd465f265da0, 0xe40d5715c435c9d6, 0xca9793aed648e2dc, + 0xe6ee0b88b9335bd7, 0xdae9d64410015f89, 0x9b4c98d2defb01ad, 0x87766dc8f34e1dc9, + 0x0983ddb12e5539a5, 0xa1733cf47b5c03dc, 0xdeb66bb4eec77478, 0xeadfb7ac78060a3a, + 0xbe17875db213cc6f, 0xb9cab450a85110b8, 0x74604bb9c75ace4c, 0x58ce786f564a618f, + 0x2ddb9396e5f30ada, 0x0efce46d9d25d804, 0x2b61552157c59077, 0xd73abc19a5fb7f95, + 0xdbdb82b1ebbb8532, 0xf17278ed8e0b877d, 0x06272e2990cb7c1e, 0xec8acd12768f7584, + 0x071ebc91a8eea51f, 0x865201127828b1ea, 0x869bb9d620026cab, 0x989135227568f878, + 0x44be2a84fd1c346f, 0x7618f7b56b55ef08, 0x23f76fc4cd2ad41b, 0x24c50176830846ce, + 0xddd7c001ba6bdb42, 0xb0a757845c71b695, 0x7eaefb0097d48d4d, 0xdf5dba8df87f6f3e, + 0xaa723d7a973286b2, 0x4c158ca43d859001, 0x3c26f5f83476118e, 0x31f8c964b088d75f, + 0x7442c1388a415599, 0xecc305bd632e4d3f, 0xc867575246a95a44, 0x257ba3cc634f646e, + 0x5fe5980ebb62bc55, 0x43d42c681d9c768b, 0x2f7bd571d25d78a6, 0x32c9cd0b55ebd7ad, + 0x0220eb9ae80b9e97, 0x8c485e5d9b3e3a1e, 0x3aae163461f6c691, 0xcd4c37da9aafbe39, + 0xb83c2eedc37e2b9d, 0xe64b70bba8027046, 0x09b1bb398716985d, 0x2035a34ccce99f5c, + 0x25ea1d19fcd7caea, 0x301a9163a4cc24d1, 0xb6bdf250e95da883, 0xf77979f601a3feab, + 0x2affc9665dbbbe13, 0xe7f2158c68550783, 0xfeff28df311c5bc2, 0xf09e9ee071bf9618, + 0xfd4b477cd7621616, 0xd9f3e0cbe4130e16, 0xae9f7f0e03ab32bd, 0xa38007b1fc1360a1, + 0xe7d223bd3dd2e9be, 0x53a260eace4cfcb0, 0xf5ff1e528c4289ad, 0x5d0c4fd16addc01d, + 0x2bcb91e78966d1e6, 0x9b0e231d41485eea, 0xf238e086c7a00e27, 0x058267116b7e80ba, + 0xf3515639aa8875f4, 0x0272477a6e97c042, 0xc064746238b98665, 0x00ab4a55a169ab2d, + 0xd8251ece9e5ad39e, 0xc5e643fc27343a8e, 0xd9283257a5ed5dc4, 0xa65a57217fb22840, + 0x9ce4ca8904dc3b40, 0xadd3d7d8c8aa1743, 0x58062575954de631, 0x50b70c7254413e08, + 0x732b3341e65cd8eb, 0xb56d0499e7e64ffa, 0xd74e127ed4f02d0d, 0x3c357838ef7eb72f, + 0x452d3e884ff9a34b, 0x3662bcce992aef63, 0x52749ec50f10a796, 0x8b1d1520d846eccb, + 0x19420772d004edcd, 0xa29a0f75e4049d48, 0xc20181d414496d75, 0xd70da1480d7b8ad2, + 0xff3f75c55c8ac488, 0x8dec7fc8efc1aaa6, 0xc89d56f0c3ea6e64, 0x9cc18c5d6d09ed70, + 0xa9c0f5e09d8aba58, 0x1c7faec11920a3e1, 0x00af9a3a778653ab, 0x887843d4c1e2f274, + 0x61107c3047018eda, 0xb3f32750a823c5a5, 0xd7efe3417c1b52af, 0xf8d4ed1f191c9726, + 0x8c6a470e877c778c, 0xe56c0ce0b746d329, 0xf24ec946e95ff2c2, 0x5affc47567a34fa8, + 0x7fc3a2d9be7f6787, 0xdfd2bf7a049a2d02, 0xa4a0663a3bd3aea7, 0x537c3282d7733f3a, + 0x5cb516a93c303db3, 0x0920de507d2ddc6e, 0xd79786e55b17ad14, 0xa4e57b0475ebe6a8, + 0x146622695e0fb756, 0x0a04b4637814a1ce, 0x129a0e718e1f44f1, 0xb88387c9d83a4a4e, + 0xa6b7f7c305d22bad, 0xc7b90d080be6b02a, 0x9cc349bc83e487c0, 0x14e9e417266bacb8, + 0xe1f23fac30799875, 0xf2bdded5177a254e, 0x5e6edef130e1b648, 0x94823736c393537d, + 0x8c6fca92016efa29, 0x43fe8deaac7dc3f3, 0xe2eb2e2e291bb81d, 0x07fa11e76711c23d, + 0x07bef68e0316143e, 0xd2b442eec1f81464, 0x9f7484990ecb4a78, 0xff8d5751fb769e17, + 0xe6495c158172e0fb, 0x765ffe80411e72bf, 0x5af9cea5ceb51228, 0xb6fa635bc1031923, + 0x5d4b0b84c2994105, 0xe0ece7e10903c9d5, 0x370b3964db811f11, 0x26a24152f26d4fe4, + 0x5e8eaeb48975de27, 0x521d43e12056e199, 0xd005e687e78b19da, 0x3ceed3fe542d2e9d, + 0x41115af35fe9b8bb, 0x071f5096e38ad3d9, 0x4a871ac86cf51d90, 0xb713cf3e9dd42bd9, + 0xf4d6a8a18630597b, 0x08333b1ab97ec1c3, 0x8d69fb82b6e4c7a9, 0xcc4c36e2a1865481, + 0x10812cec65496bb5, 0xa6500b88e2fd120c, 0x758d7c8b293b4c07, 0xae374f15a932b919, + 0x6230ad902f478a47, 0xe7325ceedc15b0ae, 0x3e29be7fcfe42bea, 0x8d5fce8ef9db0c07, + 0x196f9a2d8c50a0fd, 0x8c870532c854a494, 0x8596c8f1bfe6e075, 0x14d6d1c83e815e8e, + 0x8b06e8ac21427d8e, 0x1b0e19102d24e35b, 0x45e23b3afaf09185, 0x1e39da14e765d3a1, + 0x45b42fb7d3e81ba6, 0xb11b48aabb05f7c7, 0x73fb9a0c25534447, 0xdc3098db5549111f, + 0x22e86b8b7195350f, 0x0e54598750d5378e, 0x233023ae55d7432b, 0x5b951a96461eb6e1, + 0xfe9b9e0053a35546, 0x5d3d4fb9c5ca5e40, 0x8c65b93adcf92940, 0xac179ad45d451365, + 0x14de668d388aca85, 0xbad45d3c526c5e92, 0x42641b741231d72f, 0x46cd9cb5ce258c15, + 0x5f62e300d24f06b3, 0xd1f5de36ba211fac, 0x750a057b692bea0f, 0xef6e6aa15495f489, + 0x4b96c67d53b44e2f, 0xb08e626af7cbe840, 0xb66b3941eeca88d0, 0x48e713b7114860cf, + 0x5f44978380104f26, 0x612488f1ecbdb42d, 0x467787962994727c, 0xd97b966461428001, + 0x66a65971493e3bf0, 0xa6a09522d9711328, 0x601147e8f1dafd1e, 0x9ca063e18b54d8f5, + 0x7c2537345ede6f98, 0xc1742e0922274735, 0x005cfec0a41e7f85, 0xb7231a99b2dbee60, + 0x8ce87bbd335b5920, 0xeedbbf48d05428c1, 0x3c70f15206a20896, 0xb83fe5040eb3710a, + 0xb39c7391ca89d6a5, 0xfc49b578de256d05, 0x98e93e9aacd42850, 0x3df62a03c7db21a4, + 0x9166ea7dfa21a274, 0x1666421015c1f2b2, 0xa6dbba923a7aaa58, 0x591149e04c9267dd, + 0x6dd9458c9d42d775, 0x181645ac0ff68059, 0x0a7bfc178c68f5f8, 0xa1da2e544afe9139, + 0xc6917ff81cbb2fc8, 0x16318521af4d204f, 0x77615ac41afbb39a, 0xed7a0d43cd5c85a9, + 0x358ee0eda7e41f6c, 0x60f4b4dd83475c96, 0x14e5d47f74a6ce7c, 0x7b2250857de15670, + 0x6b5d20a1ed01fb28, 0x1526022629227e01, 0x83e90d59f7f2625f, 0x3da67a2ee911e928, + 0x21df0c044f36c320, 0xddbddf9ed2bfe0d0, 0x5134f9ccc2a89e31, 0x28ceed5009a7aaac, + 0x527869df0b1e7bad, 0x25d50d318ac2acdd, 0xde8ac7ebfb975fd5, 0x34879005326817e2, + 0x83e44d3a79091231, 0x07be1a3fe55da0af, 0xb575c32dccb444ee, 0x0501f51208bbdfab, + 0xb3468b909b29b88a, 0x699e4973a320dbbc, 0x5210b1128f7ab9b7, 0x52c8c08857dff90f, + 0x4f6d6fb47b042309, 0x7e8c9d86efd3c2a6, 0xbfb36997ecb2de53, 0x0b9fa5a495851970, + 0x4ac1f5e7c09a56d7, 0xa8ca17be5d667e85, 0x87f0799db344b884, 0x4ef0983f97bc9d22, + 0x450d10b35dabed58, 0x9e7a7012b3e13f15, 0x4e5de30bba5fe917, 0x7a782d3848d29398, + 0x6b4ac24428ee9622, 0x23738b0b1b2f3b43, 0x1499af1df676b586, 0x9482d4f67f42cd6c, + 0x87b2a3f71b679c39, 0xa0f1d1a19f0f5977, 0x5fef3176bca4a12a, 0x004f2d57152257fc, + 0xa621032aaf4a4b20, 0x05e160844e065947, 0x30b0309cfdca4d34, 0x29f0ff26d65a5c27, + 0xaa051d322bf45503, 0xe737564c7bca280d, 0x2a7b042869d82934, 0xecc188ab5fcfd093, + 0x74c144405b63cef8, 0x3fd3b7f0032d57d7, 0x01935a79173be745, 0x90b255e54065d987, + 0x7af78e14fe52d1b6, 0x9980250984f7a233, 0xa7cebe6cbd05bd70, 0xe569a780ebe227b7, + 0x0a7d065def620ba7, 0xc7a0c8ecd90c5308, 0xf6e95e3b3523203d, 0x8781c291a3d60dea, + 0x9ac50faa8f1cc56f, 0x6b17d102e2ea3987, 0x604c82db785bb002, 0xfa9f9b8ca507ed5b, + 0x65e992384db10faf, 0xa7edf4762f9647a0, 0xdcf0bb310facf5d4, 0x369418e966c2a1c4, + 0x2b1be9579df703e0, 0x49d8f9d01746dc95, 0x44b8310c23ca6c42, 0x00e5b61e395b2515, + 0x75e57fbb64029398, 0x745a56acedc8709f, 0x6c12521c7476376f, 0x5e65e4feb178c765, + 0x0c9cf19d77135dfd, 0x53cde4229c091035, 0x117fa0b28e31852b, 0xd88c8d7c6adfefbe, + 0x2839e639203c31a4, 0xa22e0e884ea9f046, 0xc84c8028254bde73, 0xf0361cc55860e83f, + 0x1670385f5e1ff11d, 0x933fa94e0bf00932, 0x512ac24448a7dd5f, 0xbc91fc4590ea02d2, + 0x2e819f916004ec7b, 0x3f8ee20d3dfab6b3, 0xee2e25f78fcc19e9, 0x9367230908c17184, + 0x0c47cc9e62def2f6, 0x3b86372b702c23a8, 0xdc875800f6e06e66, 0xac247b3cf9e93140, + 0x12fc066710b9ebc3, 0x40160c16595b0d53, 0x667a781446293639, 0x5b17a76d20a64dee, + 0xc70898985d183d18, 0x3ecc8fbe45117ba8, 0xa04ac07a05c1ac4a, 0xa1b564a3adf4522b, + 0xb40b1ae29b738574, 0x97e783ef55d058a3, 0x2208d331d934f0cd, 0xac0d9d11fc8ecb7e, + 0xe2f40ead55d78b5a, 0x777d44e79aabe146, 0xf51fb7e5e43752a5, 0xbf315e586ffe5373, + 0x7f4f5c24bb729ff0, 0xbecad2e82e507b2c, 0xaef19ea329314c66, 0x01deefae5bcf8955, + 0x46a3e69110ac7ad4, 0x8050cc46e81f6a2e, 0xe23ea3c75dc9f02c, 0xaa0e6be782eb4c4d, + 0xb7e1ad15a41ff532, 0x1abc5e87eb4e196c, 0xffdc6226210dfa5f, 0x85874e082f760f6b, + 0x25b2a77756493766, 0x4163963df3b8ec66, 0xc7724a8a13207099, 0x65b589357a4e0e92, + 0x29e25d6f5e4e5422, 0xa3e7d6ce6e961036, 0x14a11a960952d617, 0x21a19bf9242d583e, + 0x1107290466a96242, 0x58351b8c48285d49, 0x3e6d26ec3ddcd9c5, 0x29d5500236eb724a, + 0x2c6a1ea0d55143e8, 0x99e31f2e416707f0, 0xc8ebad87963d8951, 0xc4defbd455b55d99, + 0x58ce559185905e9b, 0xa9b5e1d0d25e14dd, 0x5b9da8b4baf4f25e, 0x2c103a95a72caa7d, + 0xa2843f742576dc81, 0x9949888b1b7b9502, 0x8205f8d6ca97d2a8, 0xa1869d679dce425f, + 0x5122de965a99939a, 0xc51d62f08c1f99c7, 0x07fb4ae2122e5e35, 0xd2e2a5f4c98dac0d, + 0xbe0fdd1b3a51eef9, 0x281ad85d788fa214, 0x00c0d926b3993439, 0x288a9d31d904ddb4, + 0xa6d18cb275e0ed98, 0xcce970a84b77dfa6, 0x7eaf4b92e235bef9, 0x95d428ff247c20e1, + 0xe46de494ae6c0a30, 0x382763d0efb910e5, 0x03ed5b7cca98eec6, 0xe7eb8c2f4fb28b03, + 0x99e5fcbd6614313a, 0xb2c438da1a500a8a, 0x945aa9d2fde89f2d, 0xc69e7e6f7340e236, + 0xfb3e6ea45c0712fd, 0xf8acdc63754f0e19, 0x4a6cc387115d01ac, 0x525afe02155664cf, + 0x4a55eb886dfa99e3, 0xdc003f306f7cd58d, 0x806056efe0d5d84e, 0x78342603ab82fd58, + 0x57cdafafecb37c0e, 0xcd2f05af513c2a69, 0x50bc5f2009524a66, 0x1fd8b246f1cc16ea, + 0xeea18db1902fcda2, 0x153136dd86636394, 0x7a20f66589fdc6dd, 0x9d6ce6af03186aae, + 0x81ada8a037c9895c, 0x1605ac778c98aa62, 0x2aa197bfdcb71e6d, 0xe909d6a41829bf79, + 0x51d4158e96e89936, 0xc1cc54d7fc94b4e6, 0xc1d7973f169da1ea, 0x584e3896cfbdf7b1, + 0x909fb070df873248, 0x143386edb8373213, 0xa099b7065cd0ec93, 0x734e59befa4195d7, + 0x96cbe07319a1e487, 0xd4f03d2baa527787, 0x2fe65067334e633b, 0xe9f95ceda80b16ea, + 0x08335c5e2d345850, 0x2e2ea894972c4734, 0x97f328f728b15d61, 0x573814bdb4f47c7b, + 0xbc9514f9b3748a0b, 0xc71180ae7e2d0201, 0x66dbcfe583fbac6d, 0xe2e9877c5bb9f60f, + 0x9fd0b2ab762e75bf, 0x8900daff050caec2, 0xb1488bca7f837720, 0x639f157b2b753839, + 0xf318234ebbadfcfc, 0xc774582fd74d8b87, 0x9606dd8f21bd4c9b, 0xb220f74a33e7f96a, + 0x3425d7212ce03db9, 0xa37ccff13458195c, 0x45a9e6b33b0c982b, 0x39c6cb90c80bfe03, + 0x6a8ef71b48fead7e, 0xdf03f474b88c143e, 0xc872829916a7805d, 0xf97a89600d5d6de7, + 0xfbf1cc411d522fd7, 0xabf421ffe7e82caa, 0x54a628ea76f82043, 0xf60a10899be8ba2f, + 0xd97b95671d91b318, 0x960acc11f7e7594f, 0x2e7caaa1429889bf, 0xb45e7efc6c724f28, + 0x77f7c37c1adc34da, 0xbc7fc73e5b0f8129, 0xfbfa375aaff5c54d, 0xaa78dcd469d7f096, + 0xc1f0cca311665cd2, 0x5df787be9b6fa3f0, 0x7ffe5573ea3354b3, 0x2025de5f6d78c68b, + 0x6305b1a7b4ec44f2, 0xb004132e71c67e6c, 0xe518abaa81beaaad, 0xa6070fa55ed3eadf, + 0xdaf3158fde77fc26, 0x17f8926dd445b308, 0xa480d86f3c4d8a1a, 0x6bb4194771bac8b1, + 0xd6b2b7bfb5fc35d2, 0x7fc81d56ced90f06, 0x75a51c64cf9b73e7, 0x673cf1c0e8ee6cde, + 0x0f677310aa4ccf9f, 0xc5469182718d73cb, 0x89a839f82233b598, 0x35b3053a9220a71c, + 0x60d881d5862fcc41, 0x980459f9503d88bc, 0x70e3976fcf6953b1, 0xfc05ae6b5594e694, + 0x48c01ca19fb825de, 0x3ec01f416081aad7, 0xd00145f3ee25ddcc, 0x22e663e4f14d0614, + 0xd1a209f7548e3b9f, 0x7b6cf86d91d9f466, 0x6402f01239accead, 0x90a7943722ce0d12, + 0x6c82f1a848351979, 0xb8a57d4c4fa5f197, 0x3947f05699d72d31, 0x3f4445c7376fc84b, + 0x5ed9fb236598b481, 0x9fcb6aa2208f7e28, 0x398dfb5fdd9bb341, 0x481c2f7617e5de59, + 0x4d644b2e8fd08dda, 0xfcea7a4300d36d87, 0x2a15a5500a8efc9e, 0xba321aaa7ffc4e78, + 0x04957eed8ec2c4b7, 0xe3ed4cc85a3d0a8f, 0xd77aee27926dc584, 0xbb4866537249bafb, + 0xd98f245cac9fbee3, 0x0ed33c207467ca2a, 0xae16c6687065de0a, 0xa86a12759912f08d, + 0xbec866c40e85e90f, 0x843ef7670483e6b0, 0x888bba618169c20d, 0x4101782db5df959e, + 0x05c6c544edb94a92, 0x7f717367731b0b7c, 0x7ddec76a6bf58d9d, 0x1390e7b61529901f, + 0xbcb1483f45d321a4, 0x1fab10cfb63ad2d8, 0xb70b69d64b22b0a0, 0xe69d3b8c7260484b, + 0x23fb0c0d36dc5518, 0x073e444ea4fa6d6a, 0x5aa797f7e5107a3a, 0x6e5f5fc67a2db45e, + 0x43b13259dfe7d5d0, 0xc77f6da16b443f1e, 0x00399828c206510e, 0x833026886da593a8, + 0x618aa9e989feab85, 0x1ea3d63e9721d43a, 0x83ef13f5eb2be60a, 0xf0869f84266fdc7c, + 0x1893f8f2d9ecacf7, 0xb349a3d4c7f40204, 0xf93bf9000eeaedc3, 0x61cc5bd23bb95050, + 0x542b4020c4ebf637, 0x894dbbbe32669a25, 0x29820e01b364c697, 0x3316f4f27d742afc, + 0x2b0fe91dd2c0e672, 0xf7ce562bc947d1b0, 0x94e46bd523fd4009, 0xce9fdf16c0fc722c, + 0x0240d5a6c8c8ff28, 0xa6605b9d2a52b1fc, 0xe8166d6c0b7dd182, 0xa23cf03207fcfe05, + 0x9e3512cbfbba61a4, 0x75cda01631f88c8e, 0x62b2fb7b4757c759, 0xb93103fad033eb39, + 0x39993eb95f7180a8, 0xf5411d11b4796b82, 0xa2d9c3d6bbeaf179, 0x59198832c7119ba3, + 0x2b42d6c9958f7c5a, 0xe69af361fca820e1, 0x1349c9761d3e8f8d, 0x74e7a9c05e11463d, + 0x5364c96723c71c87, 0x69e0194dd87ad533, 0x5b3f2d7adc45b2ad, 0x7dc438b33736bec0, + 0x1109cd7b873c3a1f, 0x5ea30ba931addfac, 0x2c1eb11143af0dfe, 0xf251cbb5b2026337, + 0x0fc5b9a72a7dfa94, 0xd1e030ae5a9071d0, 0xe8618b7b180df05f, 0x481bef31a552e2f8, + 0xb91fea6c59a35f1e, 0xf1fea7bd86ceec41, 0xeddc293cf7da8036, 0x972baf4f04927fcc, + 0x2ba9316fa11bfec8, 0x16ae3dc34341d2db, 0xb16d3ae9308ec0b8, 0xa372c1d885794d27, + 0xe2edef4c27508276, 0xf4fee90e85332b54, 0xd9c74de27a30e4fb, 0x71086d5baa88d300, + 0x227a4b083399f4e9, 0x6e4247a273906ddc, 0xab9a34b4d5ed149e, 0x284e86e4109ca3a8, + 0xc80f836df7049941, 0x56cb47560a6f83e2, 0x54206d439288f978, 0x62e3013a8d88e852, + 0x83e8978fd18cb744, 0x09468ef6a53d4d48, 0xc12490fd3261bc8a, 0x45955f4cedc534f9, + 0x48d186fb23eaf869, 0x5a4e4c517f370885, 0x459ef9b4b991107f, 0xb9cd5e50f562cd41, + 0xbf9955f83d5dd963, 0x2d0c4cdbfd944283, 0x7156ec54e08e1f0b, 0x1adeed7022f0437d, + 0x09d8615d697481ea, 0xc74dce830a16a2a8, 0xf5aa22fbd3c0c790, 0xf0624ae5f43b46d4, + 0xf42b58991d49ff0c, 0xd10d0dcb0f60af96, 0x061d3e5ac83133b3, 0x9c89241192dc2a87, + 0xcebd76dcbcb3afab, 0x5a54b8130eddf810, 0x4521e56e405661c9, 0x52455ff32e7cf7e4, + 0xcb0397b5d97d1681, 0x4553b6496fc73265, 0x310f98d2aec3ea68, 0x9daf2d679f7c4d14, + 0x47de6520216cd7ed, 0x16014a5c9ba65d19, 0x4d9b469b61277599, 0x196e3c0b487439e2, + 0x2cd8d5c921dfe748, 0x74472d3d39305259, 0xb7b7e9bafb492747, 0xc36c5100fcd02fd4, + 0xdcdb0a964626baad, 0x70018645df67d33e, 0xecb7acdadd65fc3e, 0xdc1dd19ac8e788d4, + 0xcb92ffbbfb192096, 0xc3f7f554c98a81de, 0x0a9286e341c21b84, 0xe2bf185ab8e23b13, + 0x0c028faa07916dae, 0x87096727d60a7162, 0xda3b97663f056832, 0xe9ce804bb4ae6075, + 0x5b5d70619428f9d0, 0x22b7fd23ac8e669f, 0xf4af78c412696f97, 0xa5ea97f2db089d3a, + 0x4658769f687bbc64, 0x29cddcfd04f80325, 0x944c540e1d6e78b1, 0x52ff5c972b52a943, + 0xf574dc9ba41126a3, 0xeea83c643431b537, 0x4ecdf281ba093778, 0x0800778d80ce187b, + 0x8967242c6cf4aeae, 0x91878a12eae20c26, 0x14d3a925783d3531, 0x082349d996dbe673, + 0xf2f944e0b56e7eed, 0x76c8fad969f1fe61, 0xce353e721e3b1ac7, 0x2e5afb3083176bc0, + 0xf706dc933b8bb849, 0x14b64232408b4686, 0x0972f0dbfe82803e, 0x530ad214bb15fa15, + 0xb9bb4baecf923b36, 0x0c2308fe46a9036c, 0xd3ac369efd48ae5e, 0xbed68633a72fbba8, + 0x40ae92877a36ce59, 0x8d313c01b40681be, 0x509772c82b825ec3, 0xdbd99f91ee22cf05, + 0x007e605938700115, 0xd524799dda2a677c, 0x59f9c93e8e6c6bfe, 0x54251e197ebac959, + 0x8054f281aa5c8261, 0x45e27e209c6dfced, 0xa3a6609a5b7af6f2, 0xb9097d4608c87968, + 0x9eb6d68825ce0e95, 0x4296d7658d1c7a9f, 0x3da1d4992e00a3a6, 0x285f4d1915bf66f4, + 0xc23d4f6ec69f5df5, 0x234385526d8bdc72, 0xc31c2d6527650e8d, 0x5960f839f9f84405, + 0xd2d1d5eb6c8f280c, 0x89e22f7b7bf0553c, 0x84c846cf494c0fd7, 0x23d055d765a11439, + 0x51bfadfee6670bc4, 0x1870430adf276f27, 0x1e1e360424275c20, 0x78585da488cc69c5, + 0x138a19744eca9f2c, 0x1dc6853290195c14, 0xdab3b91e91f5a896, 0x91f357700abcb584, + 0xe5d8cbef9c8ae189, 0x9b1cb4c95b0291d1, 0x634e31d664ea312e, 0xf0d68cbfbde5e685, + 0x446d0444a77f2659, 0xd834c80f95943138, 0x293b69aa7c18dd06, 0x7d4755e805bbb65d, + 0x0345ee777481ea36, 0xdebe0673faec3473, 0xfb52393a5d82a9c8, 0xc001543558b8649a, + 0x404c4b03ad3e37fe, 0xd2635aa468d84afa, 0x43828f9d5d476802, 0xaae632eee2c42b89, + 0xb3c8165eab686ee6, 0x5b7bab41baff23c1, 0xac24fee632132dc9, 0x972fe29d964cf4e4, + 0x2b94c88fd02d4018, 0xb0bffb2f2a4871d8, 0x0e04c522699204ca, 0x9b2e7ff95ec72ae0, + 0x9cac3b91aa22b72d, 0x2fedd4142ce64a30, 0x646a47d042f20d64, 0x1e01b20f8d57a661, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xeae3d9a9d13a42ed, 0x2b2308f6484e1b38, 0x3db7b24888c21f3a, 0xb692e5b574d55da9, + 0xd186469de295e5ab, 0xdb61ac1773438e6d, 0x5a924f85544926f9, 0xa175051b0f3fb613, + 0x9bf3db7629176ddf, 0xd53e73af2990e129, 0x5caf459b22655702, 0x0b5aa6d9a4f3b961, + 0xf08bf17067ab7ab4, 0xb47d3dfc9919b007, 0xc99b1c7de482791e, 0x01c94fe169f7cd30, + 0xacd67b0589d2fd34, 0xb4301dc813ff5f1a, 0x7207cbaddacc4994, 0xe513884525ac1b73, + 0x696ec6ca650d930e, 0x9b436ba07d628807, 0x4e3037e8148b6294, 0x47d72ba44b125cbf, + 0xe12dc16b1af7b8bb, 0xe462afca53893679, 0x4bac5266256f1881, 0x4bac6898cc267ef7, + 0x9b72c54e44cbb149, 0x91118de437092612, 0xbd2bbf39973dfc2a, 0xf87a708d05995f72, + 0xd89f0aac3015f5f5, 0xe00a4e47a82f6b6b, 0xb14bd14bb72e3df7, 0x6cf0cc6d6a14770c, + 0xcfe82c695515ad85, 0x71c9c10b26bc1b80, 0xada0c8b80b53b4f3, 0x4f3df8081379190e, + 0x06e5f650cfbf0f3a, 0x8a16ca569a88066d, 0x49bce43f1ebf929f, 0x875a1cd73c3ad071, + 0xd42b163d84d8329c, 0x011e689ac046145d, 0x11c16237db99c8b6, 0x14bdaba7279e9fe2, + 0xeddedb381b7873c1, 0x0f11359176f217e1, 0xdb4673bf9c4aa5fe, 0x74a16d739ffc4ef1, + 0x2c5b0a97b9f2aeff, 0x05483fc48cea01ff, 0xdd39518fa66834b0, 0x461c1a0eec9ac2e7, + 0xcf70938cb7fbf571, 0x6582a8c5fdc7cc40, 0x238bd05f48efad95, 0xf2d46f7ff8042939, + 0x9e7d750ad7986412, 0x565d868b0c5e74c8, 0xea0a38bfcddbcf31, 0x279afecd3833af83, + 0xa57386ccfe3412e0, 0x25c81c25518c48b7, 0x8d5453c6a6838e31, 0x0a65eb95c42c541b, + 0xa646cddbdd24ff75, 0xe263d512f8c0d159, 0x78ebdd6cfa1183cd, 0xa7f9608ef943b910, + 0x9cffe26a26df1775, 0x2313d0dd0489f4fa, 0x6e8b2f82ddbef4e9, 0x9a402af8a8256e31, + 0xa089368ccd7a39ff, 0x6945ec04c76f563e, 0x53a0b4c3fd6a4502, 0xf1f26ebb6e19d374, + 0xa52dee4a0d78433b, 0xa2d844fd070cd654, 0x3ab3a6dd4ed7a208, 0xe63dad16b8fcbb50, + 0xe4bcde97a1f3809f, 0xef85e12e9a402e7d, 0x963f671b9048f1f4, 0xc81f1798f0241d04, + 0x6d92fe41489cd529, 0xf75f52b15f3a033d, 0x374e926410a7abf0, 0x9d4408a6f98a7f6a, + 0x8ebae5dead848066, 0xfe07aaa7708c090e, 0xe2495b6f3c03abf5, 0xee10845bc81aa298, + 0xf8220c0c2ad081d8, 0x935a5d993e588f84, 0x33d47f6375269fc8, 0x56e8e7c3d1973583, + 0x8b59c97bf2445a30, 0x2498790a73c714cb, 0xe805b6979bc4fa7e, 0x41675b6f9af4916a, + 0xf79b5a2e2f40973e, 0x27401fcf90693f51, 0x0ef7abc5a44e8726, 0xa15cede03ce22cef, + 0x3ac2f43afc2f1887, 0x127200bc8ba31c41, 0xdb79eda4420607f6, 0x34265f10da810040, + 0xb31f128976abfcad, 0x2222c9521df3d54f, 0xe78865cfc3187eea, 0x7fb86a301c6648b6, + 0x336982ad7caa8893, 0xa5c42f3f65f30a38, 0x71db98d293fb7af8, 0x8d61fceee901f3c4, + 0xe2635a237d4a4505, 0x03e1698bbdd19995, 0x230886c9d850bf5b, 0x990aa9e5392db7f5, + 0x096187496fa443ba, 0xc187fe4fa992ff39, 0xded600baa9ed9f2d, 0xf0e36557f8a1ef39, + 0xa02a76ac60eea7ef, 0x0bcc6a1120649168, 0x28c10de4be120dda, 0x0313dd0bc49db21e, + 0x97ab92b0e07ec222, 0x9d8cce5b8fe9d1af, 0x8a6f218ad2a2ada9, 0xe46eeba85d809220, + 0x26d5ca6b2b854b72, 0x1a4fd16127106e65, 0xdcfc8c1b0de18300, 0xe82e25a8a26335a9, + 0x9bcdc6ad20764e59, 0x9c42f8ffc11ed9ee, 0x6d551f8e4efd74cf, 0x260d04d6bfbcf372, + 0xf16941ac2e8bae8a, 0x407b50c56a914919, 0x9801c33b2311243c, 0xcf826dab0d5ec9c7, + 0x6c2d1ccc08544ed5, 0x68570a7772f71e44, 0xb3855fe0b2b6b6a4, 0x782ddbe2cb51f53f, + 0x9b1d7157876d95cb, 0x31ced7d658cc4bee, 0x456d689c02c19617, 0x6b49082608d49c84, + 0x07aa834bb6514c46, 0x3adee3467da44d26, 0xa8aad9edc660cc56, 0x8876b8fe5fdb1386, + 0xa82924bc3c0c60d3, 0x4f6d695c3a042f80, 0x0c3fce41110e0056, 0xaa59d4fed7ff3418, + 0x4a99bd5518f33374, 0x4f330208d9104e05, 0xe05c9d54056d0f6f, 0x05c3210b869c9c19, + 0x7965ec2b73839b1f, 0x14d103eac5443f16, 0x941a6455b6373b89, 0xc61382ad217c89d3, + 0x82ad6ce15649e268, 0xec13335cc9c6b073, 0x95a8c223c1506e34, 0x99565767586f4f6f, + 0x53b3dd4c689fd872, 0x3096a25afa00b8af, 0xdc5f696a982fde43, 0x96d63e497a7127c1, + 0x1f8866214bbd9e03, 0xf17c38523a33bbb7, 0x0217ac556184040f, 0x2aa040fafe0e56f3, + 0x5413cad8ef31839e, 0x09c2e5b2df55b1ae, 0x372396bb472c7fb3, 0x91c56d4c28dd8b93, + 0xa06da020ce1b2a62, 0xdcd0bf3f3c872aaf, 0xcdc5c69d5a3f245b, 0x807e57cc6a0baa2a, + 0x90734f540cdff7c6, 0xdf39c3c40a9021ef, 0x60b4056df68e6127, 0xd2af8f5df9466f34, + 0x5e5463ba568a7b26, 0x9a541f5c3856a2d6, 0x0c6f26e3634b5d2b, 0x016bff3cd0d42b67, + 0xc57a7cc17eb98dc1, 0x99b1402be7403fda, 0x5e6a81ea77908fda, 0xd37cbf986a6696b6, + 0x0020d97bf5c65da1, 0x4fcb68ad5a292b05, 0x93e8d6472f1ca47d, 0x80f0b95cb631e75d, + 0xc2a5b3b28a5a888e, 0xbce7c6173dab527e, 0x68b3244089195d59, 0x0ce3da229a8f8130, + 0x6d2f307ed2dfc908, 0xa910a03ba7d18994, 0x85f40c97ac573df7, 0x6efcbb55bd0532b8, + 0x025fcc7ff49807a7, 0xf559611d0ec62f8b, 0x4e51fb987486f350, 0xe09d1352c26b6628, + 0x8f07a7c45fd549de, 0x2e36c9029ba77658, 0xa2f2482497f85cc9, 0xf70d4d3326c4ec98, + 0x65375895b7de078b, 0x4c9147353cce21d7, 0x61154c92f4657735, 0x8fb6aaa44ee46557, + 0x1045514a0a3855d7, 0x114d6ee9459a439f, 0x8af859115a8baf60, 0xf4e3d22e7e82994c, + 0xd8cf659bd03b99d5, 0xe762db71cceeb428, 0x1d0a34978cd8d362, 0x1a8b6a23906828f6, + 0x3e9e464a8eb80412, 0xff93b3661c9ef559, 0xd13e8df64a259323, 0x9509b89936670a60, + 0x6e842d6830a603f1, 0xbeb483c1f3dd7550, 0xbbdd4370a5bafa12, 0x01aeb2583a265a0b, + 0xba32891ca0f44f1c, 0x7227649aa72e811f, 0x42ed66730caddb77, 0xa745d2d46bbc0100, + 0x0d4b580ab4e70a73, 0xa14ab011635d537e, 0x6bb951e294a1688d, 0x5666eced4fd6e84f, + 0x50f060247550750c, 0x3184af8c1a9101d3, 0xb2c3fee458d21bf1, 0xd0d0a4af3e854474, + 0xb3aa46f99b617e8b, 0x34a16f76da10c772, 0x5f2ed357c8c70597, 0x0ff5f4444cc3b8fa, + 0x597391b42064c823, 0x2b82bab3f34276f7, 0xc4cd984ae478b494, 0x5c2b940d90bdde7c, + 0xc1dd881bdae2ce9b, 0x031ab1faae316631, 0xe5dc5f10ba1fd7df, 0xa282b69a9cc7e751, + 0x2fb96a738e878366, 0x49abc5d861c71a01, 0x2267bd7e7bbb082b, 0x6b57cfb38727382d, + 0x06caa4e0ce59c049, 0x80eb0d7862b82618, 0x6f1418e0f0034c16, 0xf2d585ee3129da11, + 0xf3a5a16a7a34e29b, 0xfa60ade62b7ebfef, 0x4fc35ca6ed5da985, 0x84ecb08dbb6bc942, + 0xd4191835a70a0cac, 0x1fe50ffdbabfa1af, 0xc7086657edb27d4e, 0xba1186b202677d23, + 0xfcd58c83cdf9573b, 0x796e556329970b59, 0xdf80434a01cdd77c, 0xb9031b96c694b3ea, + 0x10a067a88c56d56a, 0xeb69ac06ddb99c0b, 0xe2be9bfd03af657c, 0x33d01126bc1d6660, + 0x763e22d835975904, 0x678e4b846e6c3988, 0xd0cda63cc6d8db9d, 0xded91ce43c156624, + 0x00b62ae332763d12, 0xab251426c206ddf2, 0x967fc5fda820704b, 0x8583a2c9801f6193, + 0x3fd1489356c21931, 0x1923bb8e361ce9c2, 0x716f1085fe945670, 0xc76e74fd2f96230c, + 0x09066f90c1dd95e8, 0x12ed2e9edb82365c, 0xbaf6731e65f8b612, 0xa0ab605dd3b94ddf, + 0x9e6fcaa6ff165a55, 0x1d443b13fc522cdb, 0x2c2f4b6e9acbe026, 0x7a32f7eb753a5db4, + 0x30d33ce171f75695, 0xa82ef196ebbdf5e7, 0xeecd1be1e9868e60, 0xb3613db04b7c1274, + 0xb08bdbb15b5fab03, 0x766d5986cf0a63bc, 0x145bcc35160ec214, 0xc4dc582870a4865c, + 0x5b66e1ef3cc886f5, 0xca5861514a604952, 0xace6e4548eed8bb9, 0xe7958d13b21dc68e, + 0x37d29685e51062d3, 0xc1d318c6b7fdc6a9, 0xff474de9c462952d, 0xf10977a3ca4c8312, + 0x22a5730981bd9143, 0x20f3fb8d30921bf6, 0x66e3eba30b3187e3, 0x77a1531d0309fb68, + 0xc4e048b2171cf70b, 0x1d55fd8b97364bfe, 0x24913f443d2e59ef, 0x4ebb1a9f77b1b37a, + 0x9f009cd135eb62fe, 0x1ab9f9f9ad320e42, 0x38a953e6dc64b967, 0x60329de5f939ab28, + 0x221ef2c26e0c75c1, 0x2efa1c4f1669dd05, 0xe5297b4e71dd881b, 0x034d751855b27e72, + 0x480906aefd404ee4, 0x2b12e6b5d68f1f36, 0xbee7ac46f05bef43, 0xe4fba571136f8e16, + 0xdb6f6845c99c08de, 0x91a729b2702e8d87, 0xbe688461ffa7eb26, 0x4bdd07f6120a7b54, + 0x8de878a13c97c9d0, 0x03891c4d94872229, 0x11a1e8a0ca1c6eea, 0x58a4d1daa305d656, + 0xd9db45c25fbf0309, 0xe09e528aceec2900, 0x7049affee8ea5660, 0x66e4e8c2cae2e4ec, + 0xa8e24fcfe8d53fa3, 0x4fbe6c8dae1409d4, 0x5018e9c694839ac3, 0x562a7de68c7e1881, + 0x8d658e13ec4022a1, 0xacfc2409402cb30c, 0x8c4c80c111d8de8b, 0x8ad6a83dd6666736, + 0x198cf279ee2bce52, 0x925577459acf31ef, 0xf5a74b800e44c362, 0x203c37dabc0200e5, + 0x5c8ac324ce758ce8, 0x5f64ea62365bef84, 0x138af91003604522, 0x6a0669fa247ac124, + 0x723680ff681991aa, 0x2ae1248a776631a2, 0x30c2f7c42054d7fe, 0x440d965883444c82, + 0xca5a12119d809509, 0x5b96233a88e92e32, 0x3b3f33f5feafc4b1, 0x688d85b6162d56d4, + 0xde618b818073a554, 0x7f0cb30526e29844, 0x2fbd674d4a49403e, 0x8feecfaf7144793a, + 0x60ea472f6d160ab0, 0x701cf35ce48e4da3, 0x6aeae11045b054a4, 0xfbb8c92cd13c3aa1, + 0x4964a58ec91ad855, 0x16cebcab10c4b17b, 0x59c0128319181356, 0x7a97da113c44287a, + 0x050ef79a1a4eebe8, 0xfb7bd4b46ea7f75b, 0x4b517f6ac0ef31f8, 0xf8fcdd1d6cc9556d, + 0x32c04cb56a63abfb, 0xab96665ca411f943, 0x10250247d9332c0c, 0xcb4f0e321c1991f6, + 0x299776d9b4558a60, 0x8e011531a9cf1b9e, 0x33165eff1c645e3a, 0xbf5b572eb948a73b, + 0xa37ebfb891e58dab, 0x1d7bc09268e61cf1, 0x25d8508f797111d1, 0xaba25583aeb7de80, + 0xba9eaf82bf936899, 0x70f784a019f7d817, 0x920ac3630d8b4054, 0xf1a5d10321cca779, + 0x705c2c9025f20c7e, 0x41f7357789c4a593, 0xda64026442efe7e2, 0x844818444ec5077a, + 0xecda697b4b69df11, 0xcd0c0aad893236cd, 0xd4566c3fc5e7de22, 0xb81fee0c0cca4b55, + 0xc6f7aec14085ae58, 0xb4d879f05d4d6b4a, 0xe41bc026babae7df, 0xf0f13a0e01d1214e, + 0x9696d69b0427d127, 0x28b3b5047ba10de2, 0x38631ba6340ef020, 0xca4882ec5bd7603e, + 0x94cc68842fad1e41, 0x366bbd28a7acfdcd, 0xf28d3630cb87ae64, 0x02c2252b6eaef3a2, + 0xaa72f37f327bbef6, 0x191cf174404ee034, 0x99bfc0d4584d5fb9, 0x6fc646b4e6b6fc4e, + 0x22d6f8c4a73e92ae, 0x9ad5cda5d4804d87, 0xadda180b67ed9e35, 0x91272b4ae9a3d440, + 0x57f857b695b82ecf, 0xdabc49b2eb11692a, 0x71373b08c9ffeab6, 0x7c563b6055379455, + 0xb2fc097035ff7434, 0xbb7722ef9d68f875, 0xde1e852915efb28e, 0x48483957299d7659, + 0x51140a40259e55ba, 0x70f30a335279e6b1, 0x08c5f25a35c4d8b3, 0xe0018ba15f902711, + 0xf58d8ef5804a697a, 0x8024142ec7239bbe, 0xe75ef978815644ca, 0x5ba8cc73ad4ec2f5, + 0xeb6d07638fb7ac37, 0x319a996be50b108b, 0x749e64f9086afb21, 0x3074106e11f211d0, + 0x292f73cb5cc0ab0f, 0xfb353e18c4afe472, 0x0a04ef4951360f28, 0x0e208953f5402577, + 0xa8e7acfb3bcc80ad, 0xdaae04e3eab7408b, 0x05fa2bdb41a3299f, 0x4042b061e3cef2b5, + 0x1a2bbfce72308753, 0x989462e2891146c3, 0x620ff72b80078d34, 0x2cdfa69689a1d76a, + 0xcaefc67590a9fffe, 0x14e12331a0d49e4b, 0x3c504e6a928b9921, 0x3388d1f9e7a1db29, + 0x72859f2b9cc8acae, 0x368852a3899eb4b8, 0x3e0719ad45113ecc, 0xa2501a74de7a3473, + 0xa866043ab5b2face, 0x13ffac4c661b51a6, 0x68aba1110150e54f, 0x21d2a7edeccade4c, + 0x941a8a72b96414a4, 0x67c6a441d60083fe, 0x5b2238e90f1cc5c3, 0x760b0c5d2b9249b2, + 0x6076621a81c5de9d, 0x7d3c8db2b101d5ab, 0xd6329e970cea8175, 0xcc49fbf5caa71e18, + 0x781867d35c0bcb98, 0x6375fcfd1fd7cc35, 0x6a7e977ad254f10f, 0xd8fad55bc15f9a08, + 0x8ac95c67078e210e, 0x5792f1a6641e8bdb, 0xd99c4053f6327719, 0xdf23a0bfdd6c8a0e, + 0xb9a6661c005d0101, 0xa60839eafc06591a, 0xafae4c2f63014dff, 0x74e0001d267d05e1, + 0x0c735e460f029981, 0x64de0be874486089, 0xe8bfe428f59e4242, 0x8c40c6a0a7b44cd4, + 0x6f18632171d561fd, 0xd97719a394d22976, 0x2909c39b175f7321, 0x914f25bb8c9cff2c, + 0x82157fd5aa163bdd, 0xd1540ab6edbba78e, 0x415dec6cb0e65326, 0xa8455758d78f7301, + 0xbe92345f14868d3a, 0xe816a57c82535d16, 0xd395966f9dff8e3a, 0xe87578c981d74a43, + 0x09ebc55a32bbae94, 0x91912be6836ecd60, 0x34d326b51e42b410, 0xba7c8dcbd4b80b74, + 0xada3e066764e0258, 0xd17510cd254b4580, 0x6e66b73aac68fc98, 0xaa0a5e539a4fd735, + 0xf96077ba310a49c0, 0x812a2b1f78cfeb48, 0x84c4cd57d90bbf5f, 0xd830d15de0e8db13, + 0xa6a69e07a3b2575a, 0x9561f41b8dc11f86, 0x9b4a5a8cda827d2a, 0x9d4d907159d3d9ad, + 0x7f21cb643597c466, 0xf7d6bea2082d1405, 0xdc07986130ad13f9, 0x32ecaa8353e6e9ad, + 0x284061b34c13d1b5, 0x2077539cd76a12f0, 0x679b013539fb1893, 0xb941b7b488ef8a92, + 0x9a07a0b2ca64e77a, 0x573ff9b67c5521b8, 0x43a04fd427b48d30, 0xac2099118728e36d, + 0xcfd8d8f49b4f9f01, 0xa49f42accb65c8cd, 0x2f75c9cb9ddacd23, 0x095cadd8ed9a94ae, + 0xa0cd4ce9759c4c28, 0xfa96431b2a8d6b3b, 0x918ac0dd109e69ff, 0xca9c57aa266fd2e7, + 0x4ac8c493d767b3b4, 0x2800b4692d687c4f, 0xf0ff7c9794eac8ac, 0xbd55ecda9aa06f1c, + 0xb2a612f75b8e1970, 0xb77262feaaefe0db, 0x47e73caacb0f78ac, 0xe42434dc53e72912, + 0x6382d14927276575, 0xd1ac262861df1026, 0x1d99cc06718c3c47, 0xe717aeb79397a7c7, + 0x0d1e0e4c643c223a, 0x94d618110d1c7864, 0x64501fa2dd7cd4d4, 0xc42964df4caf4746, + 0xf458f6fc93f7e80a, 0xf13f558707d7294b, 0xe6d9a93d888d59cc, 0xf71c601dbf431d97, + 0xa11f3753622d7bef, 0xa9959d6e3203ed0e, 0x03050bd98ddd1fbf, 0x6f999826682aa7b7, + 0xe2d2120b40825036, 0xe8deaec0b325df31, 0xecb8b6a6061b290a, 0xe8aa723fe1b4c95a, + 0x54d162af219109f8, 0x6750c3517199cc41, 0x70a9ace837ddc93a, 0xb5b88206de68e5bc, + 0x0a38b0e43299957e, 0xab1c675e7446cf63, 0x6dd357907b12ce91, 0xc386f7c6ee1cf3e2, + 0x607971a75e3f8f0f, 0x3fdc591d5a1050cf, 0x16df0d0d90454012, 0xd371db3e374d3850, + 0xe8fa49a3ff272c56, 0x69e5ae3a74f13fb3, 0x0c0068a068f88280, 0x49e7101cd3ac2a7a, + 0x9b8a0b0334280280, 0x233252a76815d62d, 0xbdbddcbecf61ff23, 0x764cd6a7911c1dec, + 0x5733225cf238260d, 0x990e20ed9890a21b, 0x21c80647cd3361ce, 0x8b6880854bdd0005, + 0xd5b28b9b75fc85e8, 0x1710c3d83ba0378f, 0xb8d807694f113a0a, 0xfaad51da4a7051b1, + 0xa45db72027d53a30, 0x280e26638a233612, 0xa205b05c1f0ef9e3, 0x5bc38540b011759a, + 0x67d530d9255b5728, 0x5efd86e9048c4540, 0x8ebb9b506f0e99da, 0xb3f51265d01ff5e6, + 0x231c03e635a4e844, 0xef552f15c1eba62b, 0xe0e83d685703e62e, 0x8e5a4ee5c1593a78, + 0x4638afd3fe4e1eeb, 0xbcad9b673a7409be, 0x40eba35f305414e7, 0xd543bdc2ba151468, + 0x25a062fa1b42fad7, 0xf9b13970a7fe29e5, 0xe3efa3e7d6c8e226, 0x6bb2266735ae17c5, + 0x76743e4f11b27f3d, 0x1b5a4216dddcb631, 0xd840f4dfdffb7540, 0x4776cb97421ff2df, + 0x63dfb444db4293cd, 0x2ebddc65342b75c6, 0x8701f2d0f36178fb, 0x1c51959ecb1c5ad4, + 0x2c365c987c655b37, 0xe0f26f81ac37bdfb, 0xf2410bba716c0cde, 0xc0c8b49e466405c2, + 0x3d94e9711367f462, 0xc6fbe99363f49103, 0x8eeaeb3c5d40767c, 0xfef67a8354d69aff, + 0x830817a4fb406e08, 0x568a1dfdecbd95f3, 0x3ee240edfbef6776, 0x45bdda5512f8fc61, + 0x1fad2fd530f449af, 0x301b6791dcb2eb86, 0x478104bb20cb96d3, 0x39d20faf4b5b781d, + 0x9196558cace2739a, 0xd4812e1f6a22e6b5, 0xac22c499b6c9a8ef, 0x99e6f7c809f5f731, + 0x7afe3ad2fd697710, 0x87a708ed71cc19e8, 0x034c371483333c79, 0x49de6d901ebc9e7a, + 0x1aafcf1d0502ef55, 0x96a3e500b60d3e34, 0x26123e766cd34f41, 0x4de99692b8a81684, + 0x7998a64c87e60f74, 0x811d9139677371f7, 0x1a68a2c8f524567d, 0x8250aee9691167d2, + 0xe5f9369c26426b4b, 0x76c48f858762b114, 0x0d146641624dc64f, 0x521a913be1fc9c6e, + 0x4c8ebea64ce4955d, 0x7238f9ac21fade30, 0x4e9da14b37422e94, 0x403f7555150b459d, + 0xcbde6dbb7305cbce, 0xabaa0268da859a50, 0x99180b068ab66140, 0x91474cc85c7fc89d, + 0x66a84ab716d46041, 0xdd6d77cebd4ac464, 0xfadf0321b4b56d0c, 0x83b56ea8fc36cc0c, + 0x5cc59de34fcdd889, 0xf3280af9092a9415, 0x3dc7cb5f8e37a510, 0xf211eb93965882f1, + 0x3412b3727741a29d, 0xc3fe9f78ca6380cd, 0xf7ebb1b8eb800e4d, 0x80d65945e4fa1c4d, + 0x1df178b11b1dc04c, 0xc7aa27cd65da7f9c, 0x7e6a2845b6d84088, 0xdd8240183a74676a, + 0x8db28ba78d32b0b4, 0x0c451d8fe6b73523, 0xb34af14e8e378844, 0xe58d835f32369970, + 0x2094f6549027bf80, 0x6a03e5b67463215f, 0xf8bc1aff1afc7005, 0xd745037f94bb4001, + 0x88575f45379504c7, 0x3b25988a5b8ccb9b, 0x4069cec592d47d53, 0x2cbbf7cc8d353415, + 0x725da4fbbaf9b78f, 0x0242fd24935e9b26, 0xb40971211b5a7b92, 0x297e3bef4d242a9a, + 0x4bb4a0aaaf2857bd, 0x448c3b5030adc265, 0x2e65c5e13d40efd9, 0xd819a45a27b78abd, + 0x58d9f5a4cf282125, 0xa654c71298e046d2, 0xf4f57f544ed44706, 0xc04ae7c953e5d4c6, + 0x48d030f4a4ef0452, 0x2799919496695526, 0xc3cf18f14008c576, 0xf0e1198dc72fce38, + 0x33bbe17c1b99f529, 0xc9a7ef8efe39d005, 0x06f1a1ba2aa15538, 0xfd7a8f59241c23bf, + 0x8dd483497471a821, 0x1a04fa5eac53f608, 0xaf1c812963a96a86, 0x7984ad781f38febd, + 0x95c36feeb6e2b256, 0x52fcd56f8d7e0fdc, 0x9e4a061be97335b3, 0xea8936d1f7c18624, + 0xf66a08aa20bcedb3, 0x5073b3ae90088616, 0xc8d39abd1dcee456, 0xe2d061ddb2fb6000, + 0xadf334e15e7dd882, 0x394bfc5f6be72e4b, 0x6f37881ad32e7953, 0x90a254d5f61f8331, + 0x4478bbe1d7b61ad6, 0x63e473c4f2c7eca1, 0x0714897ff257f53d, 0xd938342812c9e8b1, + 0x139ead73be1afd06, 0x7445de40b1ab3008, 0x9ea93953b9f2b43d, 0x0e1bbd2927301eaa, + 0x51447217ae48146d, 0x5e446d4b40e7a3f1, 0x944e52bdaaee8769, 0xb7a6f1772b22ea35, + 0x33d40c6c67dc0875, 0x553b60f0f097fec9, 0x691d68d913260bdf, 0xf2e78e1e82670a11, + 0x9b367cd9553dc0e9, 0xcb2695f34fc667b7, 0x340610dcd702ef9a, 0xcb10bc9e24d7cb70, + 0x5789a111f099ca50, 0x701987998a9b2e37, 0x391b486d2ed7f931, 0x08e375982f4a7c23, + 0x7d8cc5092821fa8a, 0x10b2fdc43ce64ba0, 0xe37085b7dee94a4b, 0x15cd5cb23dcbe670, + 0xd100fb37993fe9a5, 0x22895b26d28a03a0, 0x3d13bef331a1707a, 0x5b687349fa78f208, + 0x968db6b956f8b7e2, 0xbf9f2de9428b9a52, 0x14d64e2377e6b58e, 0xdd8dc94458a21272, + 0x34a6cd9ed4e28f78, 0x75cfcf333bfb0b2a, 0x4c3d6ad0714029c7, 0x721465d30a5650ab, + 0x8b2e18e8e0a358c9, 0xc326187d48f97cc6, 0x24bb28bca196fd0f, 0x5533d96aea0aa39b, + 0xe27724e58bac553c, 0xf5820c74f70e41ec, 0xbedc74954a9f4e08, 0xabcf7be9eb0a912d, + 0xedba74e0f2e70486, 0x0dcb7e38833016f5, 0x61a3dcc8e2c38f57, 0x05359e0ddc02f380, + 0x9b510b6a935f11c2, 0x9e479f3d5363963f, 0xc135dbc98f45863b, 0x29006795f7081b74, + 0x04986d326e776522, 0x666c2b3f2d17be14, 0x02a796066aa411ba, 0x78357eef70a3154a, + 0x73e8632d15410857, 0xb3df50e681d36f62, 0xc08f06521f695206, 0x1fb5e193538dc744, + 0x31d6b5c335c447f6, 0x0963f588ca8daa48, 0x141df49b2865a791, 0xd241f40c8ff83d47, + 0xab5ee11bd28f58b7, 0x32749715a0fd116b, 0x75c1520d4422fe5e, 0x61d0a89c3e4b2956, + 0xa93a41d719f3f3ad, 0x74ac90f656868ee4, 0x39f40e285e898f38, 0xf2c95e94457de860, + 0x81e8666e83aa12cb, 0xb9a2271ba4eaab64, 0x7dfff681c9491baa, 0xa76af98b24319655, + 0x2dc0ff6fcb0ad706, 0x2f3cb9bac9166509, 0xc8877bd96d8f27e2, 0x8c7ff78e73251053, + 0xded45939cc99d790, 0x01edd811ba3ce20e, 0xf9f776f44e4a355f, 0x76f299d9251a0616, + 0x582f895c076c21a3, 0x1dcf4c3da15e10aa, 0xe3f0944511ecd362, 0x0d5b198cebd8eda7, + 0x4118122e6864e93f, 0xe6bbf73a8589df1a, 0x65dc1bc0548e9907, 0xd52817edf1de216b, + 0x6071d65140975f36, 0x7a79f7dcea535472, 0xafb749a013d9b373, 0x6af8d9d983b3028f, + 0x771ef9f7e17b9955, 0x68aedf678ecc491c, 0x9ba61910b5a45b38, 0x66ab19b350eed8a8, + 0x737bee9b61e2d823, 0x25aeb471f62d0ad9, 0x8aa871eb178f838d, 0x175c6263c5d3641e, + 0xe32714b53b2d7449, 0x2e5d0ee0485c9b67, 0xc80a759e5c221dab, 0x4d3bedb93ca4b3ba, + 0x6c3c8f60eca9b65f, 0x887a2d16f1cf4584, 0xfeefa866087fa1ac, 0x72953eb3757bd02a, + 0xd6b10935c6f1b736, 0x8d2335781bec23e4, 0x10170dcbffdb22d2, 0xb05b009a066a0cf4, + 0xf36acca25726c9fd, 0x57128b8e81753928, 0x5abf006f81e72495, 0xd9cbe1fadd3abc5f, + 0x5a91233b058aff61, 0x22eed41827ef19b9, 0x7b44461a1436f2a5, 0x85c89f30e9e75a3c, + 0xca0a7a1b405af455, 0xfc40a996bbf51c6e, 0xaf7df64ea7df2fe8, 0xc51af6ed5ea9b06b, + 0x63460d443e5a8a37, 0xae957ea45f460226, 0x686a7db719a5c7fe, 0xa60793025c3c01a6, + 0x1bf22a74882f9f3d, 0x602afc7610b8183b, 0x2bcad105e11c1e9c, 0x1763856c20844186, + 0x3256bffe3695c260, 0xcca33e4ba1e3567c, 0x54b6ef8db3b8e2a4, 0x14d0c6c042e314b3, + 0xb698be875dd42c11, 0xb6e212d089400506, 0xd021de2984d31f8b, 0x94f8c8364dbe13ea, + 0xf209cf1332e4bf80, 0x8f334b2802bf7479, 0x5fda4c370a978a8a, 0xa6c28ec6590bf7b2, + 0x093f45e90463369f, 0xd0c80f01c438179c, 0xf272eae1c920c8df, 0x1f051069628aed05, + 0x6d532ea42468c108, 0xc9f7c0b132c6e780, 0xd95637a9ca70d464, 0x6b888561ff4b4461, + 0x1a5d043244d61382, 0xfd12e59fe88a6cad, 0x9e2677d977c87f05, 0x679be9d8941e5116, + 0x334f8739748392f5, 0x7e0c2d86fef6a485, 0xe63fa47138d4e22c, 0xd9ce3c6d7f9ee577, + 0x08f6dcff59decfd1, 0x80ab2b041e1196d2, 0xc4a661c1ece4be28, 0x7e9dc93ca5a397b5, + 0x72abddfe452bc71b, 0x3193bd3dfd5e47cc, 0x9217a031f515c4c4, 0x7b13ca660df16a43, + 0xe9ad98ec1a9680b4, 0xa93cbd4d7136f523, 0x5ca2cc48894d17ad, 0x8b988d4b544a1bdc, + 0x702338808fc3806d, 0xf279ef6111567d95, 0x3053423b63fcb9aa, 0xe9fcdc59b74029fc, + 0xdc017ae6b18f15b2, 0xe7035b2187efd571, 0x4680b7071ed25ecc, 0x14edb94d391b6228, + 0xafba187b8de670c7, 0x6ab1e3851691edb2, 0xd82f0828c8d9e1bc, 0x9e90c1d129f70e9f, + 0x620c1095426d9eb7, 0xabcaff73f6fc12af, 0xf8572ed4d17343b9, 0x3e52f73530d5a11d, + 0xacd3691f4bc76a9e, 0x07a7caef9ed17213, 0xab1bb1a3c642596b, 0x0b2283d501dac666, + 0x7f688fec2165e4d7, 0xca4154a88b7d70f1, 0xac5c9ab32f46b80e, 0x22aab01de72641b0, + 0x3f44fd289f03661e, 0xddfbb3ae0b607592, 0x011b18b0798cba04, 0x2f489b6ba362c59d, + 0x21847c41e792e2ec, 0x11da7d848fcb250f, 0xddcc95ee7dc38bed, 0xe2ac1156dd72b866, + 0x726df81137f116fc, 0xe516c18bebb3e97d, 0x454ad087374cf8a9, 0xabdc72a894db3fbf, + 0xcc36391727815f12, 0x38d720511f6a53d9, 0x4b9cbf969b5518a0, 0x258dfd87d645e507, + 0x2a96eb3e3fc8cd85, 0xe731a82cf05e90b0, 0x07306f29089ff5eb, 0x489024507ff8d603, + 0xbbc45a6c935b9b52, 0xe32aa8cc3e53f09d, 0xbbb67bd44da9deee, 0x1ad13705b64c13d2, + 0x4e4d98e087d9b4cf, 0xae8b79449093e984, 0x59c4e5fa553d80bb, 0x1701bab58a7af1a4, + 0xa4061417a7c9fdfd, 0x4bd7bd7343ef8994, 0x99c4d50bb26095cf, 0x155624a78e4f3a2c, + 0x4992215f101ef1aa, 0x75ee42c932bc470a, 0x5390282afca5b442, 0xb2023c47fe233df4, + 0xd64c1ceca080ef5a, 0x3722b56dad48623f, 0xd87f2a76c439ae24, 0xd0823b29d8628920, + 0x96eb8bd6dad283a5, 0xf818072e58829930, 0xd2dfb229e9cf3ee9, 0x602471d22b439a43, + 0xe4bb37b1346dab0b, 0xcec1ecc625bcfcc0, 0x8ebb7dcae4cc9d60, 0xf6b5dc623778bb89, + 0x1e876c3341133902, 0x6ab18b75f23573f7, 0x9885a43501edb929, 0x550db363fd93b103, + 0x831940cd1697c962, 0x5bc6dfde5c3e7419, 0x26ebae1eed65c5ab, 0xbb57646a2f3a3a8e, + 0x3d7102b309e1719c, 0x2b9f3bb56b023593, 0x6cbca03822826f3d, 0x52f1535cfb177312, + 0xb986f6b15eaca9f2, 0x35a741f2bffdb5c5, 0x7fca371cab594e00, 0xcf7ee8c03c880137, + 0xed61d2c52f6a77da, 0x3050b21711c873ac, 0x7eedf740cc7853af, 0x7d387e25f9c473b6, + 0x195fe31416abcd2f, 0x4eb128074fc308d5, 0xdcaa5856b6a0db43, 0xeb764ca9a9d59ea9, + 0x1da220342d9bd36f, 0xdb93663ceb69eff3, 0x1a54646d49f1a3c6, 0x96499915ac0510b6, + 0x0c8fbc16f7fca893, 0x7fe4c77ab1625270, 0xd3e16bf639e44d4b, 0x4d53062add112a95, + 0x52891b721fce174f, 0x55c3871904a640c9, 0xd8c0cad62bd9f7cc, 0x408859c2597b2262, + 0xfc4b2adbb90ee5f6, 0x415eaacd634f85a1, 0x7133e185fe12c5bd, 0xd4154199c7402aed, + 0x472e22e366ae35c9, 0xf5f6707c24855664, 0x18209dc2dadd4a13, 0x62c3b42bacb3fab9, + 0x2f24d6b80aa57087, 0xe039e7732df76e9c, 0xf6f41cd0ce5036b8, 0x19b639668ed7d35d, + 0xdd75c423081ab649, 0x2be7d21b5d5a9b35, 0x43e3bca3f403b4a1, 0x4c6f940ade0db5d1, + 0x656206c5e5b5d89f, 0x60d2c339ce45c060, 0x27b6d6e155c5d7c5, 0xdce44e520b62e61e, + 0x143b074ccdafe17a, 0x8d436b02a9152ff9, 0xe18a593a0e66cff7, 0x8592e4df8a7b35b0, + 0xc39201f83891ec94, 0xb36af7f64363d1df, 0x9e4a541ff0298d45, 0x795e466c0882bf39, + 0x9c54741515ea8f6f, 0x4c4e3c0c4a303326, 0x6bda83f4f3e6d3cd, 0x668c565a42695f25, + 0x0ca4c56fc33ded6c, 0x2a6e963bf3062570, 0x90c1ef9d1d2be33e, 0x9093479023d1a563, + 0x37b3058ded2dab1b, 0x7a55d35491a5bc97, 0x22d086ff6e80386d, 0xff8b8dee7261f9cf, + 0x7be3abec5b3357b0, 0x7404e86b425bfb60, 0x188397c16c72b924, 0x14eb8615bde786ac, + 0xd234c2ea20481d91, 0xffb3fa8480b57e50, 0x0d9831591b83d7af, 0x38bdfbd19746ff3c, + 0xd0584ac628213de0, 0x2ff661657beb456b, 0x0653c28f2cce397a, 0x7b185b9afbd583e3, + 0xeaf4233af972f141, 0xce25850a7c60bbef, 0x6cd44edd5684f4be, 0x8f0511d59dbd2d14, + 0xd22ebba9001557db, 0xb028d524229b133b, 0x5de2a8c71e0a263e, 0xf80cc182eb5cdf6d, + 0xe39c9556cc433c5b, 0x5ec1b519805f5a54, 0xb799457309a3a5c1, 0xc1397b5c01da4187, + 0xe57a27d50b546a73, 0x5c9fed234b4bdd93, 0x6e2228bcc5a3c247, 0xfcf487edf8fa16cd, + 0xe86e88aa17957a62, 0xa9d62389ef1da2c6, 0x57d3799a8d85bd09, 0x973c185a7177626a, + 0xa542e7b1e985844f, 0xb1d010ecfb8c204b, 0xbb73a7577cb4933d, 0x42b70c4c01cb61c9, + 0x72854295ba34b1f9, 0x9f1be157a2ae9841, 0xecacc6be2e852d96, 0xf020e49d5a2f44bd, + 0x9c1e5c8cb1db7c67, 0x69421db1cd34f59b, 0xe083595e231dfcbb, 0xd453d34c8fdfaaa9, + 0x6e32cc038b107e85, 0xd1dd717d4d0fd2ad, 0x04e525e450038090, 0xd292012c3b978e1f, + 0x84e353973cf7654b, 0xd5d480a6df45f277, 0xf168f0cbe4a9fb00, 0xa4a4ba92bbf857c7, + 0xe954bdaedd7cdf39, 0x52f4f682b93bf065, 0x80ad5ebdce22226e, 0x8a48594769f445d8, + 0x69a2d144e3f8b817, 0xe06b7ff400eb37a8, 0x63fc741bfddb3854, 0x62de466a14d395f8, + 0x9948d98e9c5093a3, 0x3a0a330e8be12fb8, 0x1088e2b79541c7d5, 0xa848620fcd25ff40, + 0xe78a59fc927bd01e, 0x9870072664c53c15, 0xd892a6a74c560062, 0x509140725dfa1da2, + 0x455e1d8ac84a55ae, 0x5aaef818be798b9f, 0xf24bf81a7db4363e, 0x83588e6e380504ca, + 0x298523ea5e8bad0c, 0x53be8ff2729d2471, 0xe34a6099d8d1a5af, 0xf6f0a090edf46777, + 0xbf14daa2d24d5d40, 0x31fcb4f35ff341ed, 0x324310e487323c72, 0x3f59ae8e8ea23b71, + 0x00053b234c3701a6, 0x091f62ecd5141cb8, 0xb4765320fcbaceb5, 0x0de7d7ec2534f26d, + 0x374949c64f91debf, 0xeb1d31dcd3c1ab45, 0x10eaab326304d123, 0x10fc17d27f69e141, + 0x117d00050fbee7f9, 0x2705886402581560, 0x9d86293a0e8f4d9d, 0xd28e00f3014242cc, + 0xb2694feddccc30b9, 0x00e95064fadb18c4, 0x1bb66cfe7d5a1a76, 0x5af5825662b90d28, + 0xa435f18f9b04eafe, 0xba57a338179ba0fb, 0xbf53a57c39ccb396, 0x51350b4ac7878176, + 0x1658b5e3ce3ff3aa, 0x0e2620eb9571f828, 0xd0247ff4ea81721e, 0xb217fd43d43ade7a, + 0x81a418297a9770f7, 0xc931f60d899c9645, 0x35955f76469d9de9, 0xa4fa6954e442719b, + 0x15868e0ea346fbc4, 0xedaa623f9416ea3a, 0x89d69bcc5d8c86fe, 0x910a0a447205294a, + 0xe0cc9c02d7fe16eb, 0x4d15cff7bbb298ce, 0x910789de1e245e99, 0x8dbe3e2b0b599246, + 0xd9d3ef179f407112, 0x00fc0adbbb242239, 0x62658ef8726e86ae, 0x9f31ca8438d94feb, + 0xad9fe1d65577c134, 0x3a42bc2312a981ae, 0x7ff2ef52e962dd90, 0x6bfdbeec8df83b2e, + 0x6517cfa5f68e25c9, 0xeb39453af4da2602, 0xb255fb790901e5e9, 0x73a7b6e85177d5c8, + 0xabc55b5d03809c31, 0x0f68a7398dc0fcd5, 0x73d19b7b9bf2d7a3, 0x2f6e59f5b719e482, + 0x66a420077fad9e19, 0x56b60a2c3a94fac7, 0xc3bdeabdf9c9f3ff, 0x90e25f8538b17780, + 0x350f03199063f157, 0x9cd80475f40ad174, 0xd672b4a5db9ae180, 0x479a54a27e270ba2, + 0x4e5ed7b0d949c187, 0x2dffcaadf4c206aa, 0xd2d28140e5e25609, 0x579b7220574b8ed1, + 0x550248a7bff5b8fb, 0x43f6ec995c99e24e, 0x533c2f4932538704, 0x5c7922caec1d1e76, + 0x12bba099ec3c43bb, 0x03458a7c6ef1e6a9, 0x253af30575c22b74, 0x9243107add038985, + 0xf783272a391d95b7, 0x37f91cd4d7de8aad, 0x178f09ffca14dfa6, 0xfb96c440d1be4855, + 0x62e0c68cde14e517, 0xaf0f8a736ffff955, 0x5b732c4e40b8c04a, 0x00a12931d33ad2a3, + 0xd634097ae2d1790c, 0x0dfc9c68bbada50e, 0x964ba89c4a40befa, 0x6e49f32436e64072, + 0xa201cd81e9d971fa, 0x4d651d3084d2cdc0, 0xbec2bc43f1f5318f, 0x78c85a322a2181a6, + 0xfa6424e8d11779e5, 0x104f05160a0a09ac, 0xd587d4742feb1704, 0x295906d3991e6afb, + 0x644264f277dbfbf9, 0x802bf36168e372f7, 0x873f3ef8d554b8d8, 0x4669e41156f2f028, + 0xe68c242c30de8d0e, 0x008a7640e1a09a32, 0xa168338ae7826261, 0x5366e2ab3401f6a0, + 0xaa0a9caf5730e9c2, 0x51cb178eb7bb4e31, 0xc9b7e7c607e7edf6, 0x8892553095f19ccd, + 0xba8aa8bb50c0074c, 0x11fa65d939c324a3, 0x8ce7ef9838c10553, 0x21a4666c45bdb713, + 0xf2c18a9fdaf9e677, 0xdfeb786d8a1f30ba, 0x62882f5dc4f89c6d, 0x4fb9879dde817281, + 0xe9c022548ed40839, 0xac4b816632aad658, 0xbf4292f20b30cd36, 0x7fad5de659536a89, + 0x9080ac033208c856, 0x610132584e52c2b8, 0x7d33bcd2ea98a946, 0xc61dab2b60a3847c, + 0x7b3f8471a4702f78, 0xaf39027b4e941f0c, 0x294ea8a1f64609e4, 0xf22d574d235fc103, + 0x04d1d4641e229e97, 0xc55dfc4ff7af42aa, 0x29c02f8d5e0bf64e, 0xc74b949ee63ba8bf, + 0x452bac800c69cc45, 0x2ac84fce7db10dba, 0x4819edd55bcb11a8, 0x91eadd288c8c8af6, + 0xadd8adf54c069546, 0x1a2374246693b29a, 0xc086d75c7c2129d7, 0xf5a5dec3e5b927a8, + 0x3a272b0872c87832, 0x553a3eabb88c047b, 0x4d43a938995307e4, 0x17f08fbf1b9901d6, + 0xe0ed1122df136f38, 0xf6eb9d131fc827cd, 0x5801bc12130c5333, 0x5ae4a3a272888093, + 0x7c0a5698d339e33f, 0x93b580b83d5970ff, 0xd7796ec330f5a152, 0x1c87dd3b58e5ee30, + 0x1b34c919b57c56d8, 0x2d8be02d1d162c22, 0xc2a02c0bbe458d40, 0x18f7c40a4a4916b3, + 0x39d3ef756a2b2439, 0x9de0ba8bab42f446, 0x0656d078335cdbbf, 0xdb09b8f348a9898b, + 0x149e13aed09c8d9c, 0xc83deb62cd385bc1, 0xa400f82b7ae309cb, 0xbbca0d37ebc98bbb, + 0xc67bcb23609d299c, 0xe0e9becc7dac976f, 0x18294acfbff04b5c, 0xc6607e3885bdee95, + 0xddbd5e621a3e9c30, 0x6d3020dc030f8439, 0xb8f6df6640ae288c, 0x7d5dded44821da6c, + 0x30af10da52909708, 0x4c32b26320f00b36, 0xaaad1fe447c35e49, 0xf74ceb4df8f025f6, + 0x59fd4626afeec408, 0x899c8838c220b8b5, 0xe549721a84e59a97, 0x2d31625fb2ac6a2d, + 0x24236d521c45b698, 0x09878e523a2a1241, 0x80acd8496b2e9244, 0x9d0ea104b5493bbb, + 0x8c01af30ff9d1f70, 0x3ead7916f9fd9ee1, 0x7108f122ea443986, 0x66992a41bb69479f, + 0xf8242226c1debf73, 0x688d016d716a9ce4, 0x1f7e260bbd32f7a1, 0xe7fecda9ac6623c3, + 0xfba572875a71926b, 0x8d20cded51073183, 0xa73c9a61f144f64c, 0xb6b02f83308c8107, + 0x89b02761718d50fb, 0xf3a517e0a780667b, 0xb7c0d040ca616d53, 0x429c7ed34129cb00, + 0x90677fb30dd259d8, 0xd2381b67fd85c15c, 0xbe1950ca5b37bf2d, 0x03092050ca240232, + 0xec8f36851a434ee6, 0x082ee7de4087803c, 0xafe7c9eaa0f3cca7, 0x09996d59a1c29ca8, + 0x0f5ff43cd40b22a7, 0x60aa3885ad3cde40, 0xe905e74ec3f7e69b, 0xc2b85130fc9e9fe2, + 0xbe81a881840c9383, 0xf2bb1f37828cd9e1, 0x8f4e68228671ea9a, 0x7b3b646dadf43dc9, + 0x6e3b59f12d0d8614, 0xaf795a84f64eee80, 0x43b51fed57b31aa3, 0xc033a7a7d10e0f46, + 0xa84390860ac6ff97, 0xe6ff062b0e92bf21, 0xfb770ef9cf477968, 0x03f4a24b532e19fb, + 0x9ebd43fb08421dab, 0x4aed55cea91de6c0, 0x7ff519ef50f3a92d, 0x67895e7271b8a4b7, + 0x4d8d36fe5eca2399, 0x314e1838c9533761, 0x29e37ae72dffda3a, 0x5380ebfe11e38dbe, + 0xf8b15213c9fea179, 0x76d1e37f22064cb6, 0x20b40168b07eec4d, 0x5dba597ff1c18802, + 0x8c2939d83a159afb, 0x87636dc7be8b98a5, 0xa9a57365e589d981, 0x321b276179688c5c, + 0xd1b157a294e7efcb, 0xbfa0ad06299cc236, 0x97e9254ef3bac482, 0xbe380ac48382c6a6, + 0xde73d9f9b0afab81, 0x49cc7ef3d4455900, 0x97f37c847d7bc885, 0xae6b8dee56ffb77f, + 0x188c4b783e441a1b, 0xa128026853fcdf5d, 0xa93683f4d1088946, 0xc2a6b3419ac829f9, + 0x269d19f36dac94c0, 0xcba5a9d6de4a78bd, 0xbeaa334ecc4c6744, 0x8a87fb040e962fba, + 0x9f8e1cec3925b05e, 0x678a01f0c853070c, 0x56585be043e0031f, 0x1032eced5d6d0c33, + 0x3ee0b9b527203737, 0xb0949485a5c4d58f, 0xdebec6280067d9b5, 0xc397ed6ab32a35de, + 0x5e2053ed19de791d, 0x4b2c2902a0837974, 0x3f71296bdc448cdc, 0xf9ec12c2920c5b2b, + 0xee57ef8d8c176670, 0x2e7d145cae255636, 0xaf68510ad35089de, 0x70497e0fef82ad04, + 0x1cc49affb7d7a055, 0x0c62e60067470136, 0x26ffcae5dec1d1d1, 0xcc02d18868659802, + 0xfb0d7b3b81fff622, 0x693f807ac5ddfe08, 0x87289ef2085fe6be, 0xc777d7497b8ed119, + 0x29db3e2c79125e22, 0x1438c5a362f456f5, 0x3348269099bacaa5, 0xc5c0a47d9e8621e9, + 0x78783f5aa97bef28, 0x5886cdb12b7997c7, 0xaa10250093f522dc, 0x35fcb986ecd664b5, + 0xa0783bbefc5e30fa, 0x30a7036ada65970b, 0x619d98e1f209d3d3, 0x19196ec9a309c998, + 0xb1cb9fada72545b2, 0x8ebed581df93f1a0, 0x1f9f205dde052709, 0x6d813e36a557fbbe, + 0x2ce7f77f13b16a26, 0x97175f9c8ea82cb6, 0x33c22b0be6a9a764, 0xd7e10fe43ae9d5ed, + 0x886650afe20d2a71, 0xc9998b9c2ca3d20c, 0x3ee859962d441789, 0x45dee757099f62ea, + 0x3a9c5abb7c70e839, 0xaf61d66f73c779a9, 0xe95918543cd8928a, 0xe1f14629cfaae394, + 0x8003a2bc1709865c, 0x95a44eaf827a3c95, 0xcec45e7367552c27, 0x6536c677f387bb81, + 0x3934ee1ccf43b5d0, 0xe62ce6d24a7facb6, 0x3ed76bb63d6c5028, 0x3d90a75f01329c8e, + 0x379acd4f05e08e41, 0x6404493be6dde4a3, 0x8b505261042bb981, 0x2dcb10df77d925ef, + 0x977b777b6616b977, 0x8bd0353965bc3717, 0xcb5441e5eede46d7, 0xe14ca2ac16c7b24c, + 0xa3cb63e1b9e863de, 0x75c24abd9d86fd0b, 0xe4475d04bbc640f8, 0x1531d5be930a03cf, + 0x19f80142dacf7ca1, 0x89530fd6a376ec8a, 0x0d0ac7876a8da7e1, 0x82de740fc23c8d80, + 0x076e9087ee963510, 0xed077111085a17e2, 0x8c12f20185eb9302, 0x6480ae00192a67ac, + 0xe9058ddf59416aab, 0x7a1435ba1cbeac27, 0xc7040127b89f1a6a, 0x050c478fae2275e2, + 0x042ecc708efcbf6e, 0x4114a86ac49970de, 0x7cc98420ef3a3f46, 0x0a364094bdef0bae, + 0xbe39e9f934bdc3d0, 0x51a5475be1b9ad66, 0x4adea2bdc2c12df4, 0xac7545b46a41d889, + 0xed80b4efa3f970aa, 0xcb1ff55f78571a1b, 0x6e25150ff62ee58e, 0x3cb24e8fb12d0cc7, + 0x44fd1931f9168ee0, 0x90fd97e1b3a01eab, 0xfd9ba3b64f98e021, 0x45ac3e8a9eae5c82, + 0x6594579c0b5802b3, 0x4baba9361160242e, 0x3e4fb2fece46d763, 0x2b3516b910bd5d56, + 0x2c21b552f527f7c4, 0x75ad9bdefe3d3186, 0x18553dbd04e2ee5f, 0xd2a433b4bb8758ac, + 0xc9b11071ad8cc349, 0x9cd05a4f242bf87e, 0xbcd4f85f7b913725, 0xb942595058223020, + 0xc2f65aad36d90671, 0x4c2e91e591212b9a, 0xed272db0a928de8a, 0xf5b1574c2c390a82, + 0xd324dd969b8460a3, 0xe011aab84a2109db, 0x4d43d4eeade83a51, 0x7a8ce3b89b65073b, + 0x51405f05f32621b1, 0x6358fcf9c3fb6db2, 0xf6d1bcde2858e590, 0x90456d9ca1526de0, + 0x9303fbd188289a39, 0x0a66991693647c13, 0xeb7b48858069e596, 0x62efb1b808534d85, + 0xc169ac4847c42b92, 0xb050218f516eced0, 0xef472d628d6a0793, 0xb793c0f0a8961da4, + 0x57e306ec5d2fa6b0, 0xa4b2a1c3b295ea93, 0x3842197c20001fdf, 0x475c447df1af8e1b, + 0x494d57546f660b89, 0x514111d3cc3af0b2, 0x090dc3de8f4fec76, 0xa211c2353cf45d07, + 0x3c6d9ddd2d5ca403, 0xe481318127965ea1, 0x66fc7acee1a9e075, 0xc220ccc167962426, + 0xc388e5e7ecdcdeee, 0xc498961cb3c1f7e2, 0xf2df37b0a36fad68, 0x16c7978a71f07ca7, + 0xb767ab7d67aa58a3, 0x34c5c715a89fe8b7, 0xd9fdc4bf477df042, 0xd85bb2965b91b1ec, + 0x02bb84af3de9ae73, 0x2762f77af3ecacd3, 0x4cce06b6c135c6a0, 0x3c12ac70269a97c5, + 0xd34264ddf9f481af, 0xda2c20db23a2a951, 0xfb354a55dc9fe1f9, 0xae56613479404fa1, + 0x30a1e736e1e0979b, 0x8a43525dce23083d, 0x1d3d31636fe39681, 0x69b7806c71434192, + 0x5fc3d70cdf811365, 0x2c21baabdd1f3ac2, 0xa4df2734eb4fd3c2, 0x05fae8f60869b250, + 0x24f02cc89eab2850, 0x29def04380f91cda, 0xb52061a1129631a8, 0x19e06c408d77a342, + 0x098020cc1462c046, 0x63ac7fc061bcfe7a, 0xe6e7c64c04929ade, 0x1607be500aca5ac1, + 0x81628b5ba4f20066, 0xc4c5652c6838c436, 0x1050ff4ba2a8d111, 0xdd27940195e099c9, + 0xcb99872e705308fa, 0x50c478b3d94aaccf, 0x924318b014c1011d, 0x25d73860d2404cb3, + 0xdb45831ff6321071, 0xc2f9f19a14af17da, 0x101646ac60be0e81, 0x6dba342ecf5e92e1, + 0x3c99bb088c2e52bd, 0x68ae5303d5f7219c, 0xf90982fd7141decd, 0x566bba4d02652bf7, + 0x24866a4d9dbc9da9, 0x28f37d5ca5341e34, 0x6618cc4d450e2dfa, 0x5bbf2809edf350f1, + 0x80fb47d9e300892e, 0x26fc85aa9cfaa0b0, 0x806ddd37f3cc5468, 0xae490934949759bc, + 0x29a0e655e80b75f5, 0x7779044e1412074f, 0xc35cd2d7e7698fe0, 0x940aef680f79f484, + 0xe64c9f73c67d8fe7, 0xa6a96d63337ec9d4, 0x1f7dd49668eed91b, 0x907899af30155709, + 0x5bf3c5f6643ae96c, 0xd8cbec88672c85cc, 0x2d3f0a08516c4358, 0xfc4b88aacfbbbbd2, + 0xe271f23ad1d18136, 0x8ca732df1ebe539c, 0xb88d898f4ac26b5b, 0xb2e297ba042c14f5, + 0xeb1bf7ee1f77d689, 0x67d86b1cb041690f, 0xe70cc5433f0f5ac1, 0xe79f9f78543cf7dc, + 0x74b777ed83e3a89b, 0xe5269dd49a700ece, 0xae1a3584f55efb5c, 0x15e255dcdd058c2c, + 0x6a3833d5b6a91cf7, 0x8a592239a6847a1e, 0xa8fdb4b5f994874f, 0x7db74c4ec3ae70a5, + 0x82da1665ad0dbbcb, 0x358550daf164d1b2, 0xfad790370f6ca348, 0x0b9222d05d113608, + 0xc62b4011b9fa9cc0, 0xfc5a89149e7d7980, 0x59a250e70d073f20, 0xc7534a359d0e495a, + 0xf9235e314514aca7, 0x3df309ba4adece5f, 0x94849afecf3d7650, 0x5b59c52a60f76f9a, + 0xe6a2cc14e1b59656, 0xfe3178953dff61ad, 0x16c546690297cde7, 0x6f703ea28739349f, + 0xae0a30d7dd13b2a1, 0x249b762670ac916e, 0xffba778d131c907f, 0x292774be907365d2, + 0xfbf2c785fd531803, 0xdb7144d62812ddf1, 0x086570ac2b4a81d5, 0xa41b0a36f452e8c1, + 0x8fa809ec08b7bb05, 0xcae7856976218344, 0x7f356eeacdab41e4, 0xef2c422159ff9be2, + 0xfdc0207c40e5f5c1, 0x0551341564dd7bca, 0xbe53194532aeece8, 0x7d5bbd145520fe79, + 0xae5bfb107dde2247, 0xed61a411d84a58b8, 0x19b8b8819c1b8410, 0x649a81bc82cf90df, + 0x5d452c0891c8bd39, 0x86d74b7f033393c7, 0xe38838b0f87f2bbe, 0x90a3edcd1e94e4b7, + 0x299a990459528c51, 0x90426eb368fdb8af, 0xd9edc9c54888d97f, 0x6eb87744d1a30bca, + 0x9eba72a03688f56b, 0xc7b96fb38387a7e3, 0x84cfab0a6ed5252d, 0x8cdfcaf43ca0ab81, + 0x797034ccc9571108, 0x21c1a13fd92ca367, 0xaca7ff593902e8f6, 0x15fbfcd0036bacac, + 0x09adfc1ca3c546cf, 0x758179fea0eaa984, 0x585d1f20d4dbf915, 0x6b4f211231223287, + 0xfb32baef29d25fe2, 0x7816ef6fa155cd5d, 0x2a3632c1c8815ec1, 0x76a288f890cbddff, + 0xc04f600325c8ef00, 0xe3c2f0db15b92579, 0x0e07bcb64dd36f29, 0x6903e74dbb385788, + 0xd87549c2b040140d, 0xd1cbe4608d3c2c56, 0xe93bf851e1e5e05c, 0xe577354f35b83bf2, + 0x26a8c5dac3779fac, 0xe280558f97f20dc8, 0xdf48ca8728a8e146, 0x1e7cd908656c78e5, + 0xf9d9f43ac88cfc86, 0x20eb69e2e2f5a543, 0x96bdb9587173e733, 0x7dc88c3b886868fd, + 0x255a9ede9c36a293, 0x25e5b0b3ec562058, 0xac2ab486a78a6ebd, 0x7779ec182fb67970, + 0xc22d882dbf9704f8, 0x7f63347bd82bcc95, 0xe2f482c4107004b0, 0x0a651935a19023a1, + 0x82120a197e509f50, 0xd87c60a1583cd604, 0x7445ed6734397276, 0xf890c1bce6517924, + 0x646cb0d51ec15240, 0x06b53d035f09dcd6, 0x51292e6e78851979, 0x4cc297e1e946e7a2, + 0x0b64d261f89ce3ec, 0x6b25a56ac5775ef1, 0xf5e23c6fd86b2bf5, 0xb96323b27b2d24fb, + 0xf42ccb8fb018b1ab, 0x41205bf62eda2be7, 0xf273e3925ea04936, 0x312bd45c54dd095f, + 0x539ae4f37d144f8e, 0xe055c2d890f471bf, 0x322bc70cc8b64969, 0xb5d27aea96e3e954, + 0xfdad41b27cfe635e, 0x66dd8823e2acb883, 0xdf08d026935411b5, 0xe06099b3a6317773, + 0xee3d5f781463b615, 0xc03ca7478a642967, 0x333be962ca1192e2, 0x159775c82fc18c4a, + 0x5bd1422a6e3efa60, 0xcc661898e81b5a97, 0x2d1c4f5a54c8561c, 0xb1d5b773bf94b8bc, + 0x371daea2265021f4, 0x5df627ded4aef5a3, 0xae1d7dfff0fc1cdb, 0x80ccb10a2b5bc7dd, + 0xb9a0ad80a896c618, 0x75461c073d7442cf, 0x60c0c9b5aa4f961a, 0xce4db4d4458b692a, + 0xa824fa89bf5e8d38, 0xdbd0099a53bf3d64, 0xbebb55974efd30ea, 0x61c37fbfad7e34f0, + 0x11d8f3ce9face7e3, 0x8851d3ebd06495d2, 0x7a19e890ebd35619, 0x212971797d8b2904, + 0x1913dd39a3dfb428, 0xfcaf24cd21d80a01, 0x2bbb281cff180403, 0x34854f411b2cc406, + 0xb8eec1c4f20627c0, 0xdbc4ae345a789456, 0x4050e1c23e246ba9, 0x76cf678828aff38d, + 0xf03f1b4d7205c6d9, 0xc041fcbe3976913d, 0xc44a7ee9375aa69b, 0xebd559f5efa3b359, + 0x48a83b4b28aaf168, 0x05b2dd130713a8aa, 0x9b904f9edc334db6, 0x595503bbb221ed7c, + 0xe3ebe979b4a3e3ad, 0x11eb068868a96eaa, 0xe4de461039d622bd, 0xf21d78d78b43e655, + 0x3b928db0ba54d339, 0x328239b1d58c9f66, 0x6e99f0017ada5132, 0x62fcb611dcb4968a, + 0x3b5cc401e04f4a80, 0xa8cbe09b34c8fc1f, 0xeae399dcfb233afd, 0x8ccbe9665c923b2c, + 0xca62b27c66c94b8b, 0xff90cb4e292805ac, 0x8071d31743e07c45, 0xecd44b1a1996e043, + 0xc5fc723c9359de93, 0x97b308f6914e1226, 0x5798117e8ce48975, 0x538ab5cde8cc10a2, + 0xabe5e9bed4f70df6, 0x5cb6f56b7ce580cc, 0x1a61b699b431c9dd, 0x6d07ef9499722502, + 0xfb619effa077ea80, 0x6a65f6f66692be20, 0x84ca63329c9b5c7d, 0xcf60e080f238b6f2, + 0x182020cfb6f0af64, 0x9ce13cf3848df56a, 0x4b19d42fc8e4414c, 0x7852cd707c29b15d, + 0x1545a14427cdfb19, 0x1769086cbdc305a8, 0xa9d084dc8d0eafa3, 0xfc758766798194ad, + 0xde1924aa1b98ce20, 0x3051813e080d36c5, 0x3a8378380b5130f0, 0x060e436c36853dd7, + 0x84effbfbe6f259a0, 0x4029fec9b938d703, 0xaafefc6f4ed00879, 0x26e61ed228c8f334, + 0x46bb30908e6ec690, 0x9036a30ff855f37a, 0x246fa0e830780a40, 0x1e3148c990619e17, + 0x3275517374f6c851, 0x92ecddb667d04f94, 0x9f02f5e8d0696ea4, 0x14a7e9f9e22cc1bb, + 0xdac481c8e06d2063, 0x4088a3a7fb503e3c, 0xd2e25e47d1317d7b, 0xf480e52275a4377b, + 0xa88bb91d75282037, 0x3c922a4034cbe2b0, 0xa649480f027ceb23, 0xb00fc66c74f60b2e, + 0xda85fed905f600f4, 0x05a116e1e532fe5f, 0x4de9e57c6ff20aa6, 0x94f3caeee5ef3481, + 0x958615453ff4475e, 0xebd64a2a3f7f3459, 0x197acd18f8804824, 0x363775a0cdc0aba2, + 0x98afcbacd14fd0fd, 0xf7e5f9d5ab3e7c39, 0xcb41759ba3e2b6c4, 0xb12823b6b9d507b6, + 0x85177cae733b777f, 0x1fe98a584f2537db, 0x486f76cc9698066a, 0x2658ca8e0d8e9603, + 0xecdee992ddc4139c, 0x9a28d18df65ee491, 0x6e7d6b4e2e768616, 0x4eda52d2c12c5a7f, + 0xf26aeaf70ba9dd3a, 0xb59d2deb012adbf5, 0xa27e085b3dda76ba, 0x7b16a2adeb548389, + 0x0ed24c5a1749ddb1, 0xec9318bf4cfb62be, 0x8d4ea42fb97830af, 0x650b46372b02b877, + 0x299289d153d02e20, 0xa7e41325e9d77fe0, 0x361760c3063fbf3d, 0x96a9ea423fe68c49, + 0xe8fd44d7f8b91e82, 0x111c1d531a407126, 0x0dcb976f928d381d, 0x087b953775c1452a, + 0xc0a73410dfc11d92, 0xd54b69d639f333e3, 0x1a8c1420c76a3a98, 0x91f73accb9fb7353, + 0x7c636fb01d60dec4, 0xb36eac90ebc1d673, 0xeb562affee9e58a3, 0x209dac984fb36e69, + 0x91e091e7b1339596, 0x75de4bc6a7b4bfe5, 0x2235d683b14a386b, 0x7335e0785de4d314, + 0xe631c2259d991c64, 0xfb67e7e3dbafc6d9, 0x4b61d8aa333baff3, 0x303d00b884c04c87, + 0x943b02001b6c4a13, 0xe543ec9ff6aa7528, 0x5da2c557318d5fb8, 0x1e05e41a375442f6, + 0x5dce03dc6b002344, 0x11359cd5f96fa74a, 0xb850fa85d4b85477, 0xba7ee8d4143bd4c4, + 0xce2efa66c53faf83, 0x2840147f72ae2116, 0x3dec9bf9f41befe7, 0x8bddc26e45ff09e8, + 0x03ab73b8d0e62f7f, 0xb8aa40498c79b1d2, 0xd8c79eefd6f5c27a, 0x8ab7de447dc664f5, + 0x2a420416dc313ab1, 0x3e3deafabc128491, 0x8e185bfdc5c2a8cc, 0xf282cc033f7bcdd4, + 0xcccf89082c90385a, 0x1d7fdc1228868c60, 0x89dae00609e418c8, 0x077c835aa333f794, + 0xcf9fe52e125bdc37, 0x14d9d89f4e593756, 0x31e63d89e08bce08, 0x7db9365210c6c11d, + 0xf470c372a95870d9, 0xd8dd8bad10dfd890, 0x28dee96f12014edd, 0x5fedac75bc0a2568, + 0x2e484f322f8f7a29, 0xe96ba47d5150a994, 0xfae702516c54b6cc, 0xcd00ffb4968b69ef, + 0xf2801387d1cbc1c3, 0x3e926b195ea9a74a, 0x87531a019cb4216c, 0xa3f489964a8b33df, + 0x7a45efad32c79c95, 0x5a32766fcebd320a, 0xcc5dde2f89a4ca99, 0x6522963dcdcfbbed, + 0xfb152be3a9398734, 0xa63ba08b16021d79, 0xef90a96e970b18d0, 0xbfa1d710ac0427b8, + 0xb61ae59554d63093, 0x163f87d0c0c4f318, 0xbc312daa01cda2c6, 0xc9b3a78684f4ad83, + 0xf3a82e342be4b5ae, 0x48ff0e23fa6038b2, 0x8a7b33da7cef8a32, 0xbaace901a1775ccb, + 0x2c854a50b646fc41, 0x39eb8099c508eda7, 0xf7317e5f5414eada, 0xb193ed2038df83f3, + 0x8efe0432051af048, 0x02c101d8dd9540d1, 0xbbf2c3831874384e, 0x47837934d4de9253, + 0xcd6790c9a868ddd4, 0x11d99b4198b5321e, 0xe6e2e4e3f98cffae, 0x057fc17193714be8, + 0xd96b273470272d0b, 0x37142ed36c337c01, 0x804887cfc5dd884a, 0xe5a51a1c1370aeba, + 0x5bec1b27c5c0616f, 0xf117746732055fd7, 0x09c5ea79121d2521, 0x85c849aedb30d9fa, + 0xdf3224c63b119a0c, 0xd31f4384819538e2, 0x35031dda5ea8686c, 0xcfadb56e708aa990, + 0x63f539864afde9ac, 0x495eae5b295cc38b, 0x81fe22b1b5a14160, 0x32ed23e730eb5635, + 0x5f83f9df55d94400, 0xff1d9c23d996eac9, 0x556b67ddd12f5523, 0x0319f96408d54e19, + 0x0597dda784687bb0, 0x39a9ed179ab1db9d, 0x93276bc94cb2bcf6, 0x4bb054fab8f86e44, + 0xea19f58ccdcedc20, 0x5a106854d6246fe9, 0x358c5b2a4080919c, 0x127c880b950a20fb, + 0x80950cce7df3b6f0, 0x87ebc8e8b809697e, 0xe7ce42f2e5f2633a, 0x859ea7b626aea862, + 0xd532f0945e548d83, 0x10ce7253bc316f1b, 0x4253393feb8d2020, 0xb99f9b3257b4765d, + 0xc25c35242d0570b0, 0x5151b8823483c555, 0xf20d826fe909d993, 0x0ada96a7cab9b3c4, + 0x65fe6001a9abc381, 0xc5c304bf9dc5e12f, 0xf80a47363c7824b6, 0x2e71cf0628ecbdd5, + 0x3ff2e199c6cfdea2, 0xb3fe7a0f24863347, 0xa961cee5ed454914, 0x13478e30f1fe6e20, + 0xf43f81e2532e4e87, 0xa85a84e623c54fbc, 0x28d1915b4b3f8553, 0xe5bbbe79c60c3bf4, + 0xb735ab5eca2c405e, 0xf1a07668b55322bb, 0x181efc4e5d494eb7, 0x5ceec4adf84d94b9, + 0xd43e20a231d9947a, 0x6a30c25560a12054, 0x9ab008d416a27bff, 0xe778308cd4d6fd4f, + 0x3c513f87f5b2eb68, 0xd1e963a48023d363, 0x0edfb89c7b2bb079, 0x9a99d756dbf20093, + 0x9377dd24c802cdbb, 0x1a74d5e46be66d4c, 0xdb606bbeee69097a, 0xb90eb9b495a16636, + 0x4706c9de80b82328, 0x2bc86917c10eb335, 0xd0518f9f6328312a, 0xbe6209a4e13d1aaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5eeaf2037a02b1d0, 0xca8b65027ed387f3, 0x9e9f8e89df253623, 0x7550aad5e7da19e2, + 0x7a5e7fe30356eade, 0x7a7b5410beaa3bfa, 0xbda578ce466036bd, 0xc645118444bd9dbf, + 0xfaec353745731e46, 0x920797e8e13c2f56, 0xdc12620198de6780, 0x28589cd499b47598, + 0xdc0edca5d099349a, 0x372cfc338995027f, 0x557688de1f2afaa6, 0x7adb72342f6d425d, + 0x68b6f0d4ecef6241, 0x95be1cf0988f9ab5, 0x569f8ea377c3b0b0, 0x95fa205bb7e82086, + 0xc40073c1792322cf, 0x19e3a17ba29aa431, 0x9679bdddaf9221fa, 0xe481eee23f090904, + 0xe29d414645196b96, 0xfc57cacfcb141119, 0x072b29a8858c5d5e, 0x44f5a90ce661e33b, + 0xeecd5ba3fa43e0d4, 0x757f22c356aa98da, 0x8133c84f4b35fab0, 0x7e18aabb85c39434, + 0x26909ad6d950e696, 0x52b2677e6702196e, 0x3c53a0bfb1bf56be, 0x6ad6c7c6ae6ddd1d, + 0xac2fe72056454dfe, 0x4e23f8dc3bc266bf, 0x3162116aff274ce3, 0x7bcf818b35bc9916, + 0x797e3b24c837621e, 0x97453b1ab6196d40, 0x13db43ffc43102c0, 0xf9aaae5c7b1b3c5d, + 0x8b3122c3f92895b7, 0x7590f81b59616f24, 0x3215724f208ea20f, 0x176f6261aca643c0, + 0xaf06c56820514fb5, 0x00409dee1120c578, 0x8cc4ede5be28df52, 0xe8f0a2934c8e2ae3, + 0xba6f5805252c2ff6, 0xd427de194020c16c, 0xdaf0426c0896c110, 0xba17d2ca1da4ced2, + 0x9f0038ba655d558c, 0x1c22ac1fbd14b10d, 0xa0ec9ab3cb4042a1, 0x0834d15fba605666, + 0x60d66b935c236162, 0x5553f834a5066746, 0x0710de012440f6b2, 0x9552de2f03c56458, + 0x2b13e44b50408ab5, 0x078289dedbaa553d, 0xad5a1ba94959b4e2, 0x7d1a331121907810, + 0x24e8f5924bf92d20, 0x6bf34310b54366a4, 0xe240259191ac89ec, 0x25b06d09ab2c0008, + 0x4c48783281dc79c1, 0x535d8d13dcaadbf7, 0x339e384d00481308, 0x7f0a4164efc48b71, + 0xb3625bbb7bbf5e98, 0x79cadab0bb8f3420, 0x4d56d9914266bf81, 0xf339cdfb17321364, + 0x1b2564bf15e8ff17, 0x762a35e28d4cdbb9, 0x33af2164557efc3f, 0x3de246ee45f1e19d, + 0x502ae5aeb44d69c6, 0x0a8178b4ba1fa347, 0xdb323c7d9133d7c9, 0x2daa04d22f4c4230, + 0xf7eabb257a210830, 0xce8ac7d198b7a0e3, 0xa70c384212a2eb03, 0x963be368b2ffe062, + 0xcad15aa9581185fb, 0x7a426f5dc237b6bd, 0x6a32307d47b1d1a4, 0x5ddfc740b91aa3ee, + 0xc24cc4614bb6c144, 0xe689e25acf622136, 0x879430dc18ce605b, 0xbbe985d41d1a6ac3, + 0xbb0e7b75b16ce3a7, 0xf92c6480df3570b5, 0x0674538ec7484826, 0xfe9ea1b682e05964, + 0x4140f0243c789eb7, 0xe123847e2f8d422d, 0x258f4efe9c478080, 0x0003ae9ffb15d4c8, + 0xa3b406bd4852db65, 0x71f8a4f75ad6aa58, 0xf2a57ee71a030125, 0x3b64bd544691199a, + 0x6cd971ae51ed4129, 0x51f0d3f1255745aa, 0x59d6ecaf87a7da4f, 0xa09ade226345e4ec, + 0xfb2d2a560f1a06e7, 0x4f5c1faa03480ca8, 0x15c32f7070bcbdf6, 0xb383058b764c2187, + 0xaf352e7faa8b5d6d, 0x65a09effa85a4115, 0x2f1bbbb1bba73800, 0xfa563d192e30c20d, + 0xd170f48831cc2211, 0x5f6bd812acfe0007, 0xba0d9d835b742cdf, 0x43c56da24a0fff6e, + 0xb081d3a926f58105, 0xfbcad2f8430fb0b9, 0x65a546fe76c6a4f2, 0x6c07c17d7e78e073, + 0x560be6a40c1f83b0, 0x58c10b9175b135c6, 0x65433e1779e0aaee, 0x8da161d1b4d3bba8, + 0x7a15b22053a89987, 0x6c55d134ed84f56e, 0xec779673da9f96e1, 0x69984895f43c3f0c, + 0x49212d973877961e, 0x4a811a08d7996454, 0xc2dca0b5530ded24, 0xefd3fa2e0392f7d1, + 0xd8c41e7297fa859b, 0x3cffb9f6350cf9fb, 0x0678ccddbc07307f, 0x1db9d71012f2b44b, + 0xc4b2c1f201a48261, 0x09e51e2ee30a9f4d, 0xfe2aaa9243ac44af, 0xa6e23d2d62af1d8f, + 0x2caf09c834e851b6, 0x38f62278a6db7b5f, 0xca34b721933944db, 0x485ed670bd08ea56, + 0x47d3a4c1a20cf846, 0x39f6f42cea1acbc3, 0x5009a708021eead4, 0x23f1bd4ef2074a30, + 0x238a5922e2ab4096, 0x617c1cf217dd3787, 0xb2ed593ce15d0215, 0x1f71dcf4427c2b6e, + 0xda8f2196adc48d60, 0x981ab4395f2cb008, 0x9218fb4f7cda142e, 0x4ced703dbc47a348, + 0x18fa42f9a2fe02ea, 0x78ab5d2f0fe628aa, 0xfe69c0d26584bd68, 0x78cddbc7ab498d1b, + 0xe0cee9541ce8cf8c, 0x2c2e11acc694907f, 0x304fa137fcffaef1, 0xe2f5860f61495c69, + 0x47542da2506cabd8, 0x5b55fcf4aec89ae3, 0x301d4d5b2ce85307, 0xd0b5b592aaedb94e, + 0xd61be5de0855eef0, 0x773a2a1c19e47201, 0x63a027995bbd4e52, 0xab1d53197fc600a6, + 0xff73901afd1e99d6, 0x6bb15bf8fee6fe46, 0x070507d48debfa7f, 0xc94a6a93ecfb0eab, + 0xbf9ae717f1c62c44, 0x2dfdab9fe00e0939, 0x12da36eb398d3b92, 0xe675b8973d173c74, + 0x753782935180cf81, 0x63c5533b29ace698, 0x0d64784bbdc7398d, 0x72055a5d7751c47c, + 0xc86e3bb5c1230050, 0x630c90ba81a1efea, 0xdbe90d4cdbb4da14, 0x15a858a897ac223b, + 0x656cfeab4ae249fa, 0xb6334ac62701482e, 0xbab359b1e7f2e24a, 0x3ba0f8eaf09b979f, + 0x593f7f6aba94d1bb, 0x9d9841de535ac2eb, 0xafc7433103b59734, 0xd3fa5b214d7d27e6, + 0x8149335f9edddb3a, 0xbb9d74d3d8c04ec6, 0xb75c1599de8fe31f, 0xb0b479fbd8c6d867, + 0x46b612579f9c1288, 0x128b9cc4df952cbe, 0x0276f860b064f6ed, 0xb93eaf73646c1969, + 0x1c5b36b967feef64, 0xe8640d0337a7278a, 0xe203499e3ff3916d, 0x6d40f58b24d13e53, + 0xc5c8f6a15a5a2221, 0x673e94a5ec1f92ef, 0x0534233485daca98, 0x5a4618ecb0388401, + 0xb896d4eb55fc4f6d, 0x9a4259c4305e5301, 0xc62ff22b0dcf81cf, 0xc8700ea118916e59, + 0xc1854d1c8f398fcf, 0xb97d8002b04ef0e6, 0x8dc0ecd8cef3900a, 0xb89a80b62c767686, + 0xeacf89e936bc0d88, 0xb9fea68f59311e3d, 0x0ff7e68100959d39, 0x8c54a35bcf08991e, + 0xc7bddd753432dc59, 0x8a83041a8d10d09b, 0xf6160a8df49b1252, 0x35e2ae2c771a4c73, + 0x503696bae45b3d5e, 0x3ed00f4e8e515816, 0x2d04ce2677dd24ec, 0x108563110be70e9a, + 0xcaebaa9e369e863f, 0x9c041ca68ec96783, 0xcb956b59347caa62, 0x2e1896c384860e62, + 0x0130539e4843c098, 0x1ef2ffab71a20354, 0xac9830a2fbda86c0, 0xcb240cdf8a328a96, + 0x2f927d0ca60abecb, 0x7cec871a67bc9f10, 0xeab713c713f7a8fd, 0xde33a967d098c905, + 0x749f7afa4897a7f5, 0xd92199b73c9168fe, 0x3f340624ab1130b3, 0x9d9bec562661029c, + 0x09addb2b0e40d473, 0xe96ca6c1d6df9a5f, 0x38ecd32697ae3467, 0xff8b393ca4344ab7, + 0xe179a1bec318c4e4, 0x2005a1c760173587, 0x2fc0336d272fb7c6, 0x77d3f56e6fc0256e, + 0xacbde97601516d6b, 0xd930df30d8157720, 0x847912d4339e1073, 0x71d98465cfd131b1, + 0xf1278e964592524c, 0x81151cf8494fab52, 0x08fc4934aea825ca, 0x8892fd7a1fa42145, + 0xde2021e4d1d34d6c, 0x8e5df2b060f24541, 0xb5dd3a57713cfea4, 0x9881cbe4ec5d917a, + 0xf875061330ec138b, 0xf06e9b54338cd895, 0xcd2f3af1e1d0405c, 0x460e8ba5ec08fcfc, + 0x6958650d1b47db37, 0xf12460c55f717d5d, 0x2f64554145913b2a, 0x42cac96761c462c9, + 0xb150044af826654e, 0x4f61079e648f2798, 0xbd99f7180e3904f0, 0xd487efee8128ae0f, + 0x55af8274b87c3e13, 0x9163f1911c0a2259, 0xf627433179f51294, 0x2723cf8cf92cca7d, + 0x8df82931c4e77141, 0xef5a3bfca47592e1, 0xc9fb7e981788c2d8, 0x00c4b918efffd1ca, + 0xff1345ca01105bcb, 0xc5eb5c20d4db2972, 0xc9370d522f9b3a30, 0x932e373242223e42, + 0x431e0e659407a72b, 0x9fd4fcbe4663efb7, 0x3fb6726765386bd2, 0xf5951fa2c40745e0, + 0xe37624563cb3291a, 0x76c474b48bdce9a4, 0x1f2c0512fdbf88ee, 0xf760cbf5d1a8bca0, + 0x9252a523a3e73ecc, 0x6b57ecd73237c38d, 0x57d0d29edb486266, 0x2a85ff8ca947c6f5, + 0x5924111a2fb82472, 0x2dd84fe753f3ce1c, 0x5ce6c8f38528f8bd, 0x51691f539ef93684, + 0x52ea41bbc448f6b7, 0xbcad1a41936e4ccd, 0x937ce3e7303e7457, 0x4df46522c103a4ef, + 0x3af22d230d7b7808, 0x4697f51599bf5949, 0x6afe0a3cdde2f921, 0x3c722e95a065c111, + 0xe0df8d2f0926fa29, 0xa722e4cc95eb0ca8, 0xfdf83e8b818f2685, 0xa3551b738ca62fc8, + 0x5014384215e13d3a, 0xbae0d31c81590629, 0x9b18f0dfe00205ef, 0x57eb007db2eb7373, + 0x5965f3b9a42ef1dd, 0x84136aa46e0e611b, 0xe0a6dd667973a800, 0x6fe41b6bf9e25322, + 0x2009795606effa51, 0x6d2caf8507179e8d, 0xcb414f6cfddac304, 0xf67d253a82ff0375, + 0x3881799527dbd22b, 0xbfd142e475860331, 0x56acd86cd8f44d8c, 0x011a281d13bab642, + 0x0eabcaf83dbfa762, 0x0d0987b6fadb141f, 0xc953a428cddcc071, 0x5398d6f198d5ffb4, + 0x26fa9eeff6b0e4d7, 0x9f7e41f0ebd93c8c, 0xf92895405ab02ca2, 0x33d1d0b2fa3cde2e, + 0x5b3c03e34e5b2352, 0x98135c3b03565402, 0xae876b9449f406dd, 0x4040c2909d76a105, + 0xf18a6fb24a96244b, 0x3ea6ae1140dfb301, 0x08288bf34d5b245f, 0xe892396a798e8366, + 0xae6f716d86dab1e6, 0x5868e546abcdf685, 0xaa5eb304f33c0b2a, 0x6fed8c1a5f607ba0, + 0x8fa5566a2e069c1b, 0xf5b3aedf5bdf7c12, 0xb0113b59f7da0a6f, 0x315ceab94456f440, + 0x2a95361b9f5c9199, 0xb7ce76d80c864789, 0xdda2c351047e3340, 0x859b202a079eb325, + 0x273ce471be14dd53, 0x161264d8c6cefbab, 0x3c626c2b8d94c369, 0x95a83a7e5472262f, + 0x06c228cdc0da8d00, 0x1b0d4cf76ac8bd90, 0x2c62752c6b6717a2, 0xb2b03bbb65a7dea5, + 0xbfaa38b6cafc41cc, 0x5f6587decc32793f, 0x8fef79bae47b416d, 0x96188e811ef1749f, + 0x5320405be0faacad, 0x6f784fa69a541271, 0xa7c87f5708ce3ddf, 0x5979054c88b3819e, + 0x0f85a85207e3aa1a, 0x3e8c53f1973cfedb, 0xa196151f63f91ba3, 0x73ae0d64ca0321c3, + 0xd2dd3ec110b346c9, 0xcefc1e4e3407dea9, 0xef15ee0006964ec1, 0x0678e0c795316cf0, + 0x8cd6375c1df3f4f7, 0x9bc3feefaefd3ffa, 0xf749e20576152996, 0x3dbdace8e3688035, + 0x2cd02682affee2ad, 0x9eb5943b35f96102, 0x1078c31f7aecbb24, 0x65b137ded1f65c82, + 0x619e4db6a05b0c96, 0x86cda0064e089f8e, 0xbf5940b931d3e80d, 0x3cdbfdc029d5d42a, + 0x52dacf78045b9dce, 0xd8f67053df9aaff4, 0xac90c52e7c5f8645, 0x3e7fc7023a167496, + 0x88c6b2b6c75d2bb6, 0x9eb91f785a720630, 0x0f33f24724943e7b, 0x5bb49392abefaf6d, + 0x111930d44a0ff4d6, 0xf3dff37d4355b43f, 0x7b2f29102c9570ed, 0xc52c8ab0f1c61779, + 0xb820a20397e0a622, 0x8d8ec67e5c03de03, 0x0c447cf8f013ef5f, 0x71b7884422aa0fc2, + 0xd26bd7ae8fdf11da, 0xc0dd59244640195c, 0xe548c9a448b7f513, 0xfaff24472aa2c228, + 0x4cbaf788c7912e42, 0x1f8721b0fabf3703, 0xe101827ab46df845, 0x188a7d5686c1f705, + 0x5c762fcb847483e3, 0x34220635ee27754f, 0x40f598337b02991d, 0x96d0af5f12200c0b, + 0x8bf65bb2f5edec2c, 0x0eabeb218d852f4b, 0x792313c8ddd05fc2, 0x166126259de6e6c3, + 0xec7ba2ae8797322f, 0x6371206235b63380, 0xf549f255b5a6d6b1, 0xb301e10148578ff1, + 0xf33049a789378d11, 0x45c812e6405ce53d, 0x7e1f41fe812b3efd, 0x02e2b26e126d652a, + 0xc6e2ba1d1a4ffa5d, 0x1ed0706b081dbd0f, 0x721a856b981da04b, 0xc19b097bdb165e75, + 0xb94dfdeec6602d9b, 0xfb6c24399d25aecc, 0xd2f538f34ddb1e37, 0x2f7987955effb3b2, + 0x927b56d288b5ef77, 0x3c150d91bc87c346, 0xb65d43e957354dd7, 0x3e7c3209b3b15dac, + 0x3d753e06551daf28, 0x33534e1b5d0ff276, 0xf60f9a07973d785b, 0xcd4ad5c12fa6cd5c, + 0x95b23f2d9856c081, 0xabac3cfe4aaea4c7, 0x376ed652a04e6901, 0x1cbe024e14355e29, + 0x9341e84cb65501a0, 0x31c92763b5703939, 0x20abf91f59f92dc9, 0x7665918ba30f832b, + 0x89c7fd5a4f7f03b2, 0xf26e96e1c0024fab, 0x972d28e0fd3e6bea, 0xfa8d2182f3b3283a, + 0x70f54ea62c7b0fae, 0x24efbc2110c8ec05, 0x74b5d9202c594510, 0xa87a454931007096, + 0x73a9698e7bad426b, 0xf5b62ba38d12283a, 0x8e04a268c1c71573, 0xac378f106b80fbee, + 0x167feb8d33c17a06, 0x5e3260aad339f737, 0x523ac55693082085, 0x4fc11422457e1622, + 0xf5c2edfbc68a6f15, 0xe15fd21704e6ed53, 0x818a00d0cdd1266a, 0xa983776b0722f26e, + 0xb7f89d07b0e6e659, 0x7661c72888f8c313, 0x436db1baec68ce16, 0x7d2da53ec84ffbe0, + 0x1121fed18b1979e1, 0xb2cac1cdcc5a098c, 0x6be53bbe4f36b502, 0x821c8fa98369ce7b, + 0xeaee3cb046d2b43f, 0x3d58f9b80d3d1485, 0x78d8683dd83d0f98, 0xd9ba9a73ef4534f5, + 0xb64fc4eccc9df73a, 0x6ff682900af66f57, 0xc343638ebdd8a568, 0x9e6687ea8e975ef3, + 0x25850ac066cc63a3, 0x1c5aec82b19c14c2, 0xb4f94c696846783e, 0x07e35f1874e92fb6, + 0x6f1023c79365d1a4, 0x181ed4f60c474992, 0x03f5c9e9d7e02a90, 0x8174fa9c56456fbf, + 0x9e301d0155c0be0d, 0x5c2181e983794c11, 0x3e874c91c8b70229, 0xf0bdc8e3f76e2b7a, + 0xdf1d41b0081e6c66, 0x2d46776f2048797a, 0x292b61777ba2ba30, 0xd5bed711075db78f, + 0x69eaad7f976b74af, 0x1d282e02a0ba1ba4, 0xabac653f19cf50b9, 0x7c638002a183c0dd, + 0x2f097ce88a66a246, 0xf539a9ac8c517e54, 0xb788772781c10c73, 0xa23031f8ab3b5d71, + 0xddb336a522cef187, 0xcc7a46dd6518d4c8, 0x12dfd5c311bbdfe5, 0x2561f06e06abdd78, + 0xb8f12d94933d6e3d, 0x5b53ca0de81aa24b, 0xadc548d9daf48cad, 0xcd4847b6746ca983, + 0x46dbce7718386700, 0xb4456ad98b35aee7, 0x9480ea17ebe3a695, 0x0312370060ad9c3f, + 0xc0005d55562819ab, 0x8405287bf43628ca, 0xba7af7e8b935e385, 0x596978c5ea365935, + 0x0e8d45ca76ff724a, 0x3fe37e3b004bb0ed, 0x570996c752bf9b07, 0x8031e28b9645b0c6, + 0x72e041011f18aacd, 0xd274f9155906c0d1, 0xa7512973424f479b, 0x295fe0bea5cb1fc5, + 0xe2dcf7b831944e98, 0x4971472dada31b79, 0xb8b108a51f33db9e, 0x3dd86a59cf928172, + 0x6641999db5f279cf, 0x96d6a9e22fe95ba5, 0x9c2d35bb100d8685, 0x57d1a61add6f7803, + 0xe467080c3d69eea9, 0x6c64feab01b78a29, 0x6a154f57ac9e7ab4, 0x213bba59972b553c, + 0x5bd55c138ee8033e, 0x4d4479f0f66e40bc, 0x728597dc0598c0d9, 0xdb83c2e6120af490, + 0xff176ecadf752498, 0x03f95eb3204d2f31, 0x95f8040fcdc5c011, 0x59bf1560b998b7d4, + 0xfb3c13ac2cd5e01b, 0x3b92869274cb507f, 0x77e52552770c00f3, 0xc2376cf5756d4642, + 0x1a6dc59affd90662, 0x00d8c4b4c54f2941, 0xd292b22ec8fc6069, 0xe85ec1a58a145e19, + 0x011205142d5b781e, 0x8738c0530c329377, 0xd52ecd870e1d4f30, 0xa49065726f824fba, + 0x9031fb7947933dea, 0x22277a4a66c68570, 0x10291bd1ba4f28dc, 0x7f75bdfb09b47e83, + 0x018862629cccbd99, 0x906012bcb65aaf97, 0x0626af1d6e46525f, 0xc911ed1a03cc7603, + 0xc71ce28d1a1b8e45, 0x1eddfb7dddc2ff34, 0x899eddc795b0ebec, 0x9dae8260c5276884, + 0x88b99c867ae0a35e, 0x26e97fc75d5f49f5, 0x292b7486eaf91979, 0xdf7fffd307ae3124, + 0x26e4323d06c2584b, 0x81e72277caa0ead0, 0x2b6d104a5ae5c1ea, 0x7fbdbc0bea8800ce, + 0x65d890164528eb8e, 0xaf230fc740625739, 0x549d17747a674070, 0x9240f7e52afe1e25, + 0x07d67893ea9d5379, 0x7fab5b711d92bae1, 0x7062289b05ef7b2c, 0x8d4327793198d1fc, + 0x255b45444c9288f2, 0xf21222b04559cf1b, 0xe01b5a49383b9013, 0xb79f00268b639952, + 0xdd88c6a21ecb0aee, 0x93de8c64b2adaf26, 0xe37ee35289b8ec05, 0x870bbaf4cb50ad90, + 0x5f04c87be747745f, 0xc0364274e54a04ae, 0x5aa75c75850a8611, 0x4743406978c05ec7, + 0x8da71a4031640a59, 0x4173d64407e843c5, 0xf9e173dfe991b2f0, 0x6383d9c8755a8ed4, + 0x72dc08302d2db9a0, 0x4a6f61b842d0095e, 0xd68f3877aaef740f, 0xa4dd677e40f60184, + 0x95b37b8e71b5ab1b, 0x8469f4409074de88, 0xca3f5dedadfc2aab, 0x0cc677d58aaee6b5, + 0x21d46beb1d1c7c3b, 0xfd4164330c31c00e, 0x7f569e00d2312530, 0xef99c7e2fa6fd0e5, + 0x0ab228c26b88c9ce, 0x6284a2f0db99ce8f, 0xd525a3e5ea216f75, 0xe2b4b6817b04a78f, + 0x5095b31ec55c8057, 0xc6f143857e96703f, 0x5e49af7f1b15db8c, 0x6b172b6d891552b4, + 0xcffd03a10869f817, 0x29f94cb2b6678105, 0x3871b9f5ff4980c7, 0xf0a1b0b93aa33b1f, + 0xa8dd09795e242508, 0xcaefb344fe157786, 0xc59c91b3414d12bf, 0xadf4e3d96b375e71, + 0x222b8e8682916266, 0x2c0d6633de87ed4b, 0x69dffbda3c96e10c, 0x5a7023f67463771e, + 0xa9464e300fa3dabe, 0x4586e20c1e81f68d, 0x5ef602e40e3ce9f4, 0x105b346e13cb0159, + 0xd41a41b36148b7f6, 0xf97b9da9aae8f18b, 0x622d84d4834b9694, 0x88d71b397ba8f2d6, + 0x2cb7c271389d7684, 0x358d69aa8d8c480c, 0x677ddad92cb1680b, 0xba8e742ddd90977e, + 0xdc2926f589df4e30, 0x3624452ab088e1b0, 0x6d7e07357ca38609, 0x63443779eb0d2d6e, + 0x64657567516d5086, 0xa5c3011801392205, 0xf53755b84cd48317, 0xa4acd51ab9a8f9eb, + 0x0378e32147d1b546, 0x85d4cb74e37b21c8, 0x2209f858ce00c37b, 0xf98cb3222ed30dde, + 0xb41d740ca18ddc82, 0x6ade887ef267200c, 0x0cda70896015d386, 0x4bf3411a364d6d6b, + 0xf8c3018d8136bee3, 0xaa008423de9ac1fe, 0xdf51e499171b706f, 0xb6aeb47d303c7b79, + 0x25102fc57688f92e, 0xfb7ebec253cbeb74, 0xa9fb0013df64226b, 0xd171b1830ec6824f, + 0x8d7d1b38fa6e2a51, 0xec3cbdc70cfd39b5, 0x1b3886546ed20f03, 0xdb084dc0851b220a, + 0x71bbb4655f293dc1, 0xf00ddd64ee909302, 0xfc4d0d65c18bfdee, 0xba9b612e5e39dbad, + 0x5b6862be2894dff8, 0x081c08e04cf49791, 0x50d5f49e937cb580, 0x39bccc7e4cae0bef, + 0x99de5c6a58727a69, 0xd32c41e45a4732b6, 0x904357aa1dd3dd2c, 0xca8a43442ab59df1, + 0x18b7776765b50ad8, 0x98116522e9f676b6, 0x7416b8f7f559367b, 0x533e9ce3cb525713, + 0x0af2515df86a47ec, 0x55e985b886cd6977, 0x6e5dd97c537ebc62, 0xf4f9619a5de6bddd, + 0x392c6625851c4bce, 0x14839dea100a5721, 0x9f3c1f23bea7f176, 0xa406023e7dcfc7fa, + 0xd5316683ac1a38f0, 0x40b8f19361a2a13e, 0xd274cbc897781e4a, 0x7f10b228038b5a69, + 0x68f923ccf3e2d9ef, 0xa8c35ddffd3a5a34, 0x11d27a6c38c426af, 0x535b4754b54bc6e9, + 0xa05d15b42b5ebf98, 0x8b7e965017701a11, 0x679341bb0146610f, 0x01c856425a92f5f9, + 0xc304d16e29966ed2, 0xc93fab3294672de3, 0x8b999daba35dfa80, 0x8a81bb7a90801bae, + 0x1f5027d000b9b554, 0x518f5ba4626a3584, 0xc5bde19251339173, 0xff16f0a26b741677, + 0x9b6c1537d8a84929, 0x18f8e9e092afd450, 0xa0d126f657e05d88, 0x77afebd1e6874759, + 0x6a29429703d4fd67, 0xa5ad221fe9ca0d0b, 0xdd29bed8e9d5ad44, 0xa39742f27c4534a1, + 0xfd08bc94a8e7f457, 0x11c7fc80a59abe1e, 0xdc2b9703135e0825, 0x0898251fd9e2dc95, + 0x53ff8554b2fdd6f6, 0x87e433e6cbde8d68, 0x8fabe397d30f7afa, 0xce26f9c439fdf368, + 0x85632ce9197ca924, 0xcfb5583b7ca94960, 0xd3f4509e53b1706a, 0x044eef09978245a6, + 0x017a8de65560cd2f, 0x3fc139c5472fd220, 0xee0c7a668ddc82cc, 0x4c96a0c47a36354e, + 0x90197192b6a3f776, 0x7e233607c24a3bac, 0x1bfb66406b08686d, 0xde9c5fe80333d2cf, + 0xd984b19133e4b0e4, 0x118cd3e6809bb85f, 0x888dba29cd4a5b46, 0xcd34b780289103c1, + 0x7c9ba07347001de1, 0xf25e13bab9f6b463, 0x25d864d3af66b6c4, 0xe15958c900d74ae8, + 0xfabf7298afd77b8e, 0x29f6b2f6edd141a9, 0x8f56d844ecdd8333, 0xab3156fe53775bf7, + 0x2f09162c87c972d0, 0x67c4b774a1e7070e, 0x82c6abc9d88e9893, 0xc2369c8ceb8f1aac, + 0xc8ca6d1d8c40f7eb, 0x3f0fd7d7ed62b1eb, 0x2e813735e047863c, 0x4c35aacd6e480a88, + 0xc6e2b14fbcb17156, 0x3469b5d0f2a3fa35, 0x0add118247926b24, 0x93e4a7d1f82c45c0, + 0x095fc482186ed81d, 0xd31d330870c445e3, 0xd74fb46dcea122e6, 0x74c2b98117c6011b, + 0x9bfcdfbfd0d8167d, 0xc963814e0d6c5c29, 0xef5d8ac69455dcb4, 0xf7364b71935eff2c, + 0xa013bbb0aec71ae2, 0x5a7eec7f9d5e6c25, 0x85f330dd23d8f896, 0x8ba3022f4c6ebc8b, + 0x2008f21331f4f4d9, 0xa54cdf610a53a1b6, 0x132001f9d56f73fb, 0xc97e9140e444e15e, + 0xa97fe1dc83a98990, 0xf45ff14a47328241, 0x4b34d8aba481e3fd, 0x7a3f1ca10cdf5a40, + 0xdc9b405bbfd0814f, 0x820b788020835e80, 0xf19750e9b757032b, 0xe3ff5d7a3561e968, + 0x1acff0e88cbaf8cb, 0xd123874709288703, 0x2e335930d2b0315b, 0xdf112c63478ea745, + 0xf7402dcb081655b6, 0x0c2f3c0e22a7ca26, 0xcebe2efa42784ee5, 0x04befecf0251265b, + 0x0346f971eda4edf5, 0x7704eca3984d1b93, 0x48a49d83ba73e047, 0x53ae948d8209e59e, + 0x2899f8030b388b34, 0x8afd14cd07ad52eb, 0xd72e461689dd2a0a, 0x83c80ef495210bb1, + 0xc7541330d8c5c226, 0xa0e4034785cb92af, 0xedd64d246fecfdd8, 0xdd0858ccdd335797, + 0x1d60317c0bb8ca73, 0x27ea5ebccc381d09, 0x2af059f7144028ce, 0xbdd15ebc501ec5e5, + 0xb04d20e2f1730c26, 0x8f03fb4992eae9e0, 0xd901f027569d5ce4, 0xd010b43dc13a1190, + 0x09401ac98f37a4f8, 0x990d554c37e32187, 0x22dcb5e4f5d29d11, 0xfe3ae311551f1811, + 0x974fa9c902ac64d3, 0x00dfa29bc2c037e3, 0x82bca47a7266ac71, 0xcb63c63907fa9622, + 0x1e9ce93caa3fafe2, 0xa6fe6ee291ccd614, 0xd896ea1e9cd030c9, 0x89075b2ff2c49992, + 0x0ec3be6bca8af72e, 0xd2be8b2760a32333, 0xc9630112b08fccd6, 0x8bca645b3afabff2, + 0xf5b761eabfc1353a, 0x5a8d4125ab9469f9, 0x585bf2f83efd0f23, 0x378a35fe9ce95967, + 0x11d886e74a1185ef, 0xe15c8e068fb1f6a3, 0x67787e5dacd993d7, 0xff41886508b6140a, + 0x32c3a1ae974aa761, 0xf0db76ecafdaf375, 0xa01f4020c993020b, 0xaad8386efc4dfaec, + 0x5cc6a071f1e478c2, 0x46385d09ef52a7ad, 0x0bb1055867a46e6b, 0xbab089233efed964, + 0x30ca374e4f536059, 0xbc4a84759f5981d5, 0xd0959d3b068451d3, 0x51a57592120c4502, + 0xdbdf49d437e21f94, 0x552a91c7fd2a5313, 0x008c122d577aef93, 0x583db63d1ea8584a, + 0x56aa66633122e785, 0x7b81b9d7a2343de4, 0x85f8862a5bfc2e9b, 0xe0ec5af65ad9a49e, + 0xb827470bc999a2dd, 0xe5a1b6de58cadec2, 0x8bc3210cf522e215, 0xbb1d4508a06389df, + 0x2da65f0c89057c95, 0x0635e2f876eda214, 0x32c089c2e59c4525, 0x65aae2a4fbb75cb3, + 0xd26fe36de090b432, 0xbb3430200684de4d, 0xdf69b803dcf40464, 0x82bb016dfe2bbd19, + 0xf3592cb0d84454d5, 0x4586a81aed947985, 0x69f7b55cceca96b4, 0x6664d540dbbe5254, + 0xd65db541bd74ad45, 0x84282a5b9dfd5137, 0xe770994b4450f34b, 0x30d667eda6a50cfc, + 0xb08aafdfcdccbcc5, 0x0c1d89471f8ce257, 0x78ae466abee996e6, 0x82349f4cd9b4e448, + 0x2e1aef1942946b6b, 0x21cc959c494417cc, 0x5a3264f726f1b308, 0xa558c10a11797c8a, + 0x2470721b786f3ac7, 0xb6b6d6dd0a1feae9, 0x4fe6dc5de6211cb1, 0x4b0cfa132ce7a34b, + 0x560ee61ecc692fb8, 0x6148a4388a215b2f, 0xddbe33f17cf3e036, 0x15f88203797f9c62, + 0x4cce3d6f9c1143dc, 0xef095d16656003c3, 0x280e43ac4b536214, 0x3d45da693d94a2ba, + 0x2159543ae2c0d15f, 0xc973882483403bd2, 0x41b68ed8e5daf821, 0x2cbcbbd05f0188a3, + 0xf31139fae44bf05b, 0x2f489f3c0282cdee, 0x3fd9d215e7426fb0, 0x4251d156dedd0993, + 0xbc1f23f141bd5b0f, 0x98bfe75598aec79d, 0x83be0496aa331d14, 0x242582f87dc5dde6, + 0x9a88dd7f377807ca, 0x3fc9736c1bfaea54, 0x9e989fc51cd840bc, 0x445fc7710201dc55, + 0x25040fa29be52694, 0x83aadc69321cc603, 0x4e22a2405a4daaab, 0xb85096ca58754c23, + 0x7707d0e70f7e275f, 0xaf27e2db7852245e, 0x40fce827ce2de7cc, 0x86acf8e7a6a048a1, + 0xf6711a9b1d4e3217, 0x7db9d2808bca2928, 0x5aad01901988a5a2, 0x7bb5e27bf2642b8b, + 0x091865b808b6d0c0, 0x76630cf009816976, 0x03aa92afc0281927, 0xf091637ddabee31e, + 0x3afdc45a2f8f4d00, 0x6dc84a64ecb8a918, 0x75dc5e62fad91d23, 0x81d78e540402d15e, + 0x3dab1946a77d7cc3, 0x8dee0abf063d9c3d, 0xaa7d434fc8e706ec, 0x8674394379c0c074, + 0x0a5395559686c784, 0x26b398f16f206d31, 0xefcfbd7c85ff8447, 0x9c3c50cc5187c9d6, + 0x90172ab213b4b0d7, 0xda685ea68da7a2cb, 0x50ce5244f2b9c20b, 0xd6386467a8a9ba6f, + 0xebaf29f7bc1108ee, 0x3049d86a1ff85dca, 0x2ae6b41f92b3ac3d, 0xedf8846334a84e8b, + 0xdf7f19e93c6854fb, 0xacf8d6d21e0b585c, 0x17057643b49a9768, 0x9016fe426f7e38d1, + 0xd735d577821e27c2, 0x3f88aeaf125fc3d7, 0x31678ceca42de4db, 0xc541cd062afce3c8, + 0x6f6a499ca04555a1, 0x8373e4fcc7b859b4, 0x2b8c421faea84efd, 0x7f739d875cba07b6, + 0xe2c34bf3dcde3b25, 0xb0cfb9f928d65f51, 0xce2f4da5cc3da70c, 0x5b9e57956c441f5b, + 0xa1e9ca22cbdac599, 0xe0ac43cd1efe8e1d, 0x7a156fed01d6cbb1, 0xfd2d367dbacb8279, + 0x5e641907df28e700, 0x1de69d9e89fa7010, 0xac3321fdb2cbd5d3, 0xf52a596929c4dc2f, + 0xfbd7a21edbf50401, 0x796fdce584a6fa53, 0x732e28288473a473, 0x9bc6363e6c66b961, + 0x831cb7b208b3ab72, 0x6a169a6ceee49468, 0x5df81d9307c4ad59, 0xecff644d460e0d3a, + 0x4dfe0f29184273ca, 0x17c29c36aecb3330, 0x18a122fdca9460a7, 0xc3a65ec6c640729a, + 0x9595af04fc84bc81, 0xf28b2d2cf226bf85, 0xddf1bf088b86c0ea, 0x322676ecae70d255, + 0xbed49ae658d21baa, 0x585f6226b231cde2, 0xd472226b689598c1, 0x6a6582b67fdbaf02, + 0x8e17569c50e63a0c, 0x715159686b5776dd, 0xcc2600963f3d594b, 0x924ae839ae9aeef0, + 0xbb59d75fd24d3a24, 0xc38e56d78e5890d2, 0x8a237600f093df0e, 0x825dfed0e4a3950a, + 0xef86de56c31aad92, 0x1957c4266cb360c2, 0x9ef7125aac7b5e28, 0x86957a61de8b4b91, + 0x90b57e5b0f029756, 0x583792e1f432a3a8, 0x62f6b76543feff00, 0x56795fa689d089fa, + 0x199e7c6b2e05533d, 0xa84baba18250645c, 0x9c4b05d0eb14f1c5, 0x69f15b07b5bf9286, + 0xa469f5a8b6aeea23, 0x6cd5a1b7828f5918, 0xeb55d37d5d4bb786, 0x6d25faa01b471db9, + 0x2b3d22f3d498d787, 0xea3a60ad303d515d, 0x20696f3403e066fa, 0x2301a27198b5c9d2, + 0x695837089fa4a83e, 0x1f00bd7e68c2af70, 0x8b15e276ac37d5df, 0xc10a70e693f7d8a6, + 0xe5ec58f7e48e1050, 0xafae364650dbc86d, 0x86e24480ef984c86, 0x6a9b1050811ec910, + 0x189f57620dbd5512, 0x453dd9db26ea4835, 0x8d0fbdc9ef5f2042, 0xe56f3092fdba13ef, + 0x0fa50771ff18138f, 0x23f9a3d48766c3d3, 0x6467e57eb883edf5, 0x3768ba3637a1ba5a, + 0xd2870bb2874c8cbc, 0x5435128dc1986e5f, 0xe00d72599dbb84d2, 0xf641699da91a8e18, + 0x8cfd9fd630ab72fc, 0xa0ac261257c30dd9, 0x27a05f434a5e7696, 0x4c4aadbe9c4c0355, + 0xeff82e8d2a3723c2, 0xd723bd26bb4ab52f, 0x6dd99f1c7c244761, 0x989e5ea4f6e12bae, + 0x3b3e761c26c126a2, 0xdd043f6c26198e66, 0xa96fcd5eea7cb782, 0x8b473095533ec891, + 0xc0e9bfe4a2505cbe, 0xd48db6a85e1b9c95, 0x9e1a2865bf8742ac, 0x06edeca2523191d5, + 0x22106c276bb43e9d, 0x02f8bd46a9447b1b, 0xc13766ef7a2e0c19, 0x6055ce44db717d92, + 0xe66212413bddb202, 0xefc730f4d649dcfd, 0x2e037829b51b6fb7, 0xa14bb217e444ea8e, + 0x6ae91a0b5271683f, 0xc3a65afebd57e866, 0x4869d6687ba0a1a3, 0xb9f87d438fc900ca, + 0xb020aa83a5bff9bf, 0x5ab0ee52cc38ca6c, 0xaef8c83a2d5e1e7b, 0x23d37909de07935e, + 0x6115722ef9b4bcd6, 0x0e019ee2284ed88e, 0xe9d192940e1c0995, 0xf41cc76fa94b56fd, + 0xe7316977d8f0e1e3, 0x3a3eb032dffcf133, 0x96616d18ed84ffaf, 0xf2449df9bf495f33, + 0x837517b4a33e9233, 0x6b130eccceb16a62, 0xfd524e00fd8b89f5, 0x059681b1b137984c, + 0xec55ec114f985a46, 0xdadcffbee9e93170, 0x8493565ec4298bf8, 0x67663276b7dc8e57, + 0xc611c696a27da8d2, 0x1a140f38a66be0d2, 0xa955d1f148cf4c51, 0xb8049aeb334c5d4f, + 0xfae3195f20a51825, 0x93e82e1b5ad618f7, 0x7bff8157c94302f5, 0xb40cc0bb9347f36b, + 0x0f7d12e529402a21, 0xa2a6f38120935cc8, 0xabffa6b58a8b6d97, 0x110b334586a0effd, + 0x0d2008928878ff00, 0x51ad6b4f06ba05ec, 0xd4b2f05062eb80e7, 0x0668b6741ee47257, + 0x8021a2b19e1303e3, 0x55e75c7193aeffac, 0x8176ddca9f114a47, 0xc57eb42277934adb, + 0xd70f34e05bf32b0b, 0x26b3400898fe9c86, 0x542566861fc57fed, 0xfb6b3f9c59129a6b, + 0x1905e0c8a09d5570, 0xf98d2e87bb76041d, 0x08da2dc8907e3c51, 0xa156a34d4bef0c97, + 0x01ff77040f7a82aa, 0xed4059fc4486e33c, 0x28c0d2c3e8e161a2, 0xf813c406442f805c, + 0x00d252cd601bd475, 0x3f721fc0408e0e0f, 0xa45b140bbaddb6da, 0x2109d08354ebe60e, + 0x46b5fe8432c10ad7, 0xdd00f7f6a0a9cd53, 0xcd2e7488dc60fe66, 0x0503f646f5334888, + 0xd04625d78650200a, 0x9c4e86d7c5dee07b, 0x92bcc468884bb3f5, 0xbffb2cb24b27d36c, + 0x440aab66e17c5596, 0x4427468ae7770e3f, 0x0b92e422d32f73b5, 0x2da47f1060a57327, + 0x861b4ee0a33f490e, 0xe13a977be37ef5ff, 0x135ddfa90e432924, 0xd7b16859f33fd28a, + 0x2cf74ce9dd3984dd, 0x2d0414095551562a, 0xf71809ae7cccde01, 0xd8e9a12cdfe24102, + 0xee8fc3ae2b86b559, 0x6d77ce1ba5d1966a, 0x3d24ede68287ef48, 0xaf3f4e4cdf50402a, + 0xa2f943b82f2dc17f, 0x9676743a3737affe, 0x0386ad14daa79b25, 0x2be1d05b6b59fc37, + 0xfd62b81a8bccc759, 0x6af6920b60b30ba9, 0x15406d48c90c3899, 0xe99260f48f756349, + 0x741215d55a5edbc6, 0xc0922556054dd7e7, 0x3539f0338a3a6a49, 0xb086aaba5736fb5c, + 0xa4e93e79e281dc96, 0xa6d280978f9e6abb, 0xc8ecb766e5c0b9f5, 0xd1debdd51c2c4be7, + 0x0398e82d28b0222d, 0xa1f4e03158939bbe, 0x0dc2fc6d3eae1ad3, 0x525d2374a8884d2a, + 0xb09f3817b5601a95, 0xa69bb7129d67c481, 0xb8365b56c5cde395, 0x5fda8e56c8f96a12, + 0xf0cf05327c18c60a, 0xbaf0c4cf91ae28fc, 0x8c08f1ffd788d990, 0x0a063f0ec21b43df, + 0x6e3d394ef7a8c3a6, 0xba8406488a834a20, 0x1878a78e7eb757d1, 0x54bdb3e9cebd6f0b, + 0x5a59da503711a3de, 0xf33450901d888b75, 0xe2ecfc57ceac7ccd, 0x3607c106a9c3147c, + 0xadd154e3a4c63f11, 0x77ae2042c6a49da3, 0x05ed7f87939bc27a, 0x2b8db4a0b0663763, + 0xa55cecc1e045fc97, 0xb4f731f2e77fb9a0, 0xf0de9477fa8b7716, 0x51d12aa191425444, + 0x9269b47ca7c091e1, 0xb9f3637e5a0cbb24, 0xa6d8dc6afa015fcb, 0x6df02641445b634b, + 0xbc9dea4388f7fbd6, 0xe3bacdf999444007, 0x2466ae8df34cb8df, 0x78b9a7cdcd780fab, + 0x6bd239e7bf358251, 0x5fb3ec79dd3c8150, 0x3479966b02cb5e74, 0x5e058f86ff22035f, + 0xe28a3f5c11ebea83, 0x935df6d1fbf5c9a7, 0x0e7f1b6853bb8b9f, 0x7ae41bbc703f7af0, + 0x905ba15b6c83c3fa, 0xad89bcb8323013f3, 0x85cf1658249f9117, 0xa06ccd00aaf6946c, + 0x00da5de225bd1822, 0xf9cbc394a9b8abe9, 0x19bb8bc731986b94, 0x23e4358bf16dbbe0, + 0xb9f00590075d84ab, 0x34bc1cbf7516d73d, 0x62f4f9c6a57d36c5, 0x45bd14fb72e05088, + 0x424db19529da11af, 0x6272ae67e40f11c3, 0xf328c97dfca0cdf3, 0x741280f70c408847, + 0x7a21ef0a09ca3f74, 0x7bffb6033754bb8d, 0x4bd63970e8e28e68, 0xa2fc3192f9bd4a1c, + 0xca3c94b5bac44842, 0x7da26633e1a69555, 0x98095690e9dfb8d6, 0x7cebf7bd4e03f227, + 0x591fe9f6f7c57987, 0xf67e6bac21ecc8ee, 0xebf64b48bf0b7081, 0x40a57000b8acb1c0, + 0x0f3bdcdb7fd35527, 0xf4b48cd78dd77361, 0x3873a90e1cb47267, 0xc142071811362830, + 0x64d463c7c6f36eab, 0x24cc5c000bb9c4c9, 0x801ab019b494f8fe, 0x60ffdbe3f237b6f6, + 0x0428cb42ba704a79, 0x7e37d7c39bd3be3d, 0x06444497c73b5999, 0xfa58699ee3c77811, + 0xdaba09e23eb7df5f, 0xe02a645340cad7b0, 0x1a706cef7b97acc2, 0x92ae32d7a45396c6, + 0x8642d5f1799697bc, 0x0e8ba43b9aa5a1f9, 0x423df6548c7e71a3, 0x4d74c9f752e307d9, + 0xdb776998cb1c1b60, 0xead5079b71690f1d, 0xbd4785828f035d8a, 0xa58c066600b64be2, + 0x2ca9f21d1bc222e5, 0x6aa6577f4cdcc8d3, 0x0f9e36a998b2ddbd, 0x803eca39b4ec0435, + 0x9611cf589cc10781, 0x4f08217aaf31642b, 0x09677b7ca2444103, 0xd3bd98fbde813c2d, + 0xd0c7155385c10bc2, 0xd6d2a2aa01e517a4, 0x4f2d72cef5c860ee, 0xd79b13d5b67f1ffc, + 0xa06cbb17581bd8d6, 0x52b6e7246a046b7d, 0x10e13e6e35256845, 0xb30aad844e61ee16, + 0x2456fda36541d43a, 0xefef2aafed01363c, 0x4b71f214a218b3c4, 0x36c1716af64cab86, + 0xb837353447ea0af8, 0x3fa4d1428f39fd10, 0xf45d5bf1b114c8c1, 0x49d24519283262da, + 0xe5c69ff535678e18, 0x111559430c0dab4a, 0xf23fd35ed071cc0d, 0x9281b41c73e74f08, + 0x71222410af683092, 0x0021fe2eae1f27bf, 0x3235dc80213a5ba0, 0x9a86c142ba1d556e, + 0x70761373eb5a1973, 0xe79dc5ea92dd3ffb, 0x5e09f65aa4b7b130, 0xa7c0dded1025c808, + 0xaf0dd7639cf34395, 0xab014049b8c36760, 0x6795656e53d283ff, 0xc6a688160bc12356, + 0x491abf9ee5d6eef5, 0xbcd395505ece3fd3, 0x6491967585be1bb0, 0x036da8dbbfe0813d, + 0xf9b0da016f74622d, 0x9ccc375a83725472, 0xde264b42d1acebbd, 0x08b55366f65d8750, + 0x9f33eca6e36eaee1, 0x6c69264dd6b1786e, 0xc8ba6347c5299510, 0xf6be6e1bbc730900, + 0x3d0e71f2aaef8a61, 0x69db7db8cf4a51cf, 0x17b2eb5455877357, 0x9f219fc4c1cf6386, + 0xdaff6fd5a44f25ab, 0x2f09b62a2d707eed, 0x0a713782e514055b, 0x3a5b047015f5e86a, + 0x24a4b24b603121e6, 0x5003a509f76cb109, 0xf75047311c2968be, 0xf5a8923465199c4c, + 0x9fdfa7b1c66a7889, 0x376d243bbe32bd75, 0xd6027ca75658f114, 0xa6fd2641e6891e00, + 0xb43e4c693aea9c70, 0xd45c0ec98ddfdc54, 0x9271020c1d4d1652, 0xeb6768a4eda07cc3, + 0xea1d572b753a9b9c, 0x961e3a2ce62ac9fa, 0x380bec519a20e828, 0x084a5b8078753f1e, + 0x4bfd323ff235614a, 0x7e1826b7e2a4f802, 0x88b494a58469b096, 0x2f27a05c881db5d8, + 0x3bfad091366abdb7, 0x3458c6f0d466f9a7, 0x9c6400d1423a1d87, 0x67109c5acc7c9ec9, + 0x1db3cdff4a7d8a3a, 0x43ae8e8f7e4cbf7e, 0xe70cdb94b4f97a32, 0x838150324d5aedcf, + 0x0011da9fdc8db66b, 0xee412946e8b65e92, 0xa776838cdf5e7498, 0x307d10638537ad0b, + 0xcc9475dbb5fd8d1b, 0x30bd8c901d1cb462, 0x117f0173984e34ec, 0x358225662e17f13f, + 0xe16fb0e348d90dc5, 0x63b6a2edfc4db411, 0x3f02138208d2fa84, 0x807e6d4e08e1bec9, + 0x36ea4817580571da, 0xd80f73dfb1c53d46, 0x0811d27aeb8bd1e0, 0x18cea70472f18b00, + 0xaabcbf3a98956a64, 0xe53cf745e7e224f3, 0x5169a52ee170aa3d, 0x43939fb1d5f917b2, + 0x55e6fa23eb41ce0f, 0x66ef1d5b16bfb849, 0x74bc5078e86ce7be, 0x4612196f83fe0295, + 0x58f3443f9bd95107, 0xe1b6514110acc4a0, 0x02d2f7c45959935d, 0xd1ea3cc94d35a619, + 0xda6bd344c4cf297e, 0xeaa73a676cf3ac31, 0x19902a28fe1a681f, 0x46bbd3d7bf2988e5, + 0x038890e53f17a35d, 0x8e20f907700a5f54, 0xa25548f72721fa0a, 0xb89fe306a395a494, + 0x56dd6976ee8961fb, 0xfccba90313321dd5, 0x278641d837c426da, 0x8a5966c4aca81763, + 0xb6ca52ed6eda47bc, 0x361d523d8b994b85, 0xd3dc0fffe6bf6d55, 0xa793c574f6d82bcf, + 0x0fd982f75634e516, 0x804e4d8a7f32de9a, 0x20b95e9311dd04b5, 0xda8dd325dc323d97, + 0xd3a5fea0b8a7ea87, 0xb9b837e9b1e22dd3, 0x88620be8c24a55bc, 0x7e35eeb871f3808c, + 0x48ed91d621135926, 0x8e2a9442f653a8a7, 0x18252919c34bf7df, 0xbb4b161b875c92fb, + 0xf77c5f1afde5eeff, 0xb0ac415c7a44b1eb, 0x4f0f0d83f2552cfc, 0x96c5656a26c7e49a, + 0x18f65b433071d6af, 0xb21b265cf4716174, 0x4b0af600eade3682, 0xa2cab40510636435, + 0x4e5c932cc68f7a25, 0x865e091044335e2a, 0xb4e818a5fdfc67cd, 0xc3fba0ef0e01108c, + 0xbeb68bcc30d55fa1, 0x89b8a21333a81f26, 0x649d2ff63767230f, 0x18d014adeef9923b, + 0xa488f826bf518963, 0x8c2bf807b6720384, 0xf1cdecbb1d1a0053, 0xe2ffe1ce595470bd, + 0xdbdedd5c2e4b8d22, 0x82319bf31047ef0c, 0xd27eb197bdc40e2d, 0x4e946c842eb930da, + 0x51c1f990cd488231, 0x89e4835cebff8cc7, 0xc664c5adcf0bb5e8, 0xa7d7abc311bfb777, + 0xa809df4fbc098c18, 0x2278ddc92736d640, 0x5bf517f60011cb3b, 0xa8166816ad81f4a3, + 0x677de8fa3e0950fd, 0x70945372dbc8a843, 0x841add8bb5292f82, 0xfc3f92bb85674672, + 0x572dae5ce80170a9, 0xc43b7f5c826982c8, 0x54ef9b0427b8ce97, 0x7c4787a4cff5e845, + 0xf4edd06221bd0781, 0xca1f7ac267f5d972, 0x977444da04544717, 0x01a3bde49b885150, + 0x5a4c6bf8de8eba0c, 0x43d19e11d079d21c, 0xb5ce0f863343552b, 0x24767aa1039c3186, + 0x334726760c256dc2, 0xf2699e81767b882a, 0xe33735a5fce07535, 0x5e7bcd0a0b4833b5, + 0x8a1ebe9f04da7755, 0x4ccdbc7e5ba1a501, 0x6b030d885b50a549, 0xa269e97049eccce4, + 0xfac7a1a65195af42, 0x5a99168aa81548c6, 0x5f5b28dade633e2f, 0x4eaaba4a903cbc36, + 0xaaf3813c6c7bd0d6, 0xb63cf9789d4e3ed1, 0x0d5961b4ea16e73e, 0x7cf838150fda4a8a, + 0xcf0effca9543a364, 0xe6fe2dfb72eb95be, 0xd451efc89643a616, 0x98249eceeca42aa4, + 0x03d3859e983ee29e, 0xa0c5f35563abfa8c, 0x1835c606f4530e4d, 0xd89e23f46dab0703, + 0x097a16956bc41c99, 0x7c1fc2a3c9294712, 0xbd65cc0c0c7aa45b, 0xf4dbbd2ec2de9018, + 0x0b4a95f2fd75ba2f, 0xd22ddb46aea9b5b0, 0x2ffe87e160450eeb, 0x4a160a5bc7dbe57e, + 0x4a3d521fd2faeb35, 0x5163f4ce0dd82b99, 0xd876f3fea50f392d, 0xe3810c9c45dc9719, + 0x7a724a8a7caff212, 0xf510665a4d84f979, 0x6fddb5528b9c7293, 0x25232da0767666f1, + 0x3654883a54cf8251, 0xed1e42157c12aadf, 0x9914fa7100252620, 0x6a5f2ea4f2592cdf, + 0xa19dbb7c5b7a0c2a, 0x8351f228060f8b5e, 0xc9875792c4da3f64, 0xb71f5d2d9544f2a7, + 0xcc2dc9f3f91639dd, 0x7312b20fd1884024, 0x61f5fba2a1ac44e8, 0xe32d9efb6ba7bf41, + 0x8b504089dbde590e, 0x020fd96f94245b4d, 0xa0d1fa5174172893, 0x30e739b7e0139f00, + 0xce5a0c56ffc722c7, 0xf4ab7115c235cd18, 0xbf77b6fb64cd6c72, 0xfbe71e93e4d5aeea, + 0x6fc83810dbd3772f, 0x324665c12c65f909, 0x9acc35913a68c452, 0x7184d85203ed1b67, + 0x6b13cf03ac66113c, 0xf0e187d1d6411359, 0xddf76ff0f076dbf0, 0x478c361636d84f45, + 0x37a18e71e89b819b, 0x642ab6cb83519f78, 0x3761d5b5716ec931, 0xd5f2ba722134b7e1, + 0xb1f7d7734ab04bca, 0x894bb458296adc56, 0x3b177a5954823584, 0x48893f5f044cd931, + 0x0e35f8103d17f4c1, 0x4a771c9a0d87b6e8, 0xe92a4692ca951b33, 0x6b6e08eb8cee9eaa, + 0x4e5f7f611fe218bc, 0xc78e5e746ad2e1b0, 0x61dc19e66c5f2020, 0xedfc2453e712d885, + 0xd6c6a7a116c3f434, 0xfd43b0cf591b1005, 0x2fdb45c9307fe0fc, 0x8d8ff6fa5490d31a, + 0x6fe72823341b9d3f, 0x7325afcd3523fb65, 0x2ed780dfec0b53a1, 0xb9bd9303dee7c441, + 0x90fbf652605b1f69, 0x1cfa8400dd6f0f7e, 0x0eff86965a7803b8, 0xdd8a82dd9896d1d5, + 0x97bab61bdcfa82df, 0xceb692328e69ca54, 0x1fae73657aebca8b, 0x09a2b65035b66593, + 0xfdbf6e82c1457775, 0x9c44dd4207c3556d, 0x1eea947a6b7f498d, 0xde16f234b1569aed, + 0xe30dee5be89ef784, 0x2f5b2d807d72c104, 0x3f926318132a8e34, 0x36d5aeb1a76b309b, + 0xf804d55b16948840, 0xfc0c7d4c1eab6322, 0x7c90c32ed3bfaaca, 0x774319bcd50b813a, + 0xfb4f7321885ebd4f, 0xb8cec5d13d6fab77, 0x5e58ef435ba6ae0e, 0xe45b90ac494722b2, + 0x03b25f7fdf9d623b, 0x27062068d0668e18, 0xdcd6ab1eaf04d664, 0x0da7c297e5de6b4c, + 0x9229827e291691f9, 0x6cb06927990a70c9, 0xcdd20c9aa5eead65, 0x596654e45186f44b, + 0x471f545cc5cc16de, 0x3014fd7e3190d5bf, 0x10ac3bcfb831aeb5, 0xdfc943ad3cb13b79, + 0x262034a90d124eba, 0xcde6c918d3afd160, 0x9548b990234f39bd, 0x1b5ada02ceedfc03, + 0xcee63ee0fde3762a, 0xf3996803f03aa77c, 0x41a35cdab854ef26, 0xae2cfa952e691b6f, + 0x52ad694bbb2ab64e, 0x734801fd0e38bb47, 0xd9f03f6b5c5f9a54, 0x2abb04f54b216858, + 0xa0847afd98da5814, 0xf033bd0e08766395, 0x7079bb31acab72b0, 0xfe5a8e9762f3fa76, + 0x7eb654b3df13cb36, 0x384f87e8554048cc, 0x1a1ee2db5fc3fade, 0x2fb01bf6e736953b, + 0x5657fc2db66b5b90, 0xdb6562d4dbea5830, 0x3d401d6550b7bf37, 0xb1d6b256b2c14a09, + 0x5152cd0d3b516161, 0x081b92b859dca783, 0xe9aa2fb077c1c725, 0x891841f7721bc39d, + 0x96d77cb745ce854f, 0x2833bf83bd7ebf8d, 0x3888d223822eec52, 0xd6d6df3487693d4d, + 0x129d819ddb0eb92f, 0xf43e9ff2b52ffd04, 0x33fe019fc1d6bb2c, 0x7efaead9c3f4eaae, + 0x67590d94cbeeb19f, 0x9b11beda6bfb9aab, 0xcc87b4e6fe37c5b9, 0x7f00133d26c5c9a4, + 0xf14aedec89f95632, 0x555e9c2755e49a92, 0xf37fbd4e5efcf585, 0x1c5fa1fc9e8996f1, + 0xc26a6e208c82f436, 0x3cb64b62590f9850, 0xa2e430772a99f913, 0x80e4db30b6a685e0, + 0x8eb787947bc5acc3, 0x44c94fce35c5d71a, 0x424832600f0cd2a9, 0x47937104efc9cd13, + 0xe8c12bce3b926f3a, 0x6806d5ed2892e6ab, 0x6d3f6ddbc4fc889a, 0x0ca3cb42fb90a983, + 0x2531f5ec154bf791, 0x807416298ffc69f3, 0xa2504d8a1e85097b, 0xbcad351327defea9, + 0x226bce3a141d5c4a, 0xfcd6099518bdf4d1, 0xf1d7469848fa3286, 0x39ca944a4e5beeb9, + 0x365766e125dbf7ef, 0x4923729af4a39330, 0x7ef9b8ef1d820362, 0x46d915bc8cac7217, + 0xfe653ba0cd05973f, 0x26e918c661ece05a, 0x0b5f250c67807f91, 0x04446de867b2d67d, + 0xb8b8e15aac930e2b, 0x127ccad58e203412, 0x9cde938e2afd7691, 0x4a269e6742f9e29e, + 0x626c62b38cef6888, 0x4c2cd6611c363492, 0x67610970909f3b28, 0xca931852350107bf, + 0x03b6074f50f8b5ac, 0xfd95c1157187c48b, 0x8529cd4dac4cbff6, 0x89e6f64c73120f94, + 0xdd85ba4f8c6e40a4, 0x1de26f3101ab596d, 0x3c86925c858ae8ee, 0x8f4ebd29a844ea53, + 0x32cd8c3491420b2b, 0x15797284be363b19, 0x10d48e3e8647803d, 0xb46b8b687e9d07f7, + 0xda65dec41a863152, 0x2aa08ccaf0765bae, 0xaee27fe7bd31421b, 0x71b30176617c9faa, + 0xf56715e8429ff98a, 0xb77de5f0805edcf0, 0x050c241c4689c2c6, 0xca7e62e358420209, + 0xf1dae48caee3a894, 0xb6346a5d18a84267, 0xcceaaef96d8b393f, 0x0f2697c54f4bfa4d, + 0x19361d5c9245630b, 0xe0d245bd737d29fa, 0x1d52512e1913946d, 0x106d4603800628f4, + 0x4da7479d52d7e546, 0x797c4676ab51c438, 0xca5c43912215ac5c, 0xc4db220e685e6d32, + 0xe52c016ec199e5c2, 0x9b7baaf2a8ee7217, 0x9826ab0f838f01db, 0x86cba2271912032b, + 0x56262063552d2b5c, 0x450bb23115c9ab54, 0x55a0de29091b54ca, 0x5342f55e7da91227, + 0xd82e73b723dd264b, 0xa933f9d1a0f67a82, 0x6d277f6a31b49958, 0xcdb3cee9a397f84b, + 0x2f63527af49b1257, 0x23cbeb614c613c62, 0x00164bed84146ba9, 0xa40d2efe8f8055c5, + 0xab261615d5216360, 0xdcd5b45dd0f68918, 0x5e0480ba35f9dea0, 0xf729a9146b75a1c8, + 0x94851a59a5d6d12c, 0x061c60fe1539ddad, 0x48775e0ec16a0c93, 0xf04acea34a515c70, + 0x836388b897cddfdd, 0x8eb2d2bcf8972d77, 0x85e5fa032e97281d, 0xbb6290eac0e1fa2a, + 0xdffbe29d75addbde, 0x5431d19b71b702bd, 0xa5b945a6bbf8da6a, 0xc82e11ad55a720fd, + 0x170def3fa204789b, 0xe787dd4037dde6c4, 0x0992436c117d8c39, 0xc57a79680a2c80c5, + 0xf44d2627cd5eb3cb, 0xaf8c0bbbc5125db2, 0x588ed49ae87f854f, 0x3995c10b20caa137, + 0xc857cf23ef261b4c, 0xf568311d9a422fc6, 0xe50cf5df6749202f, 0xe4c468ad210199c1, + 0x31846b35709ddf04, 0x58aa160c7b0d50c6, 0xea94ae873e4ee8b3, 0x0c8dfc4383ebdad6, + 0x1684c89fbab171df, 0x3b883b7099959c09, 0x047dba0d5406c815, 0x5795ea6dc2dc8a0c, + 0x219872ae9c3f5d79, 0x90ea8b0e0ddfbc74, 0xa44321c7bbc1230e, 0xb52ec17124029687, + 0x82a59fbfcecbf584, 0x3c4008fa3c17e00d, 0x4f4bf18bf5f609e1, 0x48ca9979ddf51b9a, + 0xeeb48d291fd2f6c0, 0x4a60af2a44fb8655, 0x10933220c39017b7, 0x0984db572087fd81, + 0x48ffca03edc8fb5b, 0xce89021953bedb7e, 0xd8a6eaca6ba02589, 0xdb36f70df6cb3d6d, + 0x629c750f1d0a6112, 0xa9652c0d96166ccf, 0xde07a483612f6ad0, 0xc37397912e8d5369, + 0xe5680e9b468ba2bc, 0xd68ec53ed29fdd90, 0xfa5186d2ebb35d3b, 0x371f138509a72205, + 0x448f17d58d9a6982, 0x67a9ca2c02b63e35, 0x9319abcb6970dfe9, 0xe24b30d965a3bc79, + 0x2482990fa14da633, 0xd32c1e4d2a1daa74, 0x0c500f5d0d7a6047, 0x22e47dc2fde5b900, + 0x537691218cbcb017, 0x8f41baae4155dee1, 0x5b79955a9ae9f47c, 0xb13d43be52d77579, + 0x2f8ac58e8478304d, 0x4e0d3845dc5a057b, 0x346f87cd389f03c7, 0x2a8270467253786a, + 0x02d016306f0eb643, 0x665b17110188c8af, 0x0eea6d49bc814866, 0x7634fd52f845a73c, + 0x74f041b3b7936198, 0x544e02bca5e4d0ad, 0xbe9d2fc71cbc0b66, 0xf28362e6d6bcdcba, + 0x5bbed1a027a90ba8, 0x1b38765f7d10f6a6, 0x7d4bfebb137f62cb, 0xf55eaaadab859e15, + 0x53a63d8691512c24, 0x6620bab264cce94a, 0xec8e6cebc0ae96da, 0xa00dfde6d4e760b6, + 0xe8e107f176f23eec, 0xee85fcbceef2d99b, 0x5ef324619c9e86ae, 0x035203484036ccdd, + 0xa00a56ae95798d88, 0xcdb835a27ba6201c, 0xdb5c2e269d1e7c2c, 0x996be50fa8a6fd2a, + 0xc768081deed8c76b, 0x267b83ae8b33a151, 0x280e675bc71b7821, 0x6d250265f629af68, + 0x47dc097804b80f1d, 0x338e97fe29ca9612, 0x08b6ab50a563c217, 0xdce0b5fc55bf9a8b, + 0x28966b5b58e37c49, 0xbb61f381e6dd08f5, 0x984e1f451694c1f3, 0xb063d92809efab8f, + 0xf0cb696ac9cd8d5c, 0x495cead9d9f305df, 0x8542890ccfc7cec9, 0xf8b4ddad6a3470bb, + 0x5b9376d2d70f7170, 0x8354fce1357452fd, 0x8f7396213f4940a0, 0xd017f9544ff07e6b, + 0xc98e216f4345840e, 0x96ec9d0d96ea2af8, 0x608387188fdaa72c, 0x23223ef5dfae2ae4, + 0x821fa908a093f579, 0x994394362025b8d0, 0xe98ccd2b79c3bd28, 0x7da17b7fcb930dd5, + 0x1506ad9e4f0b6132, 0x4db8ed055d7acbda, 0xbf9bbe7a83e70b8d, 0x0b1450bf0faf1a79, + 0x89635ce3b156569c, 0x790fe7894c11d247, 0x31fb3c25274be716, 0xeeaf58e7aeed9b4b, + 0x85756374c2348f61, 0x746960064c140d29, 0xb219fe43d689622c, 0xf6265a1ca4ee2f52, + 0xdf309d0b7e38cb72, 0x177e69796db5285f, 0x8236ef5dd31b8858, 0x97d93a73078961a7, + 0x5bd23396136788f5, 0x6986739ba20166a2, 0x83eb5c797a59245b, 0xf2d3b7276c17ec65, + 0xf8adc62e69e580a8, 0x01cc76f68a24315d, 0x6f610039c8b03937, 0x1b07d2e897508fb4, + 0x26bbbfe5719f9184, 0xac3322b6143ddb44, 0x412541cd74ce1df7, 0x6e3c9e65639f0979, + 0xc64afda0c2e3cf09, 0x6b5eb4837aef853c, 0xfc91fc6ec0cf4d07, 0xb4435cf79ea6d6e1, + 0x8f87aa85856a1ff9, 0x8d5919d0266b42cb, 0x230cd605a3c7f08b, 0x7e65c7d353c3488d, + 0x1fd6b143690312de, 0x46da922b22ac95f1, 0x2342b43ade639535, 0xde9c0a1a076883f3, + 0x60a1756999d15f5f, 0x0f2cdb7e8901efc0, 0xb4f7ed9cf0046990, 0x5b1201b980a2c72a, + 0x0c2ec9f6cdecb1eb, 0x32dbd3b2810c5662, 0x23b753c42668271c, 0xa01640ff8c8739c8, + 0x5a9199bb5728092a, 0x25d2ca26d9c53b26, 0x44f2f8284005afa5, 0xa1db4518f574ba86, + 0xce859416b8c797e0, 0x1c4715a2147b78b9, 0x2373dfdd54680621, 0xf1334b2aa238c807, + 0xfc1447390c542407, 0x93f2cfab65f79aa8, 0x5cb0dbb0b71e1e16, 0x519a51074f2a9f66, + 0x46390e30b8513a05, 0x7c3abc675e702bdf, 0x8eafa9b485b7e4c5, 0xcd2fc931d0dcda64, + 0xc102d501bb1097a2, 0x8dc78457038ae8ea, 0xb63ca7df30fe9f8d, 0x2d8e4ceb5eda157a, + 0x2b77fe5b17d3f27d, 0x2dba3106d8bf046e, 0xb7152efe034ebe33, 0x5c03bf7ece3590f0, + 0x00fd93cc6a097947, 0x53eaccaf4fff8f0a, 0xe8b0a7f8d78cc825, 0xb0a23fad2c489566, + 0x3e7c2cd6784abe6e, 0xff4c39e245cf6f8a, 0x24a1d91d4f294d1a, 0x136eeb7c6d3b6189, + 0x215895ce94547fee, 0x09fe927293b292f0, 0x56e5982ccd4a4293, 0x51e889dff0ee5e43, + 0xf7a70d9382e5e41e, 0xd162f758ef9f0e55, 0xd1c13865c279058c, 0x9a9554e1be0d9f1f, + 0x99e2672f45e7e545, 0xad5b6d2e1c0e41e3, 0x859961fbb4194557, 0x38ff0c816fae2c6b, + 0x2fb6d6c5e82d5a4f, 0x6a0c935043f7b94f, 0xa0a08892ebcec506, 0xd2301ed516ca7a6b, + 0xbfadba7ed810b49a, 0xf0ef116416cb6524, 0xd79def8a7e5ea8a2, 0x0233702c2fa37308, + 0xdef86fa215c6c23f, 0x887d7cbcbe16969f, 0xf686f8fe0f0aa7c3, 0xde872eccb17a94d9, + 0x1d27e081e38efa1c, 0xfe79062cdf55551a, 0x67cc3026b54d63ca, 0x2d301a5b6d848131, + 0xa63be877b21e4889, 0x25bfea0452370cc8, 0x194d5916b50260e3, 0xe59ac425deb6a081, + 0xfca24476093832f1, 0x303d5d88d7167cf0, 0xa6a30243def4103d, 0xbb10b57795c11dcf, + 0xe12e01f0181e6a22, 0x6ea668816ca767db, 0x2f70a589194823ae, 0xf8cd73576c460fb8, + 0x7c08658f0e65b5c3, 0xa13248b96e31bc97, 0x2189ad821c3dcc22, 0x7cc1f02d04e36b93, + 0x4fe14f7dbc2bb07b, 0xb49daf2f1573c7a3, 0xff90e90c59b8a003, 0xf1060688d2ce4ab7, + 0xed13d1e16cb0ba0a, 0x13018d6a51075d3d, 0x784513f3d2b36a95, 0x6aced115f206b8d6, + 0xc279e0c9a8971fbc, 0x77c562d116835fd5, 0x094429f005e55b30, 0x7923ddc3cb1c8697, + 0xdffc48e089a69fb0, 0x38424f42639d649d, 0x34c7541730be264f, 0xb7fa5db0e79cf118, + 0x3adc28a4c6b50c52, 0xce403a6c98e167ca, 0xece839eb995c4f8e, 0xd40200735402aca9, + 0x06ea2142714b6ec5, 0xc856c08811220f1e, 0x7c3a980f7e42ae8f, 0x5b48d9dbc4bfc58c, + 0x9c7b3294c402e28f, 0xc8f981ad2064dc5e, 0xa965b16e5dbf0e89, 0x3c606d0e5c43b1d4, + 0xc7036a98b326d1bf, 0xc03615932c426a1f, 0xb46d6cffdbaadd17, 0x03a92f24d97fed8c, + 0x5b82141391dce7ab, 0x94e6c4f4aa30e9f4, 0x2881be22f97b35ae, 0xd697ea2fec9678a3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x792a5be3393fbf15, 0xe0b9865761cfdf77, 0x74f1c27eeb3cafe4, 0x77d193fef13edcb9, + 0xe7f7c64cb420b8f8, 0x030a0480b9843eaf, 0x828c2d9d27fd1ef3, 0x8a354c4212ea5ff9, + 0x367fde4141a343ce, 0xb1b932409a6c4f24, 0x204218453911e128, 0x982295afe9c5698b, + 0x634c3c14821e578c, 0xa70197b023a501ca, 0xc239f3196849921e, 0xccf6b6247c8b030c, + 0x8a55e6d30aaddbc2, 0x005a4fb89dd2bc3f, 0x94fc3fbeebd6421f, 0x058e1021bdf4efc6, + 0x5a4191bffe8a18b1, 0xaf49aae1b9b12749, 0xdf9f5622da628b47, 0xca4f5c8da9fe0113, + 0x196a842302bd8d72, 0xa971733f5e59afd9, 0x60bf28c68a13a7f6, 0xfb9a88a4e980844e, + 0x7b6071e0c7fe4c10, 0x336667a3a939ac53, 0x1a1e64860ca2c93b, 0x019e586a940e4203, + 0xd2c212dd676efff5, 0x551ef7906b62c4a7, 0x9b08fc2b5c0082ad, 0x585ec19b057b1eb3, + 0x8adba1a7acecac55, 0xa8c55ddfbfd30db6, 0xa1c4de6e4f2e139e, 0x7a00e079abd74ab8, + 0x28c5a27849a84e93, 0x34a1a9e85d8f8e3b, 0x4743b46cdd5caff1, 0xc3e8943269df5215, + 0x19347096e4ec78e7, 0x901fc8bdf1be1a2b, 0x265337d60231efbc, 0x3962f80e26bbf4cf, + 0x63b6168ffcc81ce1, 0x1ceaea2301ed6ea6, 0x72439c1d3f357986, 0x15ee370d88e3e954, + 0xc993115de2cd12c7, 0x81a69965df63879a, 0xcc11169db946c0c3, 0x5131033b74dba5de, + 0x9abf993c8e6ad907, 0x85a138bab357ab92, 0xc68b86627314f971, 0xdd2568b2cba3ed25, + 0xf1bf2d0dc15b5d86, 0x1c814713f0317df3, 0x22b4aa44aa517656, 0xc3a8ae07c6e96382, + 0x9ff622fee0b777ab, 0x4e1fad864545ad28, 0xa8b8f6eae7299e95, 0xc0c4e8aa2ab89221, + 0xd20536e3402e46ba, 0x89cf88c91ddd525b, 0x88ba3547be633756, 0x2529f82165508a2f, + 0x82c757400c8c7cc4, 0xe77f1dc074b4bd23, 0xeacef2cd0997c63c, 0xec63a55e5c9292a8, + 0x4f90a50c2721e1a1, 0x95d2d0a27bfb1eaa, 0xb54064fa54bcbfee, 0x1b0d49993081d506, + 0x65bcdc0bda212821, 0x3d3d6645ea19bbfe, 0x556df9f4e5d069ef, 0xb72466807e9356ca, + 0x54e583aa13b09f97, 0x5e2cd7ba68b3c108, 0x81b8e989240891ce, 0x34388169b8abe0c8, + 0xd5dfaff6bbfa901e, 0x8f8ab8d46d369b02, 0x624f47338bae9f15, 0xebb6952f2f0a7c63, + 0x416e4e3aadde4bbe, 0x0ca0510fe2e51adc, 0x9a4e23c41756d438, 0x2d1176839c447c20, + 0xd4738f69979559cb, 0xbf283beb16b52156, 0x846accc4f6421b01, 0xf17457a6563d219d, + 0xb558986701f9e3d4, 0xc98475d74fb28d16, 0x63ed9b34e0c46807, 0xa745e38c0872e61c, + 0xa35df7a5b33f8015, 0x3060b130e3860e44, 0x3e8f4dc3af9a745b, 0x8e828ba1e38fc46a, + 0x98781b5fbe6f622d, 0x58d563ee175cb474, 0x40cd85d6e5067de6, 0x5d6298c976cbb7d6, + 0xfc94dd1d0f6ce428, 0x0c3043df87a15bab, 0xd681746bd5c25bcf, 0xcd24ce56d3596f64, + 0xf1bd06e02d0e9ceb, 0xe545e54b912cb0c0, 0x2900d8480070067c, 0x46d082d5514dd43d, + 0x9f5e3af1e8537e18, 0x03d409d6def7b57c, 0x7b1bde65687184c1, 0x87eb10f4723bf59d, + 0xf5910296449b9958, 0x99889dcacf060582, 0xa89f9d3e0717f631, 0xa093d3be317b0e2b, + 0x75e0601112e328a0, 0x662f2d345c75d8a1, 0xa3b620046521d399, 0xa5de5ae77dc1c909, + 0x329b7dc8cbf04401, 0x23c8fce90c829d07, 0xdbf52565f371df62, 0x356065754b271424, + 0x8fd6f37a8caad9df, 0x19e4404e1649b089, 0x0a102d29053f4f61, 0x4782f4a7d89da380, + 0x5963451f926d8232, 0xec7e31d53632c670, 0xad52fa7ae8532254, 0xb470c262133f657f, + 0xc56738319f981550, 0x96ced0155a32215c, 0xbc97f0bc658b2fdf, 0xb5fb35271ed5b579, + 0xd29c5af1dc76c31d, 0xbf30b0cf615d6441, 0x0f025a659aca9e95, 0x88f871bbb22bb89b, + 0x4594185003392d44, 0xe6c6c4ce6df977e9, 0xc39a5d4988fcd5ae, 0xf00ec87a5a8c876d, + 0x8381c6f41756d4d9, 0x3dd13c6886cc9bb3, 0x91464f76d4fc060a, 0x6c644fc76a5904b4, + 0x6bed83f9ea14d925, 0x0205fb0f34b525c6, 0x8aba7a584326a4b7, 0x3e10f89137a6122f, + 0x501f59b670a9089b, 0x0bde45c34be806a0, 0xfc87189ed43208db, 0x0c3faee6871b4b83, + 0x750b95d294e7632d, 0xf1b964e35d8725d6, 0xd31d1f69605ce857, 0xcd1e2ace24dcd8da, + 0xb63a6e1228de0724, 0x185cb465f56afec0, 0xf788a2900b78a3fd, 0x408a72e89af4d709, + 0xbe0107660526154a, 0x33fd09c37aeed3a5, 0x69b8e3b28db955f0, 0xe7fe6175805d39b6, + 0x744ed573387233e9, 0xa9b64c3f1dd03508, 0x555e554f5275a4e1, 0x264a25f2b47d8531, + 0xcfd168daaa93ef05, 0xf2ab7fa3c2548d06, 0x2910b363ec94787c, 0x7490b54cc0a71d0f, + 0x86cb0f8edb515cc2, 0x546b424b3244f3fb, 0x9827b12a810487a3, 0x6b3a8c5cc7369438, + 0x5098e4e9a08b43e9, 0xa2c9d97a0df62e7f, 0xf7edad25e0ba0af3, 0xb6ccbe9a060dac60, + 0x1242c269f1e3377b, 0xbdbb3ad7ced0c9ff, 0x1f20bed33a58b2bd, 0xac9df63dbd2a3079, + 0xf1f092b4c39a5060, 0x00de3784a5b4e862, 0x71a5c5ab598b2ca6, 0x207889e43678018a, + 0xd0ffacdbb0e01bb7, 0x6f3839ec5b4e2faf, 0x6681cef892ef4fdc, 0xf8409472b86970e4, + 0x733f089c75be1db3, 0x15c8ec1a0e1d4425, 0xb90d8336eec7d477, 0x2f88679bf724f69a, + 0x393dad6a5a594020, 0xf7a5a47e66fb2405, 0xc0435cbbaceea75f, 0x117d039d9a3d4785, + 0xb01c2724c3228e8a, 0x496d73c43895d565, 0xbd0ebd7b9940322a, 0x9dc10e360f81d9e0, + 0x18bfe6cfb20a954e, 0x3898f7eff22f4ec2, 0x27d5697d9c3318e7, 0x3362718a64757ce3, + 0x1c17aa35d425211f, 0x3d4eb102f8dbb5c0, 0x5370f062c2ce29b1, 0x6c35621f206772aa, + 0x1890c19ba661a97a, 0xfbc5555dd915c174, 0x4f7d1aa6d1e2bbb8, 0x48d8746b4d3fae77, + 0x05674759c9577439, 0x411ae1015c834416, 0x74ddd92c372c078c, 0x66b4c2e8025b6717, + 0xd2abdfb4b2dc3c05, 0x97c4c47cff7f6bea, 0x5527daa745f9f7b7, 0xae06fc3e501e8f74, + 0x9a09d57a50990866, 0x400341924baa225a, 0xec6ad3c98d998ea3, 0x8602b730777be7a4, + 0xd29dba2ef3dd512f, 0x78024d3301633aef, 0xbe2d7182e20827b2, 0xfd53b638fce5e131, + 0xb98a11d6a3708865, 0x79b0eb4dbb031640, 0xbcfb335a279623ab, 0x70282fe277a29287, + 0x31c26534f25a0a39, 0x5dcbc2b5c4539782, 0xa77770a4c8ab538a, 0xf2198b0235a88739, + 0x1cb187a3df200e84, 0x86b94097d83529a6, 0xa8ef7448bd6606be, 0x4ea9493a375edfd7, + 0x15a8e79e22c7b32d, 0x1438d9c5c646d334, 0xc8ee8e34d502c50f, 0x725bd20c5513807f, + 0x89a771b06a17a588, 0x81d69f253f7cc41f, 0xacd884c266118ae4, 0xac1ea70676873cb2, + 0xf53e2b46bdbac912, 0x2811ca3ffc0f2762, 0x347fbc3584a7c2d8, 0xb10aed0167070c77, + 0x21774d93a59221dc, 0x6ca3f703688715a3, 0x1b68f3c8901c5929, 0x1d612a5823d08c58, + 0x6dc729f448d733bc, 0x219a0cb6b62dc9ca, 0x174743aee3a4acd0, 0x192102d9af0582ac, + 0xb20d65fe74e071bd, 0xc80067fa723d20a5, 0xfd477cb872a2eb60, 0xbb89aaf1f5a5fc01, + 0xf38f8b30ca9239b1, 0x6cba5916fdeb98ee, 0xb0821ad9d933a225, 0x0224ab3e8888843e, + 0x65289c6d98b0f63e, 0x71267143d8ee0d25, 0xdbb6f8a171ec4db9, 0x6a2f0d35f357b2e9, + 0x1204e970df06dfd3, 0x9fc69d3eb7fd3a3a, 0x8f38fcd11f21bbf9, 0x03998e41e1680480, + 0xbc5adbc4ea4d64fc, 0xed0ba739945d975d, 0x43aec39c9034d879, 0xc3c87b57b7380a70, + 0x9c26a847af220d5e, 0x026debbfc8339c0e, 0xac4ccf362833b88d, 0x57ea2e7a9e6257d5, + 0x96ae792741c41198, 0x0a41bd053faf555d, 0x03057dcd45f5989f, 0x6e29ad8e8621908a, + 0x464acd0c7f8e6013, 0xff09fdb95aad8847, 0xf24de6e1b14e662a, 0x7bb480362a048620, + 0x4f1b0f5cd1c2f420, 0xa14739ea691d9d39, 0xe3a47a5661af06a2, 0x884e5c09968b73db, + 0xcb039370f2fd01db, 0x2cf211e5e8ff73c3, 0xf7a5d728146abb18, 0xb0339f224cadf7cd, + 0xea2dae1836e505cf, 0x6fabcae8c21587f8, 0xfe4762ac08d95a90, 0xda8b223411b97906, + 0x9815fe14c7344863, 0x00e640578111bf29, 0x9dce2a787b469340, 0x9c1708d1d4807245, + 0x5789df7757c8fc4b, 0x82bf90b9efbdcb85, 0x450371f74ed30e07, 0xa96cbc0904ef57cf, + 0x5418f4642595fea5, 0xba2ad73beda1dd57, 0x5e1897dde2d931be, 0x33a34bf286a0837f, + 0xeb624c80f32b114d, 0x25babbd4e384cbb0, 0x0c969e174ffd302f, 0x9ae901a4e422cafb, + 0x120f33461a6b7f6f, 0x83c65381fbc8eaf3, 0x0bfa1f4d3e92b560, 0x7753197713f06a5c, + 0x9bc559fe81c2929a, 0xe0c5a2cbbfba70a5, 0x8947e86cbdd63a24, 0xf9c88cf54ab36338, + 0x8a2078fdfd503670, 0xef58447b07144c0d, 0x6db09eac9404bf74, 0xef3f869f25aa6157, + 0x6dcb7ecf980ac81f, 0xba8bb7200a9fd4cd, 0x8f27e042122a872c, 0x201a58cf928a54f8, + 0x57c24e650efa010f, 0xb07e0404e2b4eb33, 0x4ddd78d1d326c7f3, 0xd14f3d5f1fbd8d31, + 0x0e69eb6feaaf7446, 0x69fff3611e5c628d, 0xc14a8f37059ba4dc, 0x6f90dd2e1dd9ce7a, + 0x7348f1755895acb2, 0x723ed4a77771835e, 0xb45f484755b1d5f5, 0x40ed62ce88931aed, + 0xa055750daa5443c2, 0x3984bfd3a991c37a, 0xbbe805d089aafa25, 0x3439f8e8e2c71776, + 0xba0782980666aeac, 0x4977c9f40c6e78fe, 0x9da972c822905be2, 0x1cc1b18d076b915c, + 0xb7856bc20a4ae79e, 0x979bff99001b926c, 0x403f737b1f0ac586, 0xacd98bd75313b3df, + 0x176b12e0e2fdfa15, 0xe1ee26503873ede4, 0x02e9cdc9c4cfc00e, 0xdf1ac0f74aebc19e, + 0x4617954a3548184c, 0x3a56c32636515a87, 0xfbbc6d467c6c52c4, 0x7bf994189fc08185, + 0x0420c267980145ff, 0xfdb732b176558575, 0x9de563258cf5920f, 0x70da934c2072bfa3, + 0x7583c7482a3964d7, 0x8351f2100d77214d, 0xfc94ef3ef611bcf0, 0x85a67d61dd88c32b, + 0xd929ac2272f142c3, 0x23c1da0fb5ee7761, 0xadd7c2a83a9913dc, 0x26ae807a691ce8c9, + 0x416a9751586ad478, 0x137706ff4a7cd74e, 0xaa06b021f9c833ff, 0x3e2ee67e495cf0d2, + 0x73d7dad4f64e8fd1, 0xf28a4eb63a5cf738, 0x873fdd6887dfd1b5, 0xd66166b50b3a1acd, + 0x7171093a0e120d60, 0x40a677bc4c8e449e, 0x7c803b1e18a2f89a, 0x0179804ecf68d5f4, + 0x4609da3c2e94a440, 0x35beef77eff38005, 0xf603bbd4149d6412, 0x83379cc783993a08, + 0x4b702cf005df74d1, 0xd08cbfdd27fcda3d, 0xd602a508ccb7838b, 0x7516a0f1180c3cb6, + 0x552153eb74b0eed7, 0x0de4b173a675b6e0, 0xb75ef52f3c4806de, 0x6b8f76dfd899af4e, + 0xaa499dc53f7949d6, 0x5a075e1f074be86f, 0xfae74003e5da2050, 0x92df03266178a012, + 0x3a88b440b0bff162, 0x5179c690b4959903, 0xb266139aceb7ced5, 0xdea9bbafc141b1d6, + 0xf31ec2fee4caaefb, 0xde844ee0b2dc9ba7, 0x433def21ac60cf37, 0x465a246b167d2c78, + 0xb1a9cc35902e43de, 0x616e27b872330895, 0x6c53095a1aa979cb, 0x66ecc8bb9777eb31, + 0x58eb5c0278f40beb, 0xaefc0ba42dece872, 0x3fd10d81ccbcc40c, 0x39a928ccf43029b0, + 0x5867d9b99e40197c, 0x0db3dda0fe350663, 0xf6119ec60c6d4528, 0x035db20219f5dece, + 0x4849f57cb5109c05, 0x7c4eb77df64068e0, 0x6f8e8c54959b024a, 0x7478f34c00073e92, + 0x55f9c6aee79ec924, 0xd86f5c57e8bc2f2a, 0x364780f78564a476, 0xb861c9defeb445af, + 0xf520b7374e565f5e, 0x3b9361b4f75d25cf, 0xeec5df85042f1165, 0x5ecc8ba003b46f2d, + 0x70ca0dcbc7cd7deb, 0x2a0300aa20cd62e6, 0x1aab9e0c9c1d711b, 0xd3e2c2f631c3e007, + 0xdd0bb7f837109378, 0xa15c2fdde3406ac5, 0x029d65b2df30a5ca, 0x560b234cedf38a39, + 0x28bd894abcaad860, 0xd9ebba00e4c1f507, 0x4066224c6137e027, 0xca8efea0f2a41757, + 0x13f736c3ce6ee223, 0x32eb49c3adc7affe, 0x44bbfe6d8cfcee4c, 0x568772f3516017a2, + 0x1a2b7ee2fc55a5b3, 0xf2faa0e334f215b5, 0x672a1256efa5f7ad, 0xc37f1c0980adced4, + 0xefab304836bf0cd8, 0x9c07651241e37c4b, 0xfaa7d20cd5118bae, 0xe0740fe13dea7dc6, + 0x006d855f3b3b3d5b, 0xe5bf775c45e5bf14, 0xa1fa93f69f63f73a, 0xa6decd1e6dfb3fa5, + 0x2cd325a40f80efdf, 0xf2da15853d106245, 0xc5fabeead66324b7, 0x367670af2f602772, + 0x99ce8c9ee55d9f67, 0xa29b8377a708a449, 0x5725d79d73251d6f, 0xe8e3a87cc59fc27e, + 0xcd3e6564ac274c48, 0x903121c35eb2e79c, 0xed3af55172ce62b7, 0x36912bb7200a6786, + 0x972673c999c66c7f, 0x0be8d1effe4913db, 0x12772004e4e2d758, 0x3ecf707416251f0f, + 0x75b61aa1e1607724, 0x0638fbd2ab0197e1, 0x291c3437f6ae0a9b, 0xe42f40b09a7e9098, + 0x942d68fb64ebd2f6, 0x79f4240f328aea1d, 0xe2271abf21c8ca41, 0xdb988493b9d94647, + 0x3010e4fcb060241d, 0x392efccc80e6626f, 0x12356c871925e6c0, 0x87cad311fabf5ea9, + 0x6187c01c2f0d936f, 0x93218ef76ef4c02f, 0xc1e3afd915b7f57e, 0x349fd39bc31f7ecd, + 0xacf892ba73e72aea, 0x41b7693b053b4e85, 0xc4d7d05fdcb88520, 0x30ceac370b70032e, + 0x09c3a42ff17e9323, 0x5abb94168899583c, 0x63c2a7b1ac98d304, 0x7fab45ae9ebbd230, + 0xe9a20b342b533de1, 0xff0b78a96d9e45e1, 0xb10e635514b86b4c, 0x797d048508d79f41, + 0xa3c2851a823d9eee, 0x5e9e600e44742c68, 0xc48b5eb4496b7d07, 0xc6de54bee07ee459, + 0x670e841a3ed5c5d8, 0x136b1dbd6aa2dee6, 0x841207f83669c6a2, 0xfeb22d3670382bfb, + 0x625a34595eaea27a, 0xf9d33e364ccd3bf0, 0x21b7a15b479fd6cd, 0xfd542bdc41ef9490, + 0xf9289b21a1e81b26, 0x2c6d4c5db79e044e, 0xaf5bca9d14abcdf5, 0x7a089216ec5faa05, + 0x869912803b9325da, 0x5479f0de10affbb0, 0x3ae9004580b298e2, 0x35c632198dda728f, + 0x05b7adda436ea05f, 0xa03a405fdab60ed2, 0x8d503c99e54be05b, 0x20fb51191edd8f41, + 0x85bd460ea01decff, 0x04a171a73caff07f, 0x10942e7d6a01060b, 0xfae470df3e6b3933, + 0x7c282e3c37b2bd21, 0x9eceb6459818f1c8, 0x15733159a986aae9, 0x3607310777a2096e, + 0xc710f3a70b383e88, 0x9232b96f5d1c843b, 0x9515e49eebd26506, 0x50d4202cc9727130, + 0x30eee28d34cabe3e, 0x4d3efa03b42577d9, 0x37a658c199436070, 0xe41cc51711d503bc, + 0x1aae84ae11ef5c70, 0x40be866800e9679f, 0x738860503109f040, 0x600bb48348f44f34, + 0xf425c71d465eb5c6, 0x4eb8c8b825a52db6, 0xa92f0aff88ef6efe, 0x5a86fa024076884e, + 0xa4d5973e92007bc2, 0xb90a665e1f945346, 0xfaaf0ec1f069c61e, 0x5f8d959c0b7eeb05, + 0x20cfc69b225292b6, 0x1335e7fe7fc6457c, 0xcf44c0a7c72ad0c0, 0xd651d1b9c9b311f5, + 0x99da781fe9c59376, 0xa54aa656133e17cb, 0x0bb2443bed0206fa, 0xabb5bc811a70127d, + 0x1701014d7c741131, 0x6d44b302af7af7f9, 0x09b84696e25a51a7, 0xfcd22d401d0841d1, + 0x6a12ac87aab441d2, 0xbb1f95621aa4b759, 0x5285e397155e0a79, 0x23e9acd5c2f645ba, + 0xfcd6829f741d02ed, 0x04aedfc15d4bf8af, 0xa219947e9ddb37e7, 0xc521c64c488f5e22, + 0x44f32333fb78768f, 0xcf45f1ea1b2d5dcc, 0x5f733c5461ea6495, 0x513aa280e9a3250a, + 0xdccf548be26ff5d9, 0x441d8a68d97895bd, 0x4d6ae926e8491cc7, 0x9dc84696f8616d69, + 0x2f7bccaa5ae77cd3, 0xb67ddf4468407227, 0xbdcfad269c17411a, 0xfec7600456f5431e, + 0x6b6f8581e7f1ce9b, 0x0159e94a7323ed81, 0x50963316ec43e50a, 0xc10c7cea1f522d2f, + 0xef1cdff34582be66, 0x8f58b2c2e26e4a3d, 0xcdea67efa5e3ab69, 0xdfc6487811bc457d, + 0xbf3f7cc1bf8372a8, 0xf70918badb2cc005, 0x5df94b98a0f0b331, 0x071110572bb1fa5d, + 0x01b300c46006e80c, 0x00e8332e34df967b, 0x7540b5d324e7283b, 0xa2f0a88c92475d84, + 0xd0f43d473ddfeb5b, 0x835ca1ce2d4a9710, 0xd831fad3b0bbec3e, 0xeaea8d2999cc220f, + 0x901bc30f1fd60d4f, 0xa9d5316b3edd1051, 0xf2e4e027030ed6d2, 0xb7c1abe62f043131, + 0x36ddc8928918efa7, 0x0dffcc44e3040db9, 0x49551d95539913ae, 0xa2314dbe11a10942, + 0x80bc1837eade07d4, 0x8693fd2c9c2f3121, 0xc962bf7a5b11d417, 0x4ab12ed19a30fd71, + 0xcfcd528e4534ecd7, 0xc63bea3b74a61f95, 0x41bde433300c8e37, 0xd8f0fb9a41dcf85d, + 0xe5640f738c9b911e, 0xedc22ec12c7c5689, 0x0be5dee7031924ed, 0xac2b918c979b0ab5, + 0x25cdcbc4dc4fc742, 0xa1297728c0994439, 0x41ce9b07987348e8, 0x65279d0c5f9e9f83, + 0xbfa94e7d8d9daee9, 0x1aebcaba315ddb77, 0xe27f0c61a5a7f821, 0x5e84529a66656553, + 0x576fe072b4908d39, 0x287bd0d94a22619b, 0x40b0afea313a400f, 0x7573db7c7a527001, + 0x0490ca3fffa4fa09, 0x8d61cf0b44bb7bb5, 0x1360552fd37c2d51, 0x2a6437303059cb8b, + 0x4e06f056bd4b7a96, 0x52b54e89ccfff423, 0xf5c681d7e8eeaa6e, 0xc00e758523c5c9cd, + 0x73060a35282ace8e, 0x42e459745cae0466, 0xcb4fd882dee0a454, 0x5ed2253467ba174d, + 0xa2f48e753578f408, 0xb5509e350b5077cb, 0x1cf331fe0b069335, 0x29043d1787072def, + 0xd7766b8f3b86c55b, 0xcdcf97de094d6113, 0x2b996a2c5fe13794, 0xcbf4685735b084b1, + 0xfea915b08b7d80a9, 0xfe3dc6b26c4bb3ad, 0x613e457b12cbbc19, 0x1053edc8ec3baf27, + 0x0d20cd38a32d172f, 0x413fff58a39d85f1, 0xbf8983aece7ab7d3, 0xc21714edf14d5a20, + 0x5ecc396bccf20caa, 0x70114d3098ce312b, 0x2fa6913015ee8773, 0xf2f729d15e9417ef, + 0x496b2bba954a7e47, 0xa06f058f5e59e136, 0x52c23d0c5998b8af, 0x971debf8bdbe41f6, + 0x26a93cdcd8fccdf5, 0xe264a097580af703, 0xf3968c58a3afb70c, 0x312fb8458111f39f, + 0x840655c88919cca6, 0x893a69e7134395a3, 0xf63d6131c7408688, 0xc8afa11949cadc11, + 0x482736d292d253d1, 0xa8fac85a875204b4, 0xedb848dda88006d7, 0x5d6a399524847de1, + 0xda79c4a66d7b2450, 0x6d563a24378367bb, 0x55f7ab36debbaa4c, 0x7755c5b71c997a17, + 0x51164b819ddbd662, 0xdfc29c054b7dbe07, 0x1119cd748bdc5969, 0x89e032b3b1420048, + 0x4596ffd192e5b27d, 0x5c58f38d8475189a, 0xd13fc40dd9f83257, 0xf45f3432a19fcf87, + 0x139c53697c8cfd26, 0x0a5114c8b11505e8, 0x04193e9739554168, 0x48e2afa13477eb16, + 0x1f1212b12eb770ef, 0xad8acb505476bc8c, 0xb57fcd541db4da36, 0xcb89801bf3310dee, + 0x0d10c1a75d402f6b, 0x617a79563e07372e, 0x337a3d0924eb434b, 0x4cfe6091939821cf, + 0xc7ff033ef890e39d, 0x4ecd0ac67a004a17, 0xcc547dac1a8aa6df, 0x88acf1d484c7b4d7, + 0x4e40afcd89b244d3, 0x63b7b2741e97c3c8, 0xc7d7730faa310315, 0x58b0a1990a9c59e6, + 0xec71c91c25a88b82, 0x37d88341efec2a34, 0x94a47e39da399e26, 0x3a0fa17a4ce13bb5, + 0x1000bcc02f387dfe, 0x1d3c4a20002b9a9d, 0x229be278937039a5, 0x2f2304566c56bcfa, + 0x45a52c321f0c2d19, 0xe6468d6c0ddc885d, 0xa3e2da81743b188c, 0xa80b6939ed6966b5, + 0xfa16593e1289eafb, 0x471bc94e16c5b844, 0x2ef88ce9df53568b, 0xcf10b6899903ee13, + 0x93f630a0384248c7, 0x9a53c2755975479e, 0x65afcaac4f5a218f, 0x1d51aef8898f983e, + 0x28eca3e946cdd4b4, 0x2f3cb49a9e8c35e0, 0xd2ee833cfc270f26, 0x7701a72d2fd17de1, + 0x36253a3fd3af3b67, 0xecb7e6dc26317b05, 0x62c235ce6c4f8c0d, 0x7a22cf865420994b, + 0xccfb0e36807e422d, 0x3767477285a9223d, 0x7400338f754a9aa6, 0xad6c63bde8e54f66, + 0x3fd5d508c5063bdb, 0xd3f2ab009b190ab2, 0x8323bf00242dc22c, 0xf339c8ade12afb68, + 0xe4406d6375d68b49, 0xb31a94a654046d4a, 0x917cf1de6478f3ab, 0x44997551ffd7ccf1, + 0xf4c9488c9af2f9bf, 0x15d34cf1e6629471, 0xd95ddefa01fe614c, 0x4239ff0df2fc85d8, + 0x9de1c92194b6567f, 0xd870779ff9d2e234, 0xd62fe5150dec8bd4, 0xe81c8dec94ad6d2d, + 0x23b00bf02d0c9b2e, 0x90c82027644a61a0, 0x27d1921072bb99af, 0xeb26ecf038b05b5a, + 0x12aff77f5462a1cb, 0xd7a416bb141470dd, 0x3cf6359103cd96c8, 0xbe710bcd24b05dda, + 0x2d3623e756731212, 0x38c9734a010eab52, 0x894a4229c5da79dd, 0x1805170f7974270a, + 0x2e6a2ede8aa49da5, 0xa7cd147823a6d499, 0xf7bae122cf2b36a3, 0x8d7dec8fcc7698b7, + 0xfa028c8440085fdc, 0x6481c8fea2b5bd45, 0xa933702eb02556bf, 0xad1972f5b24b24b1, + 0x31598d3542bf86a7, 0x23b94d4216412b9d, 0x7571f10f51155261, 0x80513bbf2a16de31, + 0xad9b3a508e3262ec, 0x90f9e85f7972290d, 0x162e1eb7ddfbae6f, 0x3e016fe2ea3fd7eb, + 0x551a12f98110884d, 0x2d51ccd3109d935d, 0x5892905d36f7ca86, 0x35d9b58b118f6003, + 0x5e42a0eec4930b22, 0x1d344afdd1260cfe, 0xd3478b870dcb049b, 0xb8259dfd40b63699, + 0xb35f34b47f958ea1, 0xba7be49e99f5d76f, 0x6333679f4b6b7c1c, 0x7cf9a8c739d4c66d, + 0x66d4139ca4692cbb, 0x2bc204a32f273b19, 0xc4ad5079c8856721, 0x37174be215e84cb0, + 0xed878eb783d0dcd8, 0x1dd282b6e4d5b345, 0x9f6520b2b44b5246, 0x0c207e064ba9c2a0, + 0x4afe4aa679334e21, 0x5f07f1ad0cbb7fb6, 0xdb53948dbc83ca46, 0xac7bec8e88d25856, + 0x0ee214c18cc2a232, 0xc398e2420880d813, 0xfed4d219d5662f2b, 0x5766ac4c7759e0b6, + 0xcb70fbf45e5d58bd, 0x658aa40fd54e4410, 0x1d834f77a399bb9f, 0xe23320a4d732e2be, + 0x6b0b43ff40bfd761, 0xa4a19dc4dce24920, 0xb042fcd65dbda5d4, 0x19d252f962a1b194, + 0xefd65fb1f0898c76, 0x20f50652431b6703, 0x2d01712ef60b4fdd, 0x54cfa734b4d114b8, + 0xb24db30c3bd0d3f6, 0x466410a08feb08c3, 0x09ed3cbc1c667270, 0x24593cf8e8252fb7, + 0x70316522afdd7296, 0x59b6fea7cfd1406f, 0x683b9c2e69c832f0, 0xbba7cbb88d2a673f, + 0xbce8c82c26cf2b49, 0xa5514d36c4688f69, 0x7ff7ebe9d0a06a3d, 0xb794ab39f020e67b, + 0xb91f8058efc6c234, 0x93bd2de63b881d35, 0xfc78fb974f757b77, 0x3f26d29ff80c3242, + 0x3625c2e07d45f116, 0x23496d77e07c7fef, 0x239b4ae24e34eb82, 0xa9a87837952fffc7, + 0x0cc05f29323fa653, 0x910c46c018ba7e24, 0x19e081de69e3b077, 0x0066a8049737e260, + 0xba3bb8dc687d36b6, 0x08db7833c9f5a4fd, 0x0ab69778399a8543, 0x4dd335ca0d884857, + 0x331992977d1b4312, 0xb290c39a22670abb, 0x5bffe98bc2a19bee, 0x4c45e812b58ba59c, + 0x20783bb0499d51e4, 0x105301259cef9e74, 0x101b003b76db30c9, 0x1099e4bfdb4732f6, + 0x4580208e18424dc3, 0x46df5bd3d0a29ace, 0x11790e37347c5205, 0xd8d98b3088cae035, + 0x37639436e31aacbd, 0x7688541df7a76f66, 0x6648a134ca5dcb99, 0x8471ce41bd7a2bca, + 0x4c1acf423c60372d, 0x019be49c8d197459, 0xc8924c929f4ba11f, 0x6b0d229e52a2e530, + 0xf28ffaa65655a3ec, 0xca25a75661740419, 0xefebb1ea014dbac9, 0x29c16b2189d3fcc1, + 0xfa28e5462b8a3ff9, 0xdb9f9eca4bf3cbed, 0xae18e3f420a6bda3, 0xe1d9e8ffa0085114, + 0xe7267a55e6772f07, 0x74d9d8f458313234, 0x8c60226b74c1f8bc, 0x7ea5e8f6e80e6f4a, + 0x5916337d296cb442, 0x79f52744f43a261e, 0x14055babc07fc8be, 0x0637024b051fcc92, + 0x2f20672871e15e91, 0x75302d87262b00c3, 0x039c886d0beb53b1, 0xb9853810d1f01e4f, + 0xbaf6d7a7fb4b6acf, 0x4b03369eb2decb78, 0xf582ceead56b7c72, 0x2633094a3ae582ac, + 0x51ddadc20bae292b, 0xc550c49675b6847f, 0x4b5d305250e1d64c, 0x75491061bab578e8, + 0xfdcca577cf27d454, 0x178157a19dbd0faf, 0x156dd88a7a4c30bf, 0xaf3a8b0372625887, + 0x38230837f9bc0b22, 0xc7eeead9dc4986ad, 0xe533065a7783734b, 0x1ac07ba902341580, + 0xc8163db1286659bd, 0xd73db1fd518f0d7e, 0x4ab55dbcbc4d7824, 0xb6474e0a9e4938c0, + 0x9eacc501ec684223, 0x2bf9ac9cf960ff72, 0x71f014d02011a383, 0x2bf8248495fc50f9, + 0xd7bdd43a294f7e48, 0x563c4d21e735f1e2, 0x7fe9436218266427, 0x3f5e8196b27b9ea6, + 0x0b4c85695dec9982, 0xcfb053cb78173e1d, 0x70638df3cab016b5, 0xfcd6af2d74f00acd, + 0x960d6345022fce81, 0xe313188a72694f48, 0xfb479bbb50ac1483, 0x37e14a4c495aa5af, + 0x3c7725ac545ace47, 0x5a67d53ea76e32d4, 0x97413b9789724e83, 0x8de4bff41d8545f8, + 0x96cc3f7df061f255, 0x59c811915e7acfaa, 0xd8c4bfce03be4f8d, 0x73f721936df4db30, + 0x977e57457a53360a, 0x9fdb77372f2297da, 0x3da189f2d017d559, 0x7439e0d25a95c309, + 0xc4849ec50666c340, 0xa97dd2b81d1e9ba2, 0xd477750a6dab957b, 0x4136fea9a215d644, + 0x9e24392162d63935, 0xe715385ddea9e64c, 0x26e3d0c39904d9d9, 0x364ea3a888b72c0c, + 0xbd05f01769e3d4ee, 0x709560f7c0cc8aee, 0x693fbdcdcd442e38, 0xc289cf40edfaacb6, + 0xb44e7d3d73a97f29, 0x7f019fb5a7157a2f, 0x595a97170dbc8172, 0x0e248b441525ea08, + 0xab022d256d9d8f16, 0x84b849ef17ebec95, 0x33ddf6efe400cb58, 0x7276d1708a3a6a64, + 0xd261204edaf26da8, 0x34aa572f1e0c5ce8, 0x3c105d6bbb97fcb2, 0x126a75ec64d62a34, + 0x73efd51abe9bf6e1, 0xdfe0decc09a68d22, 0xb665ae663be00db6, 0x0bd941b2a5169b56, + 0xaafb73d63425cb24, 0x9a38a218fd040d37, 0x24422a688ede53bf, 0x5d97b208ba4a6e89, + 0x239ff5d4e7bcc39e, 0x8583f922e7d2abfa, 0x58596cc27800df33, 0xa7c94ef51c685107, + 0x7fa399733e16c966, 0x7ccce7201fee6842, 0x2d4d7affb924e718, 0x4cdcf18eafb5ea97, + 0x466bbafeb936ee72, 0xa5469bb30ceae2db, 0x2f5f475b798f6ad6, 0x70454dea1258212a, + 0xeb2dd1a9fd510c1c, 0x8677968f4f8adc8b, 0xf56a13d33c8da126, 0x777ea641514d41fc, + 0xc72d0861a2489ac6, 0x32ab664f6cc38b10, 0xc1e5349f1c01618a, 0x2e03244a7c81a3cc, + 0x38fc845f4520b9d6, 0x02231d6beb030f3e, 0xb0578413be2e2238, 0x8086e6c650ddc376, + 0x33cb7bb557c0d3d1, 0x97238fd87c085ac2, 0x7bab220f08dc625f, 0x30fae121d810f5d9, + 0x7955ba2f1aa53649, 0x819ba63b8f9e827b, 0x7e49c5a5fdf5ea48, 0x7775d7b7469e4df8, + 0x38623df52b0426a1, 0x258d45cd60049fad, 0xf30dee671a41783d, 0x403f2d3c81ef4bc7, + 0xff3625739397213a, 0x6e8b92774fbbbc02, 0x448079281b428889, 0xe1e3bab0ae59d357, + 0x7653e726b1d2fbe2, 0x2a1b46da95a7b549, 0x98938371b4f5bbb0, 0x8149b9d9e7a207bb, + 0xa57556d20e4b2595, 0xd9136d595f8967ca, 0xd46251f42a9bc7c8, 0x1ef78b30c52e1ef6, + 0xa9d959ab4f8a81b2, 0xf65b15267326829e, 0x8e4b938861e722af, 0x3ee2f387d87c4a77, + 0x594a29dffa2b9ac2, 0xaf6c8aae91412fad, 0x6fe3d5cc3ec3c86c, 0xb9ccb0b9a6c6d6a7, + 0xd7e5c8551444fcdf, 0x7247655e2d3ca100, 0x7d6c4e9f986174dd, 0xeb2fedd83093bd6f, + 0x354ddcdf78d24546, 0x22571dbf38076678, 0x478ee2f5ea063e60, 0x2d4211a8bc439b64, + 0x8bb83ccb377e6e46, 0x47fddfad09b7c24e, 0xb50eb184a254fec3, 0xaec19b6fe6a90c5d, + 0x47fa8f18cc359b2d, 0x5d7ef3b866e45943, 0x7d380c3bd2036f81, 0xc8e41d797a4a4d84, + 0x0f4763e140d1d1fc, 0x1ac7d11f02aaccf3, 0x2d48a2a7214e1994, 0x8c39759399467538, + 0x923513bbe2cba4d1, 0x9eaf1f44053a1f3e, 0x619de0ff829523b0, 0x902be56a99a3ada8, + 0x48deb29f06ca1833, 0x562b1bcf0f0b5569, 0xd7f1a206c7393b07, 0x9b0149adf00287f8, + 0xa9c1f40a5cb6f6f2, 0xb6ca837ae22b87ae, 0x877b598f5428f038, 0xc432a5c1608f4ba1, + 0x8db4e054a77616c5, 0x4b0305dc78fa25a9, 0x9212488e266e5302, 0xd1a7a546897f8245, + 0x3c38cf03fd9a730a, 0xad9b61fbb677db68, 0x1a557562c1b0f977, 0x2935f1411ce0c2e6, + 0x3ce63691e594bf80, 0x877e7fbb643af06c, 0x6d7de6e2ae198bad, 0x7d3a439018521492, + 0x50bb2a88ce7c488f, 0x0f3c36ea786c14d4, 0x911a8e167b0f398a, 0x947d6aac90e7e98e, + 0x56eec24cf0201bfc, 0x4d32a501b38c56c5, 0x5f8258ff9f7d414b, 0x87d52946981007db, + 0x4ddd9fca3646298f, 0x1f32e5bfbe43525e, 0x586dfbdac515d632, 0x497fe51fb3e29b41, + 0x99cdc3883e379bfc, 0x5ebb1e01559cad1c, 0xfa4bbdcee14b3c6e, 0x12e79e767e70a0eb, + 0x23c1ab042d3dcf1f, 0xb0e9d9fd63dc8759, 0x4195819fc7174c94, 0xe9277234771e7974, + 0xde0d54fc77cdc39c, 0x137e272f37555118, 0xadfa2950ee023a52, 0x9b71a88a1f32a8e6, + 0x57c749199e7d7a98, 0x13432a90c4889c20, 0xc88a948357d76dcb, 0x4decf5c94f318ab0, + 0xfa5a9b080436bbb6, 0x92144c858477bc73, 0xc341081b6c58756e, 0x8a3dc11833bf16c0, + 0x8888035dd5187bf1, 0x73c10e56adda9c39, 0x19a4c4f3201f4776, 0x7014dd6af67c0409, + 0x4b8b78888ca93fb4, 0xe5381d091064827f, 0xb5995b7b99a6dc90, 0xfb510e757bb184db, + 0xed1765509ba9b4fa, 0x170fa3d0391e027a, 0x84ebed95b81db988, 0xdeb7ec4ce3fa9da1, + 0xb740b741bcf48059, 0xb9afe962ddf86e97, 0x08d0606647cef9d2, 0xc9373f474bb7c230, + 0x78c5459b5776f32f, 0xeee613071f0189a0, 0x659d276358fc742c, 0x6d3e05b11982c745, + 0xdb959e87f32a4393, 0x2d38d2108238420c, 0x84ab5f42a4ba0842, 0x9a31294a7aa93c6b, + 0x759bb6117961b904, 0x97a525ef2da76afd, 0x1ef794ff4bb9dd8e, 0xa9deb0126cfef6f2, + 0x088a9bf2850843c0, 0xcea9028ad614e03b, 0x63c1ffb902559a3f, 0x358a2bf95dc1ad7c, + 0x195cdac4483cf26a, 0x74d03ad14d08c779, 0x927eea93628cd93d, 0x0ab24cefb8416397, + 0x3925ddb00b01a956, 0xee194861e1c34254, 0xe4289f66a6161cb4, 0x2dc9753a205c7efa, + 0x4244fe30f75fef5a, 0x8a4cbc58db61e665, 0xd146908a91fd8d48, 0x84e846a8efcfb334, + 0x1a5066a5790ecb2c, 0x590e03e7c207daa0, 0xb35b496a69f28674, 0x0d77efba2adb71a0, + 0x38fd010b04b85772, 0x7c5b3564191b4015, 0xc5910e002bd46b08, 0x44bb465e23acc0e8, + 0xcad1956b8514244a, 0xd99b7ed45e60b1b7, 0x6cf2ba5e20d729f4, 0xb417a5f8c5a21e70, + 0x5012dd4b7a08b14c, 0xabd8aff2da3477e5, 0x1c597348d3c6ec74, 0x30a46a5e50aea3a4, + 0x611fd119f597dc8d, 0x36548eeb250d1b68, 0x422dac6b2a00dbca, 0xcb647a9bcb2f7b7e, + 0x82593fb8da9cbb65, 0xdd99e4963f8301f2, 0xaf52f0a51309d203, 0x7cc796c8d48e06d2, + 0xa5d639bf24c2b009, 0x7259096214add330, 0x58679d11851eb054, 0x892b4ca53deb3d85, + 0x7db3fb8e9f84225f, 0x38afb949519f5208, 0x3fd0d0dccbd84b6b, 0xf6e3db08c23a093f, + 0x18b34b6aa3fe697e, 0x5b81323e71a232b0, 0x43018335da66f719, 0xea096df8ee0b1688, + 0xfb257c61574231c8, 0x229a91db450d136d, 0xf439c110d39067c9, 0x96888c7e428d8e50, + 0x555350702bcd0399, 0x63b816d705c22daf, 0x16bc96882d9ed236, 0x30369d6cf925fe42, + 0xbca7625d194733e7, 0xc335b97d3412e382, 0xd05d5c74d1b2448c, 0x4fe7d745c0cbf733, + 0xac97e8f750f93358, 0x98d5b2e049468da8, 0x310f0aec1a8a5842, 0x5cd712c67763aae0, + 0xee44f47193c30854, 0x3e371e52ddb061aa, 0x0db07791481cb284, 0xfe23dced2d0734d2, + 0xdc78b9aa596edac1, 0x717030751920baf1, 0xb10a4e2548d501bd, 0x0a4f71e62ddfac9b, + 0xb68929a8e682a2c6, 0x65169f13afb46301, 0x5a4f06d460f3182b, 0x79802586e381dd14, + 0xcd59d4a5272111b9, 0xd23ceee18802b114, 0xf1869d9f3f049c42, 0x0f7071e1ad897aab, + 0x6e660c265d0c9644, 0x7184155335abd2ba, 0x543fca9d24b12c57, 0xa51236596076fd40, + 0x43816ac63e845bad, 0x077b587e1be4fca3, 0x1bf5cd942845635e, 0xa63e4bca16b21fc1, + 0x2953c3becf8319db, 0xfb349d9734fafc78, 0x607e7f50b49fc991, 0x22f300f1e6f20c8e, + 0x7262bcb4c79f4e40, 0x8c573f4d886e4fa9, 0x842c39c8db28dc60, 0xf5c98d25d044aaa7, + 0xdc7826d20e0c6bd8, 0xf35247d871518d00, 0xc984d6910cf5bfa2, 0x7a93c257644794c6, + 0x109c840e054ccd3d, 0xa6c19534a17e622a, 0x22271c8fb932f752, 0x63c6bd6204885477, + 0x10b8953ed6495d58, 0x8073c5b4654efd81, 0x4feacae32782a6b8, 0x95840c9a6ed9b184, + 0x381fb3d43f4ed0ef, 0xec6fdbfcff7ded2d, 0x57796a5fc76c7e94, 0x9d286b06447dc5cc, + 0xb461c20f63281420, 0x356decd7b1eefc90, 0xfc685a1973bea82c, 0x1f4f66a1f92db9d0, + 0x0de37497ea9ed84a, 0x0032bfd65ec1af2d, 0x69ae22dbd430c1cd, 0xdad0ac4473c35221, + 0xa3f8eba0679fce53, 0x39a0db8660e2540d, 0xe66dbe85cef1a586, 0xeb76bec1aa51d2c0, + 0x03d5f123895faaa5, 0xdd91ec237dfab1b9, 0x5ff6ddf7c4309b97, 0xf9462910805938b4, + 0x0833726aca825fff, 0x3918c87b448ecc12, 0xe56c608a3f70b6f2, 0x2934c13017b6741c, + 0x46dacc829c21d200, 0xd59b7421625c37bc, 0x54f796879abaac32, 0x267bfd6304cef715, + 0x7eff8fa9f5ff3f14, 0xd97c7baceabef25b, 0x4171fa90052e6e56, 0xd321045ed87bf73c, + 0x60964aac050e34ea, 0x40002e37a804e424, 0x8f4e45b783d81878, 0x0af889152a8ae971, + 0x41231e9b47e6ef6d, 0xa5e31d99d2d07356, 0x2e2de4fee18d3b86, 0x159a89fc6aeaa484, + 0x96b1eacbd235697d, 0x92ba2184f4e5633d, 0xd67f5bd2cfcefe44, 0x27dad1c390521a38, + 0x7b0a6ac50ab57e3a, 0x6efe970fe3367c9f, 0x231a9ec699a005ee, 0xc34ff828b1b74d2e, + 0xe2b3d3c48014d757, 0x5251e197c578e46c, 0xdeb6854b9a85d771, 0xb6a98be254f71692, + 0x9a46e9e6624622f1, 0x2c7ffa7fa7235840, 0x22189f63430a823a, 0x7ff2f0c858142bd2, + 0x52795ff1c9ae17a4, 0xde4d942498e8b7e3, 0x7cb5d7f2e10328a3, 0xa448bbf7a8c17e20, + 0x577f6499b4d99223, 0x8ddef7b509722845, 0xfe970766acebc55a, 0xd3d622c47f53ac74, + 0xf2f3b22a941de355, 0x60fec70eae26e7b3, 0xd017249e9bf75f04, 0xe6e426f869da0739, + 0x48588906f7550fbd, 0x0e829fd415a607fa, 0xac5b9e7c3599a169, 0x6b1e1a8ba0266fe7, + 0xb4ace964d53428a0, 0x517725d126e5807b, 0x24217384bf9b084f, 0xb6585a398eb35b63, + 0xc1a494229d7443e8, 0x202a99a9c128690d, 0xfcf687d6e4b5a7df, 0x829d695f9ba0370c, + 0x89dc3320d97881d4, 0xc4c0f07d3dde7cc7, 0x664dbfe261e2f7d2, 0xc77c3359e6fabc99, + 0x59c87221ec4b70af, 0x6d20a2a081179676, 0xc0cafb53ccf7010a, 0xaa3c8bfe0bcabfa4, + 0x88325d6fb2ba544c, 0x9602e7cc414ab3e9, 0x539ffd34092e6235, 0x776cd67c51086b39, + 0xe6655d77e766e148, 0x13a493d95c65e0ae, 0x6aa14a331ddad59f, 0x9cffa275d139a1ca, + 0x931a6ff692076c59, 0x85858d2fd38bd488, 0x6978c30e7b3f6652, 0xbbc28742427aa515, + 0x61a92082b746a311, 0xd7630334b1faee13, 0x15b0dd5757328db8, 0x6e2d125fd75dd9a2, + 0xb6f27d8f4ece315c, 0x4de1179c87d4be5c, 0xf7b7b6d9729a5290, 0xe3b72cf98b54eab8, + 0xf5792b1aa4f0bf17, 0xdc417492e857d9ff, 0x0dccc6bfadf01a80, 0x945089bf7e52e868, + 0xf1699d463708ba66, 0x462828cdb34f7f9b, 0xa7f3f6d54f9da920, 0x9516d46027b10b7a, + 0x0c343c167b23c251, 0xb2b25554824f047c, 0xdd2c9a586c2f5700, 0xed37c196863c0e66, + 0xf3df16be4b01e2c8, 0x4e9f7ecdba2a0bb9, 0x33bfb23aae06f6d8, 0x760da13793f070a4, + 0x92e44999e44d03bf, 0xa605acbdc8d7ad02, 0xfa53e64d37c60cc8, 0xf76bb437943a7bc2, + 0xb972e28772ecd402, 0x2d625234ee5134d1, 0x6f4b87dc99da7215, 0x448be09396b62fa5, + 0x954664682fd59fc5, 0x5b03b21b757379b1, 0x9f739037c7aa3e6e, 0xe90a023124a98984, + 0x0bbde3d156a43996, 0x85d1ded0be7d162c, 0x2c9216200c5b00f4, 0xae6406805e321870, + 0xe78daea854b0d13f, 0xea25f39a5b725d9c, 0x055356c6798b8d0c, 0x6b01174bf52067bf, + 0x8038aa92356b6d14, 0xb6c6ba0490c5a63a, 0x1f7ebadcd62fcf3c, 0xd6481b149292ded2, + 0xfee875dc89e3ab02, 0x3d57b40b96605d1d, 0x3d1e2d9602493ec4, 0x89219d8125302a55, + 0x4279050826315794, 0xb02ea5e07dbdc1ea, 0x572d131a9d665606, 0x14c8f48391d0cea1, + 0xe8f65053a14ce2d3, 0xd9f61297aff37b4d, 0xf9cd776f49e66bcf, 0xb3630a4a6bb6f7f2, + 0xedf103058e3a76a4, 0xe9403a87f39f53dc, 0xf388ce92578d5628, 0x465269d3e2895e4c, + 0x6af59126ad0c7da5, 0xa6a3c5527f6e09f6, 0x9bfcab1fe6bf6601, 0xdd3ca3f09e316163, + 0x8895728d793ed552, 0x45907c854d71696b, 0x1fa5d614a0ff6f74, 0xb62fb03767c55559, + 0x5e2b3542d1ed06ea, 0x157c3ac5db1402a8, 0x88d09ac5e273e713, 0x6eb1c607e8543897, + 0x90debc4f18e30a79, 0x5ad3c56e41faf60e, 0xe92c9aaf5613fd5f, 0x33ae596e32b44bd6, + 0x9979ad97ab7dbf19, 0x4d47774832371f86, 0x764b1303b22f2c33, 0x7128fce519ee9fae, + 0x66c9315be04bdf86, 0x7f396bf9f8e5efa8, 0xfb7fbc7eeb95f502, 0xf569adb7a0bbf8cc, + 0x8b9856f857da722f, 0x1fb7d853c11d173f, 0xcd87963c2812cc60, 0x368d46b904938350, + 0x16f2b878508018bd, 0xd4da93c75c5869ef, 0x21907b6dd35fd4b2, 0x55eb2b110606cf22, + 0x5d5566a4ad062fe9, 0x2935900c18fcd04b, 0x99675186bce59985, 0xd92636f5c3993761, + 0x465349f35aa91d60, 0x36658fb924bf562a, 0x2fa8c4d10174fa33, 0x58e81d740af9b668, + 0x9eb22bc86105853c, 0xb0e6562de4c2bc54, 0xf22b18eddf7d693a, 0x99a6b2ed95f8cfa9, + 0x0f77f7dc54c621db, 0xe163c5b6b6f6e9fa, 0x0e8407c6200e8057, 0xe0636f65210bf612, + 0xa6a531974d2ef38d, 0x7ac625c1900637a9, 0x5d6f50fa441a4eba, 0x56e3fa04b376e81a, + 0xd529cab6ff052116, 0xa2410a8d55d52e63, 0x89cce8bdd7d913a0, 0xab83a42e920f3118, + 0x726a290583bd52f4, 0x458a6ffd5aa93586, 0xbfc833f8ff9e5346, 0x02448958cb4a80de, + 0xdf4e6514e5a47e7f, 0x8436d0a14d535684, 0xbac66d7caef7b742, 0xfe05435deceaa1b5, + 0xd46a06eebcb1271b, 0x26e2b1c43bdf70b5, 0xd21bc8970ac3f78d, 0x2fc2e87e2652b6f0, + 0x3d541feea4f3c37e, 0x6597dbce0fe5017f, 0xc14356e3cd683463, 0x5eeabb4e0bf06531, + 0xd3ef32e1fb3863e5, 0x535aa592799d1c2d, 0x25c6117f070fbf7c, 0xafd562f0ec083a93, + 0xd82ed1052b6be71c, 0x16523ea0b84192e7, 0x602e4df312c83d77, 0xe83945956a725ff6, + 0x13d069d03fb838ec, 0xe6890493587b3223, 0x38c03f8a7daa4ec2, 0x11810327727eea14, + 0x90960451669cb4c1, 0x203611f635ce8605, 0x7a7e4d3729b3472c, 0xb469151de6b06827, + 0x6c48e3dca113edba, 0x94e41904361e617f, 0x1c940d6cb53c9dd1, 0x53a2a79942c9a5d2, + 0xa701005af1cecce2, 0xb023225aa000dd67, 0xefb8fa80d4e56be1, 0xea711747a3296e59, + 0xef4b72273bdcb1c4, 0x2f11b9531b1dd48a, 0x6f1d50da2a886b00, 0xb76e66ab68fb62d3, + 0x4cf7b7f20b3be2ab, 0x7af89c632536cbb4, 0x8c6ddab9cc768fce, 0x8dbb25f39e853ad7, + 0x9f61f001d8752bc8, 0x45600fb62a84d5f7, 0x059e518519667daa, 0x03aa45ef487f47a4, + 0xcd7d7c26565e7c62, 0xaefc4710009d0b91, 0x3d834a4b9c163724, 0xc2c918e604cc7f22, + 0x34f698a1e485f914, 0x5adcd39cd57586c7, 0xe12719b6417793bf, 0x04c54843f1eee7d8, + 0x78ba564029811d09, 0xfebbf8e744128e12, 0x237581da8befd07f, 0xb8db2cd56ffbf7a4, + 0x9ef23b855c418ee6, 0x778ad16200b96964, 0xb0f025cfc0d29d99, 0x27c8ef3baccc72c4, + 0x47f2ec25f5694c2c, 0x470d423e2b4d3a5a, 0x31aa34086feb4d20, 0x2ba8f70b5a7cde0f, + 0x24d5bed193bb5804, 0x97e255875cc6fc96, 0xa39a11689f53e6a5, 0xeaec8f074b446e38, + 0x01dfa0bb63a47dcb, 0x554e4d97c16056cc, 0x9398e033cad1e541, 0x7b6c9e91f3505a8c, + 0x7221929702c918d8, 0xcf55d6b2c67dfbb1, 0x5fe70d9f976c42ab, 0xa9bed7579e53e838, + 0x01bd507aa62a5150, 0x22fca3664b738d20, 0x82a177f82ab647bb, 0x7acb24f9b81467f4, + 0x76461ac9fd7062de, 0x8cae3e4d405f2667, 0xf4ec19941ca53059, 0x20b9ffe98b069d12, + 0xacee7b4b14698acf, 0x9ea4b771af9c2434, 0xeed4289f8cdd9d91, 0xdd5af37c0b24933a, + 0x716c7d63f3a245da, 0xd60dc72ef03b6af1, 0x11a03aa697f51046, 0x0deb14b8a77f9302, + 0x49b0c4d9f3c947e8, 0x5cfb4cefe4f57a22, 0x76d73bf35a6b8ff1, 0xa160c2051e99f0f6, + 0x3b21dd766e08b65c, 0x00db515e5e2024ea, 0x4c0a74cf778db7b8, 0xf788618cb5ca9fac, + 0x628592d29adaa08f, 0xe7d21d3ca609be64, 0x2e5810fbbe92bb7a, 0xbcb12db2d5d1e1cd, + 0x1cc43e73d2b187dc, 0x16b60137230718ca, 0x5372c482d4006d2d, 0x665ef7a68024eb6a, + 0x5b0640fbcfb7ef42, 0x80540eab79334bbc, 0x16ff780efbf5d5a2, 0xf435ea0550d41c31, + 0xfa76e549aacfe33f, 0x1ea145f989db7619, 0xda05b32bab591245, 0x7bb60ca102cc1918, + 0x4abaf1ce5d54c228, 0x296fc9cd89081bc2, 0x406888647cc4fd14, 0xb6b0bc88f4b1642c, + 0x7a02cb09e012a150, 0x44db20f60c122a86, 0x256d5e15de92fdc7, 0x8efccf0a27382f30, + 0xb695c381f35e2d76, 0xb27915f54884799e, 0x5dd7a5bea1ed239d, 0x9117ec76c92a112d, + 0xec2b905b46f17e30, 0xe623e5887a9a07e4, 0x7cb8ae38be23ec7c, 0xa4191903410fdb61, + 0x08e7d13df6e510c5, 0x32d97aa4607f3a0a, 0xe61deace59d38e52, 0xbdd8bea09b2f3255, + 0x415e95012eb83720, 0xeff10b9b2abe83c2, 0x699752f6cff1d303, 0x2439144dbd55a943, + 0x6c942fb25d75033d, 0xacc7ffa0352e0a48, 0xcacae9ddcb5877b4, 0x0a76c550cbe0cd52, + 0x889719362db67195, 0xb101bdd3a00b9de4, 0x31c48242850c2189, 0xb8cedbc72c88b894, + 0x4e465d5fd48ee749, 0xd766f805de5406f2, 0x7ed1021cc3976f2f, 0xa338d0c156883be1, + 0xdf521f5f24c6dd7d, 0xc1eeed65ef39a242, 0xc02631eebc5c96a6, 0x9cc1fbfd628e1829, + 0x7d73216ba0699361, 0x2540317d7b66fb29, 0x63a054452be49dca, 0x7d73742ae0848e88, + 0xb30c2497e6193a12, 0x2682980472f836d7, 0x4305ec0a00594e45, 0x3c8fffd1c0ef0c22, + 0x5e8be6dad5b64fbb, 0xf5ea60f4d282d001, 0x6e9e672773fc023f, 0xe9d74708e6696640, + 0x719f1c395cb08fd3, 0x4e062755f9935277, 0xd58ba0f178758de1, 0xe57887a691e40a3c, + 0x4b6d403d2510a226, 0x6f37aef02045c5a1, 0x008f63675158b1e5, 0x56e0067421054218, + 0xe31c514f72f684b1, 0xbdf6cc0f01470680, 0x67bc87bad09c83b3, 0x22075b949dd1d88b, + 0x86d9a9b0b96deab6, 0x17aeeb734d4eb78a, 0xca242e09e738ae5e, 0x900b79ec6294c63d, + 0x69672c4b972f1817, 0x1a5af20f146ddccc, 0xc2e57d514f17862f, 0xf73624d6efe17e2c, + 0x39430990b4d91983, 0x8b64914dadc0c619, 0x7b8c0544391d2f06, 0xe1e31fc32cde6027, + 0x3f17f49563b47ae2, 0xfb5ee4b36c079387, 0x4e5f836b96ee8618, 0x6483f553d7099c60, + 0x16a3525fd0bd9f5d, 0x11ae2d4141cd7181, 0x4d467dd4036243f8, 0x25382f4820103be7, + 0x04aad65be4933b78, 0xe7c4ed8ae9f5134c, 0x5d017877021c10a5, 0xa79be1811cb4de61, + 0x3e9df7054ad3831d, 0x0caace50fd8e5877, 0xda73ea1f41dc74e1, 0xbf5836056520acb7, + 0x7865e3b0301cdaf4, 0xc0deeb305d874491, 0x606a0ca63031e753, 0xf2a54ed007cbe026, + 0x73779695ebb09152, 0x30fbcf0a4283276b, 0x1e75eb46e4a3f640, 0x50c44ab9a1985f6e, + 0xe8e2fc4184069369, 0x7013d4094a8ce4b8, 0x3f8be01df01c8f56, 0x63cb13d88cd1c779, + 0xb66264ded853d752, 0xb31b29a495ca0c92, 0xb00df6192087df6e, 0xa281d1211faa8302, + 0xcb0747c65238201a, 0x03f13733287a1c13, 0x5b9a642b7f60396c, 0xcb5269137d2a7744, + 0x0bc1ce8eb3f7817e, 0xe9412aa2690b4a93, 0x9c7b6c344f263961, 0xff2f8074abeb6cd1, + 0xd906fb25cfc7c808, 0xe102fad0dd9c736d, 0xcce6097bbe848931, 0x9a549d00790a3373, + 0xd5ac5bb214d477f0, 0xd0e8919415015b0d, 0x37c6bd1b388568fa, 0x87aa0ffc80e394ad, + 0x18fa904f2183f17d, 0x7d3bf175b8289f47, 0xeed05c40748909b0, 0x36266c65ea9acaba, + 0x2dfe6d37337e1551, 0x926aee4b432ed24d, 0x5e47ed4d9dd318ed, 0x57f0130f81eff66e, + 0xad8258aebf497eb8, 0x48bd25078aa02f04, 0xea88eb9d81e10833, 0xaa17e2454f43d389, + 0x03a46df0fd92a69b, 0x01f32bbae2669e22, 0x5ad580a747cd4b55, 0x6058ecda453f6da8, + 0x0cbbd0556fb8a40a, 0xd91df481ba22ef1a, 0x88fca89aaf45bb32, 0x1fa12d9bf4141464, + 0x553159310c51bda2, 0x64906c434627252a, 0xf2d2be89f02099fa, 0x964e47a4c77e6556, + 0xbcbec19714595b28, 0x539ba6f42dad5062, 0x96fac67913e63c90, 0x83e9484efaeeda9a, + 0xfcaf061f65942e48, 0xa9b0a9ff9ae385dc, 0xb79dfce6f8238592, 0x14e3dbcfc512ce7b, + 0xd80468e0229cb23c, 0xddce88d71254c4d2, 0xf643e0d9422ac9d0, 0xe2810d05403fb092, + 0x2a358c9a491aa767, 0xc750c0db3b17e90d, 0x7d69bd6c310e3fb3, 0x84a186b2c6b13b1a, + 0x0f272a11bb195b36, 0x52473d0ca1fecf98, 0xd7e70d382e5dd11d, 0x608da68150d4e38c, + 0xb826eb9cf77f4544, 0xd7b9e81d43cba77b, 0x08aba5637422b57f, 0xb9dc3d8ce71a6116, + 0x3fc1d04e66ac073c, 0x6b4c0fe82bdf31d2, 0x25245b5d00f6ae8f, 0xee3c6d2b6de42506, + 0x9e20b5935d612b40, 0x65a2239589a359ba, 0x243862218db0c132, 0xb3cbda169a4f2560, + 0xd868a40fea9dbf25, 0x59537872a368d366, 0xe3682a3e0bd0fe11, 0x694f50065b928de2, + 0x0180ae2c81389703, 0xd883adf457e692a1, 0xf50876b2c4c9a1d4, 0x70c2464bd9f73a30, + 0x0fcd96cdd2434f6c, 0xf2d9a073dcd75110, 0xd62984d6739c8f0d, 0x18a15515603509d7, + 0x6c80c5f8abc713df, 0x9ab2917c05261cb1, 0xe797726444b2e9d1, 0x3d3bb63e1384c325, + 0xf53b3051901ee282, 0xe871771f78c33328, 0xdca7d82c4157a494, 0x026948364812b649, + 0xf761ba1b501366e2, 0xa470e09eab50a6b9, 0xf340e2b7f59adf5b, 0xcfc2f6931971b38c, + 0x666bafc230cf07ae, 0xa702c163e23dfc7e, 0xcc5560d0113157e9, 0xc840191bead63b3f, + 0x5c1c0c85be00f20b, 0xe7a01c32bb80bc0f, 0x72a14c9f01863b05, 0x86bbe6b6933313f3, + 0xf432861d49913adf, 0x8cd7df8a3545dc79, 0xa705374c617f236f, 0x289459878d34e42c, + 0x89075ecc0513405c, 0x5f1b994f544cc725, 0x97777064cf006d7b, 0xb21c55fed3c331df, + 0x9bf7c774d6d205ce, 0x70c6ac11d30c8d60, 0xa6f75076c3befcc7, 0xea10f55bbba6046c, + 0x14493f2043d6b71e, 0x6f8a5e31147870a2, 0xcdbb9084579014b0, 0x3581034700c347ad, + 0x694c3336c5cc1ef8, 0x06383bb7b56c3c53, 0x2fb979d1bf93a2a1, 0x07f9493af6990c65, + 0x283c2fd2fd2b30ba, 0xb1fd6466fef48699, 0x96f85d1f7af606ba, 0xc43115f321ca5eff, + 0x9e79c155ded2afa4, 0xdeccd382f063730e, 0x74f7a752e25ab419, 0x783a86a0e2d84dfe, + 0x0a3d9dbf5c42bda1, 0xd9fceaee360847b2, 0x5f7b4d21e0858c13, 0xd214cf14399ea948, + 0xc28c589e31388e3f, 0x626a27c3d7587430, 0x5c555b03ff8ff699, 0x3d062a1ebadafed3, + 0x400efd1032187b8f, 0x9b74150fa004ac7f, 0x7f9ef9ef8851c3a3, 0x26a5dd7a22bdaaea, + 0x31d33df9074f03bb, 0xa02cbb077c7a9672, 0x68f3178a5157aebc, 0x4a57132fbfb7ef24, + 0x3cf263f1ba232bec, 0xdfb40cf2e6e7d252, 0x9834b9ecd8eac612, 0x105c09695215cacd, + 0x69d31e2bfbe6edf5, 0x27f4a28cdf40d6d5, 0x66dfa27d9e0b394d, 0xa2d0bf6e8d09cb3b, + 0x084e66bb5a4f69b4, 0x4c37de99f0c0cd00, 0xaa64cf6a8b188876, 0x716d7c852cab6b5f, + 0x99b8bb5b5f2e6bc1, 0x2f5f74985880f613, 0xf94612f1e743418c, 0xb9449cf3d9a9ea11, + 0xdd2447eb385ce8da, 0x1408dbf66bde6567, 0xbf708386fa5dbe37, 0x52e793c08ebc76e3, + 0x519d9f4c3d0e310e, 0x2a4ecb10ac2b04c8, 0x6f8e19c2d57a34b8, 0x3bd02f65bdac6b1e, + 0x9729ad60865b3d8b, 0xa444c0770dc2d599, 0x234c4f2ec29d26a4, 0x7a3040be1d17ca4f, + 0x1ee96841ec8240b7, 0xf0240b6ecc33a501, 0x355800a9a2c90832, 0x8e33565022ffd441, + 0x82433d3e2514768f, 0x60e2a5753349e7d6, 0xdc0841e8a4089800, 0xd86c8a45a30dd6ee, + 0x4b489c3decf4e1fd, 0x08acfd2cee31c580, 0x51a37c7ea8c14013, 0x71a2defe4e8da738, + 0x2545cabc960550a0, 0xe548a32519d70da8, 0x757203a8f4d75521, 0x271c2866bd8be26a, + 0x7a2da670931a4f58, 0xf5eed822dbd791ef, 0xe1166fb06b0f28e9, 0x0bd949d87b079069, + 0x28204e86e655c41c, 0x258a3c6f1673203b, 0x1e59e86d04380244, 0xde1a3a599931170e, + 0x92a01b8fd8e1267e, 0x560eddfa3837f984, 0x521f9b0440e9ba83, 0x813efbb701470505, + 0x8dde80906da578f6, 0xbc0a5fa235181fb0, 0x4f8ee4381a7a273c, 0x0ef7100c1fe9d2ec, + 0xf063e2a2f889afd2, 0x01edd5cc0d3cab72, 0x570bdd2ac22923f6, 0x613686f7c659a6bb, + 0x987052e905889d2a, 0xfe72524e7544dcc7, 0xa4b222bc12c656a2, 0x743bcd539dd0c232, + 0x6b883b6ec2443f30, 0xe638217862a2cfdd, 0x53a6f188b1616900, 0xfa901cb976d9f9b2, + 0x1365db124de8da01, 0x60a7d81f9b91aa83, 0x6e1e066cbb9137d0, 0xc0844ce514ac77c5, + 0xd214bb381e11217a, 0xdb601f662399f610, 0x1fd0160454fdf365, 0xa409ce9dcf7466d4, + 0x0f6632058ee58c94, 0xfa1aa4c0fcbbc5d6, 0x2256ac40d8755bee, 0xe9cbf1cc56bd76d4, + 0x87059414203c36f8, 0xd84ab79422e2288a, 0x74c81d6c8430cfac, 0x3d4f7ce973d3dc57, + 0xe098257b700b1964, 0x0ee9a1f5c03c3fdc, 0x3d48ee56902a14b7, 0xa0264fec88ae359c, + 0xbfb9fb5855ebf9b1, 0x44aa0714d94a6a0a, 0x580a06fa8ea19f0c, 0x269ee7ddec1a0f89, + 0x0daaf7a44494b10a, 0x2703eb785b7fc1cc, 0x45b1e5a01c5e9e3c, 0x1a2e53db41f4b4ba, + 0x706e08a93f73b6b3, 0x2cf6771c1d66f31b, 0x4bc96ebe0a7ae002, 0x83df17b4341f25ce, + 0x41480229c590355e, 0xd802f520fcc7c8c6, 0xfad5b6cec14e9cb6, 0xb1d40ec2370c8a21, + 0x828273b5b2d9763f, 0xa9f818ce69f355a3, 0xa96dae508268e86a, 0x508b13a181d39274, + 0x42eb7ce556563780, 0x0a283934c9125808, 0xe85ed6ce1d904def, 0xc376ba3d26c7f3f9, + 0x9930c4713ef83913, 0x62d98be760c25c1f, 0x2ce24044ba9b4fbd, 0x758f1cf816a7848e, + 0xdc705606f2ec2705, 0x3de9078f6124874f, 0x9b020ebf2ec0f8e7, 0xd9986570b7f1c60a, + 0x17cd3e6303bd4857, 0x7504ac42f974647c, 0x4ebfd2efa9a3c920, 0x68d58c9e02872b03, + 0xa8e0fcfbfd2f6a42, 0x5e8bcbaf671313a3, 0xaa4b40058b612561, 0x76ffb64c8d23cde6, + 0x6a92e17bf0182283, 0x89f3d2d362deb744, 0x44d2dd2c01d19b1f, 0x8acfc93a87797dcb, + 0x9a52bd8c60ed7f9e, 0xd9241858bfd25c5f, 0x43fb099239bb8a1d, 0xefbbb644c4f7ea5c, + 0x534928753089bc5f, 0x0d96aa2b69af172a, 0xc71c0b64dc05447f, 0xd5a207d0b657f938, + 0x6daf7ab9aca5933c, 0x4eb44e34f672de80, 0x8fdb909eab476387, 0xb02c19a8cd7b38ac, + 0x332dc7a68f73298b, 0x0ee6e9a92ddb7d77, 0x68e4ca04ed2a2d7a, 0xd8c9e8078309b149, + 0xc859ef21bdb9790e, 0x61a18792b92635ff, 0x5b2149910043716b, 0xf1bc5799725c1271, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47cb316daea4446d, 0x1951d98ce3ae6f79, 0xb7148c3ee14ddb8e, 0x529d00790b29995c, + 0x0e6944b71353355e, 0x442df4b06a9d679c, 0xf4d7d8ecf15bce99, 0xc2729812271118b4, + 0xcbec423fd5c2299a, 0x704ba2ea8625b17b, 0xbfc7840f681706ee, 0x33353b5cad9c638a, + 0xc2b65951be6563a6, 0x851b0da694ef4f71, 0x10fb82a89c66e789, 0xe77d6281f2f2c293, + 0x1d4f177acd037e60, 0x3f8cc338e2be8ec2, 0x9b3c04eaf322d105, 0x28efeed79d0b0bcf, + 0x42b8f17f9f28b232, 0x30ded5b11c39b20d, 0xaca5ebe1a69cbb0e, 0xcdcbb3e55222b7f8, + 0x6fff1331ca5d80d0, 0x07743e6c4e604abe, 0x0b72ce3024ce8baf, 0x4cc2563caa3c8421, + 0x65f799cd78856906, 0xc8c8935bdcece665, 0x213ca01f187ee65c, 0x72e7becac6f1ad22, + 0x10f649dc860091a6, 0x143a53ef13efb407, 0xa3948617437489f7, 0xeed84b264ef67c1d, + 0xc3f103cf0dc4c5e2, 0xcd5672e8f36d5cbe, 0x02e7aa140381add5, 0x90f53bb2c1798b4f, + 0xa93b7e2605969c9f, 0xb244078a237bf710, 0x189c129beb9776ee, 0x291383865815f73e, + 0xadd260584c31640d, 0xa807499843f1fe10, 0xfebee385bbb83457, 0xa0e3d3196d896f3f, + 0x5f39077784374edf, 0xd70c57651867dfcc, 0x94bfdb26142812b1, 0xa8e6f6791099039f, + 0x84ceb1ece9923461, 0x91ca82b4f734663e, 0x545f9488d8bb743d, 0x16ac9ea0959b1d71, + 0xec93068e54fe6370, 0x23e8f22996689b71, 0x33740d31eb184703, 0xc84f773116418155, + 0xbd0ba404052c2c4f, 0xd6c051c1eb21b54d, 0x0ac0dd54e06261f1, 0x380245f267754403, + 0xa50b0c8ef0017a3b, 0x2bc6765a017852aa, 0x1a1adecee30de67e, 0xc9c556e56d906cf5, + 0x69196fab4542af68, 0x9fa1700ec6374adc, 0xd35583cf612d0fa6, 0x36f38fc3e8d40eab, + 0x2f1e71d61bc1ead0, 0x724cc10a8a09c43c, 0x042d4dc607b5e38a, 0x41438e3a0dae1e43, + 0x0dc2b6772ea5b922, 0x581f84f233ef2ad3, 0xbe9af0cacb8a9f03, 0x1e2443006ec883f0, + 0x96175ac2efc8e191, 0xa9c7c6f669170786, 0x4288dddb2a127a38, 0x7aa54716c2885182, + 0xfdc4ce25aefd55bf, 0xb295e7dad3dee7b3, 0x15cc19af07873c9a, 0xa7bba9aae9a100e5, + 0xf3ed65fe29a42e3b, 0x1609d3ccd4980df0, 0xb538b1096d1271b6, 0xae96631e92f9ef3e, + 0x2e33eb109f4c082d, 0x83ff675eb63fe29a, 0x3482765c2cf3f6cc, 0x49bcbbb7de41ac68, + 0x4a20c4923377f0fb, 0xed53162ac48e7879, 0x7f20ca8caf99f8b3, 0x8f8f6adbd7f27490, + 0x09a0429ffd36849c, 0xc1e9629b88840e3e, 0x8c13728a7747eb1e, 0xa00874f8321d00b4, + 0x059eef8543a7d067, 0xde7e4d040aad2c4a, 0x099560dbfbed784e, 0xa46808fe07aea14c, + 0x998caefbbd951923, 0x4a079110f47364c0, 0xc8d623516ae34623, 0x30411d5ce9e120e8, + 0xc673cc7c96f31c64, 0x2f3f72499b8ef808, 0x347d54c095cb019c, 0xcd80db5a2fcf8e4b, + 0xcb8163d474bde015, 0x76df0e64c94b8e1d, 0x7caf4002d6b5e32b, 0x918dab05881c3ba4, + 0x85fb5a4e3290e444, 0x6f8ff530cc29ee14, 0x8362006271ab4291, 0x0469b4d3f24ee97f, + 0x23c7129756f2a337, 0x756f56b50fa8d68d, 0x9d0a9d2f85a1342a, 0xed1c6a919e2cb92c, + 0x56a0d97e41cac1e7, 0xed34cfec61a63cd4, 0x6c38deb8413b7e95, 0xfe46eaa74668e061, + 0xff34677a9c214500, 0x55de956f83a1dd96, 0xaf792861304df3a6, 0x4da6d0710faf12d5, + 0x2a5dc50923cfee45, 0xd7aa50a91b7e77a6, 0xfa465360ad5ccf84, 0xa160fb98fd14590e, + 0xf453666b5a6a8234, 0xb470b84f2a78ba87, 0xe333706269ceae4a, 0xd8a7f4503a7e6f4e, + 0xcd638baecf55fc6e, 0x917472517219de08, 0xaab34ad80912cd2f, 0xe1680a485af2a691, + 0xa32b31bbe687ba14, 0xb663dcce34e070a0, 0x27b39a1b925a82f0, 0xc900fb075b7b676d, + 0x594664aa07b0d620, 0xac339c094cc3eb14, 0x53dadcda8e2efcdd, 0xbf3b7b3a9a10d5da, + 0x90262f690ad4579a, 0xe54f32aceca1a63b, 0xf1c3772584ecfa57, 0xb2ae4c75d776d718, + 0x9ccf0f69e3d7556b, 0x52f085ff31cbeb2d, 0xfc45f7287d7285df, 0x2bc6a12c6c003d65, + 0x7e8cc21f50b5f71c, 0x00f98d230908895a, 0x582d2664a34223b4, 0x3eb7c2bef8223a03, + 0xafad7bff8c46cda3, 0x24976da0869dc94b, 0x7f80682972f7f3d3, 0x0a257c22dcf077b2, + 0x7b0097d30dd81fe7, 0x875ea948852008f4, 0xbbae190cb83cd7e8, 0x664bc047360ebacb, + 0xb3063486d9b4ea84, 0x8723129e521ced43, 0xf4dd00f371fb45e3, 0xc68cdd5f48009724, + 0x23a1ce213de11e81, 0xd1c2aea3c75b435d, 0x92f1c67dd1ff86d3, 0x25ed902c664402d7, + 0xd5ccc0d981c86105, 0xef38207fb6b53c9c, 0xc3e2db630efa6c87, 0x1c1ccc2c1bc04c8e, + 0x0fe21e302194d8b9, 0xd2bfcad02e6bda28, 0x4574300cbb38ce15, 0x867f16a835add5fc, + 0x7d884694eebe3ab0, 0xecb149d5705c2f2f, 0xc0d0c28f3f7c1a56, 0x3f4a2adde22e8524, + 0x13254d1970d3371e, 0x3c4352c7145bbc10, 0xb42ae4836483b273, 0x6826beb9c032efe1, + 0xfadddcc70d492dcd, 0x03c498a880bfc6bc, 0xf6e4f6031bce807f, 0x7e7441bdc4b13200, + 0xa3467dbe77c74c92, 0xb90d82bc024a6ac9, 0x11f09ea3584ce63b, 0x3619a167e2607ff7, + 0xefec2f945aeafbcd, 0x2dfd4f62a789d762, 0x55a7515e54f991e1, 0x5061b50a19bd1c72, + 0xd3385157619354b5, 0x14699892fd831a54, 0xe0bf057ab6f655cd, 0x61d28d98ff39a941, + 0xb8d9ee573902a2a9, 0xd782b6aa9a24006c, 0x2c9748b3a91d29d9, 0xaa104d93bc4a5e17, + 0xdd1756dcceb4c938, 0xcd84c8924ed882e1, 0x35873129ef573559, 0x745d64236733f746, + 0x61483f5519e6c605, 0x5df423a8d6cf44df, 0x51d901016c72ff7f, 0xaeb4d808de28e1c5, + 0xff6fc0dbc1adeca2, 0xe262917f973040ec, 0x6961452836b1357b, 0xdf4eb4c6908b2470, + 0xcaa2e62e69883261, 0x2b5053b94e0f50d3, 0xc9c8824c766e90f5, 0x975effcc70b8c73c, + 0xc085364f4cc9401d, 0x9e7b5f9f1032b91c, 0x4fa4cf11f7c79943, 0x1997f1c8d634a144, + 0x36b6205ba9d81aba, 0x44ec41fecfd9fa85, 0x6f29d3728be3c8a2, 0x810ab87a65196835, + 0x3b2fee0196937387, 0x7176f65fb338d2a4, 0x7de602c866a8d715, 0x1949fd7f53364725, + 0x4e503250f063448a, 0x287ef746ffabff92, 0xf1b17d0c50fbb9fb, 0x8e184be143d22139, + 0x82199f86a4d16fa7, 0x347721622b43cdb4, 0x6d332a0a44c016ab, 0x71792bcd04504ff2, + 0xd7c23253f7801b75, 0xffca4691bb4a7f6c, 0x38f974a36cedd305, 0xae5bd756ea76453c, + 0x7f802f51225cd4e8, 0xdf10c32f2bcf3945, 0x236193b2644e05b4, 0xcf541753297c8992, + 0x0d08c9fadb641ca9, 0x1d240820083d4fd7, 0x51aed68225884c12, 0xb343010b93695ddd, + 0xcf8884e73886bd75, 0xf973c8e5421e0496, 0x268acc5398d9fed1, 0xac7acfab2910110c, + 0xbaeaf17ad7fff99b, 0xcef700952a481763, 0xf30c97e9e2688049, 0x968ba91addf95150, + 0xdbab7bcf53eff647, 0xf3a6fff8b4f471a0, 0x05d842e0894e6ae6, 0x45dc59c109c8c876, + 0x45e326285966227d, 0x033cc45b8a557bc8, 0xa7ddd9e723b09cac, 0xa828b283b4661187, + 0x72f19d5293f0be95, 0x6169e406134dc960, 0x6d8151a7239fa753, 0x48d23ea63515a23b, + 0xf11bb3de503ea6bf, 0x5f9ee2d662870eef, 0x60b595c51bb84fe1, 0x3afcc46b4a6f263d, + 0x693a38f9bd48333e, 0xf4ea534f8dfed1f7, 0xe76a7aba7270adc3, 0x6ef7512dbe51dea6, + 0x2ce7df1feef70a0d, 0xf50fd0fa12b2999b, 0x87b2766766a97c83, 0x6e882dde7d6497a7, + 0x298e5298d267376e, 0xc891c72ebc0261b7, 0x5a197cf8ec6868cb, 0x66e48ffd0ff1418d, + 0xd242f03716739628, 0xaaa329db92ce8133, 0xf0dc48352d745444, 0xa3d2f9200b0e221d, + 0xe4009afbcc0d15fd, 0x998d25b96d0de8fd, 0x67cf64f86bf785f9, 0x7b5fc4dbf5735d10, + 0x83df23153143e04b, 0x22a99125c73c5a6d, 0x051c91517fe3de04, 0x13652a71d7e1cd45, + 0xab078084feaf04b6, 0xa2c9b439282ca036, 0x7907ec117f87202e, 0x3be8c40a15315dc0, + 0x72cc683f303b4766, 0x704166544bf83523, 0x7e139628355f78f5, 0xdd09add8ff4e57e5, + 0x7a585378089aa255, 0x79ca69a5678573ec, 0x6f486cce3cfd8c67, 0xfb6b0e2ad41f9683, + 0x828a251c85edeceb, 0x1889b443c4c5f958, 0x0ea11dd07a38aa13, 0xfb8d47f003f0b660, + 0x29d6dcff77376523, 0x53754ce8aeaddeb4, 0x86508b071448c4e7, 0xf792d741169f62b8, + 0x0c7bf325d1724ffa, 0xad1d8a7328b8d159, 0xed25e8104dee693f, 0xaa0c42d660566999, + 0x59dab08a756f7d19, 0xb31f5841447a6f6b, 0xa749e402fc1a6f6d, 0xa74680f8e09221ba, + 0x3721282011e718ab, 0x4e135060f98410ea, 0xa6aa9cd85563caf0, 0x073053dd8ca807c7, + 0x2aa679e5c2401ed4, 0x4b38f9d7d09731da, 0x66bf953a6335c2d3, 0x601b6feb84438214, + 0x4cf1a02e3c0f4c57, 0xb9a4e7bb82ab37a9, 0xe6aa242706f354c9, 0x665edd041e1883b3, + 0x76d1adaf1e01ee9a, 0x4431789abd420625, 0x792a05f7a10a4944, 0x3ca1135ec3d3d39e, + 0xbdbf76ff77fd0207, 0x61042fe5613d9603, 0x4efccade64f769ca, 0xf799a7437f32c6d8, + 0xf09ae0e7caca0f66, 0x960098c6db2a0e99, 0x425313ede42172b6, 0xba24954b4a181acc, + 0xcde435229275b83f, 0xdc3e51b9dde9e591, 0xf0c3bf296161cd97, 0x8a4554ef0a626f30, + 0xefc19b8265aee9f5, 0x00a3156603833e10, 0x93584c3c940ded54, 0xa1475668db068cf1, + 0xebf8fa31471d7ca0, 0x64e3c3cfea5e3eeb, 0x7e03d2e778592fa6, 0xe98265e6de7ab471, + 0xbe9bd3ef6d3067f3, 0xe8cb06bf3d18c58f, 0x80264e09dcb3015e, 0x212c431fb9a5c174, + 0xeba51260e4960b60, 0x4b3d953fc4a7a7fe, 0x379a5a6b0c3a4957, 0x853f6c8faca0f413, + 0x2c629ff34faf1f36, 0x067c4531626d07b0, 0x0db77c91a5a15c32, 0x3ddeb4d1782478f0, + 0x0db951b3cffc2146, 0xf909b2d9ebdf32b8, 0x08da82db8dcf6e58, 0x4028a3e4c597a3ee, + 0xbcd5db4732d38af3, 0x7e432dddc9934aac, 0x493434be916138e6, 0xf1835dd64c822313, + 0x4000b4d6a6ba3295, 0x5f8e7afadd35d2e1, 0xad36e660029e7cf2, 0x4dd64c262b5a578d, + 0xb871bd38de2a76d9, 0x235a4fc21d72498f, 0x627cbc0775bd48f0, 0xea62f8b63620af68, + 0x4f855530302c2354, 0xfa092ad1cb2a1fcc, 0xe4b7c36c7d50017d, 0x9bc32bfdb6a45806, + 0x7d57edf81f70d8db, 0x297e985919f3d59c, 0x276758dd38787959, 0xea14765fbe238fe4, + 0xdd43cbad080c8089, 0x34454eba4d36098b, 0x96a81a8e493b3e5e, 0xfa36f6569e8e5b8a, + 0x632a3634befe270a, 0x932f7e0b969a49f9, 0xe3c655d0c06b08de, 0x60b8f06c6861583c, + 0x39872ae9ab4932d9, 0xd9bbbd35f32c48f5, 0x9e83f41bc1af1c61, 0xf0ad701c188c67f3, + 0xf3480953397816b0, 0x5930c8aeb92b2b05, 0x70318e477f997b41, 0xddd5e12fcd674ffe, + 0x699c40ae0814f288, 0x59986c252ba524cf, 0x4a7000843c4d1ce9, 0x8c0216bff40533b2, + 0x6efc37b594987609, 0x7b8e8659bb21816a, 0x44f8c072d4244980, 0x9763a5a1ffc2284e, + 0x57284699a4b29d76, 0xc5ea66e93bcdb658, 0xa92d621e1b324485, 0x84479b39cd5ea278, + 0xd6e4ddcbd3c649aa, 0xaaacdb7a319656bc, 0x77d5568b1b583f6d, 0x4b7ba20c8e54693b, + 0x4055c17ef7b9df50, 0x2d313395c890f8a8, 0x16a4e5fc3172fefc, 0x980661c87c33184d, + 0x55ffe897ed35ecc6, 0x21c7ba4702409fb4, 0x28f5687b1908190a, 0x235e3c15f38226ee, + 0x0460b23eaa313168, 0x9926bdb8e71c202b, 0xfdb3407cba0b6486, 0xc1b1552443aa19fa, + 0xc6cc5507ac2c5379, 0xeae3d62018ed9df8, 0x1a86f1ce83fdf045, 0x855518254d9a4192, + 0xaea2c4b19b71d093, 0x27fb0175bafafa07, 0x040806d8f6bbd258, 0x3529b0bcfe57f4ed, + 0x6f960cbdc7eb0e16, 0x288efac98d684114, 0x3ba44bb950d24c59, 0x6d2a43a4969f8467, + 0xf9aaf9a10ffda60c, 0x87fd0ee930173869, 0x11cfb125401f56ee, 0x1dcd1dab3cf955ea, + 0xc557d042bb3f72b0, 0xbcca1b773e40fcc2, 0x97af114ceb5c4b3f, 0xa69fc92772b72fbd, + 0x666aba79dfc2dcbf, 0x595a1614bf33dd4d, 0x21b3e745ca12809d, 0x08a014ead0f1c42b, + 0xdf6ec5c128b1a985, 0xc394bb039c7abfcb, 0x327c0cbff595ef3f, 0xe9f2b89edfbde610, + 0xfa2c03d9e372b12a, 0x8c1956db1b0b6f1e, 0x630c871c996008a6, 0x1eb6da14c5c87bd2, + 0x3d0c76dfc273dd35, 0x1852a10138e64305, 0x12cbdcba4f7749b6, 0x9d646b9a39d398dc, + 0x001377cc14f6e69f, 0x694a04d7199f1370, 0x064cabfa1617d659, 0xf2917f4b3e041591, + 0xa31297be87524fa4, 0xa998da9e100e3a42, 0x44aad0fe965ac824, 0xc0301443dcfc5acb, + 0x3f2193b6dba57e46, 0x0bd47082b2578ac3, 0x0f89e338ed507cf8, 0xb8162fc987a33f5d, + 0x3632d1dcf107fc18, 0x6ac325bfe3a0be2f, 0x49f8dc81579733ea, 0x82bbe493bdb803d9, + 0xdfac95e92d79ac8e, 0x4a285f579b518ac1, 0x4f4a4aea08909091, 0x6f433216233e47f6, + 0x924bf19673ee901d, 0x04082aabef5b459b, 0x93c5ba2a98b61546, 0xbecfe21475dab497, + 0x7aabc67b85716bfe, 0x2eda9d697a833bcf, 0xa1464a06b8ecea75, 0x721b825e794aa4cb, + 0xe751041d4e5e5d13, 0xc555e497c0c3077f, 0xf7a9459b707ef6b2, 0xae919c9673d32555, + 0x423d9bd7b4e20617, 0x288aa5523d9b6c48, 0xed9e31a80fdf2bca, 0x9b4bce3410b63370, + 0x6485958b1dd80350, 0x75dacb5228027426, 0x70cd6e76243c99f6, 0xbb19667e246e56fe, + 0x2210273f1c3e358e, 0xa103ee4e62c318eb, 0x2a4fd1aeeb834dea, 0x8f59d7cf5c78d96e, + 0x48373461fc75fa33, 0x09ed4eaa83376b05, 0x6e7d4375f60317ac, 0x7156fcdd0880dc03, + 0xfc1ba0c2f1138649, 0xe4d10a9c057f74fc, 0x334ce263b7898ca1, 0xca290e92f437a928, + 0x45ba0b07cb32c7d1, 0x4269315a8c8c8505, 0x49851998931f4183, 0x43fa4011a70ecd3f, + 0x428f6b5f209719fc, 0xccf1bb0647981d81, 0xbd25180bce544d86, 0x13f3e913e128411e, + 0x75a7920596a35609, 0xb3ee52adfab44c63, 0x01295f8681c67165, 0xc2fa9c41b8eade42, + 0x35c66e3b68f78919, 0x7034b0ee6e342860, 0x4623cd0229761f82, 0x7cb18e1f019c2b02, + 0x50d15c51a7c905bd, 0xd00fa6856e9828cc, 0xc0002e908755cdf0, 0x47750491cabc0271, + 0x6bb6f6172283e05e, 0xb012eab6321c6ec8, 0xac641d597d9019c6, 0x4d648d043a4e8748, + 0xa2375339001b9cf9, 0xada4648d8d0dc3e4, 0x4004d12b0a0d1dd4, 0xd20387e8759a524f, + 0x587c6c770f9cea80, 0xc5dc826b2a921d07, 0x8f0f6b3de14c9fe0, 0xb89a4e419f3c0993, + 0x5fe3947f7de56f90, 0x24184367a51fcca4, 0x9d94b51c92db4dbe, 0xbb2309bd85800234, + 0x8d6fed1c90ee95d5, 0x96eae22ff57eb7ba, 0xf826197f2d07cbc7, 0x48d525e90dcd1623, + 0x6016aa5b6ae100ea, 0x5ff8c63f5b590a1f, 0xb59b2bf14817ed39, 0xa192056432a8d025, + 0xca4cea8599dfb866, 0xc35b85fb1e017e9c, 0x9039f1bef7a4a410, 0x7f1f289608d04c23, + 0x886074a37d8bbf74, 0xa9e2e5faec088d67, 0xe81e0b6aa76f742b, 0xbf00e276db6b7138, + 0xa14c7390c72952c9, 0x39763b6d4c852242, 0x1ca6b5327f716b38, 0xb647d4e3a8116bfa, + 0x3cabbbaa96cdb599, 0xf1f1c103fd93f3e2, 0xbbc5663208574c6e, 0x35257365df41bd73, + 0xb38c0269a2ef7ac6, 0x695bc8fc07c22ad1, 0xf5d65950fce3839e, 0xb6e3ca2d45f8f8a9, + 0x78a57b935d45070c, 0xc4665585fb5c1678, 0x3b59ae4f705a7543, 0xfede23d7b6d5780d, + 0xe8a8d460b43725c3, 0x361d8c8c68440d28, 0x13f356072e5fcdf3, 0x2882d50c04da36bc, + 0x9edc7d2e50db8663, 0x0745565d51454fc1, 0xbaba03de33903404, 0x1424e9fc1b4f9c17, + 0xe843201343e05786, 0x7c2ea99cde59abcb, 0x287299373d7028c6, 0x8ec81191abecc4f8, + 0x7d9cb74299ccb8f1, 0x9ed8d1b243a797c6, 0xcf1c00bf484c3a85, 0x3238b380b4bae9ef, + 0x1487ed49765375b9, 0xa65a82d8fbcf068c, 0xb68be07ecfa34900, 0x02268f3ad4497df0, + 0xc3436e5766042e7d, 0x2f11398b36f348d5, 0xe50b51e4de21adfd, 0x871681cdf4135dbf, + 0x9f3155fa73776c53, 0xb64123f08f711456, 0xa2d0d22f23cc6685, 0x245a1b7088c1a2d7, + 0x819c3a58be83483a, 0x6fc4ffb31c43c956, 0xc879a30ae1be570f, 0xb2f37760c9176243, + 0xe31baf84c38f7595, 0x069c6c9ad922c3ff, 0xf62e1d24c751f9fe, 0x2104c723c93273ca, + 0x6ce809b56520d52c, 0xf91c38465ba2b6f1, 0x093ddb1b427579e1, 0xdc19de78b762460b, + 0x53c69c49c1f9724e, 0x8b0265fca043604f, 0x7f8f89b9bfab5db4, 0x37f63f4fb2487664, + 0x2b3440b91eec4044, 0x9563be670b3cdeb3, 0x0758e285978c74bb, 0xe3105c1f607b3468, + 0x021379fc2361b7d4, 0x37a76eab34f18162, 0x69858692b5445131, 0x428380fe0775e500, + 0xe809432d8e597b44, 0x57c54422f33f6f97, 0xc2ec6cf9977f006c, 0x66fc757e7e4b99bd, + 0xfeec3309152f9925, 0x054ad60e0e7a46ce, 0x9479f4b64541483d, 0x67e6f938c0b64e21, + 0x112b71fd7a9fba7c, 0xbcb4f119fcdb4850, 0xc9d138daa7702b58, 0xac42ebc3175ba914, + 0xaa16df74c28eafe5, 0x000c43a79776d8b9, 0x3fb46e8f755a665c, 0x6c6cb9d59666b7e0, + 0x64e2b6eefba13c34, 0xbc1f817a9285d039, 0xbe2574491afdf18c, 0xd8e7c71bf466fe32, + 0xb7263c83586e2c32, 0x85e9a07da29a1aa8, 0xcc03588a0a8994b0, 0x5b69fa2f454f57c3, + 0xc7cfe9c4a9795ce2, 0x67894d6d49e83794, 0xf533bf76330d98f5, 0x708405f9dcce681a, + 0x60d978cffa081e3c, 0x5be06f645d693a06, 0x1abdeaa0f3301e9d, 0x19dd54b112ba50d6, + 0x52bb9528e5223894, 0x635070fc469a8ad2, 0x411eb7511019ae17, 0xa915001fa159aabf, + 0x259340edc94fa139, 0x424dd6c0b7e58318, 0x99a9b357f0e8a901, 0x0a9a3668a0f2fad8, + 0x91b249baf870b0b6, 0x7d9b2c5bcda0e175, 0x1283b326f609a375, 0x68c0ab09cd0460df, + 0xcc58c383a4880227, 0x3ef37c2a85e73f27, 0xa6c87b71ee14fc41, 0x64936b667b77a39b, + 0xa87cc1c311d57939, 0x0e12cea78550a98a, 0x0edf3416ff006295, 0xeb8f3540f57987d1, + 0x0cb937a5ce8a2188, 0xfaf6b5689ce2320f, 0xbc302819b0376102, 0xee6184df9a45b63e, + 0xdbdad8a918653125, 0x5707ad611d2e6f34, 0x1ec378c9f4db2853, 0x63141c1d21d20498, + 0xebba70461457f020, 0xd9c6c7a94b852e21, 0x174fad4cbdcdd88a, 0x1ce8fdde17bac1e4, + 0x88febbffcf1d3f55, 0x2b602e30c2a37768, 0x05663b30101c7a7c, 0xd442d0cb93ef78e3, + 0x9fa5d43570bd84cf, 0x79397b09174c3fff, 0x40ec092470734a27, 0x30b408ac34025f2b, + 0xd9bc7a63aa62850e, 0xe87d2b829efa4406, 0x6f496234b5e2a055, 0x5021867a710481b3, + 0xb35379d77d6241f6, 0xe56fbd4bf3b02b88, 0xee7be2d64cc67585, 0xfe34042bdaeb413c, + 0xd69badb932f14be8, 0x796633824168aea9, 0xc4d1607a893bfbaa, 0x864df0080dee784a, + 0x69de3fca59ccf044, 0x26bbbeceb6d1aec4, 0x4bef826bd9c2714b, 0x08bf0c4394a7cc10, + 0x295cad5f10bf1038, 0xcfd50867a7deb835, 0x398035d3a934ed5a, 0xd02c0c31f2eeb615, + 0xc8263073e51ae573, 0x9eb3d04c1fee5c9c, 0xf495c0a301c45247, 0x71dd00d967ba79ea, + 0xdd2f22907f57a746, 0xe56d25c8fc9db477, 0x68b020553412a08c, 0x0760ce0cf31b722f, + 0xdb4e6c427ef76516, 0x494a53cee10d34cf, 0x7fd825f55bf4a4be, 0x3b0a3173560135cc, + 0xd082b29647d98c72, 0xe9ca03be70de959e, 0x2fd5f068cc93b311, 0x3ea8fbcf90efea68, + 0xbc977cd1f2635187, 0x62c0f8b4f81a7f5c, 0x166247828fe3c2a4, 0x22c8067c262b640d, + 0xc0232bea1e9e7386, 0x1d0b61512ab417d5, 0x7935e8314da7d05c, 0xfb4529e0a661514e, + 0xa9a5a253553ab284, 0xaf05514dad66a498, 0x6cce42c3b28cd2a2, 0xbf2eb430f2ec5b57, + 0x95c54a03eebe98f5, 0x28101319b8d1e262, 0x75b6661a98fa5c34, 0x37f99e27f124fc79, + 0xf034af90ca8906b2, 0xcd73c94dc7f3fbc3, 0xc64e8e2d02110a9e, 0x89aef42d28f67353, + 0xb257700c28a619bb, 0x3e2482c333d0717d, 0x48206b6b1943c481, 0xee9e03015007ff7c, + 0x83249b9377caf192, 0xa1396245c04896ec, 0xe59924288321090a, 0x9c48279b72be9bfd, + 0x9b0d6e0f436ba245, 0x3fa440fdca7c5927, 0x1a5bcc14f595799c, 0x8edfdeddab469aa0, + 0xc14f62d1be917def, 0x18e4157fab5255f9, 0x2f6454a15e9ff53e, 0xbc62423127ad4365, + 0xf97c76b0f9949566, 0x02e91eafe1a67feb, 0x7d6d192dd561632c, 0xdff1d45d66c66d9a, + 0x803a9199f1a56646, 0x03db75de54454f70, 0xace0868fda2642b2, 0xc8f008c0212c3e95, + 0x9057ee7cc43576e3, 0x26227f6795e29ef3, 0xa3bf923d51c7c2cb, 0x4cde9f0ef5700132, + 0xe71234eb70d03ac1, 0x96391244c1ffda3a, 0xe579efe1283b4825, 0x977ef1846832e63e, + 0xacf7b77d1581a80b, 0x0019b7d5e2d2a3e5, 0xd75e868876250920, 0x44f83a7ef51f6857, + 0x1c7373654e9829fc, 0x3e5b1c3c23c3b5e4, 0xf0f10ee3ab5e0d03, 0xa247caea0f5d4003, + 0x9ff14eed5de0a13e, 0x63f81ade4945da25, 0x35b6385213119c79, 0x3a3277733f095313, + 0x656bd0ef38eb78a8, 0xfcd5186d88a8ce66, 0xe20c27a0fa96d44e, 0x377d8a0bf100eae3, + 0x080c9ae246a0c063, 0xe875149e21d86df2, 0xd347565727c083bd, 0x02f8721aac0487ce, + 0x7752851fa108937f, 0xb081c313f237f377, 0x8b9526db8ba325fa, 0x29c66a68f57918f3, + 0x0512e9646f2c5137, 0x089781692547d02d, 0x6569b9392b5733d7, 0xfa4ccca436aa2d6d, + 0x803bb51c3113cba0, 0x562e69ef558c64e6, 0xab9047f724161343, 0x7f5d285969df4c36, + 0xd15765332d5d48ba, 0xc1974bd021b3b300, 0xe6770281002ba1aa, 0xe6d1b80853359a2c, + 0x590f9dad2c5a0d8a, 0xcf8a37435edd29ef, 0x979d39c9efa9aa8e, 0xf83a4da88bc29f6f, + 0x508a3d5e22aad5cb, 0x68e903ab0d52cb71, 0x312955296d2218a5, 0xd6763edcd49132df, + 0xf2aee76eb4c2b452, 0x0a79a3a469e4eaa9, 0x91d5b16859d5945e, 0x46bde14fea91c2cc, + 0x1c21b0d8a937485e, 0xecfc62c90a9b8d72, 0xdd71a76ac34568e8, 0x744113505aefb078, + 0x8e6ede0695cba7b1, 0x674d23032850e515, 0x141e60f4a0c34b23, 0x1c0bf8bc3a201bda, + 0xb19fb814e9ab8fd3, 0x57437bbeb6c78720, 0xaf050278a1bf823e, 0xaa9a76aa461c0e50, + 0x484002b7cb46a46f, 0xb1268adabea1d8fb, 0x268e3df300a337fc, 0x0d99a7debb2f5128, + 0xf2c9ca9eba2acc4e, 0x98d0bc5f8beeb084, 0xde59ada46aec2ad2, 0x0b9504aab45d0c01, + 0x630bb43177e7a1a6, 0xf96e736e78d863f3, 0xe5230a2bd828a5c4, 0x407299f22d008275, + 0x9d42e7b40e2f79cb, 0x1f036aa3dbd21e14, 0x1fa8808dbfd1dea0, 0xee6f091f5904636d, + 0x91fc99bf63ae1083, 0x7dc884d88c542023, 0x144b12d52dbbe853, 0xda5d9b8e2a24f9eb, + 0x227d286a8798d192, 0x74157aef50711b0e, 0x503b9aa5f947720c, 0x893536b2d5d97949, + 0xf50ad69fef98d74a, 0xa4eb7b76d5315e4a, 0xbe95c7d12ae7e2cc, 0x803543580d9a83b2, + 0xa37514831cba3ed2, 0x6c2d3d6fc6250a2e, 0x2f60b856a9dd9a49, 0x76c814bc1c60a2d3, + 0x2c7ec34fe5a0ed41, 0xa48b89c7e7899f67, 0xb094004b5e9d63a3, 0x52797ae1bd3c94b3, + 0xaf82d4f5608fabd6, 0xa6a2fb39d5c19fa8, 0xf96b3a8bf3625a27, 0x222e9a6aedfba7b3, + 0x49ef45f8dc23045d, 0xdcf70e4663000e41, 0xefc841d124b61dfb, 0x13c09e0bdb90184d, + 0xb8d738e075586921, 0x1e050c769a1ae290, 0x89244fdf1b9551fe, 0x802e84d907f1ada5, + 0xb4fd99152b21929a, 0x5c62f5d7a9b8bd72, 0x3ac3429c56929428, 0x0c9f0c4a4894b478, + 0xfed6c2d8910800bf, 0x8bdc84f7a0efc8a7, 0x42085048639d33e9, 0x9c2081ee94962f32, + 0xe265d303aaece6ff, 0xcbf81d5e472e5d9e, 0x9774628a2c9e1384, 0xd7f1c6020b0b8e61, + 0x8070b09f2236f896, 0x530e6858efe2826a, 0x5dabbe0d21622264, 0xe0ebb13efa5d6f1b, + 0xb89ea0457c6314ee, 0x004930c7e3715faa, 0x88b448d351f918fd, 0x5f482cc1d901b1ab, + 0x572760107bbddfd7, 0x069b90304afacac1, 0x9a99682b54885287, 0x1facd5be2f1294a4, + 0x4f967a5015d1cf1f, 0x76163e0546d7dbe7, 0xfa275d894d4f8193, 0x854b07c578c150cf, + 0x1dc7bfbe799dee0f, 0xf6a3c45e52e8aee5, 0x976e5563275d2520, 0xc13529e66676ae8f, + 0xd265cbd73652709c, 0x4ecdfcdf68dbc49a, 0x19c4e31faf26fa73, 0xca1cd6530166132f, + 0x8cd3dd1d84254cbb, 0x5191689df316289c, 0x59593d62456c45b5, 0xb74f9d844cc6a179, + 0x0f32bf9f98e3092d, 0x1b2bed3ec1bbdfa7, 0xffe0b5caa38d9fb0, 0x9e26f336ce31155e, + 0xf12c954aba567b3e, 0x2165dc08bedda2ec, 0x54eebd0a17a9134f, 0xabae066183916b25, + 0x2710a17e4dbf1e39, 0x31328d6b37ff69a4, 0x68e819fb4d792fa8, 0x0c483e19ab77610f, + 0x9e388c818e3c59aa, 0x0aae6910a3ac698a, 0x310d0ba78f2f071b, 0xdbe5ded5465dd648, + 0x2e4867a24f6e9699, 0x99052eb3aa1ad32e, 0xc0ba8f29086f00b6, 0x46d7d5733f1e8e14, + 0xae852045df608b88, 0xe4f3879f1126a717, 0x06709ee95d812d59, 0x78bc6e0b53513cdd, + 0xec95ded66b4301a8, 0x056ceba1858e168c, 0x0b5404f133e43790, 0xf7246cb79c9d6ea2, + 0x7516a42d63c67451, 0x937a74beeaf5bccb, 0xc6b778e2e4d25993, 0x1a4e27bf1f1313e7, + 0xcd4635a0e871f17b, 0x1ff342b9ccaa4185, 0xf4788faebc4312f2, 0x39356ff42b2a75e5, + 0x0cc3564e52f81b2d, 0x7e8936d18b5540bb, 0xd92432676f54e2ea, 0x8d4e73c126a1db09, + 0x951cee42b521deb2, 0xa8cd89e58c2cdd67, 0xdfcd3c678a43028c, 0xb488d09f6cf4cabd, + 0x187084d1feed6fc5, 0x8b03cf35cf64d01e, 0xcacbefc199a62030, 0xf76f4c783b218eda, + 0x9ebe34d4d778e02d, 0x0ee390b46532b26a, 0x6d4072fa129207b5, 0x1e2b19b67ed19e47, + 0xa29d9eb10ebc7e65, 0x327f6d57cdc159df, 0x8a400df13b4a2298, 0x09b91c47c852c384, + 0x13733539f94c8fb1, 0xd2e36a7fa55e4d00, 0x8bda57cf1729b023, 0x7865c25ea55f1eda, + 0x0712c64eb879d8db, 0xf1f280ce4b527f3d, 0x3343922cd4bc18c6, 0xdb5de50531ee2b70, + 0xea3b957df1bb79c7, 0x348ed5e10ddfcfd8, 0x68fc345d5b6b6f64, 0xd910640aa29331d3, + 0x08854e8ff6f6978f, 0x6d0df657a038a57a, 0x6463a1a30f62899b, 0xbeaa22899e2337c5, + 0xd8e219de34c7bfca, 0x7affcbe16bba9663, 0x274f95cfed85aaa8, 0xb77d2bf0c95125b6, + 0xc07c427fc0acf7a0, 0x3c60bc3399e408e1, 0x8a2eeb621420bccd, 0xec663ad1deba216c, + 0x0ab0dbce71c30f67, 0x6e16b6d532e3a98a, 0x46aa447319102085, 0x27e752c7cac6eef4, + 0xb1f9ed6e05ac9c3d, 0x8bf8b1d23067ae8e, 0xba898030c7d9d7fb, 0x523696173519d106, + 0x86c177f7521e5482, 0x2c1aacd42e24d4ab, 0x5149f959873e7db1, 0xc85a8b10fb5ce953, + 0x0a90bec3758fc3e5, 0x01f1e06f01e0c685, 0xedf59a08f381c59d, 0x92fc8c8ec774cf40, + 0xb6eb9905f9a8c5f2, 0x1f51adfadae73724, 0x1b72b73cf2d83156, 0x9e59df020c098c22, + 0x19ee954df8cf3ade, 0x808e65170e18a8ac, 0xacdb8c9e9aa91ea1, 0x984f66e920bf4e18, + 0x60e0790a9b3da320, 0xa67155461566fedd, 0x5caf6098eec644c5, 0x1914e48b07b150b3, + 0xade8b48fed8d64f5, 0x5d74e9475606486f, 0xca12e488d1eeb59d, 0x6b629604a35b37dd, + 0x223a543e49ae86a1, 0x1ec4f982454bb064, 0xb2e224a2d714aabd, 0x9df5df3f86ef6afe, + 0x2358ad066f298f87, 0x900b627e298f03ad, 0xae423ff79c289af7, 0x1e60a35f906d2729, + 0xd8a87be56265353c, 0x283d220bc656bef1, 0x4e1568642a67e90b, 0x4a372da4090c203e, + 0x930f17fa6d9d9295, 0x008e7cad7ae44963, 0x4def85ed7d6a2684, 0x8ac38810bbb07c1d, + 0xc1eb38ff94e33719, 0xa20452176b0e10fd, 0x8653c016932139a8, 0x65801e9076b0d5a1, + 0xab480895a5783ceb, 0xe4497b4f9cd239b7, 0x9c633934099b5587, 0x9c2ea07e2443ac5c, + 0x1fccd8d242221b62, 0x58637826b3405107, 0x2432b21719c8d05f, 0x3b38cf7af7879264, + 0xa85e7e22226cd4ba, 0x80c15b74cfbcd5fe, 0x4a3ee4bc6fd5a1a4, 0xe4a25f80f79b0ffc, + 0x3fb4e9303e73ac7f, 0x898dfff3e53ad339, 0xe86e0f1bba15eda0, 0x60533e19ba424934, + 0x75a7705ba2031cbf, 0x10f6b25dad4cff20, 0xf3d368ed7224ef8e, 0xfa45adf2440d8ee9, + 0xc81f29d2dfd91b75, 0xb3d103a0f4343748, 0x2531a2141d6b559c, 0x5036701548a751a1, + 0x08954e789cacb630, 0x7b6b11a33cebc0c4, 0xec19b0d5733c051d, 0xb8e99762e92db1a2, + 0xbcf3317f85af2fcf, 0xdf8e19da0cb927eb, 0xa25fe9d344618317, 0x596b4ff3a88ac428, + 0xc07c1bb018a073f0, 0xa93df433beb88c39, 0x3b47c18275f93404, 0x7567bf3e78958bc7, + 0xe904d5f90df577bd, 0x78b3125f1ddb8139, 0x69cc3d0ae81d428a, 0xb66145ae356801a2, + 0xda3082217fe10444, 0x7a0bda5f9e98b7df, 0x74902f50cbb04c2c, 0xf4abf3924010964c, + 0x23638997a9931a3d, 0xaeb063448efe7508, 0xbca88a5517f38213, 0xc81b64dae5874482, + 0x4bdecb1808bd0557, 0x78a0ab6e90584ef5, 0x0f38dd21b6d8087f, 0x800049c26c151625, + 0x495414f1764aac21, 0xcdde8ee0c950786e, 0xf105d0591baa20b5, 0xcbbc516880056d89, + 0x11fcd7f6c4502d8f, 0xe5116eadd640b15a, 0xdf7f734105551453, 0x2747de7d01793454, + 0x59aff3ba6581d1d6, 0x467f129784fc33db, 0x84c70d02d105d5d4, 0x8de340b6e077cf4f, + 0xb9cc74a6854e5659, 0x539dd27bbec75ef8, 0xc44a042b67f5b684, 0x0e45e5bf8ee70f28, + 0x03ce3dd8243a27cf, 0x77c5953b67c0394a, 0xc49e22eb3055d0b2, 0x5e30d1816f6325a6, + 0x88cdfd302a91213d, 0x1bf4594fed605006, 0x4cbf704f19713184, 0xc16eafa4760eb7ce, + 0xd0b3cdb7ee8d6bbb, 0xae557152030015df, 0x56fbdd1e8a7c13c7, 0x8650dc7437cfafea, + 0xe7360958b8190b61, 0x8cdeef985b588f54, 0xebf6b16fdc991a71, 0x8bfaf803dbc82953, + 0x62eb1fc78d40d6c4, 0x34812e41cf0889ea, 0xbbe7890e434b313e, 0x739ffe0d6d4c0227, + 0xd9c229c40dd06ced, 0xadf41a3b9ba14964, 0xa668ea699254ff2a, 0xe9d4a68dafa3ec32, + 0x239099b86b4b5d17, 0xfee2fdb2ec108e49, 0x58e135fe920bea50, 0x08ed44268d416142, + 0x844e2ed4afd40801, 0x08572c2d4c6e8515, 0xc38ce392d0af2414, 0xa274a71febd66711, + 0xc9cdecda07b309d4, 0xddd7bf8d522ff68d, 0xfe2cf92627fc261b, 0x70c9254f57f2c2b8, + 0x4a9fcef9888b9fe6, 0x275c57ab6d6cf167, 0x94fbe062e3ce1366, 0xbb4942007c21eaef, + 0x48ba00be03751ae0, 0xca692e7617f9f867, 0x7730cbcd74c5080d, 0x8d6fecde134f6ac9, + 0x6c807e361adff979, 0xbad7fdb686d0438a, 0x1d559db4a942d85b, 0x5d26e0fa12087d15, + 0xbc07f142baf0c3a8, 0x67400a87453c020f, 0x65cac6ef2cc17db5, 0x80d5d9c8d995d83a, + 0xdbe188cac6b7e851, 0xd09daa1accba128f, 0x995a882a4b043e9e, 0x1652f413c43b61d7, + 0xb6a7c65ea2e614b5, 0xb29476ec31360102, 0xe096ae81dda16d1c, 0x8bcdb96439a5ff52, + 0xfd950222976efb67, 0x241cec3aa3c23931, 0x3c24b775287aec32, 0x0341a7df8309b969, + 0x6c66ed622d1b055e, 0x5f44f761bfce19fc, 0x308ec44109203cb4, 0x59d2ee6c4b88fe73, + 0x65821597cfb45938, 0xb5dca474aae9bc46, 0x905468324a31580f, 0xce19dc288b5d9d97, + 0x27b6cce1420c8b28, 0x5d93367c1f5a5ea3, 0x5bb50d6939c373d7, 0x63eed7cbad5cab44, + 0x327f066591780682, 0x85b61bb1fdf7a633, 0xb9b4d037bae429d2, 0x4805fdbb1a39a24c, + 0xcf59d5e292befde5, 0xe4ae180d0223b3fa, 0xd4a25f4da61cb7e7, 0xb8afaf674cb4b8ba, + 0x5cd11d67be6763f2, 0x0b492d820d840c45, 0x56ba3608bdf83d8b, 0x9f339365fbefd11f, + 0x50a34a8728042fdc, 0x81a4b4d888b3c713, 0x4be8da1fa991b8c8, 0x282257f7f30ba02d, + 0xe87095d558724e62, 0x893db002f003c1a1, 0x3dbd1891517622b6, 0x671bd0e3a63dd5f9, + 0x544acd92d791c56d, 0xd3c07db5378a4171, 0x39cf33e23fb2de61, 0x868824f8718a7769, + 0xe53406291cfe9611, 0x9d48889653ade343, 0x86f89e6654ac444b, 0xff2453ee39ff4bb3, + 0xfaa2cdd362faa89b, 0x52f8212b0730b506, 0xc4da1dcd13540c73, 0x51d8c5d24436493b, + 0x63fa2aa1d7bd87fd, 0xff00aa0e69724743, 0xd3387bd34baed072, 0x5b94668c23c570e7, + 0xeaff4d1dbbb05580, 0xf52056bc66a6c80f, 0xfb0d2da7c8e40470, 0xc913639dd1942f12, + 0xc4a0a52e8e9e71d0, 0x95d0e4c8ab9492f2, 0x167f9184dedd6b7b, 0x8eee4cdb3e5d5b19, + 0x7220cc62e71203bd, 0x17d80b8c21508b10, 0x27f8453c2e3a8538, 0x56ec343a59233409, + 0x54f9e9c686f9fdee, 0xe05fd4b5363da293, 0x183724cf40ccbb0f, 0xad5093e265e449a9, + 0xd6e6cea5c7385cae, 0xdcd39b916a12fca4, 0x2d5667f7b622b7ff, 0x64f604cc21413c38, + 0x35df90a54d628045, 0x20da70e4ffe6882b, 0xb8a62e793ddd8e55, 0x01828b9da66c3f34, + 0xf51126c77c0d21b7, 0x1de0aaa3a0c76071, 0x3565dc664b65fa5e, 0x7eedce211bb44079, + 0xd7b955e20a021331, 0xc3e716e42da8409b, 0x164e615f92d0ed2e, 0x78fc527a7554b384, + 0x663efac6fae91776, 0xec6ad065c4399330, 0xf86994010dbc35e3, 0x62dbc3beec6caff9, + 0xac2df2d420b38533, 0x4c027bd7988b3ff3, 0x2bb2ca5d04585127, 0xdf0572d20c82a968, + 0xf362b1335e82d222, 0xea0d08feaf494906, 0x9eb1cb9f11656b63, 0x85a4640eafd9d016, + 0x93c952ea62a1e2d2, 0x1a24355bb32b19f2, 0x5641f07e5be61c86, 0xc79cb618b6f806ca, + 0x1b4c0aabd9dce0e6, 0x3dddefed24e17f00, 0x0503c6b53be8a126, 0x120b2a2d8c1e66f8, + 0xa270580c86a13e81, 0x5413d15b09d76d7d, 0xbaf4727db5ff2980, 0x44fdd143d20da814, + 0xca73411d8c6fe7b9, 0xb5b01d9e3f74f739, 0x272612acc2ba9b32, 0x51cc5bffae475930, + 0x98211d6c632031b1, 0xd42fadc1ac8c2eb7, 0xbf884a8934c3841b, 0x09c08aaa348c0f91, + 0x1ccfc4714715bb91, 0x57532d159fc84bd3, 0xf3d5eae5ee3199d8, 0x883ca018707a12e1, + 0x1a5f4a23903b7fb3, 0x2d99749c321d832c, 0x79428c48c991c49f, 0x0b288eba0ae89261, + 0x624a40ffbaf45910, 0xbeeca9ba3f2a1b64, 0x205437aa57f81059, 0x8118067e14e2e4d6, + 0xde5b9a4585d06e18, 0x39e0610122d24e94, 0x70c5c13adf4a649a, 0xb99c623fd2b85032, + 0x4899fc05d5d4f8fa, 0x538a90c1a03c3493, 0x69b87fb2b24fba99, 0xf498b5305d37f996, + 0x00ded8f787ee2e5f, 0x72a0150e2ace176f, 0x526e87ea868b98fd, 0x2965a46a31fe83d4, + 0x140babc924206a50, 0x9b077d8c18df4632, 0xe9d279ad9bef721e, 0x526029d9b17e515b, + 0x4466d50c771e178a, 0x6b7eeff2c93d9bd5, 0xb2f22434b4e95b8a, 0x51146e21eb622f69, + 0x60b1d9daf80647d9, 0x3363073029c8ee6f, 0x28153f1581297849, 0x00d71107db9a4a27, + 0xb04564ed9901895a, 0x66cb133bf6abe80e, 0x414c13c6d405c706, 0xbcf45abb4908c354, + 0x752d4b8bf80fb3ce, 0x50a42ffecf806b54, 0xf60c89ff4db3faf8, 0x204ff208ef8ba12f, + 0xeacba888ea889c05, 0x7eec3fdddcacba9b, 0xbabdd5b5fc47ad34, 0x2360b80ddb33e0d2, + 0x5859db730dcd1f1b, 0x731af6f31a8bf130, 0x2d7b4e37da6da9e0, 0x3177c5dbc28b6e1e, + 0x9f6ea1155cc1ac81, 0x20551ed993f28729, 0x0ec39004f9df0a32, 0xc236181679db9ed5, + 0x9ef683ec7dd15253, 0xc9959a3e8fc9cf79, 0xdef8192f6607410d, 0x72e53088b42f5e79, + 0x46fbb5bac6271518, 0x5a33f965044fbb10, 0x5f9cf92d0e48770d, 0x47a6371777a1b216, + 0xe50f0a789c725f3e, 0x4dfe6e2dc179ecbe, 0x25bb61271db9f00d, 0x6723ef7d754cb90c, + 0xdc59aab0a504122d, 0xace4beb091fd2a5b, 0x415cbb93d5b53232, 0x4781d1eb2751ee48, + 0x457a2c2d653c67a1, 0x2686f01568cf6417, 0x7ce35b3aacdda374, 0xddcaeabc80a10a12, + 0x33dfb73c60bd11bb, 0xc4d82c05a1b89855, 0x240f6e5f6045fb14, 0x88c846eccfdb390b, + 0xc0ada53d0e0d6737, 0xcf0e2d848b6414bf, 0xfbf8b6d82e08b14d, 0x92b7cacfd220e1ac, + 0x2b6c05256a8a27e9, 0x2a3db35729add9b0, 0x596e247da113cc22, 0x8494be40f94de427, + 0x178d892376d680c2, 0x9f2584e0e40eeaad, 0x82ed61e42f55d963, 0xa9743a1da41c3838, + 0x6a8d46d78ba82cda, 0x3f71a9f1d67dd999, 0xef28d9de93dbe99c, 0x6d2f4b03e4d753e1, + 0x7dd46cb40e8e8558, 0xd3369177a765e599, 0x22a6c36ff89cd99f, 0x93ea2c16c766efca, + 0xf448b76aa5bfb04a, 0x9cd4a20d061fc730, 0xd6950dccf487a6a4, 0x3b58ff7e1126ceb5, + 0xf7bb0069790e8c24, 0x153eb0ed546daade, 0xc443955940a73eec, 0xf1b9845010d116e6, + 0x7b5f119f4d43026f, 0xa2caaac2fc3009aa, 0x0400bf2231d980f6, 0x889847cf1317f51b, + 0xe780d292154b61f9, 0x09cb12287223e34f, 0x9659f13221c95d23, 0x76b190e0510767d3, + 0x445230143f70843b, 0x55e06d8cfd13f0af, 0x9f7ec0fff5c0b64c, 0xed3fa8beeec7c975, + 0xdb469201a0ac176a, 0xd52f9ce508670427, 0x37808801fff18765, 0x97876b08fb04577f, + 0x4626dff92fe31a87, 0x7e9306c182ae991e, 0x9b4f740552f3ed5d, 0xf260ac16ad5a618e, + 0xb79f39761f2665b1, 0xd06e2b04271b9cf4, 0x3bbfecda3f9ecb03, 0x5baa74707f559a3d, + 0xdfe12e537e5246e2, 0xaa3e307dd21069c0, 0x99c10121bb01ea71, 0x4e1a36ebadd6b0be, + 0xd5cebc177e0978ff, 0x463d5f9e8e729ce4, 0x877824c0cf42266f, 0x021b150ace5e648c, + 0x2946c3678309432d, 0x6d67a3af313d3bd4, 0x586b35e5618421f4, 0xcf24559d339621cc, + 0x902c0ef7e9667b56, 0xd9d3d01377c3422d, 0x30109b717cb04798, 0x495fb55b90e3420d, + 0x37a8a414c01e959a, 0x5c106c49a79c56af, 0x020a7bb04c9d8cbc, 0x04c88903448c4e3b, + 0xd84532e065f6d162, 0xab95d0fef6ec33c1, 0xf5e196fde0d44e80, 0x733020e7424057cd, + 0x780cda11a95588d0, 0xfb5e6fa83fc9696f, 0x1ca62b3478ab680f, 0xa661bc3f6855337c, + 0xa1b870f1f4991c8e, 0xf6598e91f2b24a18, 0x90a0b03f1d5d0ab8, 0xe11f7c52d49b2994, + 0x909c9ee31bee3d84, 0x190022760e06eadd, 0xd19d1b33703cc985, 0x3e03cc571f0f56b2, + 0xc92173187bc107b1, 0xa28844263458eed1, 0xe675aaf903a494d7, 0x4827d6d36a588f5a, + 0x333259248eee45bc, 0xabe9076fd02e3e7e, 0x1f65553f546a405a, 0x23142d6193beb6f4, + 0x34e89bc34e6c5b90, 0x7d71a154edffe99d, 0xbd57d2a4be542b79, 0xe92d9832edc5dbde, + 0x40eaa280dbfe7e8a, 0x5e9702e10b56bf73, 0xb207ae2ee4c55b2f, 0xa58deed5f938254f, + 0xba5aa9f7e10880ee, 0xc592695e86d0831a, 0xc8bd11009279c702, 0xf6a27d3c98a53d69, + 0xbf47f5e427c6e2a5, 0xb8dd49f706529353, 0x9d928374d5e6dcfb, 0x1f8c22b3f4983d29, + 0xe40d64fc483557da, 0x47122186bfc32686, 0x18cbc900da69dda6, 0xf154fa05c947dd3a, + 0x13d790a028c760c0, 0x3c0e94621f5240cf, 0xb01662b26ba5dc98, 0x498ffa76bc80656c, + 0xa94c013464e96ff8, 0x95e058e99f12d947, 0x6cbb1d2722178d3f, 0x67449b0eb00827ad, + 0x9f0f1eadd530a958, 0xca5c8f0e8cb8cea2, 0xee7992e28425454e, 0x41f843a5434a8d81, + 0x1e70d629e89ef62e, 0xe73d7ac161925697, 0x2afcafc126bafa40, 0x839c8541e17787ca, + 0x059b4a1347775dbc, 0xd0e8e8aa2a02b126, 0xba19423ec103d8f8, 0xa269cb5c4b392621, + 0x49e1d81c1715a816, 0xbe8128262c06b176, 0x637c94e2611aa824, 0xe79182e180fbfd1a, + 0xe52499e8db72176f, 0xb14c5c8abd81059e, 0xee85302384c91e38, 0x2415e1e03acb9b3a, + 0xce9b0902f0b16591, 0xea871ee4ff52d791, 0x4dfe7d9f354e97c7, 0xa423aebf855a966c, + 0xfca679f5ab43e7b8, 0x2376f2c256580689, 0x75c007c9cfcd3e6b, 0x007018deb51dd51b, + 0x05741b4392ac9f46, 0x4219f55cad9fa1e0, 0xd34fd83f3a05b018, 0x3258fcb6e2caf401, + 0xd3706a047f3a8bc5, 0x7282e95f1ece0b26, 0x2629595b3329cfff, 0x109bc1edf5a9ec88, + 0x10b6f17cc0fb80a9, 0x021a31935b546561, 0x4a0ce2ffda185806, 0x646a4a57fb11c849, + 0x336eff842bb4d613, 0x91076d5a5e281e69, 0x95ac47d63002f6b2, 0xa689c31c90ad9f20, + 0x47a6f9c6c3039c06, 0xc8e24f56589f6129, 0x1cfb5834ed4854f9, 0x66bd581ff4a5139e, + 0x0a307a46aad4e7a7, 0xc419c108f8fc0006, 0x789d491b2883ce29, 0x9470ed56758d6909, + 0x2a013295b0530545, 0xf84ee893b374ce5e, 0xd33b40c8cf50e563, 0x5d604a36907bf253, + 0xcc86f8a55fd58aca, 0x866e0a4db7bbf60b, 0x06dadde4854de211, 0x4c919fdd2db95152, + 0x203364852994802b, 0xe40f2646072519e8, 0xcfa3733d49a67573, 0x4d43c581968d40ff, + 0x020261c0e38ef90b, 0x07ee52c01ccc54f0, 0x94eadc04211a92d0, 0x085374ae06151475, + 0xa1944c72d1fed7ac, 0x2e61e180ba300666, 0xf66a49c2e672a1c1, 0x1dde22a920be5309, + 0xf306bfdf1649666d, 0xea1962f984ad97e6, 0xebb447fa2e8367f3, 0x2babfed61d5c4c84, + 0x1d85a5d9d87386d8, 0xc25d1bb63f19af12, 0x4d0d3bad766d283c, 0x0cc0b000e0364e46, + 0x3250646806e2a32c, 0xa42b02227b68de06, 0x7d018af3aa367513, 0x4dbe3308e9f529a0, + 0x7f0181b0d10c1a37, 0x3e68e528ca56a94b, 0x69abd2aabb33e533, 0xb4a78f483f9b00f8, + 0xe04772e10656ebf2, 0x08eff26610d421de, 0x7dfca8e4078a34b0, 0x73ad97d7909ac3e0, + 0x87b73920626bf7eb, 0x4c9b95c4cae699c4, 0xdc6799ec60217dbb, 0x818c6d1b6fc5ff4b, + 0x1f74545f51c0328a, 0xd00e5e624e442b79, 0xc3fa2c972c5c1bc3, 0x03a1c2715335c907, + 0x9c490192b66167cb, 0x3438986b5b13c999, 0xfdb9e92495267c5d, 0x01ba8574f26e6e60, + 0xc31bcee671043164, 0xf771215b0ad446ad, 0x1fc1078db0cb7fe1, 0x5e1e5431ef02de38, + 0x7b8cf33274bb42d8, 0x528e850451492ff0, 0xc128a5221dc49829, 0xf6cd5baeb93cc8ac, + 0xdac5bcaa0597a5d9, 0x3c569072c708bca1, 0x4c13c4e69d08e0fb, 0xb123cbb52dbb5188, + 0x7631e917bad7ab7e, 0x6256e54f060aa039, 0xba81baf06ca42a4e, 0x72a0210cd661dd19, + 0x46039cfc6dc4f3a6, 0x7c426366ec1757e8, 0x57b41e2fdf60921c, 0x38d48028b54aa707, + 0xcd9f0dfc8b25c5ec, 0x9bc25c6e29e24a51, 0x3698f35b9332be85, 0xb490da53e89feafb, + 0x2b27a7fd9418aa2d, 0x8c62bd6f0d796721, 0x967ca3257ccfac36, 0x32f8fe66de3e55bf, + 0x1a26dcc5d403afe9, 0xfd52ab81ed6f7465, 0xc75a25a36e48113e, 0x027bb33cec1728b4, + 0x4d7df30f98e42623, 0xa792a4c2eb5e3ec6, 0x89a90212ed111e77, 0x86bfb86e3fa4473a, + 0x30f7ca7a695c430a, 0x8f1a47cf19a6ace0, 0x3d54172fcf52386c, 0x05b18281ee8d51c7, + 0x6b58e01432a2052b, 0xe83fbc359c6829f1, 0x82908594cd40fa05, 0x592d56989165a9e6, + 0x2065db5008ec360e, 0xc1259a1acabcab83, 0x3da4135656c9fd3f, 0x99d67d5003717b6f, + 0x0d246c3b2bf73968, 0x19b418cb701a7428, 0x71c07f7fd3f02724, 0xfde141bcc4117143, + 0xc7ff52916048096e, 0xe6dd6f3e83b03d45, 0xf615d14fe9d236e7, 0xda97ec7be57ebe9a, + 0x558007425a37a097, 0xd7007a0dc16a9c21, 0x88f1eecf2fe8a303, 0x2a41e3159523eda3, + 0xf6bbbfcbe32da0a7, 0xad9f8998d9b0b659, 0xba0dcde66a3fa571, 0x084d1fc4236ba76c, + 0x1e7b0ab173823e0b, 0x27ff05523d74ea43, 0xc2a9da8be6390ef4, 0x881f2154179089f3, + 0xa46b0387598e0173, 0xc6ed5daff74323ba, 0x6340bba4ffecfd2d, 0x802702495095c677, + 0x404c15f9992679e7, 0xbd090123145673ea, 0x0601a806ba4596c3, 0xd0fd3b76a940737d, + 0xf357cca9525daa33, 0x51fd8aee99dcfea1, 0xdf391f8ce0828c67, 0xd90937a8cbcb2e18, + 0x28911afc17aa443d, 0xfc27c92441385ec3, 0x11929641cf493c00, 0xa8807b842e2e7afe, + 0xf24ded425eb56586, 0x1e581f0729804ebc, 0xf841bdff4f815816, 0xccb34b71af841516, + 0x3bdff0d3d2e42637, 0xb77918f006c04d8a, 0xba134e57e3c95927, 0x01cd483888b78ee9, + 0xa8b3a2c5d82f7116, 0xd39ca587ccb58ac5, 0x9c3c662156b4af80, 0xdd98da47c0abb777, + 0xa6f9c510be7176e2, 0x96aa88205667fe12, 0x62bf037b395d6cac, 0x0788888bd5e45b66, + 0x520dff35e0c87278, 0x4bb162251835b4ef, 0x31b1e8cf070aa857, 0xb88dd111e01ea6ca, + 0x1da9d43da36514ac, 0x3070129125e823bf, 0x10db89b25fb49b14, 0x541de82488beefdd, + 0x2374b2f8c136b8dd, 0xdb967534c109c5ca, 0x6ab9ac670f5d95b4, 0x8f671c38cb69560e, + 0xe3b9356e27cae84b, 0x71a26536a94c2178, 0xb981d98bdad90b42, 0xa7737a2bf3b895e1, + 0x7956135fdfe3bb39, 0xbfc4aea536701f00, 0xbfa77621164c27e4, 0xd090e133dcc9f8df, + 0x9cf4b30fe5c77d96, 0x5569faa83b6d7076, 0x365e3af98a952adb, 0xb07d3e52b300ddca, + 0x9620b0d00743ad2a, 0xe74acf8427f122db, 0xb819d02a30fe4a8c, 0x818e8a24f3a1c3c6, + 0x9126518fb26aa458, 0x327c8681c781b247, 0xa5e480050330cc13, 0x3a3f3a00cbcf5ef9, + 0x2b37fb383719ec98, 0xd4ddbc3eb910c43c, 0x71971a79119017cc, 0xfdff1d970413dd04, + 0x339c394269d04642, 0x7f7ab88f0330589a, 0xecad5ca203228a41, 0x8fcae7fd1bea1fbf, + 0x1cf9892a71413d08, 0x89fe2466439f690e, 0xfb8f76bf7f667576, 0xecd74be2ea1f9f6e, + 0x4f1b01a5c3d1056c, 0xf7053907fcc7c4ae, 0x2317293ca18d6da3, 0xccfb652dbc010409, + 0xab0a9a0828c909a2, 0xae9205fefaa950df, 0xd44c1726c3be4ed9, 0x9347813eb6dd28b2, + 0xf0bf0d403449ec2a, 0x7ff2a7fb59e2e1f9, 0xd38fc88e57119cef, 0xc44d7aa91607e906, + 0xca5d7d5b1bd8c0db, 0xb3bb5e61058b6bf7, 0xe969053e20a4f165, 0xc7cef08dda54cbe0, + 0x01f74bf955282c05, 0x95a1135d3f9b6569, 0x4bf5bf0e85cf29cf, 0x7bfa44c5277da909, + 0x7c211995704dd9c0, 0xf671f43049a302f2, 0x0bd5e5c0f14887d0, 0x60c6c1afbf0f0a4e, + 0x6c96f9e252be9e47, 0xa30700f418162677, 0xc9ba6d3b5f661a71, 0x4f21f3066c20c7f9, + 0xd78a03ae9f56d6bd, 0xd41a0d42df6def57, 0x673612fc7ed41543, 0xa5de6c73ca1e839f, + 0x52171e1656560c80, 0x48cddaad2a6f50b8, 0xe6432d42663586b5, 0x7542d8747f11bace, + 0x13878728158d0f2b, 0x7c33ff11c336c8f5, 0x224c42d7ed586107, 0x2f69585137acb76e, + 0x2c3b780b7b49541f, 0xe8c8403f99f1088c, 0x9619786690bdb39b, 0x71e6f780d500942e, + 0xba293f02b7ec7c31, 0x9e775a56163d60ba, 0x889964209259bb1a, 0x5f09ca6197469bf4, + 0x3c0d6198a8d17284, 0xf4b04e61f5f3d83b, 0x660e196e4102dded, 0xad30c74fefd8daec, + 0xa287ca1b53bcd6b3, 0xeb31468467d14f15, 0x1803e0fcfa3759c4, 0x463ed7002995f12b, + 0xeb8d23602d77346e, 0x3c2c740d653afce4, 0x3f84b5b3a47f571e, 0x70a9c8a3e9261dbd, + 0x126271164e64ae28, 0x262886639733289f, 0xc4bb2cd30bd80910, 0xf69ce6565c59e0c1, + 0xd9e6f58aaa8adb62, 0x0ea602be6a2f32f3, 0x7d59cad10a01803e, 0xa157204ca0fd03a8, + 0xaa09f8e8ebe31823, 0xfe569b92ef3ff553, 0x34d437459ce3f123, 0x8229313fb5ff507a, + 0xdbea553ff188298c, 0x7b4d71f99ec8cdf9, 0xa5fc8d9541cee13c, 0x3260fccfe26138f6, + 0xe9cdda0088736ba8, 0xf68d3ed50fa2abab, 0x8120fc7835bc1ad8, 0x07c6e4b9e3efae6b, + 0x8090386af4ab9023, 0x059652bdf4fa9b20, 0x0057e127e3e39eab, 0xd146cffdb9d0e4ac, + 0x7e1b457ec70050f3, 0x34b4e4c8db1ed921, 0x1c37217679829216, 0x8bd2ea275de42cfe, + 0x4f2445358745bfbf, 0xb7fdb22b43d9ed26, 0xcb350fe29f9e7b27, 0xf1dcab7cf1709d57, + 0x47f7b2df9a71cb44, 0xbc973febbff968d3, 0xc67591cf7333eacf, 0x85ece1c4a0e14093, + 0xcc714ab3b6f47531, 0x1bb99cd8a348a85e, 0x247e8301aae6bc8a, 0x9beb36005325bee4, + 0x64d4de5098e14469, 0x351c70426ad04682, 0x210c7a9239815db2, 0x12c000ee7c1725db, + 0xd6189b38a58901f1, 0xa01f8ded5ce6cafe, 0xd64a48963d8b3d4b, 0xb1f751b97be0fe7c, + 0x3d1c7bd96cc79c55, 0x1b5e89e7e32f515d, 0xc54d13d1c351aaff, 0xc32751e95a283af3, + 0x83312af72f9ea759, 0x04b9352e6368117d, 0xb501ccfc2286f90e, 0x35537873b9c2c8ad, + 0x96a73ba3404597d4, 0xd7211d2c8ee19a7b, 0xa115bfa2bb85bdea, 0xb334683bd1a209cd, + 0x111cd3f00fd5acb2, 0x9648cc7a00879c9c, 0x61a3946cd61d2596, 0x3ccc4a4c90eefc85, + 0xc0ebf7602c9807c3, 0xf1db93f9eee10304, 0x2201acebcd536d03, 0x8ff4f3860e1f172c, + 0x1c79f304102349d3, 0x72aa7fb1077e80ee, 0xa0f565e9bc004ad0, 0x96ba74f0773fd5b9, + 0x7ce7fb42c193cb6e, 0xd3ed2362a55b47c6, 0xe2b6606622ae7aca, 0xef6c4d0817dbd7c1, + 0x4be8271e9e449610, 0xae8916f72ce0c551, 0x8beba29b9503edc5, 0xb4ba98a0a9dbc28d, + 0xa25548bdabed562f, 0xc41c2c36d371aed1, 0x4a69e935df646cd6, 0x72512589e78ee5f2, + 0x04a833ce058796ea, 0x04903de9da66c0f5, 0x75d6d83ae8dcd8a3, 0x774631271aff1402, + 0x5d63fb92710323ea, 0xd47245ee28cb1a7e, 0x8bda24eb944f24a0, 0x1217246b7d566412, + 0xe11d8f7c21a84e84, 0xeda8eb5facd06b93, 0xbefa5f580828fcc8, 0xb8e2242c1c58f8f8, + 0xa09d89f069219db3, 0xbf829e263f62c37a, 0x0b99207c6d836e97, 0x3fd8661fc50a3f30, + 0xf404e13fa33c8dda, 0xc2ea108dfec0854d, 0x55760e813c3573ea, 0xf17c94ebad517d29, + 0xaf07337dac11f006, 0xddb9e92d2e8fa483, 0x5fb9dabcacb0d849, 0x8a200380f82c0629, + 0x9fb826f075c11f74, 0x0590d52bea541ffc, 0xb9e3742c51dfd804, 0x9814c6cd967c82e4, + 0x14eaa0cf6ecb1240, 0xa6e2d477fa834ebe, 0x6a3e5aa64f39eca3, 0x0b2a5e0080311d4d, + 0xc2ef7569f975bd24, 0xdae2a608eb817861, 0xb78cf43bad00baef, 0x75f0f5b5e494b67f, + 0x9ac7fa57821a872b, 0xb10f561c071a8b21, 0x43a0ebf2c32f50a3, 0x8d78fafac056ac8e, + 0xb1174a2630d06a98, 0xb26143fa1c8f3ba6, 0x4da0090e9f86d136, 0x55ee567016823d48, + 0xee69fab4f1d2b8f5, 0xa4dbf19aecc373a4, 0x68b3b42e51e967c1, 0x5480d1af12462163, + 0x2ca2ce808aa84a03, 0x0aebbcec43419402, 0x48a850139ab0d603, 0xd2951ecd03b50489, + 0x0672735ac41d421b, 0xabfa2407540437e9, 0x5370686da6e4040d, 0xc3d0b6c8aae9eca6, + 0xf99578fbf67c20a7, 0x1dd2bece9621c649, 0x40a02641d579ac42, 0xae3bd888fc37c8f2, + 0x040493804f45e6a4, 0x24aa374a9e59d9e9, 0x36047abbb144472d, 0x0e255712cceec542, + 0x6ff01230483fef3f, 0x2cff5040a6aa2817, 0xc5368ee7f062baac, 0x68238b4bd643292f, + 0x161fd0339b626b52, 0x36654cdc77fcace3, 0xde55500445eb7d4a, 0xdc34aa47d4b83b2e, + 0xbf58a9e3025dced1, 0x6e324e501436bae3, 0x83a646297eee6d9a, 0xd9ff7f06572c8984, + 0x6032fa2d0044880b, 0x33302f5166bae5cf, 0x707b6340d8d107a4, 0x9e343e319bb58fa8, + 0x4fe8af87987b2fef, 0x56c20cd316e21a80, 0x889819f09a4cbdca, 0x6ab218c485c81c36, + 0x7b0d9905dd239fe9, 0xfeb245572b6a83d9, 0x73293b451411a655, 0x8b9d45ce35e7a7c8, + 0xcf73294aec97abc8, 0x9f2505504d9f41f5, 0x278063c15cffb38d, 0x53844a31ba22cb68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x834dbff6678337ee, 0xc607e811fef0785a, 0xaaefc62be30a298b, 0xeb5ca335326afad3, + 0x9774fe1384af54a8, 0xca4b6ef5785388b4, 0x1346c82d66f6c642, 0xedcc0c2aaa2d53ce, + 0xb9dd9b739a6a8ba2, 0xbc51e19177104dc9, 0x1a83634213237211, 0x5ff69f51cdcabeea, + 0x6dfbe5b4c0172223, 0x187a6a8b284fc824, 0x33d6aba3aebf41c8, 0xe026b4eb8795d856, + 0x5d020728bd7d86fc, 0xd15ba07e713c1ac8, 0x7b8a85468316aa0b, 0xde53bf4a0921c5d3, + 0x3bacf926314274b1, 0xaa6473f0e489a20e, 0x1a35b2266183f440, 0x27e38367373832ab, + 0xf4b475a052f7f6ac, 0x1319fb286978fff3, 0xefaffd23eb76cb67, 0x4c3514b07e7fc4b2, + 0x6b88c08b50794140, 0xa666ada647622f9a, 0x8dc0fc40a2e7fb96, 0xb557a9504af4ad12, + 0x423066e6cb7c5af7, 0x6d4aa104ef0ddde1, 0xb50e24f20c0fa712, 0x14bd6aaeeec4e1f2, + 0x4c835329efff35e1, 0xbcf4baea96e851fa, 0x9a0f11623885b71d, 0x166707a74e19411f, + 0x932ba9289cd28601, 0x50fb36f017896b35, 0x68237e2f3dfb90e6, 0xba2ea6bc3cd9a39c, + 0xd1ad36cd23fe8f01, 0xac8b2ab8cf0cc4ce, 0xb043ffc82b2b5b63, 0xbd9162720ec3755c, + 0x9b708568bb21cb79, 0x31493b87821d5c5b, 0x22f8418ddc2dd569, 0x992028fedd061736, + 0xd942c46b5191d9ff, 0x2bf067df5511345d, 0x277e70715aa2e38c, 0xc4d3dd2c649895cf, + 0x060a7f6eac0d6b6d, 0xfe7d6270c845cf26, 0x964658cf2ad87cba, 0x467f1493cf5f3ee0, + 0xcd45853b3b56e262, 0x83ec7aa03fb6e673, 0x0efe037b89445388, 0xa1a175362967cf21, + 0xed0b054915382916, 0xed71547e28b9726b, 0xdd8d0423d588f46f, 0xb49596f9186bb489, + 0x7b0bb2912e6e0ad0, 0xb6e3a6b5aaebca7c, 0x5d47bc7c5ec4ccc5, 0x615b74d006bcee76, + 0x37e279b70bdd3234, 0x912cee2fd0d0a4c0, 0xd4360b55635f0474, 0x2e7c64035873a344, + 0x4f33e31a6d46b307, 0x9ad457a3f9f8bfbb, 0x4ae7ce9df7a244de, 0x3c3d8e0eeaca457e, + 0x31e2d107846c72cf, 0x5196826a7c06eb69, 0xcaa792d5214b5b92, 0xe58bd074bb238a83, + 0x3280c94e3325797e, 0x3bb4edce17974073, 0x2e0b3f5245cc5177, 0x23267f698e609923, + 0x6d654eda0fc9a12e, 0x340ac26f7b46d1a5, 0x45deed0e6a65c721, 0xd2d96ca1f382660a, + 0x33384f4b1f2d1ac2, 0xc58b41a266ded10c, 0x1a6eb060519479e3, 0x9c4595ad1a60e9f5, + 0x221b517530317642, 0xacf0afcd376d30c3, 0x08fb0bfc4b86f3e5, 0x747add2f86cd7c23, + 0x7cbbad6fe3e36cf6, 0xcbb66fd9a266e57c, 0x8dc9dc9d0d111b28, 0x031c17cb5d40a944, + 0xa8dfd662ce5bba5b, 0x1c6fc1a282e49bcf, 0x8d3d05c2fc8bdea3, 0x51e25c00b61b8154, + 0xf1625614357f93f9, 0xe1fcbb86270d89a4, 0xaa0204a7d66a66c4, 0x84cc776bfcc8d5a7, + 0xef2b546422529f8f, 0xcb6cf3fe2a406bb9, 0x6566ffbb8d4ee8a2, 0xfd6508248a7f8a5f, + 0xc06fe2d06b12a423, 0x197f3b8ad3dc4452, 0x9c61281388d05818, 0x261ff495f9228b2d, + 0x69d3e0a876abb7a8, 0x132c1433636d1c4e, 0x6539d5f259b4df32, 0x4ce0b6759b214c13, + 0xe330bc9b4ef66167, 0xfcbd3f24a2df334f, 0x048285d14074ce86, 0x1390ab9c7bd9e91b, + 0x0cb9235b41fa84e9, 0xca99e159ae43e247, 0x48c713975061cd6e, 0x71278a093b84c968, + 0x9ccadb3cfaaa12ff, 0x63cdd416fa1af8ab, 0xdbc255d0e5ab5a5d, 0xed3136643f942f1e, + 0x9de8cb41dae09c7c, 0xd2ae9b77f9ab32e2, 0x48d5b61d5802b496, 0x893caa4ec91104bd, + 0x6e9f0d9322bce488, 0xc39a00dc21338bc9, 0xae348034d9903b7a, 0xa5ad87f9646e68d2, + 0x4e7f38d77fe247d2, 0xcb16934588ac9393, 0x1752e6f5c995b0a8, 0xc2bcd27f864eef35, + 0xc549ed814286e7b2, 0x3aef8b12e5ee7ef8, 0xfe1e048b7bcf26af, 0xb95ade8441ab150d, + 0x8509f758fd95f8a0, 0xf10800ad91e63003, 0x4c1329aaa056fc71, 0x3523b1ce29d78dce, + 0x24ed81165923ccf5, 0x59e6b7cebd213931, 0x914ad94282bf8af7, 0x342a752978122c61, + 0x06712352c34318d7, 0x9585bbd9a27819b1, 0x290a347f8d7fa655, 0xaf0aebc1dc20798a, + 0x11d7e55a47627250, 0x5816f7d327b5cea0, 0x4719b3b7d732d136, 0xa0b4bfbda2519db6, + 0x5532d6daa3b75698, 0x8321cc4a81ef90be, 0xf38a78e14ffb463c, 0x1f609818617df89e, + 0x9abfd2de6770b121, 0x7c177385315f17cb, 0xe85df23c7b81d190, 0xf3adb4857b454fc2, + 0xa5444030faede6d3, 0xf0422412d517829e, 0xeb14c0d39ee9045a, 0x0c301ab47fdb44a2, + 0xaca2ee4e6786f072, 0x1d87032d2f334582, 0x345fe5516c32f166, 0x74ee80ae0ebd7960, + 0x4b73b3bc02a6e29f, 0x70b8274f9418ffb8, 0xf01022c3b4042db1, 0x19455881d2b42ac9, + 0xd5edbdb61d20cf9d, 0xa6415bd817d4a3ca, 0x3c62a62b1fa4d1ea, 0x651457f278665943, + 0xc9498001208b83d3, 0x6199028c8200f975, 0x711e5a0ed13ff0c5, 0x1f0285a9d183cc30, + 0xf29675cd0a36ecd7, 0xb7cb5bdbbf4d666f, 0xd7875f55618fd235, 0xecda9ef68c587561, + 0xfe25a100fb188178, 0xa82c75c8c949e3f7, 0x60725c0ea385f9be, 0x4403ee407e4bdb22, + 0x0a3ea67d44343dd9, 0xe556e011299e0ccc, 0xba5798f6e65b0435, 0x73824b5c2b50ad4c, + 0xa09b100821fa66cd, 0xf1eec9f3886384ab, 0xfa208374dd80459c, 0x8e24516c85106c37, + 0x572cd306a60cefd9, 0x096f95aaa9517214, 0xf17697ec1a00392e, 0x17139c3bf7fbb785, + 0x3e680d3d6bed4611, 0x8d757b5a6f01c1fa, 0x11e98a2ed9a755d6, 0x0f0f0b22cd26393a, + 0xac8db9c6f2967ede, 0xc8b6519b6cfaa5eb, 0x47d39eb78777ec37, 0xdec11d458058d973, + 0x6145626a9c4bb00b, 0xef80302ab5dd292d, 0xf8d0111620fe7faf, 0x9432a0d5efeb4ed0, + 0x2fe0a22db22026d3, 0x8ac10fd791ae09ea, 0xf18e48939d42342c, 0x72af9bd2482dd5c9, + 0xe1b2d3d63310861e, 0xc3c6d8d1198c676a, 0xd4ed618ebd765fbe, 0xec1227c11b8ac80b, + 0xb2b5ab35a85945ad, 0x844a44e35868c22c, 0xd89319cb421f4c8c, 0x5daf65e96a41e286, + 0x369e1b4a84bd8b30, 0xc2d183e647dae27d, 0xab9e0dc9d338469b, 0x7316b2e32cac88ee, + 0xd806bcb9524b211d, 0xcddd2192951440d8, 0x77686fafd0d7e10b, 0x791a76820f073947, + 0x7adf1f6eec0b49b7, 0xbfff9310ad564ce3, 0xc5d423f9cec8d505, 0x90987a8e587fffb1, + 0xe8544f0024ad27ef, 0xfb62130b397e7efd, 0x588431f2b1f447a9, 0xead0c17a8556da90, + 0x4745b8f2c7c02ad0, 0x26e60d2ddcdab226, 0x2e68c2ac9a0206ae, 0xffc6e1b678a3045c, + 0xe83fdc122eed9851, 0x27f6147ede88de2f, 0x5c2d53ff1bace11d, 0x1b1a9e6c638453a8, + 0xf72aed1ec0a6af19, 0x230157bf2561a47f, 0xde0424bdb6794fcd, 0x48729471c95f1dcd, + 0xf6a0598b4772caf2, 0x323de456af48b324, 0x92d0a06ddc83cce6, 0x455bb49d0ace2960, + 0xfd6d2430faaafa84, 0x1faf50dd97bfaae1, 0x41559a930f226689, 0xf7853dc5ee820c62, + 0x1827900add846d09, 0x02c6c4831af2abd5, 0x118de37cf6e8d132, 0xf6333484d47de9ca, + 0x4d0a62e7ca2f7f61, 0x85edb0a80d575ece, 0x4b489639624ea886, 0x67b585f1c85a901b, + 0x546d2f88d27b7748, 0xcd424665d509aecc, 0xcab6296ef0cdf1e5, 0x7af0dee910218c3e, + 0x1047a308cc6e03d4, 0x4cd57159c1187ba5, 0x122e80e0f2d577dd, 0x71931ebe058bb764, + 0xac86c688a0df2953, 0x6fe9552c242487ce, 0x0015f05835e26e47, 0xf09f5e9497fc613c, + 0x4b6d9a1187e2a40a, 0x2e56c3543c0de8c1, 0x2e7c09583d44fe58, 0x7ee4a21fa64e639a, + 0x072b357bb1329e36, 0x4b29424b427b85a1, 0x505c2c29f4f1b25a, 0x037837f7d1fa8a61, + 0x4691aa02e724d914, 0xf9612578c5fd5985, 0xe71ac574140e74e8, 0xa387ffa91cf64056, + 0xbb54b110e1493c0e, 0x309232ba427c76c8, 0xe24e570c52a97048, 0xf9e2dff7a6ce5794, + 0x74e5b00b8ca30500, 0xa3c2a5f3a031f239, 0x29f530ab8ecbf939, 0xaf40c098cf39e1aa, + 0xfa62ef0a667201ff, 0xb8aa4fad52d0c41d, 0x4fec2215b16214d6, 0x8a159680b7bbc775, + 0x2570b9daaab74ed8, 0xb2d3427f63c5b3dd, 0x5c20043de0a267da, 0x8d172f5b8c2e54ca, + 0x98e7ce45f5971c47, 0x6f0f2425a354f34b, 0x5ccaf33d8c52e73d, 0xe652926cbf5c3151, + 0xff86e5d00b0bd563, 0xa6f53b99bf8dd888, 0x9b86f5dc3a43e6e4, 0xdd966504239f52b0, + 0xd28cf01b0a2049e2, 0x63b06dbc16a0549c, 0xae3ef317e84e64bc, 0x7bb18aae5a9aaaae, + 0xa256f03bba656034, 0x6f3d836b97e338be, 0x686572916d31cfb9, 0x8af4c2df94db844c, + 0x0f0c1421b1d4b71f, 0xbe2c583dc659000e, 0xf073f0aab986e8eb, 0x00053a1bd6cfc0e8, + 0x582b88988d3b68c8, 0xe68960a141e4dc7a, 0xef0543d68502c491, 0x17a335260135fae0, + 0x7e36dc66bc16dfbf, 0x5499030fd1d3b0d8, 0x5fdc37548e0699d5, 0xf6da855de190effa, + 0x3fd075f61c440456, 0xc96590d9765e3906, 0xc4f219279d340900, 0xb6d7fe8e91abcfae, + 0x8c3de25864b469e8, 0xac84d786a8695195, 0x8503722387943bae, 0x256a74abf7e359b7, + 0xbbfd5dac02ef24cd, 0xc7c5bbe1c6822740, 0x0ffc6c69548aa8a4, 0x5dbfa0fcd7701ae7, + 0x00eb1a55fe2ddc6d, 0xb26d5ae633b92854, 0x28c933684ecad3a2, 0x31da221c04bc72ec, + 0x9ce94ee5ac3475b6, 0x46d0b101875805ea, 0xadf76505b132f324, 0x976c7574b87b87a7, + 0xe68e60bc1c25f907, 0x497c79d5b9438fa7, 0xc0acf4e2598ff65a, 0x5607c17d0bae1b19, + 0x5d12071c66120577, 0x772f87b78cc1c13f, 0x38217f631a9b1b76, 0x741772bf483cd064, + 0xbb6474471dc2d18d, 0x45579fcbf21fd86d, 0x4acd4f32b958fb49, 0xdae690181a8f3e66, + 0xf92bfbea83e0a1d6, 0x1a9adcdc0e368995, 0xe15c3be442c50e1a, 0x567510e046f8db31, + 0x101bf54e0f05183c, 0x380546174e856d8b, 0x6447ecbb57be82e8, 0x6e66ffb820a7ceef, + 0x7188af51791c6fd2, 0x9fcdf63f9ff07fa7, 0x90d87bcf2d2dec3c, 0xb16be6a7ac5c97f3, + 0xe4270ab82aa3ed95, 0xbd850eb7914f3b52, 0x7869e4362642c796, 0xf905a0b439c3977f, + 0x2831caee108c3335, 0x9c568ebe238cf0c5, 0x6d52ac420d69692c, 0xd0ed9966e5063900, + 0x5335c62747b59f47, 0xa18840615f2e1ebc, 0x82b544aac2e82cce, 0x4bdc24c9a5ac853c, + 0xdaa8512081f5d393, 0x296d27e57cc8d0f0, 0xec6f6e11f18be957, 0x1156dfcfdc26f0d5, + 0x949c759ba60bdeb9, 0x301578b4a3f22614, 0x653049722adf5796, 0x8eef8ccc23e6c1b9, + 0x64884fe5ed416e28, 0x41c7326cee44328c, 0xfd820dfc3de01d87, 0xcd15e6e37f55e84a, + 0x3776fc058ff85076, 0xe75b7374681b96c8, 0x67a267873320bb1d, 0xc217b6c69827a6df, + 0x9af2d19cefe29835, 0x4676d16685f1ab32, 0x04d850c49aaee825, 0x8e81b03e42b43487, + 0x21b81bba4881966b, 0x7a803bb31f6c245a, 0x7922420254cc66c3, 0x58ceab50b983ca9f, + 0x1f4fa588e5e53230, 0x0d360325f2b26d72, 0x5a503e16822bafd5, 0x7eb1bb9c18b9f2aa, + 0x0106b60873136d60, 0x76515e04340ee9a4, 0x314a28759b0a911e, 0x1f5b35a1ae4a7f81, + 0x5098dee8c62e27be, 0xc652ae78c3a86eb2, 0xe177af724f517cfc, 0x6da41fd8249423b3, + 0x99f54220dfa36f60, 0x04d3abe5502ed501, 0x055942122f3ff774, 0x0aca15737996a982, + 0x8cdf36e00fb40e84, 0x18e7dbf8829fab49, 0x86cd07b8bad6f876, 0xcc461a88c853fa90, + 0xb2181c38d4b1444d, 0xf27e3e4f88e2c17b, 0x8976b16d247f894d, 0x495417c82c5b5f92, + 0x6168f795746f53ff, 0xab72fcc1829c7431, 0x491c498e83b05d6b, 0xe0566db638d17e28, + 0xf7b7138ecd53e772, 0xce6b2ed9885ff54b, 0x7cb6aad48764ac15, 0x25bb2a692caec4d5, + 0xc1f8a7d86949753d, 0xaced07b867a041ca, 0x4a96286e44c06fca, 0xbb9e643adc5c4148, + 0x82d152060a560804, 0x2b2c83048a2e6c26, 0x4d1503163f7ae25f, 0xec1dcd5e532fc6c3, + 0x2d3ef0e95522871e, 0xb7316f9cb9990570, 0x850d0aedee195dfb, 0x34b1508a402f18d8, + 0xc1f07e202b3c5d95, 0x7e4a56c2ac2a9f14, 0x9bacf077f1422a8d, 0x3aa44fa2e92ae1db, + 0xb1f3701f42d58b6f, 0x9834b6245d36109b, 0x4e73a3eae0a60e12, 0x85cc652e677fd390, + 0xec73079a8347f096, 0xedef0ae1d6c7d829, 0xa3287756760fbf0f, 0xf1224bf6863f556c, + 0x3b51028c6725acfa, 0x351f8a45c88ece8c, 0xa51d86bc6a5e7c7f, 0x2c3c12ffdcc59b15, + 0xe795775769620f48, 0x1704855fb1483f5c, 0x3057d55201bd0a8f, 0x050762232efda61c, + 0x513e7705af5347bc, 0x6fbbdf25614c15ec, 0xd96c6f36ed55400b, 0x6242744f1f95fcc9, + 0x069189ccd8fc1915, 0x15f1cd37ad455d34, 0x98316057fb7653e5, 0x3c26c159e8630d1c, + 0x1bd1dc966a031341, 0x674ee0ea249a94f5, 0x8d22c449fbd78c25, 0x092d89c822cd79f3, + 0x3f637847d7fde301, 0x4567904474b901a8, 0x9d5c10ae67d3379e, 0x896d59db3843a8a9, + 0x8176b2efc6c04118, 0xa55482a741cdf640, 0x89dc5670a2dba5aa, 0x648c3cf4848bf82f, + 0x0466b4398ade15d1, 0x0697924120c74be9, 0xc100086d25a6cc08, 0x448d559904509c90, + 0x142ecfca095a7629, 0x61f1644225154f04, 0x115cf3b7befa7131, 0x37ad7dcca404c5ec, + 0x5cd8439d4aee100e, 0x4a96258495cf42cc, 0x69e2a04cd993ee93, 0x375e23d74ff5b885, + 0x5377e13299113806, 0xc578e11da2b9e7ac, 0x50deaa94950e035b, 0xfee5852e44cddca1, + 0xa41939a880da2a1c, 0xded44ebf39c030f9, 0xda1391a366ff953b, 0xef36b33e02be3811, + 0x1befa81aa41dc12b, 0x95597bf4f67d44cb, 0x7949a4c180749247, 0x3389e0a207502389, + 0x53ec2aac3a724d3c, 0xa53803de17dd2a04, 0x805452524d3001e4, 0x2ff04ed1aa7c45ba, + 0x6dc2e3396061bf4d, 0x89305cf6a85b4c06, 0xebe02688e4ba769b, 0x0b1f19a0e3231b27, + 0xe188402466c68416, 0x127b27d8d97fd131, 0xd215526b20e083ff, 0x4b15fa79982c13b6, + 0x1e2fff2a692cc961, 0xde4e80fe6a827bdd, 0xa0338f7526c97e60, 0x3ffa9d9d5ec555a7, + 0xfebf228c37db2238, 0x687007a8e014237c, 0x7ca5ebe3781dd59a, 0x05b46050d20eeafb, + 0xea8041262852de2b, 0x6eb1607f8539536e, 0xfcc10541992d7bf7, 0x58de42fabfa2c704, + 0xb3cf070910bc7f70, 0x26643556268c3625, 0x1c2713fb9f65be2d, 0x34d7a23cfbe6544b, + 0x3a10c168248255ad, 0xa69d669683a9c14b, 0x460e2af63ae35487, 0xa1b1b0c748504510, + 0x6dd55ab97ac8b270, 0x85d62f5ad1767fd1, 0x274cb6e8a11e6deb, 0xb00364df3099914c, + 0x0f424f5bfecc56db, 0xd82b78fd00f82839, 0xfb2b8ae8167af182, 0x9c441334602b7072, + 0x9eeda2338c7c434a, 0x443beaa029272823, 0x87edeef0ad331149, 0x626e8486b4de5387, + 0x19de0ed5abc37ccd, 0xd9b30adca0118572, 0x9c61dba0f3e40777, 0xa4671fc8caf89109, + 0x4e9e18c8c635a150, 0x2e2d0c7205d5ba0f, 0x8ade9dc025b3fc6b, 0x58f4000f9fbb137a, + 0xab2663bf5c970b19, 0x1c7394e4daa75d1b, 0x154043d9d838c332, 0x353de120ab55b189, + 0x2217c2e0b910676b, 0x3bc824e8341506b7, 0x65348f93a5cc2d82, 0x4b4588813419c367, + 0xe4cbf3a775ec4429, 0xebbdfba4201dd16b, 0xa2e902b0d55a3457, 0x469ebf4b43c255be, + 0x984a36ff70407510, 0xc48845a11ef232a4, 0x6a31ae01406d1cd0, 0x3a0d1019adae9c57, + 0x6b236779eb024380, 0x539d15f2f04df89b, 0x1539bdb3df4cd73a, 0xef9ae1c07447ba06, + 0x3b20c2720d628cd6, 0x00090f31c568b31a, 0x312daaa42a0cdd28, 0x00d5660897ff7b38, + 0x46d450dd16f8222a, 0x03fdb8b1bdc80ff7, 0xbd25a752604b8f31, 0x2d3d23fc78d17578, + 0x249ac8b3b073f884, 0xab776510d4b155c3, 0x0f901a278de859e4, 0x6a8e5c8a5eec0c28, + 0x1a0030d53615ee6c, 0x94e3a655965b8fcb, 0x8c96b15c23a73726, 0x4c5cee55bc2b5b1a, + 0x72158c3b2485e6ee, 0x8868a38b7a94af03, 0x685250359c5cac78, 0x3def9a660c34ccf4, + 0x9fbaf6c9f9408408, 0xb2fcc6b9e5c986b6, 0x5686a961561a9344, 0x01191bd3c49b0202, + 0xb9b2895eb9a191da, 0xfa168213ee3d2207, 0x64fc9c8db8ac88a0, 0xf44b36eb17f01852, + 0xc0cef49547493078, 0x2c8f655a7768c43e, 0xbad3e2a7ba401bc4, 0x8bf489d2110cffec, + 0xec4e5d151606cd49, 0xb6821342a54336b1, 0x19683bb2a6c9a9dc, 0x3b486440a3ea5d5b, + 0x4c255204773a455d, 0x2cda95dff3268edd, 0x9ace7fa71c9486b5, 0x975521dec41922dd, + 0xcc3255ec6161f4ac, 0x966cd574ebc7e117, 0x8c78d71c770f319f, 0x0ce5774d965baab4, + 0x1b198b0c594c5107, 0xda135791f36e3539, 0x3e5986e41675bb65, 0x6e86501df18f963e, + 0xd5984d329555150f, 0x2102a2c95b707d58, 0x90e8c851f2d1734e, 0x0b91ebd3fd842010, + 0x0956e678a70b17cc, 0x6e03dd48ad3bd55b, 0x68a81b6e0c73893d, 0xb568170e153be7e7, + 0x40a8e28ec29d592c, 0xaa5e2794baefa34c, 0xf2dfed7dd66d98a0, 0x8a57fba98085ba98, + 0xaedbec19a010b33a, 0xeeac675444a4322f, 0x952212bf47ea9dcb, 0x2be61cb715d32f11, + 0x7a4575609d071cfa, 0x54bc02a750fa7f5e, 0x0ce48a1c3d7a53ae, 0x3a50772501d6b4f8, + 0xca5aa96020d62c54, 0xf564565df9620f8e, 0x070aa789c9ffac3a, 0xf080d900db2ad43e, + 0x25daa110453abbdb, 0xb87b7dc1caec595c, 0x6a014234634d5814, 0xfe61557a0eb73496, + 0xe83169ba07db2075, 0x02846dbc06c74455, 0x9ac8229bab731248, 0x3da1bee0133b9407, + 0xc720f1dca01a14ca, 0x3b7135df80f4300b, 0x9a4bbf9946b19f02, 0x1b7183c8038b68ab, + 0x1e0c467ada0c6e3d, 0xbbb4f4308ad285f1, 0xfc3b214eb76463a2, 0xae82454aa1cabf8d, + 0x4ff8c559794cd0e8, 0x2bb1e4de7232100a, 0xe10f3086170d8446, 0xa6fe832b273f415f, + 0x59b9984c7fe7acae, 0x5e5dcb093db867c6, 0x9d60938932c6b158, 0x1147767e2329cc51, + 0x3d492aac8647680e, 0x366b49f792ab664a, 0x1460707db39b989b, 0x5d3b5b41096ac61c, + 0x1817e90cae7d7c57, 0x68160afa17a37063, 0xb5249f9034a7cb16, 0xe91c8eb5ccb11456, + 0x944839e78d8ada50, 0x00dbb0ce5bf89ce2, 0xb4048ea3f193a9be, 0x74bd065d8bc757a9, + 0xd48ca43e7ad929d5, 0xaacf25a6b204b722, 0x503b00ca70db1f71, 0x0a2ac26d009638b4, + 0x6ddd514f7b4e9c5f, 0x43c18c776514e4d3, 0xf39ce6e2dae69ee0, 0xb8aa1925bb5886dc, + 0x7ea100a92a6f9ba0, 0x246dfe32fc5efa19, 0x4c76806c03397513, 0x1ffa042587c1c23b, + 0x7341d4d0a2fa3b06, 0x1040b3e0a99df8b8, 0x1706521ba418003f, 0x2890ae49aa03e78c, + 0xf3653f53a27949da, 0xe8aa64b52adc7208, 0x8990ea519fdc7212, 0x4f80300bfeef0cfb, + 0x854b8b126cfa817f, 0xc49ba62dc43ed596, 0x5a848d418950c6ba, 0x50908d394de9e05b, + 0xd8d3a5524bf14697, 0x1b41254644063c7f, 0xaddd324cadb97afe, 0x2ec5436e101b3b8c, + 0x6d4337d3cb2e459d, 0x3acd68f204c01e5b, 0x96e6223566271b9f, 0x4f1eeac7d25a6bea, + 0xdb743f549bc1e70d, 0xb4a80efdc7def233, 0xe135be26c73cc673, 0x54df97a6280761b4, + 0xfdbced3b8f9b8363, 0xf46085d320d572fb, 0xf0a14f022e979bcb, 0x6f9f5ce7ece6b8d3, + 0x90f8cbb98cab0737, 0x8d31bf010dd8c27a, 0x838957587a699c17, 0xfe82ee34a90f81ba, + 0x1a7ffc5b3ce35282, 0x4f9067d32d68682e, 0xac6378eebed261c1, 0xb53f7c37a66c25f0, + 0xd93b47a353a9c0a2, 0xcf78016647e81b0f, 0x5c1951beeb47b6ae, 0x147853f00f5995c1, + 0xcf927312f632def3, 0x49ef4594cfc4b4f8, 0x3e1b752b4d78fa0f, 0x1882a837887df899, + 0x2ea1408527040c68, 0x8be8c480e449cf5a, 0xdbab6ff4ff3b8c3b, 0x7676d17d838f06d9, + 0xc835c62d8d53b69b, 0xbb5a82031e8019ef, 0x4aee0217a3a2e499, 0x5cbc3b8114ba0b2a, + 0x7ca22753677ca0a3, 0x7a05743f1f50c4d7, 0x0cd0593c5dca20da, 0xedfa441184139c49, + 0x05f7712b276fbac8, 0x53c94d4d91b7d7ab, 0xe768f5113cedc320, 0x40e4a1f39bf3f3fd, + 0xa11ed6b9c7830354, 0xad6e232b6e2950c1, 0x7557b94a96a9548a, 0x91ee96da76588e2c, + 0xa5f86bc269acad54, 0xeed58581d0862377, 0x2650b5e576534c3f, 0xc735f9ca03674d14, + 0x2e9b57a5f0aa1e20, 0xaba84b505d0a3730, 0x935ac4d419044d67, 0xe4bada37d4f9df2f, + 0x83137f9e5f08cfb6, 0x485c7339e24a3ea0, 0x941e7aa5ff371dae, 0x6209b70ac3275683, + 0xab6990061d039b3c, 0x60b0a3477805d9f2, 0xf39dce403c7eba94, 0xc02a7b2459869525, + 0xdf8a58ae4cf70e27, 0x443fff84b0cf982e, 0xc507fb4381acf121, 0x9295c6508b89e27d, + 0xe7427e9679ebc213, 0x3febf378ae486fe0, 0x9dcf064b55e74e24, 0x97eb8a701cc3b15f, + 0x11c564d988346bac, 0x7fc0ad9af399e017, 0x92330608fda6205c, 0x2edc32b628056b34, + 0xda07815beafc7cc7, 0xed465ca8dca50b23, 0xcf33cd8c0f78b624, 0xd4b600fb5b08f65e, + 0x3febfbe7b93181c1, 0x7929f3c915ee7a5e, 0x043d494ddd66126a, 0x49b6e73b15414ee4, + 0xa5e5ed21ac6852a3, 0xd91ac9aad73cd4a4, 0x50384c7d4e2cff5d, 0x3a53b3c7faab0565, + 0x412aa0cab833d18d, 0x5903be9720271c18, 0xf4202c1af7c23615, 0xfde760408ed44237, + 0x32b9c84b1da554d3, 0x0177f951666a8993, 0xd59b61f911e59ada, 0xe47dc1b90cb3703b, + 0x0e0490f85b875dd5, 0x9d86d6e11408255c, 0x3a7d916b049c5bfa, 0xb8b601e7bf44e7e1, + 0xfb21753aedd3a954, 0xe743d95287a5b605, 0x72badf2e32652deb, 0x3d0a0bc9adc60839, + 0xdfa7dd25351e1bd1, 0x17db4ba4617dad3b, 0x7f121ad3b18633af, 0x8bd1b3eb98e18893, + 0x6dc1f12b53b0726d, 0x25a12113d063377c, 0x778f2e9632701b2c, 0x6f6db3afb5f84244, + 0xfeaa8c2d77cac2df, 0xccc596b84cbf81be, 0x113a706c9175c4d2, 0xd73be62875063034, + 0xd644b625db2adf13, 0x0e74101715928b12, 0x4b9b45fe86e3e887, 0x326567c1b8eb4400, + 0x6378a2bf177ed627, 0x82796fbd85d466f8, 0xe3b46580cc517238, 0xe27bd5be3ca32760, + 0x00c9906048323c07, 0x00add80864fc3321, 0x5ed46047e6638844, 0x41f5aa0fa8a6de87, + 0x775419afacbef9ad, 0xe25d9addaa6a3d95, 0x929e95bcb16c0f1e, 0xf27402b28442885d, + 0xd77743b89e170d39, 0x607b5dff43c4eed2, 0x0d46fb17f1bceabd, 0xb12dd623ff00b1fc, + 0xf6b0afe670cfa994, 0xdc8f808b367ec7b2, 0xc09fa60c7749d901, 0x0b9a01916af7f190, + 0xad072226300b1aee, 0x0793cdd244feb924, 0x70c0755b697f6c2e, 0x600728576fd0c5e7, + 0x8f2da12931507368, 0xa586fa7ec78c7091, 0x7ae0c124d4ab6b6e, 0x404eb225a730a760, + 0xbd368e5ad8a7be2c, 0xba6600f77f1b5cf8, 0x1a217b8129d409e3, 0xdde2a85066af4a7d, + 0x130195c6a633217d, 0xc587f70874942ce6, 0x75739d13e4e459c1, 0x479b35bf8f835e08, + 0xe2417ce224577eb4, 0x6bedd3f8a71899ff, 0x4fca88e3de10cc40, 0x2bcfd4962dcb6fd5, + 0x3d5cf2da6e7cadf6, 0xab0c642c3a7b98c8, 0x95ae180376833e73, 0x9f9506f5c406ddff, + 0xe410d533d769b795, 0xa27e319307a5929d, 0xb49a403d767df49d, 0xe42ce93f919215f5, + 0x9ad55241f4ec4b0d, 0x3dbf372ec6ed1a03, 0x4e8efbada855a3b4, 0xcab9fbde7690002f, + 0x984f91a9d25ad3f4, 0x7c17d4e02729a547, 0x6b07f0aa543d67de, 0x6f70ab7cbe47badc, + 0x13b12f4d0511bffd, 0xc1de5336a586e4dc, 0x684e9b4a8a835e21, 0x464a2b04ed8226e2, + 0x2eef8b6ab39e32f2, 0xe65c226a5f37b9c6, 0xf46d3c6183c26673, 0xd29a7088de2f10b0, + 0xa50d32bb1355f114, 0xbea9129b0333bd65, 0xe956d7c73007f5a1, 0x544959f678d8bb27, + 0x1c404e70690ef3a8, 0x945e6d5735c0b740, 0x2c3f36f8cbfa8566, 0x2e0426a0b5d80c7a, + 0xcd2ed31ed2587d19, 0x6efacbfbdf6908e6, 0x968750066ad2658f, 0x9d4b3a5c5cd10bcf, + 0x0ecabb0759ef811f, 0x53dc033e2983287c, 0x003d3259d30b0327, 0x1a5c62726c1d6e0d, + 0x5e4313d7849869b9, 0x95fbaf1036cb9382, 0x72e47f25a6eb21e7, 0xa62d5ac89b082f60, + 0x17cffe72cc96c08f, 0x86feab9f56614b99, 0xb33c8a135b06c763, 0x6398d78df950ce9d, + 0x2e0562954ac6e5ab, 0xdd925084d65f5907, 0xd32f4e0eeb030fa7, 0xbfcd5162715654a5, + 0x08d0d6558cd40786, 0x06877bce467241de, 0xb09fce9e48bec539, 0xb52893d15e530b22, + 0x7fa0e7a78a47804c, 0xcaf594d8a1749ab7, 0x00756071f94091e5, 0xe13ae9c4c9393cfb, + 0xb8ff7e4c5c10b0c0, 0xb3d1281051f15c3c, 0xd3bd8d56fc1cc3a7, 0x7821cdb5135216cb, + 0x8d67806f2f6068ad, 0xe61929fe191bc17b, 0xed29a8c799af3450, 0x200c39ec2759f604, + 0xeab78ed42624ea80, 0xa1a2b12173b1b2be, 0x02c6d1d26de912ba, 0xcb982a8d921b8e89, + 0x3fa7806f3b3b9e05, 0x9a593734ada4813c, 0x1f44f40306d6fc30, 0x3817df3ac118db8f, + 0x84fcc3d072f4a566, 0xe6f4a01e19b53f39, 0x84e306d981d74de3, 0xab534a239c1ae202, + 0x3ce23d0d9e41442d, 0x9c088a28ce6cb62c, 0x90c187a63b5492a8, 0x452e8b2a8d85ff34, + 0x3cc54d3ecc9d1d73, 0x79a425cc18b5642e, 0x367e41eadd6ff8ff, 0xbfdcd3d790108551, + 0xe68bbcd85451b6b3, 0xbaee4537d2210c21, 0x9b493d2018d5a2d4, 0x2450fc3db9d80c5f, + 0x30b8b70dbd1f17eb, 0xdd2717995cbbb3c4, 0xc0a6d2d5e288793b, 0xd4f2669e4eef4dca, + 0x655dadbc0c53b597, 0x589c38a66d76e8b6, 0x50dfa6357d52950a, 0x0385dac5ab79f8c3, + 0x987db7d3b56b8688, 0x652d42f469a97dec, 0xd02939ff063ec2b0, 0xb0d8ac67953de4ae, + 0x44a0b43c48e9f981, 0x23511e5c2ad3388a, 0x709d372e8ecedec8, 0x283ec4d4593314df, + 0x3e894d77492fe9f8, 0xd0ff7b33a95c9c4e, 0xb8e679cd2684e7d8, 0x624d4cc29c46e770, + 0x04e71608a7c372d3, 0x71cc2e96e3234b9e, 0x97afcef914a633cf, 0x81457a3c739c894d, + 0x916c16dd94221621, 0x0a419a989362721c, 0x3ca722df05df2d15, 0xa4853cc08db037c6, + 0xe3c69adfcc18d483, 0x565420f5bc003d2e, 0x27d4e078224431d7, 0x51e5da5bba319836, + 0xee5952d6317cee08, 0xd1ab83c77b2f95c4, 0xc4bce189215a2902, 0x304cbf7642eb0c93, + 0x62ce0b72b0531d23, 0xc64b27c0be6fd67d, 0x32f7a47b0100e2ac, 0xb2ffcbb69887a35f, + 0xd0ee092438094101, 0xf87afdd802db2fc0, 0xf2d1d31a968fe123, 0x1e699fab5cd051dd, + 0x888322238612474a, 0xa67e20a6ad4cbe2d, 0x404b6ea6befa95fe, 0x63ee3c57297d9794, + 0x0d07339a8fc99c01, 0x661dbad1385cd640, 0xdb52f8e743865c50, 0x7cb5df36939864ad, + 0x1c4b581c70e03212, 0xba78d2d1d5fcc83c, 0x25c1be8c8b031426, 0x91a96a8a2e0addd7, + 0x30f7ba737e781f08, 0xae48d61ce5900a08, 0xd6017f52c4a41699, 0x679718da675bd100, + 0xfc15a4edf51cf587, 0x750471f8dce79549, 0x7d271c7b283a020c, 0xb3e923e0ff040d70, + 0xe107058e529d20fb, 0x3422fbc8d4c93808, 0xe2ce0bb9f4e72204, 0x52c6a5bae4102705, + 0x5f342f72b78b9900, 0xba6ec81fb4fdc1fe, 0xdba0a728e5f31406, 0xcd5fb8ae906754e2, + 0xdb9ef8d54d6daa80, 0x0a7061451a0c7018, 0xba2e7be8cef73c51, 0xadbb52f7d02d2afa, + 0xeadb948831ff2634, 0x9efb6255516c7273, 0x875b7028de3e6827, 0xbdd4404a1130b225, + 0x0f232bd6b73d4585, 0x0a06504e17e4a42b, 0xa2b73821b1ff1341, 0xcd0eafda8ce7b427, + 0xf073fc120ed84bef, 0x99e15c0002f5d4af, 0x15cd30d512d606a0, 0xd8de5a35e1b83f63, + 0x097fb0d560f8af2a, 0xb68847a954fc5a0c, 0xf1f7fab53790aa9a, 0x31bf1d4ac0029531, + 0xa9c4a2c0e56ecea1, 0x7544f42fdc24eb0a, 0xc7619b45f5b002d7, 0x06cb75e874d88f50, + 0xdbc94a566c79e4ea, 0x2b1c899750e6e87a, 0xec4038ef589b3cff, 0xffbef115cf6591fc, + 0xc3e4dadd296d2015, 0xc8da5b22dd5cc031, 0x4c3d50fd72711d27, 0x9ce85e22362de40b, + 0xa5d9296c7e92889b, 0x8734b5ee57172b93, 0x087da725fac5b439, 0xc4dd30a9676abda9, + 0xa883cb2e03607e5f, 0x872f8800ad4f7503, 0xa62aab2d74d00ec2, 0xaab1922cbd15fa2d, + 0x39b43a4e1596ba05, 0x5274eb52dd67c58a, 0x86a8239bd22b7d01, 0x6dd4d77df49dd5f6, + 0x55cf16da1e91b89f, 0x01607833de80b593, 0x7d190450266c77ec, 0x7a46222a9d994ce6, + 0x6395ee4613c9f79d, 0xd9be6c4f4f572fa7, 0x682aaf993ce8ace1, 0x5e101a104be63691, + 0x583622e6f93f77a7, 0x7b51d0bca39b2b03, 0xdb07337dac6d6037, 0x449c3a8c929c8684, + 0xcb36ecb5e7f727b3, 0xf6924201c7798dfb, 0x5fdc99745e4c0a18, 0x2d74ade2588caa60, + 0x1dd4c9adc0f46df5, 0xdab116dead0e9104, 0x5bb770e46e52df93, 0x5e020c30fc715f47, + 0xf193549b502a7638, 0x81ba8cee1498081c, 0x4b39938e666260d5, 0xd6437be8c6db0b86, + 0x19a5e87d9b5af1e7, 0x9c2403e9a52f77f5, 0xfb19060f59779918, 0xa1e608cf4e692f4e, + 0x2411f2bacddbfaf0, 0xf24ac5e3abcb1c1e, 0x2804bf0cfca53897, 0x18a7b3791cb41652, + 0x89af37439d4bc60e, 0x2576ae9a9b8e5282, 0x7f3379ccf01aa876, 0x86513b2bd4185610, + 0xf826f6d5fd037494, 0x275d4322f851d993, 0x9b140f6b8150721f, 0x28e0c5ef42439749, + 0xfc7f5aeec6ab106e, 0x41019fab9fea7dd3, 0xad20f7d7e5e16c28, 0x733d5e86ab3cd029, + 0xf7f2846847d153a7, 0xb2c38018d6a8a9e6, 0x277992de9c63c07d, 0x5894eb3353a19488, + 0x17612711bce8bdff, 0x749714592288992d, 0x6de6623ef90afdb7, 0xdf5d81ed1b1145a2, + 0x906ca97c98329ea4, 0x84195602c19e1d96, 0x884ec039d958b571, 0x6967d91db9a7791a, + 0x778de6768155aade, 0xd1d16a43aba579e8, 0xc4f77feffd7f5d89, 0xd09b4bfa0c3d0d2d, + 0x47e5a2aa07fed0fc, 0x665c729cada29d0d, 0xd4805c9d34e81edc, 0x2132689f0a3c2e89, + 0xa75ff57444b1ba7f, 0xfe3d1beb159457d4, 0xb2bab2016fcb2fbb, 0x62b4fd302cdaf4dd, + 0xd5073013f0b0384b, 0x7375793ec708c192, 0x98e52236c9b71714, 0x48ec18ee50f8fdf2, + 0x363bfedf438fef4f, 0xd41ea73295b143ad, 0xaa3dbc67edbdae8f, 0x33c8794f9cd4d352, + 0xfaa79ddea95a1cdd, 0x3ee8f98b2dbbe739, 0x7f6dfd48100895d0, 0x1d5fa08d420cab74, + 0xaf3a47a9377385f9, 0xad10af098a65827e, 0x7cc8f9a8b30de56f, 0x65df538488f9705a, + 0x7a324c4c39f6794e, 0x36897230f764d854, 0x7b1a81f7083a441f, 0xc9f6570ad9c366c5, + 0xc60fa4c70c589edb, 0x396e3af190dcd228, 0x0c0f0e93e4ff2ba1, 0xa9fc4563a5e9f69e, + 0xb3cc765f664a39cb, 0x55e8ce2c21a55bb3, 0x3ea4c53934a9ddeb, 0x16fa5a57cd5f0bbe, + 0x175d8804af0c86d2, 0x9cad21f57c7c27fc, 0xca3d6917e0345b60, 0x0bc13cecc94e753b, + 0x1752882a8de0d156, 0xcac3431e2f927733, 0xd760e44df10274ef, 0x62213dd8291736c5, + 0x5a724a8dfd7e1306, 0x2b204cc1b6deb535, 0x6c1af48289ad8cef, 0x65243a03a1c38dbb, + 0x4d3e18e5bac085bb, 0x8601671ab007c492, 0x460fbfc48331d0fd, 0x8b377fd61dc020a9, + 0x25d8b7ff8bf01ea8, 0xf7c1affa2d5a68e2, 0x091b333af226313b, 0x4be4a3c5395f7cde, + 0x3b3b416775b63804, 0xfd505d8c2867f79d, 0x2f38bffd96fd1540, 0xaa4d819c895e7c7b, + 0x79f90665c1475fbe, 0xd1bdf5bd270155f2, 0x8c01a2519be2a7fe, 0xb001c77e19e090b5, + 0x12366b067589f3b5, 0x7aec7a032923e703, 0x04dc44c9163ab998, 0x454ed4843edbeeb3, + 0x4973e5a27e31606c, 0x0605af22b3c1f07a, 0x63a3579d62aa3b21, 0xa587c44740640701, + 0xf67a923d543b3acf, 0xdea79ba02f19a955, 0x97f14f1e4dd36595, 0xb6f855294e02a4a4, + 0xf747fa6bcebca709, 0xcbf0c93a237a9655, 0xa5c3c3c3256360e8, 0xfc0b2727d576c2bc, + 0x2c16af0ec03987ff, 0x71387460588360d6, 0x32343aad274a175c, 0x130f74e06b5bae47, + 0xd1bc1c10338f6afa, 0x2b0f29ff48f8c7c9, 0x135acaeb9b6709ad, 0xd71106f0327d4047, + 0xa3125588679e7b67, 0xdbc415ca13a55a9c, 0x1d6cc04b023bb5d6, 0xc19c83dad308b764, + 0xa3655e25f8872774, 0x97121e6894499b79, 0x285e5d60f5b6fd2c, 0xcfff7fbcb1799ee8, + 0x3df0f25015ab3776, 0x447726f0bc89a254, 0x76aab70446686f13, 0x455eb6627069f6a9, + 0xdc176e711899564c, 0x33fa15bd2502985a, 0x1748fad6ae8bd8c6, 0x0985b152f1adc870, + 0x14272034791c5c6b, 0x27a24f4f5cf627ad, 0x7be960bf97ba3850, 0xa3deef691d10b684, + 0x4520d77812733101, 0x0cf51ccff852cc4f, 0x48e0a830770125e9, 0xf1b8d5cbd6e05065, + 0xf34c63cf466e48b5, 0x25a8863368fee33c, 0x7325ee7a101f114d, 0xedf98c24e579f993, + 0x4c44ed80aba7e9b9, 0xa1e6ca452acd47fc, 0xc06e561726bf6d77, 0xc29d2989bb24db28, + 0xe57fac3e75033e18, 0x38b5d6f4c537eb16, 0x640041934165cf9d, 0xbcf7c377603a3f9a, + 0x49eecec34dfa6f15, 0xdea935be4070e334, 0x2373fb09488f03ce, 0x78e09fc9c679833e, + 0x1e28b660b30aa3b2, 0x2fe2e259dc8a2788, 0x5e6d11eb4f416897, 0xf38388d82ee40044, + 0x3223a284900960e2, 0x2ce794bbbc66c8d2, 0x90cf60375624b940, 0x835d5c070ebcafc0, + 0x77c3cccccf7425b5, 0x239810f33dc17b73, 0x7d5f2806a42c05b4, 0x2b770978eab4eb83, + 0x337dcffa88110f7d, 0xdc0fc7989e405469, 0xf98ce8adc047af17, 0x67fd18cd6e12c86f, + 0x38f2259c56e5fb2f, 0xef26948f22c9019f, 0xd62d756f74a5507e, 0x3c8c59c87cb0cecb, + 0x3a4adc31be44a97a, 0x78f1702517c0223f, 0x499d2e5d6f95f58f, 0x4e645163dfc42bbd, + 0x8c9c21c5f5f9a4fc, 0xf87ee5e93349881a, 0xef48bced3c7bb5a8, 0x0f97c2226b7b66da, + 0x6e6f0128ff05d048, 0xc99facf1a257760d, 0x07dd7485317716ae, 0xeeac9982b61497e8, + 0x4947aa2900d7225b, 0x17fdd310d95b4599, 0xe19527ca9d50b554, 0xc1892cacc26a227e, + 0x31f6fdbc9c4af32d, 0xb2959ab6771adb98, 0xb1571166f2b82dd5, 0xc12abf82b6bbf559, + 0xfe8500135862b66d, 0x083b1c0d2e8063d5, 0xf8562b3b41ca1e2a, 0x5a6cff012816803a, + 0x0ee936df4c0c6c9d, 0x655f53a11f1824a1, 0xbb1af8ac07a9907b, 0x294e6193dc11b2aa, + 0x10c901702b05529e, 0x47621eb90a4fc548, 0x9011a522979346a1, 0x1550828ac6b861e0, + 0x1a16237d1d869111, 0xfca554b19efb0a38, 0xaae4e23d328dcec8, 0x4325701ba1efb861, + 0x143edab4d6c10978, 0xb7eca8125aefef97, 0xb9b96cf742a4d1cd, 0x91f7bd621788d9da, + 0xce65ad539dbacfbb, 0xc07f2cfa648171d6, 0x84380c44755a2bf9, 0xb17c1bd1fb28161e, + 0xb2ead82f204ca51a, 0xb9c519c3deb48075, 0x490e8e273386a4c5, 0x62fe20b896aabdc7, + 0x08150553d4fbb8b7, 0xb63bcefa397b7e1e, 0x8e31d60c9f8f2c1d, 0xf14c82ff9f148b40, + 0x9ba5fe4c96c0ad6f, 0x3a1d23df697e327a, 0xe581a946a5a3c7bb, 0x20c32db2ba2cd082, + 0xa1cbc0a4ef37a9cc, 0xbbb1adffde502e68, 0xb44ea412508f8201, 0x92f0a51aa41c9bbf, + 0x2b1da53e0b137079, 0x05ee0f3c3d481a43, 0x3ad65c87391713c6, 0xcba6e998bd4542f3, + 0x5e32d453b8f2ba75, 0x60da46269bef3bfe, 0x3a86517f5cbcb848, 0x5a99f0da7fa5f345, + 0xed9b38f0fa3e9d3d, 0x15bcf01a4b29770b, 0x8a1286497c0c6f90, 0x6acd5c08efcfa4c0, + 0xdbf02b38010a3cdd, 0x80e2327c2fe4ac7a, 0x855c8b49c2963894, 0x098559a14258ece3, + 0x95624ac44e757a49, 0xbf25d3293ae9cd0a, 0xd53238f6b8f7bb0a, 0x36a968035fd1c8d5, + 0xe051d6484063306f, 0xf53fc03c4723b819, 0x69e876c598e8a5db, 0xfabc1ea5302e31c1, + 0xf26a1ae58fbb95d7, 0x3a822ebab5a0bf93, 0x561c42f41b868f38, 0x18fafa517dd4b6da, + 0x6af57fc438fd45a5, 0x40d86293cd88f629, 0x0ce7365686ca1391, 0x5d8661c1c84d41a9, + 0x79868e0607026b93, 0x30556d27f3ccef6d, 0x15dd62c2eeb804fa, 0xa333732911f5cc36, + 0x9bff54e0807455d3, 0x797998c07ba99ab5, 0x4671f90e861fc580, 0xb590b2677303f12d, + 0x0cbcfd7d3424c39e, 0x2811092e87360f84, 0xc51b1e2455b58896, 0x730e2a6a2617790d, + 0x0c6515a19e5b067b, 0x3403d29e3e84fa67, 0x0ff2a06d1a289f05, 0x0d5274d3c65a773b, + 0x2b5ea8181f91471d, 0xad656587e821b310, 0x5bbc8b600a762e90, 0x24148e977d001783, + 0x3d9fbaa34369f083, 0x3cd5a711da22332f, 0x2b8faa2d06e89b7c, 0x08adb3255fff611c, + 0x1fca63750eaf1c40, 0x414b5d2d73baff49, 0xab3629b5d9263c38, 0xdb7cc3bf44e4cd1d, + 0xc732e590e2c8379a, 0xad424b702ec19d01, 0x43b6b4d978912937, 0x5c15ca4822975fdd, + 0x8abc511954742d74, 0xeebd3a1fb466e087, 0x070099e1d43a246b, 0x9063da354cc04a99, + 0x29c3ac9bde33b592, 0x497b59e128c6497f, 0x73862eb2eec34906, 0xd32d228aaf11dfa5, + 0x2bdf5d9b5bbbcf33, 0x62d768cd0f02d1d5, 0xbec1a308e03900a0, 0xd79e72d438a9c1b5, + 0xb5aff58a8b6c4024, 0x9506625f8cfa4926, 0xab2ca7627b707193, 0xd905f2b202a12e9d, + 0x8154cbfc9d0ada45, 0xe723738498040733, 0x72b89e04543af8db, 0x9499bfa7de4f51e1, + 0x746e3b239d3a6eee, 0x7cb0642f4f625572, 0x8cba0ab60d2a63bf, 0x0548667d48752f05, + 0x151fccc5863b35f6, 0x5b6e1c502fe4ebf3, 0x3dce755562a10890, 0xa0e5b98c27c407a7, + 0x169d7c98c445a565, 0x790f9ece7eed3be7, 0x4b73b8834b16fff1, 0xdda5765e581eafd3, + 0x653cda81bcb801fc, 0x9e3a64620be6b967, 0x20ac4042fcc06134, 0xd7824b9cdfad452a, + 0x6b4adfaacfcf41f5, 0x70b01f29240ccfb4, 0xd02b0694c5f716bf, 0xe18af666ec172a38, + 0xa898f65cff3ff144, 0xd6c1800170c8f098, 0xa3fd80165b09a524, 0x2bced08ff5bf500d, + 0xb683d65fb19f1987, 0xa5ef2ce4f48d31e3, 0x6fecb237491b5724, 0xb8cf7b5ddeb2ae20, + 0x0c214b1dc76c1977, 0xfdfc91d67cb24b57, 0x7f9872d72bfc9f2b, 0x1f0cc2a7782131b3, + 0x993742b329727edf, 0x1a068def328e3011, 0x4843e31a02130818, 0xcbf406399845eac3, + 0xc9d35eac79a19a17, 0xf70045c93eb82f3a, 0x30c75424b05de249, 0x49a7f928af8bdc97, + 0x1d2e19f457339378, 0x5ed8d2b4dde49c63, 0x32287bc276e4dc95, 0xe21aa52523105d92, + 0x44f8e79db5c7d50c, 0x701f9ca833cd4c10, 0xa7a80b865a23d508, 0x5c43db78ca0fe31b, + 0x2052cdde7cd80735, 0x2c50f11c1f8c78c0, 0x21b9ed48028d1acc, 0x70642a59746ff93e, + 0x54b851c4239deb79, 0x82e0e9d8cc53614b, 0x07ec84a6c32b6d23, 0x0636f29ccdcfc4b7, + 0x697504028a739001, 0x0e83edb74e6cb802, 0x13923fd32d0cc9da, 0xd95f3300f556f534, + 0x57ba97946df38723, 0x7501504fdbf7fa10, 0xc20a8e32607b0758, 0xfbda887ca4b987ae, + 0xb220a0d666698947, 0x6010a6ae85bfec59, 0xa2066ba9c2b4f20d, 0x19daa6bef56c872c, + 0x93d824c59800ec4c, 0x1f09e8b96ea4e172, 0x8346c8dfa9c9b740, 0xed174c23b46ae650, + 0x10937a28ad590fd7, 0x6ce1bb2f6f5aac99, 0xa90883edcb654bde, 0x63657e74170bb493, + 0xa35c97782cdac674, 0xb5918c8271a8b61f, 0xf8577e80ef39d4d9, 0xfdd6e6f750fd1f8b, + 0xde2da1449563a106, 0xeb4fa4d6bc38addd, 0xe9a46ba3aa76be8c, 0xcc2d9dbf498c1469, + 0x3edc5f3e9dceb64a, 0xac3b751e1009811b, 0xbdbb04d12a6b5d73, 0xd4ba520b808339f5, + 0x23c4ef1d091b8cec, 0x4041e7a367d6596a, 0x7829385e5a564f91, 0x28794d93e4855add, + 0x5d3a4604b6bef218, 0x20f405e2c7155627, 0x22e91a99ab11cdfc, 0x0a8448bfcdcc81f3, + 0xcc79588cc231e874, 0x0a407f549d7782e9, 0x96c46d234b2b81cc, 0xa383e49fe81c48e2, + 0xa95b1d89e3cbbb8c, 0x31328380629718ef, 0x2a60a04ed9aaf281, 0x5bae2a13687a673b, + 0x046f72d520161fe6, 0x969c870d836ba230, 0xc5b1ea79a08ded5f, 0x3497c5f228081897, + 0xf31239acc18e083c, 0x5cf4113b4c0dab5c, 0x60368758620852ac, 0x360b0ad5b275d591, + 0x89daef9a13bc1e1a, 0x8e056edf1a6291c1, 0xe756641a8d2067aa, 0x119b8ce49a12497f, + 0x794ae2689af4ccb0, 0xb2e8a87f5bf538eb, 0x3fc1b9671758b88f, 0x8e7ffb31776060e9, + 0x8bcc28d529ded9c1, 0x5a3dba33bd858b95, 0xf95ba6cbed8676cb, 0x56d7b831645354d9, + 0xcb97f95e560fd42b, 0x15c975e3a5f02edd, 0x1c8ad4cefe84aab9, 0x89fbb3e5096a1b53, + 0x8a6bd72d19a49336, 0xa8c438674728cce7, 0x6e9bf006367fac77, 0xbe9c0d034da9aa83, + 0x562509d4613f9d50, 0x9ec925306b829745, 0xab206bfad977cd93, 0x53fc240e8ba439d6, + 0xebdb554dc809bfcc, 0x7abe14f5f08a80c5, 0x5ef4b08d48bec6ea, 0xdb5e2d1367fd0c2a, + 0x9eca1168a300f53d, 0xd2c94bc950afc447, 0x4fe87520c63f57e6, 0x2e114f5af5bf6213, + 0x47c01ea3f87daedf, 0x856916951bfecf80, 0xfa14e57dbca223fc, 0x30f29363506f032a, + 0x800324891eb84f0e, 0xef95b9baf0b59993, 0x9e8ed3145f4c16ba, 0x7ca2427b60bd568a, + 0x5d09f57e7aeb0368, 0x7554d0144f997c0c, 0x836c9e97ca75ef79, 0x6fe2b78a492a0bfa, + 0x6c55024659cbbe4c, 0xb223c5125067de96, 0x65f8556a7a0fd7ce, 0xc8dff2d4a543b7b3, + 0x109f0515ff97b76f, 0x1c6d61af9449b16a, 0x6782ba8b5c295541, 0xcd61f36187ef01f2, + 0x8f956bd35209c792, 0x05d59b2b36853ac0, 0x1cac6a7a2c55e244, 0x22fc68aabb238fe4, + 0x93473f8653c4ca78, 0x26d1fe1ae466f878, 0x068541965a0ac6ce, 0x250deb24b76e97db, + 0xce3db7ca3fabbaa9, 0xd325fb7959ae73d1, 0x5396324c7223d623, 0xe4c5dae4503ef770, + 0xbe1cbe9a36116ed9, 0x81396af46c645e30, 0x78eb830518944b0b, 0x0aff10c440185c1c, + 0x673ad80932ea6ca9, 0xf950ff18c9efe0b4, 0xc9c05a63846d071c, 0x6bb9867b8384dbd1, + 0x218533e69beda535, 0xb05399e3783e14db, 0x37349f1c0794650e, 0x90d61522228fc7df, + 0xd6dc715c1a996c40, 0x70cc8908e7ce206e, 0x01a2528c6c7797d1, 0xcd849e4f15fec036, + 0x0344f566333e9491, 0xbc4a737ced22411e, 0x2fb1fe55314d97df, 0x440546ef4c2302fe, + 0x435f749d341964ca, 0x17feb4e8f6a95d71, 0xd8b49c65668f0d16, 0xef7a410529cf8d2c, + 0xc2e8fabab69b3781, 0x870629bef642f07f, 0xcd84fd849dd44e32, 0xfdac194751e9ef10, + 0xdb7d9655142d971f, 0x4584c374c1665006, 0x317690c9f33518f7, 0x86b80f41d7a169de, + 0x98386e92e68433b2, 0x20fa940824a71db8, 0x032ad708792f6f86, 0x7e86f29b3d1cab95, + 0x16ded5992f217d1f, 0xc26aa63754d300ac, 0xd5a8c1e348f2d7f6, 0x0b6b023137759e5c, + 0x751d2a2d6f5ac019, 0x89815fe1f6a6d9b1, 0x4f5fce1a005599f0, 0xdc562c9b86740dbe, + 0x51d47ec6922bb5b9, 0x43adda9c459efbdf, 0x0bc47dc36a530bbc, 0xf2ca1eb4609b70fc, + 0x6899de23f23bfd69, 0x3b91544c8da13ee8, 0xb70470e07809b424, 0x993a0cbafe1c599a, + 0x61a9999f5f79e066, 0x97ce971bb002b6e6, 0x5b6c48609c0ea530, 0xf18a1bc681ff09ab, + 0xeeb6d1704a0de5a8, 0x685dd0856d6d3b8f, 0x58234bfcd7dde628, 0x444288801fbe53e3, + 0x4bdf30ed3e09c0b8, 0x5e9d2940228d7872, 0x971fe18a19c705ed, 0x2ceed9f8e683e599, + 0x2b68f590354f6e24, 0x317d6029b2c1ba67, 0xf4efa17f924c6edf, 0xae99be4459572eb7, + 0x31d3721087d452e4, 0x86b4c1186209780b, 0x625b55e9f7ccd20f, 0x82b8590608ad25e1, + 0xe3174c6e6deefb93, 0xb7c364f9e5d5c2c1, 0xd81d193d68170e51, 0x9b31af9c2e7a6be0, + 0xb264d807799747c5, 0x35406801fa2fe502, 0x3a30d416f8c0ac50, 0x645ab9f50d60fbc6, + 0x7c951203cc6c5a61, 0x16a1bb5122f997b2, 0xb0c5b6b16ce7c525, 0xc5183f8241e0f121, + 0xec10da3b8b523ca2, 0x903a6bf119f8e5a6, 0x6ae88d5be6f20157, 0xf65813ccdde6de57, + 0xd75a9fb2c92003bd, 0xcf4d0a2c050db506, 0xfe135f472cc3ec40, 0x5c78c7bdafc86873, + 0x8794cc8b4128227d, 0x371fba35d5ddef74, 0x53d101f48b8d1be9, 0xdd96cde41c1413d8, + 0x9910c6cac12222f3, 0x4d73acf31d9a8b30, 0x9cad7a253e57f524, 0xb70ef86a6a9fa4a3, + 0xecba7bb8d95ceb02, 0x610805e9d8ac4e8e, 0x2954a349451ff273, 0x87d3dddfc0d2eb25, + 0x31e4cfdc546cd33f, 0x3dd1015bd4b1a9c9, 0x34e6ab7a515cce41, 0xa4f22cf39f1cfc45, + 0xb464ff5eb4eae19f, 0x5c919485e8227c37, 0x60864efe35178354, 0x2428295be8c87610, + 0x737c2d31482e8af7, 0x809459d01441fa58, 0x00739617c28b7fa7, 0x5af1067d2335c563, + 0x24ebd3779985ad1b, 0x644f007d16bf4620, 0x5c72161a4b69fe91, 0x768fb7a25c413376, + 0xd7722256a5fa5afc, 0xa7d33547e6d6817b, 0xf7ded47ff6dbd0c0, 0xa32ceb0b14cb84b4, + 0x34fffc287e08ae84, 0x250b01f07b70541e, 0xc330859c1071b6f2, 0x7d419225744ffdc5, + 0xd6edb96d32a0918e, 0x5ff5e0551e0e5e4d, 0x59fd55d0b6f84d99, 0x9bbf6ce86e759ebd, + 0x8a3091a3af0fdce5, 0x6123b268e3891542, 0xbf3e9a3527b3fc91, 0x83840881c56293f1, + 0x153489e3eebdea4f, 0x74befd70e198c760, 0x480ffa542f801aa4, 0x03f2e70186ba50ed, + 0xe88d875b109c6c53, 0xbd931df445b0d3d4, 0xfc2894ca22edcc5c, 0x1066a5577207be0d, + 0x37f816803f972d9f, 0x175fd13b5ae6bdfe, 0x1dc7e6b9d06d4917, 0xb323f50957f4f1b6, + 0x305421a2fb06ce9e, 0x2547cd68fae353b7, 0x5f4ceda4556087f1, 0x3c3d2b7c2cd7fb49, + 0x8108e47fbab9e200, 0x2547712db36f5f60, 0x612c8d9ed208c410, 0x361f5c6b6de91ed8, + 0x2776ac78c812e4b0, 0xdca590b07b798a46, 0x976c50dff6b6796d, 0x9013f75a77298ca3, + 0x42c8c9fb21116b6f, 0xfcb09b8c8e776827, 0x78e2b35644743a91, 0xa203c7f743f2180c, + 0x1dd91e45d4dd2abc, 0x8a8effbea582ebe6, 0x0a7f2df21d63cc0d, 0xd7dfaf88d996d764, + 0xa2fc94bd9f908309, 0xecc3e36594c3e009, 0xde8aedc2bbd12a78, 0x8fda6164c9487270, + 0x621cd2debe25d21a, 0xd2f595317a56bc92, 0xdc1ecc590b0516d3, 0xccbf0b3338e306d9, + 0xfa020f459ed94817, 0x97c77259ad48fee6, 0x6980cf7631b9b233, 0xba0cec9a661e8849, + 0x8fe7eb6906dd3555, 0xd88d8a5a165232ed, 0x1a9656966730978c, 0x811a4db34e0f6852, + 0x5790a988ab8a063b, 0x0288cdfae5575614, 0x9b673c4021752b39, 0x7a20c2401b85f684, + 0xadffc4e612e05232, 0x1af35ff6cd2825f8, 0x4215da02cd13ded3, 0x47bf1a7ce68b7230, + 0x5f8f8aaea57c55a4, 0x9885d05cd2542364, 0xa945b5e5673ccb8e, 0xbd2b8732ed143f93, + 0xf4a53be4bb45a1b6, 0x292dd9745aad7fb5, 0xeac4450be4da8a97, 0x3e15d59e60484586, + 0x9a544f595bd88ac5, 0x88a4175e62441273, 0x1d4df9115351210d, 0x806dad28cd8fe258, + 0x83e72db86b4193ac, 0x8ac4679a7566924e, 0x1888b6ee4533746f, 0x64980420b3f2959c, + 0x6031b63e5eacaf3f, 0x3400e8ca7d212f10, 0x68c88a3457370b23, 0x2100766c9b127aa6, + 0xea08f8f9c782bbd3, 0x2a663454c175061a, 0xa88fa16f7fc16335, 0xa0784eeed2698503, + 0xbb2df291f2c37992, 0xa0417cf58398ca6d, 0xe7d52653105508b1, 0xeae4336f7b5d6697, + 0x94f4fd20d5a05f6b, 0xeb687655cc318deb, 0xeaa180612ef6d649, 0x1e52b1aaf7f80766, + 0x71d93ee3608ae4ff, 0xc697c5f587aa24ce, 0x6eff5cc55b7a4ca0, 0xfef61f4267121dca, + 0x3f3602e0877fa3f2, 0x5ff7b1d221b405a7, 0x53bc1542e81a3f84, 0x156073fd71cfcc82, + 0xb7e2f343fbf47484, 0x5a08619d28b7f98c, 0x834498e92393e623, 0xc0ac393b79718ac3, + 0xabeeea4895446789, 0x140b529e2b07643e, 0x21ae3f79853aacbb, 0x44ad2d0990f68dad, + 0x13902e913a97d294, 0xcbbd6f12a9fc6507, 0x63a2ffffeb4a2034, 0x61bddff9135935d0, + 0x0fb8f6c35769e0e3, 0x5f99ed6b8583a395, 0xdcb92e3ed8f9d253, 0xd3647f790044bbe0, + 0x764e2cff879ed85c, 0x4c8550964e05e7f9, 0x07fa97575f10767d, 0x122d9b222e50c3c7, + 0x9d02078e35eef7b3, 0xb9a6e8eaffb82479, 0xe90b78bf97d9b963, 0x83bd489d4f7d7334, + 0xffcf4c529c0c40a3, 0x830be4590c8c9525, 0xded4425f0035a025, 0xf27b78518ccb1314, + 0x67368b2aeb5f522a, 0x75fea8d59f53934f, 0x0631508406640e54, 0xf26ff24bbe55470e, + 0xd80d0bd5a8a0fcfe, 0xaa239f6ca5775639, 0xab00f8c9ccc0d7b4, 0x515f7c1d5ebe18b4, + 0x197f11cccb452d66, 0x7d5285f0d9cc14ae, 0xa64fd2740b9fa3de, 0x0994d30bdbd08278, + 0xb0805478044b3598, 0xe9cdc8a7ff34bc8d, 0x19c803ed3e289d3a, 0xeff429199efaf2ac, + 0xe4da296c6cc35a02, 0x7ea6be40e152402b, 0xf2b1ed318dc9f447, 0x2e8bfcf47268e756, + 0x77e1ea429fe24a7b, 0xb2ac6e9f234c57a3, 0xd08a887f6f121134, 0x5f633ceb8fd91839, + 0x80718529cf61952f, 0x7d74aa3b4379ae4d, 0x7d1294787a0f5df6, 0x87e7cedb3d31f444, + 0x7fc9b76a83d0ba5e, 0xbfb3d782a5ccfcd3, 0x3b7a395620ca9d16, 0x4f99980ec5e4554b, + 0x10acfba4908a8078, 0x7d6e371bb8dfaad0, 0x39f4a2fa0321c69a, 0xe2b56aeb88d08466, + 0x75b7ea90c19c7045, 0x83df2887b082603c, 0x9959f1af0b47e63f, 0x1c50672d39e09dd5, + 0x5c5c5736c88a8f51, 0x3597670c1610fcbc, 0x28733ea483c7459a, 0x9c9a51c4a3e89245, + 0xc17411bf2b79ec63, 0xc53824e14bf176d2, 0xba47229691a0748d, 0x9241c732e9f24a1e, + 0x00144891e5056563, 0xb0d9b0c839f4d643, 0x26bc6e0aba6db9c5, 0x4b0b54069a520144, + 0xb6250d4628820dc9, 0x09256eb4654fccdd, 0x8837d07266dab501, 0x86caf9c1ace4b9fc, + 0x772ff27fcff91506, 0xbbc6e07d9e9e56d4, 0xf7f1f269b17bf681, 0xa6e61af74875bce4, + 0x26733027a9f43088, 0x7a411cfc02229ed2, 0x7a333f0ee8b579b9, 0x3f5a2ca63db98dfa, + 0x72847b87f2f08ff0, 0x7c15723f8e3e649e, 0x917c0a3bfdba0cae, 0x6cd7b3bfa47495b1, + 0x83365ec1a892d5ae, 0x8d40fdde02574135, 0x51d90586a2b7730c, 0x88da5fb16420433e, + 0x86ca3f4fb016ad73, 0xb57fd399e0db1e25, 0xd88d62c8e21de074, 0x893cb5fc6392d706, + 0x516353658d4700a8, 0xae1481a2b8649028, 0x88bc3dfa04e2e358, 0xd2585b40c5de1757, + 0xf2525c77121170ce, 0xc786dae485abbcb9, 0xffbc1378494d8be6, 0x4e9c59c64acf357b, + 0x016da700d4de7474, 0x8d526b0ba6594139, 0x91371534804d51f4, 0xeaac0ef283e0bcbe, + 0xc6636fd552a1f7ce, 0xdc7668b39482ac91, 0xc6689d5abc8668ed, 0xecaaa304aa77da3d, + 0x8886c5ab9dc8feb8, 0x4ecf9fcb77dd14e5, 0x6973ce60b7c2dd91, 0x27246b9247843128, + 0x4286b30eaaa530ec, 0x6b245a25bb5d0142, 0x6449b36bdbd9b906, 0x45d525b156707f77, + 0x2430cb07005ae3fc, 0xbd704fbdef7e895e, 0x189eeb8589455477, 0xa1c4f6eaced92cb3, + 0x4f28d2442e7de9a1, 0x6bd1ce0c0590d6da, 0x6b5f5f054f163493, 0x2490ac5c7d69c723, + 0x0aa7bfa912b1e3ab, 0x2fb29033175acf86, 0xde79b2de687da6ae, 0x000f189cc9b3bf5c, + 0xf1a2c129991ff277, 0x59052e36382cd2d7, 0x139a6db0c1ec2a8b, 0x1167f43b985c898f, + 0x8276818b0e5f4119, 0xc35b6ded13821fd8, 0x70aee68f2a45a4ce, 0xf2718867a22778dd, + 0x302df979402bde10, 0x027108603ed9cfa2, 0x5c90161497ddc5f1, 0x5f0c966bbd71d9c6, + 0xfaedb74a312872ff, 0x48e176e0a01893e8, 0xe995889528d6544b, 0xb99fb176e3217bcc, + 0xcd488fd4bc91414d, 0x1a04f6971356e715, 0x2a7e4e4869822eb5, 0xcd246cc619a0dfd5, + 0xd89218f1d65a4779, 0xc800628d28c346c7, 0x994834b81c1dfbb1, 0x0234841ea632eb85, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56ade753a18128e2, 0x8e0b65a3e6f002a0, 0x0c67d90f6a968afd, 0xf74bfa7fc58d5cef, + 0x2fcbcdfd6cb4f76e, 0xfe7bbd749052577c, 0xdc2979947d1f1167, 0x5481430e884d6ddd, + 0xab41074d3279aaa6, 0xb224d23cf8cc855d, 0xb9775e00e2dc94b7, 0x60fc89c599b38501, + 0xa40b6eaeb852d1b2, 0x5a95acdeba9d0251, 0xca4649001d906779, 0xd2bfce1442a1a126, + 0x31840acd267bd511, 0xd2b7056a7d65bdad, 0x228c05b9d42e77dd, 0xbac4a70243b1599a, + 0x367047cf7735e04d, 0xe12c6d25d4e174ba, 0x45492b671b88fae1, 0x5875282efb76b479, + 0xe563507a4a5c9e86, 0x3ed469fa90a3f7da, 0xd9c1a904dfacbe50, 0xd3a9f9728ec1396e, + 0xdaa67a58d9402a08, 0xa936adef62506d6a, 0xb9c19d615875a3dc, 0x61df4bc427d24570, + 0x708f77c22abf5c35, 0x99a53b0ebdd1c47c, 0xc017233c28a95795, 0x8e9e9ae36e50f6d0, + 0xecb1703545de861e, 0xca636c80b031bc99, 0x6d33d1203e83615c, 0x54502434f10c069b, + 0x7f055ddacbcce497, 0x11a12b3c681554a5, 0x917bd7d938de9953, 0x3e9ef8eb6c549cc2, + 0x3b6fa570719bd91d, 0x27b61e903699897b, 0xa2bbc64d406e0a27, 0x21dfd2028bc627b7, + 0x59487e05274aa1e6, 0x54c162fcdf490ed0, 0x2223a4682c0d0311, 0x0b46ef4a76d1fe4e, + 0x54d5b408d6d77871, 0x3f693afd38b64802, 0x93d46a1ee711c081, 0xf20561696a403b47, + 0xa9f36ab0daa2b5c3, 0x45f19955638cca22, 0x2ccbc1265398a372, 0x2a89eea977260cac, + 0x75334e0b6a180fe2, 0xfb3facba29e5b8e3, 0x5d171f094e85d2e7, 0x49c4cef69ac20dab, + 0x6464b661e403051d, 0x454d9e7d05f74a05, 0x7ef78fa1c632a6d4, 0x4ac5e32c3818c72b, + 0x79ce543f96d4dd60, 0x1fc99a68a448e6eb, 0x1d211886b3852a44, 0xbfb5fdd1b06d96e4, + 0x36e11c944ecd2741, 0x9a800407ffbf461c, 0xdddc2ee912b1e680, 0xccbcca995ec3268e, + 0x8315b2721997d624, 0x68351be7f4458024, 0x40b5dd9561855a6e, 0x95ab53765f070b4b, + 0x3924be3b01f901cf, 0xb8e3abebe9b96b47, 0xf95d138760ebf51e, 0x3507cdcef2af1327, + 0x30ef79c39a3b8f20, 0x90f1bf39a1e10658, 0x19411380430b8fc7, 0x9865e6acc27a9367, + 0x1818da646b991b5f, 0x1fbd9e0f443a754c, 0x35d89ed5c436eadb, 0x00ee6b980b1385bc, + 0x8c6c19977eb7ccc7, 0x7e068d39593efcd6, 0xd94a26e618fd5c51, 0xe260ca63b5bf5457, + 0xdecb1dbe41838c79, 0x5581c3d26a80b0e0, 0xbb464bd48e392236, 0x8189c66021134fec, + 0xa58a2a8805180abf, 0x5d0a0dc03a91e480, 0xeda8323508cf64bc, 0x2053fda089b80372, + 0x1daed6daf35c2fce, 0xbc3015d754bc3708, 0x21aa61e28317a4fd, 0xd32a0b919e399955, + 0xb137815bc69575bf, 0xb34594ea2cbb95c5, 0xb06fc328c7b60dd8, 0xc8ea7378716c00ae, + 0x2472318dd4ae2b4f, 0xd4aea4200f4a6729, 0xcd3b782f7a87bcdb, 0x9be2489086acdb0b, + 0xb4604c5def22147e, 0x34f165eccf1361ec, 0x164973840a35e939, 0x2e704fc6d2a3fc0e, + 0xc897a6b93429783d, 0xb5d6b5765e42dc7a, 0xa5eee9d4a635ff82, 0x06687d1078ba0903, + 0x036e4394ee352a7f, 0xa8133f73ada63db3, 0x1a7c23ce9652df72, 0x61a557d8490c51dd, + 0xb97237b3a2732e60, 0x7293b1e573fc8e86, 0x4f85c8f63d901718, 0x0de1f9b1e25862cd, + 0xd00c305f449e7775, 0x878842cfdd380775, 0x95db0a365e58863c, 0x8f8e221f54f5b82c, + 0xa4881c5f7a77f45d, 0x95881512dcac7276, 0x7b39a0e3181c9835, 0x6da0be3bc6134542, + 0x848bfc3706d132fb, 0x7c4b5de565b85251, 0x58335f12321812ca, 0x8046641c6732093e, + 0xe40a5c97869fdf3a, 0xd2294084a25f336e, 0x53b7c37aeef28ec1, 0x653c0334dc6233a9, + 0x32436f2afb405d59, 0x7512866ea3a5aed3, 0x90cd7c4da140e6f6, 0xb46a69cd9121d655, + 0x8968eed57ddb53b3, 0xc5fd7d554ca0dfdd, 0x7d5f742a14e3fcf8, 0x600dff0cbca7d7c9, + 0x1db48658afec558c, 0xd8fe267f0d81688c, 0xce4e4241375c6041, 0x80cda5842b710cfc, + 0xa58fcb00c7ae1d7c, 0xef8566280bc57dbf, 0xbd9c32afa23ad4e7, 0x68785faf5b7f2bc6, + 0x645a519b44525c75, 0x6d34cb9d094efd4e, 0xe7cd9acc04c993d7, 0xc7daa3f496bdbb51, + 0xddc2584218cd9ab7, 0x07c2c378a73bfaa2, 0xc33bf53f730e0e5d, 0xf986e73befc5f655, + 0x7923f71eaef7757a, 0x866de2974cefa7d1, 0x97646d4adf3f4eb1, 0x3e09482918ed4569, + 0x6434f2ab5a652108, 0xbf76b82783115a21, 0x3d461bd81f0193da, 0xfbce33564d8d64e9, + 0x83646a58249d9437, 0x98e48566a080ce72, 0x73d223e0ac402801, 0xc568e561351ea597, + 0x3e39d6d3fd1b31e3, 0xe20f99671429b295, 0x061189bc2b15bf22, 0xc4ffcbaa121afcf2, + 0x2b05cd3224f394b0, 0x389c5349c00304c4, 0xe15327c9f84fe4dd, 0x6c72ab2e66405dc1, + 0xf3c7c74e6b085a95, 0xbc0b58c231e52c0c, 0x648c5eb6af760e9b, 0x5ab49e76e95c05eb, + 0x75b96f95dec0a89d, 0xe38d3f0c56b3442c, 0xb474968e76a76628, 0xda62edc26468c3fa, + 0x22869acf40771c29, 0x8d1e876ebddc2610, 0x6d8f098662eb66f5, 0xfa61c4a2ad73469a, + 0x163f7d1d4546ee06, 0xc24fa53771941edc, 0x83623bd6c6e2ef76, 0xa97b777755dfffe4, + 0x547f8c03c592449f, 0x4626610bfaa8b1d4, 0xba3e27b95eda58d2, 0xb49aa4438ea5d042, + 0xce93bfe2c4fc48d5, 0x95bf9cd4cd372b02, 0x5db18104b9d49574, 0xb471fe585495822d, + 0x6653add72d8ec8b6, 0xc795382ca0e89b03, 0xc7e90aa5879493b5, 0x1d3b725757785553, + 0xeaab684ca4840157, 0x45489cdc127b0482, 0x0eeade98dd6c5878, 0x076c2ddaca695fd3, + 0xf56f9bfc32779222, 0x425b770e549f8664, 0xf44ff886babda87f, 0x48e78d982d5c775a, + 0x38912341ca87380d, 0x991a4eec59790d60, 0x551f87b5a77b0db3, 0xa75b3a0e6306c016, + 0x70b4a8ead1570af9, 0xc132696edb595393, 0x9ea19890375e1ba5, 0x03b2a571006f96dc, + 0x969e9cf39ac8ad0e, 0x5bb5572e200cc78f, 0x755dcf2785768ded, 0x92fcf34524dc445a, + 0x92fac528d6afdbfd, 0x2afc8177c5fbeda4, 0x080568800d45c6f6, 0xd8303d47cd804386, + 0x7f2fb76f1320b5d4, 0xe69d24a85f64aa2c, 0xaf80e93b91ea4db0, 0x9d9ca6b54709b09c, + 0x4f147df629677af7, 0x3450a1b94a2d6896, 0xa50f9fe2ae92049f, 0xd9c8428d0cd4e7a8, + 0x53aeb2013db86e57, 0x38b9549594385b39, 0x927107fb4135d1a4, 0x41e8a6ed7ffd05be, + 0xa06bf7a3591328ac, 0x4ca14a4c728a309c, 0xbee22f3a71bd8199, 0xc498a0fa84d822a0, + 0xc0892569e58d391c, 0xd6a578e2d93ab827, 0xff2dae24c26f8706, 0xb2aaef75afeb7b5f, + 0x330c2a337328fc7d, 0x1f5f5356264157b0, 0xb2f307c183aa8ce0, 0x137a0f069e9ec063, + 0x56a5481da68341f1, 0x2e843ced41a4b156, 0x4c94c9ea05681b65, 0x15b36d578cb6bf11, + 0xc1570b00402a3d4d, 0x2e794a714e132d9c, 0x16ac1e8b907d2ee4, 0xadf3d0aa0d8b32ba, + 0x48bfd58c4b1067c7, 0x78d126b622c49d4c, 0x80b2922a7123be3d, 0xa668a019514cefcd, + 0xd2172cc2fcd4b978, 0x9e4b1dd4cc9b2e47, 0x22c291c567a73be2, 0x02e5919c4b3d36a7, + 0x397ff3a415816d88, 0x490a83c41b04f0b9, 0x2cf2bdfd24cc53ac, 0x7d788d4942d22778, + 0x9e00a10d6c08e752, 0xeca1303e883d5eaf, 0x793058d7d4f537a6, 0x4d1a48ae67163065, + 0x8777d271272e27e6, 0xea5decd51647e90b, 0xa90c8588f5db968e, 0x3f4f7d18da7349f2, + 0x2750ba6a0b5a6d3a, 0x4abd07407e857301, 0x798a2478cd06cbee, 0x64e9dad00625ef3c, + 0xc98e07ac71dd0d2b, 0xba9067794f64fc4f, 0x33b0cfb9a2a53225, 0xcd4eb913b3315345, + 0x957e1f9b09b09cfc, 0x0d231e09e033c10f, 0xf305de1b555d7536, 0xa7a3c6a3672519f6, + 0x0e47030df79b2560, 0xcec5a920877d68a6, 0xa1c198cb9de40c01, 0xfea46d2a7bbae9d9, + 0x42ae0f90b29a41fa, 0x69c2b5ee4dc853ad, 0x5886b7b244e8f8da, 0xdf3ae3e33e1c2601, + 0xaf6455d3e06d8fa9, 0xad1b931243f798e1, 0xc318250f66e29e28, 0x4ce17036ed8d1dcd, + 0x24e7733f6711b3b6, 0x1b401171145ed99f, 0x8db529b6847b3081, 0xf38d49b2f2268a4b, + 0xac3818ab95c0c7f2, 0x9dc8827bdf8d6025, 0x83e3049ae1b28b07, 0x6946bc44f9dcdc1a, + 0x5090498e7a0a2cc4, 0x20c728652e103d6a, 0xe1ef326900cfd7b7, 0x390c1a247dd6b011, + 0xf9b034b05e136fc4, 0x04afd6c7901b4781, 0x5a7de9253cbe961b, 0xcee994d1835fe30d, + 0x2e8957538afaf2a4, 0x0142b006393b3988, 0x33c35aa8fa7507f9, 0x85b0072c191832cf, + 0xf3d6f769ea7aa350, 0x03f20e5736bba3db, 0xbaaccf20c928a386, 0x4acfbeb7bf20c9e2, + 0xf70870c8079586c2, 0xd30bb2a77b7668c0, 0x8474cf4bfe5b6907, 0xfb437a3a78bbe41a, + 0x3831d80c7292a47b, 0x20d68f0c570243ba, 0xb16843e72f1b6101, 0xe1bde562f3617838, + 0x5ac0ceac72859058, 0xb8c3bbc1a7c592f8, 0x1f73eda1a0aa0362, 0x0cbf0a88b2973c04, + 0x51a8819818af1e53, 0x23d1cc6c5c5902a7, 0x066ded2f9b950cac, 0x909c03b584fcc6df, + 0x42b21bcf08836d4d, 0xc014376a44679fbf, 0xa4e25915bccbd87e, 0x4b983bee020b0ff7, + 0x28b3cc85e5019644, 0x13b41c7d3807e7ea, 0x08eda7486dd03ce5, 0xb7d06e8a66aa9166, + 0x3cdefae3e31e848d, 0x92018365825457f1, 0x7668f204e6104f8e, 0xcb9c3e8cd721c67e, + 0x33ed893d74bcb5c7, 0x863edc504301c648, 0x3b3bb9383b5fa061, 0x7f59e14a87fdb967, + 0x603ebe9ee6d252cb, 0x7242612e277577dc, 0xe8af8f921d690951, 0x2b9a7709a5f20dc5, + 0xe6c7b0e4f0b5e2e4, 0xfea2998e54c74435, 0x7dbb07bd70b2b57e, 0x3452dd18abbda548, + 0x3d11d526d6d90fb1, 0x933197d80ed19016, 0x0f72b20376fc2a69, 0x8fcf74d978eaa1de, + 0x7cb20c4d844c6ec8, 0x3a5e93f246a6ce1a, 0xe2860bf20ace0123, 0xf30bd30bcb85e696, + 0xa6d348d0bba958ff, 0xc00d7812ff88491c, 0x9775cbb5adf55d09, 0xcfd894f9184e97fd, + 0xe9ab298ec0417b69, 0xc72f3fb15e2fede9, 0xc9743f18fbced93f, 0x43b61b8069880ee0, + 0x825189ad88a33454, 0xb218383d275f6aff, 0xb97f5c6fa26d1b63, 0xb4cafe74a9f64b15, + 0xee8087487db34682, 0x041c626fd16bb541, 0xae97356a7fee4cce, 0x06e4343a305b42ec, + 0xc484b8f1319dcbf5, 0x0770593606c406d3, 0x961fd507f6cbf4b3, 0x0db98c3e6489dc33, + 0x10d06b153c864857, 0xed4e4cfb17304d88, 0xf7da72b989ac2076, 0x28194504b2130379, + 0x16f3c70d9642268a, 0x6bbde17657123d77, 0x1776d1027681cb1f, 0xd7bc9e6404472b9c, + 0x7302b960ddeb1536, 0xe86a2ab1265ecfa1, 0xa739c45b70f89619, 0xad5a2b78cff8a8bd, + 0x36040d8e58e9d9f7, 0xe85a01c491b42dfd, 0x7eef716453ccfd91, 0xb0c3d37c2a423a0d, + 0x500b3729475c63dc, 0x267597292bd5cb25, 0x5cffd83768329a89, 0x4373732c04dbd8fe, + 0xed651d4addf29942, 0xa72494b134f14f42, 0x946d44f687ff81c7, 0xd832cc13d732b1cc, + 0x5113577d10b77896, 0x84979de1f59bf743, 0x8674f36c973f2380, 0x880dd79a4d8a136c, + 0x6b74aeee4614443e, 0xf2cd42e402a3f55f, 0xbdc7f2db5c3e0560, 0x8a2ba36de240d185, + 0xf3d2569f6644b2c6, 0xe58d535c54f28116, 0xec6d494814057979, 0xbd58c0151a959ea3, + 0x52410b41b6d257b2, 0x6c0ae9a4a43e7082, 0x8ec381d52579519d, 0x2c7e25997f9bed86, + 0xb6f5df9ba2e90d8f, 0xd909305724bcd54c, 0xedf1cf65f53e4ec6, 0x2d02f22f6e965d6c, + 0xeb92ce0444c65392, 0xbb4bcdaa05d66441, 0x8469e04ce903ff86, 0xe9f8a144b7177708, + 0x6062d2b77f9096f2, 0x8b94e632abfbd988, 0x006dcc4a8b357273, 0x0b52b365cbe8e247, + 0x83e8df34ed500725, 0x60fd84dd1d9dd5e7, 0x8084cd8c5ea4c7c3, 0x20b1eae5c60af630, + 0xc3ded3e993ef93e5, 0x14f0de738fcf3494, 0x30e0b5a99e6897b1, 0x90cde81f228c44e4, + 0x79865ce5f95cdd7e, 0x2fe876ee23e0afe2, 0x85a0cbc260e2a112, 0xb4572a6b95ba6774, + 0xd76a575af98ef0da, 0xbe7fd58e4019fada, 0x9e31546f4480eb77, 0x2207255c4da78544, + 0x4151a1a4e409cc08, 0x24f42c01534d84a3, 0xe00cd214dcfcf70c, 0xbb12e3cf2271e4ce, + 0xdf9234ccc043cf94, 0xd65946c90ef01aae, 0xacf686bdcd04a68c, 0xf886c2f66101fa0c, + 0x21e99356dd3754d0, 0xc1d66e4014890a4b, 0x7f21863e79124044, 0x66c5684baf8f53f9, + 0xfa3a335deeeba46f, 0x7ed01ebd976ba75b, 0xd5f7d4a203f31d90, 0xa7f86f52d24f9a55, + 0xd57277f15fa4ab64, 0x217657d3f174d742, 0x1a222059ed4f8708, 0x02df867792490925, + 0x70e6b96c1d3b9308, 0x4cd1efd51599c084, 0x3e4db2b342ae63be, 0x043591db287b835e, + 0x45b6487afd915989, 0xd481630e213803f7, 0xacb638e76039fb66, 0xf2fd3d7c759b7e2e, + 0x5f053ba171dae8f3, 0x727e8b676acc4351, 0xa0f3cff7e86b30f5, 0x87f1d93d7c5e0908, + 0xdf071bfc0823ce77, 0xfcff6cb801d89da0, 0x162bc7acdbb97075, 0x6edb143c6075d706, + 0x5f40d968d73880bc, 0x9381bf4e3d255711, 0x09666fcf275dd855, 0x02a99f634bb41153, + 0x40ff7e0456e8b2b0, 0xbc3d41ea2a241bd4, 0xf536beff38cd0323, 0xf23284725407737c, + 0x081ac6490e883541, 0x24819dce50295be4, 0x45158ba43e44f2a6, 0xb44eb9760b20402b, + 0xcc827640eff56875, 0x170353d089c82f78, 0x59761458c22a7b80, 0x3c38dbab63a12852, + 0xe8874b8e2439a3f5, 0xe00f6141a0ba8b2d, 0xa95f5f21ccec385c, 0xd7423c3bb39557ca, + 0x48a538fbb3052bbb, 0x1cccc3140a0dd8a5, 0x197544019fbf8294, 0x11c44dae5b97deb3, + 0xd75e7d364a9f85d9, 0x17119f6d11e845ea, 0xc7377ebc4f4f57d3, 0xe5f5a3e4ec0e66fb, + 0xd3f78681f6e9dee7, 0x7769676a2c6f1b64, 0xc383b05c7d2136d3, 0x0544a24860f19dd6, + 0xd9c6039ea1047fbc, 0x1711e7b5695a7844, 0xa0c61bb4157caa5c, 0x136ba9283175f8fb, + 0x8818099c9e918e12, 0x5d6520a7680d300d, 0x87c5c86f623d5222, 0x86faf4f72bca8507, + 0x8e80b76f6bc33a69, 0x7503aff95849cf36, 0x0781c0232d62012a, 0x43f95e8700817154, + 0x03a3074f05f6fd83, 0x83092c8d4060d103, 0x316ff2cfa1cf05bc, 0x66a18b3689c3b485, + 0x8bd44428a3b0cc8b, 0xbe7cead795d16dde, 0xae6ad5a1f1a63a14, 0x9cd2d25e9b86e245, + 0xbea173a04e918892, 0x8ef9e9aca9151c7c, 0x7703940a6d0416cf, 0x0530351f5656447e, + 0x55a7761e78f757cf, 0x21523a3af82472da, 0xe0464a72643d3561, 0x3ec19098aea1acec, + 0x7022f407893c1e09, 0x06d47170ba660013, 0xb03ef6f367bc0a1c, 0x9afa7e5f3723c6a8, + 0x3693f31dec3c6503, 0x61da062779dc24c7, 0x40f46b048c6e18f7, 0xf80496de46cfc92c, + 0xc826e25c17bd4af5, 0x71f62131df10f47a, 0x3ee5902a456b5872, 0xb861d90a571fb997, + 0x6f2bf9f500513def, 0x30cc22f1be87a8fe, 0x040652e6176dc08a, 0xdd474e12ee614d45, + 0x4bb625ac7e0072ca, 0x9c97b75fdf73952e, 0xb2432b3849ff6452, 0x27b819c8a0bbb820, + 0x29012df96e6b71c7, 0x1b93822e39cb3542, 0x4fa971141efcd09d, 0xbe498e4a455777bf, + 0xd41757cf32472a2d, 0x523626f8a1c26b2d, 0x18921b9df745480c, 0x8bee769eba287457, + 0xcb27d05b0b352e39, 0xb1c3d655d7f11ffa, 0x9b2f3ea4d84d19de, 0x6dc61172e8af0e56, + 0x4356445d5413a47e, 0xc8ca751b61fce681, 0x28ec0280a2fce37b, 0x9dba07c74b45b615, + 0x45156b6db2928bc6, 0x12efc082a5c86e12, 0x583fce5489074bc3, 0x203b7cc8d33d983b, + 0x346121c682649c27, 0x76fbf3c0b5b675b2, 0x802e9924d7d45438, 0x3a32b66d726839dc, + 0x2edb4ad1f793f886, 0xb5b4ca71a5053caa, 0xded14dcab8b9e7ed, 0xb0d889b189ed0ef9, + 0x92a4c1606279ac8f, 0x37f69b445b37c897, 0x773898e36ec19c51, 0x2ae2e23ea8d5afee, + 0x7f022a9f834e535c, 0x2bc273111502b755, 0x4be2b6180cbd87e3, 0x34e1045804870c8e, + 0x98dcf58e30eb5463, 0xefa785c718ba2aca, 0x2f55f4418904a8db, 0x00a6ea0afca95b4c, + 0xc63d852930812175, 0xdefd6b5ff3a57c1a, 0x69349d4d1368d59b, 0xa589f7c541f1a189, + 0xda661a7e37dc1f36, 0x3a844d87a50f77d9, 0x4e2aaa3c258e5eb1, 0xcbf59291136311a9, + 0x9bf035cf21318e81, 0x8ae1fee150cecdcd, 0xd25cb7f69d2e6afc, 0x7b42f7a2ca434695, + 0x0c619019f458c37f, 0x574f6d982f5a8858, 0x3e31a283aa4be987, 0x94584af5c4214dc7, + 0x36381d95c5a35b86, 0x179c81ac4524d405, 0xe3d07e84b57eb8da, 0xb150a8283e862816, + 0x6d2fb7e46f4d1366, 0x581fe96536be719f, 0x34c53e9df4fb4113, 0x797586c3ad4562c5, + 0x536be3480fcb5f05, 0xbb7cecd08e9b4253, 0xc67819c60fd14bae, 0xa8f6561b80fafd13, + 0xf8598d9996740fe8, 0xaf1d4af39cff83bd, 0x882532cf59669be9, 0x36e54d04713113c1, + 0x3f3af394a1142c38, 0xadb98c08a17a5de4, 0xc067884114add3c1, 0x5e4c1634ecbc83dc, + 0x7dc574028603991a, 0xd01f12e15ba77a6e, 0x248d2117f5150bc4, 0x9acc2cfe09139956, + 0x68c00775a0314212, 0x20cb68d03b3e1011, 0xb1ae3d3993c8aee6, 0xe1659e5e2834396a, + 0xaf8d28e389021c6d, 0x35fc4d30244e2053, 0xf7811386199e0efb, 0x42a003970b8d3efd, + 0x5c9bb0791c0c51a0, 0x42e9e42c3a96709d, 0x749d1980b24648b5, 0xab63b32a4bfb8b4d, + 0x8d21126c23e57c2b, 0xbefa700750b1ee0a, 0xfcb3a2ac78898891, 0xba08bf5840f3522d, + 0x37930c44e5938de5, 0x6be163407fcabaaa, 0xdc6cc486dc44a915, 0x7be4a191962ca11d, + 0xfeb5963673afe083, 0x5d03f23fd0a5181b, 0x366ad0985d74fd4e, 0xc47a6faadc060059, + 0x78c9ef306c6b5f6d, 0x60f1cb18e74120e9, 0x1f1232ec6e36bc19, 0xdadee09bc0857e11, + 0x886a659de662d2d5, 0x76ea0e8215387a72, 0x270866a5e759853f, 0xec2f8e0cdf1c52c4, + 0xdb957fe531eefd6c, 0x1c4cef001432f7eb, 0x2db63f558f2ab646, 0xcee2727199a74ad7, + 0x908f1fe1be97adc6, 0x0039b476c22d0b34, 0x79ef96620bb04ad7, 0x601f73eec945226a, + 0x75bc5b1c397d17c4, 0x6dcc36bbfd684827, 0xdb6fa85c2b027345, 0x87c56b2baff3df4b, + 0x811d88d9efd75355, 0xfcfc1c1e0849c17c, 0x0fa3e4adaaf81f9d, 0x5c432fb7ee778f37, + 0xbc23d9625983e39e, 0x356089d7dea5675d, 0x895ea85d94c6b249, 0x347449bc949a6ded, + 0x460e3e4af7013d7c, 0xd6f79548bdcb19f7, 0xc6b41cc483a5c1f5, 0x42c6e10799029743, + 0x3657222ac4d5251e, 0xebcaf6b8b38eabf1, 0x980e92eaa8082f31, 0xdfc1d11acef82d97, + 0xbe80c7ba84f5f2cb, 0x3c8523444f1d4419, 0xd4a5901c06160900, 0xf2fd072325fbf418, + 0xb7552e36f39f4147, 0x11cf0a2a7760567f, 0x3198a6418f1425e4, 0x2caf84291274bc0d, + 0xe57aaa42a1436353, 0x0d1f9ba0881960fd, 0xbbaf2df2d692e5e0, 0x5ab2c251192652ce, + 0x7b20a122a443e293, 0x96598365f8a2fbb3, 0xa305ab86b49e3c3b, 0x04884c0f4028aa5b, + 0x89f491d63c4fecda, 0xbc502942e8081415, 0x83ea7a3ce05d18fc, 0x11a163249fab7a72, + 0x112d1cee61e5318d, 0x9e7a093cb612d7f7, 0xdb0264fe1be213c8, 0x3a616071d417950b, + 0xc14651674a6630ad, 0x72e68619e7bc788a, 0x178dffaef8dbe8e5, 0x1444931895f231a4, + 0x1d1810dfc47ab56e, 0x3c3916216e3887a2, 0xa28f2a29606b7825, 0xbbc2f403f39b034c, + 0xbf1d4d13c05f3024, 0x9282d719a9a7f17c, 0x5be7b8ee6eba3e3f, 0x6d0cffc8d789a36f, + 0xff6e5fc3496a65c3, 0x1f01d2c1ebab6ed1, 0x02a92eb674a551e0, 0xf5d607a11bfbae84, + 0x27bcc52900c8125e, 0xd128ae9be721d4eb, 0x9a990d8bc088d989, 0xf3cd14eb9c2693aa, + 0xaffe63eaf21db2ee, 0xe62ef4715a1e203c, 0xb68f67d1294da274, 0xc827ff060bd31224, + 0x607b5a4973af2aca, 0x2c5e1a8b0444c202, 0x1722a565d069a21c, 0xbbf2ddb67a7c6a5a, + 0xb5a8eb205e255128, 0xbf4ed6ee45ce6bd3, 0xea7054634a877ca3, 0x68f1fd386d50e277, + 0xfb26b5713f484a47, 0xe44aa02589a4be16, 0xe6e8a6477f730028, 0x31a49b99b889f50f, + 0x8f6b8f39c1e6ca22, 0xfb02cd89bc28609c, 0x63e17473a9fbf162, 0xd0a72354c5bfc2fa, + 0xfa727684a47a88b1, 0x68da0503e8590112, 0x12f38f0babf64ecd, 0xba99d47442ad8741, + 0xb8dc041d8fdc2b41, 0xa5f6947056b49d61, 0x644681f60dc4021e, 0x34ed5cde691424e8, + 0xc72bf567e52ae403, 0xb0f67ef58df60f5f, 0x0a827bac8c3e862f, 0x39dc49a2b2f42e28, + 0x8ae217f8410308bd, 0x452b5a3f4df88b0f, 0x430f3c1dce6e177a, 0xfa51a42fd5a6d789, + 0x6e5f2afff5f1d257, 0x3c0737c44539fc07, 0x67e72e1cbbdf718f, 0x2ac9d3c84173ce2a, + 0xc0df86e6470da6fc, 0xc810a322c4d8c662, 0x17bb018cdcdc4bbd, 0xc3ab0c624b650319, + 0xdfc3adbd0e6e072c, 0x16729f78f1f62f12, 0x7fe24963a2c4730c, 0x78e48aaf6c4f7b58, + 0x3988d6b4951e8858, 0x7ccbf72642c06a4f, 0x6586fa1255e544e7, 0x61298d3c386ee71e, + 0xb82d0d5facc951b4, 0x0d885d2241292c7a, 0xc3f2a683b76006e1, 0xa373fb96a7febfae, + 0xa550c922be54ff6e, 0x9ef8759c70574dd7, 0xdfcf8ca38f6d40e0, 0x9fdd3c671315f594, + 0x6cead69ae1238cde, 0xfa3a4508465f8b16, 0x4a1a128bd545c3c1, 0x673bf884dd3f6991, + 0xc33cb99eaa67749f, 0xad815e616c52c4f1, 0x32360428bcdb35ad, 0xae915bbf8fdaa611, + 0xfec3ff4d6284b53f, 0xbb038b2b60ccfb5a, 0xe8fb28de4ba0d116, 0xf39a06efa9f275d7, + 0x38c3e2c52bffca35, 0x65e60616323121e7, 0x3d406d524b78bccf, 0x507c0330774bd0e7, + 0x6dbe6a02b4a57bfb, 0xc3f8bf3af89b1525, 0x80ff15c53e327172, 0x76d2a6fa659d042f, + 0xa9ab3383a2f794ee, 0x81112970abd546ed, 0x81e209e9e200ee84, 0x65c9cb20da4f7126, + 0xe32a41034dd6d241, 0xc973e20d592a3fe0, 0x71eafc732b1fcfbb, 0x3f6bfc164e0a7d8f, + 0xefd2798ca89df45d, 0x5b5535f6f29192fd, 0xff35124e65e93af6, 0x9e2d74c162498a97, + 0xf92eb1c1b427a70d, 0x10e8ca21fc7b927a, 0xdaf221031ea41aae, 0xff6af20c56ce0961, + 0x61f134b36a87b97c, 0xce772761bd4daff6, 0x124bbcf04ed56de2, 0xed4082483c18fa57, + 0xf4fab53a52c2c77b, 0x6040dafe70c7c149, 0xe2f9a7d31dd15a65, 0x8879a81d8ddff120, + 0x34d386cde2bdc6b2, 0xaae1402a02bc64ba, 0x0bb9aef985cb1df2, 0x84ee60d82c5a8cb7, + 0xc671d33db0f15f08, 0x35d097f0e8cdd9bc, 0x049bd2759a8002ae, 0xd634a3d2f6acab25, + 0x64ecf0be7b3b3b63, 0x1f23156f16a798ac, 0x5b33ab2701fa7cf6, 0x8c2d3f24c48fcf08, + 0x7ac15fabffdd4c85, 0xa3685f57cd088a4b, 0x65604388be2ec68b, 0xc9b656446f781b15, + 0x9609211701611bf3, 0x8a00148e9ddd6c60, 0x17243a04f64a574a, 0x1d06e5192cfb5155, + 0x23530648d38b5c1c, 0xdc680bc5f4d5ce7d, 0x6b2057306daedc19, 0xfacea2129a1dbe65, + 0xd9edfac05757c699, 0x9597e5290bc9cf0c, 0xd45f1c389d7d4a68, 0x3a8168bf5c24bac9, + 0x1d8987040a891f08, 0x78da3a18478641ae, 0x505cf0582b1df9c6, 0xc109120c8dc7a277, + 0xd2b829f701b192d0, 0xdedc1f5b18478c13, 0xc0dc9b35328517b9, 0xf57b53e08ecb9a80, + 0x23f2e72dbcf41418, 0x7c2c7501fa1b0759, 0xf6b780a85cfed843, 0x111c5c642993ac2f, + 0x11604a9c9dc9c293, 0xfcc32e0e41ff9852, 0xd352c549219bd47c, 0xa8d0dd877ccf98e8, + 0xc4cc66cf00bf4c17, 0x26c309d8c3e788e6, 0xa0098b965ee0aa7b, 0xeb3a30f355728ea7, + 0xf4938284f136b702, 0x25099f1272843603, 0xa664ce435e14038b, 0x381bb3866f5150a5, + 0x39d629dc082590f6, 0x2836ba46c66bb4ad, 0xceb214e850e4ea64, 0xe48036ea3041bc62, + 0x48126646e9701da5, 0x03fcd4b18e5bd998, 0x7fb1262e091477e7, 0x8b3dcf7216b7fa4d, + 0xfabe3fd8f47e9b0e, 0xcbbbe5301fb00a6d, 0x5744e5c66486f32d, 0x04489ede39a8e231, + 0xba61564258672916, 0x0328f9f1e736e2a7, 0x75b09f2418d87ab3, 0x97e85b98cf406e8e, + 0xa59de15997979cf1, 0xd9f24958952c986b, 0x15fc3a1fac92c5ea, 0x31d68ef6f5ad241d, + 0xd97982c709589cec, 0x4f5045e5b2c84704, 0xe54811b322f6321e, 0x711da6047c85112b, + 0x313315e842fa593c, 0xec3d985cff07e762, 0x6994dc0e3dd78dc4, 0xbc9b2dfc0232443a, + 0x99dd46ed39c07d6c, 0xe0c1001690ca7a8e, 0xa117f38e178666bc, 0xdaf9003ebe5a5e44, + 0x728f89ace6ef98fb, 0x068023b8a7ba1fa2, 0xc4e2b3522c5f2e8e, 0x40d5e0bca4ea34ea, + 0x034cc9fb2708b080, 0xd53454e8369ba3d3, 0x6b82ef1502d917df, 0x220753d0530f7877, + 0xdaf1d162696bcb90, 0x7032edee8ea6aed4, 0x8cec33d3fb85bbf6, 0xb0f6f2a3bfcc4a01, + 0x36fc4538b6eba5f7, 0x082b8813d467d91a, 0x55617dca197bb4bc, 0x6219075aec1b5e10, + 0x83247da4d7c91444, 0x8bcdf605d4dfe8d2, 0xf659006120c57e8b, 0xb602840c48c2a29f, + 0x436d6d528ebc98a0, 0xeeec330ad6122438, 0x11cdd0f92e5ea03c, 0x06f80872a9df0544, + 0xead35b186b700328, 0x8d52540a8e65bbd5, 0x95aace2409869caa, 0xfad3a3ec20048cb5, + 0xad333c7252f7cc71, 0x36bb03f340c44872, 0x2a148b6062170c61, 0x21b0f4c1356d5c0e, + 0xd84305411199c017, 0x464afb3395347f9e, 0x6dd693c51eb182a1, 0x775ac58542a276e7, + 0x20971594cf8de26f, 0x71bbffaeb0f3f042, 0x65f7c54a2fc0346b, 0x5aed5bc8679a895c, + 0xe18773e416c9df2f, 0xdd9cea6c8964c35b, 0xee0d2f4a412deeea, 0x5ca868f95594338f, + 0xf9f426a07a8679b9, 0xf36957725e9c53aa, 0xed8cb503dddeb6ee, 0x306d12054aaaa608, + 0x8de3f0666f2c9baa, 0xd61f2ec1b94964a3, 0x73449d5b8808e1ad, 0xc45b5423f0653260, + 0xf3e85d462518bd75, 0x284c2d5849a27e7f, 0xe7271e78c92aab81, 0xe80f69cc31528559, + 0x3038787e093d53c8, 0xe67dfbdc6169287a, 0xf1fe50748f614390, 0x422d24aa8a3bdf3c, + 0x4e8ff618dc55c68d, 0xb88dc2acdd118428, 0x96d1050cf1badc44, 0x284a5e41e2b68b6e, + 0xe39065957804c753, 0x7b5aa004bb709165, 0x444836942d26d62c, 0x515beaebfc3ae606, + 0xbb77364301adabca, 0x4134ab404d545d41, 0x016497b070eee340, 0x0e9b6b637a9a6690, + 0x954fac12e71a88db, 0xbb77bb024d521d86, 0xa1118a21c3ea1f6f, 0xb3945124694de3a1, + 0xa53f48accbb0ac75, 0x9e53cc1e0fc665eb, 0x04752aea2f03141d, 0xe2c81ce4a6f99078, + 0x767b21f7d387bd7f, 0x74e34a760658769c, 0x1ccac6c03c8fa2c4, 0xcee524f5bc7b391d, + 0xfb4111502e3595cd, 0x05576d1d3c1b4c82, 0x8b03029012119e66, 0xd28822a7093dcb7c, + 0xcd82bfe2ee0d7f0f, 0x18ed7363fbf73bc4, 0x9438ce0aa3e4d0a9, 0x308618e834e9e0ab, + 0x912b93cd6a2035e6, 0x6bb2ccee9bc2c489, 0x2f5a2bb33dd0e157, 0x10dd76f0126effcc, + 0x002b04d4639d2197, 0x71c6e39ca0175ec4, 0x1761ddca96410b15, 0x367dc51a39ff1ada, + 0x3dc4f6c2747a4fe1, 0x277667b78a649d78, 0x37a1d00ba343bdab, 0x29377d384be15bd4, + 0xe79b4d3867b685ca, 0x56c90bffbee643d6, 0x7525f208f34e3eb6, 0x0375539a86d8ea89, + 0xe27aa0474b9d7ab6, 0x767175d2947d3311, 0xda72fbe570fa6d96, 0x0ebefaab9aac0f2e, + 0x83ab0a032b5e716c, 0xf65f38ab24a5805a, 0xcee5470ae184684e, 0xf7a885f3c21045c9, + 0x2d8466d39982ba9a, 0xbde9120c864b25bb, 0xa561a9f50ee08b22, 0x4600e3c72779bf2a, + 0x33230446aa3854b4, 0xc25e397e58495557, 0x8e043b773f9e88fd, 0xe2f59e854c3b6c29, + 0xbeae22fd68085c9b, 0x358ad74d95b939eb, 0x6cd6239dd5bc4e4d, 0x278ad4c22bbb7ed0, + 0xa9caecfb86f67c90, 0x9e2116dd016635ba, 0xe4b69bf2e4db4d95, 0xaf13105a367719fa, + 0x16b55864a69ae171, 0xa4e783d3097a9532, 0x867204d6815be317, 0x1fc95302f15a2f9d, + 0x527f975eef50668e, 0xc92c02c6dba67771, 0xfb2c4cfce985ccf2, 0x97beb7f89e212fe4, + 0x9120236a5d645fc5, 0x087f23174065afa9, 0xee551075a4140901, 0xfa6854fa25d4ff2b, + 0x3e33844d53c159ae, 0xa69eb7c14ccbed57, 0x1bd696b9389c314d, 0xa26130d5fd650225, + 0x0f3bb5ddfc8249ab, 0xa39388a60a872abb, 0xab0481883ecedd2e, 0x48978ae9fd6d6d8a, + 0x71b454a019f8bc95, 0xd22b7df2e04587d4, 0x2ba5616a77f1cc2e, 0xf949181ae92fb1e9, + 0x5bf10977534fbf43, 0x284713719c17d419, 0xda93bedcaeb5714e, 0xb124c64f545560dd, + 0xb9d6b8495ac19488, 0x5c2ba005a9332395, 0x3718b22dc2c8e3d7, 0xdebe421c13b66a08, + 0x980d3820cfb24c3c, 0x29b578ca69c577a6, 0x2d9729ad18aa3934, 0xbd4c88e5514cba87, + 0x0c76a74e83270905, 0x5e59c7a679709ab3, 0x9c35dde44d246a24, 0xd5de8d9aa129f3c5, + 0xa3ec60bc4c46a7df, 0x5bd9c8db6e6bda43, 0xf385bf78fc911a65, 0x96e7c50407335cd2, + 0x36b8e6178895fc92, 0x97f44e36fce9f39c, 0xd0fc253652a4647c, 0x11c8d8fc5e2b221f, + 0x3f93cfc2ee897ce9, 0x7e75aee2d5f774d3, 0xa648a2df457d494a, 0x73961d270a40a3fd, + 0xe4996304e1907f66, 0x1427d1b3d99bb75d, 0x8b014aa0d1540406, 0xd3d69926d35647d9, + 0xfa22093a0323765b, 0x45cf74f035eda47a, 0x2bc0eb5a92ebfc48, 0x5b8a6c57fcdc0ad4, + 0x334da2a777b2dcba, 0x7b2a1c8c556200c9, 0x1b5c7354de61b5f0, 0xd07f2c17b0d10d24, + 0xc975bf2abefbbce5, 0xfb71ec0de4eb9379, 0x03c03283e29942d5, 0x07a0c9f62f5b4989, + 0xa32776985d902bbf, 0x90ed6f3048c1f4e3, 0x42b9f9c658decbb4, 0x6fc55e0c175429b1, + 0x3bb7898960abb9dd, 0x33d926a628ce0deb, 0xe05c2e00ed1150e2, 0x5d2c528040e0e30e, + 0x6d15a5f03efeff76, 0x090c6ee678b0d374, 0xe313d45152cc8113, 0x3e764fc2999d0364, + 0xaaae0487ff581f39, 0x8b52dc9b473d9c4e, 0x8eb8744cf3ad1be0, 0xa696d348c15f9a08, + 0x0a23d09bba9842cb, 0xbbd1a9ba14c9308e, 0x8b61b9442292ac65, 0x46d459e65e2518c4, + 0x9d4893063d76bfa6, 0x50a0c234f060e91b, 0x7e77a03666491d30, 0x7d70d32e34132244, + 0xadab72219505d0ef, 0xd1722156c586ef35, 0xe0a87bd791c32090, 0x765794a6952de117, + 0xae8f97f5a835ffc9, 0xeafdf5145e107884, 0x27c86318aa7ba1a0, 0x1b0536fd42926745, + 0xc70e56f45a9aed13, 0x215364d78dc0adda, 0x795cb646752b72e0, 0x09c11a43b6697cff, + 0xf3cb4cfb69ae5108, 0xce6231e09a8f4977, 0x4f257d51b836088a, 0x4c1c485ffed1d5ec, + 0x2d36c6469db8660d, 0x7892335e0ec62383, 0xa4acc1a38f10b6b2, 0x3ebadf7d97b1e06b, + 0x569589fa8e278d36, 0x81f1262ef0cb6087, 0x7132bdbf9c734ee7, 0x4188b0aa38abf80f, + 0xfa90291a2b68b21f, 0x4bc614add1694223, 0x3e052bd548d3753f, 0xea9485d95e9f325c, + 0x51b363e85294ffc1, 0xdf76f6101234846d, 0xb7d46ce4db8e10f2, 0x9a9a23c053f559e7, + 0x79a93ae5d0a6dfdd, 0x31f9b64a65ed99ff, 0x659e14f91ae75c09, 0xb42fbbcdf7175c71, + 0xeb8f43dce46b849c, 0x60f63197d82c0a58, 0x76fa236c56501ea0, 0x667d49ae28dc3702, + 0xf858419d5c621abd, 0xee42168afc1c8e14, 0x04f541a9a7078adc, 0x373257c8be20ff92, + 0xcbdd21cec53ae15d, 0x5cc4f178817d14bd, 0x735185b898d42ec0, 0xf8538c3bd4b48f29, + 0x4ff7e931933e473a, 0xbab8032790b898f0, 0xc0fd9ce521961e4e, 0x05a4e9d76d7865b2, + 0x3dd8c2ded4a70288, 0x3ee53e796548aed6, 0x9e100223969d4adc, 0x7f8853a64077d02a, + 0xe05822d725e41343, 0xeb74d45af6ec17a0, 0xddbc4fe9af3f9cf7, 0x9b958fa7aa573128, + 0x0a6f41c37a0515ae, 0x3fb56560be64d75c, 0x51b9c42ddc151ff6, 0xe377ae8ab80bc45e, + 0x80f01690d6119bef, 0x1f626c08897dbca3, 0x196e2f2efecd6b40, 0x49d26bc4b9dd0799, + 0x2f322ca24d887faa, 0xaadf24aaa0361295, 0x2d0c05ce7793241b, 0x3f451a79540a5fb5, + 0x4ed5f746adc8780f, 0x6a0f7fab948c1d95, 0x5e56be4f7c5cc470, 0x924cc0d6025ce42b, + 0x6809eb6a7bb5d94b, 0x094f446d84e6ab24, 0x3d1bb05295a106d4, 0x3c14f180dde4ba33, + 0x5cb8d84bacaa8ed6, 0x15e14644a099cb4c, 0x84d1bfe4e320e1d9, 0x4c49857689ee186e, + 0x4c8bf94d43013fd5, 0x7a232c3aed100723, 0xcb348f572ef09283, 0xdcb3dac477e70234, + 0x472ae9ae14bf41a6, 0xc5421ecf18539cec, 0xace00d70765787c0, 0x405a1bfd6f7504bf, + 0x805bb6663638aa80, 0x902e12244fdbe97d, 0x513737b2a12982ce, 0xfb69613834342be3, + 0x83685a4028ed7ef0, 0xe89675dba086f929, 0x8e6b05b66d460668, 0x8313f0d9009e099a, + 0xaebeefb0d96dd52b, 0x20cc3c5b8d6e1354, 0xa0d9dbd63830771f, 0x7e8182888c94864a, + 0xdc8b503a7fc36f77, 0xbca1672548d26488, 0x35c43e16f28b357e, 0x2be989b14e1bf90f, + 0xe14fb805b853f9f9, 0xd2c204ab3e1bb67f, 0x0d4dc8a8d827c49a, 0xed8c67127beb2a51, + 0xb34d1828909f6d6e, 0xa8a19888ba503612, 0xdaf5ed8e81ae56ee, 0xd7e774fa74756c2e, + 0x6f8fcb4b6e5bf24e, 0x34bbc8cc36bfc5bb, 0xeb88a054c17628b2, 0x0ecf053fa582f641, + 0x9d618d0492d0492e, 0x910511bdb29e16a3, 0x1e15564e50afd095, 0xf2ff25414b37fc87, + 0xf76f3f63384c92c1, 0x8d7b5b9f6a8f36c2, 0x110a7a89a1d0e85d, 0x4b7ad5ff6073ea67, + 0x377a7c5fe6a13ee6, 0xfc6ef1961257817f, 0xa6a5801e0a26b70b, 0xa069edd56b43e346, + 0xfca3f9127b10830a, 0xad540a4f37d96c53, 0xba71d2ef9baa3fc1, 0xfe47bd05889cfa30, + 0x400c27bbb49d4efb, 0x2f6d33f68be6bc18, 0xd5fe0bcb92a68c0f, 0x85763d41184fd4b7, + 0x3eb3f537d7169da2, 0xf24dd4da8362226d, 0xad39a8373c2b047b, 0x1a914947818d51c5, + 0x9e4cf47494e7e219, 0x68e8dbd631dca0bd, 0x65f4260385afda51, 0xd7fde31c3bae0c70, + 0x09e15e852b6294e9, 0xb56fb360e1d56f95, 0x00d63e13254fdd80, 0x81d9ab96492740e7, + 0xd6de50cb204790c1, 0x42fcc23ddc89e1f7, 0xba1f0e16a0cbd46b, 0x19f2367995541b7c, + 0x00d489423015ddef, 0x6b69961803218aef, 0x73a9d119c961e0df, 0xfbb164e28757a9b7, + 0x88bbc65e242bca94, 0x46c352a98ec37e5b, 0x18ed2227c5538b3a, 0x42e7f6f78bb4097e, + 0x697b7d9680ace2a4, 0x1cf211535b77fd32, 0x681870447a476039, 0xe38265f88bc66a1f, + 0x5c897711af0c64db, 0x267aef382fbadf85, 0x0f908732e297183c, 0x4e0d5f3d6130c259, + 0xc577f90b4d87e142, 0x8722e96c5e9734cb, 0xb27f5e6bc644f54a, 0xf7fa3a21b6159ce8, + 0x227cc23ba6431d48, 0x17de80785a206c11, 0xedea21f2a6638048, 0xbb1c17c6934291d8, + 0x7ebcc63e90804846, 0x39c61a3647ee332f, 0x406c6eba3c3a7ed1, 0x6497884e828124a3, + 0xaea665ab4ed930cb, 0xe7e2d21c9f97c742, 0xab6db030434745df, 0x3fae35126b9abb00, + 0x9f6dd814ab4dbb1f, 0xed10492b737ea1cd, 0x2acb280f03d2775e, 0xd8ec0f034c2b8ca0, + 0x7678ab2c7d11497e, 0x2d464dbd9dd3db12, 0xc630c9201f694773, 0x40024150586f801d, + 0xdc8766c6600108cc, 0x2dad1cccf0600bcb, 0x4ea4e29913689fdb, 0x30a875aa94d0a82c, + 0x0be9100b0f92b8d7, 0x30b2451879623fde, 0xb4b7c47cfd80e13d, 0xf8b2a49c074213ce, + 0x3855d9eeafb5edc1, 0xb660aade5260fb22, 0xc27eb4a2d6d00e37, 0x4aa55dbb5ca4ada2, + 0x2705e64f1edbfcef, 0xf0a80db047c0a903, 0x7c6eb467887265df, 0x72843cea6254eebd, + 0x6fc175a4f41aa822, 0x61851995167b5151, 0x36b6cdeb06fe575f, 0x30f894399f952792, + 0x5a51c071714c642d, 0xa3f0ddabc6e841ed, 0x0ae333da6f7c9138, 0x9149d23a17569341, + 0x1f251b037485bcd0, 0x4a7657876de9c548, 0x2f7c840f497e3a4a, 0xe82d53ae4d668b60, + 0xfbc3b69fad4835ac, 0xec2e4d2333e00798, 0x07d59a3c4c05b3b0, 0xe8beb15d4738fd5b, + 0x85e7d47e09fe3fa2, 0x52d47528276efd0c, 0x316e2ce5ed754cf7, 0x548e858349624e29, + 0xccfa6bbe9ddf9aae, 0x75abd6c57c9d2616, 0x77691a1135204180, 0x7683a4cadb2ea38d, + 0x844387838ae5eace, 0x13017165c9dae4cb, 0xe44226060001d9a2, 0x73f63072200780e4, + 0xb92088b818c7bf3b, 0xc294e7e2ca8074e0, 0x9240748d08f9872a, 0x238967186fa747ac, + 0x0e36621827c344d0, 0x57db097b7138027c, 0xbadc243432fd330d, 0xe648ad40b5cffec9, + 0x5a520eb09c258f68, 0xe9340dfa993e999e, 0xc85338b6b745221d, 0x7a9f0939951e4ad0, + 0x915672c66b84279a, 0x0d7f00e101218fbd, 0x235a264f592f330c, 0xae2ab17a7bbdd156, + 0x8db1be2781eee902, 0x8bda463863d599e4, 0x7a6583e5ac6d5b3d, 0x79fb85d75a6f931f, + 0x6cfc167c61bd90bc, 0x4c59fe228c5e3b70, 0xd136a27e57adcc78, 0x1383bdfd7c856712, + 0xb1b096f5eae05f14, 0xde0df2f5f09b48c2, 0x4fbe190af4a0aff3, 0x404a9dcfa2f3132c, + 0x440bd69ba7f0e941, 0x4112a4e869d3c9f1, 0x5a3afadadf27c0b2, 0xb1fd487973e49718, + 0x1f091ac1ce68af60, 0x25cf30c9ccb135bb, 0x4535df22d73df4af, 0xb256dcc40f763679, + 0xf67b98153b8e9a1a, 0x2e62156fc501d0e4, 0x72b0958c8568f329, 0xcf38352e91ee877c, + 0x9efa70568358057f, 0x8eb1e0ddbf7cce1b, 0x6d3b1fe4f548ba5c, 0x41495bd8bb341615, + 0xa65fe13cc97bc853, 0x62439e25392efbc5, 0x4ad5fdb7d43d0d15, 0x1b83166bd34d2769, + 0x0ccef53fb6a986c3, 0x38f2a61ddc85d349, 0xedc61eb711c6072d, 0x7b68e2b92d2e4d28, + 0xa0c5a4b1cdeba45c, 0xc9c968ccce86bb4c, 0xf35cca9fb837419e, 0x718359452490e96a, + 0xa6b9968d80e3ed0a, 0x89de1801606ea608, 0x7d93ff455cc2ea7d, 0xe1693de6b307ea11, + 0xdf362ef9ed73d130, 0xa5de2330f27f6ff8, 0x0e2f5c9c3b13d7f2, 0x80449279c65cfc5c, + 0x64a79a1fc44289a0, 0x6560595e26b579a2, 0xa4a808b185f7c128, 0x17396ed3ea098d73, + 0xb7ed276eb35ae0b8, 0x564718adddd8fbd3, 0xef296967d40b4583, 0x262396b76f5f644c, + 0xfb22ab9fd0feccb6, 0x90a0e1c08ee0fa68, 0x41f7111a9becc78b, 0x4bc161a92f8a117c, + 0x0d8e50bad529e8be, 0xc7f55ecebe2e13d6, 0x94c42b2186fb5ba0, 0x64a8fb924af7c62a, + 0x75942bd9c47a69b1, 0x45d86924972ddad2, 0x83547a55c0c467bc, 0xe8d8dc0e1bc3c651, + 0x7f3460368e1ad64b, 0x07b24f48518cb541, 0x521c349fb375424b, 0x5292a8f8264bf26d, + 0x29f2133bd56a1710, 0x37e3ebcad4b16220, 0x1a57301801eba217, 0x6c77f1cd37b538dd, + 0xa42259505043aeaa, 0xd7270b9351894d7f, 0x63b781e7e42923a2, 0x7dfaf8840228f6b7, + 0x61dcf785709f5e3f, 0x873a4102953a2777, 0xae40b79bd103fffc, 0xe3b7ba0ab26310b9, + 0x195f1396d39aff4f, 0x7c41298ae5d4355f, 0x46b4d307d48e7953, 0x2c0134482de25522, + 0xb43da8f953be6915, 0x3e9dd2036d89341e, 0x4cc87b4af27e4ec1, 0x75d0db76a7ed5eeb, + 0x9df1701f40009719, 0xfcea3623d01180b5, 0x399dece6854e75a0, 0x0522431059dd69f9, + 0x2b1ffca63dbdb6c5, 0xeac6e1dbe353c735, 0xca61bc69e37f9c4a, 0xa01831c7ab5bf58f, + 0x5bbda493fc993e50, 0xe3007acb4a6d352f, 0x13dbc2cc1fd724c0, 0xef73262aa33d8f90, + 0x565b95d6c6b40fd3, 0x5dc876e3cd9754f7, 0x8f0e047406dfae20, 0x55e5121f21e9c3f9, + 0xe0cb3653aecd6ee4, 0x00cc909cf73a984b, 0x4d80bd1eae46a736, 0x9b7c029eee32cbf8, + 0xb02cd90913b8487f, 0x72743ba806b5b0b5, 0x07286b4b1cb6c3da, 0x943a5bac7bdb0ba6, + 0xfc2598e864e7acaf, 0xe6563063d7c12123, 0xc4c625acffa95a37, 0x5819af45a0685275, + 0x6fec595eabb64ea6, 0xcb34b837cd27ef8c, 0x791011e292a40e5d, 0xbc16d5943fe1a61d, + 0xbc599cedfe3dba2f, 0x0df3a6fd38df2412, 0x569834ae6e3046db, 0x3fc46428416b08b6, + 0xf329551a6da4e7ab, 0x452833bb8731d89c, 0x48fdafda082428d1, 0x7f6c1638e04e154b, + 0x3ce8fdb5d1926d20, 0xcb2869d1e5de87d0, 0xb13be96625cbdc36, 0x360b06c432bee06e, + 0xd6402441ea36f55c, 0x0de7b632b1b7c70a, 0x79144b010a12381e, 0x868c0d8c9e0cb274, + 0xc684860efbb22d0f, 0xbbc60427ef6d296a, 0xbe65f1de4aad12db, 0x02855670cb7c83c6, + 0x49d0b4a47d1bb24c, 0xf117b7a92665d597, 0x6de90bdf04543ac7, 0x65595bdd6faa67d8, + 0x3f5720203378f263, 0x1a739498384b86ef, 0x0684f7b2b0967b8f, 0xd6e15c859611aefe, + 0x3407665905fecc1a, 0x066ddf47b2789fd8, 0xb670d5d5cce56b3f, 0x883ec957316fd9b5, + 0xaa0a4492592e173b, 0x53f41f7f29ac947a, 0xa118d464268a4845, 0xf63b0b5242e5bfd0, + 0x1268f0876d50d3ea, 0x2ac4f9520ce3f3d1, 0x32145025c9c8da33, 0x28cfc4aebd45cf23, + 0x964238de1f31605c, 0x361ad207ee7c32c0, 0x135045472c1be0bc, 0x17d3c78ae101a9e7, + 0xfeea0ded84fe33b6, 0xeb9ecbd11a9e9896, 0x9842c91a51078d8f, 0x5e8a353b3da7e567, + 0x9b7f21b72efe275a, 0x3f38f0472e3892c5, 0x8dfcfdd74564469f, 0xefd39d0ed9171e79, + 0xc80c012dcc99e88c, 0xc10e9c55fff07496, 0xc601b9f44494916f, 0x52e6cc3ef6173f69, + 0xfd97fe9ba2f183da, 0x4e5270f600037b81, 0xbea7b02cd9d4f958, 0xcd98e614be43d9b0, + 0xfb12816c86131076, 0x21382f96bbb867ce, 0xd28ea5970c3bfb7e, 0xf32a92ebe79d7132, + 0x338dc97cdbb6ed81, 0x3aada4613fb2cc7b, 0x96605d49dfa62ba3, 0xaeaed2410ef20d36, + 0x44bb7dfac637c61e, 0x7b4dd0586e58e0db, 0x0e83a6c3eac7f526, 0x7ba75acd2ae8f6cb, + 0xfbc4530ad38ecfbc, 0xa6d3cdf51656bdba, 0x5cd3e96cee8cb6cf, 0xc182ad53b196f315, + 0x27fcbff52d71f5ff, 0x55ce6a5abd61df73, 0xd7f0cadf60014ca7, 0x2297c2086fe8b642, + 0x6a5f1f16418dad54, 0x5c9714f72d215f25, 0xabdab8b3ba505f03, 0xf4f89266c51b6f3a, + 0x99dc9d598c509f6c, 0x4ddf4bdfe6b236fa, 0xd26eaf393a07bd2a, 0x40e5c27cd072c49c, + 0x8bd73a4bca41219e, 0x11a787c2bc1b4c4d, 0xa08161782bcafe1f, 0x188a5377287bb3c7, + 0xe50b84098a490453, 0xd7d49ce0d2bc2b7e, 0xfb7a218d1234555c, 0x0a81bd1769058caa, + 0x2af67cbeb59c7e42, 0xec15ccc03a35001b, 0x26ed94af73f3df30, 0x888fdc168701800c, + 0xca7efe780148f689, 0xbacd5898d54daaa7, 0xc2e3b65616551198, 0x1d424ef36bc4a5c9, + 0x81974c4d38e27566, 0x6f0d0a91274fcf64, 0x44ded70ed19963d0, 0x55ebe2e535a21c91, + 0xd68514174a225c3b, 0x6fba9e0e080bdb2c, 0x56ec7bdaaf17539d, 0x6b982b145c41a56d, + 0xfdf4a16d50d1604c, 0x5a3c3fef97c17968, 0x7e78dcebc3d1a9ea, 0xb3402a4fe7dc1521, + 0xde3bcfe1f6a88d32, 0xe504e4b43ea13532, 0x27518379519e0f43, 0xba295cc50cff4b44, + 0x958e3d05f21956ff, 0xf4666ae5c5421ff7, 0x8f51fbbaf8fbc1ca, 0x699f6371cc51e3af, + 0x208eaa1b896cc758, 0x40a4d27bb49a4a45, 0xe509aaec4f570916, 0xa1add92316c872e9, + 0x280092bee075ab3b, 0x706cb36ad58b7405, 0xaeeeb3e5059fda64, 0x636d6d71b548ca8c, + 0xafd776d27b0958a0, 0x3c4ad3a65dcc785d, 0xd664e9dcc4e93847, 0x546e850f1c6b3bf5, + 0x83acbe62b55ad789, 0xd5853f8222d22104, 0x2b009aad0d75905f, 0xc88e223b63e83406, + 0x64459fd59600011f, 0xb05bf3ad705d8b92, 0xcc5f8c655da127cd, 0xddd328aa252c7181, + 0xc49e18012b8ecb76, 0xcd4d592e8d58b944, 0x16604d9cfadd3511, 0x62b38dcc5f066b75, + 0x99435fdbdeabd4e5, 0x16db9465a7a9f605, 0xaae1023e416d5966, 0xe49a9167391df0b5, + 0xa1c3887b9257deca, 0x06751b5391cd13f0, 0xf83954f9e2ecaac9, 0x51764b2262c0d404, + 0xb53b1489da49ec2f, 0x503483959ca1eaef, 0x0ab7f037a8798c65, 0xc941596e67310997, + 0x2a2ea7d65e950f17, 0x0582a190a8bb84ae, 0xfca8d225fb88362d, 0xaf40046830e8518a, + 0xdcfa77593505fbb6, 0xb421604e1336bce7, 0x448451e84fc65cce, 0x4041ce7b056b25aa, + 0x14a6534b7cc74919, 0x2f91d4a9e462246d, 0x928d78c14997222a, 0x20108cdd35b41171, + 0xd23395dd1662160d, 0x5958d3651fc0ef7b, 0x857c673ea63fd8b2, 0x6fd7528c3ac0abb7, + 0x2080dde6118a10ca, 0x8dcb9171a942ae44, 0x10f7ab722592fccc, 0x6a67ef771154588f, + 0xf0328663bcb0f6f0, 0xe17f2644bf5879e6, 0xa47bab498862a61b, 0x1c850170e66f96d8, + 0x7aff13c20fa91597, 0xe7394ea5ab0b500a, 0x348dc7793493b9d7, 0x39185b41d4e7a358, + 0xaf46c4e9d881095f, 0x3d823680804ced20, 0x92b9b0ab8ea29f20, 0xda47d1829d7668d5, + 0xd1599c3f13af2b25, 0x808b109bd70ed006, 0x7ac11ef869343fc6, 0xfbcd6b17571571c6, + 0xd0c0b92ddb002927, 0xc8817b03990aaaff, 0x2ada4417188674d1, 0xa05ad40022868353, + 0xa52966d2928f67cd, 0x9b87d8042f9067cc, 0xea6b630987773514, 0xab030b812cb8f4c8, + 0x6ebb15ba6d83dc68, 0xd2082096909efa60, 0xff9c89aba8c96073, 0x0786d99ab8b70d5e, + 0x10fded6bb87bf992, 0x226bcd5cfbb3c848, 0xe6ccc5dd19484196, 0xb405740e63ef0d60, + 0xb22849b22ff6a285, 0xd669b7c04da4f423, 0xb2c6505c5787988e, 0xe8b79abbbb858233, + 0xeb54debc9afe99bc, 0xd68754476b34b63a, 0x443083341fc40d5c, 0xe1f7dc35f7a216a7, + 0xac24e7d31570bef3, 0xb135a68dfe265e74, 0x5ffbd3deca3b3e74, 0x4c1b68a928b669bd, + 0x3c2d9003d9816651, 0x4b9a26d8cc1ddaa5, 0x8a569b58675f8061, 0x7a952bb8274deea8, + 0x7c1be4a1932a7ab9, 0x6cf4f6896e1ae35f, 0x22f21412bb9201f7, 0xb2c0fe56e3be263d, + 0x44cf08fda88c8c35, 0xf48ba7cf0b79d648, 0x2a0403abe57f8515, 0xbc397d0def136411, + 0x83bd3eee55b8bfcb, 0x140ce02c4f5670fd, 0x7d912b9bec2eed00, 0x0e190f06f12a7c30, + 0xdaf8a900a7a98a3a, 0xa6956207566ce87e, 0x88691fb6410a5841, 0xdc8d4aa9ec1ea548, + 0xd39e85d301fe6d97, 0x9c8419ae16bbc71f, 0xab7dcdc60d388a93, 0x4dc8f97604248d66, + 0x7433cdebfe640c16, 0xafb69d95e8994424, 0xa2774b5f00c97aa9, 0x1d78fcaa5819e55e, + 0x3a71649dbcd36a0e, 0xa8ed3835424ca467, 0x8ef5e8059487d851, 0x71a888792777cffc, + 0x42238e163378543d, 0x9cfaab57036813ae, 0xfabbd8063379b8b4, 0x5ab7ed84195a537a, + 0x0c98dd2e5c9a3c9d, 0x036ad63a02f931e0, 0x1a53a8926ae3fa5f, 0xefddad35f430f5a7, + 0x7342366d5a15e3b2, 0xf7bb11f4c6286b35, 0x85c4d86c6ab9d775, 0x791319a190b4e90b, + 0x27081da84e2fa544, 0x77ef0be4a10a3c7b, 0xd3bffa533968002a, 0x1befaaa33d4c7d63, + 0x75acc0f01c95cc29, 0xb55299014149a9fe, 0x48d3cbfcac8b0478, 0x6927ba295eeceafe, + 0x5362df06eb960c1b, 0xdc5e1ae76b7bdcef, 0xe4f0b1d708dcdeee, 0xe4f2159331b05e00, + 0x93f928098af5ebdf, 0x94553e32eec78ed9, 0x9a15e822cc48b42e, 0xa0beead4d3d6ce02, + 0x2422eebb7c19b2b2, 0x0ee6259f6b2de3ad, 0x6fcddf1b26bead94, 0xd9a0825484ade174, + 0x751aa874089f4964, 0x0c6c2801b9d0703c, 0x62979b8de23bf3a9, 0xe11c80a8e4d78d45, + 0x83c188c2cbff4ea9, 0x4eff922682ec26c8, 0x11bac6d25b281d7f, 0x60d606a90f1c53ec, + 0xffe4048d78f0d8de, 0xd49c40147272a197, 0xf4dbe5f18e22f4d7, 0x1703be685ca08624, + 0x7663a78c381f34db, 0x88a0709ec1add91a, 0x247e6d8027b93d9c, 0xa23b47fa9381a330, + 0x08f1b30fa359bee6, 0xa550a3c144300385, 0xe769ca32443eb826, 0x36d8af4532aadd15, + 0x915ca3f94a2da07e, 0x5d09f8f4888210c0, 0xb3ead867ebab8ec3, 0x87f30bc384e49041, + 0x8f88cfc0f066eaa5, 0x82a8a43c5a02d4f5, 0x0ad45d7c823d359e, 0x83ca220fc6ce6e6b, + 0x2cc135378e98f6f2, 0x9e6fe6a3ec72e91e, 0xd0f98eefaceade1f, 0x5f80b16d9c0f40bc, + 0x50102d02b483dd00, 0x70263250cc89fdc1, 0x88baec9b8decd192, 0x2c5557d1004259c3, + 0x99c710153fdc5d47, 0xf3ccd27585fe1aa4, 0x9d0c6386a3d802ae, 0x3aaf3266af0729b5, + 0x1d509ce186cc80ea, 0x80cd61a91122327e, 0x58908698a4abc525, 0xb0e785e95b987aeb, + 0xb91ebbf1dfd53347, 0xa36af62c0aac52e1, 0xa360736e08eb5472, 0x08f0f470aebb4472, + 0x68d851e9c1cfde28, 0x88b56565fa1619a5, 0x2111319eb4dabff4, 0xe390aff741b113ce, + 0x53a69f348c4d61aa, 0x899cb31a7814aeee, 0xfa9f4dd122fe2f58, 0x368151697d058f52, + 0x4ed91d69b3196e71, 0xce31c9a4570ac75a, 0xb6b41a335fa8b35c, 0x0b09340c59ae4345, + 0x82ebd25812c14e71, 0x482063a32f61418e, 0x68a3b1baedf8e148, 0x43636f2cd24e2ae0, + 0xd0634b6db577e32c, 0xc365ec9cc73731d0, 0x6526d4b3e9d34a52, 0x49a54587a8525b5e, + 0x6e9f036a54d3dfa8, 0x88ee0f139f953fb7, 0x787878701af37bca, 0x16c500c3ee39ed20, + 0x179afb3fe1acd1a4, 0x7d38730623e0500e, 0xa045143f765624b2, 0x9052d2a14bd506c7, + 0x721e3b9a685bda2e, 0x833dd53b0d1b7f4a, 0x93ea0720c26668f6, 0x8c991671001c4603, + 0x011b756cbda56f63, 0x8ee9a9f3cd32a3c9, 0xa4582d06c3d0da4f, 0xe3f9b7502bd0b86c, + 0x20820bdb3247ae1e, 0xc8c26c035eaba8c2, 0x4f46e323bc76626b, 0xee132e79f106e86b, + 0x6448a694ecc318a7, 0xe3443138d617c6fb, 0x84890ac1807eb3d0, 0xd69bf2d7b38ea61f, + 0xaa5856edc9e31a61, 0x81d5760d2e605c5e, 0x4d9dbb22d274f310, 0x7d39d5056698f828, + 0x1aa90eee61c38f60, 0x056085098104a68a, 0x0cadf40ba2c2312e, 0xbac6656ff63258cb, + 0xacd0e771c41d6729, 0x96a24375f6aaa1fc, 0x3038cb7e075a7f83, 0xab970b5da0ac867f, + 0xc76d55eef495ccce, 0xc0dfc4c6b1861232, 0x814ae212bda82a65, 0x1ed19c1af1e46b04, + 0x053dacbf58cc7b3b, 0xc3fadbe9ba704853, 0x26e912710435d118, 0x648062476983f040, + 0x238041bc8aa1bad6, 0x020fdf0a1780e8b9, 0xb74aae4eb456813e, 0x11e4289c005472b1, + 0xe15a400c6935a7af, 0xc5ac17434ac36548, 0xa90f9c905da686a1, 0x75e3f8bb5bd26776, + 0x8d79c00064f39030, 0xccff9ee408c27523, 0x0b0614aadff25751, 0x9fa420604f7b360e, + 0x609362db416b9623, 0x4968594c9b437401, 0xab2f4383a7c230a4, 0xc73024b6fd58b91a, + 0x2c3aee006137e1dc, 0x164e956a94d1c2cb, 0x060b6ffdf864166c, 0xe376ac0c3b811715, + 0x03c1bb39f23a92cd, 0x9f4a61cb6a8fb912, 0xde3958efb2424782, 0xf253766450e452a9, + 0xa1478b6653ae55f1, 0x1a05267fc33a9448, 0x328006de4733c750, 0xd3e8a45e276e7efd, + 0xfaf9a4ebaf777b59, 0x1c66a26848babbd7, 0x84fa35a85f704cd3, 0x3a6b1545e2cc56eb, + 0xb1c16ae612cb283e, 0x840d882b1bfa9eb4, 0xc51aa8d583872502, 0x456a5977e3acc9f0, + 0xb021d23bf3a2ea77, 0xfc480546f279a784, 0xe86d06b7a23a3bfa, 0x612e7eb71d96dfb4, + 0x93d4aaab8c2cf2c2, 0xfc165ea58879ec8f, 0x15fe6cceed76dd67, 0x46081490fda876a4, + 0xfd3d91f3e6ba2d4c, 0xaf7a5e5beb73ef56, 0xda9a339f21fcd01e, 0x6aac3daa36d4fca4, + 0xdc357f40a2c144ba, 0x6630f8ab67b52802, 0x134162f37024d561, 0x500b82a18091ccee, + 0x4dfadcbc733b5528, 0x9092d3db69d04552, 0xeccb389f5291a63a, 0xc261ab69d83e3bda, + 0xe69b5249311b4f7f, 0x99a9a34582cbb473, 0xc29cd844a15fe400, 0x97e71b560d77a425, + 0x0c1b231b57d9f201, 0x8ee5130e97542777, 0x7e9ce13e1d657b8e, 0xb3ff7ae4dc8dbd78, + 0x8a44ef3c19e1c616, 0x3006f055dc2f7230, 0x1aec071abb5f9372, 0x52a1b15f49df5831, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe0c0696af16ea60, 0x67e04e815aca19e5, 0x506e57de98503ade, 0x4982dee131f9309f, + 0x70622bf624c3a9fd, 0x373aba1de3f256b4, 0x7c5e8e1d2586fb41, 0xf2a2d3d383553c98, + 0xd72194082b8395ff, 0x0a2a747b61822e7b, 0x86dfbc1f6cee0e84, 0x54967faba65ff882, + 0xc3c62a22c42b1af5, 0x67506e9d0801b684, 0x2e6f290d53f05c10, 0x39240cf81d08b6bf, + 0x0a9d729277f7aa85, 0x2f5a9a374a41d036, 0x35737e7507542476, 0x14339c981e467701, + 0x2a3dff199f5e5fd7, 0x8d34032b8f7bc7bf, 0xdd745bf0340cddc0, 0x2cb206e831b837e3, + 0x956b8bff8eebf03a, 0x6dc4efb04d210bd1, 0x66599ddebee240cd, 0xe3bb7cb63df3562a, + 0x7ebf2109fda12027, 0x4895bc04eb2981a1, 0xe10c3f08a0503d38, 0xba6173b6bdccf122, + 0x666fb23e95b1190e, 0xc12cca9357c0f953, 0xdf2aa3d99cdb3821, 0x0af8422626850564, + 0x744dca7fef5de19e, 0x65870b797db48569, 0x9a2bd6e0b607efcd, 0x77b4a295df0fbe90, + 0x1e6b66b72b140c33, 0x26d224415fad3c7c, 0x40a028d359132838, 0xa83580bb2053c6ec, + 0xcecaec85efcd1de2, 0xe4deab1d810d4c4a, 0xeda4173ee0aca18e, 0xec8f719d4a39ae8a, + 0x9a194fa318b37662, 0x2b9fae9022158dfa, 0x002ee4e9841eac9b, 0x91088fc017298eb9, + 0xd789b82ed1393a6d, 0x25c00ceac7b9cc74, 0xe983eeab217e7cc4, 0x21f9f830d35858ca, + 0xfa4163d0fcecff6e, 0x5bcd213783de4890, 0xe1b47de54433efeb, 0x63b134b9c0f7625c, + 0x2c65ff9f5f41d91c, 0x943d14762edc5d96, 0xc807eca0203b3b66, 0xc42707329a57157e, + 0x52c918477e5bda41, 0x5baa32aa66a6ea8c, 0x056f3957820bf1f4, 0x45d8eb2627e5d2e6, + 0xb13ba52280332544, 0xefeb08ca7bd150dd, 0x1b7bab22dcd8965a, 0xb739c7122c0eb041, + 0x603542f73bb5a723, 0xc26c1ef66acd27f3, 0x01d89539a0254f10, 0xb37b39a0a93736e2, + 0xc434b77d1aa789cb, 0x071bc9d76627a54e, 0xd6b093b50a1a7d3a, 0x4f640d96bebe32f0, + 0xcc80ea0aec4fb721, 0x2f9b2e77b5999dc4, 0x8d0ecac074f06cdb, 0xe2f8bc656303fd87, + 0x414f6108a5bfdc4b, 0x2045f401498d233f, 0x59c2b3ce689c83cf, 0x63764f4b5efd4f42, + 0x016ecae6a3ee8d07, 0xea91c9ad87c17fd9, 0x5ed09ea73cc9b066, 0x4543c8cac5bd1bff, + 0x00efb5805777b3a2, 0xe152cfec419e9cc6, 0x3b72b71796713ea9, 0xc5f1a8b85bffdeed, + 0xdf7b719b3432b2da, 0xbec9b99071f6c9c4, 0x543ad0c354c21cc1, 0xcac5e9e1ba40e5f0, + 0x5d18660e82ebb52b, 0x2923ff54a443a934, 0x29e9dccf094f1f17, 0x53f9506ae0e8722e, + 0xbcdc48af90c65d0e, 0x70eb49ca8196864b, 0x299d6b2db0bed9fc, 0x9ff63417f21d4dbb, + 0x41cc4df470e341fa, 0xadaf80b9072da0fe, 0x30380882cdff5a2d, 0x203a724ef2cf3d11, + 0xf1b6247a39ce9b19, 0x5f5738a8a1d03e87, 0x90b0e16a84a5a6b0, 0x6a93d44f8801b84f, + 0xedde095eaf3dac7e, 0xbdfd17c9fa86c480, 0x0dc54dbbfb346182, 0x489b77d9d2f1471a, + 0x138a4d1a8c366226, 0x147b1c72102e0468, 0xaefe97255fea946c, 0xac66b96111baae83, + 0x5d9f2078e454286e, 0x8f8e053574d650f5, 0x90d24265e998a42e, 0x8fb6390b553579e6, + 0xc3696cfeded4005e, 0xab0b34410b7f035f, 0xac6c20c5436de821, 0x1ba147b95e0738e8, + 0x324a13024109c931, 0x367b54cbf159471e, 0x9656390469b5e34b, 0x162b67fc16ed9e9a, + 0x37bebe2e7bc7c3a3, 0x114afff4ce3025f6, 0xea5f04430b758140, 0x107475143357ba51, + 0x6990c64e57aa3a34, 0x6b361d5a6b9a7e41, 0x36fd8ccaaebac07e, 0xd22dea4f43bb2e2b, + 0x1fab5d8f2e7c460a, 0x90af3880cc57cabb, 0xef45bc4fed879ba0, 0x8dadaaecaf0b221a, + 0x1359a307e82157e9, 0xcb61fc76e547369e, 0x077044b9ebb11201, 0x77e14e6957b4c579, + 0xe5c903b01076455f, 0x531a64536a27c158, 0x047299b0bc695b21, 0x99a1225bc40063d5, + 0x6d8aedb1447125ba, 0x59a58bb6a5e83ba1, 0xe949e803a53775c9, 0xafe45d48836dab4f, + 0xe541e7b0f0aaf595, 0x33213d8443bd1143, 0xbe57d5655fc42d47, 0x0fca52426da3d296, + 0x42a25d6900f13979, 0x700a881ff48b62bf, 0x53549cade71eee8a, 0xd1cad80c0fcab540, + 0x1a28d60d63d8ea7b, 0xd93225138a1ceea8, 0x1f7a24a8f4c89093, 0xd43f17969e8ecbcf, + 0xeaaabe2d593c7bca, 0x8362d51f678717f4, 0x94eb5ba74a8aad9c, 0x62e9c960ba5773df, + 0x9361ffca9d5a565b, 0xf63b61944e4d9ddf, 0xebb6a8eca1f09ff2, 0xac2fef4ea59d792b, + 0x978feede090b4c3c, 0xc74348511404a2d3, 0xea78c5381b123ffa, 0xe07ba98e73373de8, + 0xf3fd19855ac4b090, 0xc9ea33fab40886dd, 0x033f76c4850f8cb6, 0x59ac9b2ef26ef1f1, + 0xd62cb5bee4db5685, 0x096614019fabe137, 0x023affd0041a82ee, 0x862aa976d8492839, + 0xc7d57c7c95974ff8, 0x063d7855b9c3490d, 0x7c5ae6afdd4e4e5d, 0xafdc17284d046195, + 0xfe8e762126513944, 0x23418cc2b191f9dd, 0x305d322d13054598, 0x928e8bced326018c, + 0x0e38481c20820c38, 0x507e8ea0362eb4d5, 0xf5ab717338b562d2, 0xfbedc27652c590cf, + 0x1f86588785cb8c14, 0x4b722bcc82cc0750, 0xb8993e3ff6c28648, 0x4a2a4299a4b26e81, + 0xb07ca4ada7046cec, 0xc3912167eb55e4b3, 0x6a14688e77e98af4, 0x8316ae85764ea338, + 0x86063ac6cea03907, 0x0867b176232604fa, 0x32456e3111248d47, 0x995bd47cd007bda3, + 0x9dfe41bf19cbab52, 0x4ea048d071fb4ecc, 0x8e451b99aaeb1962, 0xdebb87cf5792246c, + 0x657c5602d5d25c08, 0xe5eaadce21d0950a, 0x2535cf0348ba1f3b, 0xe084c652c4087199, + 0xc94b742108204a06, 0xc9d3d43ecd77f658, 0x11d611f60ce03ab2, 0x52cb41a05ec710b5, + 0x37d1edc7593097e1, 0x734f6bf6f24917eb, 0x1b75851482767a06, 0x51d7f44a22d52d16, + 0xc1bde8949b96ba7d, 0x5fe1818d8a80b7cd, 0x8bcbb20169333b26, 0x11f1f099bb28b15a, + 0xeb78ae13f00d980a, 0x317bf57b15093687, 0xab79d9a29116da02, 0xe88a80db454e4902, + 0xf4c6dbdb51eb0974, 0xb9de939f6000728a, 0xdb2c76550bf03d02, 0xdd02f4a481c24279, + 0x4495fe97fed9b1fe, 0x86ba5c9931909c65, 0xacfb55b66b6384a1, 0x896791d0a7a867ec, + 0xc4aa32f333b60dcf, 0x722f5f7cbb787c45, 0x1b8131da4436b955, 0x1c089511b522c565, + 0xd5094aae96729ec4, 0x6a43885794ca9742, 0x1ac3296c092eb33f, 0x85458fe8c224ba7e, + 0x173e27a1cb03219e, 0x19fe007729b89f54, 0x477ecc86c687dfc8, 0x738c5f9cf472d72d, + 0x40e124e10f49431d, 0xfaed40385cb78a3f, 0xe8f00ea3670d99da, 0x6378917e3dc37f12, + 0x429dc9197c616f03, 0xd26e8203d5a1aa49, 0xcd3cd57fbed18d2d, 0x4b116a91c46ef560, + 0xcc8ac8337e2de47b, 0xdafa613df0716a55, 0x9b035859df238e4f, 0xe799c1a41cd4e632, + 0x0c63141330d17ddf, 0xecdd13ef33a43ad0, 0xd99517e048cc7191, 0x3b56c619543c7012, + 0x177609fa53833e7d, 0x2cb391c61566638c, 0x73daa4adf78e0bcd, 0xd36e6e6458a1d3e9, + 0x77dcbc040605bb54, 0x354fe0358cd70c25, 0x6ecda5d3acc41b2f, 0xf9592022ce846a3d, + 0x3657752289770572, 0xfdefd35b68a30d34, 0xf3b02449888c1a86, 0x0936006c73c13210, + 0x212df8849a1933d1, 0x81406ee8542bf598, 0xd68d13d48e05c3bf, 0x9a0c6e5505b988d5, + 0x2dd184de5977ef43, 0xf8fa939abbe611b9, 0x9ff27d64d4784752, 0xcfaea34b86ac2f52, + 0x19b3af7140cfbcbe, 0x550c22ae24d277e4, 0x2e5d3d785b0afdef, 0xd45630eadd8a5fa8, + 0x832e04eaba267614, 0x4105957c9d20029e, 0xac4bec67eed573a7, 0x629c6456d93e91a5, + 0x17f56c680137c2d2, 0x915b27fcfd99ccf7, 0x7691bfba3d05abcc, 0x94c2ef3f0dd0c512, + 0x1053e8087efeee7c, 0x91b9e6196919f5b4, 0xdc04db132ee1a10f, 0x0731207ab585b4c5, + 0xa5878b0032944593, 0x0f23bbe0b483f2d5, 0x0e0abd6f1332efce, 0x2ddddf3a5ab1119a, + 0x6e69540a9500e647, 0x962f6456902b9b8c, 0x69054b8c34f555b0, 0x9e31574a90c78d8d, + 0xbe627136ff79a922, 0x4fe2dc09443071ba, 0x01a325e72c8a7ac5, 0x2ce819c80a79233f, + 0x78d8789f30d5d0c3, 0xc916bffd5aee7cb1, 0xe91a792af49f55f7, 0xedef20ec6e3f1e9d, + 0xacb01bc1dd4d4b34, 0x2627c73c78950bb2, 0x6cddddfbad727c78, 0x4533bec4100020b9, + 0x4d74af2abfb1c4d6, 0x2a90095eb6de0fcb, 0xfa08a9149fb49ead, 0xd548b3fa0f65f7cc, + 0x17f76d10fdfb2446, 0x4f6db589371230c5, 0x35fd96d0da4bb9ba, 0xe53616eb5bea577f, + 0x0c26bb429cbe9955, 0xadee469a1819289f, 0x5fba77ffd2b926f3, 0x2b2974ae7f275565, + 0x87152d4f145ef8f7, 0xc6d0ad47f3fde1b8, 0xb8621a333fbe6997, 0x1e70238096457ff8, + 0x939034c45d644ce5, 0x95e9b3b26fc10a78, 0x29a62fdb70395689, 0x9b9f480ecde3061e, + 0xb1c0125b53478f56, 0x714a8c3504b5d6cf, 0xd3124546314e9ab6, 0xe80291a7112762c5, + 0xf7c0422f4b7466ff, 0xcd593c68d79ea308, 0xe99cdc3925f857c5, 0x92087b3bcf1cc288, + 0xe14422c453945d9a, 0x79955436452e920b, 0x0db7ff75a64cbe10, 0x98969ba27fa4e17b, + 0x48e6bd608c79d0ee, 0xc4c69bce1fb7c836, 0x374bd53f85919f2d, 0xcc3494698b17fc22, + 0x83f4278fb35710d4, 0xf8abacdb77bf0a18, 0xb0c51de557728489, 0xe2659e5957ad2e83, + 0x708b26e76e91e799, 0xe80fc50c3a6f0245, 0xbc01c0ff6f22f4f8, 0xe1eda51ad0290eb0, + 0x0be4505db5e8d56e, 0x4b7d8a274d9475aa, 0x0e1df4606ba3f943, 0x8c743a37694180ca, + 0x95079fd1ec2e10bd, 0xf2f2ca5db9bd2d39, 0x6b451a304bfc8dbb, 0x61c0a15a7d616855, + 0x00dd985bb4f40e25, 0xecadc9ebd8890197, 0xd64d70a4f025a226, 0x2593844e4eae2383, + 0xea3fe387aef67ba6, 0x452fc56796c54160, 0x365463a8c04539d8, 0x0a9fd0ff080b1ef4, + 0xf0ef7f2b9f43a18d, 0xca41212f026ab8fc, 0x355684e7dffc4691, 0xaeb4eced4d208c1c, + 0xdba01f95ea794bc1, 0x15babfe5995b3525, 0x41a6c9c5f0b7d1d3, 0xc58f9c7d59c3ddd5, + 0x6a65ae80ee64947a, 0x4c23157fd1e283fd, 0x323549f40628033d, 0xef17418741dd2927, + 0xfd30096a9607e30d, 0xefe59e4354e8bad7, 0xf84c3a07557eb186, 0xb4a411b0fb841e4e, + 0xc3f28ef770e5ac4d, 0xb12f40696f8411d2, 0x6d53e23993b8a4a3, 0x84653b833df78b96, + 0xd7abd89069755f14, 0x4d7838e0077a7809, 0xb6b20b74c0842371, 0x6374af05240b49ad, + 0xaf45dc3f4a5cae62, 0x0454910a1a4e6c7b, 0x0cc531a42cc46f8d, 0x68e48ef638c20088, + 0x3d333c89a510ae8f, 0x5fa18d5eeb5045c2, 0x25e2817614aed3d3, 0x9d1e548498f4b4b3, + 0xbdf881a57a2fb458, 0x9709f0079b6375ad, 0x214563e52d0a2364, 0x513b821731adde18, + 0xe0657230d1bd78b1, 0x7d24bd04f9b5def3, 0xb19cde2239faaedb, 0xf28703cb65ab1009, + 0x12540e5681d57a15, 0xd2974fb7aa022b75, 0x3ef73adba37fc448, 0x6d6c71feaacc0948, + 0x062bba6136cd4f70, 0xebbba420b6dcfbae, 0xd9e7d204862be4a7, 0x6825a3fec58ff5db, + 0x4e0ba82cfb9fb6c9, 0x02f96a868aebbae3, 0x9cb467e2472d84dd, 0x9866166dc2c62970, + 0xca2ff48598759b63, 0xc1767f6e6c1f2400, 0xa60cd34743c05674, 0xd1101c43e82d91e3, + 0x06fbc95e3f24b934, 0xc8571d1769d79ddd, 0x7a48c74afe904ecb, 0x9910ad4f081413cf, + 0x892fba786df4d3fc, 0x57f3edd3edc540e2, 0xc27603685713e10e, 0x8fe0aab3f28f3ba0, + 0x14f453694c66c751, 0x80a0c9d4dba726a3, 0x046b37222f30a97e, 0xa7661709777b5ea6, + 0x71edc593736e88fe, 0xd26d67c6cd5fe6e6, 0xfb4e127b67e5c5f0, 0xba4d18984f28af8a, + 0x1c17dd1f9a942c93, 0x44c0be90c46994af, 0xd66f2b96ce390660, 0x26dc6df8911f91bb, + 0x2764f42ebf2e167c, 0xa405053c256f6216, 0x823bc2b7abec3971, 0x3dd61660702c15e2, + 0xaa0d3551c99b7df1, 0x060ae0da77d9e908, 0x24631f2a4dc507e5, 0xf4522a6ad69996f9, + 0x91784be06318cfda, 0xab71c8a1da86ce2c, 0x35604568d285f9d1, 0x1b25b1f75beb25a6, + 0x182fa1c7349178fb, 0xab69dd014a4385b3, 0x0ce77d5173e35147, 0xed6f6b9d66844d93, + 0x1d53b577be90628b, 0xaa3588338e1f0430, 0x03468a18bc1c2745, 0x6181eca9396138cd, + 0x589c73fe52ef21bb, 0xa5a8c3b6c72e36be, 0x6fd89cd44bc12fd8, 0xdd6fc86a5438c55d, + 0x1d75c3f15f4182fd, 0x99a1f954a2b2556c, 0xbca5296415bec8af, 0x2b50e4a4b74959be, + 0x4eb1aa8bcc66c4ec, 0xcfc8082b1c79fa84, 0xf2fb076c571ff104, 0x9f2dcfeaa40f88eb, + 0xcc4f8ac80089e216, 0x619c09be6089adbf, 0x9159dd05b75d1ba9, 0xfb0bf317ca2d662d, + 0xf0a8650a3c7cbe7f, 0x2e446ebb1cacfd05, 0x87249af16fc48312, 0xf38b302e163cab1a, + 0x3fa3000cbc94061d, 0x8054e8821056f182, 0xe956a56868a855b4, 0xcd2c13108730a5c8, + 0x99e43d6960d3bbdf, 0xef9848a17a6e8486, 0x5dc58dabee7ac7c3, 0x372393a414c1a497, + 0xcebbe1301729d06a, 0x2d82486ccffb68c7, 0x508486894f1b735f, 0xb10e55f560398ca0, + 0x0711aa19741156e9, 0x4148dafa30e5a84f, 0x86398a6aa5a8811d, 0xcaaef75a0e1588ee, + 0x55b1c3bfac3642d2, 0xe7ca19336e472e9c, 0x575f36de0ff72504, 0x0ea430d32b430249, + 0xc7ac9fcb03f51ee9, 0x9b21d2c0394e3600, 0xda8f3ea9cf822c97, 0xd758e8694b7a28ef, + 0x0f0afac6e7a8f840, 0x788c9d587a294800, 0xcb9cfd2ea371f939, 0x4a4c82051e9bc24c, + 0x55f291d37babb6f9, 0x9c56d1871ac83c35, 0xde0ef84a22d76c35, 0x99ecc1a6bfc1d241, + 0x9576e0bcd7bc84e4, 0xe9d894b013802475, 0xb371b02ea7382c25, 0xc078413506d09428, + 0x682d6b0c3f7f6ab3, 0x5fe30fd81c442baa, 0xbcdbdd8aa4afc6a6, 0xe12e92fe2b610969, + 0x0d95365ebe905e4a, 0x582decf9aaa4a2a0, 0x09613d823822c216, 0x9f2e75dcbeff816a, + 0x066beec86c0b252f, 0xe8b1c7c36f947916, 0xe972cb4c6a36f197, 0x9ff5bbbc0bcc4ba2, + 0x532c9663f7a9d741, 0xdd614ddb81aa9985, 0xce53907af37525d0, 0xf41c4a87ca653248, + 0x10c0380c0f9cd596, 0x2af623c7cf82ca22, 0x097c10728d0d4d4d, 0xe10c8575ed045d7c, + 0x1725b39fff6934fe, 0xc4dca568230d8d57, 0xb62f747b80ab4eea, 0xcc726630f6338e42, + 0x3fb197787da1705f, 0xe4ca65318a172fde, 0x86bbc89817212b28, 0xc0f0da1e1e8d2db7, + 0x16b2bfd9d4ae4b3a, 0x51b1ac596f804c0e, 0xfe4f70ee06caef22, 0x863954bac19efe7b, + 0xc8210e8b89f2a0c1, 0xb5fada191df32438, 0x2769ec6bc93037e6, 0x9b69d5000bf6e91d, + 0x91ad5d84e67e8f83, 0x2a7b76c699823bec, 0x9f251f2402c8613b, 0x01eb0dab3ca9a765, + 0x10defb0ed6f6a61c, 0x20547d3ae8d8f161, 0x209de984d3741c27, 0xf70df6615d11a6c6, + 0x5c574943e8bd92f4, 0x678828e6bbd5b04a, 0xfbbbeda95325b573, 0x44b2dd2a5d4e8272, + 0x705f0b479911259a, 0x775b1c34a3732e4d, 0x2a4d5ce696d861c5, 0xebf8945742dbbaad, + 0x4e8fcd6c7afa3a22, 0xd1569ed2de95ed38, 0x092126729e703f8d, 0xc8a178da320d0930, + 0x397a8eb8c272ddf9, 0x13b66902415dd6cc, 0x1955c9b1f51a8f81, 0x90b80b8022936e41, + 0x28927478e543712e, 0x83a58f53faf8b9d3, 0x80357065146c0e51, 0xc99dd68c97975917, + 0x8eaea0b78835389e, 0xe5083a63323150df, 0xbf08d905976b4976, 0x3fc6309b1092841a, + 0xda0718f54d715ceb, 0xd6eebbd808b8cf40, 0x87fe5793183a6ddd, 0xcd71162f58f4be90, + 0xbf1838ed40510a9a, 0x7fae6e7bd4feab24, 0x98d6ce71bd140761, 0x110724f62745cdd0, + 0x88e9e8e1b3522865, 0x0dcc639a015cbd1a, 0x5d4b30549bda2077, 0xdc48930f94b63f33, + 0xe2872bdc01f84efe, 0x222286d5c23d4321, 0x358e67a979d9ca7e, 0xc0887cb6d1c8a11a, + 0x582e0875359cb353, 0x48bea9a53fe11c2a, 0xa09a11aaa167123c, 0xf47b7d58a013fc6f, + 0x9b383a7e90d0d662, 0x20f5b0f910eb2bbc, 0x7deed4083e4f4eba, 0x6b4870849e7f292f, + 0x6a1d957c7c08e6ed, 0x737ae55672417c64, 0x42d218e8433375e4, 0xca8febf1cbe0f3d1, + 0xffbfc549366d89d2, 0xc70b8b88e6431522, 0x09d13a7fb8d6e63a, 0xa2135ca8b603555d, + 0xaef2b5b11d1ca07e, 0x9f718178f04b005b, 0xec6a7b1ebc75de70, 0x0a1724943e035d3c, + 0xef69900720b0f1aa, 0x070cc778bff41bd0, 0x9ec404ef6a026b89, 0x2542c310b30b8c65, + 0x94da2bbb622edca5, 0xb3178aa93ecf9e7c, 0x95b8bcf3c2f44439, 0x3cda672a42117d9d, + 0xd580d4ffecec500a, 0xe5bd43dc0e565dfb, 0x1675905804049488, 0x33af3666564f7a39, + 0x0ba335bc84efaef0, 0x797025f44ba7dcdd, 0x8e80b3ad682b501f, 0x6ec0774045055669, + 0x48fe08b9004b0a9d, 0x2704889588e7a8b4, 0x058f9fd38c8c2a51, 0x204f6619de89a7f0, + 0xf719c254158b655b, 0x9e2527b7697ca746, 0x61f57f54717d67bf, 0xc8796acf55cd415f, + 0xa6b25b685e370808, 0xa60ad5602cdd2aea, 0xdd7b16ff5d2517fd, 0x891648def546de90, + 0x9d40ce3c2f88c23b, 0x907d685764c2a79f, 0x5a1f9d94b5f0ad75, 0xca6bc9b0f04e233c, + 0xdef83a1f6e001b6b, 0xff0374579cf9cdc9, 0x37af4e09c3f84f96, 0x4d6cf2fe1bf4aa53, + 0xb01be863d99f03ec, 0x542761d4d4c2c741, 0x60711f5c46fa16fe, 0x99dfa17f2f2a7fad, + 0x6df2989376bc665b, 0x08caadb30cd74c7a, 0xc61018cd2bd8357e, 0xad024cb4c53d1afc, + 0xca389d437c82a550, 0x34bc11507c6384f5, 0xa4a1299caa112381, 0xc148a9dd1e06a3f9, + 0xe50b4421e7cfd8f5, 0xb27eb772f98b90f9, 0x73e663b3749888b3, 0x1879773525d4bd9e, + 0x619e5a17fd2ae475, 0x907a2d2874db9bca, 0xea59efb9876f5e97, 0xc299b41c4690299f, + 0x6b6a37deffda097c, 0x10d44f94e305813e, 0x2bfcc4adfcf6f59b, 0x4aff8b8609f59822, + 0x53000ee16b2a5bba, 0xfa8dddc34439d1b1, 0xa613a2499ddbe560, 0x49e381006024435c, + 0xb0e4ba1e77f2e40e, 0x23f7c4c13ca15860, 0x2d898324268d9a1c, 0x0d3e493be0516160, + 0xbfaf2a45f441d2d9, 0x1d46df51386f06bd, 0x4c2ce95016ac6694, 0x11ce62ed7ed9a1d8, + 0xfb31116ef5eb7133, 0xd02d61a61fb86f22, 0xe648a605f4aaef76, 0xe08d0ccb7d2420f3, + 0x3cb4e2a2be26edaf, 0xdef5e29a52fd24c7, 0x33ed71ad0409a6e8, 0xa7b258b969a2fed4, + 0x19df8c964ceafb8e, 0x1668074ba179b2b1, 0x18b3c4c10bb29521, 0x367b7bf64646d305, + 0x549be257f7341976, 0x60c659a426894098, 0x3de9a8be140001f6, 0x23ceeb49dc4e5d4d, + 0xf6e868b935340fae, 0x958519ed5ccb7b51, 0x389181f254fe31a4, 0x587caa6406fc57e8, + 0x4611a55b4eea5840, 0x07367e67b93e9444, 0x2b57d6be24100066, 0xf0564fa8dccda22c, + 0xbc9150b2a1a6c025, 0xe01f25d87cf3e3f6, 0x9e8b17c6d1a842b5, 0x73fd5f3e6a736099, + 0xdfff4b25e1abcadc, 0xedc02567d1eb6211, 0xb49efb946baecc86, 0xf8489b079b35cc38, + 0xe9998ba9a7b61c0a, 0x672369475fa2229e, 0x3040611b80ac9c43, 0x6b5bdd39a83fad83, + 0x17a13ed4811330e4, 0x2db0ad34fc00f2d9, 0x88e07b0593d5214f, 0x5e3c7374b2913d99, + 0xb8b49e8fb204b30b, 0x2b49f24e4cd04cb1, 0xc3bd42728c485b4a, 0xea92e5ac1e726457, + 0xf8aa43da6555ede0, 0xd48b9155ef1d770f, 0xe7044669d7fe7433, 0x89f7565261094d6d, + 0x75ca2a7e519f6a65, 0xe1932b7841d7cdae, 0x4330594b27c55fa9, 0xb10d94eb38453ce5, + 0x6aca2a7c7fb40917, 0xf389389c0f51a349, 0x211f83fb6222e8ec, 0x3a8ecfd2f687b355, + 0x581cb58bf30cc079, 0xbcec4c9f07c3b4eb, 0xb65ef4eb7e0793a0, 0xc64df68569179fcd, + 0xf2f3cf12493109c6, 0x1a4e19ebbba5a836, 0x908603224b55857a, 0x1d86e50746224ec5, + 0xbe172383597fd86f, 0xe039030e0483b39c, 0xe8e30869504dacce, 0x90ed50587c12c9cb, + 0xe50b29211e960b80, 0xc444e3d39423d1b1, 0xb93a69d722fe2da4, 0x59537f1ea1a79ead, + 0xf2b8b9cede84d785, 0x51b1616733d02516, 0xd83b507b297b29fb, 0x34dcc6f588c34344, + 0xc1ed35d691c15731, 0x3f3ece2cc6316a11, 0x25eea38f418e6110, 0x48f674b98beddc36, + 0x50985064e7173536, 0x13d7b40cd5a38241, 0x9ed88dab010060f4, 0x05c94a58262f2383, + 0x26b3a6b83dc641ac, 0x10697e194e403002, 0x15c2f089cfa17ad0, 0x07792b166becf3a9, + 0xa2175816a3ebabdf, 0x8e78b27cd1b0c8ec, 0x2f91f2daf873c29d, 0xef67aa282235d992, + 0x971fe33ed94afc79, 0xbdf9b59ff40a5fad, 0xb3aeb47af9f06e7f, 0xa03750e7bf7d8913, + 0x92c9de5a87ff4ffc, 0xf2ce1ea92135066a, 0xb70014b5f191a15a, 0xe1dd23ca96959073, + 0xc46b9a2da21177c1, 0x2e5379dbd76bddff, 0x1083ce9c6f98e375, 0xf1ead0d11899ebc2, + 0x0797299ae91aab4f, 0x187b8135a9126746, 0xde887667626991a2, 0xbcb9d76e1d7c42db, + 0x03f5f29c8042961a, 0x68a0335e50ea834b, 0x50da9df53df1184b, 0x5e748f0221fffba3, + 0xe5ad3db9b41b23e2, 0xe6b9cda13ba1121f, 0x50ef38a574132e0e, 0x1848e575096315dd, + 0x405d51036a7f46ed, 0x41f5a58e9fe42312, 0x5c175d2d8310504a, 0xb27f8b2b4579227c, + 0x5d62ecdfa14c886d, 0x9cc43f3dfb855832, 0xebd477fdd2576b33, 0x548639b35fc84e84, + 0x4dfb075af385f77d, 0xd89f09fee64381bf, 0xede8d1cb54c09aaa, 0x3eeb5fa0cb52d24b, + 0x14511ac77f2a4da5, 0xadffdd5ac1298cf6, 0x9788c0e098ceb2fe, 0xb5f75eb3eee49855, + 0x8a583f4edda300b8, 0x7cc1423ffdb48c7e, 0xd49d092b237aeff5, 0x22cb521d5a86c2d1, + 0x25e7ecc8b8eb93db, 0xd8624cb708d59967, 0x6c366db0e411ca9c, 0x1544cdb65879952f, + 0x02ff3b20977b2908, 0x3d891e9856da4347, 0x5a223a272f6930ac, 0x9d023a3f995ee81b, + 0x8c4bbbdcb81d0cf3, 0x703c26feaf2cfa7b, 0xb56bb404cc729853, 0x1670a13e755eaf3a, + 0x3fbb39edac853e55, 0x15f448c1842aecf0, 0xd3af03502e6d6495, 0x46a15766b8480f43, + 0xbfb3b461113f0e6e, 0xb11cc9e9939bffd6, 0x2ecd49c43e440de7, 0x7e088ff1e0496c29, + 0x1b9131f71bb86cda, 0xd1290e39fd89ce3b, 0x8b0d123cb2896a50, 0x46981709eb850953, + 0x1d9a8478d35191a9, 0x6296b525da70f443, 0x1924b949c32035c9, 0x9fa1c690653641bb, + 0xc3e20f20a99c4418, 0x3a1ad7be82507001, 0xfcbe24756a6cf124, 0x6dc14cf96668e2ed, + 0xa7849d04eaca6de5, 0x24c04ba701cdb49f, 0x06488d7fdfc00779, 0x9dc7e03065a80961, + 0x296f1cc01b4fd5f8, 0xe0789f8dcd13e149, 0x1be70cab6119a011, 0x680ed3b4c15903ef, + 0x8d6e1c7b6cbf21d2, 0x51cf5b7129bcda4d, 0x63e564eb2f9badda, 0xede14771c34cb479, + 0x9f32a400489def0a, 0x54a9b968775d340d, 0x3d8f2cf5d3ef7569, 0x6d741ae17755e7e6, + 0x6e130036accc50a4, 0xf321a97b144eedbb, 0x0b218d7c0b8432a2, 0xe27a7ed69125274f, + 0xaba91ce3e2a384e2, 0x38206f6295227690, 0xe15f152f033688f4, 0xb0dcdfc18c077c27, + 0x580de028edc38193, 0xd402986bf5d97812, 0x8df737e116f0e94a, 0x4a1882a9c2b9ccc5, + 0x0841926aa17a1b66, 0xcc73275243da997a, 0xe1eb4e91682e8f16, 0xc2d234cc31b17b1e, + 0x45050f6cf72e988f, 0x67cdccdf8787bcfc, 0x7a9917bb86dda5fd, 0xa6a1adfcc814a06b, + 0x60254ec1069e3f33, 0x5d298d0572bb86a1, 0x38090c8f7031c173, 0xb3e22fd5e4b4d765, + 0x79de384d42c3dbdc, 0x4c1363bbcb0890a1, 0x21ff97a3b636638e, 0x6b2649436e3541e9, + 0x7d237c746fec0597, 0x6c2a8d4884eaccf6, 0x86c83237ad82ca8a, 0x2368b2fe8d391173, + 0x231e32aaf842eb2d, 0x31863f6a4b21bae5, 0x85812a54cb34e40f, 0xb661d5a62457799f, + 0xc41ccdd646284643, 0x40798887853ef30b, 0x77cf7e7006dee320, 0x8e3d2610342ce3cb, + 0x9bae3aadc77e658e, 0xddacaaba30b0ad7b, 0xfbe7a0d86bde9f65, 0xe4c431fef5b404c5, + 0xb0f1818fe5a28f91, 0x40ec268093b282bb, 0xbb9c3515d03aac33, 0x04284ce13ecbc32b, + 0x3efafc8d7e4484b5, 0xb0e9ecf288696de4, 0x53dcbd8362f087ce, 0x95edd2039da74d09, + 0xcd9841503a2de2b8, 0xca119235e1a48983, 0x648401a8ec010a46, 0x05d5833c6dd04e90, + 0xfefba4ba1c26c16c, 0x6d902dc635fb73bd, 0xa749fa1f8e2fb704, 0x6090416c653f598c, + 0x0a05fb7a436519a9, 0xdf438dad8157684b, 0x0392dd61c2a20633, 0xf7c3e258f979d38d, + 0xf8b6f24641257716, 0xef1f38850e2d5b85, 0x6de223a51a95441b, 0x765ef525077b0165, + 0x95cde52e4f032586, 0x030c84e39b53f3b6, 0x5d1e545a035e9d70, 0xdfcb7156afffce7e, + 0x20034070a59ffeaa, 0x06b738a27b34fd50, 0x4557caa68154f25e, 0x9f2d101b4e2eb1f8, + 0x63b48bd4859e9454, 0xb20daaec7761bdab, 0x665d913c3972257d, 0xbebe255fb2a63e15, + 0x8d3379848a2e215f, 0xf13ed2c7d540743b, 0xaffe3edd26a1e251, 0xa134cf0aba0b3fc8, + 0x9054715d3e1642d0, 0xf8eb4d5ad56fb1f7, 0x7088e87e86069439, 0xa854342b78191112, + 0x3e62d3c4deb55ff0, 0xbdcc14007bbbdd71, 0x5c4c5f3c56f9a142, 0xf2dd3b23863e4165, + 0x121cbea4a6c74e35, 0x1ba594fb84bdfb4a, 0x27d3c4b80fae40c5, 0x737ba6c92731ada2, + 0xf758e56511a2fad2, 0x84e8e6c43f696ccd, 0xe64b3f8c716ed3ff, 0x97d2c89c8adc062b, + 0xd8a9178b507c4f23, 0x9956ec6bc3732b67, 0xafca4e3f243529cd, 0xb4fbb09dbb1f8b8c, + 0xed6235608561637d, 0x114cd6fc6e81b4f3, 0xf6995b871c66eeae, 0xc86b62d1bd820e63, + 0xa27a44a27c7602b3, 0x98151c09c0f8f098, 0x525af701c07d5526, 0x845b3c52bdfd9ca5, + 0xa4476a40e617c001, 0x59415a274f87e3bc, 0xed47390f56a18edf, 0x61f5a3fb5243ac97, + 0x2577accf8281d599, 0x2c6e5c44b0f7e6c8, 0x5ea760e5a5417839, 0xf887685c2c51c30d, + 0xebb973b68ba94904, 0xb53b96f406e7a845, 0x9c0141d9586f6708, 0x2372cb9566405dec, + 0xbe81ffe007472e07, 0xd57485a42158db08, 0x246d6b0ba4de9542, 0xd52a3d1668cd6797, + 0x599e0def72521bcb, 0x6f2015bee2c79930, 0x4e48ff8304aa99e4, 0x69abd4d6be31de5b, + 0x6d0668d8cc862225, 0x2107e1c2dc41972e, 0x9064ead282b6143a, 0x9ac81f56f84948ee, + 0xd271d2b576b851c0, 0xb9d6a648b575f305, 0x59e58b8c4faab3f7, 0xd79cf6148e06e2ed, + 0x0adf890935d2ba7b, 0xb64f002019b56c9c, 0x13436b2427cb2138, 0x2deff3278cba08cd, + 0x8776afc11c5fad02, 0xce45e560e3a630f3, 0xe12b4c7868d82f1e, 0x43ee809aafbdeb12, + 0xe1338ad3b27d6ab0, 0x34501882c1b0050a, 0x5314d75ed582809a, 0x62e4c5ffcb21412c, + 0x89d6e1548b84dfe9, 0xb834023527ef16a8, 0x513b6c4e4df76f7b, 0xeaeb9e75fd366691, + 0x566eed9658604f35, 0x914fd437810a29f8, 0x42a6f2bad6e66fee, 0x273efa72614c7952, + 0x2e7bcecd83f1887c, 0x47eb7d7fb7b62934, 0xa9354446b3ee8d5b, 0xbf31d548190626d3, + 0x2917a36f65a9d8e5, 0x41b8ef2a4c475788, 0x4fcf91eb211c1199, 0x382fb895e69ef4e5, + 0xa67c86bf1c09a04d, 0xac3bbe467eaee4ab, 0x4139efbf89cf3a72, 0x75a60bf927d1c5b7, + 0x381ce3c10a587cdd, 0x4f9bd21f98deef12, 0x563f76d8f42f2720, 0x673c32bd844b692a, + 0x71490248bbf44500, 0x64f8afe48b2982f3, 0xde55e33138790831, 0x7e44f567d3e9f792, + 0x86c2b84b957c60c4, 0x50e677c6cfa66ca6, 0xdd1e35bd8c854702, 0xbd7cdc7082d2e585, + 0xa4d115541e1ea5c5, 0xf9c42ba5eda4a6a8, 0x30b37b768a97b9df, 0xf188177d58ecadb9, + 0x301b17f838820361, 0x8c920ac6e4982023, 0x28a32691eb5943c5, 0x6bfbc0421b50ea92, + 0xfa58da76e40a06f6, 0xf6e5fefa4e87fe9e, 0x60b0fd07764de7dd, 0x06467bd66af100f9, + 0x4dbd5de0c0cdecd1, 0xc198e0830ad7ace0, 0xb1d34a15dc21ca3b, 0x1fb46b463e9d501c, + 0xf5b393f672a5be61, 0xb6fc615f0feca44e, 0x5fe8f4b11bfef636, 0x9c2f96f23a545699, + 0x2125f827499f75c3, 0xfb5931977d316f73, 0x530e981579fa759d, 0xdd262499c729dd6f, + 0x9406070586e7a739, 0x4733b0705c8f8934, 0x23083861eb42c82e, 0xf64194ffcd3a9e53, + 0xb5afcf9ec729acbb, 0x4413284cd32070ab, 0xbe89a94ff7c3592d, 0x9afa2d341a40ae54, + 0x3474e0cadd80ac72, 0x4796c588f37a8afd, 0x0f6a2a67df8d8aa2, 0x6f2133418347b5f3, + 0x2d2160bb14e18e3f, 0x5a4a0ce529dd2232, 0x6bb38ac0c784b734, 0x3a02acab3e957bb3, + 0x4b234a8d134b6568, 0xcb5409bcca78ed4d, 0xd1faf6bf0deff0d9, 0x8c5ef01d9ade5900, + 0xc9a3df41ed9d66b0, 0xd5db7b7fdf41805b, 0x1f1a5e47acf60f23, 0x1a8d2b57e749930a, + 0xf1dbd5bdac7e27c1, 0x3222b0ccde01e28a, 0x53a102755e01d5d7, 0x1e53a3daf7cf10aa, + 0x4343a3f1c5988fa4, 0xf5f7af0b90941501, 0x433696e28b1c350f, 0x7f1a3c4a785924c6, + 0xb8c83eccae0633b0, 0x5b9bfc7ef4fcc118, 0x6e920f33bd31d9eb, 0x181cc425c7f44999, + 0xeea5b29b2a38f61e, 0x24e0d3f28a5faf99, 0x5a091873a0bf9a77, 0xd09865c8a2dfa6b2, + 0x7d7e9b6484341bb2, 0xe438337be793b481, 0x4fbbad997f25e4c8, 0xaa0f6b2458eeefd0, + 0xe371650aa4710886, 0x58e99145d5893423, 0x5ecb9f9b684fd9fc, 0x8f760b3ea4f028f5, + 0x563d06c215f2c0b1, 0x791ef3d0fe50c649, 0x9365b9298ff52ee2, 0x41b3e25bfb189d6b, + 0x53b1236f167bc5c1, 0xc1f82c0e18b02f40, 0xff093d103c613b8a, 0x4804668950b19b75, + 0x283e23aa110361a9, 0x75e38ff473b0ec0f, 0x09bd491699e1d2a0, 0x710aa351654364ef, + 0xd3c347e8793ff3fb, 0x011d3a5fe13e613c, 0xf9929f1f027a9b7d, 0xe2f1afb37deeb058, + 0x2aecd9cfd3231c29, 0x391ddd36d82662db, 0x242892e112dca5f6, 0x540af1828f57d0b6, + 0x1299c2a10000b3a5, 0xc1ae9b44078e7d73, 0x733d03c683dd93cb, 0x6e07e9d57f92f7a5, + 0xb766b5823f7b35df, 0xbb8a7effc5da652c, 0x75adb16fce9b4681, 0xabeb12f915153942, + 0x072a56daa586c243, 0xdf63b2bed4ddf894, 0xf69b450451b498b0, 0x7c3e2cc4ef5b482c, + 0x2e31da92c8fb8181, 0x5d7e68fef025454f, 0x5e2a121cebdd4a4d, 0x20a6736e76af0645, + 0x4d2077205687b67d, 0x863094ac6d96ef17, 0x2fee2b70e997d2db, 0xfeefc7b0f0a4940b, + 0xdf5cf6486d5cff53, 0x18d1d6d4f209d95a, 0xdd66772fed6faa37, 0xfe884afab2e16386, + 0xa4f9e17a824db151, 0x0809783e6502b913, 0xae679da17029a35d, 0x8528ad8bee4fa73d, + 0x835f1699225943ab, 0x6be82fb1ea41cf46, 0xf72d79cd5ed44bc4, 0x2dbf179cb3e611d0, + 0xd7c5d9779e177a27, 0xe52f2cd9785f4b8c, 0x25ca2880349ede53, 0x8f452e179c8414e0, + 0x0ec1c02bdd5ea308, 0x8466e11593b6c17a, 0x664503515aded236, 0x94b3597a5b118fc8, + 0xa7d9b75c85091291, 0x5478a0f732597115, 0x9e779746a30dff5d, 0x4d809f865fc1a5af, + 0x8ed3dbd364c89be2, 0x2a91007e1742803a, 0xf5782f25dc4c625f, 0x1691dd122e1a954f, + 0xfe4ca35636467544, 0x89faec0404649698, 0x2d59d0ad031d79df, 0xda28bab16fa6ccc0, + 0x5abf25b177e9c7ed, 0xbb5675ac15df382b, 0x2613d5b6188613a7, 0xbf42ebfd48eea069, + 0xc7efabd1e74c538c, 0xf7a061c898bfd88e, 0xa72c1ce1c66e5aea, 0x2b6e2523697f8a2a, + 0xdc181e273a66976d, 0x67e1b8321596a4be, 0x47b610c557867d27, 0x9ed6d5c8b9d07005, + 0xa00278b16aa9149d, 0x8291565e01274cee, 0xba3ae4ce261194d5, 0x42fb64756ca82d86, + 0xadb3b525b9db1714, 0x7699f13a1ae2d3a5, 0x2f75f93326dda802, 0xa72f256466174d04, + 0x2c027126765db09b, 0xfee8d1ccf8bf559c, 0xd0253579c028e1f8, 0xd0e772e313ba5ac7, + 0xd61c86fb8cd5c05a, 0x0096b73167c79e44, 0x41bd740321d7d35d, 0xb3b9a269b45c46d4, + 0x95f5d2321282b6d6, 0xfba42aa1a975079f, 0x7c6366ca83585cd2, 0x4d9257b6bead31d0, + 0xa7eb3a8052e82c20, 0xa6bb242612e7f42d, 0x908156b5a1b3c0c2, 0x5ab963de9fa184e7, + 0xa042c474c6cfc4b2, 0xfdfbbc40d0bba95d, 0x966f92fc17760083, 0x41ff0a1dc916ca85, + 0x33091cc11d4703b4, 0x8ca400d729c16899, 0x845b6f162398443a, 0x2d7128d600fcd4e0, + 0x0e3e02cb1a15f4cd, 0xf0c25d7990d3d2b5, 0x4348f79dcb3b8419, 0xbb4564b87c73320f, + 0xbfa65673f34bd4cb, 0x586aacd9077bd2b7, 0x3d9aaadb6e2bbb39, 0x0ff223fd6a090454, + 0xc2e8472ab94c538f, 0xac2b10428c1d774f, 0x11f150ebafbe0d6a, 0xeb22935171500230, + 0xc4e00aaee7f32576, 0x5cfafa2a98e5bda4, 0xb7fb2ab020a5a893, 0x7d9ed6f8d176098a, + 0x1c24a7ca529008d5, 0xee476b7a879049b3, 0xb3e7405a408c71e6, 0x1673786d415c6328, + 0x4f218834bb1f36e8, 0x84cdca85e36c968d, 0xd53e60f48ed3a73d, 0x017c5ac42aa0ec2d, + 0x128d9d616e5c1737, 0x96b1704c5c29f3f8, 0x96e84f79dd7c18a5, 0x42e244571b6d28f2, + 0xb4866840e21da423, 0x37259f151e76c0ed, 0xa4a97f5cba8659fd, 0xd9249061631fddca, + 0x086246d6a1440c16, 0xc04414b53d8ad38d, 0xe8bd28b67dbf837a, 0x76b6aeb42803e652, + 0x6540ef7c8140449c, 0x60ac238e69602689, 0xb24cb4c71a76c46f, 0x3368407ce34d1926, + 0x94124d68dc4921db, 0xf0a41f0f2fa7f999, 0xcfba95e1313f6630, 0x32477b6623841b1f, + 0x17645fc84e8d3a8f, 0x30d31ea542f6a937, 0xcc070478e478cdc6, 0xe81f867d5e3d107d, + 0xcdbe21d501785077, 0xbdf9cd3ed8c61668, 0xf2b33997a8e1b19f, 0x58f7e9161f113d6f, + 0x085057db45cf73c7, 0xbcbb2a79cc8405f1, 0x4e9955adbeb8c49a, 0xa81b06483fe6ccae, + 0xf72ee3ecdc41783e, 0xeadea722277d70a5, 0xf3cd15e86eb993df, 0x2a1bff1299088219, + 0x70428b993edbd370, 0x95a4e4f141ddac15, 0x5339c037e664ba75, 0x64992443123898bc, + 0x6b2c080e072fce92, 0x2d1a27214c304b14, 0x07dfdf091069a02c, 0x4dcaf67db789ac68, + 0xca57c5c4c2df63d8, 0x7462afa8f769a6c1, 0xddf6949f1cc15270, 0x902f1a9dd127d5f1, + 0x74f61e475a3783a3, 0xeae8e181e130c9d6, 0x523be69b82f4e501, 0x9c0cc4cbe6231dab, + 0x085fe4c45e8abb81, 0x675f9816fe882ddc, 0x87a765215f129b90, 0x247b734b7c3e010c, + 0xddd60bb0878c24b8, 0xff102dff480103c5, 0xa061b74fddd72001, 0x023a0c969420c32b, + 0xaed5dca6f671b9a5, 0xf714cde311c80712, 0x49bdd42339e05038, 0x2b7ed3345f6e5932, + 0xd2381ad568aacac0, 0x21bd606150fa7eb3, 0x2aa8d3953351fd2e, 0x9e386456e3cdb032, + 0x0f501078a9395bed, 0x0e826621e4576abe, 0xcc599786ca6dcf98, 0x1276a79d5495f597, + 0x398bb8493e2d9b79, 0x6def1dae77b76db1, 0x8fac7487743b24ab, 0x46947d61a1aefd1b, + 0xccbd9756e9277f32, 0xeca045c555d198c3, 0x6570fe5e8b089c69, 0xec92694f50c2ec75, + 0x4e49e3dc17b2275f, 0xc554b865ea361c5c, 0xd8e42c7f805f5704, 0xab89590f65dbf0c8, + 0x4030825603646061, 0xabafe99b4c5f31f5, 0x6d30538b8c06c50d, 0xa4088aaec3c6f505, + 0xf9eba4bbf02d3377, 0x8f05e855e5d1a504, 0x76d474bb9e965faa, 0x670c0c7d0fbeebc1, + 0x1e2f078c86acdb4b, 0xc708f4ba42ce0455, 0x9e516db0703c60a0, 0xd9a4ec1bd7fb1a00, + 0x3b7483a3caa5c287, 0xc2b6d5460575e31b, 0x17c167aa0fd6a584, 0x802d49e9a8bdd8d5, + 0x73c6200b8a1a585a, 0x563ece8855c224a8, 0xeb0a0040edea7efb, 0xb2a2413d768d7d76, + 0xa651f857c7cd14d1, 0xcdd0417468a3ae62, 0x0c1b4b5deb592abd, 0xd63feda402a0fbb3, + 0x890a75599e60e79c, 0x2433fcdb19761a3f, 0x9623e6aa0fa6a035, 0x76d564e4ad912040, + 0x99b49075b232797d, 0xfff7607e45372c4d, 0x6477c180dd6d8829, 0x0a0df16f8e506b61, + 0xbe34bd6a4aa4ba00, 0x54b433d3962fc784, 0x940cdab5293df29c, 0xe8a7712823849dcf, + 0xb610cf0d5e6e36e0, 0x68aa76b26d63d904, 0xb07b95118235ff17, 0xabbe72a41bbf6937, + 0x4335102116de6c95, 0xf18468ad9fc60850, 0xbb109e4a6d63982a, 0xfbf576c7101c19a9, + 0x48c645d2d42580fe, 0xe4fbf2c0003af10f, 0x7ab4d6fae3e17b06, 0x19fa6886e1906a40, + 0x229074673a955a19, 0x5d308012b518b165, 0x67d153a6c5088361, 0x98bad801cce60366, + 0xb45e9247bb364c29, 0x29dbb367a543427d, 0x02332528d45694fc, 0xdaa97eec6762a0ea, + 0xc685c6a545998461, 0xc14af1a65b000a5c, 0xfbc934ac98f97b8a, 0x98988099d629a7d5, + 0x0f35cc4f16125948, 0x3e96c4eecb45828b, 0xd3776b91c76f5733, 0x4e8e260f4c5e38b2, + 0x58ee23fed9b1baf5, 0x9c484fa82ae4c4db, 0xaf8c61dbcc295939, 0xa3712e0577317725, + 0x053d7a7aa60c88f0, 0xb6685f17bf9d3a8f, 0x4bf16f93e649a772, 0xc2045f3a9c720932, + 0x65f05cc39d831146, 0x976134fde4337450, 0x4e2ba081b7e50f42, 0x8e5320c951916a0c, + 0xf71cabc3b97534de, 0xf108ba882e62277f, 0xa3276d81cf830d0a, 0x492ad5c08177ce90, + 0x5dc6863f5b4ca83d, 0xacb7154e38190d42, 0xe688889b2244c780, 0xbf5f200b255aa3e8, + 0xf7b2d764a44b4b29, 0x3ba21e3c0fb76665, 0x92f2c8502a368540, 0x670e239fedbae5f4, + 0x138d8794bb2ca459, 0x7e4d1bce72c28b01, 0x2668de28d037cffe, 0x1d1ee3819c7a30ec, + 0x33c38d38e7dfea3f, 0xbb0972c93799a8ff, 0x6f5446a6ee33af8a, 0x532bec51fd252b1a, + 0x9b366b5cf86dcd33, 0x908d470754de3d9f, 0x8ab904a52cab7663, 0xd038ac05220b1b14, + 0xb5ac4321bc5d24ff, 0x9f92f41e6ca0ecf6, 0x9e7d7bf762790456, 0x45f423a19152927a, + 0xd681f8e0c1b1e681, 0x6ffe25c099487c8d, 0x9f1c31f8d4b7352b, 0x2362078c1f65c57a, + 0x3936cc72ce47aa77, 0x6c933ffcad73be3e, 0x37ed509053bcfe0e, 0x3c9076fdab33279c, + 0x065f743fdc22d071, 0x0d7e85751de9d8d1, 0x280c10b433277fb6, 0x4ddf26c8f1049f57, + 0x5f25cfeeaa3eaf51, 0x4cf4ec3be1c93924, 0x4dcffc17c3ea2177, 0x20b02b1b26328e57, + 0x3646e9de6bc8ad25, 0x786eae906e01fa14, 0x77d72c30daed2b39, 0x974cd08716b770d7, + 0x3c1e6f872fe81c53, 0xbb7f1deaeb43ec79, 0x624b80a122cf6839, 0x49d210183ad3ccfc, + 0x6aabd6e98fc434ca, 0xb36aba7a255bb1d3, 0x9732f2cc61a8ae3e, 0xfcc68c2adaff8706, + 0x1edc8ba4898cb7d1, 0xb5ac15cb166e790a, 0x3351915a051ff1cb, 0x97bcc2f3d801fb2e, + 0x1f5c168df0422395, 0x4cf59e3ba5871480, 0x8c4be52d16de5f1e, 0xdfc3b0c36d609a1e, + 0xe4da2162b0e595f5, 0x5911f0cb5855085e, 0xd00fca7a498bbbe6, 0x58b3d3c2dcb3c6cb, + 0x13eadbb24291aee4, 0xf3c461a0c662f645, 0x7d2350b72d61df99, 0xf8d63b1d105c7988, + 0x7af7b87dfe9d02f6, 0xb5180fd00f01a679, 0xb4d5bca520722f7c, 0x12b6c0b6dcd7b46e, + 0x5eab7bd1edbd5bf1, 0x9b18f206a7f573ee, 0x205d2eb585299908, 0x8b64f5099613105b, + 0xbe74c37875789ff6, 0x92f4c22b04d84c0c, 0xbfe400743d558510, 0x5ece784a4cc21c13, + 0x49e7322371157e61, 0x3e17e47ba80f660d, 0x12e61375f5752dea, 0x9e506f23cc1f4041, + 0x066a4a3a44f86424, 0x0a60b5c5eea42566, 0x5af39fa11e5ea0b2, 0x2c6f192ffbd29655, + 0xc269ddfbe928fcfc, 0x3a96639475a4d2f1, 0xbe2a7b982ee497cb, 0xc074ec700915e3f7, + 0x4d4d450f0260f53f, 0xb6a9c3ca5dd3d39c, 0xbfb5b9ad60102e0f, 0xe386084cddc8eadb, + 0xe295019000245b4d, 0xfaa02e40ea95b332, 0xe5531beb1d40e432, 0x7ee078e1d15fa02b, + 0x015ec6e38c87a50c, 0x954c764681f7a062, 0xaf3c0df0e81f99b3, 0xec80287c9170b38a, + 0x1f5538b9575ad5a9, 0x686db1e4e6aafd36, 0x81c85254fdf4d70b, 0xd3f7562a75c1b114, + 0x8e3aeda89da24bbb, 0x9bd4927db732583a, 0x47f96c3749de4cb6, 0xf557ec01beac7dc1, + 0x89cfff6753e1e71a, 0xcafd46092c7c7a00, 0xbda8d2955d7cdc75, 0xdc658d8ac71ae85a, + 0xf6222763ad444d80, 0x31b3cba10565a282, 0x9471954e8cf3d8fd, 0x9d1d2294213e82c0, + 0xe264caf5902b3520, 0xd3e384827ab1d8f0, 0x22c1cdb484029f4f, 0x53b07c637068ff4d, + 0xf3e2ec54670d8169, 0x1367dec986477371, 0x85a80e8a06169dbb, 0x352b67b9e7248fa0, + 0x41c771850ac6f24c, 0x96a5f41163640ce6, 0x583e94313b442f2d, 0x9119db28bd0c1256, + 0x5e7ebd232265fefb, 0xa5b6b6cd9b3ed589, 0x381a000f59ed6ea2, 0x08c63eb903e0ef04, + 0x52528e0def72dec3, 0x235fa0594c0175fb, 0x443473747d16d6ba, 0xe6ba1816f4e81d71, + 0xc52c269b9df759cb, 0x1a42cc36fce01a2d, 0x3201ec0a611c7f9e, 0x5835848cf56d69a1, + 0x46e7ad4a20a895a6, 0xe7b9943c13a52892, 0x3d2ddb9e8f898c46, 0x90b2467bcfea2c1a, + 0x245c12c39fe5b875, 0x1912f655d8c7f863, 0x713fb253035e6aa7, 0xe93d48b13d7db94f, + 0x2714ab912028dbb7, 0x57058dada56592e1, 0x7904f129190d0c0b, 0x4c77c4691629737e, + 0x11d89ab172ea1d24, 0x752fc3d0c468b9bb, 0x172a94f1862c7721, 0x95125e1fd0b16e01, + 0x4d548681bca4cf31, 0x9a1eeffb6e413e59, 0xbfb83e42ddc1ee03, 0xd1cfc5549279e631, + 0x5cfc8e12b5f0da52, 0x70899ec9bdbc7182, 0x0020e1a5e4687184, 0x6029b4bdee4ebe7b, + 0xae3c575f3d00f559, 0xf9ff6baeca1f92a7, 0x9846f96e736b2582, 0x12407dd9fd565e76, + 0x44ae6dc391154dce, 0x24cfb39f74f62354, 0x423eb39c4ee9507a, 0x525b8648273d5da6, + 0x08c6206cea681dba, 0xc3e38cfa154d3c0b, 0xa2e955c843079d20, 0xde17c095d95633ed, + 0xc3577cd7aeb59135, 0xfff2f1695ae3d076, 0x57da54c4bb73c6b5, 0x4620dadbf64c2728, + 0x9b63ef766d514b98, 0xe5947230656808af, 0x0c4611a8d4595383, 0xde8fe2c3c54ae7fd, + 0x6b251ef515cc66df, 0x4cad0638e91e9fbc, 0x262c2460e8d8f845, 0x831cecbf8f62df38, + 0x2378082b1ae861c7, 0xe84685174ae5e3c0, 0x1f05368123d194bc, 0xc6be55029b5c5214, + 0xa68ee1bd0028df68, 0x1bdf8086e0945a96, 0xbef6757f8747a107, 0x4c6b7675e8f464db, + 0x2529f40830adb2ef, 0x26feb8baac572e33, 0xbe68e6e7a339a7eb, 0x9c9e72b363d369a8, + 0xce8f7c5c3d2d525f, 0x731cddca25ce4433, 0x3360076f92182ec4, 0x337c968ea1de4f95, + 0x3f2f097842ed09c1, 0x93b0f8e164c795b8, 0x15e3e9e28de26ab8, 0xc47c402a0a693551, + 0xb1790c3f2919727d, 0x7127d8ad1970833e, 0xa5bf2e0ef6cb99cd, 0x28a42c14e20f90ce, + 0x4c3d83e5575b8890, 0x50bd3ec7e130a39c, 0x1db891777191da03, 0xf82e3d7fb9265f1a, + 0x8702324f34b7b4e3, 0x1a3e56bbc85bbe5e, 0xa6584b86d64a190a, 0x952c8aba7e6dbaff, + 0x4f6c77460278d46f, 0xf35ee7d808cd80f3, 0x3d41cab38258bb70, 0x9632d8b60b8f8a52, + 0xc687417308791655, 0x7b8518d529a5f7e0, 0x088ab1c978ac7c1f, 0xaf2d05ec2ca77731, + 0x324c49e681c84a00, 0xabb5f914edcf5258, 0x82e56965e67cd033, 0xe08c44305853a661, + 0x58e301fb2ed803d0, 0x12b1726dc24e932c, 0xd3e9d4ce5895615d, 0x5a0aef1e9fd7a325, + 0x0404595bee9e3392, 0x1a705bf411f63ced, 0x9c41dd9d43e92ecf, 0x3e964aaa9e83c657, + 0xdde2974aeefdd469, 0x45e6aeb86aabfdc3, 0xaf810fbf17329e40, 0x0cd9861f2f803dda, + 0xd7e6b5cc4a44a6ac, 0x354c739599ca2989, 0x51dd45c3b7438f45, 0xc18252f61c6e1295, + 0x8f9ed53c0d66a319, 0x641db9fa4aaf3d8e, 0xe3c8e64b4773a518, 0x300f3c820aec5ab8, + 0x3f626c8ade367348, 0xb57b459f87b35fe0, 0x3c55c637f5cf6da0, 0x88ede31e766015c1, + 0x706c31ab43e05f78, 0x57ef70ec3c6f0342, 0x9c3d2061322a9ddb, 0x5d793c8f81b071b7, + 0x753c1350a7b85828, 0x5c28dc7a5be38a29, 0x699beb979af1546a, 0x53a76100107b079e, + 0x9445880c8dc3fbfb, 0xabfcca75384f2bac, 0xb119a0494642b8e8, 0x44aa6fb866e65497, + 0x5d1761d932fbff43, 0x362f71284b71e7e7, 0x5b3351ce6dbed3ed, 0x8fed7aff2664b9e5, + 0xe5faf83dcb1648b9, 0xb55a8bba8ea4e7da, 0xb24005c2b13830ab, 0x36c14e55285b1feb, + 0x87b05f29e74e9990, 0x6b60856392a33d96, 0xce8f177cf9751c8c, 0x8d8ba4626308e8e9, + 0xfa6f947d5f0ff81c, 0x98b564d86cfdaf40, 0xcfc2c17c700b294e, 0xeaafd1c9c9ef2bc7, + 0x0d951c41490af34d, 0xa6709f1abb95f676, 0x4015a6ec249ee4a7, 0xe6889aa48db8d43e, + 0xedaef60e34a7521f, 0x8ebe5259d1a1a3eb, 0x2b440b6f8feb74bb, 0xe0aace7c555fbba6, + 0x3089afd561c53c27, 0x64d363bd2f4298ec, 0xe99fa96b6fe1fd02, 0x9ce8ed7559210412, + 0x6c491230ca6e8547, 0x4652f83544ee70ac, 0xff646a622f77c3a7, 0x7708b53e3b239292, + 0xd4634354abb0f9af, 0x9ceaca26df6b9e8e, 0x85849c997cb431df, 0x483cce1b12db34c8, + 0xed56d12ad5112b79, 0x0d632aadcbbdf80e, 0x70edd711a33737da, 0xacbed8d424da0b52, + 0x211c0f59d2a879b3, 0x5970039203d5bf4f, 0x2aae7111b77aa919, 0x9f80cac3a40ebd61, + 0xadbc1ce2247261d3, 0x8002bde45fedc0d9, 0xbfd89769234c93d2, 0x2c698508b011c283, + 0x64c425a3b8023a58, 0xd6969d1c52da2a18, 0x70071b8522e0ca4e, 0x21870ac7175596ab, + 0xae89ca1f5ab6c092, 0xde0ced8f36a0f775, 0xbb6f308f9560bc9d, 0x7e980ead1f356832, + 0xfb6a447607a48d9b, 0xf8a0a1d2fc93acb9, 0x29896860bc83649d, 0xf2f155d09e48d512, + 0x36bfa958899afce7, 0x9d942fcc07a357b1, 0x94a0f459a2ab1a3d, 0x983ad53f8ab2d697, + 0x944e1ef67c75ac44, 0x836511af3e8ec5f6, 0x109d60cb24c301e9, 0xd1bc77688552287d, + 0xef4806a963941d4d, 0xbfedef941f736b5f, 0x0f91c97aed0f516f, 0xeee2cc0923c1f8cc, + 0x11843c9bd04a416c, 0x92d93d228508268d, 0x0b23a136dc386510, 0xcce870b2746153b7, + 0xb7c72bd49225fde1, 0xbaf5cd7fce0bb71e, 0x686ee19c531ecae9, 0x023dbc7831f4d544, + 0xa228c96d7b84736a, 0x677b06ffce47f427, 0xba412c4fc41b8722, 0x29c9ae86dea73624, + 0x6bc740b124c6172e, 0xfcebb2f4192631f9, 0x32600c5babac82d7, 0xeff09ceca6aec448, + 0x3e7eb96580ed6e7d, 0xd9ef4fa3f2d78ca1, 0xb2320e022ef15db4, 0x69909645bb63b367, + 0xd8797201cc82acf2, 0xdfc629abf4bb0665, 0x88cafab34337abf9, 0x32d40784db22a3bd, + 0x9991f92ea80cafb1, 0xfcd3ab39dec48eb2, 0x881722b0f377788e, 0xa26e7ba7277ab096, + 0xb6984d0d4977db60, 0x5358d5e4bae2f7f2, 0xce309fdf70b72b3b, 0x195368e486236134, + 0xe61181c4c4f8dbb4, 0x93f6a0fba39d6134, 0x548c41e10f7959ed, 0xf2005a32db4d51d4, + 0x5bced3a3f031f115, 0x858bd172800e82e2, 0x616a97f3100952d2, 0x37c4914b8f8c9816, + 0x25455093ecbac731, 0x8baa5f5ee6bad42b, 0xfb1111ef59a11155, 0x1e50a81b18d6e0db, + 0x3d94ad28d3ef76e8, 0x866c224e7ec0f20f, 0x6be1e112b02a461b, 0x312083b8773f0cd4, + 0x99160c2c025b1140, 0xa481d53db41e5067, 0xaffdc1e5ca2a8ed2, 0x2158d3e80bad63cd, + 0xa94ab90317f52729, 0x294be56a2562de0d, 0xeb5516d9e85bf365, 0x478fe9449186883c, + 0xcd20fef03d63ed26, 0x36c9658b5335bbe1, 0x391391658524c7c1, 0x5b4320917f183400, + 0x0f4b45615188af4f, 0xfe285dc241fb5e16, 0x643853c70a444ca1, 0xd514594cb07a64ee, + 0x51148edbb32677f5, 0x1c37c06e46cfa878, 0x0e3b7aec6871af79, 0xf0de443677f5e615, + 0xd5fe161abfea10c5, 0x367a305e5517deae, 0xa74f080cf2ed2671, 0x6f409e1bce6ce74e, + 0x733d12e80cbfa881, 0x8037584f75c3236c, 0xda33e89721b59ee4, 0x56e3f8e837cebf5f, + 0x301901062fa5b975, 0x898698745490101b, 0x885a0d1841454c11, 0xe1c0c3f9f82e76c9, + 0xaa3020c67cf175c0, 0xbf27c1fba255a0a9, 0x7ac04064ff19f5e6, 0x6390cd0e43c7f470, + 0xe13e495aa7e6537b, 0x04ebfa43f7b5823c, 0x2f61bb8db7b59a4b, 0xaa72ec30b87dde00, + 0x24fe5e0cf95ea9c9, 0x592c46275780e21e, 0xe11fdcb30c62926b, 0x33143106d3907c9d, + 0x6294933ea07a23e5, 0x8a7f9b869d3b10fb, 0x7f1b2320b3a2be3e, 0xaebe58151afd9ad4, + 0x62984d47040d26fd, 0x4c92360e2c216f09, 0x19bc360b2f1a84f2, 0x3297c0ce0af56744, + 0x811f05d424c0a63e, 0x29da07bcde62643d, 0x736cc751de1b43a3, 0xc2ec878ff2a49f33, + 0x452ad8b66741c79b, 0xd0ae9d941a26cd7b, 0x8fddbb4473334631, 0x9ec7a45e5982a62d, + 0xb388e4222c02f4ff, 0xaec63a9998e91bc4, 0x1d78f06ab0c9ea18, 0x6cd2c23c240b0c3f, + 0x61800c3b7deb062d, 0x3ce1de65404f195a, 0x488a6fb78b1072d3, 0xb003e57cef41900a, + 0x4e34991f8191ae05, 0x0582ea81d4b2d22a, 0x50f78bd18a906d4b, 0x122ce4c3b0441147, + 0xab8c61866f80578a, 0xee116fa2d21d8e2a, 0x03071fe3e82f599f, 0xfdc6933a55a87d3d, + 0xc9acb0abb2e7d0bd, 0x4636a992c998e1ea, 0xae898d265827c59f, 0x9f6519ed066fe521, + 0xefefe34740949480, 0x56b4645b10fb7c8e, 0xaf6915f671870880, 0x283ea1ee03a6e196, + 0x9d94184b6d405bcb, 0x49cba7cb18fd46e7, 0xac64e174161b3d18, 0xf15fe69ce485fd91, + 0x58a921f1a5ac2f88, 0xc710a1605f42e22a, 0xfde897f12c363fb1, 0x8c6a24ebd99f2bce, + 0xc720ab6a87f510d8, 0xbc203725dbda6a1f, 0xe889bc8ca0c5ac91, 0x52609ff83f8ecb71, + 0xde2724b0a84350f8, 0x220e60cf09b880bb, 0x5c57818f6ed7cfc9, 0xd7b4b48a586e4c70, + 0x2756effa2cf67530, 0x5724337f1629c10b, 0xddd4192046a39a64, 0xa2d065d29210fe58, + 0xdf96720706f727c9, 0xfc27a49e1076eb6c, 0x7c508eebd0c55cf2, 0xe20720a7ddcb83ed, + 0x910631cf6fcf4315, 0xddfe59cbd0f9c089, 0xa9d794a4eec973bf, 0xfe0354f82ca31fa8, + 0x132ce3b1d394f27e, 0x3b5590cdf656ae93, 0xb6da438100c3d7bd, 0xb26093950a48b436, + 0xc467bf890877866b, 0x008ba522d26edd2f, 0xabeee5b109332fd0, 0xbd7d3d60070e79e5, + 0x71cd7d1dc4cc8501, 0xfba071f129b52df4, 0x6c8d2789fc6733db, 0xef2952dd6cf59d8d, + 0x4b1dfb9e62c87e20, 0x78bc1911e5f0caec, 0x0fa5b0ab7e98da31, 0xac30980805f1a0f5, + 0x507f338eed25c6ba, 0x068f2e9acbb91839, 0x424a884edb364c9a, 0x43d9b67230917af0, + 0x4cb315ab287fcd88, 0x7046b76cc408dfe5, 0x9ae2e6170f496aeb, 0x7706980c747efa87, + 0xc140746d8b3daa6f, 0x1beb17c43e5fe37c, 0x9dd84f4d82fbe635, 0x20556f2415762b2a, + 0xb4a5c0c5fcb6e55d, 0x99ba9e7e139fb6da, 0x6298c14758daddbb, 0x8a0a3701d20b2c7b, + 0x086ee5c9a5065444, 0x3adbacedc5f2cbf0, 0x07cec280dca0f2e4, 0x6ac9dfed4154c0a2, + 0xa400eb033937d6c4, 0x28760b2d8b70eb37, 0xad3029a986fa934f, 0xfef995836953e63d, + 0x6387859173112617, 0xe8ac784be4a1b060, 0x97fb07f070c990d2, 0xe32354a3c65a4a51, + 0x44e1d9d0d273799f, 0x76374da83dc5ca52, 0x0569bcf76aab451a, 0x5d1325b97640a6c4, + 0x886fe2490ffea79c, 0xe35142a2be158d9a, 0xaff4035022511e91, 0x74299b2ef9daa1c8, + 0x73683a82ea962377, 0x754fba24c083a599, 0xfe58cb20af5335ef, 0xa8d0b1e85e5aef13, + 0xefbafcd215beb37a, 0x95bb254371b878b1, 0xe5eba9776bd3b9dd, 0x01ec959c32e353c7, + 0xbe6f1ef9b1702e7f, 0x8ee4837082d99ed3, 0x232ace301944e61a, 0xb1241110683b1408, + 0x492c5b8af3eeb207, 0x4eb64aeba3b84739, 0xe77d6c6b50562cd6, 0xc7a6de9d0e95ff22, + 0x7abd08dcf3282ecf, 0xcf02e760005404e0, 0x04f1766827885b8e, 0x8aceb343d9742645, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc8262abd3b39b9b1, 0xe60bf00edca1e6b3, 0xed4adb11f343aaa6, 0x05e490af8b3900d4, + 0x3a810102329192d7, 0x30b80e9ef889205d, 0xb975451dbdcac43c, 0x193fadade2fc1716, + 0x7725cf740490e669, 0xcb58c73f4c575843, 0x4e44152901cc6310, 0xba982df20859e203, + 0x392a81c3d34d6b1f, 0x814c5f88b1e6070a, 0xaaf3ddff045056ef, 0xcb8953e509890774, + 0x21559725fbe467b0, 0xeee03a4eeddb3cbf, 0x008f9fd6d54586e9, 0xe2ebf5aedf9b6533, + 0x63eb0e035c256495, 0xeb33c8d4335a16da, 0xfe47dea24b430db1, 0x18b13ad29f0e7966, + 0x65e2f4a3fe88d77d, 0x35afc1fbd67965ed, 0xeda0a65d97407175, 0xfb1746af8b1908a9, + 0x64d55d92832fa7f5, 0xa7ad683ec146cc66, 0x5d0db3a88327c5d4, 0x236cc7402fd0d18c, + 0xbc6dc347233a6fb0, 0x24f0cc2ce4959b82, 0x8e1ebd57f22e8a7c, 0x764eeefc376a0d75, + 0x7da2de7f2b5245bf, 0xfa9a1b6c97fef7b6, 0x43a2d194ca046324, 0x5a936de649eacbdb, + 0xc08d1f429c441d62, 0x56b7d209cac1a3b5, 0x59adc69c2d70501f, 0xdbb3b04b7f3ed2e7, + 0x42c3d3ba4dd8234c, 0x98a0b5617c1969bb, 0x0aecd08f2cf1ec0f, 0x8653d196e94f0369, + 0x88e571f559d7845f, 0xab0540a7bb7442f0, 0x310d4ccb2b1e8430, 0xd2af48b75971d8fe, + 0xd535ccb53cf4ae1b, 0xf5b2b105302acb9b, 0x2330e80e4196b8e0, 0x55e486b2c2914062, + 0xf3aab520de57d2b2, 0xc9ca9dd7f9540d11, 0x1fedd079904aae4f, 0xeddf090d6e970f43, + 0x7ad7b5bdec02151f, 0xe49fed5bcf849cc3, 0x6525aabc18dd0a3b, 0x6238795c52ce8b9d, + 0xde12f5df5a19ef02, 0x44a449e6d8292dc2, 0x8d40454bd0bfd955, 0xa0f6b0aad5e81569, + 0x5aefac6f38845398, 0x40a5d11dea55305a, 0xc9df50fe52c1f427, 0x218b467e7568955b, + 0x834015cd5198f21e, 0x447111ce5ae64215, 0x6f11401bfea88aa2, 0xffe75c4113bafe86, + 0xe2b48f7a200a42e5, 0x839dacd4288d1f5a, 0xd9444c95740475ac, 0xdd14e1d1ea3e6462, + 0x45f0cc8e99c6d1da, 0x7a03540fea610c39, 0x909d6b6a0fae0f17, 0x05ed2454bc88c856, + 0x242951361df3f5af, 0x9b3b360a3b24813b, 0x4841163bda66dd99, 0x8aa60cb754cdd5bf, + 0xb8bbb48bca9865a8, 0x10bcacb0162cb6bb, 0xcceda9c1abf2cae7, 0x5ffd91fe98549c00, + 0xca42bd99c5fc953a, 0x5634f2239991960b, 0xe622ea5fd0b738fb, 0x8484833e53c91674, + 0x876b7d7aca23e963, 0x1cde128535b4ab4e, 0x7cedcccdaaace3c7, 0xd5713ea86362684d, + 0x58faeb0f03b702a5, 0xaf13db66966ec9eb, 0xe6716a31058df8ad, 0x66ab4071ca58fd38, + 0x7957cb49d2d19e37, 0xf9617fb72af823d6, 0xa7e332751050048d, 0x395596b56c51a5a7, + 0x6083c6557de3a2a4, 0x5257008061cc54f7, 0x0d689ac705d3154b, 0xf827966fcc134117, + 0xd126ee677e585a44, 0x5bd3bfee40db0664, 0x65f55009d3df7c60, 0xc2d07f1747dea883, + 0xdbc983108fae32c9, 0xab5acb3d7b4cd0c9, 0x7cb8e265b6850ca5, 0x72fded8debdf4359, + 0xc8ca5ebf8d632acf, 0x47af9f7738f79ba6, 0xecc52bceff23a8b2, 0x3b04b1bed94c2b4b, + 0x86f43870a0ceb79e, 0x493fd815769941f5, 0x58df64287742315e, 0xc3657113d8da762b, + 0x35e34df0a3a12ccb, 0xa653c2baacf63006, 0x805dbe73922f50c6, 0xa803dbc03215f571, + 0x93e943e03dc28830, 0x38859e9ca4aafe43, 0x3fe5d938671a4175, 0x6fd1105782d77593, + 0xba8a1b4db0a1307b, 0xb744d84063a767a0, 0xedbbc5d4445de18c, 0x5432da547d5f95ba, + 0x9608786c271ec975, 0x2e3285837baa917b, 0x869ba079b4987aaf, 0x5c16bf24ebf099ec, + 0xf3a739d749306f23, 0xbba0d18a7b0ce464, 0x7ed4280658f8e901, 0x4b0217c7cf425b0a, + 0xf67049e78a2820b5, 0x79280fa60b2a0efb, 0xfa88d40c981afae8, 0xf53469cd20de9365, + 0x0457b41d1d5d6fb3, 0x0a87cabe39247ab2, 0xa8f5af64b89cd6b9, 0x828eac9013a49169, + 0x4a6584dd6e82067f, 0xa6e318d300f7532a, 0xd87ecca6443c119d, 0x8061448dd1e26bde, + 0xbd83f2191486bdcf, 0xedc7050260e2f946, 0x890fa510990bc567, 0xb247ffde5c8d3a31, + 0xa2f99b16f4c23337, 0x15c2261e37411d61, 0x302ec4888ca44c70, 0xaffe8d089f3ef502, + 0x0cefe020a7454197, 0xd1252bdec7b475ce, 0x0b9738a5e2c37a20, 0x0c83c66d0ca05f2f, + 0x5ff2ddf364cf8a8f, 0x4343cce75a1ac5ac, 0x8372369347fe36a0, 0x17ff4de73f32a507, + 0x3e6836867d5e3bcf, 0xd98ce42333478b49, 0xec06c2261c669b0c, 0x60c044763c4fcab2, + 0xda44669bab2ab5e4, 0x7aeefe90f3a14c79, 0x15a8b43c7ad30259, 0xe5180308c2af7125, + 0xc2b9379a066728b6, 0x1e429e21da3a6e68, 0x8ee4dcba644e0304, 0xb60335d8e07c8e10, + 0x4f813281fcff343b, 0x96d9de85005d8c3a, 0x2684dd1b9247d759, 0xa904af25cb3e4e43, + 0x20b767ece53a2ae8, 0x6e3ca764b7779948, 0x708477d973193114, 0xa5d326b737a0e503, + 0x815ad27b52af3a94, 0xf02d10b68d85081d, 0x49cbefabada95380, 0x1ec65dd80d53338e, + 0xec1727216e724b85, 0x8c38c1a29e6396d0, 0xc7db58a979eae9d5, 0x093f44f74a79471b, + 0x332f317b801a95ed, 0x7ea31f1d689e4600, 0x9075b51db8571f7b, 0x56905f2879ba787a, + 0x47df4250c8b6f372, 0x6e016ddd9cca5ba6, 0x3b729f2b191f7f85, 0x7ebf1d2354035578, + 0x74c9f94fe0a76bfe, 0x7cdc07ba9de48b54, 0x6acab0c89e1cbeb5, 0x3db6c5086439d876, + 0xaed7fb6320e18492, 0xe8318a4ce30d2cc0, 0x65ad2db45840ad1b, 0x163f94a3af95a974, + 0xf4f546b7364e3b58, 0xa566fc5fea9d776a, 0x3902f5a8d2395207, 0xfa45c573db9dc4bf, + 0x909ffea0fdf85c69, 0x7e29a46595844de7, 0x61c2bb9b0894211f, 0xfc88b6370d6a9185, + 0xfe65320726a5e176, 0x301d41d3bf9c8e26, 0xe74546c4b2adedd5, 0x71ccf3c726b8e32c, + 0xbf367946f8db52a4, 0xe97732ef63196670, 0xd6b550db7c1e4d14, 0x5f9589b006d2e775, + 0x48e2533301af5f8a, 0x8aae0060bd237052, 0x41e8cef9c466da00, 0x0f266246047c0f12, + 0xdd442b288bfa2253, 0xc306e0532dc61a0a, 0x2711bf71854ea80c, 0x6e427b8703bd8f93, + 0x8a125f8cea261dfd, 0x089d06491e84d00c, 0x181797e9b5e93d4f, 0xe0486a2af3d6582f, + 0x8479be2ce5ab4ad4, 0x2883f8b40eddbd49, 0x680fba8b1618d3c1, 0x2a367b47da9f40d8, + 0x29d9239e48288a3f, 0x321cc7c1b3b8ce0b, 0xb254cd398dd458fc, 0xe3cd431719829723, + 0xfcf6e8cd48a95174, 0xefc88e7100d910dd, 0x48c8b17d4601427c, 0xab2ee81fbf40c9ac, + 0x92d03071c15fff43, 0x13d21338ff8fc415, 0xd1bcc55eec33756a, 0x9837544317c2cdb5, + 0xcd447b5bff31f6db, 0x3f977e5e48aff7b9, 0x05dbec11bd7ae285, 0xb8df878a9c0c7da9, + 0xc4ff5b7bd7197e22, 0x28b26465dc31ed7d, 0xeaefd22fd2ea3c56, 0x22ccf70cd9567ff1, + 0xd092cb564530ad8b, 0x42946234c4a08cfd, 0x14f2837a7488152d, 0x78133c718b217b54, + 0xbb6fec40d774a58a, 0xabb7947810ff2bb3, 0x45515c7c271ce353, 0x806cb20c1da63986, + 0x76d9995f2344a018, 0xb21f1420ef624fd6, 0x44f521c43ed41dba, 0x6f059479b51241a4, + 0x64868f0781f6e6c3, 0x8a67592bcdfb131f, 0xc0411343d76726e8, 0x1133a626e1c936a9, + 0x4e24e6eb21560984, 0x56b602a46df3e8d4, 0xcddf072a40be5dce, 0xf9a9465e87a67582, + 0xf8bcd3f42a6b9df4, 0x292e1bcc1bac0fde, 0x9abf911ec232417a, 0x332f3f0636388b4e, + 0x95cbe58e42520bb7, 0xaaac4fc762c86aaa, 0xcf1074de23e51112, 0x0d920833a729eb0f, + 0x6af154e74e8b135c, 0xa97a2dd50d5b516c, 0xa2d039a4a918e042, 0xec813189d2c95d4f, + 0x43ec93c6c49728d2, 0x675d4f24778bfe14, 0xc57a962d7e4839d5, 0xbce857202c7ab25c, + 0x0df4b462b12167e8, 0xa74ec4209603e47e, 0xf7bbb60bd3e364fa, 0x1059dc45fe259f2e, + 0x9ee1983504ae31ce, 0x3b0c7ffc4213b7f0, 0xbc06fb9dfb7cf49a, 0x00df01dcd325f977, + 0x1d69336863393cf7, 0x50ab7bf1b33ccb45, 0xe6c7869d05b89d11, 0xc939b6abc327d49f, + 0xac92fa5af3dfcaee, 0xad9a6025d859e1e0, 0x015b407fb0061005, 0xc3bcaf4333b73959, + 0xd81c61af6b00a24c, 0x98b5173620d47301, 0xcbb24d874d5448ec, 0x3c23479afce7236f, + 0xd4e09513c51d3e6a, 0xcbbe3ba832d4dc6c, 0x2ecbe4cd103a903a, 0x0af9d12360c1ab56, + 0xbce89100add7f40c, 0xfe0121c129f00b9a, 0x59c371eb5a539b62, 0x367526e5824a9238, + 0xb06a301fd1e41fbe, 0x1008f64a5729fac1, 0x40aa208f561dba5f, 0xa6d5f0ed086a5b30, + 0xf19dea4fc848647f, 0xce6d3402c3c289da, 0xf444dee33a518bb6, 0x7888c884505e3faf, + 0x3459375ed89011c5, 0xa2c72fc9936cb064, 0x931d06964349438c, 0xcffa7cfa11becc6e, + 0x17c4f1b45ad11b4e, 0x6b89f7b164b65282, 0xa85123a88e722924, 0x657aca4c897992f5, + 0xfb10db2725e68b6f, 0x9d2f296d47ca52b3, 0xda7bf1834f9a0687, 0x7bac00138e1ee7b2, + 0xcf099d5a0cf43f4e, 0x02c79a0ef8a1e89f, 0xb2c9f107d6e6f95d, 0x53fc61b3fa69d81b, + 0xeb7498d5a36a7c9d, 0x028b055dbd84c86a, 0x9c1bcbc63d311d1d, 0x8e0daf51ecd1edda, + 0x8b66511e0b6caec3, 0x8d870f8462e282bd, 0x7828ac68282aba19, 0xcf23c72043f337a0, + 0x89773ead20642678, 0x442f43ca81cbca66, 0xe14b137c008855c5, 0xa23578f4bd668ffd, + 0x0b54c97d59344c69, 0x35e3d7bf83b44ba9, 0xc9b2db45c08f020e, 0x14f13318c7848f16, + 0xba67dc4c4fc73e5a, 0x3005dd297ee71e81, 0x95abc79b73250353, 0x30e873f34c51a0d2, + 0x8a6f51caddbabce3, 0x020448deb4588fc4, 0xdd1258c1957e3e51, 0x6f6dda6e29a875d3, + 0x8f27c4f8d1c81fcf, 0x06006b8adaff6205, 0x525c6abbd3a1188e, 0x80246698dc86cb63, + 0x64c2bff746c98f7e, 0x1c814565c06a7f15, 0xefd1a3f664bd9fd8, 0x093dca464b094e6d, + 0xfbaebf4b9e1a0cc6, 0x2e5b8046a170b020, 0x56e40559a96580f3, 0x5afd166cdeae5618, + 0xbc03f598b2bccf26, 0x7131809d54fdc324, 0x978dc5a70c305539, 0xe68f942dd8ccb778, + 0x2bfff105f1029de0, 0x72925e022a362c31, 0xfc16d3fa7fb40ee3, 0x634ae9b82cc0e12b, + 0xc70bafc6e227ed66, 0x860226c77599dad3, 0x7444a24015dbb6ab, 0x685284d99fa0dd40, + 0xa8c8b802d74fdd4f, 0xef91d344e31fb2d4, 0x6f12eb98cdc499f7, 0x9168d7e3464046bf, + 0x93d9db65aca777d1, 0xa1be49215c64302a, 0x2885a0f6966d3fc1, 0xa6a2a73532f66e1a, + 0xd4c6eaf3b5a25eb4, 0xbc874f314c657cdd, 0xd9777f391b27a6fe, 0x3b0648a11a991ec6, + 0xd19e3061acdcf266, 0x9ddd7c6c6e4f06bf, 0xe5d0a051fab2b596, 0xf009eb4191cee75a, + 0xc03ef9a49d8b9e0a, 0xdf42cb1eff347366, 0xa3c92515cb7f4e0f, 0xdf0464e286e5f1c0, + 0x3f73db78018bdc6f, 0xe5f943807bd3a23f, 0x8c235211df0994cf, 0x2cfe072a4e8bdea2, + 0xc8d427bfe56f0932, 0xe5e1ac239e20cac1, 0x083029f74f8c0212, 0xaa3a3ed45a4287e0, + 0x74c6ccb14b430144, 0x4c381cc2e2ddc27e, 0xc4885af1065f2d2c, 0x9586768179db0b09, + 0x89466b20078733ec, 0x4825181d8039ffe9, 0xc87831e1c6d4cbb0, 0x87e034a5741961a5, + 0x29aad84c29f1428c, 0x4b9b21ef6cbc2402, 0xfed029400ade7f5c, 0x814b16c0d0310cf9, + 0x538ba08e935a7427, 0x0e4d59b8e5aa648b, 0xf8dce8be29638c2a, 0x3fbf1001dd155592, + 0xd6081ef4dad8857a, 0xd3e23eb6e8270505, 0xa6cf6761428d3f7c, 0x1e8a9613728bd9e4, + 0x5c88078224adb34e, 0x63984819edb72568, 0xb92397ec15b63ab2, 0x0f867ff3fe5846d6, + 0xc37a596e39b13b5e, 0xe6a376cbc02c1804, 0xf8e312c5e9f281f0, 0x9c38a8541f50f2e1, + 0x881261176e601702, 0xadba05de1ced4c46, 0x83d6d06e8393f1bb, 0xa54d0cc5ced322c7, + 0x50e4ed28b150e074, 0x303d53636ccbecad, 0xab7bbe71bd1fe4f8, 0x5aa844511f3f32a7, + 0xaa1d7b06e930916c, 0x051d3440a772ad0b, 0x7901075e16f8012f, 0x79184a4ebfc0943e, + 0xfdfc3a4f3cd3a849, 0x5cb5691a2c256d9b, 0xce7d8192594dd790, 0x55f27c7ea161da27, + 0x940135ac335fa902, 0x80db23d00d5f82bd, 0x350fa9c3ea6db4e1, 0xd527ca9ffd83dc2e, + 0xc4ddb24bf349bfb0, 0x4f7af90ff0914dc3, 0x2f883972d643960e, 0xb20a54f70bebe428, + 0xb9de59fb8ecd911f, 0xbb95c8d7732b567d, 0x86438156c29305f9, 0x82e32b80d2514700, + 0x4bd94cf9c669a45f, 0x5ab5b7cb35a8babf, 0x9c5b36fd20c00862, 0xd0554b39a8f40dda, + 0xf707f6a43ca75a5a, 0x1a9a99b8f559bcc9, 0xdaa2de48f0fe5d6f, 0x14bd127adbc8a816, + 0xc271625baa62c146, 0x4e64e340f5b53840, 0x385d6908dac9cde0, 0x163df47a03057fe9, + 0xdee2b5d838dc9d2b, 0x5a05142d558c2991, 0xc2392c9bb4f9d5c1, 0x50c02ef42c3ff462, + 0x783e01b44917e215, 0xd602419cc153cb99, 0xdd932aab20c898e8, 0xdf10d6aa0959ad3a, + 0xf9ddb328f5c1a2c8, 0xa19a407437a828f2, 0x16617fc6cafbc39a, 0x2735c1dc69e470da, + 0xddfd58a3ebfee999, 0xbeccc33304da1cb5, 0x9c9f553d8737ca63, 0x051d0761f56c17e9, + 0xfdc01782c17fb9de, 0x3ac70a41eefc8493, 0x3c61ea02eab3125d, 0xddd32725f3661ce2, + 0x3308bac59c80bcc0, 0x611897f580ce5f2b, 0x59661276cb9e8d77, 0xe3835160ebcb5e4d, + 0x121ce9cb7cffccbb, 0x730cd4ca209aa18e, 0xf9b4a030088c8b50, 0xdca207ff26da764b, + 0xc6968dadeda0effd, 0x39a7b133899d0d4a, 0xda0098faebda6483, 0x02b62caeafbe789b, + 0x165f0e314ffeabb5, 0x133f726b07831b93, 0x13d6329715c8f6b4, 0xa5cc40fa78f69991, + 0x7e8adf7afd53c80f, 0xd28b08dcbf47df60, 0xafffc1caf977f320, 0xe362a59206a37580, + 0x5948361c82787066, 0xcf9cd43ec23f2b6e, 0x11b25b15db1507dc, 0x830470024c00c46b, + 0x69169d7705c18274, 0x2cfbe6fa49b4d89e, 0x1315d6a4fe33f124, 0xf55eb7a720e59af1, + 0x61839724995a2533, 0x139e6ee606fe7593, 0xc35fa00db97dab33, 0x421c8be8664f7e0d, + 0x7b71149938068230, 0x2de781c19f52cd7b, 0x5f73ccdfeac85212, 0xddf77578ac96dda0, + 0x1dfaf5f084693ac4, 0x19611464f516bb86, 0x010d84be6d8f15d0, 0xb333b02e51e0b27d, + 0x0357749b81b61e60, 0xbc5d7e234ae42f9a, 0x073fb0028da484cf, 0x7eee16b8dbf80d23, + 0x896c023acbcc551b, 0x7b9eadde5be233d4, 0x2b82bbe948f94018, 0x7a4a53b765b9f3fd, + 0x0090954f291b9eef, 0x900a921f4503f87a, 0xe17f34b5245081d5, 0xd09a1b1da2584768, + 0xe5cce3530b26cce7, 0x373aef871710c7b7, 0xe94c78861c36c7ba, 0xe3c1f24f0a5ea2c4, + 0xb07c4a66c147187a, 0xc30f65a2c415dfe1, 0xfd6fdb3f82a47a15, 0xaf826f25f94543d2, + 0x152fc4744283c954, 0x23259f7f4304d188, 0x90bf7eef8330e747, 0xd4d96859d260025f, + 0xed48f3adfc77212b, 0xbc0fb30c4d95e224, 0x9a430f7ba89a8074, 0xbbffce1fbd79d817, + 0xa8ed6129edcc5cc9, 0xd7ad65c141142c8c, 0x8cce08da486488d9, 0xb89f1b275dba10d9, + 0x68aa1d82c2864477, 0xb0881722bc485b76, 0xae7444b971d53b61, 0xbffc0efd51b676f4, + 0x2fa26ca116dd1796, 0xaa0fcc720ea32863, 0x1a950cbf09155d72, 0x91fe8b751780e2c2, + 0x3d13d82aa4f8c1bc, 0x99710873bb3b92e4, 0x876d1f9b11cbb0b6, 0x0304e7338714503f, + 0x863a8f6e2f934730, 0x693931a0af423f3d, 0xc04a3a35e7752d17, 0x31522c6c563c31f2, + 0x21f944903b44826d, 0x8a43559fe3d1fa47, 0x0adc5f3861f67f1d, 0x4ccbddec9767df4b, + 0x421802efd669a032, 0x72aaf7472d9e9af3, 0xc6e7a6ad415bdb73, 0x95341a1d1396008e, + 0xa3f0bbc3d1b39406, 0x2bbf857e31607f66, 0x6ce1ac8bf06f961d, 0xf2bcf45b995d8d80, + 0x54e40a3490ec870d, 0x0aa305028bc10f9f, 0xcb6e23dd8aa524ab, 0x89ed504e843102a2, + 0xc44f156237de6268, 0x96a1dd4535ac4fe4, 0xc9b5268be5f3f462, 0xded91ddde7655484, + 0xdca6d90e607d7a99, 0xf69c789f8618d96f, 0x37d3374acc11f162, 0x4c8ed7be15f5d3bc, + 0x45d7499ab68c2b9f, 0x3c85a3176518e602, 0xc5228255dd278cf2, 0xf8b0c00d850f0bfc, + 0xf859d9f2be619bd9, 0xd91763b129554710, 0x8ce965d8fce4c3c4, 0x9d8f199b207565ba, + 0x8402ab289268bdc8, 0x1857579e1f375da3, 0xe2556defe2ba50b8, 0xd220c2acf01ead79, + 0x638e50950f2f0992, 0x998f2fba260d197e, 0x7872b743036d708c, 0xbb0d066cbc93e667, + 0x783cf34df5b54bc3, 0x2bf92a590998be10, 0x8407d5b3b17403c2, 0x793ec4b5e96a7bd4, + 0xfad64d79e005de5c, 0xe1ec7d4654583bc8, 0xf76990aabf810fb0, 0x5023c76424773c43, + 0xb29182696b42afea, 0xbcab07ff215f0ba5, 0xa12fdc03e3d1a19e, 0x8f8595eb3a928ec1, + 0x074ddc5b194444f4, 0x70c0fcacafaa9480, 0x83e0e178371d60ed, 0x2e9570fd0cc42529, + 0x492a0233357a5a28, 0xa89a164bd12f8457, 0xd89b3443db0dd2cd, 0x7b17165eee2722e4, + 0xecb4354cd47d260f, 0xd921a0e447dcaf8a, 0x38830949a6843433, 0xf9447ebb37bc149b, + 0xbaf6d7deebf522ce, 0x6224cecde84b64b2, 0x69d60ff41d6a7bfc, 0xdcab06f680908e94, + 0x77f5e3c95351b9ce, 0x475520c75246298a, 0x9266b4df1c61fe76, 0x97015c55bc7e8502, + 0x507e28bf212383f1, 0xe4dce1fbb2212f63, 0xdf60ff51da8bf25a, 0x693d47379fb16217, + 0x0ff9c5b19deb7bbb, 0xb3f2731390cae9e7, 0x24a0a42b48203974, 0x6db7a88f38505171, + 0xda55833025e9293c, 0x99c01baedc1f7808, 0xa5ff89cbf0c51c97, 0x36e87a7337fd2154, + 0xd61451956fc41ade, 0xccf744ba04064690, 0x265e766074582bb8, 0x4dbaab4bc0b50d49, + 0xd14cfb3bcde50d58, 0xcab1725bb6cf3c21, 0x8228ed9ab71d74e7, 0x8869e7da4e2f7dcf, + 0x0e0d9c99c2434d26, 0xf2d9d650471e3665, 0x5ea2caeac7b27954, 0xb3ec2887cc509de5, + 0x940b09171b2611f4, 0x3271b74c068cb2df, 0x51c7437a63f9fa1b, 0xf17bfc2a13f5bf4a, + 0x528efa0a0b29ce97, 0x36202dd7baeb543c, 0x07c3c1a2621310b6, 0x5b8c526656ec3021, + 0xf4bb87a0b8f8165e, 0x9e1f35c47f8f104b, 0xf779bf82f46beb81, 0x7e3a590bb7762349, + 0x17b9a6d328bc4404, 0x26d383c880627f0e, 0x374a0e32bd57683f, 0xddd484552f8eb9b9, + 0x71327b6b7b4d6a11, 0x8bb0ccbdd9ebf893, 0xd2ae7cd1f9f4320a, 0xc38fc9641895f301, + 0x31ba9ee5810819ff, 0x8d7f037da5a7cf4d, 0x13365bc499635048, 0x026d26f28adcd7d3, + 0x848a75680b009f29, 0x1b2a0c16ae8ae71d, 0x0677fde750d81a21, 0xa2ebd26758863c82, + 0x20271da647ac912e, 0x07951936c7cbfc20, 0x4003bfd4ccb5929e, 0xbe82cb93cf5f4fe4, + 0xb35863ae0517b07a, 0xa4eeab0bbedda8db, 0x9a736f1ea3ba0e1b, 0xaf2ed098bf860daf, + 0x47760cd654d8ea3c, 0xd44f528b01739006, 0xd5e9574579407c80, 0x9e3b4a583fb5a3cc, + 0x8272a481a6291159, 0x2645f3fddfa2a9d4, 0xaf246fc054619919, 0x7920b61d9a70155d, + 0xc0ec6f55d82a4518, 0x2edcc831887cb0b5, 0x0040ff0bbb6700a5, 0x0e1d414257b6c7d3, + 0x4d39608340177d8d, 0xffc299f2edef6d8d, 0x8b18ae9033649e75, 0x365a019fe5211386, + 0x91258c69359c0367, 0xe00740d55ccd9819, 0xee12c8065e54940f, 0x8f9d508aa6e31ad5, + 0xcaad6df5ec1c7846, 0x0fb17a85cf0a8292, 0x5ac202bccfaf485e, 0xe97ccbf6c8b69aaf, + 0x7b74907918a17e99, 0xd37266ba63c1d74a, 0xce2031290715de47, 0x3403b73c1727bdda, + 0x1821d6d60f5c2f74, 0x35a07c57b008fa8e, 0xe091c57597b91e50, 0xcfaa6060ae48b66c, + 0x92f1266ef5b8ea0c, 0x808f8429f278d39e, 0x92d273eb0a8ba957, 0x513d57cebab1345d, + 0xb6dbfb612464632d, 0x6adb3a010cd0bf69, 0xb5c2908f1a45ab5b, 0xd456a6f0800b0a10, + 0x6ba1b566ec5853a9, 0xfeb09a4bc1b613e9, 0x11d8d51b09e01ee1, 0xa086ac536a806a31, + 0x00271b2411ea3b16, 0x94b39bea5fb50180, 0x45a04f3ef7e8bcc0, 0x3565e41efe365b6c, + 0x6da5d2a6cb79100d, 0x93c91e2ee5a81139, 0x4c6ada4c38945284, 0xa04702486888b283, + 0x35f2abfb416a8294, 0x29c749e4175e652f, 0x8809977e32235d5f, 0x7ba0eb91e236ef50, + 0x2c25e067e0f8fd7e, 0xf013cc5f815c308b, 0x755740e8829f6e4a, 0x56ddc51b84a07d0a, + 0xedc2af6b380a032e, 0x73c841ade30d7e64, 0xd8757e5de44d001d, 0x438bf6478251b977, + 0x930a28316b236b6d, 0x66d38a492d97694f, 0xd4724d57dde20a95, 0x9d276c6cfa11221d, + 0x6044fa85aabe0930, 0x75c07419d9d0b1f0, 0xc6da5f29b5f1fb31, 0x67dbd9a4d8f1f218, + 0x38499c2cad04abc5, 0x5f99d46c1f41bc8f, 0x91a4806d717258f9, 0xe2207201aefcd8ef, + 0x75f9aceb539d7a13, 0x6a3c120cc4b4edf7, 0x6657b5aa65bf7b07, 0xc5344d4320182039, + 0x4152fe780f341c83, 0x85441680b7ef6ac8, 0xa6b6425d279aee4d, 0x6f310f8727bebb57, + 0x070064f13f2bc818, 0xf961201bcc0d948e, 0x74a0186f6d95845c, 0xe326ba59a72533eb, + 0x06234a0bd0ae3f02, 0x06b1f375f09add05, 0xc74930729dff87b8, 0x7bbe4623b672ea51, + 0x95149656bb78f735, 0xc5a6fc7b747bb2bc, 0x7fadf9e2d3fefd7d, 0xdb58af985690f1cd, + 0xdab71092a013d481, 0x411a96c20ed3ea76, 0xd7775aaf3943a822, 0x95a8c53bb2da5dae, + 0x90c3b1eff76cf6b7, 0x53211922add0adbb, 0x944515b3428ef76a, 0x708fcf0f0eba9774, + 0xfbfd76c4d96e6d51, 0x3c64af3335028c80, 0x696fde98feaf856a, 0x5d981ceb593c006c, + 0x74d6d0f0521531c6, 0x31255e5bc6630ef6, 0xd156025539ce28f0, 0xc53a700a404cce5b, + 0xe2fffa50d96af07c, 0xdd24b7c86cf9dd02, 0xd7354261c373fc6a, 0x1d56f89c8a5c9bc7, + 0x33a7135f02921c7e, 0x3a5319d9b1a1157c, 0x941182356070275e, 0x211c6bf9203e488c, + 0xde48c6118d6a8068, 0x819fb5f989368755, 0x2ff90e9192f90693, 0x9fa86b348e8c6ac7, + 0x4843b8dd2e186336, 0xe39b352e5bc6c40b, 0x44e2593bf8b46f9d, 0x29f3f1297917dbe4, + 0x025bcdbc636f3c7f, 0xb04683cd5aecc72c, 0x7c27b9f84bc42d2b, 0x12481ebb3d7429bb, + 0x638e311128ec1ca1, 0x045ea4af0da3304d, 0x8365a09cc4fc50d9, 0xff5a758aa9bb4d5e, + 0xeb44acf4dc874d35, 0x4b4df65e70d1c43c, 0x2abd42898043c9f0, 0x135335441c426e79, + 0x8b7dce6afb7c92a1, 0x08ab46f36fef1396, 0x16ad4bf8497aed38, 0x3d7a45838852dd3e, + 0xf929bb3a1197c421, 0x12e7430cfc75d34c, 0xc350fae878a51ab7, 0xea92c9f9066605b4, + 0xc2e456b5d293a1e6, 0x82bf1d469e473fb2, 0xdb8a9ef6060b7431, 0x84d7d518a687aaa0, + 0x7511aba6d72ab3e6, 0xf1803a219a0e8541, 0x6671e0b711d16ada, 0x1fe56df3dd806f34, + 0x123e3e99c75584a9, 0xfb2912ed58114083, 0xa567b1be7f0d6ca6, 0x158fd724ae15cd42, + 0xe4e9093dbb2251fc, 0x693066c64a877938, 0x7f0a88da9e49d69e, 0x85fb2e8c884211f4, + 0x16b3703d61b5fc07, 0x10f204ae223a3bb9, 0xcea9b03f769dc6af, 0x26a85ba73d11a754, + 0xa736a3990cd8fba1, 0x3d78f3fc826589c9, 0x6af351aa1d5af8c5, 0x9789da391b4045a6, + 0x7dd80e45368e8f15, 0x55bd8f69c6c4a04f, 0x63701e126f7f7555, 0x0f4eaa6b192e7b68, + 0x3e60f97317c3355c, 0x3d8369696399d954, 0x811db425ca1bd0c3, 0xce60f0ea613717ad, + 0x756b4896c9fce76b, 0x48ff48057e170322, 0x1e674debc605948f, 0xe8ebabc592c96df5, + 0xa0baa2890072593d, 0x3d5ed05ce017bd30, 0x2d3a4321f9e14bb0, 0xd8b6cb333adeca62, + 0x56ef35032f9f8550, 0x14a78e964178dbbe, 0xd22f28cf4282954a, 0xfdb769b92fb886da, + 0x456419eb131cdad0, 0x8bed7ab49a0a975e, 0x47f3344e8cf0bd23, 0x89be455d73df6c65, + 0x6591c78ea6e9cdf5, 0x62f3ac8394595027, 0xfbbd73e89d04aca9, 0x754ad3395cc1703a, + 0x2c631059948a10c6, 0x70444874cc7a5bd7, 0xc42433386e225787, 0xf623d0f29219d8d9, + 0x7863ac3b2da17b77, 0xf974847549705dee, 0xe1311d57f9ff4c29, 0x4d8d8e511d37bc5f, + 0xc710841563d5653c, 0x9104f0ca4619cf27, 0x6c5a6c9cc63dbd38, 0xf206bbd60fb4f8b1, + 0xa46ab141d503ce00, 0xee0b3cb552228988, 0x43ff2198f7e7f130, 0x7acc681a85338892, + 0x30099256bf85ab02, 0xf3a19d21e796b48d, 0x974e069f4642153d, 0x951024e9d8c1c0e0, + 0xcb98162507a57526, 0xba7bfba106f8915c, 0xd689a5916572d2e1, 0xb04d938c0bda12a8, + 0x312ea88fa00e767d, 0x5ceb9f376b2a1458, 0x88ad23a48716e444, 0xb357a4055cb6c755, + 0xefbfa99f519b14aa, 0x05100ea0c2c5bed4, 0xbd5d0ed83008e7f3, 0xbc808bc4f3c5a3be, + 0x043ba08eee404167, 0x48da0a5381c0053d, 0x8e2acfab62d8b2ec, 0xcbb65307060907f2, + 0x8e2e03d00f7c3b46, 0x7bf1342e6c1eb4b7, 0x79326f91ce2f90f9, 0xcf82c22596bf087c, + 0xbab0205f3e37d6d6, 0xcbe0a2bbbbb6da98, 0x88df65781c3eb49b, 0xd3b3af5c9881f577, + 0x5ff9c025b3bfdbf3, 0x1bc44d3f4bde0426, 0x3c7ec7faaed59e19, 0x28b3338b3346ec94, + 0xeb3013c3c63271b3, 0x72cb71dd6446654f, 0x9d77f015f5180a7b, 0x04cd8c08a9a7759e, + 0x68f6648046ced404, 0x005c821877f9a0f8, 0x60ca2c971cce3888, 0xe7f67f893a21c0dd, + 0x2b86e3ea4feca4d5, 0x9f4f45daf48f8733, 0xe2c504d1e437accb, 0x3a1b9b1fd301f763, + 0x130cd4d44d922a42, 0x947d0bbd5de87b2e, 0xb82d109d4d3c2e21, 0x15483db4eaae9858, + 0xce64e28b31523814, 0x3a3fcbebb8d65a17, 0xc366013c9b823c80, 0xca98f47fe9a4b5f0, + 0x0500e33d24b127ed, 0xf311e5b0c89a63d4, 0x5fa7bd3523d869c4, 0x39177c3c2a86174d, + 0x92cecf2593315805, 0x167d95526c5d5c8e, 0x538da689aa9a8bed, 0x5ec455f011991ea4, + 0x19088f17d2bc0219, 0xc9a4a3cfb111acfa, 0x3f188df22fc58014, 0xc7931b5dbd7e673a, + 0x7920b3afdf7677e2, 0xe081f8fa266d4c5d, 0x0b6945311135e64e, 0x333e25be4f7f644b, + 0xf26668cc1020fcc3, 0xa657a29ebb251907, 0xb5a87f8ea7c160b4, 0x0ac7cdf80bed35d4, + 0xaf99003f68236072, 0x594f8bd296dfbbfa, 0x347603df94903d61, 0x6a76802e6e50b807, + 0xafda83c584773d4b, 0xe67c98523866f9e3, 0x65a1d20b0f3f30cc, 0x1ff89acf370ee8a0, + 0x703f8476e5aca25d, 0x85113e014c2cf1ed, 0x158f0d836d09f6b1, 0x222ccb0cb5b73fc0, + 0x9d91168520866ba1, 0x01c832c22023edf5, 0x821b9950192046c8, 0x29e2a78b9bf4d684, + 0x839a1fe01a24c654, 0xdd125c5554c65caa, 0x2dd60754202b1373, 0x78ee3d9e93237add, + 0xad1a23444173f4c2, 0xdadaacd0cc99129d, 0x951faf617bd18088, 0x6d5fb5c0072ebe96, + 0x46bbab0a7e9d3066, 0x7331eb5fd19cc432, 0x672b8bedaa55f6d5, 0xbb856f1736d7a84e, + 0x4997d67db772a9cd, 0xd9636095aa677b67, 0x4f19a6d90385d33a, 0xabde735cb2ecb18d, + 0x2b4021056160cb51, 0xb915d9d52c68f2d6, 0xe11bfc79b430fed3, 0x01ef451db7d1d49e, + 0xc8152fbf2fad5342, 0xe08deba32a30d49c, 0xea8f4b3cd2a6a5f3, 0x8e9ebf6876efc454, + 0xd9cc3adddaa306b3, 0x4761850006eb24b6, 0x9d7125e6fb08f8ff, 0xce982936473f4f56, + 0x0afa1f01b49afad5, 0xd4939e7cd20890d2, 0x1184d45f45a0bb7c, 0x81eb0f8215cd5958, + 0x924c56059ba64c6c, 0xfe93259a01693ec2, 0x1d4b1b17843f0caf, 0x9c5146fa7cf9c947, + 0x8d3b9b3112a98622, 0x1cd73990a7fcf454, 0x41869db4247aed96, 0x69b5e8f181202ba6, + 0x2bc3e697d630def3, 0x2679557706f067f1, 0x49826fe4040975c8, 0x82b0d2f2af7c8210, + 0xd10b7e6a658239cc, 0x46670b29242387cc, 0xf35390ad05300ce6, 0x62575308ff2a442a, + 0x9862525d43d07bc8, 0xc9c46092a5ab0841, 0xdbcb53b9d2c6090b, 0x4ce9e3cc3a3460fc, + 0x0b0ac10e618d4ffc, 0xf23e6d76006d6dc9, 0x16232cf717d0fb84, 0xbe2556867f968aab, + 0xe0376d7c1f7db74a, 0x7a8b4197f3995d69, 0x52ab45c5e1afa41e, 0xa8a5171cae8d9040, + 0x688fb5f37054de63, 0x945c0472b76db91a, 0xcfd4aa2875e188cd, 0x252624a7ec793b96, + 0x8bb4f81976db4f82, 0x506aaa3ed069ef0c, 0xa87f85e7cae641ff, 0x91a44d5c2b24e4b2, + 0x5c0d96bdc7e06d49, 0x29634968c7d9390a, 0x475bab5a9de0a68d, 0xd860c14528fe7869, + 0x93c9cf184cc29ddb, 0x9999df6af81beaf6, 0x0f8e5eba505b5eb4, 0x1bf1c5ec9e022bbc, + 0x8da274bbc2cfa328, 0x64b6b450c00936de, 0x1aa683efe64bbafb, 0x65374861c906cd92, + 0xfc7dc9a96e2f9af3, 0xcb1c8f379b8aa99c, 0xa828a12cd72b6f46, 0xf4a8cb20c5c81808, + 0xe1c8509c894f9658, 0x27f6c8a8f029f1fd, 0xcf642e9d8b676293, 0xbc8981ceeead4ab9, + 0x9ee89a2a0d428070, 0x1ffdc8c438926f89, 0x79ee8615877f02fc, 0xafc33efde621d1a3, + 0x9cca0c08750a4abe, 0xdecb33b434cb80f8, 0xe4433ef13b1ce5dd, 0xc5cb21343f2b9ae8, + 0x09e77af5da3b4236, 0xf98ba451dd7a41bd, 0x1fe44edf92767723, 0xfb48c3791d4a4537, + 0x728a41972d39cbe2, 0xf92fd3f52f2401c0, 0xabb622c744100316, 0xaf474266fae92641, + 0x4f78d2718be6689b, 0xfe80ee10a758727e, 0x3901c7b96362545c, 0xd315a1d07b59f441, + 0x36cc885bced72e02, 0xe6e0837d1daae373, 0x20e3a2f455e93f17, 0xe61e085fb412968d, + 0x9855ac8513613ba2, 0x76914016c0ddea45, 0x83378d7f4181aa02, 0x12cd6c7d26d449ae, + 0x0610b41d77e39f52, 0x152b56ad03066fd0, 0x54b406161d4ce266, 0x835e05978ace9c3f, + 0xd9a4b6d98ba0781d, 0x0d2d0a2851b77d75, 0xd3e7afe8539341de, 0x007639151eecb098, + 0xaeed0e267b68f0fc, 0xa902da2e13b658fb, 0x430f488dcf8581f0, 0x2c924174f82ff2ea, + 0xd264cebe790b82e4, 0x7375956fa720560e, 0x287fa0a7f2956d33, 0x9a023aa5b62371d3, + 0x2a96ef68776c87c7, 0x21978bd44c54c70f, 0xe4dc757743ebb080, 0x6d97494df9e5f95c, + 0x066d726c54c3fec4, 0xd71d6552a27ea73e, 0xddd3df8123a035c9, 0x827449c03c292121, + 0x5a82a72ce82b1b6f, 0xf84d27daafd73fc3, 0x6f2a181866577e6d, 0x9f6bc2cb89320c69, + 0xcf8be96b5b1fa761, 0x33277a29b8a3be29, 0x0e09cdbe68c2e7bc, 0x34d99fe2a7cd7dc3, + 0x848b83123a91f836, 0xe0885e2b4367b50a, 0xd70e37311d410a95, 0x7a2b7f6eb15757d9, + 0x6cc4c1ded49786a3, 0x37d1ce40640e48e8, 0x0d631fa500c5c6ec, 0x88c3573ffd522b5e, + 0x46a7b1f0c7e053b5, 0xf5353d8418b27b87, 0x4f1a08fa84a5cb18, 0x3124e26187e67b8c, + 0x39231c72ad9bc640, 0x93adc2157aa4cb4a, 0xf1400ca0f7289ab2, 0xe2d93855eeb6c591, + 0x3bdecc4177c634b9, 0xb1d04d7a5810c581, 0xa011ae3e7aa7c62c, 0x99c6863a6476445a, + 0xa2e5d9811e704882, 0x660a9bfd7c032c91, 0x1299aed8f59fe22c, 0x0faa651d92dea160, + 0xec626cb62d59846f, 0x0b78fd17c18130f7, 0x5bf19b4b6ada6f7a, 0x335da108ae82a51b, + 0xbac0d6dcd378160a, 0x8b85ba5a5fcd56ce, 0x8ccad6332b2520c7, 0x9193101383dff7f9, + 0x692381021347d487, 0xb99d5c4555fc9656, 0x9f9d653012e0b9a8, 0xf0fec44ee8e3a9e8, + 0xafbc161e857aede1, 0xc861d5974b8ec38f, 0xd35b0e08153d8227, 0x1329c83c17ea2f98, + 0xb37671b74069beae, 0xd1dba3d86b20b392, 0x0ede977a030e37bb, 0x6132d7d961238ff0, + 0xb61237b9d7d9cb04, 0xacbc31af0de7beef, 0x6ecf35bddf10953e, 0x72495d1023e562cc, + 0x0d59e2bc0464e025, 0x4689875c9c97e731, 0x0000e9094f280665, 0xf388e71061169357, + 0x27eec6f2c98fa92e, 0xacec9f264e0819e9, 0xfa76a40a7b409599, 0x073336202745e229, + 0xb9fb60354815573f, 0x07d7f6f5aa902412, 0x35953135b3c055b3, 0x38bee00310bfb808, + 0x13bd214be1e618f3, 0x2fbc9d9d27bcf92f, 0x3bb7966ad020dc2b, 0xb6672cb57125b5a2, + 0xe208b4552b0ee534, 0x8c25b40fd81e44a1, 0xe35944eddb676495, 0xe765de9c752482d7, + 0x7d8e098e615521af, 0x1e400c10cb5cf038, 0x551fe78c7a7a13bf, 0x468e05a0dfec2dca, + 0x0a4b468d0a3e4676, 0x8d718c5c609eb027, 0x4b0d9fe48bbf3e1d, 0x0874133f690566dc, + 0xff1d5ded64da5c55, 0x532a6d4e1959ca49, 0x9562bdbfa20c5df6, 0xf41c5bb19c152155, + 0x3bc72a305a9c46a3, 0x6ca44362c39d311d, 0x4fbc94e7f381f018, 0x7fb00a1121aed419, + 0x4929ba12480ba73e, 0xd13324d7e1ecb90b, 0x33df7e886e2b8426, 0x620e25127b0a75b3, + 0x833658ad16d27bdd, 0x5eb53842c1dc1abd, 0xb526e71233ef1429, 0x3a01c24633d0d32a, + 0xff6ab33b12e559da, 0x3d1fa997fefb14a4, 0x58fdf931e359fdd1, 0xdae87d0a877dbdc9, + 0x2b559fe28d79ebe3, 0xe761e9ddd8c4a297, 0xe9a63c7d7eaf12d2, 0xc9ed537205e1ac10, + 0x2bde0b4feda7729c, 0xe4f18ada76311439, 0x82b892592510d7b3, 0x5d8cee05c472072b, + 0x18a53fec6f337fe2, 0x60275333f197418d, 0x0db0fe9efbf0f37c, 0x6a5c6d2ea787ffa2, + 0x5187c6d316964188, 0x4ebf4b3f9dca23dd, 0xfddbe23de6c38804, 0xa298cb8bf95f36de, + 0x8f7987fbc3935c12, 0xe24b1156c0f2742a, 0x4b32e9ff75677667, 0x15c6cdf36f12d3c3, + 0xac5270a3318c6a4b, 0x651dd822ff6ebfd1, 0xc68b2e08b497a6c1, 0xc43ded5938b8c0a4, + 0xf2bba9ac4118fda6, 0xc29a8bd9582cb066, 0x4fad577274bd735f, 0x2da00fc13f14f256, + 0x97525069c9edccc0, 0xf59363b070f0d092, 0x503aa30f7355d890, 0x6e1d4d291bea2222, + 0xa1105233cd692269, 0xd9fd7d8fe5e61214, 0xe5e1571a78898fe7, 0x321e99d9ea1d3029, + 0xbfe388d8f873ad2a, 0x00806248e903f63d, 0x6b0fe4197bb3d19d, 0xe755e681146a2096, + 0x4fff7adc0eee3390, 0xaae3391991cc36fd, 0xdd3d7148b5206969, 0xc4a5e397b9c72cbc, + 0xf340ebca0150c739, 0xbdd6a499bcb6c7fa, 0x945c46991d9fc470, 0x079d6b60b7bd8480, + 0x1c92c3ad0a66b8ad, 0x5567f02ecefed2df, 0x439d96ca947a0be9, 0xe68a0f6d367ff86d, + 0xe3f371d72cf2a428, 0xf4dd42b7e6c0ec21, 0x2d4650fdc0f4d7a9, 0x2674142c9d9da001, + 0xbcf940b8522ffe38, 0xc5b71b5807bcc397, 0xdc5584bdab79d857, 0xa8ac6b2b067fbdab, + 0xb689adda503612b7, 0x085e4044fff668c4, 0x9caf0f0920a0f708, 0xb28f7a871c89193c, + 0x754770da5c773557, 0x598997cc5214c327, 0xcc51d6e04cfa2851, 0xd4108de786c72f74, + 0xd96aac81b6fd6e92, 0x7b15c51f843356e4, 0xc589928a613c40a8, 0x9315701d92158198, + 0x501876d8c9c016c6, 0x02875d52d0545f9b, 0xf485a603855b1fd1, 0x9f87176ca08ea6eb, + 0x18069187e6dc5585, 0xd32b6e850541be76, 0x2d765922b364139f, 0x65cff3de48eb11ee, + 0xcb04c6e4975b9f85, 0x86762558d035dd2c, 0xbc809d7d0bad9f7a, 0x2bf396ada69b8569, + 0xc1b04349a8ccc91a, 0x1a09328bcbac921e, 0x826127cae83ba7bf, 0xc1fd60bf480975d6, + 0x17820de74cace639, 0x0f13f947749d3830, 0x241358cc5bd02e8a, 0x57da67775b3fc5cb, + 0x648b99295b8b84fe, 0x07d7555282349ac0, 0xe5f56d2fd5bf113b, 0x1bad498690192b1e, + 0x025df4fe038e041a, 0x0ae4c5327a963888, 0x74de8a9e7d0f8c2e, 0x4b5a994417ccb071, + 0x7ef8f747a525c5d6, 0xd3f325f295a3a1ce, 0xa4b6e5a83c3f6da1, 0xd6a580809ba36ffc, + 0xbd99c925d2324ad7, 0xffc5021a4bc6bada, 0xe266a3277325c8b0, 0x06d1a245d4ec6e16, + 0x893365ae33bf88ea, 0x190739b7e49ed2e0, 0xa80e6022c6e7f182, 0x5822c7a0ca206110, + 0xcbb0a7b35798df3c, 0x546f121c6ace3652, 0x90305fd56f089f36, 0xbdb96bc252013109, + 0x2e55f4ba753401d3, 0x48b91e63882d57e5, 0x64d47e9672073ebb, 0x0bc4c6cbb16107e6, + 0xfdc4061d5e34c8c6, 0x89f8c2f10c0a492e, 0xb1ae3535e2e81b23, 0x199aef7a8ba0633e, + 0x9eea1f7d6e9eb3d9, 0x1ee5fdd29e2fb04c, 0xb2cfc080773b2382, 0x9c77da06576f817e, + 0x2603a12c53ee968f, 0xe0c29056ad915f84, 0xb0b80a92453b4294, 0xf12288da4465ed5d, + 0x05e6449fc4d591ba, 0x72642c50c1f353d4, 0xa3e75aac1bd91301, 0x5ea6875dc4945a6f, + 0x4e8db7ce56ee10c5, 0x63d882bb454cac46, 0x7fae3c5c5cde9baf, 0x05a2ad4d91188440, + 0x7739e9e364e430b8, 0x8b27483b3f72f77e, 0x7a84d9ff9da81d01, 0x7fe7a8f25a6507f6, + 0x104a09d66ff8aec3, 0x221fccccee3bf002, 0x8f456c566864b491, 0x2a38bc19bba083e3, + 0xca4df86ed7f6331d, 0xa915c2e70a21c466, 0x1b0a6310b07198f4, 0x880205f37b38db00, + 0xabfd5dc088f28724, 0xb902944c8843a56f, 0xea21cd710b4b0941, 0xa08aedf5bdc929d6, + 0x13fdca5dfad83c9b, 0x25be3d6caf6fb5c9, 0xce657651331f107f, 0xbb8fee7065e57110, + 0xe5deef7727e9ea0d, 0x85a4e89986b1b846, 0x07055eff7acbc66e, 0x85f8c65f27b69203, + 0x1d51cc06a246676b, 0x6da38092ae38a8b4, 0x347cdb985732cde8, 0x4626d721dd731972, + 0xeafebbc5fb211c7c, 0x87b8470bf46d19ca, 0xbcbd4d982c98e52d, 0x33914aa83fe154c5, + 0x8544d451754a6d58, 0xcfaf07cc2412f46b, 0x5ec12a7822086fdf, 0x04700feb313994f7, + 0xc4f0313beeb0edf1, 0xfe7b5b03e1edf878, 0xc44e597dcee44416, 0xf6a4732fc93cb6c2, + 0x70d20a4137d58e15, 0xb1ec5d5d9abb923b, 0xfce08de99a26e4f6, 0x3a651d5a87af493b, + 0xec72cf6367eb6c89, 0x2c2a91d3a2244247, 0x0c06629cf90ce339, 0xd990235af69a95a7, + 0x94c66316a1895e82, 0x643ede73df79d9e2, 0xe9a1b799a742e55b, 0xd3013304870339ac, + 0x9a38898b6872ad4c, 0x1d8a6521f5a39304, 0xf11fb450b68f1874, 0xae6de3dc2407fdb6, + 0xc831ba678cc7716b, 0x1abb10a06d30dd78, 0x32c9fd5a1984af48, 0x0774fb36a08321fb, + 0x17eca8e7c1831760, 0x2d3058f5a8e11c20, 0x24e07ec632d50292, 0x07a60b2fc2bfc887, + 0x8aca454fe34d5c6a, 0x1433b480d7346a6a, 0x0b8e726318d6b7be, 0xbf64250506fef9de, + 0xfd52082d0dd17caf, 0xfaba2ef781cd6a7a, 0x42170fe9288c52b0, 0x7212bae00badbd14, + 0x373943bcc9127baa, 0x06ac6ef6146dd0ac, 0xbe3349c937eed4a2, 0xed1c6046dc5416f4, + 0x5eae655572e10bf1, 0x1351db63fb13efe9, 0x66e9dccb6b27bbab, 0x8095b4e20c66e765, + 0x7a7cc44bb67d697b, 0x9c5892c5b383733b, 0x5e4acb76cef38e33, 0x9abfebea5de73782, + 0x49b68c4b47b2cd98, 0xf15cb68197be9d40, 0x5e6f77d022d111ff, 0xc2bbf876c1f27342, + 0x6f50665c0980d3e5, 0x83465806192f276a, 0xf3c54e0ddaabf129, 0x0b672acd1a1ea896, + 0x8d1cec1cbebd9da6, 0x1a52837f5a372f01, 0x2faba87e32c2062c, 0x74a14286eb70ed23, + 0x47918a2a0769603a, 0x4547f51b7fb424ae, 0xb33be6d28027942e, 0x8e44b22119dc78b0, + 0x54f950241fec7316, 0x9246c6dbe38825c4, 0x3483b15a04262936, 0x563ca7bce7202412, + 0x00ae5b00bcad778d, 0xa90c95a7afbfcc8a, 0xa586965961a78056, 0xc86d7ca2c6f20029, + 0x1cbeafe9f9ecb985, 0xc076be90209c7e33, 0xae19068cd6d9f825, 0x886f507cc9eec63e, + 0x97e563026294f8d8, 0x56dc8679b6a592ca, 0x8c6d4f3a5c878f1b, 0xa10da022f7bd8bdf, + 0xb8fc5994d531d673, 0x90d6c11921577f88, 0xf17823fb973df077, 0x5067b9a780c2b4af, + 0x69a32d12ef5410b4, 0x0e45276fb4b7a126, 0xc6e974204bbfe249, 0x572d95bc0cdcc601, + 0xd09b0e69f0758cf4, 0x8eda90918d18b26c, 0x6a0e4f119e5dab83, 0x6c58e5dad45ca8fd, + 0x3d5cbe91ef0adff4, 0x225784ec557eb6ae, 0x4d5a0c9bc888b68e, 0x47f3fd705131fb28, + 0x2e7b6fc01f5f1ff2, 0xaf8957acc909a0bb, 0xed49ddafcbf79b6f, 0xca89d0432a68bfab, + 0x7f4fd500fd5dc725, 0xd029e34f012ff05e, 0xaa43c4a0cbf2d862, 0x0dd9c348c4a10af5, + 0xf3bb564a13990178, 0x61cd5392089fe43d, 0x064b2b9ec49f6376, 0x7a77053e241cf322, + 0x0b0bab12bdf3e0c2, 0x266c4ac6c7b9fe69, 0x442ae1889137211c, 0xf23dece399bd36c0, + 0xd172bd1e5633899d, 0x70950cfa8c8d4b6d, 0xfba42c430cf138dc, 0x646fc4021f2c7d91, + 0x7fa825edef3a9667, 0x4ebfc87c386f3a37, 0xe41f57cba74fd040, 0x5e8b0f3c6fb5df91, + 0x27d4be4c2be3b874, 0x623a2e90a791a3ca, 0xff1b644bf8e0fd91, 0x50817140186def61, + 0x0883ad49f5e4196b, 0xc79625d083449f59, 0xdba819843a5296c8, 0xfda3c04733d456f2, + 0xbd3899cc21144b45, 0x688fc6e4964183c8, 0xaf02290f6ecbe50d, 0xeb11a01b5fd41e5d, + 0x6522873bb28b527c, 0x6ef8c0b10f97aead, 0x5c3ebc27407850eb, 0xa1fd513b2e3ef020, + 0xe14d489a06a49bba, 0x1fd2a8a1bc1d81f7, 0xfca58cd4ed95a112, 0xf02cdf9df724aff4, + 0x729b5217df995cbc, 0x590c118548cbe445, 0xba85bcc5e6f03f72, 0x8d519f8a82458e9c, + 0x137dfa0262d2dc0a, 0x366c3ff3266b9d8b, 0xa40d53a0e14b4c8e, 0x3cdb908bec30b72d, + 0x85217ea75d29bb86, 0x831252473c340533, 0xb7413eb2333b4655, 0xc7e2f0bd5bbefbfd, + 0x75f2bc68d5eca377, 0x3f76ce965180f95d, 0x744307274250190d, 0x9b71e67608a0db0c, + 0xf6587e89b22eb31c, 0x5cd1d79551cccba7, 0x0cae07b81be35ad8, 0x7cf57ddb13b8a35c, + 0xe080bfef828ad648, 0x25c495491887efa4, 0x8f0ab2d3735f106b, 0xb79480ed1cb74039, + 0x1beed6bdb4fe45e9, 0x73e21cc0af3b6527, 0x74972fba1628207a, 0xdac8bdbf762bc34b, + 0x1f67156057b93027, 0x1f7d9ae945c351c1, 0xeee82e575dcef68f, 0x2e6e9afe066955ae, + 0xf1b80f947a919f54, 0xc7cac7e9ea0deda2, 0x01b90ba9287df438, 0x254345d52c896fa9, + 0x4fd93a5c442b881d, 0x597ccc01d842569c, 0x8ef6d00892e39c44, 0xcb72872409e97a26, + 0x94e62a1fe5f29368, 0xf40650bbfa1b916d, 0x6a9997aa13bffbf4, 0xd4eb2bc552fb90bd, + 0x12ec524718bbc05e, 0x1a04b054139da5a2, 0x3a7411de644fe3f9, 0x85116ae61cb39ac6, + 0x32d377f4f77a2adf, 0x2bbd9a82dbdc5fca, 0x3b403aeb6647a7aa, 0xb1242a7e1d54971a, + 0x8a1a12ce640f536a, 0x84cc00462b2e9a05, 0x425bda357cc6b80b, 0xb79d2f30bd32f162, + 0xd6d84aae9eaf237e, 0xedba93ab2686f5d6, 0xc3ae4c1be1332f21, 0xa62438304e19083e, + 0xa67396573a33a04c, 0x01551985bb53d0d4, 0x8d34936482e27d4d, 0xd402537bd54c1a9b, + 0x7156c31916a277e8, 0xf74e523cbe729c55, 0xe26a9d052770fa14, 0x8e69234fcb340f75, + 0x81d3df4bdca859c0, 0x89bf13eeec7b420c, 0x65b053bae5a53d9d, 0x1a67e49172692fe9, + 0x0f45280e81499413, 0xc51d0f0155760914, 0x0a5b252532e4ab49, 0x0a2dbbdfb738c5fa, + 0xf74c88e8b66d9c8f, 0x38a582534e62b441, 0xf3dd3f3230a5908f, 0x39191a50a489823b, + 0x88400571618a4fa5, 0x72525c9833876892, 0xdc9cf45181bcbe4f, 0x25dd68c151a9b9f9, + 0x81822c3a0f8c122f, 0xf7f60d3887d0c3de, 0xdd31955783566f9d, 0xf36eb6b8f8426c34, + 0xd984d34e1b023be5, 0x42fc4944ce9c6a53, 0x07d3c94ae15d36d6, 0x872305ce57b403f8, + 0xc40441aa91af1357, 0x89704975bb11ed3a, 0x58a8d8a371fcd221, 0x07f2700ef9ac4c2e, + 0x36a18f8297bfd4d4, 0xf1242a374307f169, 0xda186903ba4a6586, 0x7fee365f8f7a71e6, + 0xaa1512a0322ac060, 0x845fac97497eefcc, 0x388a56b002461ba5, 0x1a12cc2c9a191065, + 0xd64dcd6876b63d7a, 0x58287eca4eba17bc, 0x6ab5bd86c45f84d6, 0x238956db4225d442, + 0x6e6d52642b1383b0, 0x5fc7aff410d71819, 0xf18194fb89ac8823, 0xff6e2ff25cb5a049, + 0x255aaaeb81e47d09, 0x07532a160bf92e0f, 0x0c7f7b51f62de239, 0x15e9a0f3ee90da89, + 0x595937bb8cb074ba, 0x70bcf22d0f3423e4, 0x66a30d62710e8367, 0x925f2734559f5d0a, + 0x0f427ac20056a06c, 0x94f1d2dd9061f3d1, 0x35370d6ba793f72b, 0x1a177efe275108e1, + 0x02808a69be95d5b4, 0x99bdb888d68204c3, 0x20ede4d884601290, 0xc29ee24e32bf260b, + 0x6f4e51ee9373eb76, 0x91d710f82ba44dfd, 0x010c106fcfbd4c06, 0x86d7d5e841f4375f, + 0xa75657b1f7c2e3a5, 0xa011de1a131a9851, 0x0a1b7c2086ce6760, 0xb32680d6582d6b69, + 0xdbb6b14b8d826704, 0xd55ed88184e9be71, 0x379a238613b9a92c, 0x6f36257ba6a78708, + 0x823af9f73afa8159, 0x4b609fbad69f1234, 0xaa0bb117ab301fc9, 0xcf0fe0055aeb6f54, + 0xf729426bb380f099, 0x878519050169b573, 0x45c986af1c498099, 0xce4e0dc3a12b51bb, + 0x82920776a5135fb6, 0x336f34c4f1aace7e, 0x9e4f738169518155, 0x39b7c9f32f575dd4, + 0xc5735c782fbf8223, 0xea51cece535d0d15, 0xe472d99968a3cc94, 0xfff8033f3adac524, + 0xa46b453910b0be8a, 0x7ef14fb4eac9a562, 0xa987d6a6d7178e21, 0xcca1d4455ca9c3ea, + 0xfe6990bbbfe37f4d, 0x9d8837ead7cfceca, 0xcd5d5804efcaea7a, 0x5d72786dbe6ab8a6, + 0xf1b0d2f1158638af, 0x5b79e508ed9e4f8e, 0xb307af9641e8779d, 0x1aecc0bbf5482d2b, + 0x9de4d831ee050ff0, 0x4dff44d028f0e5c2, 0xd2735b010b7b4cd6, 0xb2fbc9e6fc5c272b, + 0xfc80d65bdd52def7, 0x2143aa1f838ee365, 0x4192d91fa0481fe6, 0x706dc068d535e3c1, + 0xf77a44ce6ab54d15, 0x4bd995e78c224550, 0x7769696268eff391, 0x1fdf16ae5aa64b85, + 0x90af33ff6768ab0a, 0x6d2c3da47455e27d, 0x085cc726ab2d0bdc, 0x0f978107f6f51755, + 0x3fed3f76c846379c, 0xbcb2f9f060cd8b08, 0x6c73cfd3640aba02, 0x4ddfd1986e18efad, + 0xe5e2f79152d49baf, 0x3415efd12db9ea17, 0xdee5c7c8fa3144b9, 0x9138424a9548604a, + 0x83f73b79cff747b7, 0xfef3c9808834cd05, 0xd9504e020f456baf, 0x74d1284ed6ab10a8, + 0x98bd9d1af8d2356f, 0xe525efb0f0d4ecf8, 0xf3fb5de4cb3fed51, 0x9e7f6d9fce3b70a5, + 0xfae98c1f96b97307, 0x00a801def0bde569, 0x2b6a1148b301159d, 0xa8c3f64882f4dea4, + 0xbacad82ccef76184, 0x52d5d6a821732eea, 0xfc2ff309b92eb9dc, 0xbccd367e49083131, + 0x66b794783fdb0f8e, 0xc2d820d1d492a582, 0xec37cad13dad924a, 0xacef598e41a999ff, + 0xef518d3cda6bc7f4, 0x04d6e2872da2e7e9, 0x6d8b5dfa8957e78b, 0x6b29d5b66e122bb0, + 0x6e1f4be77afd6623, 0x743c3707f3858573, 0xd40f6152f6c4e8ce, 0xb3c10b801bac7d72, + 0x3ce6e3fed7d20eb2, 0x8e9fa1b72de70b40, 0xb5ec1b1c5dd29e8d, 0x8d6f178064892870, + 0x93d654cf6063b59b, 0x9a121664f44af21b, 0xf353c6e144ccc5cb, 0xf548320b74c70ebf, + 0x13fe62657d6fce64, 0x5170e60b78758e22, 0x1261a3afd4acc7d8, 0xa5deced974a2397c, + 0x5eb98ad8bc64d5e9, 0xb90d438bdc1b9859, 0xc8605d2bf744812d, 0x5c0e98b7e0d20e0a, + 0x550bf6348f8c4330, 0x3859a5cd209073c3, 0xdad955138b3a6bd7, 0xbb6322c076003df9, + 0xfdff4477d2d5ded4, 0xb442cf00915c2740, 0xa071f2acb80639e8, 0x3ffe61d14d206519, + 0x6bd82656b0701c7a, 0xd310f63801a783dd, 0x301b224c9311aee4, 0x9a408a07ffde6aad, + 0xb106fd4bd2ded631, 0x3034de3c4c252161, 0x15ee40e3f3e14f00, 0x835e5de9a7e01f5c, + 0xd379566157d5f104, 0x246da89d16b9934e, 0xb72fc03c12ba20d0, 0xd43f4f9f8e9fbaab, + 0x1ee83c2386f38551, 0xca8c69e4f4a1300c, 0xac7ce7219648f61a, 0x64d5ea940163a06a, + 0xd524518fc3024c5b, 0xa4e01c7b590b62ca, 0x4f371e72d2e67e4e, 0x559e18e77bb9c385, + 0x0802931d7a61b9aa, 0x87430cfb9b406e32, 0x53bcd2b77c137eeb, 0x3c3f29c59d78bfa0, + 0x1488ea2299a0c16c, 0x1b67ec24d1c23881, 0x401b68c41713671c, 0x03884fba97532717, + 0x395155e749a570f0, 0x59d1b525242c5c60, 0xa387c0448894846d, 0x0e6f2ebcc795c726, + 0x0281c8e35c14099d, 0xe6f13ef226874322, 0xe2db24ac4523cf64, 0x7c39fec0d5ee32b9, + 0xe4066008ba725cc9, 0xfbe6d527a8e3f0ad, 0x8d3ddb07faab1f10, 0x41d07f91e53b24c8, + 0x16270b7efec4c76f, 0x0c637d63c0514ab5, 0xdabb68bc780bf0c6, 0x26e40c9efa148830, + 0x0dc02761d306c500, 0x87234baa133165aa, 0x6a1f4a09c9a2cb21, 0xeed87e5684a9332e, + 0x207941e4ae3c5cba, 0xf7029d43fa3dab28, 0xbcd5661eaaf151a1, 0xde71efef4854dbbb, + 0x7097a48b6369c877, 0x84504d96f09773de, 0x781d554ca4eefd73, 0x9f90b15c76996be9, + 0x3cb11140412cd42c, 0xce9542b523eda067, 0x0473019dd214aeb1, 0xbd4bde9d7bdda27f, + 0xfd67e71907f96410, 0xea2ed09261efd8db, 0x52cf94f287e3209a, 0x7740fd2c63f5dcfe, + 0x8fd01dd7be5576ed, 0x09ac409ad55d8ee3, 0x94c124a6596e4465, 0x67505c07c0b5a8d9, + 0xc9ae1cb21f3c90d6, 0x440e7ed19ee2f710, 0x3ea217f51eda3592, 0xf083632528cdb80b, + 0x26c1c467dbec5679, 0x37c47d541631dd42, 0x4bf3ea283f9bffa3, 0x6dee2dd3b306f2ad, + 0xc06a216062850c39, 0x47d2089da7357819, 0x8e8b629338e5e152, 0x2837bcb2562091be, + 0xa239cafdfeee8f33, 0x73c7b224793be241, 0xfaf7a533fc90d7af, 0x4a16ca9517c8120c, + 0x94f6c3da5e7019a0, 0x8bf0194fc37e1c23, 0x5b2992b83f28938e, 0xff72c2a0f75e6b40, + 0x80383e172d67e512, 0x07f73796df794a8a, 0x25546c2f1726eca5, 0xe5cb191a66566231, + 0x1234251e0ecb2d4a, 0xeff762c1b19b3190, 0x3dc580a41a845c4f, 0xd2f801965f73cdea, + 0xf9b71118b3e240f2, 0xc0c2afaf351e5fdf, 0x8c1e22d426611894, 0xd74fced7e9f128b1, + 0xbe1e10f33f23403c, 0xaff6a9579b1bcbef, 0xa7ab39abada2dd1c, 0x6a327f527feb3d3c, + 0xea7c13879fcd5d92, 0xa3be11c2c79249c1, 0x534a3c1dcb413a07, 0x5413aef65c157047, + 0x7632e3f187aff728, 0x092e3f72a5555ec9, 0x5d21cffb11658aeb, 0x552ebe4dfdbe7798, + 0xb1ab16ee92c98ec7, 0x059c1a2f640eb003, 0x943930c73f90d599, 0x3593d1c9af168924, + 0x8683ee6607005191, 0x24948f955f28f1b4, 0xf69bac73113fc911, 0x8efdba6546dc2eb7, + 0xcf0839cd7ac348c9, 0x0b98a2d3c2555bb8, 0xb23067a0a8124614, 0x2fbf6cbdf113974f, + 0xaba1121357b658f4, 0x080c55eae9a647d3, 0x49415854e654ec8d, 0xb983fb2b8d01efa7, + 0x26b04c5ee68d8d74, 0x4a1c0499ce1fc48b, 0xdcbda5c00bfee0a6, 0xdb41bada10a48e4c, + 0xf2ea7a18400ad131, 0xc44018a75b744731, 0xecd4b447fcd6fdc5, 0x86bef9e04d60e47f, + 0x0e75df7a09d572a9, 0x0bfe42f84acf8a10, 0xcb67dccb0f1c00f2, 0x46d05bcb24fee1c6, + 0x7ee1803861a504c3, 0xbc618d71d09e5db4, 0x47f1e5da06d87f7b, 0x641d8a27f1f9f431, + 0x3cb5aae32466f0ec, 0xa02d3a5fff233538, 0x4f9cb3671cea8a23, 0xe8b10b3d7f69944b, + 0x1b42331e241a32e2, 0xbeaca9961723b1b1, 0xc7f26bd2800cbed5, 0x1d62937f40d730c1, + 0x694446061af804ad, 0x9172fb75d2f78122, 0x297ed99b697844f5, 0x60964079587f3ff5, + 0x2a9d2521e5991458, 0xf3015c1a419a857f, 0x6e2d211729cfa8cf, 0x512b1972dc78cead, + 0x4960b77bd97e2276, 0x959c13f93e9381c8, 0x456a1d79f4bc172d, 0x1fbc9cfd9d16322c, + 0xc5776bdda7cf4e11, 0x1e3f7f64152a497e, 0x2a8bce59cc66a064, 0xb843dc70f3a6a43b, + 0x456ba6d109d96250, 0xce8a401d1b900d0b, 0x0bb586909ea06350, 0x7152221c9cb1537d, + 0x50e22a11f5d30b9a, 0x4350c3f15f488564, 0xd802baf8537f98b1, 0x572db9b49f9029e9, + 0xaf00f8ea4bf9ba25, 0x0fc801d5257d3566, 0x9b898768be614f92, 0xdad7381a68467491, + 0xe7f56c36b654e247, 0x7d192a43080643cb, 0xd372c8e421433007, 0x2043137ca90f3a9f, + 0x307df50e51f45538, 0xd1f81a27f318ce30, 0xc1787fce99113738, 0xe4cacc5fd7867e40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xad8bc68ce031d616, 0x16888d8ee4003187, 0x44c0757f3bb8b600, 0x793fae7af0164245, + 0x210cd042973f333b, 0x08666ff52dbd25f9, 0x65c5b129f5f7ad5d, 0xe03d7a8d19b3219a, + 0xe0d98d04c44fcaa4, 0xf99439ee8752bcf9, 0xf5b9b6e8c71a0e10, 0x713f9fa797f986cc, + 0x9a67c3986d98a43b, 0x484e8d2758a09283, 0x6d0952de13455120, 0xf9937540698be490, + 0xc5b0fd8fe13eb912, 0xf512ce57673bcb32, 0x6e164408eb8f345f, 0xccc69dcd48c3cdd5, + 0xf0c920e6e0afa3cc, 0xe842857399981e91, 0x48ad23d074346f66, 0x8fe410fe8bc07929, + 0x023899bb9ea6a3f6, 0xe20fd0d565070c45, 0xbd15dddf6c80c013, 0x6ebca33ef486d172, + 0x5906b47b84a9d6c8, 0x51682f2843d0c4f4, 0xc968add0f5e0c2a7, 0xa5cfb9d08a1967c5, + 0x86d17d3b96e91b7f, 0xb6567758af97c825, 0xa87529701d98df45, 0xd9dc6e749df9d26d, + 0x9d079949b4480750, 0x0338a928aa10fe48, 0xcf434b3d2afddb6c, 0xe3c1f5298dc39f10, + 0x78e9a0846c4f6621, 0x3d274e75732ef3fe, 0x8cdb67d9e4366dcb, 0x930f3f5a6902449e, + 0x7252041991d9679a, 0xcd60e915b231c490, 0x4da119217b6ec062, 0xdf1609130bc19e60, + 0xbfa14d5f24823e15, 0x934a9377a9a12764, 0x557f263e69a1666c, 0x18ff26e261aa8846, + 0xc134ace5dc841e80, 0x075865b1de84e3e4, 0x1e28a52e7e84ecba, 0x42f5a659c1d05dd6, + 0x870d9541158c9176, 0x769f45e17527d450, 0xa74509d7328f6de2, 0x6bae6f172ae5297f, + 0xbaece7117891400f, 0x191f2080e989523d, 0xe5bf7d9851a2c974, 0x507c65e03b7de2d6, + 0x93dff2dee8f46ca7, 0xe4767a2b717d4b12, 0x8645aa11aab86959, 0x1b0e754dfcebd22a, + 0xb8b0221a346522c8, 0xdb1334e2f2425854, 0xaa074f9bc5144ad8, 0xfc418dd2d8ac14fb, + 0x59f9668458f26776, 0xc1985681d89bf549, 0xfbeac674878c3f08, 0x8d6ff97eb9f16443, + 0x8b61657c91ae5545, 0x059dd8a912f861cf, 0xda62378dbeb83d03, 0x9af0fa2861888892, + 0x4f2d40859a0076f1, 0x21cc77c9a754fe8c, 0x6a32db7dfb459ef5, 0x1ce4edcaa2855f23, + 0xb261e2a233654ee6, 0x6ba0441d353dec43, 0x8e669cfc18ae9f3d, 0x03efdcc14f0181d9, + 0xe13ce19d8f16a473, 0x1ac01ae30accd9ec, 0x46496b50a607e9f0, 0xef63affc7b636211, + 0xcc86e37c8bcacb41, 0xfe74cb479a38d888, 0xaafe0aade7d6f3f4, 0x21c8ca1917d1a4f4, + 0x0b15de89b65b39d0, 0x03a0f7294e38bec0, 0x1d791616a7cc9625, 0x405f3612f5c91abc, + 0x2d7c7b5b0c8d001b, 0xace57829fcbbdb16, 0x9bae7a0e2a85d001, 0x931d1002fdd010d3, + 0x5c3802feaccac564, 0xaf21c8242cc36942, 0xa753592d67660b38, 0x3d8d776f81851f57, + 0xf6a6521f0f22bdc2, 0x29b399ca9fa723ff, 0xd81b74c1bc4bac45, 0x5cd3d2a38e220c05, + 0x037f9aed755146f7, 0x8e5ad27d824a8b9d, 0xfed8715a9d32a3c4, 0xd89fa46c4af1623f, + 0xc1fe24754e9175dc, 0x1063cdbae163e8b3, 0x7ba01f134500caa9, 0x06179734b0e5ac8a, + 0x7249439236b0df30, 0xef2d9625c7b9e3bb, 0x971cea093b4ae42d, 0xab05d3e2133af6f3, + 0x625b6a5cad0ea260, 0x820ae79552d27add, 0xf2e97f663b17d5f8, 0x39506e1c3fc013b7, + 0x191f324163cda313, 0x9f2c0bd8e38193a4, 0xb94e3e059cc12b5e, 0xd6fbb8a180999f20, + 0xc37df2f0690eb305, 0xc823d9bf21849579, 0x268eab19769f0e8f, 0xdcf93ea059620f4b, + 0x8e8869a8a78eedef, 0x11957cd8d173b5cc, 0x0a349326b5f1b856, 0xa81bff5757a5bdc1, + 0xb9560179f44ae2cc, 0xba90572797b35863, 0xf0209d906ae871c4, 0xcd8ed6da40fb6bca, + 0x72456cd3cd2b7c8d, 0xbfd522396c8afc1a, 0xd66265e4366a02e1, 0xdecd0077e670e8fc, + 0xc08896c3391d9745, 0x6c80ae0f13b4a431, 0xc1fa6cfb400bd57a, 0xedb88922879c63fc, + 0x6ef6b77820fa3f63, 0xca311016bf65a345, 0x95e6a68042d8b988, 0xa2e9404ee478a29e, + 0xc7e323de9fea4709, 0x4b3982d7fe4b6995, 0x4164ba666304cf04, 0x95f63593b70010ee, + 0x1825c0737e7696f9, 0xdc16f46922949f9f, 0x0816da250604c637, 0xf92ad91faa10194b, + 0xef048d890f461c33, 0xedc5164f3c020c34, 0x79d0fb8ae2cfeeca, 0x8abb4ef43d8100cb, + 0x9ebd569148bd4cab, 0xbb918e4bfb053e38, 0xa751f211bc4cd877, 0x8b04d897be741a0d, + 0x80764af4bcbbb271, 0x99008678ff5788b9, 0xc8c7841e7a08c504, 0x2148f446482e76fb, + 0x436d727584079a9d, 0x1b5e228a73e325dc, 0xbd2534706156a568, 0x07c11faff2ea99cb, + 0x61781e958be19b01, 0x03d384aa323790d9, 0xcfd9b8311a8fec96, 0x36eeaeb0fd58adca, + 0xb0ee8e87939c0dc0, 0xfbbe1111ac50cbf0, 0xb73663a5c09328e8, 0x3479b3c2b9b83324, + 0x47ea9590bdfc6a52, 0x215b1a58397a980d, 0xb960b40e4d453d6e, 0x48f8036f37a5f313, + 0x4acb94f16c968f93, 0xd28ebeb00cbdb595, 0x835f9af487184cc5, 0xc68ac73d514f66e9, + 0xeddc70db04724292, 0x1f14683248943b06, 0x0e46637d4357bfdf, 0xf529abf54245f486, + 0x57cea528a94e7085, 0x27184a175b192fad, 0x7295d93cb6ab4615, 0x97074eeb2fdfefde, + 0x7dc7c36053661a5e, 0xbcbb863815ffaf57, 0xa836b132b417d9b9, 0xfaf8f382e81f47b0, + 0xaf1380ffeb9a66b2, 0x78ca5acd02c0025b, 0x06121e5380c216a9, 0x0f20aeb213cf6976, + 0x9444e52ff201a5ba, 0x124e01e767777ce4, 0x6f7f84e409cfa0e5, 0xd0a914edb7831260, + 0x92657616096c1bd5, 0xa2f1edeaf3218fc0, 0x1d2f23410b1b99f0, 0x006b688790c68464, + 0x48262de13a1f9e17, 0xb1257e94ce377cf5, 0xb32132b862293f74, 0xa885444e6d9788f5, + 0x47f46d5e29bd1f46, 0x6b35ddd815e0614b, 0x4dd2adf4dec20404, 0xa61fcddb8aca9021, + 0xd18f376e7f0c6e22, 0x49c0de42986bc333, 0xcf58c053772fcc75, 0xce7467d3036697ab, + 0xff8cf62d701b3740, 0x4812908ffa6193c9, 0x511af45040e6d04c, 0xe27a49b05469cd2e, + 0x65a40175a5f675b4, 0x113634eb76ca0920, 0xab7c35edb3d83a85, 0x42b97f246360e041, + 0xec46f227e51d0264, 0x6d89de8ac4065de3, 0x9694f16073fc54a0, 0x18319970f67c715e, + 0x3c30e74aa69e1d76, 0xbe3abf39d7943514, 0x1823f8168e5fba40, 0x9f81041c6754eaed, + 0x91e35b0beae11188, 0x522f53d831fdba2c, 0x08b03697abc449c0, 0x5c3932444df85d1d, + 0xc61faa71a5a4886f, 0xbe9adec82d320086, 0x7cf8c37c7f510fc9, 0xe90d874d5a24100f, + 0xba9a1b32028e4856, 0x1ef41a9042a73f31, 0x99f0a584d3da9a2a, 0x4204dc9a785c4bd3, + 0x2eed1db8a6d24b4d, 0xa047dc4d25f9009a, 0x97d1f744bc68ce6f, 0x980bb2d27ce06fcc, + 0x259c137f5642dda6, 0xb947348b80db5caa, 0x624b4a5f435e7574, 0xea02bb4c5aed06ee, + 0x4b03746f59e42106, 0x5523879bb7572b55, 0xc7572f70a70f3781, 0xd884d71c8dfc0f02, + 0xa158d1080140ae6e, 0x9528770b139a9263, 0x585e169ae1e92db4, 0xd924489320d810c2, + 0x09388fb6b783b910, 0x50373d28896b92e1, 0xbacd0a0c6667f018, 0xe1e02acd2f28685c, + 0x60b54c1ad833d9f3, 0x31eee6f40afd126c, 0x0ee768cec793cb04, 0xed40050d5aa849c0, + 0xd6f44aa739a4e55a, 0xb01e72322b243c91, 0xd2918a7e36bdec80, 0x579d876e0a74ec33, + 0x66f115b3f97ae770, 0xa61d42657348d631, 0x3fa2b248a7f25789, 0x24235d1d1e7cb0fb, + 0x027a9c67959777d1, 0xbd000c805dda2d7b, 0xe1e5799a19603cb6, 0xf70b93c568893ccb, + 0x81eb233bcc3af284, 0xd2f0b28c41338818, 0xae50af1f82d93202, 0x764428fb4bf481ea, + 0x934b2918e0dd3951, 0x37cc7248aa9286b7, 0x8c4c4da9a19fe021, 0xdfb1d156fc1c3358, + 0x802ed9b76fea0968, 0x2602ad628b498333, 0x3ca12fc3e172190a, 0x981247e38983901b, + 0xa456846a3713a0a9, 0x4bf8b9c069f118a5, 0x4976bfe5352ba8e7, 0xe73f3efc3f9ef9ab, + 0xec19dd6cdd423bfa, 0xd2cef2c12552fc65, 0xb4e2f036e4add7dc, 0x1ca87755c6db3231, + 0x7fbd7cbce56acc93, 0x960d4b4ab8959775, 0xa7398542d36068b4, 0xd7040b66fd0057d7, + 0xb41b2b776c0234dc, 0x00b8ddbe778c18c6, 0x6b5e43944ecf68f5, 0x043b6b7ccf259465, + 0xc992b3653201d6c0, 0x0dc80b5d845567fd, 0x17a054fbe99a4489, 0xde87f6b1c38f83ee, + 0x36b3d2b536dfb35a, 0x2d15ba37444a5596, 0xa3afa817eeeb111f, 0xe5ab367506dede69, + 0x6d4f2ae42e147a5f, 0x5133df19dffe067c, 0xc459088e06c4b37c, 0xe0f149c9cc380b4a, + 0x9e32e4e2e7e7d0ac, 0x7709ec21db32156f, 0xfcb636cafa34624d, 0x5a14e436e1000c72, + 0x19975d2bd3d5e206, 0xa95f63a7e82068bf, 0x6373566711af4fd1, 0x052c972732b53592, + 0x1f20ab824f02fcf1, 0x2b169e6a8a8684df, 0x27388136ea2662ef, 0x56aec80cbb5c0e06, + 0x8f52e5c931b8f736, 0x416caaeadbf1d56c, 0xfe2aa53c41581446, 0xd549a265ec64decc, + 0x3df3a3e78869081d, 0x1d9cf882c23f01e7, 0xd720eacc96fd81c9, 0x125c052ef30e0f67, + 0x0270dbc43d1dbccb, 0xd07ab6d7177da3fd, 0x1072ccda35e696b8, 0xd4210ac66eb921d5, + 0x14c622910a017dea, 0x8c703e672b73d136, 0x4942a8e05cf6d5c0, 0xc72f661479bf185b, + 0xd5e5391a1ce19300, 0x0c8b5a12ed183891, 0x66645fd0ea45f259, 0xf30647ba7010d636, + 0xf75f5f4a2b1c94b7, 0x13391d4b9fd4798f, 0xf947a6b8800e5af2, 0x8af76f7fd5576751, + 0x0343e4b0a9852c2c, 0x0d5fc25728852d0b, 0xead2c5d671a91e35, 0x7f02275863b5d10d, + 0x2b45395f8ce30452, 0x1dc8f0ab1c9c564b, 0x55684629f1770b59, 0x4627cba9cad4037e, + 0x2d97f53b8f497527, 0xd5a6c8c83f899451, 0x8961977fc3c651b4, 0x6d792a973d645dda, + 0x9062e41e207eb827, 0x67968b238c32b264, 0x59928bdff804eb7a, 0x2cca31672d9f17af, + 0x647e9d4da66ca99d, 0x9ebb6fac229b0340, 0x84b634f9f8bde3d2, 0xf68ba53aeb7b9f51, + 0x415d44b181557d97, 0x596797b8e464be37, 0x44938d128fa8ccd7, 0xf5cf473d1f61e4ae, + 0x9830dc9a384c3d65, 0xe363c2d278cc4bff, 0x5e8c02ef5550ac53, 0xb9e2e955a90a0f59, + 0xcdb368765853fc03, 0x142ac6ad816f1d5d, 0xd3b729517d50130f, 0xbb5b0d2f4c167b11, + 0x0837a92ac2069d9b, 0xc392729c7f788596, 0x5c1a24a2a79191df, 0xa1d7d3f974c93d3e, + 0x596365646f44c7b6, 0x4115f27372425ba0, 0x0cf7ec0c4a28b2f3, 0x00431bcee95314f0, + 0x1ee7e74940765d87, 0x68850b73062be66d, 0x4b0a1761b7f7a66d, 0x2a1ecb67c725d90d, + 0x44eeca98805bf112, 0x7c615b2923d661bd, 0x23924b532509e387, 0xfe0f3b3629fa3e9f, + 0x72e77e5f02f75116, 0x6eed54e4f9952cd1, 0xc946db9f3d82172a, 0x6caac55e98fca10d, + 0xa86e7cbbd4a4e429, 0x95faa7b647e709d2, 0xba5e19a694e9eb16, 0x2f4f6b22afeadd03, + 0xb48e925f1af02b65, 0x578e3c423bce8be6, 0x82256d2edf79d6da, 0x62e180765b54012e, + 0x661bd7992681bb8a, 0x0526128540824191, 0x7a7d279ecd4720f3, 0xbc0c263b22256981, + 0x3f406ce2a77e381e, 0x496e92879b9a78a5, 0x4002487382b384d5, 0xebd513c7a9dbc170, + 0x5af0df1289d0e48f, 0xc851cf5cbc4ce0b9, 0xb039e21b260def5a, 0xdb915088bae00294, + 0x90a875849f005fd0, 0x216e2fac1c859da7, 0x95b7031f134469dd, 0x660c5100a280d466, + 0x504ba3af9bcf6cd9, 0xb57b2c794654164f, 0x00c5ae5b818acbc3, 0x98e283c39b38ed6a, + 0x134cb409cef51d13, 0x772bc6983458f2d4, 0xe5999bb11fd45f26, 0x01893928027e4cbf, + 0xc20aee9edbc83df3, 0x676f4b2caa556f49, 0xaa87d88fb2dafffc, 0x9dff1c74fcca5623, + 0xd84eba8cffba03d4, 0xdc003a3bac5c49a8, 0xd77811a9fd7f69fd, 0xb31593ad280c6f0f, + 0x31c2d67670be6936, 0x52822e373d880148, 0xc161f514d9209431, 0x5679c20a803d5df0, + 0x53f06d16bf3d188d, 0x06c08f0b862ae58c, 0xd4aa960d534bf0fe, 0x84d452bfd4d1caf5, + 0xfa40006321382333, 0x286388ea172b96ae, 0x24eec962b7911486, 0xfaf78faf90150a68, + 0x9c0cf33db4113808, 0x761b7a94ea344ea5, 0x9f95abbaf774dac6, 0x572bc6d43c9c7e4b, + 0x54a89ff5e8f941fe, 0xc0fedfd448b0198b, 0xa9c3f21bf0cbdd96, 0x82efd318bfcffe6d, + 0x055db5dc6be3be75, 0xd157cc8249d8d28c, 0x6429d4902cce3fe3, 0xb7559d1000b3a9e6, + 0x7358db9ac82b1e00, 0x52c983b6da12029b, 0x33feab193ce08b26, 0xa42a05d86c60246e, + 0xeb4e817547ca65d3, 0x10741b657eed1773, 0x96d65bb9125f95c3, 0xa0ee0469fe77b14a, + 0x6dda3d8c1d0875af, 0xe5520eccf49b85f5, 0xfaebc73b9e83f56b, 0xa63b277bd28a2489, + 0x33a76ce9f7b33c2a, 0x73aa71ad66ad532f, 0xdc08c5325792bffb, 0x8d16c863c37ae721, + 0x947c7690d47e706f, 0x1b2d1a8433ec72b5, 0x3e0e28c490e364f5, 0xf44aaa572092af6a, + 0xcdfe7fd6d7b2427b, 0xcf85e74409db9efe, 0x140c309240d11c22, 0xf274d6098b1b8ecb, + 0x11216b3eb0ca9d68, 0x8e4fb722e1b82d7b, 0xb68c828a981d087d, 0x5cd379c71a770be9, + 0x212e322f5552af36, 0xe41877e8135862de, 0xdd95fd498a65861c, 0x2fe79c930e2bf1be, + 0x6bb58ead5208e88b, 0x84bb2ea8ff4ba5e4, 0x045bde9b3da4f5dd, 0xb3c080baa26576a9, + 0xa51be0cd90dad08e, 0xbd5a1df5166cfb5a, 0x6807231c14297d62, 0x326b3ba573a3a7c0, + 0x7ada34558b345c98, 0x8da1a70b3c91d7ff, 0xa576bcea83daeed7, 0x8af65985a3e4a39c, + 0x04780f77127c0d9b, 0x2fdf5e19f86bee48, 0xd2c8fa482c3d3980, 0x9fce9d031f9fe625, + 0xc06934d908203598, 0x278aa815d2f04a87, 0xeedc89c3b72cef0a, 0x94efd5c0f0990ca5, + 0xcc309fa90e373da9, 0x719748c91f73c72c, 0x56836802b043a589, 0x67c3c26d885609cc, + 0x5ca6a547d73a6d54, 0x0716b5cb4b763b4d, 0x58f41f6d24e53eea, 0x40b1417a73fa9b24, + 0xf0fbd86da3cc638e, 0xf4ee73920d5b697e, 0x695a260fc195f439, 0x98879f92c0378921, + 0x8eae6a15ff2c7042, 0x5587d772bb83194f, 0xda0bd09a839c0460, 0x4583cbb276c1fbf5, + 0xfe60f4e2b090b65f, 0xd5017c68bef1558a, 0xed413f19061e1245, 0x7221a8b4d87f8e58, + 0x5383d8b7c376cb31, 0xf0d901e229b86680, 0xd9c934ff118cabbe, 0xfb32d7a16b2abafb, + 0xe0f5036303b629e3, 0xe0ae0818dc0fb75c, 0xe4eea3431935c676, 0x1205a565da0786f8, + 0x808382b0b9bfde29, 0xf110e3e298971c57, 0x2c12e65e5c359f44, 0x750f21db8dc849e0, + 0xa6036536df854af6, 0xf5096a448d108c7c, 0xdf91f300d48a2133, 0x88b0876fbaefb5c6, + 0x22973f2784cf620d, 0x5f3bfe4a0b197417, 0x3b6fc0e1543118da, 0x94ff4f25472baa32, + 0xeb2c2d9df5449cb1, 0x6e3f95a226ca9468, 0x9ef0e6ef443ad247, 0x42013a842d493fc1, + 0xcd0e2dd5f5f1e47e, 0xc4ac44ce934a7606, 0x8cce1ef7b72e1661, 0x1e2090bf5284d333, + 0x02bd7bb6d5d3108e, 0x663042c8f7884df5, 0x81acb949cb0009ba, 0xdad17497d48f86f1, + 0xebe8c481d34f156c, 0x99335e8f78a6c0e9, 0x11d4c662ad95fe2a, 0xa69f6ff236ec2d3d, + 0x588bd689a4995927, 0xa95eb190bc4ef82d, 0xbe029150cab44569, 0x419b5cdd35d217c0, + 0x66e45390ef0a21d7, 0xe0fe295db23dfcf2, 0x514b122a536563ed, 0xcf1cbfa50828d353, + 0xcb2fed5c50464661, 0x1724e8268c696a1a, 0x5645f53e0db58b90, 0xeed3f47bb83a3190, + 0x860b49f7a0737f36, 0x2ec8c337654f18a0, 0xe07f01e61fdd13cf, 0x7e3e2d46d86472b7, + 0x9bb6cc0992bbba91, 0xda45841774b93f91, 0x6ca92e4c7e7fc8ec, 0x0499187cb0958c77, + 0xa2a4d0b22e7eb061, 0xab73cb0b3fd65ad1, 0x2ca185e3167271a9, 0xadcb19066ee85f31, + 0x0765fc451543a137, 0x9d39f713d2e4dc9d, 0x2b87b6287716a6ff, 0x55e150ecc40fcb1c, + 0xa56a62692372f042, 0xa044dbbe8c82a4cc, 0xb3d27452cc341b39, 0xa308233beb7e33c0, + 0xcf19a57901481ab5, 0x23867e0f96854bc1, 0x6f1da8842dd26999, 0x3c3a6042c375f9df, + 0xa66949b5f2abac01, 0xf5300524d83b9ba5, 0x73be8b3ad663f6b1, 0xd65d774e0ee07de2, + 0x57a7d7d0efdc36f6, 0x3f94831eb87e8e32, 0xa8ddd8a004c38936, 0x4202544447480294, + 0xcb76473a4ba3482e, 0xa597a56d1ec3df7b, 0x3aa241f6bafb75d1, 0x4336cf805669782d, + 0x123f3f62d5dda8c0, 0x656ce3d7ff630946, 0x8d398514fa96d663, 0xd07b57fb3fde1cad, + 0x028aed43d73bfb55, 0xc7d42c07b12c1c92, 0x88c91c0cf517df79, 0xc206369595cc4802, + 0x4828c60bf1613a12, 0x1b557465a9699f9d, 0xa39c8e842d8c8632, 0x59356131f19d62ed, + 0x1f999eab87c8d648, 0x551dc01264170f3f, 0xba7c75ad4e0e997e, 0xdfbf5763c418f1cf, + 0xacb6ba72b92c4c0b, 0xa701a9ff921d878e, 0x5d4290df833d54bd, 0xf67588f723d8b368, + 0x815e3eb30ff43292, 0x3b6b61223569d20b, 0x8edb036030e40034, 0x3804384da0da7346, + 0xb72ae0ff3f91c51d, 0xf1e7955f14121458, 0x84b0dffb02a38d5e, 0x2a538b2ebfd25a74, + 0x2ea2cc4b0317de28, 0xc3426c050e51b31f, 0xdcd9c0969f9863df, 0x10bbae42ee46577c, + 0x652c0e21b4e198f7, 0x5a5e26415dbfb4ec, 0x361b6a27ee5bac4f, 0x527c5a34450666d8, + 0x2628bc6d0f2af7f7, 0xc69185f49bb3b14c, 0xe7b7ea7422ccac07, 0xebf9f0934bdfd6b1, + 0xbb0c28b52a166e10, 0xd43c310b58bc085d, 0x49db070b995420a0, 0x12c4bb44b72b4c3a, + 0xfd7990c5cfa76aa1, 0xefeb2ed084769e79, 0xf1f4ca6ceda6adc6, 0x217d0cc743227012, + 0x9ee9506325a0bf19, 0xafb33245ec46f4b3, 0x9171c3e5713da8c2, 0x32065311ea3f3f5b, + 0xb17af92889a84d36, 0x8bb41b3a81768e0a, 0x4b4a60e09c16dfce, 0x6f82165af73f76fe, + 0xef28729cd3131be1, 0x2e2e6b3467ef084d, 0x034eba547990f823, 0xc7e9ff1731b0face, + 0xbfd2cbcd881602ad, 0xe6515e43ae8fec21, 0x193365c6787acd9c, 0x34d09409aa93c5cd, + 0xe7ac515c76670d81, 0x1155a946a38b0178, 0x0448ff9f5e5a175c, 0x1af998870fc39f41, + 0xdd0f17b6b849e7a0, 0x044287276c664788, 0x4c35b4674eef9358, 0x4d9ecacd482a1946, + 0xacfb090c2ca95b72, 0x0b2d9d9fc1404add, 0x3f56dfbde50e0478, 0x1e930fcc78a0d1a6, + 0x6090bcb793adf6d5, 0x5bceb13646e5cb9a, 0xc37fb75ec42335ab, 0x247164ab0b2e88c1, + 0x856ae1836d71fb54, 0xfa32f8960074a709, 0xb6053031639a0fda, 0x5db909b6a11f088f, + 0xc6b333f265327961, 0x64aa39e7ee9e02be, 0xe5c435676b5aedc0, 0x38bbab7846288185, + 0x3b3af4b084e93c21, 0xf9ba84cff5e4aab2, 0xfe7b8ab181cefe8c, 0x7970dc93a3abb53f, + 0x83662e4927744e7b, 0x825fe03b9a39c1f6, 0xa05afbc2eb85b459, 0xec0d6a0eda7bac3b, + 0x630e0b9a9e7e008f, 0xf162baf5a1de096a, 0x14c43cb8eea326dc, 0x0b1cce81a0f117fd, + 0x5ed2783cba7d1fc7, 0x15698133c8343049, 0xe5e64e5b2accc011, 0xff1fa8847f3f321e, + 0xd6c53b4f215db9b9, 0x37865188dc8871f6, 0x55918f66965e734e, 0x8cd0d6a2688b99c2, + 0x1825c9a54a8514fa, 0x06ad2bd8f5c11b89, 0xc7980f347e2806f7, 0x7575451f3f3f0fb3, + 0xd25afd14d64f2cda, 0x47c5774db2fc9014, 0xe3cf2b311f5fc1be, 0xbe613f1918577d15, + 0xebbc1afbaf183651, 0x8e1fd7a7c86e8672, 0xb3551d30e3aca559, 0x2af0f7548a87b3df, + 0xbe86a18f403d02d9, 0xbe7667739c710577, 0xf3ae8fc8dd1befc2, 0xcda11092ef0b8609, + 0xc0a532d2d4f1f0bc, 0x438d0b24f3e6d3bb, 0x92641fbec03ae1b3, 0xad30feb4d3d29961, + 0x5e04da55f5f1a227, 0x34c61cb61635808a, 0xbc97fb19484a326f, 0x2b0bc4ff2f23eab5, + 0x798aae3d827bff80, 0xd1885e665da2621c, 0xf30d937c90320f25, 0x4d5ad66bf1b28a35, + 0xed6a868c23ec404b, 0xe8042695fe29b19d, 0x07b03728e8ed6e81, 0x4427d1f371db1eeb, + 0x4b84d0d54530ccd5, 0xee960ecc37b42fa7, 0x0a53fea51938ea2d, 0x9b1620ccd742d967, + 0x0b01eaec56cc58b0, 0x775c2b6d99d128da, 0xe35df337a955f20b, 0x96ec13abe7e5cc1f, + 0x5a6c1ee338c87984, 0xe129606ae99103b7, 0xef680a415460db66, 0x7f5293053ba27e72, + 0xf638efad29a447c2, 0x3bec133c80241fca, 0x36515db203bd7793, 0xdb01c6b4c0155744, + 0x2ba45d681117ed79, 0xe5e25d1e32c2e6a5, 0xf8ef6e90e36f98a3, 0xd45f066251de4cca, + 0x43ceb28f4452539e, 0x8170acaed9cbfafd, 0x2d016ebb4448cf79, 0xf8528150e4ee0763, + 0x673a7c1561a5aba1, 0x3278e4229586de9d, 0x67e3db5aa73cdf6d, 0xdb5a987c1d1ab41e, + 0x6ebf8a10cbc2913b, 0x0c3bb0a4ca4ae5df, 0x21e5aa3e65736300, 0x6be3938b60f630a9, + 0x6d53fedc3470fe29, 0x60485160f7f2c84a, 0xd599d230abbc9f26, 0xf3194a36f28ae487, + 0xd1b54a66a34555e7, 0x3b24e4c77328bb0e, 0xdff3dde865908b7e, 0xba877ad12633a697, + 0x1a73236cba236611, 0xc50e1c1338fdc6d2, 0x3e676c15ab5bacf8, 0x0a13a19241fc80df, + 0x98b39a2da38de97b, 0xecff5a4f94d07f67, 0x502a193da0fe8a8a, 0xdcba794ad7cb47d7, + 0x58ec84f47c4a94f1, 0xedcb97c2404c0a22, 0x4bb35b16bed2f825, 0x58085d4b92b66c3d, + 0xf3fbebb14e87ab6d, 0x0cfac81a4d5b0675, 0xb986e8513ffc2451, 0x0c5bc57857b7026a, + 0xd504e39688e8853b, 0x468e16d8d493c2a9, 0x446730d5fa67cce8, 0x8cc8c2791c14af9a, + 0x95de43cf49c45409, 0x85280f7c319780ec, 0xa619fda30b6a4930, 0xb88b4f9004e84468, + 0x8b1b1fba47fc6239, 0xf48df5305e64c312, 0x05ba6dc628306108, 0x226e27184d3c78c8, + 0x7372d88d3015ad75, 0xdd1fb12c65cfd3df, 0xa0f6d036b40364a1, 0x7773aac7ca85180d, + 0x0272f3538a8f42dd, 0x80db715bd1134cbf, 0xb710fefd2e74fbc9, 0x8563c90564c7353a, + 0xe5baabd1cf1b8ec6, 0x10e8f1e06810f65f, 0x4b05dc2bc0370ef5, 0x6e78e87101d2c4d8, + 0x6daa03b3b84c8cdb, 0x8255562694d15e69, 0x35516f8ae84b1823, 0x5fadde6dcca820b6, + 0x89827d11b0129f76, 0x803bb1bb939615ba, 0x94449644695d491c, 0x62879d0a6c67d02f, + 0x83921456d321eb63, 0x94de208245486925, 0x514682786c0242b5, 0xff4e0bc3e3465c44, + 0x001eb9110f02970b, 0x9d360f599bae38ff, 0xdca594d4ce6a6df3, 0x25dd74b6db2252e8, + 0x791cc122b538d11b, 0xdc475a2a188a8e6c, 0xac5414876828a3a7, 0x9384d2648fd8bb42, + 0x9bd1ced03e8a9013, 0xb7e804c2b086596d, 0x537ee55721f8ac87, 0xc4c849855b10ce0b, + 0x75ce9cc0422e4f19, 0x600366cee14d194a, 0x1556464a8608f8b5, 0x3f1c56d6092f32dd, + 0xa024860f9f213420, 0x2dc5da2f9b3c7f89, 0x22f2d5f433e406f4, 0x0a80fcd6b13e8541, + 0x288e07a2e2186e94, 0xa82804c33f92344f, 0xc11110a2cbead10c, 0x36bb0044cfdbf959, + 0xe121b026364b0d77, 0x5248a4cea833d9d4, 0x21271c6ba7350b3b, 0xd29f31eccb510604, + 0x57873f2d9604b8fa, 0x974a949bb0541e48, 0xe0ae231ee67d0870, 0x4ee35448c7362f9c, + 0x126cad157654ff51, 0x1ccf52e4c4634434, 0x291710a5b54983e2, 0x44c3ff00c76576ce, + 0xca0cd02f2e42ffea, 0x6d85405eeb23daa6, 0xbb313a2e755ff0f0, 0x953676d0a48fcae6, + 0x39084f920edd856c, 0x087599fad019da46, 0x1ca7da072010fad9, 0x2c964d52914ed2ff, + 0xd7905aa2f8fc6157, 0x6bf893fa451f8844, 0x9d388406f8112422, 0x711450f546fc6ee8, + 0xb428b3ffa79db352, 0x4dc8d369ac4599ad, 0xe1d90ba6129bf63e, 0x2c7d57ab645b862c, + 0xff30037b58b3d985, 0xeda9e62245f8cb34, 0x84a240366d02d6e4, 0xd995c2811d587334, + 0x2705fefbb208958b, 0x0a7d125cd8a004aa, 0x7d305afd992a0111, 0xd667ea21b4cadab6, + 0x88c4700949920f46, 0x59795a204dc41eae, 0x4b24ce02a24fac2b, 0xea454c6fbc3b1457, + 0x09b004d5725aefb5, 0xd19793592a0fc855, 0x2e5b8dc2d557c990, 0x8e3405542277c423, + 0x83a0804974c0842c, 0xc7edb27fe946d380, 0x120b645f99c87dd2, 0x52644cd25dbf0b69, + 0x2fc2bdf0c6fb3393, 0xff874e321641ce96, 0x2f03c261d8510302, 0xaa8941b91888fc8d, + 0xd5e1b83119e35d3e, 0x49a459b8e91f0e3f, 0x8b36de1c045386fd, 0x6c1a7bbeb803f2bf, + 0xac3696f05e24d9b9, 0xd56c41879e52a0a8, 0xf1188c1c5d640e4e, 0x70f6b11ebce4c7cb, + 0x5eacef67cf1ce2a7, 0x0cc7933561adac50, 0xfe7dc27823ccefe5, 0xd381e0a3b1ba6682, + 0x84b57bee78dae1c2, 0x49f9312c092803fc, 0x632a029375baba94, 0x03affd661a6415fd, + 0x7ffe21dd89984ccb, 0xc23919d46bbb0f66, 0x93f149875f525ab7, 0x3f7a99bf356764b3, + 0xf30dcec0978be581, 0x372a8b6b270286ef, 0xf9b92a3d25679768, 0xcc6124949183090f, + 0x0bd22be8d1d110c4, 0x68f5d5297dbc876a, 0x5c61049caead8d6d, 0x0583700371020f27, + 0xdb23f82f0d94a924, 0xc83a244b0d66658a, 0xf0721b693f685cf5, 0xbd99742d09d9a1e9, + 0x8ce83c7ff91d8877, 0x9c00ad5e4899872c, 0x7a9ce66c977b536e, 0x75005368c68334d3, + 0xeb1c6260de15a27f, 0x40aae370f0f5b1b3, 0xb84e3670acb3add9, 0x525edffa86187c78, + 0x758ba461594b6f0f, 0xc6d6f9c6d394e553, 0xf651cfc061361a39, 0xe11be7a5e7b291f6, + 0xb9b93ef86b643a01, 0x4d6bd93757908c49, 0x767754b9b6ce6c8b, 0x9be6f441e1bb0192, + 0x5a38abb5a5d848f2, 0x486c6a23974ae781, 0xb328508ba7307455, 0x7d9ce9c86b03ea7e, + 0x03bb58e6bdfa39d6, 0xfd20b608c59dfec5, 0x581c9daa35477b59, 0xfdd477c393dd8830, + 0x60aecdbdf34a5271, 0x4933253867cb51bd, 0x114ddd56b20e015c, 0xa8ee8ac24d4eaabc, + 0x1541495c64bf3bd6, 0x265c15e7bae82684, 0x10a6103349cd7723, 0xcf99d8469e6d2937, + 0xd157ff74e147db1f, 0x12b2d9ad340d0e35, 0x485142e395af3f5a, 0xc873c8c19b0a085f, + 0x976f607d11961faf, 0x3c44ccffb04e6c1c, 0xa3a8d7462123b8f9, 0x3b35fe642cba0482, + 0x666fed4b4d03f9cb, 0x518e6a9db0f7a65b, 0x059759fe417e4ad7, 0xd30e9734359aa77c, + 0xa763eb7b845b2c24, 0xaa07616ec1108086, 0x0b49c7da3890f553, 0xc1e46ce4e82e390d, + 0x7a3bc2c88cd84737, 0x1647337316aa17fd, 0xdf7e7af50ad76557, 0x096fe7b29faa33d2, + 0x52debf3c9fac977a, 0xdb1cc3d929b56bb5, 0xc4fbd2fef8a00ce7, 0xcdb4f656b768aaa8, + 0x1bf02c90e4574541, 0xb6872d129f6f0a57, 0x9ae23b95316671c7, 0xde22caf792ff7099, + 0xc61644e8b95f0c8f, 0x6eb676237d5673d4, 0x3d478b893bf4aaaa, 0x04c381d407510043, + 0xc26a456a19076a6c, 0xb0516879ba1f99ab, 0x9dbd57aa34f1842c, 0xe42ad2d58cb5589b, + 0xb9c5d97cca386925, 0x053c7be2b7358ba3, 0x49c3b14c0b8d318b, 0xe1d48901d0c8ca55, + 0xccf46702aa8f4cc6, 0xff9d22b54eb3ed9d, 0x57c550ecb4d4a63a, 0x3ea67ef30102b03c, + 0x11b3996f6df40987, 0x3db9e0131e7c88b7, 0xf2e8675174439d60, 0xd1d82795d81adc48, + 0xf1e745c4e45c0029, 0xea97ed9e69d0e9d4, 0xa3a5a5685bfc1f94, 0x16438c326caf5e44, + 0x9ba950d62e00cdf1, 0x84f21b4ede6177ca, 0x0641db881a953f0c, 0x010765b3fc469da1, + 0x658c2f0f84e0a5e4, 0x35de32d87bc7a595, 0xe6860706ad7a7430, 0xe0e58c2800595328, + 0x5afab22a18fc3c4e, 0x951efdf5cd92e5e9, 0xf08bbb084bfed598, 0xc8864d6ec9331ca5, + 0xa912a95ed9285f0c, 0xf127c60ce343bd86, 0xf6dd5a34fdbdef49, 0x735a23b9a57a5fff, + 0x2baf471c81515ddb, 0xee3500e0532d6df4, 0xfe093f860f193143, 0xf6e9c62b5b347205, + 0x51ca076f8b36d961, 0x5503ea9faf7c2917, 0x48d5cb93912880fe, 0x67944b5c28ad739c, + 0x079f1973e99f18c5, 0x3892e1ed0ae8f3c1, 0x487eded21df64f9d, 0xf4536971aee2ddde, + 0x8ce1bfd3d68ad04f, 0x786e5b62e53c46e0, 0x98bac7191444f53d, 0x66839dbab2c6d02b, + 0x7c8bce319bb15e84, 0x2675b8e555f8af55, 0xe61fd18dc23b9d86, 0x1ed0ec1e61de209a, + 0xf68a86bc64aeb2c9, 0x5ae5ae6b1972d6a7, 0x1531025fad24912d, 0x05eda620fb6a77ce, + 0xbd70160d482d321d, 0x6b87c10c6910a764, 0xfdca6f279c438eb1, 0x8afd9cdd1e60adcf, + 0x9702de073113eb68, 0xedf26d2ebc49a6ff, 0xa0c7aaf785faa386, 0x701723acf7e4300c, + 0xa1f4fe88355e2f86, 0xc931578c32c7b4f5, 0x57e6c85a9eea7a78, 0xfdb7febb7084c1b1, + 0x15b27578256d5710, 0x75df5a9f946389d2, 0x6a10786c27f60f67, 0xd13db34fc32cca10, + 0x2ddd37827eb5e2cb, 0x4153e6262c799542, 0xbca50b3546f5162f, 0x8cfa17d08a59bf18, + 0x76555e06f01fa2df, 0xf9b915a9b1c8cdc4, 0x6d7c7ef629a15f35, 0x659da55c6c53254e, + 0x5779ffb3cb86887b, 0x807cc7f441b4b187, 0x008ce572e9e1ca5d, 0x9ab1cf7e050e2255, + 0x38a06ee1a595643e, 0x24f7f022f39b7528, 0xada6a3005da8c730, 0x10eb7cd0a3f86b40, + 0x632772584dafdb86, 0xab23c5ca2bc3c0c1, 0xeaba26809e095806, 0x75cc973b7e82dcc6, + 0x59caf380e8699998, 0x38347a8bb5f3e007, 0xa1f4c243428dd443, 0x520c1afd2915aaf1, + 0x731ed8e7507e9e12, 0x683c6d72461618bb, 0x0f761e848bbce97d, 0x890e7aa52d6e908c, + 0x8a795b05ef1f4b21, 0x146f25796b7c0b6c, 0xa9db46dd8a0eed1f, 0x86176b1287061de4, + 0x96cc303d723bd1f8, 0x8b77fea1d5d87212, 0x74d592acdba619f9, 0x2d51243334d9dd2a, + 0x66a34394276e11ca, 0x7f9c203e8e62a3cb, 0xc4eb5a154d8514a9, 0xfc896dd3cc50a2ac, + 0xbf0d7fd967da230c, 0xdf25506739d3c42a, 0x97871d8005f68e8d, 0xefcc7e6e7456285c, + 0xdbe5ca6f2e123719, 0x20cbc8e38bc268bb, 0xd17d079abc4d7986, 0x5668ac37d32df205, + 0xa047c0b5bcd21805, 0xb73f7e026d741cb2, 0x1bc6c2d2611696a3, 0x4fe69fed9f7056e1, + 0x3c01109d7ab2ec7d, 0x83a40f93e8901b39, 0x87004ae5a176dd1f, 0x8b9ae7935207a7cf, + 0x2c35bfdffb4e3c5d, 0x1ca5fa81c416e79e, 0xc96bbcde55b79ccb, 0x4b5dbc610429081c, + 0x5da5a050c67b8c89, 0x12f4468a10d7aa16, 0xbbba2ddae73f1330, 0x24de15d7fe7d64d1, + 0x55d32d5f59ac4032, 0x8ad2de93498c9c22, 0x15097bca5e06c066, 0xa1c41297956f998f, + 0x24585f555ddca960, 0x26a9a02e79ff6d01, 0x29974316af6cd918, 0x8f0c4e124227e62a, + 0xc06837915350aba4, 0xdc61db2b0feb4690, 0x6762534cca16def6, 0x844ce6d7d93804e1, + 0x1531677b40dfca94, 0x463b1052a9120281, 0x82021d8457aedc1e, 0xefd1d5d5a714aa55, + 0x988abd81956603d5, 0x8bba91a1b8b66aba, 0xc0c7179ee212a7b0, 0xa1b368cecedcc421, + 0xa107b55e2e15deb2, 0x89a8653d8070c4b2, 0x27a00795381198d1, 0xe842780d7cf406d6, + 0xa05af3d6f2ae3110, 0x874a4a5442978569, 0xcb283b2826a350b7, 0xb3a34521c47005b6, + 0xf5b85e588f6ae236, 0xa633e9da76dbac1b, 0x018f63a3c4206f0c, 0xe902487c55744dc7, + 0x9a64faf59c91b256, 0x27261ab2566b825a, 0x505fb59927a9d6f2, 0x9e8ac9e82fac08c1, + 0x0980f389db2233b2, 0x4aad46944c35475e, 0x582ace01bf9a07e9, 0xe31d992497f30151, + 0x4e5e841705cd8030, 0xc0ebd307bcb517d0, 0x6e00144bf7aa6465, 0x68bf3a5d23e2a451, + 0x7775b165d058fd4d, 0x333b2ef38a83028a, 0x8a8e5ed3b5f05bc5, 0xe2b6cb51765dffd2, + 0x254311881cd29b2c, 0xf3e08788eaa8299d, 0xfe5413491e2f9aad, 0x17f1de18d622d5a7, + 0xb77ef53de3685c16, 0x96a90813f2c9e5ca, 0xb66e2a1d31d0ea27, 0xa30b7cda6415c2ea, + 0xea5d8c0332e1169a, 0xdac565fab2953579, 0xd368a5b63678591a, 0x3e9e94082e323aab, + 0x8c65aff4a4b66459, 0x3986d2a068f5bc73, 0x7c2f61afb2b21833, 0x5a56379711b8bd38, + 0xaf81029472abee3a, 0x711b34e460250cd0, 0xb0626dfc43885ac7, 0xca1b7764f06a0e7b, + 0xa88bdc11bec8c039, 0x6cd4af4ecc6bc58b, 0xa14a30f68ee44183, 0x18c4246a0e9579f0, + 0x51f0752969f39d8b, 0xe2dc6dea0854fde6, 0xf0822b4869a62980, 0x3d4ee71e92a2b5b3, + 0xb01aab5a138b940e, 0xbf20d0ae9c2d98f1, 0x7d439cf6cad03c1f, 0x68a5b02dfd97e70e, + 0xae1559a31e86242a, 0x47129fc295561089, 0x42b5ef30a05654fb, 0xfb0490fbcdd7fc43, + 0x3af0f2bfce2c8106, 0x50acf99de12de893, 0x45554a7abebdef93, 0xa95cea3ec444a518, + 0x361c6d1dbf532dad, 0x104ba9c52139eb46, 0xd82f036ef8e62972, 0xe3bf5c43b7cfe015, + 0x6e4ecb4b010852eb, 0x294695c26bd5a19b, 0x7545f7614335d132, 0x6bbe738e8e9cd014, + 0x437874873d59fae3, 0x1a642f8ff3bf2eaf, 0xd0975b777abd7af4, 0xdb98c39c2472a4fe, + 0x8904a249bab3eb24, 0xfb2e065542a87ce3, 0xaeffd20a61cec0cb, 0x69352f71eff9ab35, + 0x603d8a901f0d3fca, 0xbb4f0c5d7d456262, 0x2638ee897cd3f789, 0xb4a77784050d703c, + 0x5be6b108913c26fb, 0x38be35371d2e2d02, 0x3837339f8809893e, 0x60d10df11dc812a4, + 0xe5a7b893ad28009e, 0x2e78ba212bf34abf, 0x66070574fa6deb06, 0x9e3932d414c774ad, + 0x2e3e575ffc95a337, 0x4b651f093407b19f, 0x1967f4679905d9eb, 0x2b26bdf1217ccd30, + 0x6312156c94f7c56a, 0x0e356ff20fec666e, 0x5bb08f48bd9bfa31, 0xfdf99d8a3a77b220, + 0xb200f24929040510, 0x9309fa8e0df272bb, 0x9338c39fc45c5fcc, 0x4165eef972184767, + 0x921f3ce1d2570738, 0xdf8324955796ad2e, 0x19a1337b134e19ed, 0xe40f67a824378062, + 0x3c77af462d31210a, 0x49f14f7fcf191d35, 0x0dc138d24cca183a, 0x12bc60e66d823150, + 0xfb428169c8ee1542, 0xe90d2708848d8bb1, 0xd0031495d83fb68a, 0xe00271cf727f0415, + 0x86e194f43cad9db6, 0x223cf8e7d9f87d20, 0x75595e1d6bf9e28c, 0x8f61389183d032de, + 0x5943da7b05a5a4f0, 0xcf7a54e90e09ff27, 0xdd3b65b0ad2d430b, 0x9cc67a371a5fbe54, + 0xb3dbc3d93e875c10, 0xa55af470429455ec, 0x26ea48a9a533fbe5, 0x03bc4bb30bea7531, + 0x6fa557845602c634, 0xfb790ac11b09bef6, 0xd7b00d2addeec181, 0x1d7ef2bcaaa182ec, + 0xfeccd8fef0ffed48, 0x46ae488e9af37784, 0x3f0a65bd8ddac848, 0xeda8a54a84c7db77, + 0x5acd96e73e7cccd5, 0x91df8b942d79b7d6, 0x2fd509eb680af888, 0xe53823d0022deb79, + 0xc7b4c0fec49335d1, 0xd4adfdab79cdf41f, 0x9b1e670c2a1f3603, 0x3e42b951239549a2, + 0xa77dc1f3dfcf047e, 0x3f81ba6e39d4db2e, 0xb7cb754a92addfb7, 0xf2b043daef6f5c51, + 0x231421640f8e58c9, 0x666c2ae3eaea7738, 0xbd2eae1c92e84044, 0xbc82baa71a5cd08a, + 0x63cc08fd2831be84, 0x9407bb8e33ce1bfb, 0xd5733d072d893568, 0x0e045b14954bc9fd, + 0xce18e8a1add59adf, 0x7dbdb10c0781af0c, 0x601997a369228acc, 0x16203d7dac717474, + 0x5f8c28eca6f4d222, 0x6aeb5a543e0b2f6c, 0x76b40c4ca52d8c43, 0xd8123a4713d1b774, + 0x9142e92ef17f74f7, 0x2be60926ab4a9926, 0xde0c7008ff03659d, 0x547682034efec13d, + 0xf64a67ae20ba35a9, 0x97d5f0fbc727c4c1, 0x84821519687ff379, 0x9a6fcf054e5c2c2c, + 0x0256dc58143168be, 0xf9de3cfd7d836bae, 0x934f6044e158fe7a, 0x09f61790a7f8327f, + 0xbf7d3b660142d860, 0xd82816a085c84281, 0xaf00df2b0db3616c, 0x824755f83e04021f, + 0x3d86bc2c4d0eb6e7, 0x0377e26be02b1600, 0xfac4b33dce67a2c8, 0xf6a077f29cf87bf4, + 0xdaa2a520f9c1b590, 0x21ed4a43778043dc, 0x099e007b1046184f, 0x07332ba0a13f3ce7, + 0x4dd02f8ff369c6df, 0xdc858b7247d6e624, 0xa67f179b0eae79ae, 0xcb191725966f0b8d, + 0x04013d4b7ae563ad, 0xbb94ebe8fb101cd1, 0x4a27e47bfc6c6ce6, 0x584171cc5c54c6c5, + 0xfeb9ec8af722a5c0, 0x631e0498e08aa19f, 0x5ff0bc40bcfe4e6d, 0x00eab65e934b3ace, + 0x70e3545c7a09de77, 0x5c432d4ba52db20a, 0x45ece20df417435e, 0xbac8f7e7e8433d7f, + 0xdcb8666820aaa473, 0x9da1391c21e1d570, 0xce86cf70d05b341a, 0x835c179aa3e57355, + 0x2e5392587e60aaaf, 0xa897b6a47218b85a, 0x552215f524f03907, 0x6d4f55b9f3b7dad6, + 0x7658380b330da9db, 0x2a6397611b8cb577, 0x756598a3d805c879, 0x63185d6e2f900fa7, + 0x15298bb8136cc7ac, 0x4939bb3f98030099, 0x4329fbfbc10ca4aa, 0xb8854f11deb03811, + 0x25116328c87dd8c9, 0x681c6aa288ab5edd, 0x6bdf1f47a59bd3ad, 0x60c8e05aad3afb74, + 0x60b4d735eb27e581, 0x30c6edf7375209fc, 0x7b4bc33f37871021, 0x016902edc9bc3d4b, + 0x87598b818cc76647, 0xe4d2f0d4ce273d50, 0x9e60271ff852edbc, 0x65f4772c2c5153e4, + 0x984d23216681ac49, 0x06315c9293173b76, 0x6b81394dab386cce, 0xcb9a60979248f9e7, + 0xa3bcbf70092e356e, 0x8e485e0ae55e2fbf, 0x3deba59867354745, 0xed8e19c8f5aeb007, + 0x0fc5366b2844516a, 0xf0787092414ac62c, 0xfd0dc6a79a391bdd, 0x00b632d5e29bc851, + 0xe9435fdd6c02ed80, 0x18b0465ce1d34702, 0x91d93fa72dda5b98, 0xcb00429aae5ba1c1, + 0xcca3a4bfd8eec3f0, 0x152aff9333f6422d, 0x307e9b2b210a7286, 0x4330534cbce43e1c, + 0xa24b4e7eb62f81ea, 0x9feae875867d079a, 0x22c2f6554fb1f052, 0xe44b6b16df285e74, + 0x76c4981976eba103, 0xb2e660a177a1b405, 0x6765bc0744443970, 0x1adb8ce12c39ffe0, + 0xe73e595890260e15, 0xef3a51c2a323cc3f, 0xd4680780ce067e2b, 0x18bdc1e0138d7718, + 0xe58e8de7143e3dbb, 0x7a8fe5d6b18b8bcc, 0xf9b15f1a5ac71cac, 0x07e6729aeb96a9f7, + 0xebf3da95e0c2d599, 0xc1240e762cb02eeb, 0xf1352359c1db98ea, 0xdc3b799e91f222ef, + 0x0a4d60448a7ca598, 0x36810d0b875f5dc6, 0xdfd28e6b4b9fd2c0, 0xd3ba54564d5ceb58, + 0xacec80baadb1492a, 0x6114be69ad9b9002, 0x03553a9f3128a0fb, 0x7463e4dbe892d00c, + 0xd693a80228b36e22, 0x80751f47d3daf342, 0xffbb1ec857b15526, 0x5639c6e72ae1560f, + 0xdae0414cec888f69, 0x011e3bf269741587, 0xd19166d49a925650, 0x3bc6ef116ce11941, + 0xda70f8081cb4fc75, 0xe66f884df3f2912c, 0x8dd83fb94706d96c, 0xa04c4efdea6afa89, + 0x69d0435761a09e82, 0x35cc269068f3fa4d, 0xb925e452526146e9, 0x22b352d5a5002135, + 0x792cec1110b2a765, 0x4c6a1614e4dae95c, 0x79719e22b04a95e2, 0xe22052eae2e13e5a, + 0x6a7238a52539f0d7, 0x8a0f377a8e204b3e, 0x7788bad972992e58, 0x6f875733387b5b83, + 0x9257972a0b488987, 0xb40caaae724fa6e8, 0xb2d89e6ae6c5ee7c, 0x6104435a21b77bb0, + 0x986ddbbf979af5df, 0xecaf6bdc61e33be7, 0x45e9c729615d5b65, 0x0892befab55ce136, + 0xb6141f6aa2337dcb, 0xc3c5db89f28ce416, 0xd3398989e215a87e, 0xf1f63b86bfa1536d, + 0xe7625f16c187257c, 0x9c9a7ef9eeecc07f, 0xfac5050af18c13cf, 0xebb43abff6e713be, + 0xe3a33a4cbd01c317, 0x21ada937140005de, 0x55244e0f39004739, 0x8f2b4448160c66f1, + 0x83d16ebd9b4ddb77, 0x8623d713704f5fbb, 0x9045f1883af96844, 0x6a7760a60ceaeb7e, + 0x8cfd062676b52592, 0x9d6fb66a4eb53b1a, 0x43903450a16fca9a, 0xa5533fc9625a2f5f, + 0x8c26c4b0bbada818, 0x63ac76bece4bff58, 0x3be3f7db72d94029, 0x50e2b42d8280b8e1, + 0x6494f650fce2bce9, 0xb65dd994c7cef393, 0xe5fe3c505a85fe6d, 0x2b03581820340cca, + 0xc20396501b5ca00a, 0xe1587cb0bfd49c4e, 0xe178c083281e65fa, 0x92cd0b48330aed3c, + 0xe2399d0402b58a4e, 0xe929b086ef597f58, 0xe11b42bb6f353499, 0xfaf742bd50e2744e, + 0x6ee8fc37c316f8f6, 0x5f2ce60fb02caa99, 0xdf103c3067f122eb, 0x004ec267f0ac8bb6, + 0xaa71d703fe199442, 0x48be9e28144bda1c, 0xd2898ac22d18aae1, 0xfcd42d82b02a4c8a, + 0xbd4d6c6b0b283c9c, 0xc98b7dd982b5f484, 0x4bf931753115ed26, 0xe22a764b2c76b4fe, + 0xf86b96c66554f3b4, 0x24df9fc44385ef01, 0x6bdda1f7ef1c0aed, 0x701008900e5cc3be, + 0x8b27319fd8205491, 0x92ce807f58bb3a62, 0x60637ee6f010b3aa, 0x43e049437ff6f8e1, + 0x726b27bf47cd47e6, 0xb18f23d71ca363a8, 0xf8515afef6427f29, 0x303fb1eca31d4943, + 0x31306e225b7f9eb5, 0x138b5d0f4fafe917, 0xb5e9b3bdc5dea9ce, 0x88a344eb8ce710ec, + 0x12d52a808d02623c, 0x06a1aec77d5bd9f9, 0xe67a93d41aa7dc20, 0x519a5ee1f9ee711f, + 0xa486c12923a46f8c, 0x6d14147f822fc06d, 0xb1685c72147a28e8, 0xaa83f0ce41f43423, + 0x9725ee6cc0a2a926, 0x836085dd3014cf05, 0x3d2223a0977ccefb, 0x4360915e79383583, + 0x831998dbcd91734f, 0x8e3dc8dd1cb2a3fb, 0x6dd3ee8715c570af, 0xd330fd8bc3ab1a3d, + 0xb00c4cb20e975a08, 0xc7db11d82ef74ebe, 0x2ed9126cf16130b1, 0x2d52a173eb0fb798, + 0x003bec1d9d57bcc2, 0x49bc1305f0775089, 0xa1a924c41d5721ee, 0xe8e63e150f50ff3f, + 0xf96b021b86a31a22, 0x011bff0f684e6e81, 0xa0179117b795724f, 0x1197a07ea06b8de7, + 0x4521943b918d7fbb, 0xeb5ba9904ab5f361, 0xfd821bd37cb8c2f1, 0x8b931ef1c2135448, + 0xfd46452625bdd7f3, 0xf0b1231e5db45953, 0x063574d0352432d1, 0x82ea03ace1b40a2f, + 0x05e5ded3e4b1e8d8, 0x929ed8e193f210b5, 0xcafa3501c9d23979, 0x951940d8e3a69d8b, + 0x696e947938774ded, 0x147979682a18ef8b, 0x64cfb7ba23444509, 0xfe3dbd4a2678c8b4, + 0x5d50486a2943ce7d, 0xf7222fea75f07257, 0xc140e5b0c1f25859, 0x8604d373d2765a8b, + 0x29602fab895949d6, 0x1b6e14a6bce7fa30, 0x19f61b45c5355e32, 0xb895fa9656ce89de, + 0xb8afc49f571ec0d4, 0xe56969e30152e02e, 0x74539c7af5f50e6f, 0x5a7ea420d31a7d3c, + 0xac582548335763ce, 0xa8b12e35676c0de8, 0xda82520b12336b18, 0x04499654b13b0bd1, + 0xdfe6468c8753864d, 0x7ee5695d4f872b1c, 0x08f7461dc0dd0cd9, 0x267b013c86732a1b, + 0x06478f206462df47, 0x02dc7f8ec0e99c1d, 0xbafa7e776f12806f, 0x58213eda30327e00, + 0xe2892ee9f1cb11a9, 0xddca2f7c6e0792b9, 0x90271461bd8d71e9, 0x08683789d66544ee, + 0x2dbca0d9eb26342e, 0x43d46010227659cd, 0xcfae45ea00b3fdbc, 0x5ecbf2bf17ea65c3, + 0x791554c64f37f26d, 0x3d0d26f6df9c5b63, 0xa657556ed490b7f6, 0x3d1d22e7da2362a5, + 0xb60639be2f7b4a77, 0xadae7f0f837ddf1b, 0xb4953abd1e95ebb0, 0x20e5d84844963b91, + 0xf2cf0830be795c11, 0x30ab128456d11b0e, 0x40c80975c19caad9, 0xd7e530bdc51d92d7, + 0x2c6744c46292101f, 0xd530741d49685f1e, 0x331a35db27d5022d, 0x3b7a6be9d0ab3676, + 0x35338d814da4c6e5, 0x35e88f4d275bee8b, 0xf64d96f442824de7, 0x2755956dc495c4dd, + 0x185a318a3c24c1b2, 0x771c72dd813e5632, 0x4554313faf5bd65d, 0x847a8bf9e5193ca7, + 0x9aa1341676d7d991, 0xd8bdc4abd11cab4e, 0x2e57e96d27e923e3, 0xd8b1b5d20bf1b4ff, + 0xbf30ab6ce0d2143e, 0x4e8c28e0dad171b9, 0xa0bcf5e015d8f27b, 0x435fe4979471817e, + 0x52884ad5233cd7fd, 0x5c02de59b26eac44, 0xf17fa5ff710ae52a, 0x20f140aabdefbd1c, + 0x0898a3f42f549cbd, 0x563ac7b705d77b96, 0xc38e813a9afd035d, 0x0b08441064a508e9, + 0x55de827191737ed3, 0x8de5b2fa9b2f21c4, 0xb3ea94080702e6fd, 0xeaec40606e224e73, + 0x1cae950c1d06e95f, 0xfce0e0d0093d8102, 0x0e5dbff0ae87da7d, 0x4f21bd58804289eb, + 0xe2c283f5aaeaeb91, 0x353e0250bbfbddd3, 0x5d86e1a7e8183fb9, 0xcaf06c277668bd19, + 0xaf2f9b92c119e1e6, 0xbb60620eef4aa9fc, 0x6db6bb70cb9db9d9, 0xa7ca3a32bff2b1b2, + 0xcdae6d6ccc43b15b, 0xc4ba5a3ddea54e1f, 0x99e2b599ca42092e, 0x7a8a32283309b008, + 0x5a0ea54020c0a459, 0x02db74b093dc5e5e, 0xb28c6c32d5fb07c4, 0x56a6b5b384e75d15, + 0x5efd05aeb6a3f34b, 0xfd3f3480f1bdad11, 0x1c7f54350aa49ccf, 0x4339ee25899d5fff, + 0x4d77212ffa386f54, 0xa4c6f10b0a3a4b3d, 0x8d70f861fdd9fe0b, 0x52eab4e040c0215e, + 0x17d442065e8e1bfc, 0x0fd6868858fd9a05, 0x30f7448e8c12a773, 0xb3c655c9df11500c, + 0x6399bb856719b704, 0x75c2a6af0f47e933, 0x2e6234d056502aaa, 0x5e405d9550b05a5b, + 0xeb94a7cff8bb575a, 0x2c23da687104266f, 0x336dbcd7d56bc0d6, 0xb8ca1e01cd5d7a9e, + 0x52c172be3fd87df7, 0x0896e6254d54a0f9, 0x15dd274ddfc4b099, 0x484148e6682e3aeb, + 0xf06cdb9a724589df, 0xeca9e17eab4b653c, 0x4b6ef73fbedfc887, 0x10180202b532c92d, + 0x8fc9498669fb35e6, 0x2624a886af623c94, 0x7131c6ff6dad97d5, 0x20c3da4608e7b58f, + 0x1e36bbfaefd0d616, 0xe3dce9f218f7de78, 0xfa62e34531c11f2c, 0x62e189e841d14ca8, + 0xf266d6edb307b251, 0x823c5c686e4e2144, 0x7e1d19e32ac6d5fd, 0x8eff8862f0ba61d4, + 0x40557acad81c5c85, 0xd13ff4963daf07cb, 0x185fa2eb0a6545d4, 0xd223823ea11c8595, + 0x63603fc351d70950, 0xc38c270331d65bd6, 0xa1005c55b7c59e27, 0x01686651817df2ae, + 0x4a435deaea063512, 0x1547641a364d81a3, 0x52a35d16f423e7d4, 0x788b49cbf5a86371, + 0x2ed717ce8ea3bb68, 0x49831307ef96d5ed, 0x22d4a8bfa35149c9, 0x64b8c5abe78a7813, + 0x99f41728c951f7e8, 0x94655356db786cf5, 0x6d393de9cb352d9e, 0xabca521211eaa2ac, + 0x5c9bfd8e9e150418, 0x6ab3e4d2e2610278, 0xe7d488e7a045a8a3, 0x131991eb5ecfc408, + 0x28d1a1a57baf509a, 0xae3fb89bbe60b7ff, 0x14c5bcadcc6f4769, 0x952a3c5169ac2569, + 0xdb2f099ea0861b46, 0xbe022ed894c5b38d, 0x545934f1d4bf79f1, 0x73a6b6ec394c0805, + 0x5d85ecd69cc6f5cb, 0xbc90a891c69324a5, 0x55b66c8eaed01af2, 0x285259c3e2d60b9e, + 0x5e611a230231fda8, 0x147ba77bef350276, 0x16f990e0f8681661, 0xde95ba8fc66d5d0c, + 0x8fa314cda13610a3, 0x9264158ddb36607a, 0x9b176053d750df1a, 0x594dce946810afd8, + 0x045e0e5bd92aaeb2, 0xb5a6333fb9e1cd1a, 0x61a9b5d1f1054cb1, 0x2eb4384401c4f708, + 0x0e61add50688a190, 0xfb4e68d0c9bfb741, 0xf1426640ae78dfbc, 0x43b450cf78c3efcf, + 0x45644cc65dc64dd6, 0x5adfa9ebfd8ced15, 0xfb6afd5c95267112, 0x48975ca21a6a21a4, + 0xc3023ad35bdadf40, 0x7a683c8b12b6ebd8, 0x98e151f584b46c3c, 0x02840ed66e9915fd, + 0x9f8bc359298655ed, 0x49725e906b54f56a, 0x107b268889f72253, 0x78c9e5eafa37c510, + 0xf33494a6426d569c, 0x750d1b4a23910b0b, 0x04d5423f82998d72, 0xaf985f33bb5d6804, + 0x7fcb45cacbc16cb4, 0x27ad6742f80c9f3e, 0xade1f456973e698d, 0x07c4dde77b32eda3, + 0xe95e908d4892c97d, 0x61bd34943fe2774a, 0x95dae59d3009298b, 0xfcd159a901d0a8a3, + 0xeb022e747a9bba47, 0x384e8b297a3600cc, 0x614dbf4f2c3ff5c0, 0x71439c824f6be963, + 0xb82ca378956c1673, 0x2830d7f787fca139, 0xfe96bcf4d7d2ab68, 0x45a7018a030b7ee3, + 0x836a637e366416bd, 0x9aa6a0de17c80088, 0x5578ceeeb2e9f332, 0xef71f48296b7068e, + 0xb8231b2aa5c6d089, 0xcd84693dd819222f, 0xcdd94d170a1ed0bb, 0x68c6e4295209886b, + 0xc65a86a352df4657, 0x9c9f4c89d36d6329, 0xea85e9ad10f8d063, 0x60955b1303ce25c2, + 0xe7c6f4801122d0c3, 0x45b9d4c62cea42db, 0x824b2dc9257f4ad7, 0xc2a29d4ec50e5120, + 0x08796a094d641258, 0x0d20756d86101a11, 0xfa01f478e25490e1, 0xae1e2bbda20fc36a, + 0x30ec95c3629389ec, 0xf49941b37d4dc502, 0x95b6137bae3bbff5, 0x8479e65674fa2841, + 0xc366d8ae98e23d62, 0x0560b2a85f99fadb, 0x0645943ffe0ebb50, 0x97ff6530ce63222f, + 0xffcc588fcd88b6b5, 0x0b5d088d1af64948, 0x13a4125fcbed8d98, 0x60eec3dc5351f514, + 0x0f4fdab56c12f196, 0xf42b6479dfe890d7, 0x49ced3b2a341892a, 0x6f489e11c4f2f563, + 0xa3e7906e0800ea4c, 0x6d6ce56e88b19da8, 0xad7accea715a24ad, 0xdae8b66df39afab4, + 0x649143bfb795a97d, 0x620bf33c23fd9963, 0x6760b747c5c7026a, 0x093b0d9a44468ed3, + 0x4425f8c50a663eda, 0x19ee9facb7a5b74a, 0x645fd5fd07216130, 0xe5f9d7f2ee47ce18, + 0xaa98b91bd0b2a13a, 0x06542db41630a300, 0x4969e39a29867149, 0x9dcc7e7456ec3395, + 0x2c373c23325f2b6a, 0x5404c9305a2b2365, 0xe00d26e935b40505, 0xb66338b1af315770, + 0x565eb7b409b3a5da, 0x2b895a2ccfacba17, 0x17276deeb23bb4d1, 0xd5d0c79382703267, + 0x3282097e99075f11, 0xa075a1ad9d811f39, 0x70ef1c6f2a10ec8d, 0x42dabc23f06a0488, + 0x2596ad1992db6801, 0xb96d38841788db1a, 0xcc6405924429a4e6, 0x3eb9b87096205aaa, + 0x7df08c803e4ea5f4, 0x455beb421eeee810, 0x2045728a45dc9123, 0x4f5ad6647403ae33, + 0x794059f72018feee, 0x3623fe1f4bc38149, 0xfa7c41de263a0667, 0xcd67a892af10d084, + 0xc3770c298a41e6fe, 0x4c856e881f137f08, 0xc4f850de61c69d68, 0xfa0ef5da5e0539a2, + 0x52076b42ccbad387, 0x2041523de945fa64, 0xbbbcae5cca85cac5, 0xae6a3c5423df4d8a, + 0x5eac296c0b7ee422, 0x11a4ec37c9d225ec, 0x98ee358ac76d052f, 0xa28bd0c395c89ed3, + 0xd790c36dd0f858c7, 0xc0a6f2b80ba105d1, 0x3464b85f05e22b66, 0x76063c06a40c6be2, + 0xb4e50777cff89564, 0x0f16860d5228ceae, 0x84ee4126f94448c1, 0x08936ff6b202b4aa, + 0x8657c747aa2655fc, 0x689f283d988eed5f, 0xc30482562f3a2497, 0x2ddd7409d8c53e7c, + 0x6772e5c5cc7731fe, 0xb144d9ae05e5e7d3, 0xeda599f039b6ca7b, 0xfd4ce13f59103c23, + 0x1f415ec754b3b784, 0xa2f249ada8e84e11, 0x3c3814571b8077c2, 0x45f0e06bf4dcf786, + 0x0137aded796ad680, 0xe81d6f0ade7421b8, 0x7044af319237f16c, 0xb20ea0bc8da3e3aa, + 0x718581e2c2c6fff1, 0x56a5bccf33ab1dbe, 0x6a7109754d358441, 0x1f3091bfffe0e552, + 0xfb9c72c0573a9fe1, 0xe49d088dc97d638c, 0x9f58d4ff9feb64dd, 0xbb95c9734fbeede8, + 0xf328627a96fbe049, 0x024e3775f352b912, 0x1826dc75c812ad15, 0x22bc4ef23a8ead2b, + 0xc6898e3ca143d8a6, 0x94f41df2677b8cf8, 0x2816c04f2838f793, 0x300d2137c9e52ac1, + 0xa2b5820e482887a2, 0x1fcfdb00fecf0e83, 0xc6dc035b1eff5cf5, 0x9a66e973c2a50111, + 0xccad368dafc50c76, 0xeed5dffa03676bb7, 0xede1402311b0ecf1, 0xdf8b95b550e6bebf, + 0x44710f41283dc354, 0xb13dd2f027179d2d, 0x8102e7c3a00223db, 0xa3cee3cb3c32071e, + 0x7893d3f6cc4ebf05, 0x7f7f6308c650a2f1, 0x3f542132b84a03d2, 0x5bbe5ac7ece0d1a9, + 0x29d78ebcc7d9ab23, 0x9d2bacb0c558d7eb, 0xdff8f6a1bd37fa84, 0xc72d5ffe40dcee26, + 0x98b1693c2aff0012, 0x1f2a0722120a168e, 0x4c6595728dd8fc73, 0x70de0300097bee65, + 0x76d0309a33a87e66, 0x08e1ceeb8efb47c3, 0x0c3097e50bbe270b, 0x4eb51a4f91d5d151, + 0x30eaf0365ea1a728, 0xaf9cbd611b5d74c7, 0x8503807f474ab221, 0x39ee66d06e1bc996, + 0xcc085e60f175ad60, 0xacc0c7b02698b851, 0x4cd0084ec00f1b11, 0xf3df5a3606e90c56, + 0x07ad715b6952f865, 0x269f242f382bced9, 0xdfb5c5d90c6929d5, 0x608b84ff2a4e1a06, + 0x3e9239859f0f7035, 0xff114f8c1ef228a6, 0xb35287c251b69394, 0xb40b54262db2cc1a, + 0x6e1a99d05c74ff98, 0x889584b38ce876fc, 0x8c8c20bc8da2af0b, 0xc27391d07edbed3d, + 0x4f6863ba6d1088ee, 0xc0485a0a35384c90, 0xddba95542221ae27, 0x590a650f7e97ec48, + 0x9543e7a8c791b3e5, 0xc21f5f28180a2d17, 0x9de580670fd28fb9, 0x618a5f8d2ab7024f, + 0xae63ca1b7c841494, 0xe33d4b521cec8147, 0x5e71605ae0ed7feb, 0x88750edacfd6fbb7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6ba80d6d9e595bef, 0xbf74e3a2dcea2b33, 0x6caf1defaf37aec3, 0x05fb7d6f85a9d77e, + 0x6324953a900b2d09, 0xb41d83e7132852e7, 0x1e1dd0e57108c827, 0xee4afcb8f9f4ebb0, + 0xde4f506ef4f7f569, 0x8ca73bc863181420, 0x2ee9d0741b938ba9, 0x285680cb732d977a, + 0xdcae1f50c2e5aa55, 0xd082e3bd3bd721c9, 0x3b8262e5eb074dd8, 0x430ccf7a349bf3c5, + 0x697bbfdc594fa341, 0x360f0f6280b4e319, 0xc417b8b41aa1502d, 0xb0c70506afcbacf9, + 0x2ebb284c2f7f32a2, 0x08e9d3878c44042d, 0x1dba1d5347e2faff, 0x3e15b1c1438709e1, + 0x5901c4f1954d7afb, 0x2367e97ca9f9451e, 0xdf4a3d76b632e2cc, 0x9ff330659054b186, + 0x4962ed3d807bb4ef, 0x76af4a9cbed1d494, 0x379f297db24f6299, 0x5db0c4d44c0115c4, + 0x66d0f0b8adb1b594, 0xd73a91265710164e, 0x44f7e33ee7de32ac, 0x97c0c025b33e1902, + 0x2954c3cdd11cc6fb, 0xd5cb87117b75347c, 0x0eb11501d2585808, 0xbe7587e40c17e2f5, + 0x57918e44b4715a33, 0x04b76edd2c9a3f01, 0xfc52614ae3119f30, 0xa14c520f005cce09, + 0xd0a6a276f9bfe270, 0xf960fb0536c682a7, 0xf8ffd7a93d177870, 0x87e4dab2cde67a33, + 0xe397dc97e31f18fe, 0xa9d27661d2b7098b, 0x1b57d7beb4dab663, 0x3dcffc0011459cd3, + 0x968ccc7975670966, 0xb1110a7e0778599a, 0x0392af40057fe183, 0x01136010174bf091, + 0xab90fd6921c759fc, 0xe19a8ef47a385cc0, 0x7388de94ba9aca10, 0xf3ffb4d5b1314d97, + 0xda177f11ca6cc2e0, 0xaa6ee679e0d72c12, 0xf48a9b5ab93fa5b3, 0x1163a065305498dc, + 0x71d9ed185cbf8ee1, 0xe87cf67567f0ab1e, 0x9262ead9284d7808, 0x2cb5d43cd596a7b8, + 0x5fef752a106e3eaf, 0x18060962e036100c, 0xd6cbd3ae55b346df, 0x0a2ef6708035fc5a, + 0x2314520ef630546d, 0x2bd78448443bf776, 0x8b907c80bcb43477, 0xbd3a07eae299b7c7, + 0x84faaa9b70723518, 0xc54afe037cd43d70, 0x87abf08000fdd0d8, 0x65d13f1a33b81459, + 0x2262d86765467952, 0x5ee71bd0c12ae50a, 0x17a82729fcc74a77, 0xab3774283b961f61, + 0x9aac1588549837e4, 0xbfa9c930db51210d, 0xaf140f711bb37d3d, 0x00929a771e94853b, + 0x82313d4b1a9bb050, 0xd013b38b73dd57e9, 0xb0d8b279df7e043e, 0x53eb6734aee485a7, + 0x564f78bada79f4c9, 0x5017cc7648649561, 0xc169197a6df80d80, 0xe5cdbe9a4cab5a03, + 0x9428d2611c978d99, 0x97cc5f8faf299830, 0x3cdf07da75870abb, 0xa5076d9caaca215b, + 0x2e01d129c157aca8, 0xeb4870bec5a157f0, 0x01cc4c5f5e615a08, 0xa1790f82cac8affc, + 0x221788e13f7c4c91, 0x58d7e502280efa4a, 0x255a7cce431061d2, 0xa5ce56923ad9043d, + 0xa233dc77ee419864, 0x347aed9c799aa53b, 0x11ca654570b96d0a, 0x5656778f6294c9da, + 0x4b9410948d5e136b, 0x574b9aad45e34a96, 0x9ec281430d14c61f, 0xaa0d009e0d893d73, + 0xaaad5bf3a355e88a, 0x138b3f41b169c060, 0x0460703ddcfbc08d, 0x86f7d7c990072ad1, + 0x603860a22919cc22, 0x07f17c2fbeca03d4, 0x18bfe3ecc7aadae6, 0xf25ed5d952ce0638, + 0xec89d8c7fba547bb, 0x37e39422c2849133, 0x423d6041f4e5d85d, 0x8850748882eab882, + 0x2077225973c19257, 0x3fa0008a78b59d74, 0x1bcf59341e13c65d, 0x51ca4da47b61b55e, + 0x47c19afc9603c0b3, 0x5ba14de8d485b715, 0x3ccd7164ed35e57c, 0xfb77018d829e711c, + 0xde9c444da65ddd34, 0x519fed98329f3adb, 0x738ec0b6e7c9e6e3, 0xb741a50753bc8bc7, + 0x7c13508c3bf06c67, 0xa91519399bc5492f, 0x88341b6772c135f9, 0x3065b1c1f1fd7536, + 0x6fe3556135384ea8, 0xad089435b3320bb5, 0xf1a1863876ab5200, 0x90f87630152eec81, + 0x2be5eaf04af33dda, 0x5da11256b39e9539, 0x385634c5f66b956c, 0x84e8df37503e1fd9, + 0x69c4f0e31c3d4e1a, 0xbdb98796e88b888b, 0x8f638815e8234df5, 0x83963fd83cacb98f, + 0xbc2b7733f159cfac, 0x88111730b6e68f79, 0x58d51ea9b3fe539b, 0xa077e6ab425b0826, + 0x4131b5b06290358b, 0x85cc3ab76fa87388, 0xca017932cbb7778f, 0x0c94e0dcc0d8b2d5, + 0x36374ac1d45d1bfb, 0x5ffceb267182f45b, 0x02624993b4fe8022, 0x3f05baf855fc313a, + 0x4db56368dd60cf56, 0x8849033f25770438, 0x74173a7daffafd4d, 0xf8988d85f165d92b, + 0x148145e8afe98fc8, 0x633bc57b8bd5210d, 0xe2446cecb15f2baa, 0x9e69418dfb3485b2, + 0x4135ec1a2f0b17ab, 0x778593414bf40793, 0x6af7214224bfd27c, 0xd307526d9139380d, + 0x4d29f65dc1ab9c76, 0x65a9dc5afe3c159f, 0x29c8cef9e24c2646, 0xd4bc9355a2287256, + 0x61bf74dc014398b0, 0xf33e6e159ac74c7b, 0x7752d745ff8c2a68, 0x0606581ed90d0c86, + 0x83fe2220e057e157, 0x9fffba45d2fd9109, 0x1814aecfab9f35ad, 0x8df551f24bd41a39, + 0x89072bad58aa6fdc, 0x9d8329821db69f78, 0xbec9701d31174300, 0x7caf2e14e5faa0b8, + 0x3beda2c3b3ae8a47, 0xc1edabc8e44ac9a0, 0x1c6971f03d250493, 0x19af641011b39386, + 0x6f6e17744515ce52, 0xd9224cdf41c9721b, 0x504bf630d5593f05, 0xe043b20fa5ce526b, + 0xf8447964c63b631f, 0x18ce408244819977, 0x4ad7ba658904332e, 0xc5cff7f1a689dd48, + 0x40d0e3bb2b49f922, 0x9084c0a8eaf63362, 0x5ccfee1b98df32ba, 0xd2e3ea2a37f0fd67, + 0xe9be4a66e542cfe5, 0x42c4df27b443c8dc, 0x0af533eb454bb47f, 0x684f114b5e0d2c0a, + 0xeb0650ad3e892fb3, 0x32352378c6c759b2, 0x0afa2bb9d4d45468, 0x3cbd99511fb6a29c, + 0xd34d415ad8fb679f, 0x29c0352811f53cea, 0x7b6e5c9c1d2fd319, 0xb423700d6474da31, + 0x5c7317918e592810, 0x212b5dc5c8d87c68, 0x2c1e6cd6e0bb127e, 0xc2103e097b708a7d, + 0xc3084eeddbb20e43, 0x061a9159fc390d92, 0x7f3f1498c5022245, 0xda19f6bc9fa1e420, + 0x8bdedbcc2d410fbb, 0x6589cbfa6efe036e, 0xbafd48471ec3bfcd, 0x6c1c3eee7589445f, + 0x09bf9ea6f2ccd49d, 0x2bc8ed181fae376d, 0x190e40a0aa7efaa0, 0x784a42a0f02406b0, + 0x534af0489194b5b9, 0x5bd021701cf0fb60, 0xaeb421979d02745b, 0x8c3a8f28184b18d3, + 0x615990d325528f71, 0x77d61f56ef48dab6, 0x121b39ecdd0fcb2d, 0x86b73fd8ad7d4bf6, + 0xdcd8ade86269454b, 0xeb7ca8d2fe4974d3, 0x7ad07dd231b7b389, 0x817b19ec11aa92a1, + 0xb5ada6e94fcc0dc7, 0x1833b9bdcd69d646, 0x6f7908b696ef6f69, 0x5e5816f77dff6cf8, + 0x681b74d54d2780fb, 0xae8fe4c24fc5e2f4, 0xb1dd6bd193a137ca, 0x015b345f2274364e, + 0x1aec139421778339, 0x2645c6889d8180e4, 0x73075dced32cc5aa, 0x58acc87f97a76aaf, + 0xa77dec0805de5eb9, 0x154f9371f5a3194f, 0xd7258e65736002ba, 0xc1d4fc6e0a60cca3, + 0xe4872570338cf073, 0xb4b666d0cbb49848, 0x9d3e75f761317e8f, 0xa3333be64d2ed7c4, + 0xfd294b6252d1d1b9, 0x9cd734ec41cafb17, 0x4cb3f8ade6c1e3c1, 0x54316712841fe1e1, + 0xabec61bb7799f721, 0x691b7d7fad3649db, 0x069961e6a1b63e59, 0x91ae6eec5f7a5882, + 0xe35f05562e000119, 0xf2f909f2fc30d30d, 0x1363be8b9888dbd1, 0x8d90183a3e1d0a86, + 0x92f3c37b65e68cde, 0xd6919899978214e3, 0xe2d717e45d36709b, 0xc77e7633fe1f66bc, + 0x8dd07e422b331fed, 0x403dc270560e1f44, 0xc75ddad670e464ee, 0x3d2102b9f8f07ada, + 0x9863ddfe594b94d0, 0x7e445ca34bc5e70f, 0xd6cffef8b2c07883, 0x0d87aab233dbf06b, + 0xe3bfee82c3f869bf, 0x527c27a656008480, 0xd1836b07c4c3af36, 0x99eb569cd86f57fa, + 0xde43cf4bbb769d8c, 0xa151a30545424711, 0x1be851934129b601, 0x8e1f369b314e232c, + 0xbe7018e9c85f8cea, 0x4b92adc66da7ef5a, 0x978807220192b66a, 0x39df3cfb1d7bd73a, + 0x8284e06ba40d72a4, 0x75bf7732890881dc, 0x6d2a498bbe19415e, 0xfb664e541825573b, + 0x976a952d5f4ce437, 0xe1ba110a02b3cd62, 0xabd205c4ddb02df7, 0xb3e5f0aa4b9ea9fe, + 0xceb156780c88e260, 0xd01f2786b33c6a8b, 0x03de408ce1049efb, 0x149ee09fb6252d3b, + 0xbb7ea066696241a2, 0x1b0f001e4ea6fad8, 0x27cb4d7bc8043bc1, 0x084b64ee849cce66, + 0x37d4cbc31864ae4d, 0x3c7e9f77b16f0208, 0x64f8b04523d7d7c1, 0xacd75b3f0bc656be, + 0x18586afbde497301, 0x176759e3e788e938, 0x0b23cf2f02291758, 0xc3918a77b0c472da, + 0x69cd54c2b22bf285, 0xaaade807f33c799f, 0xe78a725e72ea8f46, 0x0c92b013490ea332, + 0xfc462d3e5f60bf28, 0xdd7bec6880b45067, 0x18137cce039085c3, 0x31fffc94ab12acad, + 0x0cf3e2b5b8af26c1, 0xd3758616f1ae8d83, 0x1369db9dc16b4213, 0x52b7a52bf17eef23, + 0x71503135a5d4502e, 0x08d4295066556b28, 0xa7120ab63857ac4f, 0xfeaf84a2b3d9825d, + 0x194678ac4eb0823e, 0x910da1e33e5b9cce, 0x1312dc0fa35d96fc, 0xca5242da171f343d, + 0x6159c17ecbc7669f, 0x163b12e29b80b8b2, 0x167b8bbe8346c2c0, 0xc0773e549be95e05, + 0xa83c52b546c249b8, 0x7ad674c9bf5f8b8a, 0x84909b12c5801b83, 0x499edbc0dfc90b2f, + 0x175626366fe5cdf3, 0x9ed024f0dc0460b5, 0x7e5b2ad761d07816, 0x64257e7c1a66ce70, + 0x8df9810108b6862a, 0xb407a22e3b001fff, 0xacb5e817f4798f70, 0xda454b80a60598d5, + 0x7b9e33f535d1dc38, 0xfb73e396fdfc7977, 0x6feac162d336892d, 0x53a13b856555b289, + 0x72ffd8c7ae166eeb, 0x59756694c17474db, 0x02694cdcbd6819bc, 0x7d8931535ef516b3, + 0x563cc4be6cb70abe, 0xe8071a717b6385b8, 0x8a69ea8a5ae0fa38, 0x8b54a6b06fdff099, + 0x5dc231c9a6d9e8f6, 0xef2ae32a3c91b24c, 0xc2680a6b8dd4a71e, 0x8c0addfcbb4b9df7, + 0x6d985dff061bbc73, 0xbdf46ee1d160b3a9, 0x5580fa38dfcd336e, 0x48a953367c6b9719, + 0x819ce7e0d7f6a332, 0x8fd88cda98092ea4, 0x4c2d0be98db0410a, 0x45ec5331c5012a8c, + 0xcb26f46b50cc776b, 0x9160c00ad454116c, 0x250fd86321584324, 0x4b56071e8db09fa8, + 0x407e529b9bf5ab00, 0x33367f04537f7109, 0xc11f9fed6c01261d, 0x961fef17d19b79de, + 0xbf95ed6e1b87a599, 0xbe4caf3d8dbda966, 0x8b3f2f6d68e43a0d, 0x67a82743cbc96a8c, + 0x01ea2ad03dc62deb, 0x4dd3723cbce1fa40, 0x0a069e1998b7dd58, 0x070b93a8ad85b8d7, + 0xf8c81b3c6cb1dd49, 0xb0bcfcb6ec0ca057, 0x4bfbebc2351f428b, 0xf595fa6d4054003b, + 0xd34e29f482c8e04c, 0xa5617a0ca711f06c, 0x5d1a9af1a6b0e97b, 0xf503c3501774bacd, + 0xd8f090492d15b114, 0x7cbc66982960e088, 0x51f2b9387991b35c, 0xf3cb07ba49b25908, + 0x2892880393de5846, 0x4e300aa2d084a47d, 0xc79a84d2339e48a4, 0x4638ed418b76c15b, + 0xc0fc8b084fa762fe, 0x3723d840b65e6505, 0x8497993d5a01d1c2, 0xabe096827f18c1a7, + 0xb9adf761351376e8, 0x35a0d7504a8b1e10, 0xef2e6b32283a77ec, 0xfad2f136100748e4, + 0x644ea41c9e698e24, 0x1968015936792a4a, 0x9ea1cedae07c5469, 0x4864ac682e3ce51a, + 0x611ae22d395d280d, 0x83ce6aa8216ff3b0, 0xa1991bdf6ae86e3e, 0x56e791d68bf3f2ac, + 0xe19ba907a64772fb, 0x75c5a4733b31d752, 0xda6df88f1788144e, 0x026bbeb995429cf9, + 0x1f6d1248511abbf9, 0x9de4f443ab074134, 0xefe1c258d5911d0e, 0xb6dc66bf94b999d8, + 0xef55eb299f980c90, 0xc2d20fc8b1f90833, 0x94b961c0b4614d50, 0x7aabe6fbde19818e, + 0xd5775875ec2478b2, 0x3dbc0cdbace727d6, 0x9ecb4a32f5eedc0a, 0x97066199c0f193ff, + 0x7dcc5b63f10ec589, 0xcc343d343d52fd84, 0x1f60a17cbc276775, 0xa7ade1bdc6748d64, + 0x600b5e5badf0abfc, 0x1a40a916dae8efd1, 0x459321785cbbc22e, 0x47e23995b59e79d1, + 0xef58d8f372fda762, 0x1a1013b064ce0dca, 0xbfca49c6c05f325e, 0x976e9a96a82fa37c, + 0xc90b74de984948b0, 0x59604ae4e8421b43, 0xdc5a52a7b0df5f2a, 0x5217f5d834f56ecf, + 0x71a6814dacbb73de, 0x0d52623b4e07aef7, 0x150f13dac5b6d1e8, 0x7a2aaad6e2c8d87c, + 0xfdf67e73f84c5e6e, 0xef49f49024030f38, 0xdd2a86ce0bc94230, 0x537a1124bf405617, + 0x415af0bec9af7057, 0x668a9e81379b39e9, 0x0bf7230894b3aebd, 0x59a933b7344f4e2c, + 0x8f63ad8abbcfb01e, 0x1bafe18804a66ed4, 0x9a34109d3bb4a200, 0xe7abf0dd43df16cb, + 0xeeaf9a2b53e5cc5c, 0xd23360ce09b0707b, 0x5133eda8143af28e, 0x5fb02ee11d346f2a, + 0x2d16ead5593f8950, 0x97051b0d8c33bafb, 0x5c79340b195a15fc, 0xb592c5974b7d317f, + 0xd07ad581a6a34d97, 0xaae011e7632567c5, 0xa91067ba576ea8b8, 0x3526a8f75406cfce, + 0x1a547f3ec5223cdc, 0x96be2ef067ee60da, 0x89f2d6dd15226d14, 0x98b77b17fdac3a4b, + 0xb1d8b9937251d353, 0x722470cecc426467, 0xcded3e014730fe09, 0xbc47664cdde3d0e2, + 0xb589437570c105e4, 0x66a2fc59a2b19a6d, 0x4cda8e9acb289ceb, 0x439c69e86392c491, + 0x2691dc6670365132, 0x2432318bf89b5120, 0xd2895f272fae2bd2, 0xf351b96eab33aa4d, + 0x41e3a8b67917914b, 0xe858d1b0af9c8f12, 0x486a21f52a1fa878, 0x5f1d0be89bbadf66, + 0x11b3fadf38459f57, 0x55ac1fe54f76264d, 0x1ff96a738f57aaf9, 0x9a8bb1fd5a344961, + 0xcf7fb0413911881e, 0xc19bb798789472fd, 0xbec0e34ca2f4baba, 0x1e0ef06e5fdff850, + 0x9b2008caed1198e1, 0x4ff9fe3e9646fba8, 0xb34d6ed466dede7b, 0xa47a473934a29144, + 0x3a0f9e52749f8376, 0xd16e2b50c98a8829, 0x07db409dadc05655, 0xba814b693d5c8cb5, + 0x95ab401906a566be, 0x83655c4bd7f0ee89, 0xf98e2d54a6cdea90, 0xb77169096020c8e6, + 0xbbdcc5fcd61f675e, 0x07f5d94dffebbde7, 0xeda568bdab379402, 0xdc851894cf611c3e, + 0xc04f36b7630cb051, 0xdfa360df8a28031b, 0x6eded21d69dc730c, 0x88bda3c31218a19a, + 0x017334c871e3e30b, 0x7fc594fc0ad29359, 0x1e1784e864d01c88, 0xe496ed538b5541d6, + 0x6bbf165cb96e1fea, 0xe4758602a9b4555a, 0x0b24e044232f7577, 0x9b87c65c7721e089, + 0x429dc32b0267a05a, 0x6082e4d3d3edb268, 0x4a77d47da7e98295, 0x0c768f3669a0a032, + 0x14858d4678d530f2, 0x123c70f29c0b69cf, 0x50d103c6fa518c90, 0xd1aa915a3992b7a4, + 0x195ff5862e27d5bc, 0x9649d1d851b05a00, 0x5dc55fa5a2a60a04, 0x743e71de252ef060, + 0xc81df09ca90c3525, 0x23e3733c1b9ab4dc, 0x7c98202b29a35ed2, 0xece34e68743e4b16, + 0x0ecfa166d16d1eee, 0x31b77aacd04adedb, 0xec0a7ffa4edb87ce, 0xb83834a90361c9ac, + 0x3e294d944bda3caa, 0xdff637a3652d5b93, 0xae425d263e9cc999, 0xf6b4cf748b42d8ac, + 0x05857d057c8e7a15, 0x5a49a66e979f35ef, 0x9385e97cd46a9a20, 0xcdce10b63eb6183a, + 0x4368a964f22f002f, 0x6aa20b55bae2b618, 0xc41c44d8ca2d080d, 0x16b9a7375218cd0e, + 0xb30ea60999e72bda, 0x361ef27b809be1bc, 0xf2e4da0735754088, 0x6f9d7f5407674963, + 0x2a6979dbf009d406, 0xc1fcdf27342d6f43, 0x0f0b56a965c5be27, 0x62b1574fe2a52f2a, + 0x5c37624e153d0793, 0xbecf6bb888f91ea5, 0x9fc392da79852e1c, 0x24b6ef9e4683e1b4, + 0x354e59fa39c81319, 0x7d4296b051c38b90, 0x940d8cf33c2c135d, 0xf73182fa73938ace, + 0xbd6041810097c64f, 0x0a2b47c4bd877d46, 0xbe8d4d8a3ea43524, 0x37fcfea59664274b, + 0x1adffc6a9de447f5, 0xe0ad0cfb9cf9ab27, 0xd1fa176c030451d7, 0x107a993bd31a30a9, + 0xe69919f8ef78e669, 0xdde2088d5065c479, 0x1195c973f1c9194f, 0xf599bbb08c1dc8a3, + 0x7c2644c762eb4da2, 0xde7141c70326e72d, 0x73b84ac8e4f5986b, 0x0506978d60544185, + 0xd3a025af51855a7a, 0x4255d3d263d8eb1f, 0x4f78a275d25983d9, 0x733ee25406452183, + 0xbfec3455a1ba14e5, 0x24de877bd3b9d41d, 0x93ab8958d14b11e8, 0x300dc0f105b37ce7, + 0x27fe1b19f06dbd19, 0x4573779b41989ea8, 0xcca0898939579291, 0x0f5958995476c263, + 0x68dbf21f62c28bb5, 0x4b6b8ad1dd0735ff, 0xe13c2c92799090d4, 0x535df82035c6c642, + 0x2d17f2f0193af29d, 0xf16a3e183415b731, 0x33fa9ba186cef653, 0x7bd33de594f046dd, + 0x4df415b6655b2c45, 0x26d53e986edcb178, 0x1ab99c3dbc37ea80, 0xded6f35cd35c63c8, + 0x77161d063149b571, 0x43e56bb16e53d05c, 0xf8b48d8380704f3e, 0x37a7a5760f09aad7, + 0x2d1862e85b490f58, 0xd006065cc7f6f8df, 0x2037189b8f34a654, 0xd9beaf1401605d9e, + 0x517264f6c64c0286, 0x72dd43b5b5c1e9e8, 0x57295382bd92a099, 0xa15a205324044aca, + 0xc9966948eecb5e23, 0x6335159bbe55a098, 0x07c8355e785fb8b8, 0xbd84473ea8950b18, + 0xe3fe2b40f168c1f7, 0x81e144eef9e64518, 0x4c020634c82fbc84, 0x2ce0fc7a5992dd7d, + 0x5dd951fc6c0389dd, 0x70aeeb6da8160cda, 0x636cdd4d184d8508, 0xc021ccef61a28386, + 0x3d215d34a8cd6bba, 0xcf8f3a8fb69a8b60, 0x49e98a03c4ff877d, 0x326cfb4aa1c7d5db, + 0x6ba0ce471943c7f2, 0xa52f6dd3f97e0058, 0x0c7f9c01ae6fd446, 0x3113a25e97321534, + 0xbf6bb6e70ab83dcc, 0x2b3775e21e458b5a, 0x6665c42bc3aa7613, 0xb110c199efe30aba, + 0xdffd56f480052717, 0x45ae47969e523beb, 0x5308ac188cb02c57, 0xf11cbaa3c2dd249a, + 0x1d11cdafc80a443c, 0xbda1d9d57ffad7c7, 0x5d33b39069883fcf, 0x6fde77086b2c5e92, + 0x088cd180cd90704d, 0xc2f6bf4ae94c72a1, 0xfd481187bc85536d, 0x0af99190a55fd5ed, + 0xc5fdc1f1e5c20805, 0x24ae9582231f95d9, 0xbe798af004ac67a8, 0xf10787cebeaaae54, + 0x30ba9c0484908244, 0xbabf0e78ac882179, 0xef78e16b1ace6436, 0xba69426b1f8a1075, + 0xa7882c0eff80d61a, 0x1e9e1ac22806995e, 0x96e8f313987ccfd7, 0x2b3254b81b80f4b4, + 0x602b00a5b4371310, 0x0b3b4bbd673c27ff, 0xb5adb3cca0f90ac6, 0x22d956d19295d906, + 0xc294068109ac92a2, 0xba1c7a257678b8fe, 0x4cfe1e8785bcdc18, 0x5fadeee2434752f8, + 0xf429ca362fc2dc6b, 0x1207e8810638c05a, 0x4295dd26e6189c98, 0xe4f5e7b7e18e57a4, + 0xe4f3f6c62b5286b4, 0x1a3f17dd2927fb17, 0x9350ae5157e1f4b2, 0xc0b76ff6b76451f2, + 0x792c0579f64b8cff, 0x511f3e4429ebacac, 0x780fb50a362959d4, 0xa21d6a961cbdc259, + 0x6d06939fd21cb76d, 0xef3d12ad1ab0c754, 0xc2455c7b4503dc47, 0x06e7f9f95ed770f4, + 0x7aac8a14f60bfb60, 0x5d4af428aa85c6c9, 0xbaf01f75432d70c8, 0xd7e39a298d8ec048, + 0x2098fcb7a60825d5, 0x9a87e12b49fdc04c, 0xa6c31269ca73e86e, 0x90e3285d7b03bbe5, + 0xce9d2d615dd342a3, 0xad8297590eac8dde, 0x495980f6fe34be0d, 0xcaa5216e9fcef019, + 0xdb4a206d9d7106ec, 0xe210f6d8083765d4, 0x8c880e4ae81842f4, 0x211ce5aac7f7f3a0, + 0x9112ab34b9522e0a, 0x9c28088d9eb361af, 0x169d1768bbe7b4ef, 0x2fdf29cca38bfc5f, + 0x1d7c91b2e2e6aeec, 0x18cb4f3ba20a92c1, 0xd86ef8ebb024fcdc, 0xf2a3c4f9b7d6444f, + 0xa868d00ad2b90d7f, 0x8045276c3277cfc1, 0x6a1e3d32b12b321f, 0x5f3a136868460cbf, + 0x8e5cc1e146647434, 0xc991453fc181e5bb, 0x2e53ef63da828af6, 0x88f741e5a442ff88, + 0xaee8f09c8f05ea07, 0x596aa430ebeed2ca, 0xfbf67ddb9f061e4b, 0xb8f4b112569e9ff0, + 0x19579d5a908ca61a, 0x1ee4e2714e04e371, 0x341abab6e1667c4a, 0x886dbc62a9e95f26, + 0xa03bd6a07108a693, 0x0f07dffa1a7c985b, 0x724569988ede3fd2, 0xe8e1b7818f4113d2, + 0xfbcafa9d88429a77, 0xc908e3e00ec06a71, 0xc519e73c73f90302, 0xdf8ddf47287cc5ff, + 0x9e7f880cc7f98496, 0x95f2d8842e9e99ba, 0xd0076ab4ce17e596, 0x382e71aab3c9a83e, + 0x6f618f30dc4265eb, 0x190c084cdc0b0614, 0xd91cd0ec703704d0, 0x7fcb7a5c5848656c, + 0xee5c5478b015f182, 0x746f1e5cb44bafd1, 0x7483822b70ea8589, 0xf80d49c4312e97ac, + 0x308d3deb37e98bd7, 0xee04c3c99f407bed, 0x9ba26239e4ef141c, 0xa6e7ed32a6b3d96b, + 0xb8348e9ae2cd9796, 0xb39f344320a221c9, 0x7a6ceac688fc4cc5, 0xaa96fbce5c1ed18b, + 0xcee2f16ed46a7d99, 0x31e7ae31a48ffb4c, 0x9ff98769517a0989, 0xf6e9441b173099f5, + 0x25d5c846d4ba79c1, 0xda39a1aa5ddd7cd0, 0x7d71729bd17ec9df, 0xa84231893cddee69, + 0x7d4e468681b07e3c, 0xfc071c8c3f0ba196, 0x2e5a99defb5c68c5, 0x2d35f21c6fa1d0a5, + 0x5077483a6c12015a, 0xc3e8a1d7f00d9147, 0xb39f48cbb562688f, 0x6c8b3f2bd9052b04, + 0xd2dd4b6d2a637143, 0xa5a86984482b9441, 0x16d54d0d4be141aa, 0x89338cd58c592888, + 0x3261a79be7003b15, 0x6a0f74434f838bcb, 0x6118d957e43f3e58, 0xa5687096724754e4, + 0x0e2937f091e7cdca, 0xf878457176b3cebe, 0x9bf13aeadb8358a1, 0x1563119d6e137817, + 0x0a16cb9fe9c158f0, 0x8c9e2b9011b7bc29, 0x97bcbb7d85a23b53, 0x97ffe6dd3e49237c, + 0x9fcb7245137261eb, 0x1981e3be0378778f, 0xed7df5ae39fbdf9c, 0xdbb5046a8ad7e05c, + 0x687391e185ac838d, 0xa6584128ed9e7ecd, 0x2643d0821805f321, 0x78fd9a64756804ec, + 0x57916a68fdf22f96, 0x87a8978001e0cbc4, 0x99b3a28474a6e68d, 0x3278c23584a55e63, + 0x6fc81c4ffa68a849, 0x0e413ff83f642522, 0xd6ba6e5cff3232c6, 0xac76405b3efffb30, + 0xa24f106e80fdfa89, 0x90df16eb42d104bb, 0x71c1a2bce2a20710, 0xc6a1620114a601ee, + 0xccdfc2decf2a961e, 0x639b571a21f1f77b, 0x850b60cc6e7e5b26, 0xb93b218bee04bd99, + 0x4ba0be61e5f586a6, 0xe2bd70101bae2aed, 0xfd28688758c19284, 0x65607c31960b1b97, + 0x0248e8bed0ac1e3b, 0xfac95427a2af24a8, 0xbe8d3195eff1aeb5, 0xda37c7fb32c4e085, + 0x338a21479043125b, 0x1a5afebc028baea9, 0xab1d9b3f5d3848b0, 0x964ff1e50dedbca3, + 0x5f8f982301dc9620, 0xd950fe06b70f6ab5, 0x99453c215a5ee807, 0x707cba2b712d0c12, + 0xd3dc8ab577afe3d4, 0xc0a682ab35bf2dbf, 0xea37aff5571d6bb1, 0x5ee6c34e007a28cb, + 0x4b5b1d79fd98284a, 0x822d754b38b8b971, 0x0c58464704335b4b, 0xb59d3572d5d70976, + 0x77fdae2d786e9730, 0xceb737037f3f689e, 0x27715ec99f1c4718, 0x169cf9d90c1b7c96, + 0xebcc6bab0add59f2, 0xf3068f6756fcf6cd, 0x44c8d5c16925ad21, 0x4ae40bbff2836d10, + 0x5ed26c79c6894d1c, 0xd6d9cb24b5445d2e, 0x35f49992e3674662, 0x550a3e3183de8caf, + 0x14575ecf312f6c3a, 0x4902bbb5d436ccc8, 0x79d90aacb1c5db86, 0x349298bf333ec128, + 0x10c92d95d00e1080, 0x32f98f50437a60b6, 0x85ee0c76f589dd8c, 0x4c8dd45f0ee18010, + 0x90e535ac678b6066, 0xf0f4fa6f097d4eeb, 0x14a40d5d115405bf, 0x1a5f89969eb4c39b, + 0xdecfc7c1bd22a838, 0x65ecdb952ba11722, 0x97efe5bb1c7a55a3, 0x8468c31291aad10d, + 0x490a5987bb1f6536, 0x22012bc3e765bf38, 0xb9a63fc565461c7b, 0x1f9d2e9d6ff7e86d, + 0x4464d41a80992204, 0x51ef238973d3604f, 0x74a5217d1edf96ec, 0xe09234009589049e, + 0x078b6b135f5c8575, 0x9e1549e93dd2250c, 0xb55f4812840fb5bf, 0x2a05c905593ce544, + 0xb54c2a7b4e916c12, 0x0d08f2c6f4636b06, 0x37f55f9546ef7ede, 0x0d05f19062cc21f1, + 0xc8649fc34ef55198, 0x47f411cda73fbc9c, 0xc143a975348550d2, 0x0d6d11fb99ab6f9e, + 0xdb847977f02c3f88, 0xc0df5a1063f70200, 0x1c906205134ae5df, 0x056dfb52d1f2151a, + 0xa8571383f72ce77e, 0xc7285f9e0abde084, 0xe74a678b0d52bd70, 0xf3b941d3701ec43d, + 0x0221b3ee521e33d1, 0x8f78416953fbe7c7, 0x3f095970131dab05, 0xab02c595fa7dce3e, + 0x350bdb13d3345db7, 0x1d1e9faa98554776, 0xa0d755ebe1325e61, 0x96b4b8ea60bc7b96, + 0xa938363122b4b39c, 0xb647220e1e7b59c3, 0xd4e63ef78dee82b9, 0x7c61ea473c315e36, + 0xc9913da68c9f7723, 0x3065f49ef4f805d8, 0xd1e408903b859219, 0x2f73187c39eb5d26, + 0xbcd7cc8c1da12e4d, 0x00d068f5aab9f85c, 0x43e48da4c6f24ff6, 0x81cefefde94e3abc, + 0x4ac04676c3162c9a, 0x505b0142e8d2028a, 0xcd811e43379d30ae, 0x0713956fa95904f4, + 0x1d3d1d5ce01ddd00, 0xcd0c5d8fb10e8896, 0x4c270dffba49db55, 0x3731517035254a6d, + 0x05b940151d93bf6b, 0x4cd91f0d1ebfdf60, 0xd2e637c2791950bd, 0x4695f8a6d412145d, + 0x3906e6a624fe15ef, 0xc29a53adc610ddfb, 0x7f066dd3a658ff3e, 0x60311e4d48848db5, + 0xd47ea7e7a6ba1bc0, 0x4f03aa0d4ee2dad1, 0x724eb1be1435e017, 0x15dffb3ad0b750f3, + 0x6a91da7e0e008f1a, 0x40aa3ace9100fbc0, 0x9cbd4086091a3f85, 0x17ba584e0214c146, + 0x06c24e245254d6cd, 0xbe2c1d8b8c235a77, 0x206b3f09969170a3, 0xac977b008785c187, + 0x52b2b50353d60b91, 0x7ff8fe55ce83a453, 0xc9758cbcea5e7b39, 0x0ff9e7c40b9f7fdd, + 0x4500b3204d3374fd, 0x7af188393e2d5f53, 0xd8e0dd4ec438bf8d, 0x974d9f9cda9406f4, + 0xea35cdf9a40a90ce, 0xee10560f7dd2f150, 0x6629dbdf77fe4018, 0x28b927b1ba6f71ff, + 0xa111e6873af1eaaf, 0x60c82b469096c9ed, 0xff2940a348b0d625, 0x6d853ed1ccd49a11, + 0xc533dd13ecc13f1d, 0x77f01ef16f95fa16, 0xb7af7f6dcc5249eb, 0x287b454eb6a75498, + 0x2070dce28ddcf2a7, 0x0c0ea2b77da9a685, 0x1fcab14666be4281, 0x5d5c1d37a7a774b0, + 0x576682624c84ddae, 0xcef34a956261d3d8, 0x84579a45668f0178, 0x89fba785feb9d7c6, + 0x38dfdde663ed4da3, 0x5c4cb15599dfc575, 0xa725ffbba4491f3b, 0x01d1b2e28ca7cbd3, + 0x01c3bccfe3c78014, 0x1b2ba952c699754a, 0x61e213b454fbf9f2, 0x864d9cb7f8c4ed1a, + 0x9f426ce566f2951b, 0xaa923ac6493ea189, 0xde61cfbf1792697b, 0x3fcde0fc67b6009d, + 0x9b08bdd596e2bd90, 0x57c8fbffb35a39a9, 0x54c351e7fd70163e, 0x1faaa586e173abdc, + 0x04f910e4e7d69cd2, 0x07c071378d356a7c, 0x9834386202ba5e69, 0x6b2275603cd339f1, + 0xf5e78709463472d8, 0xa7f475c34ad30da6, 0xf35c7ff1e38b5608, 0xd502de26e4bbfa5d, + 0x8e423dbe27ac78be, 0x0c703a06c6d2664b, 0x55ca004466eca6a1, 0xd8a953a9e694e7e7, + 0x638f18160a8f3e09, 0xd22991066106550b, 0x8e95e027d492f3a0, 0x1bd4ade3bb2fb84b, + 0x73d70f9489419393, 0x3a94ebbf6d2b92a4, 0xf516b3cd3b8e6b8a, 0x5a0821c7b1c9ed11, + 0x7d2b7bf62dba06ae, 0x8efcdc8a324a2b4c, 0x8633a222c0f00f3c, 0x148df8497afeef8a, + 0xbe93e42f449636b2, 0x8f124e96421c3efe, 0x56bace5507de2b87, 0xd1fd04e2f9bbc971, + 0x47aadabe3a4f41a3, 0x7bcd91bc772b4a4b, 0x47a1e7426559557a, 0x967fdd038942d9ec, + 0x5b9ba0986c50fc26, 0x8bd8e205b3d3e98c, 0xc18f6b02f86a9e28, 0x66d2672fb1119cb3, + 0x1191ac04b3ce431e, 0x709d4cf205ba79f9, 0x033b5f01a2854c1f, 0x62b1eec32bacb556, + 0xd54189085ad817dc, 0xe40f6ae0c51d2823, 0x0403c762e71c819b, 0x5695716631f224ca, + 0x03b6e20ed00e8800, 0x5440717037f13054, 0x8201a8a6b6ed4196, 0xc4768d3063d2fb65, + 0x789f92947c37db28, 0xbec6369c1f6ac419, 0xd13ac76d7f47678d, 0x0312b75c56b322a8, + 0x9edc6892171af139, 0x6e44f0d4b361d904, 0xd185f4cdc16ac922, 0x7602089aed899873, + 0x3659cae46334b308, 0x2d1f5d845cd56a39, 0x7a6d7931516eb2e7, 0x1c938bd46b2a3ac8, + 0xf8841354211159db, 0x8eaa70ad8b33805e, 0x8eacedbdfc4543c1, 0xbd5d70c64c63f6b6, + 0xd479809b1823f5f4, 0x6db286e9ce50a70b, 0x5922145d43ddbef8, 0xa2d366591b25847f, + 0x6e9b88694832aac5, 0x0647dfd325b775aa, 0x22a0044e46fa35b6, 0x2f876c203426e894, + 0x17989d50a40a6dac, 0x6869250c30dc012f, 0x3fd959f3906e1eec, 0x9985a136336e9382, + 0xf42e3e7d291d048c, 0x17a43ef715612957, 0xb5a7c4806a4bfe2e, 0x884995127035712f, + 0xb168aa05e48f32ee, 0x328ab9cd3ab0cb67, 0x334b17bbac8b1784, 0x1781f2f118cb83e8, + 0x5f64a67775a16648, 0xa6a00f503301cf74, 0x3ad542b9f92ee37c, 0x479b17d4542c184f, + 0x873830e421ad76b7, 0x3119ac128c572c13, 0x772daf77c54845a8, 0x35a08f7b3f5469ed, + 0xdb4796bef1f7f708, 0x27de394f50df1b5d, 0x170c5eb348df71a2, 0x8da0f6934e65739b, + 0x454907bc420523d1, 0x654653c403e4c330, 0xd60bec91c0f2d796, 0x4df6189e94e8af68, + 0xff1704b2c163b530, 0x3c546403a588c79d, 0xcb815f3510c411da, 0x9cc67a0f87badb31, + 0x00e102723cf0cfa1, 0x3e4d9889d7a9ada3, 0xd856c12c04401bbb, 0x3cbb37d86cf80ad2, + 0x385fbd0fa962a72b, 0x8aa1c2e852d51eef, 0x3111771a81fea7e1, 0x2adbab164473c104, + 0xc79454d92778e3a7, 0xd4de86bee7c53763, 0xf975471361ce1f74, 0xff53b221b3340749, + 0x21c83d6a4b54cdb5, 0x6f8217a1c20ac318, 0xe41b38db06925dd3, 0xa70b66b85969b519, + 0xfec59d517772568a, 0xf151ab8d6c4e577a, 0xf147490e4b13c538, 0x7362b37ab42d2a8f, + 0xb776b9fdfbf04c99, 0x5de66b8d2c03572f, 0xd6aafea40f87458e, 0x50c838e3af626690, + 0xf92754cb549ec5d9, 0xaf9d481240fadba6, 0x26c818e944293d97, 0xb73faeb6ee337b70, + 0x14a8b1295a1aec48, 0x5177599efef02c4b, 0x2584d2a2c3313190, 0x4d3bff9aab7b565d, + 0x8e2a71470acc72fd, 0xd36a72e7740822d2, 0xb670a2f584dbb89c, 0x5206e78416cb3b6a, + 0x87c751919169b51f, 0x02997755004343a6, 0x9b8d3c7b41487c20, 0x3e0bd6111b4287d1, + 0xccdcd0f680dbae4c, 0x31ceb43bb8dffc08, 0xc1bf34d7d63b41d3, 0x459fe030df6cc3c9, + 0xcaa0cc4d70c910b9, 0x6bef2516b746ca3c, 0x24e20744bbf36ef8, 0x239aeb3f444d052f, + 0xc0949583958f8633, 0x33bd9a430f2b54a2, 0xdd8a959f21a0a9b7, 0x52ef00ae7a39d4f7, + 0xa8ab3d1aefc29fdf, 0xb8cc7dd5dc46bba9, 0x31c38ef5fd21c21a, 0x6886b4f5ab487343, + 0xfc216082aaed970b, 0xecf3637845f087f7, 0x65c3686003ecc7e2, 0xb9ed68b04e297ce9, + 0x3f36ec19770da1fa, 0x756fdb017f19419d, 0xfe7db08b77ae2973, 0x6fbe12090ebcf0e7, + 0x852c9d3598dcb8d6, 0x7042d7771aa740ff, 0x9c72bb6d176f07df, 0x7e5761cfb120b3c1, + 0x57260961a8e5cd97, 0xca2e120a46c0989f, 0x9d05b33c91d76ea6, 0x451455bfb30a62e7, + 0xbf8d6b4687cbe7b1, 0xe089d47fd306ab87, 0xac2e597653ecdca5, 0xdc191d79888e1c34, + 0xd5c1fe3719ff0e62, 0x9b874f912007d3e3, 0x7d739e45faf33f90, 0xe705a51907f8200b, + 0xabd796266778603f, 0x572310f379a4589e, 0xa143998fe4c05fc4, 0xeac45d302e06c866, + 0xe2ee86749e4e6991, 0x16ffc457eee9a18b, 0x87e56c7b5cd614fd, 0x27f49d71d0a53a96, + 0x22df607982c3e0f2, 0xb21c4082ec7fa358, 0x1f4c16b8ca537bcd, 0xab40398be4f0a96c, + 0x2048b050f84d4f35, 0x4182c7fc26ba92cc, 0x6c8d3881e1bc1fc7, 0x7fe4ae7b21df29b1, + 0x350a2fbb61d8ff5f, 0x7a7240c60b396dbb, 0xc84b2544a083ebf1, 0x556b858ec60cd574, + 0x0f7f68c821d23fea, 0x09447e107b0e9f94, 0xe30659c66ad5d8c3, 0x4c43069ed13b5a07, + 0x5c1f813f7c9d3ab8, 0xbb649c86aca37d86, 0xdab549708c14a550, 0xb9f38b094e34323f, + 0xf4a680b33c3522e7, 0x56db76c4e7c812c5, 0x653591396a07baa1, 0x83c19a8b38a9f3ca, + 0x85eeb9ec1f7d4199, 0x841915b55ae12a3c, 0x4a8d75e8eef4e33f, 0xc02423681dc148da, + 0xd0ae5d2a15a25dde, 0x00adcefc2ec88483, 0x319f849928cf5003, 0x3f2c9abf91085d16, + 0x5809d7ef7e72ca32, 0x4892ba2af9bc255d, 0x0ba79e9cc5cd7d99, 0xa93543ebf7b852f2, + 0xae487de0e939465a, 0x0b9625993f4b2952, 0xa5e345e9a12ea00d, 0x7ff0a7932cf8837e, + 0xc911fa2173cd5c82, 0x1907daf2d9f9617c, 0x952005b028e08022, 0x01d0f6fa16aaf76b, + 0xa98e3a84b2f03427, 0xd649bf140dd0f6a4, 0x92e109d9db0885fe, 0xc4c1e4852ae19f0f, + 0xfd4244f6fd8b1ec7, 0x382e374e5224ea47, 0x3de7152457229a61, 0x3080f3348e599bed, + 0x8af858c87152ae5f, 0xc62cbda2cbda1e01, 0x816525c4418de8f3, 0x7df97929b652bd61, + 0x1647e46dce394b19, 0x218aae56b7e15b4f, 0x001b9c655ad7cd50, 0xcf9a95ece9ab6e9a, + 0x44f0bc945369c81d, 0xbf743cc9e195663d, 0xc0f806f1dd906bad, 0xd8dbd59384217dde, + 0xc333c0eea88ea071, 0x1b2bfea0c7310511, 0x86b2a3e9bbedd577, 0xe363225f2fe5ca52, + 0xc5fa61175ae57b1f, 0xe55fd5731b4a1745, 0x30aa73768dad2e60, 0x1fbb005063322af9, + 0x833db5e1bbaa87fc, 0x908ae9ea6486c431, 0x7b87ee310160a515, 0xe5c147d2d79a6c9f, + 0x37f0901244b0a59c, 0xddef6946863a4230, 0x726de91defc5a40d, 0xad4420715257d6ae, + 0x38ed303408196fc5, 0xa2cbc9b536bf63c8, 0x1d1b52d387f77e53, 0xb32db47c6ce5209a, + 0x13de4726a12f9544, 0x897a078286e0ffb5, 0x3640bc23dea72e0f, 0x117526606fc31f4a, + 0x9ba81c370783934d, 0x85e3cd3a79fa4cd7, 0x02f050388afed867, 0x184d024ece089815, + 0x68be8b4fbb403d33, 0xa9ccd3e106aebcdf, 0xe804d56e32de327f, 0xcfea5ba43cf97c00, + 0x3b2522c75b9869d1, 0xe256fb75c3704b5f, 0x555196c7203e7592, 0xb68baad0b1156488, + 0xd7a0ad3478e65456, 0x1533b4a622069d25, 0x1d01e90bd43d667f, 0x2b76f7ee53a96564, + 0x341dc0f1b6809549, 0x2a5632463915f239, 0x99b45c62bf1506b4, 0xe431ce42b3641656, + 0x0263925ff02479ba, 0xb9aedadf7d92d95b, 0x6142d5eb839bb3c9, 0x6f0c8c61b99b510c, + 0xd604ee367f1386da, 0xc3e8ffb4e8f2140d, 0x284a3574d5a88d1f, 0x5aa963bb5d548d2f, + 0x5c77bb44c914e590, 0x3400e170c0e907ba, 0xa1c24c927a2434d4, 0x4ed55484a833aec6, + 0x0cf5bb44dd1854fd, 0x6111efb00898de1d, 0x9e58e0ecf23c020a, 0xde15067dc2ed809b, + 0xaad4332534a80399, 0xd964c2393c45eb08, 0xbe26363b47873262, 0x1403dc1b34de805e, + 0x73b022c3eed8b9a7, 0x3198dc8118838200, 0xa7df6e3903bdfa0b, 0x55dfe1daa7693f57, + 0x4153a2bd15dc3c95, 0xe0db00ebd7102aaa, 0xd809d0c16b562d4e, 0x33f68c07455f948b, + 0x0ff2ad37ab775ffa, 0xf45eaf4aab728258, 0xd61bda838549e4a6, 0x91a25a3c25d43a9e, + 0x584fd60356ee5394, 0x78b7f90f16b82bcf, 0x51742ba9fa7084c8, 0x735a63c338033963, + 0x88519260196f8f88, 0x5741e5baf090f319, 0x7fe464b6b7487b42, 0x94096736834f17c8, + 0xf341ccc2256ef239, 0x9b32e0ca197a5a7e, 0xc222e8e3a91d7a9c, 0x14abbf6529b4f9ab, + 0xb5c5a433996fb92a, 0xf790340bb517e4ab, 0xdceec1394e5ebf41, 0xe87b35ef8f510bbd, + 0x8af38f8b1c0a165d, 0x0d93e9597ef01aa8, 0xb69089c00aacb168, 0x86df700cd1d7082c, + 0xd2cc9d867312fa29, 0xd3c91a8a6d8485c6, 0x200fc36e63bb45d0, 0xf9e3b0449e9408c1, + 0xcb8cc66cfd8b5eb5, 0xa0f2147892e7cdec, 0x405a3d9078bcee38, 0xd3e41c996f792a6c, + 0xdf0315ace36a07b3, 0xbef02c951a7fa0d7, 0xad501d9618ce8a1f, 0x1f4716a11c295aff, + 0xea69d7e73cac91b8, 0xc812d38905c60b2b, 0x4999ba140e86cf85, 0x16086d394098f396, + 0x28cce63cb472467c, 0x0333d54a83335732, 0x3fb5798c542c686e, 0x9b3eea69ff0b269c, + 0x1dfb9b8bfcd62808, 0xbffc11ba2c2cd453, 0x84fa1263dafb3ba3, 0x5dd4047e7d1b6536, + 0xfeee8e4c06dfd4af, 0xd0574c9826b91535, 0x0eddfc4713c847d9, 0xe3a211fd760c6c0b, + 0x96cb56932021d5e7, 0x1245962341804b43, 0x203aa3e5851c269a, 0xd2dab9454ffaea14, + 0x745407c6245e9d87, 0x3652768d77ec8385, 0xc898d68999756ef6, 0x5e40d61be1cbead1, + 0xe8d130a4227acd73, 0xfd8349c75e36cdbb, 0xacc5db39985866ac, 0xab2b759b740c480d, + 0x11c6cc7766427fed, 0x8a32a32e0121eae5, 0xf44f9272d4735d53, 0x2399d575b3fd249d, + 0x5be74f2440959d9d, 0xb4f528db8ac82df6, 0xa0d3ae1172ad86ed, 0x0dfcc68e485456b6, + 0x4bb9dd3d2a555047, 0x97f564156ab0e66e, 0x54c70edadc373694, 0x819e46d346e33eb4, + 0x621f4ba4d3a7ef90, 0xc960c804439fcb76, 0x80d076c77a7f6d3c, 0x7b207004393316f1, + 0x8bfcb18140b35e85, 0xe9fd8a1dc3c56eb4, 0x9528a818a22772c8, 0x115b10779b531fb9, + 0xfbab9c458778f238, 0xfd5fa694b61e34bb, 0xa113d9ff58515007, 0x1aed06b9ef841e05, + 0x6f81fa597ae350d6, 0x40cdd9ddf41d44e0, 0xd099413b93858fee, 0xaf6ca1fb12d510e1, + 0xc8c64c59a739efd9, 0x2ea053d3921d53d7, 0x1ab67abe81295eae, 0xf6b366a7ec12c9ad, + 0xde8d18aa3756b150, 0x89f02aa607ae4b4e, 0x52a4dd43b3ddb14c, 0xfbbe8a7d19ab512b, + 0x6c167a64efb1a243, 0xccfac4abe42fd439, 0x3c9595103e05a3f6, 0x0950b9df1e207108, + 0x6a03d09c32dea7a4, 0x5e88eb0d10e08e4f, 0xda0f548719fdc820, 0x5f37e1cd685fb228, + 0x4bbe370def21cd23, 0xb03fd7d70a5899eb, 0x9c846b472498b2bd, 0x44742c1c9f04780a, + 0x0225a479c5e82e45, 0xd9ab3efee0944892, 0x2b93901e09ae4973, 0x63ae5dcf5d76bd06, + 0xaaf9cd361ec18062, 0x0a9de070f631d8ca, 0x65a3f2e4083aac65, 0x802e4410dff9f5ac, + 0x933e1c8552c8d36b, 0x77242c4459fe96b1, 0x6929173bb109da96, 0x4e28787618c0119c, + 0x4e0641d70ae0c076, 0xe062b0cb2b5d5057, 0x66e86231a30efdbb, 0xa5224c68eb491ed0, + 0xee23a5a0e5168837, 0xad13f7f50bae58c7, 0x6255f18b49565ec8, 0xdb6c284dd7468269, + 0x7522197396a6ce0b, 0x74bd7023b732ad5e, 0x209bacc789da78f4, 0xb1a5d83bd2272465, + 0x64ba935c4cdac539, 0x9cd8f52f323cd65c, 0xd7befe83a1cf9b21, 0x7c9ab780e37e70d4, + 0xaccd3539ad967c9e, 0xe58e2e5872d112fe, 0x8df0850bf00a00c8, 0x29670c2ea3485f6c, + 0x7280ba22637d6758, 0x63dd8ef2f10d76e6, 0xc617dd1817288bb1, 0x2ba3f593bf81fcd7, + 0xb69dc3f9ec1ab163, 0x3536787d7beb5418, 0xf4b8ba3815762e6e, 0x062389dcb87920c0, + 0x3f39c52850f34b56, 0xca223251be5b2be3, 0x39db9670d6fa5924, 0x50d41ba8ee8792a9, + 0x4b98c18850bdbf66, 0xeaf31c1976874c17, 0xeab28fb2ee7d9101, 0x530155a69be22942, + 0x579ff0e03fdd7554, 0xd58b588abcab598f, 0x049c172d092268d5, 0x9ff22f3b94946989, + 0x5a69791413e434d4, 0xd1d1807ea7fe76a0, 0x41d1397dc454cfa3, 0xdec2fc5f824c5420, + 0xe07533eb58e3713f, 0x7d1c546f4612ed84, 0x3f4fb8bb23e75459, 0x196b2138f87e931a, + 0x669436452dcd4c73, 0x14243b4526afef43, 0x0146bdcbe1d909bb, 0x71215ed142e9f830, + 0x0ab820250a76c669, 0xeb8ed1dd4be5f41f, 0x32fd2b77f4d1aadd, 0xa86b380e1e8d2ea7, + 0x1674ef4edc54a2fd, 0x058c633280af995d, 0x86690f059447030c, 0xb6b6ffc387dde5e0, + 0x29eb633f897abcef, 0xf193a57229da4b06, 0xfaaad5ad5d8fe969, 0x4d7f6dbcb2e629ef, + 0x40982c877a2b19b6, 0x36be19582fe7768e, 0x97b45b12154ae2ef, 0x5b608cac9c8def94, + 0x8be5e7201e276d9a, 0xa2bcbb964ed449e2, 0xdc91b2b2618debc1, 0xed8e41c8922df1e9, + 0xe4f2c8e39e784b30, 0xa1110773ed8469ac, 0x804a7b72e40b7588, 0x77303caa04aff440, + 0x13bc78bad5baefae, 0xe1e2a3debb636ad0, 0x9de81c54ca0a5cb5, 0x235f08d4c5e790a7, + 0x8a87b164e2b0a8bb, 0xe66fefef0a7c6659, 0x40ea1993063a88c0, 0x846835f9ede4f8c8, + 0x3ffb4e60a5479445, 0x5f9e7ba458f7fc20, 0x71fdee06d321fc2b, 0x258533b53ef06dc8, + 0xa047ac673e94c324, 0x549634696280c1ee, 0x9c3bcc2ae57c1d59, 0x95d568720240e50f, + 0x756c82aa16220d52, 0x38f2b02c9f5f56b1, 0x6d332eedb7aa2b76, 0xd72628fb270bd114, + 0x2f641f6144329682, 0x5bc5588cf218afeb, 0xb20bc520b403382c, 0x1a2022f2b79a1fab, + 0x6609297faf341f8a, 0x29f2089bcc31f0ce, 0x82b978abb7cb46ef, 0x55bdd936d6688a53, + 0x55edf1199d86b7b6, 0xc12a6e907661e9ce, 0xc3e3f7ba1ed737d7, 0xea0fdfcdbffebcc4, + 0x9d7bac8653cf3ff0, 0x2b5fad18ffb37042, 0xac108be56cfdd26b, 0x7ffcd37c0309e203, + 0x1f14d7be0a24eea3, 0x470012824b447d7a, 0x706c45e5895c300f, 0xe90b7a2d44d0e521, + 0xfd8f29ac3919f6b0, 0x2f55fbaa424b512f, 0x1333a55d59e80098, 0xce970ffc0a52f139, + 0x1e1a1a8b3c9d6d81, 0xc004504e92f2c6c5, 0x9f3eb3504e689aea, 0x4fb5b57ddec22072, + 0x0f485e8ac6d456c0, 0x62c92e701548d5dc, 0x2f3203f5ac47def4, 0xde0598028ac19753, + 0x4133c6596aac7e05, 0xdafa4399a0ce47e2, 0xc6538bcbcc4bad6f, 0x5b397fc52fbcab1f, + 0x84e2e02302ed81b8, 0x40b8dbc5e94933fb, 0x6986bc7ad444511e, 0x438deca4bcdd9aa1, + 0x230d1e595346d5af, 0x3e3d6eb2e40a9fe8, 0xc2bafb69cb478d64, 0x68f9e2cd55df7c56, + 0xb3b1e5bf16e3805e, 0x66ab9f4e0c0a447d, 0xc7cbd2a5a9c31b3c, 0x6da100323d6a43d9, + 0x0095438529bcdafc, 0x27df57bc0bd080e8, 0x61f68ba946773e75, 0x0bb4016ee2b05731, + 0x3e99f8affa6730f9, 0x35f8cd06113f8140, 0x692be58c881f1497, 0x6850fcb71f4e3437, + 0x0dd0c4f5da457363, 0x45d54b3bebdf7783, 0x6fb1cb19eeeceab6, 0x5ab1e795cd1213fb, + 0x76b7cde88be3f857, 0x454b65e885c475e8, 0x253ab99c7ad47c3e, 0xfa781d50ecaa1eed, + 0x7d4b3481c8f29237, 0x9877551da3c559b1, 0x991294f242661e29, 0xd4f7a6253641e4e9, + 0xbb013a4c535e74c3, 0x0d9da78470983d54, 0x8560f7df7c140fe7, 0xe247b7b8cc1280e1, + 0x1ef70420ebf1dad2, 0xf1cc1ea551d17d93, 0x736eaffaa3f61fd1, 0x2c5b7f21a0ee02f8, + 0xe00d3051d43521a6, 0x6a8aee9197979abc, 0xca8be1d72fb24080, 0x2c83c30b00d928f6, + 0x8282c3797babc781, 0x811935570dd3a6ef, 0xa1bf60537720163d, 0x5ceec0878e299016, + 0xd95db7fad1a992bf, 0x75275a08984fea7b, 0xf3a64beca260f9b1, 0x06ae7891eacf8ddd, + 0xe74a604b26ec114b, 0xe5e8795494a413b3, 0xa4c7dc355c1f1c0c, 0xfafd10bbe1c22887, + 0xb4d4744e6df0729f, 0x706badb38a285796, 0x25dcd7aecbf62530, 0x84983d6091531ed7, + 0xf9a91c1746e986ed, 0x8c3c48d20594095b, 0x48382b612ead5e5b, 0xac0de8dfd0e34903, + 0x94fe970253308518, 0xfeba7a72c06ca7b5, 0x6e439bd87fb1dc6a, 0x59659aa0e780335e, + 0x500bf820162e6fc4, 0x3ab4e4adbbfeb856, 0x43981f470d82f41a, 0x771674b177628e2e, + 0x075eab258ab653c2, 0xaee2882a943ff301, 0x1b27473ca58ffaaa, 0x737c21968599133b, + 0x25d792ddf94f79e6, 0x2dfdc6525cc00029, 0x24aec78423bf5c57, 0x5b106eedb81f364b, + 0x2fd8db7d3c2b13ec, 0x5f7f95fadc9783ce, 0x1799e120f077f6c9, 0x1aa459a91f6a36c3, + 0xf3321cacb1511dcd, 0x1bceeac6187df713, 0x410ee9b376f30452, 0x793609400365981c, + 0x876e75d887f2f101, 0xdbc1484e8fb8706c, 0x75aa05b8f6ed9191, 0x14d2f3a1ca95c6bd, + 0xcddeb10130d22eb7, 0x52ed9ad38503b576, 0xfafe57cc176c0403, 0x8170cdce34667c11, + 0xacd06bc0780ef149, 0x195a1f0cd6ea9ff1, 0x713a88609d46960d, 0x93934526a00eb72e, + 0xb86b22c03e712846, 0x7219b6bea25d35c8, 0x4bdd36e3c2978c6d, 0xa0cba610e2905b16, + 0x298ac7d04908ad60, 0x46428b07c44e6887, 0x76d803bab3397cdb, 0x3684fa6529248b83, + 0x1eb3a76fe775d12c, 0x9c58c59842629fc6, 0x4da36a6d1bdcbe5f, 0x159e5f58f8a3b540, + 0x7b453db9123b626f, 0x4e301fd6246c0cfb, 0x7aa6f2679d795e91, 0x11ac21f461c06e01, + 0x65e30767660afaf2, 0xed53849379ea1b7a, 0x1faa814c84551f29, 0xd086aabf74a7f5f4, + 0x1fc2286d10b4e812, 0xf3b4ac72eec0cf4e, 0xd1b91e287d541729, 0xf15cf8717068fe3f, + 0x844f54c7cdbe429a, 0x822d30345754b8d9, 0xceeb383983678b1e, 0x98d230d30024ec0e, + 0xa3b5999b9314c56c, 0x8f3fdc8755b19754, 0xd3f3fadcca90872a, 0x204493e688d23400, + 0x4d93155dbfd67387, 0x52603a37b2a7d72d, 0xd3dd90b6faf2a91c, 0xd86ba08d63f3bfa9, + 0x297ea48709c5dcc8, 0xc5a60f70c232627c, 0x81f2c85651f8ab9d, 0xf242317d5d72fc58, + 0x40fc056098555f8a, 0xf92573b1f80b7be1, 0x348d64773f64aae0, 0x4d6ba134b1b1e2f6, + 0x524890475a4832b5, 0x4264218ca3f77aaa, 0x5e4505757bc44459, 0xb9c2ec758a2900cf, + 0x761e865824383c84, 0x7eb27b21e816f477, 0x654a05f40b3945bb, 0x1c0351ed82cff701, + 0x081e61762e7b4247, 0x20c7b3c613052d4b, 0xe890d639976d834e, 0x0e010c137d82a90c, + 0xf3c4669c734d3405, 0x2a69e3054051c51d, 0xd26532d6fe62c58e, 0x4e032b14c32861e9, + 0x2b05bcbeade9c8e9, 0xf5325c27fd2186ff, 0x09155cd5996fe687, 0x0741672c5c9d8e02, + 0x19e9663e9782c659, 0x4a17e9acfb832692, 0xb7db1d6020534ddb, 0x4eb80a906def8ede, + 0x6235ddf37fab84c5, 0x90b7ed200ff636cb, 0xdb567ffa21f84109, 0x6a6f290a5339dcbd, + 0x5a310ddebda79471, 0xbf4270200b033ddb, 0x5a9c0ad6cb2dc8bb, 0x578461089fb75ee1, + 0xad30333392c9f417, 0x6b2d7fba9f09604b, 0x9e3ddc5cbe2cbf08, 0x55c3d2f1464d096b, + 0x307cbb8246bf8dcd, 0x3730b0f1012eb0d5, 0x0c8393a4d48895a9, 0xb117032d9c0dbd50, + 0x3e7dc4b693dd38c9, 0x2852d037799efc60, 0x802884a5a4f90bc7, 0x0ff140f62396f353, + 0x76c938109c8916bb, 0x0866bdf44a64b752, 0x7afda533ecbad279, 0x6a4891e0cb73986e, + 0x27ee88fe6402e8d6, 0x8e09ad5d27313a71, 0x1387b8f864e2a0c3, 0xfff6cca7e3e6a376, + 0x7135ebe4f69c5ae3, 0x29b0156c4aa766a4, 0x2d3a01bab5ee2721, 0x10e90946003beae1, + 0x222f554e8299dccf, 0x9b8edaa2559591cf, 0x83c130b08b685cfc, 0x6ccd28cf1865ec9a, + 0x404b9658d953ae89, 0x2a5c33d1a1c23689, 0x53013a1504ebcc19, 0xa2c33e30eb913f3c, + 0xb8b25004e9250f7d, 0xc58b720152e893ae, 0x0697bca1562723ca, 0xf2acbc9931d28b99, + 0xbc4d734f9eadfdd3, 0x4309a532d1f69b88, 0xb2ea7225a0dd1d66, 0xfc3e6525acd73353, + 0xe63ecd7e8ab7f786, 0x9a02b18fbe3dfd55, 0x00009e77589a68f3, 0xb05757942afd3573, + 0xb7604baf88a47fe8, 0x203c3469ed5fb3db, 0x9e285f0d1415d4d0, 0x54e57b00875d662c, + 0x68df74370c2264c7, 0x2a88510cfab58a2a, 0x25b0428b18986c2a, 0xefc221b10e5bca0f, + 0xba3bb182af5671a0, 0xb95605adcb6d287e, 0xdd6b836c2f8159db, 0xfaf7a301afc80cff, + 0x00d957f240e7ad38, 0xf70524efec05c34c, 0x86369e947b9dc9b7, 0x31323c4ce232cb02, + 0xc2cf47c2dafe18ab, 0xf441fa74cdf35fb5, 0xe02032f4930e8935, 0x1ba3ff67f39590ea, + 0x684b7e869c2cd13d, 0xecbdfb9243e0cd6b, 0xa34dc40982f070a5, 0xdfcd4ee911b130a8, + 0x7b318b977c5da342, 0xfbc0cc23ea1ce086, 0x90823289dc113374, 0x5e9e417cdcf0cfa2, + 0x4da5c4737fab7524, 0x9c287bacfc92866f, 0x803886d6f883ea99, 0x07aba60c09a22b4b, + 0xdb9cc27dbf1ba1d8, 0x0579aa9a02ae92cb, 0x7a80e3e3727eb657, 0xeccba0498386d34a, + 0x6f6ee44287bbad01, 0x2c16efac48d23ad8, 0x1d89636be65cc278, 0xd8d311af06f78da6, + 0x6f1f62a014fe163f, 0x7536c21aa75e5122, 0x64e8c6ed73bf033a, 0x526371c1c07eec0f, + 0x7f3e19b04884c9c9, 0x3fbcc4a06f8f0009, 0xbdbd45be1939cde4, 0xac3a9c988a0f219b, + 0x95ed7eef5e4dad56, 0x0afb30ade0fa5713, 0x5cfa36408822abcd, 0x021d64e96ed444c8, + 0xffa99bac71612c8f, 0xf7c90e3b17b50c50, 0xa95c4897cf07440d, 0x0c9995adf85a584b, + 0x2cd77ba5e4a26dfd, 0x95560587993de26c, 0x661e8e35c7c049f1, 0x87bada3f76e09e5d, + 0xfeee24b8d6e97f36, 0xb1004deac829b857, 0xeb51027b4e72dcf6, 0x47860343d28b40fc, + 0x288408f94b075f3a, 0x8093f95fdf799172, 0xf1a6cc6f4b74bee4, 0x6ac2ce913693a5ea, + 0x85226f249026d3fb, 0x7677fb2d1451f3a5, 0x6fd32728fe4ae65d, 0x3187d5104949ed30, + 0x3fa34a1e953e5cae, 0xd2872367a58450b0, 0x9252b32f5e423646, 0x7bc65cf4e72d0b2d, + 0x5c92da9cc6f4fb49, 0xf417cd08687a6d74, 0x891a8116385721e3, 0x7367ff0ce20bad6f, + 0x8f81184748ec07a2, 0xe97916a44a9035f0, 0xabd7335b3f8db96b, 0xf435d70af3b6ec7e, + 0x7ef5a8abc69362c3, 0x8112c67d568db8d0, 0x9d8f9140a936e6ee, 0x01841533a6945cbf, + 0x0c88dd7ee278fbe4, 0x2675add415581159, 0x66a84a1a8598a0c0, 0xa655b21e7fb9bde9, + 0x1c6a4f5b346b4e03, 0x0d812b378e45123a, 0xb76dc272c7d4ffc8, 0xf2fa977bf6236c99, + 0xe53a4e10f1127e58, 0x3685fb8f6a99fdbb, 0xa6cdfb6f3eb88059, 0xeb0d9b9231464f11, + 0x58c1ad3d9099ce81, 0x68d7ddd698709e76, 0x988e555847be1260, 0xba9795332cbedbaa, + 0x7f7932085c3bb30c, 0x835b299205f22a7e, 0x29be38eb1a3a2008, 0x2f6b5276b7793d24, + 0x013f0b7aa3cf0b4c, 0x793f3a0bf3b8c1bf, 0xfc166342d101c56f, 0xc0067de1923a26d9, + 0x87b84789dac694ba, 0x5dba43616bd0c68a, 0x17c92e7b7c1372c4, 0xda5a18166c0d87dd, + 0x4d2fda4ffca3c1e4, 0x61e35569b3052d11, 0xcde9b16f4ac4b15a, 0x3b8eb91483c7abc6, + 0x3bae3b780fd988df, 0x25f386da6b64771a, 0xa270b9754a842d23, 0xfaf0660efba4af20, + 0xc52f6e9b0d930016, 0x420b2276433f1084, 0xeb5203326985af94, 0xab62277e98ea4331, + 0x5c1579336d815e8f, 0x11c3c74b023835d8, 0x4a169e6fe0fe362e, 0x9d26ddbcc2f915af, + 0xf6e858d89a72de23, 0xcbf04f7caf05be7e, 0xba6de0e0749a0377, 0x5244e8573b6d4135, + 0x9fc9d91f87abccdd, 0x18e9cededb1bde1a, 0xfcc448978e7beaa2, 0xfb1d8e002ba9b852, + 0xa04666ebadb8f65d, 0xb67843a6c5c9e9c6, 0x32d9887dd3028b92, 0x51381050ea0522d9, + 0xf6b755dd6dd15607, 0x4fac0b7a04780a83, 0x6bcecee5115e0c0a, 0x002d65301846c3e4, + 0x242389b56256aed2, 0x5493b33727337f7e, 0x6e4c246ccf9ae62e, 0x580f6c2fbd84f52c, + 0x78feab157b0c258f, 0x34df24b5eeab2b27, 0x88a87bf6216abf60, 0x9d75525b86165d14, + 0x65ad4eff45c09e06, 0x3e68b27026312dc0, 0xb04ecff45e11562b, 0x1aa3a3e0b27ee625, + 0xe5d705c27a1be709, 0x5802b259ed6e3d67, 0x040d594d0436264d, 0x70d6d5a40e1ea48c, + 0xd67d0b9f6a24da15, 0x8ba9036ff8348d09, 0xa25b0d5a27f37e79, 0xd1e33fc657dfe209, + 0x980ebf4cf7c83d9b, 0xe68de6bc5af00815, 0x2e74c43566954678, 0x7497764591a81a86, + 0x5578a453c7d7168c, 0xdaaf0a3b33e9195b, 0x28ef49c68282e47f, 0x4d2bcd04792ad340, + 0x5e7abbc03dfdc56e, 0xa5ef9a77cb92e794, 0x918c7e08cc44da38, 0x443bd4a7add01449, + 0xb1689cc0293e59b8, 0x376ae4eb7e63898c, 0x48b6439b5155247c, 0x9b6bd1bb5fad621f, + 0xbbca2b0db8ef483f, 0x60839b79b1fd8077, 0x53896df7b49fc2ba, 0xedbadd81ad675287, + 0x439c07002d93c773, 0xbc0b135fdae0071b, 0xd16c36ea859fa311, 0x9a2f59f18e5a336b, + 0xd7f022cd2acfab8b, 0x565c4ada530783cb, 0xff8fc630bef02782, 0x97e6f8513cc49eaf, + 0xfd34ef4ee526a2b1, 0xdaf614da8bf00162, 0x004c0fcafc0e7e5d, 0x44f15551a0edfb62, + 0x56bc0f68be7399ac, 0x1d4b074edf46748e, 0xb3660b2bf82cf330, 0xac1fbaecaf897e55, + 0x85bea8578d688ec1, 0xf8384402ee5ed763, 0xd3808926506f4282, 0x71a32c9f12d502ff, + 0xa824d97dfff89f18, 0x13ca3a0f002eb2ca, 0x5b59298466e0c7b8, 0x5979470d17f26aae, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x527bc06b69d3c6c3, 0x05498eba956c0576, 0x8af60ddc108e2cd7, 0x525cab2ffab7d9e4, + 0x876279cb60382bbc, 0x35f80465ca2bea54, 0x1cb75708b47262b8, 0x454d184a787480a8, + 0xf84cee287c5d5d24, 0x77b9ee8ab8465bff, 0x8b0705bdc161999a, 0x99cccc004bef1a29, + 0x76d9a4b18d584e51, 0x934e1591e4c767d4, 0x0d68e5ddaff0b1c9, 0xb95e68b04147c852, + 0x58ec6f70a9ec2425, 0x30540079823bc9a0, 0xe475cd6a3fca0cdc, 0xa37d28da4967f14f, + 0x7fce8638fecdff45, 0x98187280ee74ea16, 0x4f9d2fa1df01d9de, 0x6a542cea7cd3b94e, + 0xda3fd31eacb4c0be, 0x6c4897a56975e65b, 0xce21ba7b2f3782cd, 0x87feecc2b2fb1245, + 0x20edf5aa560d4a58, 0x0bedfb01609cde9e, 0x2ec53f5943829dc3, 0x01fa61eebd049076, + 0xaa0ecd8ea37992cf, 0xce2080d9d9d3d2cf, 0xd2d4662d9a071cda, 0xe1fdf7f5d37a481e, + 0xc9c2a730fe3a36b5, 0x30e52565fc9dabfd, 0x38571f188d4dd4f3, 0x66efc528e471f9a7, + 0x8dd25558c49bd972, 0x2312737577df3097, 0x614b3979db2b79ed, 0x6bad0b0b5cb516d1, + 0xe49bf01be371b050, 0x6d4164ba4d12f7a4, 0x7bdb13874255f3ef, 0x9a1d5a1ce1ebdee7, + 0x52a3b0638af27831, 0xce52b48c4468b91d, 0x4c89e8b6b417334b, 0x225d500b3d251ddb, + 0x5602211f8c27777b, 0x58329b879ccd2b34, 0xbb737d59a15cc10b, 0x1179d6efaf894ee1, + 0xb5eeb1f1d16038a4, 0x8b79ae4a94af87ac, 0xc0fe0599d51b7e3f, 0x2e90a083f45e5a2e, + 0xd3bedc90fcbc932d, 0x6fe5e7d09db47405, 0x737e67a05d097232, 0xe424d7cc9afd00a7, + 0x4b6f985d28921434, 0x94273884f6c42b59, 0x37929f69bf344e72, 0x4f8e4cae2ddbd892, + 0x1c13fc4ab1ba0452, 0x88e9564d129f32a2, 0xdea8e01400a0b7c3, 0x3b1d1ca457e316d8, + 0xf5b4363728eefb64, 0x35635f3c2b39dea6, 0x7c0397b5de6b77ad, 0x143b1c0bd134e41a, + 0x32f3f8cfc2aa48cf, 0x6af26650ef730f75, 0xf10dddfce6747e81, 0x415d62e6a698ef4b, + 0x4d2c202348a8a8a6, 0x0b9c9c3f78594116, 0x0db3ea52e0967922, 0x66289f1221fe3c2d, + 0x5f2ed12125c16a53, 0xb31ce59ce7678573, 0xf4f18e32934e41b4, 0x5a5d53e319a3ce76, + 0x9b8cc6650616d74d, 0x38e6432ce39488ec, 0xb19c9ef2ae396ddb, 0xb240e3a5bfa3d7b1, + 0x3c2e79d6d1af706d, 0xf3ddf33a537353a5, 0x2f70b6a05b16bbfa, 0xc3277c04cd96252c, + 0xac440931c14b63cc, 0x5a381e36c812809d, 0x44a8f07ce4a8e4af, 0x520a0030035dc4fb, + 0xc39989af8c6aaf5c, 0x618be06597fe1d11, 0xadfb79ff2b1c9e67, 0xd1efe42505a354f4, + 0x2d4693f22624687b, 0x3131b4d208b77967, 0x7dd88f28e16288a4, 0xad9a91a1ad60567d, + 0x4fc0d5898af0f4a8, 0xabfbbe028dab6f38, 0x1c7ebf59ad529a72, 0xa1103fd248ef6655, + 0x5232e43b1b8b48eb, 0x487c5caaba72aac7, 0x6df179800409a351, 0x9dc5b62ec041e68d, + 0x8e8cb63d9a3e6802, 0x2ee477de98105c0a, 0xfc9b63e302e6a88f, 0x77be699081abbc6a, + 0x311aa96418b534f0, 0x7139373ede15c937, 0xe77f3d855a40f67d, 0xffd549aec9539c04, + 0xb43f7f6627b3ec9c, 0xe1893de70ffff7c1, 0x9c68f5bba7a538fc, 0x37b323311467365a, + 0x446fc45b43101c8f, 0x2302cc8eb20d1fd4, 0xa4df959b36b02eeb, 0xd61c9c6005732146, + 0x3a7d5c663e11a288, 0x97d687ad2b43268f, 0xd8b72b2ea8ac0f9c, 0xb3a1bec5c3d64d51, + 0x2fe0437f832d326e, 0xb4f782627f8ffc0f, 0xc802630f134e8ff1, 0xa976247a20f9c3e8, + 0x8172015e2e9e84a1, 0xd05f43440d213683, 0xb7ae8bfd397ed087, 0xef617cbe5bb6d51a, + 0x86f1dc4a06b1258f, 0x3c16f88d60ced74d, 0x2ad2a19b2d60da1d, 0xbdbcc0afd0284409, + 0x8cc31202ba4c5635, 0xe921f17ab3a71f0f, 0xe00af9c780df137b, 0x1dbde3b846422082, + 0x22003ccfb7df4afa, 0x6fe17aed18a1eef5, 0x8b4d08c3a7b01bf7, 0x97441d7435875eec, + 0xb1c09ec91a0dbb15, 0xd1224b3004b77c71, 0x337ae492f4dcb3b6, 0x979f3c259b268cc0, + 0xe597eaeefdfb62c9, 0x5780d8b5f29fce50, 0x292c118b87872cd5, 0x49c3014d7c02ce01, + 0x6d2859332e630e36, 0x1ffa8fca890df4e2, 0xf5d942b3b521be9c, 0x41fed73ac018fd14, + 0x0c3874f45a860f01, 0xc1742055f2f655b9, 0xe787aa619dacfc1d, 0xbdffc41d11e879b0, + 0xfec8cbfdbd023c03, 0xcef0bb9260290a3b, 0x30066ff9090e8cd4, 0x41b8763b7d2665e3, + 0xe8d514e544250487, 0xef5f63c03f53e873, 0x2aa4d86daf3a82a5, 0x2a6b8ecfb6be9fb9, + 0x20f2aa6503d9c3ee, 0x26bb05bd46f6a75c, 0x70f09e251c036bcb, 0x1651d9ebdd99c00e, + 0x0a1efc3158005c9f, 0x2630cc5633dea383, 0x6b2e4fd9fa9900c9, 0x9a0f20e2b0d0ef6c, + 0xe0a375cb130c235b, 0x026f0324789b19bc, 0xb00adffdc53e4679, 0x309d682a20e3b4cc, + 0x9a708e3803f132b1, 0xea307336668667aa, 0xe585ecbf32853f75, 0x3820f32d1c51a74c, + 0x7b7c03ef41076761, 0x4437d4af98bdd255, 0x51ed16da4a4337e2, 0xac9cea2dedc3d3c6, + 0x2c32b0c90a84806b, 0x7a2b1a27732003d5, 0x627849d214aebc79, 0xd90ecaa8b13dd4bf, + 0xa3fd31d0eb60c816, 0x80ef80ebb334320f, 0x6964641ce74227d2, 0x44708ac91167da63, + 0xe5d108bbcc0be99b, 0x619d65a3a484a5c9, 0x63b9095fdbbc3e94, 0xa2dfd29403dabcb6, + 0x32cdc14d5889265d, 0xd01527102d9be1de, 0x6b01b03562a3ac7d, 0x3d9bcf388d72f405, + 0xb185073ad4ee70e9, 0x5303cf55725cc965, 0xd02bae7f388f29cd, 0xef6c95d804001c34, + 0xd08f063051125a7e, 0xbd16db472737ab4b, 0x9b4a2c87f779a94d, 0x3bcd4e2c70023b97, + 0x939d65f7a94ad0fa, 0xa3bf3a1ffcd9df8a, 0x53bc2cd7b0826a03, 0x24463ef66fc58c3b, + 0x0c061c57dc62192e, 0xd56d417f8fa3cb2c, 0x4c747df3f421bbcd, 0xd3fafbb0488feba6, + 0x862e61b3e28e9f16, 0x9d25259e46096eca, 0x0cb19435d177d2c3, 0x7d37ec1d69645729, + 0x34a79b7571da5923, 0xe0f2857ded0db07f, 0x757b6ff5f0906697, 0xa4ee31d02c7b44d0, + 0xde417bda5b474733, 0x7ad4a3959064991b, 0x7c649d87b5f11656, 0x9d31b799f11c6bc4, + 0x9ea74b7436a56472, 0x9d4a9afbeb310aef, 0x79a11186ca6828fb, 0x9b9eac9af245a8ea, + 0x06f3bc8df2bb1c0a, 0x9da08420a9cab483, 0x203c4fe107bd2a26, 0x99bb32564db646cd, + 0x3881af645f9f6cce, 0xc59683c28446933a, 0x099b304810100d8e, 0x48f970c9ec4111d3, + 0x71902bdef39d81ae, 0xe96f41d09f1da163, 0xbdca152b8a6092dc, 0x98c30847f6fe6f8d, + 0xc5d858548e798a87, 0x2f330d523af3e613, 0x729a2b4a351ab44d, 0x4dc5b7810c1a167d, + 0x3416bf916f8996ed, 0x70c3ddb3af0a1040, 0xda9d0e77c3ffd501, 0xb13663b5ac9be58f, + 0xedbaa88f41805287, 0x5dbcdd2c26e202a8, 0x88d3c69477d3ced3, 0xf94c7a8429467651, + 0xdb0f9095b0ef2f4e, 0x33c25f9ac74fce4f, 0x8789b42cd793113c, 0x0615cee2a18a66ec, + 0xacd19f05ce522ddc, 0x8d193217e004bf70, 0xde304b40ed93a7b6, 0x9950230705069326, + 0xa39ac2bdecf5a35b, 0x5c584231369edaf7, 0xf14caef9ead95f57, 0x7a1fe266d14ff9e5, + 0x2ffa4aa05dd20078, 0xfc1640c5f8ad649f, 0xc2c842b7ca977417, 0xb8f6f8bed57d1787, + 0xd7951b44dbdfa1e1, 0xe7d5ee18b668c5bd, 0xc508b80eb87843d1, 0x0ada489d87cef66e, + 0xfbc5d7fdf5b65dd2, 0x4cec150191658ece, 0xa4ed2415f11ca6b6, 0xcef97a762fb315b8, + 0x5e5d86fcc6530c63, 0xcd06aba91c549d8b, 0xb1291a37dd276637, 0x2399703400bafb43, + 0x0682672a99c5dc78, 0x5856670349296bd1, 0x175d7f91e968ca54, 0xa501df19ce173123, + 0xf30d6ed491cf98b3, 0x0634a8607a78df7f, 0x4a52aa5d0a90ce55, 0x8a7b1ea23bad88a6, + 0xb9df4fe2a8b0eb33, 0x2a3b088dc66146b7, 0x782355254bb4cd81, 0x0f7ab7ba0b6bfa0d, + 0x01a20ece85199c31, 0xd66a138b603bdd8c, 0x6f2c291883dd1141, 0x7308e11eb374ee45, + 0x4e5c546f815a23de, 0xc27ab6f752764394, 0x823ba591cdf6e231, 0x4f43e0c2373040ec, + 0x3fdc79fa1d0d34fd, 0x0939aaf3112b4ce2, 0x3ee2baa29c0aba26, 0x67dde73e9a732bd9, + 0x3d45d85d529d9376, 0xfab8626835b069b2, 0x7356b6a4fda352e3, 0x0a3ec98792397666, + 0x54eb17aaf4d92424, 0xc8f1bb8291fff65d, 0x057baa1bfb3c80bb, 0x0ec74efd9948e6a6, + 0xe139d7e63bc3a6cd, 0x01d34c5372f3990b, 0x8998d23238cb0964, 0x1eac71a1a4cef3f3, + 0xfa512da72508ff54, 0x5ad4ec1e22378f8b, 0xa88356fe6c2b667d, 0x783c683b7f9a4593, + 0xc6adbe981c29c9f4, 0xa62b8e0264006eb3, 0x21a302897c333094, 0xd9e68cf252a89173, + 0xd413a38eb3333de7, 0xaf2665b565a8efe7, 0xc7edcc1879a55733, 0x8efcc1a446668e9f, + 0x9a505f0eab1ac263, 0xb158989a9b5cd50d, 0xe531fe0d9c6f3093, 0xf2ce8f9cbee3b7a1, + 0xd0aaa22862a8592e, 0xe2bb580ba6053c7e, 0xa065b762acec45c3, 0x15a64f28a583b910, + 0xa60c5ab64dc9cc33, 0xc7be61a23432778c, 0x3b93f9b996c66db1, 0x637a384392bf619f, + 0xaed5d351a2470bbd, 0xd4822cfaa39fb5ec, 0xe03f6dacb4e71524, 0x7291f8774c2c0771, + 0x28be310786b27725, 0x687de67c79ba1c34, 0x2e2d7a155a4ab615, 0xb4ff6ea11dc22e4c, + 0xcfa326bd4e1fba66, 0xaab46c8994735d1f, 0x74c80df08305ae81, 0xe0b65f217cf29acd, + 0x887bfec93ba5402f, 0xac7717726e3f643e, 0x1fb48d9513758835, 0x277d80216264480d, + 0x568b4d85bb69c481, 0x8d333b15ae871fbf, 0x29a005373d6d6cbe, 0x4237fc6ab33de076, + 0x9d85920a19b30958, 0x1947a72ebb36b9dd, 0xa43c432ccdaa7a02, 0xa1d857534f215d41, + 0x4281a176456ba54d, 0x28771e2f0619e83a, 0xa1b3ccacae92c6ae, 0x991750a9ac1db45f, + 0xc18e1b1aa427ff52, 0x1a971ee527f13956, 0x897af3bdc37d52d7, 0x1daef12cd556ab4d, + 0x4649ceda24efde75, 0x979285dbf715b358, 0x9731c1fc6d83a666, 0x056f3b07f3d3e02f, + 0x5d5e0273972a3f01, 0x0d44493db5ab35e7, 0x5b652d9fdc5c8d53, 0x9132c09ebfa009c7, + 0xe8cd596505e4c886, 0x5bfdfb654539873e, 0x710eb30619195b01, 0x5c1c8c1d318208ee, + 0x46be5759fa2611cb, 0x8a2ff5105f01334e, 0xab52c31aac3714e7, 0x63e8640b013d0b57, + 0xc4286c611347a206, 0xba757ce138460497, 0x16c7f4e4106a1bbf, 0xc7944db997763be8, + 0x0f82326a0e08580c, 0x4bb0daa0a7928719, 0x5372c25318ac2da3, 0x3c499e8db4091448, + 0x964ba0e347cdf444, 0x9f9861f80307b682, 0x7e3d70eb721f9f28, 0xc09af98c860ac6cd, + 0x59ee754953f413a9, 0x8f873d6d20f3ee0f, 0x748256c0b8ef7e2f, 0x5cd3c8a23d365f2d, + 0x64168676872d4589, 0xc3f0b1504ac8f909, 0x1fab77143ef9297d, 0x27ce95e651e80c40, + 0x6bf0a4a149beee8e, 0xe5f4318173181810, 0xf9e1109af278b5d6, 0x20350cc1c70e3f40, + 0x62814c97d7b67216, 0xe98a02d9b5573677, 0x775053e204087f2e, 0x26c1ab69939b6abd, + 0x502904a8938fc3ae, 0x3418acfcab8d005a, 0x68edff9ba48c045c, 0xfab82881219a0a72, + 0xd9d743bdafc699a8, 0xda25e6e5ebb0a0a9, 0x3efa707ba9fb191d, 0x6dcf9201194a26c7, + 0x2500d29cb2567e28, 0xbe93dc5dce629d19, 0xa5d8fc73ff70e757, 0x6da16566c731fbb6, + 0x03054492fa748acb, 0xa3f691b5e6ebb6ab, 0xe70e9e259ab09c3e, 0x1c9af3d7a721f52e, + 0xc5ee7aaa7a72b6d7, 0x9a76746e0eaab44b, 0x61754d335583a8d5, 0x1b6602136624b5e2, + 0x0d5ff67d2fca3d30, 0x44d121ee1d0f59dd, 0x6f520d90d0a2b85e, 0x90a6f6ba497adc51, + 0xb5fb5999391b3633, 0x9782a37e84cda07e, 0x94332745fa6758e1, 0x6785cdf3f86f2435, + 0x585873707c2adfc3, 0x296aa37e739afdd6, 0x7a252c526b67611e, 0xcd1d3495be0d19ec, + 0x22e02c0dd9f7b691, 0x68f1f0a5c2d3ee29, 0xf8c429b337ceb8be, 0x4183459867716757, + 0xe05ab2f5df16e74e, 0x7baaddfa1548d180, 0xfb783d7474d89a33, 0x2cfa83c5a876f786, + 0xb6873b3e0adb43f3, 0x80f2e14096f518a0, 0x1e62c8ada3ed7c29, 0x9afa34ac874b131f, + 0x2a5379cf2de87ef5, 0xd9d7ce33e21f6e62, 0x9677b81462106d7a, 0xbc95b85c79d4a7d0, + 0x0f14cc12685d6ce1, 0xc917d85c1074389b, 0x66c1290a1ce76d03, 0xa4befc1343b5db1f, + 0xfa9ceffab2c18101, 0xdbcc1250b6c50ac2, 0x224e9bd15162e30d, 0x5dea04407e7d8316, + 0x82d7881d81c4c5b9, 0x16cdbe057b87fdf8, 0x0cf6f0b979e33697, 0xa3c2fc254738ebe7, + 0x12bcd78e112f7abc, 0x352ac1ff2c7a7123, 0x4f428cd0af990470, 0xe793219287307feb, + 0x77acadc62d5625d0, 0x5679cd42e147b893, 0xdf64902d5c436273, 0xe6e2df1fb3f0b493, + 0xc23ec5a0a58c8a50, 0x71a7737077d1f4ad, 0xa3984db89049a293, 0x6cfc4569a97b33d1, + 0x0f7773cbec0078c0, 0x223a7415eb8c1b89, 0x86d916b56ea44ef6, 0x34177c8a67558ca1, + 0xe8d52d3e5b4800ec, 0xd25202d17c0c45f3, 0xd66b923b0041372d, 0x31c23e908ba0fb86, + 0xf25b3029c6d0c0c8, 0xdcd5dd8e6fb8270f, 0x745fe13f3e1842b8, 0xbde17e0db3bafe0c, + 0xdfa217c57eb8444e, 0x71acee25fec0bd8b, 0x2fa5d687fdbe62dc, 0xf7d485376ef9981a, + 0x3f890b66aeeb2227, 0xaee43f31a783c84f, 0xe27cadee8fd181f3, 0xb0b6ce9a4bfcde8f, + 0xc99b2afdb62b106b, 0x081286cbb9226043, 0xcd8fa3fce78027bd, 0xa502b7ed60ea56aa, + 0xafb10aa5949ccdd8, 0xe5345259edfb1ccc, 0x0cbf812d9a49e31b, 0xe1c8740757a23930, + 0x67eee9e82b5605e9, 0x858f5b24945a88bd, 0x22915e49fe42c35a, 0x776ed5d365290cbd, + 0xe2f5b20a25c5b7b8, 0xed5cbcc0e4f7c8b7, 0xf46acf4dace016f9, 0x4dedbbe548f230dd, + 0x71026831c9ca9f95, 0x3a4043da86b54849, 0x64970176b1397c16, 0xbef5a640ec11823a, + 0x84554c053ffb7d8b, 0xdfe4fc206a0146d8, 0xa2ac8e5ea0d196c0, 0x999c853beb7db32f, + 0x5bc34c93ba98ddb9, 0x633888fa2686d4be, 0x99a275407547d6bd, 0xc211e8ce31ff5777, + 0x1f3110d37470afd2, 0xb1d45087e444f060, 0x4480ee2ddef2efb2, 0xe51c319cba5e1993, + 0x9d114110951c462d, 0x63936cd37c3c3b50, 0xc3ecc17873090db4, 0xf024f6771a17d9fc, + 0x105b19bebdd07017, 0x4fb78ec3c1e9222d, 0x11431281659ffe9f, 0x5e3bcb1615f4f364, + 0xc8f42915bb6b8d8d, 0xf5a411fd12c1e14c, 0xc47d9b6815aeceaf, 0xb19f4aa7d1d4d66f, + 0xeebd588fa66843b0, 0xf7c733fc8ec9b0c0, 0x1934a8661c55f1a9, 0x3276587f1448ea7c, + 0x228177458445cf0e, 0xa32c25de9a4ea2f1, 0x3bfe9c90c3115084, 0x3d78811bb5be1e15, + 0x2073a64f87bb4565, 0xc0a18a91126bf02a, 0x1db1d41b531cea01, 0xe2d389d643e173e3, + 0x9821cb570db7c548, 0xe3b0325dc849a73a, 0x1c2cd6e05e22bfc2, 0xa94a97ae1c0668e4, + 0x4c86f87d1e1568a6, 0xe25a2b104439d8c3, 0x394905bccc5d7940, 0x30b38f18c0cb980a, + 0xff7470608859a262, 0xff435b62eb2f0138, 0x57ff9b8b524e20a1, 0x2bcf4dceccebe38b, + 0xcc048ce8441d87f4, 0x3bd9751020a2e8be, 0xbf8f55662bae10db, 0x3d36646d0bd072fb, + 0xfda298673ac05f6b, 0xfa37e9f5351a0d0b, 0x3a6a0e3a9ee687ea, 0x877f92c95aa3079b, + 0xc81dd4ed48f9a625, 0x741eed7861aef93b, 0x2dcdb8a805578a59, 0x458d27f03b58adc1, + 0xd635a7ca054a251e, 0xbdc1674249144311, 0x2fe3f014f0f6f6e8, 0x05bc37174ad163fc, + 0x95db2dd0081b7445, 0x35fcd01628839f9b, 0x4f2a2d1b581bc1fb, 0xc2251baf1a9e5f58, + 0x3e04d8d25b5266cb, 0x41138154d072046e, 0x7fe056b5c1bc9513, 0x7ec5a07020b22bce, + 0x599c13ed2a7198da, 0x038e68ce14fc8bf8, 0xd50d729fd0e00631, 0xd122bab3bcdfbd18, + 0x5af5c2d77db32720, 0xe5d7f81391dc86fb, 0x0d60adc5f879032f, 0xa594d6aecbaf9736, + 0x1bf486ac72542727, 0x9457e2c474c0695a, 0xb6427a0201c5c638, 0x8fb3c636bfa5b923, + 0x273b12889b0f39e5, 0x7d7bfcdeafa25cf5, 0x4b36ec8a73006ecb, 0x6132cf6c703d7580, + 0x19c5777695518a22, 0xffee3e21e6b4a0ad, 0x6a7870c1b0f0b8cc, 0x1e6ba492e63d0670, + 0xf46ef85d587fe708, 0x15fe18b56e4c6fa8, 0x2ed5bfba95894de9, 0x6af9cb3574c6bab0, + 0x43bd7c15fe15b065, 0xec2223819a1cfc13, 0x79c2f96447c8bbdd, 0x7931a49be0dd0bcc, + 0xa3a0c7ca0e5ccc0c, 0xab2b105ad13a8391, 0x565244297abe4c4e, 0xcbd09ff9b3cd3d2f, + 0xa750f1c48256041d, 0xffd6f2633bdc1448, 0xa10efbda94fa8afa, 0xa8aad983e48ae447, + 0x0d82b6442d0e1548, 0x2ece640b636c167a, 0x733d867aa721cbdc, 0xe003cf5e3a8798e0, + 0xd30896d8fc429f87, 0x39309fbf77bfb1c4, 0x26751cf478e45667, 0x66dc87a964e236f2, + 0xcbebca317c508f8d, 0x18e901268fe63a44, 0x99b51bbcff6315b6, 0x5c2517277008524e, + 0xa95a2dee52129a65, 0x69219caa898b34b1, 0x5a6dc81cd41157f2, 0xbf939234128ee31f, + 0xd06cf207b05ab7f3, 0xf4f60d74579613c8, 0x203182a119a9e526, 0x280c29473ec2da51, + 0xe869aedda9b6a5ea, 0x25ecd3ff423da68a, 0x6eb3718e8ab5bb82, 0x363bca98469f0068, + 0x9243fb703f70aa1c, 0xee7f87bf0c757a1a, 0x1ae471a5a5cb4379, 0x3efa6b1039bea9f6, + 0x6168ec831ad60b0e, 0xbe85d9203cf84b20, 0x4d6ea3677b78f4fb, 0x3906dce6b289b401, + 0x53842b626e854a5b, 0x69d93f4c6ad0e5dd, 0x071265768d63cecf, 0xa8390d8f06e355a1, + 0x2910bf70117fb7bc, 0xe76adf6121406162, 0x77c4b695bc1b3065, 0x8fc4e9bfb1f51822, + 0x3d141c6eaa68dbe6, 0x115213ec59ea2196, 0xf2fa9e26a52c9ca8, 0xf600d0a51df92483, + 0x0d395a559281c13a, 0xb45d9fd230857d1b, 0x14405a8b22d97873, 0x7cb5eac97bfbdf1a, + 0xad5da91dc4e32dc5, 0x6e214e456bee2bf7, 0xbe0b243dcc577c11, 0x059d031812907dd4, + 0x5d599b864e91c843, 0x99393c1d4eadfc4f, 0x293852f2a107ccc6, 0xbebd6bf03e8e99e8, + 0x222a5b46c6381218, 0xbfb9fb27d91b0178, 0xf810f449d77a6c97, 0x6594a2951257571c, + 0x5f86c179e62516b4, 0x8e48a62f34ca380b, 0x149077d9e47c6b07, 0xf9ef284bf1c657e2, + 0x3ccf8e1352839ce5, 0x9f0d5a1df00701b1, 0x6f26e54fe5824faf, 0x792da0de9275f232, + 0x3d32b968b445c3a3, 0xa927e99372923261, 0x0daad8741d4d6c0e, 0x5f8d00e5901ae972, + 0x492a438492fb034e, 0xc43c3fc1c583dd06, 0x56ade41c5fcdd732, 0x14cb33efba06863e, + 0x86c7ee1ad9db42f8, 0xeabbb93f5d15060a, 0xc5d1d11d33bec8bc, 0x671e6aa0a3a17b93, + 0x0db30e06053d6445, 0x091246a470107037, 0x66b310406988516a, 0x581f5b9a9418315a, + 0xcbb24ea3808f1863, 0xafe75a4a83b6d617, 0xc3c132b2b0b4ed25, 0x731247d53e5f57ce, + 0x228ee29f5bc51be7, 0x66e77aee4a2410a7, 0x9254c1b4f9a3f522, 0x6d417b09c5eed63c, + 0x3cf9277e25ab8ff4, 0x66a75ed5cc5fedc9, 0x292d395977873bea, 0xc74073eacdbfc346, + 0x3acef694411969e0, 0x2f55288792760230, 0x088e0f6459578f05, 0xe97720072ccd9a62, + 0x54d0b5264b9287d6, 0x993b4d9d5aafc437, 0xe0006e04113b3ee7, 0xcf50ccac329a48f6, + 0xac17389d6784a05a, 0xfe5a896d9696aa85, 0x2dca2a0a5089a151, 0xe28d29badbe727ae, + 0x556a462bb6d28d31, 0xd6fabed32e06edbf, 0x6e224f74f9eea43e, 0x52fa24c251f07fda, + 0x8c20bc0fbfc9b805, 0x6be9ac5728f4f9fd, 0x996a6bcd227701fc, 0xb10eb6eff56e04e5, + 0x482db2853cf6ffcc, 0x02dd5e5c1d5d7186, 0x4efd89f842627b97, 0xd2c8e4a1c8482724, + 0x8656bad25748fc43, 0x6e4cf755efb7633a, 0x801afad3b760bfb9, 0x068352987e9c10a5, + 0xad51fcc88e9db195, 0xcb4eb33e1f780e03, 0x3a64518af6488a6a, 0xe5a705b274325fd4, + 0xa9b12f8d2f2c7280, 0x5283d148a71a8dc6, 0xc747b8bf3154c53e, 0xeca849400d4c1bdf, + 0x328601757d57687b, 0xac4abdfc00693aff, 0x0209408a2c500dc8, 0xfa41265c53d8173e, + 0x9fb75e4a22e38677, 0xd3a559b66e7d61ec, 0xf8dc074c7e0e08b7, 0x200350b52f2bd6ef, + 0xfaa9877213a52229, 0xce77a2d78791fca8, 0xc78e9f6daa775bfc, 0xa08ce0a4eb935900, + 0x38d5d9b58698c909, 0xad7710b070bfd52c, 0x5c2dae5ab048acba, 0x91391b7704630003, + 0x9536712574789929, 0x1bef759fa113c332, 0xac7c2445df4d7f2a, 0xffa878d2fcfc9a5e, + 0xc8d7a709c11ab5f4, 0x8df7ef2a6db2b6fc, 0xea7e95becbe17eb6, 0x55f72f7799e23115, + 0x55d151e34a68c790, 0x2551ddc3f4444254, 0x7338172f7bdf3c65, 0x95c4a77798bcf593, + 0x5cf97bfbc3d6f2c7, 0x1f0cd1cd12915de3, 0xd516638f8cc27db2, 0x09d5b7be24b9ccc4, + 0xc5d8b280d979e177, 0x70dd07ecb190f616, 0xe76ba3c522ef4482, 0x357aa4fd6916cacb, + 0x53050fa6a32ee871, 0xf172ce8332dd0204, 0xd733a292e775fc21, 0x4b51c958dab75658, + 0x8996c7ae5e7352e8, 0x2db81c567e16f3e0, 0x8d7c5a26cac22c9a, 0xb98cb515ae16d486, + 0x4d34f494ab8ea6ad, 0x937c83862a023362, 0x7414fcf8574d7254, 0x4dd2182c280f90c5, + 0xc387952524a804ef, 0x76104ef75ab620d0, 0x988319647e7f084c, 0xe51fff124fa86f99, + 0x6ad763d4e42e75c5, 0x6e23f19379eb6040, 0x60b75a472d3e11d7, 0x18596587b023b235, + 0x1fc4d53128da27f2, 0x4b11b1f76fe97a2d, 0x6f257c9dbf970c2f, 0xaea2f5dcfbf2367b, + 0x1f3053998380d862, 0xd63aac0f03f2a1e9, 0x59a7d72da32cf025, 0x554c55ccc1a24c84, + 0x4e727eaa44ba7d9f, 0xcd758345521536a5, 0x69d1aced2477b337, 0x146938c83d6c2396, + 0xe8bfcefb5d732d25, 0x34fffecaf92eb30b, 0x8220f7d787d1b84a, 0xab38b08d772a57c0, + 0x40a859994765c098, 0x8f3f26ba662f79f4, 0x0037dcc078b2c32d, 0xd0b5a5e8f03668b4, + 0xcd6aa35798e5cce3, 0xdaa33745466b1636, 0x01a9aae54257039e, 0xbb72e38b8aab0f9e, + 0x3cdf21b0e37e66dc, 0xb965b6ce6f84cf7e, 0x28ae8f59d520c25b, 0xaab81d89bdb16d6c, + 0x6e96d6a1b5a96284, 0xee9ca4e9ed1fa05c, 0x8d4e4c2b631278e4, 0x203325fdb69b4e87, + 0x4c53296525ab130d, 0x9b4a1d24d55fd789, 0x755ce32b7c9aed6e, 0xc1a72061245c0f48, + 0xb7948605da7adbb9, 0x648963256efe7a0d, 0xa574c49e8da06f6a, 0x25b5c626c4d5da5e, + 0x606b165e226c65f3, 0x626112748099675b, 0x22a5d4315eb038a2, 0xb8ed494ab96dc793, + 0xc4799090539c7f43, 0xd93f13390b787819, 0xc547c1d7977662b6, 0xd603ff58f9b8db55, + 0x1cfacba4b2f3c831, 0xbd2669f54da6c106, 0xcb3cb9411efc75ea, 0x1e7f2ec7eebc7e1f, + 0x67b02deebbf183f0, 0x86579965f743b3c6, 0x8e2259a28d5228b5, 0xccbc6a98ab906574, + 0x9521b7eec6184d70, 0x4113c66bc8ab0ccf, 0x8d66ab3d13bbe880, 0xc3b7c0c8f36446fd, + 0x448a0444cb2585a4, 0x1e2b3c2e4c75d06d, 0x2a15f2c73c09e402, 0x8b0b1945162be9b5, + 0x5ff11045e3355859, 0x19114e5948c21560, 0xeada146fbadb091a, 0x6ce3c6e16c5fe265, + 0xf3827c766e951bc5, 0x1d1091738d6a55e0, 0x97f1ea6a17bec836, 0x4cd9420c9229c3ea, + 0xb22170e67978b0ca, 0x5be0c0088b8ca810, 0x0f15c9e4b6685984, 0x74cb033982ae2667, + 0x5c6c5a2d85065882, 0x7b109bb09655debf, 0x56bacc5bc5db2767, 0xef8babab6935664c, + 0x1eb15c0bee6c8b37, 0x258b0c1bf2b5bbb4, 0xd95ccad6fa92715d, 0x9577ee75b742cee6, + 0x81e2e6c555e2fbf5, 0x951928cf0d18f816, 0x6686c6e16aadf2f6, 0x7270cd96ddc8d3b9, + 0x47a17f2a6a722bb8, 0x668c0f727f83413c, 0x028cb35e0f176eb0, 0x7fbcfbb4b4d5e41e, + 0xb5d7a1255a097cc2, 0x37d956f36b107390, 0x87217dd542a6dc8d, 0x2d41a33b7127cfa7, + 0x55b72ce72ffa38da, 0x337dcaac4e15c6dd, 0x49bc3d7cba07b97e, 0x88005d9da7656738, + 0x947342869d8d029b, 0x91cbc8367e34f809, 0x55b8db39221e2249, 0x2bb38401062a3235, + 0xb902b2f07aa34f7e, 0xd8b72b22d939af67, 0x2a45efb3ce1f4904, 0x0e96f91aa6a83508, + 0xc17d7fbb5d3f7e75, 0x24c926a9673b6433, 0x7f79fce7c4bfbd36, 0x61c40b11b705af07, + 0x6c938680b55032ad, 0x2592aa14ecce2357, 0x8d1328c0ad3d6c40, 0xbde590cec54c5bed, + 0xa53436b02b65a3b3, 0x984341eba2b81eb9, 0x76330da141c01f06, 0xf5da3bf1e7a5d161, + 0xbec5455b891f80ad, 0x7f1db5bb91c87745, 0x88cd3e7ab50f7d0e, 0x052b1991b79493ad, + 0xb9af59f2da249721, 0x97dd819304dd04c9, 0x51731eae5f755b36, 0xcad7db0033ea4a8e, + 0xd43d57f2ff724f21, 0x2ef70267d48f4c99, 0x80061ea7d7e473ca, 0xbc828327fc5c8f43, + 0xc6dc39660ef1610b, 0x2f06ed5f218ce49d, 0x855ca0d286723c56, 0x1fc15a495254af05, + 0x408d0964e363a528, 0xc9dfcdd5e57692e4, 0xf39897882de50c1c, 0xb9d27aca194ba134, + 0x5e7c667e7890cd9a, 0xf3efa39b825dc8d9, 0x3982e744260a5bfa, 0xea9a954644a2c3a2, + 0x79c9828626cbb23b, 0x89afbe946ec766f5, 0xf3c829aaeaba4732, 0x7bc93a3f35dcd86e, + 0x3a6b34a97cebc1aa, 0xba1f3c317bd99cbb, 0xcd6afba53d872970, 0x994f1023afb18744, + 0x24aa8402756b8ef4, 0x15537dd5dfd090e1, 0xd715a49071f00b2f, 0xdb83972a7c93542f, + 0xe36a9ef7516f82d4, 0x6296323fad0ec190, 0xcc41210f982f19be, 0x878e1df888833969, + 0xb8740bdc558f456b, 0x378da7088ce5e194, 0xaba48f7959e0d795, 0x14e27c831d3c00f6, + 0x9a723a12eb96e7a7, 0xf162f30e5a4eafc0, 0x0420a802f463f507, 0x395b4998de937a15, + 0x915ab99eaa1d64ba, 0x8e51d6cdc5f08500, 0x66fac167407acd4a, 0xd446f72d250cf47c, + 0xf8e996c937040556, 0x965ab458322fdcb2, 0x4a21d0a2b9411d1d, 0x20dc3a017e6b3e61, + 0x143a57f20804d010, 0x0d18f09a537888a1, 0x085914296f7ceef0, 0x2bd03eec6509d5f1, + 0xf7e46db26c867fad, 0xba1bb8847942a78f, 0x8ecd8e94d93474c8, 0x4fc2a6483f3c69a4, + 0xfacf50ae1b9cbe8d, 0x50e7adb3c10ce9c9, 0x301342529c99245f, 0xd7fccd9353dddfab, + 0xbf8ec2995d1782ba, 0xf50851db7123d0cc, 0x01cedc0aef339df5, 0xf449ecb0bbd52e30, + 0x2b64ad7c106c1dc5, 0x5b8f9311b3c37f99, 0x5dfc3b21d5cc618d, 0xf8bba7582be99cec, + 0xfea5b1d70088a207, 0xbf4387daffdda71f, 0xbe642814a59c852d, 0xa800adcc819b4f63, + 0x50c85746c7972d31, 0xcf62ea5252aa76f6, 0x893752345030149e, 0x4004881dcde9db6b, + 0x17bd165759cd9722, 0x72f5b515d47d4854, 0xfc42f097c47cad49, 0x7c10782c3481ef1d, + 0xfb8a78bbd857ed49, 0x6f376d8eec792bf8, 0xb4c1ac43e5b7c22d, 0x74d79b2e4a21f15c, + 0xb3c3e8d0a3f371fc, 0x19c70d69cddb3cb7, 0x6180731a9612db16, 0x2df588dab10fc8ca, + 0xae6532cd45781c2e, 0xd7d9a97e37075155, 0x43537b879c9882e2, 0x3f553455fcae8e4e, + 0x6451b39af00fd9ad, 0x7c6459da8da3152b, 0x85bc5561ed572d02, 0x3d643ebfe8e98079, + 0x66a7ff664ae39ef7, 0x7827c861a062334a, 0xbf6ac96466c0e1e8, 0x9333ca5f77cfbaf9, + 0xa6a8a0f7ddbfc9d6, 0x15651954bb81f270, 0x47147d111e836534, 0x8beacc5102a8636a, + 0xa4e8cb060f2ae617, 0x4237cf2711441880, 0xe0022904e9057f4b, 0x63ddb809a138b8ff, + 0xa2da3cfb4619c2c2, 0xd81dd11b63a7aa8e, 0xe5540f596069dfdd, 0xe8c65ed2bd24ea43, + 0x4ca8233f2368ac44, 0x52df9e9f4beed4d8, 0x1b608e948d7c75fc, 0xc99967ae4af26f8a, + 0x20f0a795b48eeb13, 0x74b4f7593b3e3a1b, 0xeb5315ab19b99e9a, 0xdad283cea201f472, + 0xad9102d4dd92d388, 0x50837cea9b218186, 0xc92dd8107da087e2, 0xf2afb2cfbcd2f884, + 0xb0eb202c890e2ea7, 0x68a8cfc2567c0c4a, 0xed78716c901616a1, 0x749353579283fc04, + 0x01eeae3c5730eb52, 0x16946d4d52ddc894, 0x32bca2dd63be576a, 0xfad6c15e6733d3a3, + 0x21386bd7228ee954, 0x0a577a44c8bc48c6, 0xb0aea714f6825855, 0x3dfd69500ebf69b9, + 0x93a4d7ddff220417, 0x6c394468d5c8df40, 0xb8c18e05d3a98655, 0x2886d5b932afdcb0, + 0x6dbbb721582bf13d, 0x99f3666a10acc9ee, 0xd02f80f5954d97d3, 0x00bef487eaa9aa1b, + 0x0b9d42dea35c8e77, 0x7e29d2d65fd7a78b, 0xddbfeaa5b7d3b144, 0x8da38cf3ed0164e3, + 0x530f5569d641f597, 0x8ff59ac675ac19fb, 0x9468047a51b3c4e5, 0x05ec9ae8bd1c0971, + 0xa8a4ebbb7c57eb9b, 0x922ab899c9e92da3, 0x3bc812008c6e7f09, 0xaefce01fa66062ef, + 0xc6da99e1b7f68c7e, 0xea8f0657b7158777, 0xe3b9ff40f58fc677, 0x6f7eb115bb419fb0, + 0x8acbe7780818721c, 0x9589e01afbcd168d, 0xaeb54fc322878191, 0xfc22adf19237d5c3, + 0x5de940bc2dfb41ea, 0x37308ec12997a976, 0x26dc7ab698781c97, 0xff1e1e39167c4c79, + 0xaa13fe6ceb679607, 0x33ffdd57fff3d635, 0xc5c065b004e3e81b, 0x90076e37cfbb3b27, + 0x7bb5d81f2aeb1ece, 0xf8c80e617de6d08c, 0x4df7e54424ab5191, 0xa1c818c14756c25c, + 0xe16943c1ead721cf, 0xb1e15bcda65aa4e7, 0x5223d58f8d9286c2, 0xc8824a19895b029c, + 0x924aa58f1122dcd8, 0xdc66f927110fa933, 0x2da5fbba7ea356fe, 0x5b5d6d52aec9e5d9, + 0xbafd2dac6df100df, 0x9ffa8e11519ac74a, 0x7a8fcd20fd86090e, 0x014e3c549a8bd7da, + 0xf936d1140a10ed26, 0xd25cbe0ade57fb93, 0xd01c7f8e9d52047c, 0xdb72e278bc88c9eb, + 0x6de3b137d58228a3, 0x8932f53a1a18063c, 0x174a67defe216e60, 0xbd29536ee3cc9b16, + 0xae5ab163f66151d5, 0xe6e44d1aad038562, 0x2037e479e9acb15b, 0xcdf3c5ef6a714e19, + 0xa73e5d5f650ad914, 0xe0f6af922aa502f4, 0x0a6dfbd7222bee59, 0x5505ea6fdb4105f8, + 0x476c5c4875358769, 0x35ad6f007244ab4b, 0xf0b58cbaa43984a3, 0x4b43f4118ae22902, + 0x889f1f2554440066, 0x5f40b4173e0db3c3, 0x99b239b7253ab36f, 0x5ee1c0b2bfe1168a, + 0x04e4ccb360e270ef, 0x6e154346cd1e1d95, 0x71189b05bfcf95cc, 0xb82cb59ec38400ff, + 0xe80de52b0da51cbb, 0x2fb8274a266307d7, 0x221c4c5f77531d89, 0xbdb1bd58a5a5ffc0, + 0xfd1d2fdb9d695dc2, 0x378764a220131abd, 0x8180ed4fddd87ad7, 0xfd225366cc3f6418, + 0xbbe49008706e0fc6, 0x8f33da0ff8eaf6fc, 0xce22d2bc75082c2b, 0x86531526c62eb6f5, + 0xcbcc76bf847eb1a2, 0xeee60924fdbce5d5, 0x65fc3e82a509e88b, 0xf4979eab3658bf42, + 0x2af994c859b7fd99, 0xdbb892dbf9373baa, 0x57979a42491cf1a3, 0xb48aa89de6651963, + 0xf11c0f9fa424238e, 0x97f8e205ef06c082, 0xf2a118fa1367e5b6, 0x1ef41dec2f857eaa, + 0xe1eed5042b8f337f, 0xaea45849643da220, 0x35746d201a2764f4, 0x5cc21b8b28008b76, + 0xe1ebfb9bd0cc9ede, 0x10f165081eedae57, 0xb0a71a8c90256317, 0x4666c1cd4ac2898e, + 0x68bf3a48ffecb3d4, 0x3317507434db3003, 0x61ba7ebdf94b518d, 0x41a518093ed93fcc, + 0x1f0539464db2b670, 0xa3312a11e34177ea, 0x4153b75f5e2bd449, 0x0c93aafc1497a9c9, + 0xfe64520bef8b6c1a, 0x2ef3b69dc1b950eb, 0xc50bcff31323c55d, 0x137b9df0a41bb83c, + 0xf8e4e98d30582e1e, 0xb5ae72f9f43be8ca, 0xbdf3f8e1a74335ef, 0xc87d092b772b41c0, + 0x4cb852a1e3f5b5c6, 0xc7d7b951e854d86a, 0xb0411ebe46765c16, 0x568eda2c24758408, + 0x9f8908e6198d5652, 0xd468571e05276c24, 0xbac62185cb3b365d, 0xc7fca94dfa7403d7, + 0x7ac4208ffe930e32, 0xea6097ad7725dc7e, 0xa237def29953e68f, 0x2a0f537b4b4af124, + 0x1f83cf7028ea592b, 0xbd9a9e944cfbd5be, 0x4ba1867f6cba1f75, 0xfb78ad72b0219be3, + 0xd15e52aae258e86b, 0x1045e5d48cca55c5, 0xe13a7dbad01a7cbf, 0x82f199510e27c08a, + 0x5edb7aa78eed597e, 0xf01a1d727e07a609, 0xbf012b768ce03f91, 0x96f65507238cfad5, + 0x8af234918d123905, 0x57917e837e8cd0f7, 0x6288c4124f07bfaa, 0x5c2b52d1ac020b07, + 0xede50a7eb7ad4e0d, 0x7306494f6df89616, 0x1ffac5c14a635424, 0x40d92e3c4f9e7253, + 0x965447ba3f573fc6, 0x99ac297b70f9d72b, 0xf0e20f2b03170156, 0x0c801f40cc1df451, + 0xbd5bafdc652de461, 0xb099ae2dbaf93d9a, 0xab24028e1b8172b0, 0xd7ef34c5340db7b7, + 0xfd5ed5a0549f7d09, 0x05cfb5d7621950f5, 0xbd9d9de82b5656d2, 0x952e13c8559173eb, + 0xae66eb2052370a9d, 0xe871c6fcc9a75f32, 0x23fa6877d29b6221, 0xae2cef849717be34, + 0xbe9dad289da5e2d0, 0x8d3f46860877fac0, 0x136e6d4ace20c93f, 0x5b0d9e220f209e99, + 0x0c0eb9608d75e9b6, 0x30fa13e5b070252e, 0x87d13223efccc859, 0xd71a27c23cc63c85, + 0x4b5b83c6871f5cfa, 0x74f73383a108dd5a, 0x1ca54d5d2f768044, 0x1f8fbacc27067794, + 0xd642d2f8356c7a49, 0x9e6689b2ef3802f1, 0x85e616cbe8c19dea, 0x8b489aa9dc687936, + 0xdc0715eafd33ab71, 0x53d2ca40ea4a728f, 0x9ee351b1217ae867, 0x00eaa589c55c056f, + 0x4397eba9f5e52757, 0x3547cbfb489e393b, 0x9b824502e15c3449, 0x0d5639d3e43cbcb9, + 0x9ea36df677ecf972, 0xed10fc839cac702e, 0x134228dd9bdab488, 0xc0e4458c71785f32, + 0xe10d06f73d07ff19, 0xfabf3352891381e0, 0x84d3fd91e1331f1f, 0x4e3b838d0bc45076, + 0x812b0f10637c7483, 0xea53484dc3b88ebf, 0xea69d601cb027ccb, 0xb49a40c94f1de4d2, + 0x2e9e687201084bb2, 0x3a5dd49aefd6427e, 0xe6404dd01c3aeeaa, 0x0d62e010d2788934, + 0xf9670006c5e67689, 0xcdf6ca7209300d95, 0x494196c2f168b56c, 0xec9145c61b32a618, + 0xdd75c5986799aeff, 0xad348129b9ffba03, 0x6d9f0a815c90a142, 0x9077173b158b6145, + 0x7c208588f257f28b, 0xd97337ac54508243, 0x4d757e4b9a316189, 0x20578fa448c1f64a, + 0x603c38468d73d4bb, 0x6e3d2c01600e8143, 0xf22ad145b1a6366c, 0xaaccbccc2d34fd7b, + 0x84a6b01db9a3bf93, 0x23e8cd1d659f2137, 0x5f684d4e486810bd, 0x0991db2ea3c08827, + 0x02fac0c908599741, 0xae9043198fbf88a8, 0x4b38052c0ee8eb27, 0x5ee085336ca7b73c, + 0x934c785c648c9306, 0x0d8ffe812c23de8a, 0x8e7ae5bf93b0a735, 0xdeaa1dd1945ab6f4, + 0x2357f2ff8be97053, 0x7fe6c7392febe11d, 0x089d5fa95b2519f3, 0x8c6ee97646323f24, + 0xad6b7ed099b311db, 0x38431c703502c400, 0x6e11cbc2f4e4270d, 0x8263bfb1dafeb41a, + 0xad7097c0cbcb7b42, 0xd6fcbea1016b0d14, 0x2be2f83ddd35cb17, 0xa85a65cfa7e8f192, + 0xa6bc82bf4a403279, 0x34952e64df73c0bc, 0xec0493fef156ef40, 0x8332cc58646fe8fd, + 0xad9ed5b9436010d6, 0x8af139efb2484d89, 0x24fdf989b7e2a8f7, 0xaefcb67beb38aab4, + 0x71e1ad9080d3dc45, 0x6e33032124026a46, 0xd6cc72ca6003d27e, 0x8c32cdaacb2e6281, + 0x4b2e1e5ae4305092, 0x4dbac277fa4bc906, 0x3d0b60b3d5f23f6b, 0x3e9b4ea5bd200fe9, + 0x9c7b5c3cd2aa2828, 0x0ef020eb51bfa9fa, 0xc6700679a120f2a4, 0x7b8df6e053728241, + 0x7ade720fcf2ddba1, 0xb12102b57d2aa2d2, 0x2e6d676006d4b171, 0xef1fe437ca6b8caa, + 0x6666700703ff9641, 0x8fe91eb2585c9c9d, 0x46933ca24b693444, 0x69519edeedea3b3e, + 0x159b1789ff0cffb7, 0xa1232c8260a26fc4, 0x44b5f96671c1dcdf, 0x5cdb823b21875cce, + 0xb208c8cd7f6cbb39, 0x0ae5c6a881afce06, 0x3a341dfd3f7b669e, 0x40f9281816036d8d, + 0xe4b70ddf94a68a37, 0xf5fd85195b1b2f97, 0x024a921bd04eed31, 0x6bf328ee0efadd1b, + 0xb9e19213a20c1fae, 0x7e1879d7b06d2086, 0x38f7ac6ac026e465, 0x59b72a5f13c192f8, + 0x833b4daa85eec5d1, 0x3648b527328425da, 0x33cd4c074d3e95f5, 0x21b4f87fb462d872, + 0x5a962facadccf050, 0xc60fa211e753dcda, 0xe9e673c033892942, 0x7303aa9b19e6608a, + 0xc73d98e2230bd6cf, 0x68231928d2abade9, 0x1427a7dbcc2ee787, 0x9e9e41797e8c613c, + 0x9715d1d10cfa7cd2, 0x7960165a64a60a61, 0xcdf740436a708000, 0x70e3f0e9994e744a, + 0x5816aeb7c3ecdaed, 0x9d8915ff37fc4a96, 0x4cb51143803b0a93, 0x7a0adcc16f9b1beb, + 0x422062b638359f16, 0x344bc6c4e290073c, 0xeda0cc0c24fdbb34, 0x3a9c81462b59ceb2, + 0xbd82308bf76a1cd9, 0x74c452c2f029d410, 0xbb9dc5f4e7ada533, 0x63dff9d3e5693396, + 0x58c88044a48038b2, 0x9900478c78615eba, 0xfde9b14287390053, 0x82d22f6b5d9c9bf0, + 0x0f41023071a2e1ba, 0xf3bf6dc000b70e71, 0x74547dbfc56609b0, 0x4410714add5110eb, + 0xfae57be8fbc5d666, 0x21b066345b096623, 0xa0188239d8a0f016, 0x7568d7e32b286fc1, + 0x3612f13ce609212f, 0x9137d545ca6e2fc5, 0x8fa6748e2d703dc6, 0x1dcc4f600f50b63d, + 0x434b32baca4b9484, 0xbed9c6df88b107a7, 0xa238542a67605cd9, 0x42d499c67535490d, + 0xbed7c65ab167feb9, 0x0e2d9b421a200965, 0x18ea4b9e911e4142, 0x58d20e2293e56bc5, + 0x275db3d28c78265e, 0x06ee512cba71d0f4, 0x9688deb9e97c2294, 0xb97cdb8d1b81e956, + 0x67533d6e3deb86d8, 0x0524878a81ed676b, 0x7062d73f7e8ee778, 0x6a053b1361985336, + 0x4ad3280659f49a98, 0xe1f40dda848afe59, 0xcd569106951cf523, 0xa5718b489c89b788, + 0x94ff359b11447e7b, 0x4a5ad3ab9fbae86f, 0xfa5bd91dc159103a, 0x2b2fe43aace7f9da, + 0x5514a060df98226c, 0x0ee7482c6b7cd226, 0x5b12ad7f4a36e091, 0x6d763d570c7a3d16, + 0x80ac0f088c0325f2, 0x92ba5f82b6ade82b, 0xf3917866c2ef6a0b, 0xcea7882f6cfadd58, + 0x3bbe413305e214b9, 0xad9f1a3fd51eec00, 0xbb66d0285f8a4e93, 0x29ee68ed090df847, + 0x6dfc631ccc8e10f4, 0x7639d254615bceb7, 0xe5c388004e58239f, 0x863bfe9b5f7d3898, + 0x1e724a8ba7bb7b59, 0x9c721ed7711f4b62, 0xc9535c044a2f9353, 0xa396cfdeedfc4143, + 0x30b4f246a536fd7d, 0xf350cf5ad26720e8, 0x9a43e38f265b3210, 0x9d33aeab3cd6950d, + 0xec95778e77b20800, 0x46dd1ebf2a696aee, 0x7e74a3c113d7f40e, 0x9a4a291cf13ea136, + 0x735aa38987dbf7d2, 0x0b5a69ed9980680c, 0xe27cf6e9b5288bc3, 0x505b1d074b66a583, + 0x13d0040502eb80ce, 0xfb17e5b2fdffbccd, 0xc30ca9574989c0c3, 0x10bf726e578c21fb, + 0xc668acc2ee45fdc4, 0x7cdf5587f0143433, 0x48a17f1c3ef78e1a, 0xcbb1dd26a47d624f, + 0xda31856fcb739d6c, 0x8d591f5a29646617, 0x21c8c466f12845b9, 0xb593ecf8d16f8adc, + 0xba909c56dabc7af9, 0xe966e5a47abde7a2, 0xf731925114fa06e0, 0x6a14a4d6b46e3c0e, + 0x88ce236a2599f99d, 0xad9a2d3df024558b, 0x40d6179c58ca29bf, 0x4b0932da0dd79185, + 0xd8f6ec18852f5a03, 0xa16c134263b8f026, 0x5d91f18c5e0a5162, 0xe38cf0c0336aa0dd, + 0xf6bfc0a4857be21c, 0x0fd63faef86280e6, 0x93d381e9d184fbc2, 0xb2667fdc4f709422, + 0x89df29085ca1ba5b, 0x0bbf611999981c79, 0x356ed9536ef97eac, 0xd967c57787227b3d, + 0x149abe628f7fe7dd, 0xee992b9d12a4172d, 0x0c5f17bc3dce1223, 0x9f70f68a68b92fa2, + 0x2903b10ffe33fc51, 0xa8ecf8ea96093e6f, 0x9190bb471b454c77, 0x8d1d35335edccce9, + 0xb899815177efe522, 0xd45d27cf8128c439, 0xe79629cbdd6010b3, 0xba52ba65a52e4eb3, + 0x26ed87e226c9fb22, 0xdbe0db4bbd7519a5, 0x120eca287dee888d, 0xd2f7fc69830e0a60, + 0xfb4dfcfa77057d31, 0x8215b70677827952, 0x06bb138db0cfe875, 0x056268c0e706ee90, + 0xefac511a4f798498, 0x945d8cd21628b345, 0xc1c069f8685affe4, 0x512e6a44a73706b5, + 0x59cdd380757b532b, 0x562699032d619472, 0x4d55692214f22193, 0xb70f0af2ef39a86f, + 0x19822b3ef7cd1b8b, 0x87454fcd5ed8d1a8, 0x80d6b306505941e3, 0x437b678d1a8c14c0, + 0x3931b1d8a7904c06, 0x7d8eb32de4e18644, 0x6eebe9166c3000c3, 0x2d65c42904528a44, + 0xffb63149f3af2acf, 0xa799a35c59525162, 0xbdd8b1ece3a34828, 0xa4d72877704b1477, + 0x3f1344ca5311ed96, 0xe75df7afb57a747a, 0x186833ac2da1d112, 0x1e8029bdaa8cfa85, + 0x8fe6ecf4e4b06cbe, 0xb42eca36d6586a20, 0xc5f7cad8441e1b74, 0x4eee86f5eab8d53e, + 0x946fe279bc9bf63f, 0x90856bf5a1e9969e, 0x6dc098e4b03cec48, 0xf84d203b36ae5fc0, + 0xba31832016f094bc, 0x5c729b422dbb0659, 0x877e3e457e6eddd0, 0xd2a188ffd5153ff5, + 0x4e96bd6737eceaca, 0x6b4bdd29ea50144d, 0xccb766eef0541baa, 0x76e156bf39152cad, + 0xbc434b89559cc4a5, 0x825e9a3fd791535d, 0xdc8f26c7ea6567df, 0x9af7a54a7c039c8a, + 0x306f0dc701253fdf, 0xfbc8b0199055a8c1, 0xb1707d865415160f, 0xb11a95123f3c9a42, + 0x2e44ef9663591598, 0x1e1084a35a63e375, 0xee388b73b265a7b1, 0x23918627e715d581, + 0x07f4ad1f562237fb, 0x1a7e603f47e9de7f, 0x34100cb488cec8e8, 0x14992b0b9851e44c, + 0xd61cc16d8d3b1db6, 0x1dd8d2be1c65fde1, 0x1db08942bdf50541, 0xb75500f5335eb49d, + 0xfecd8765d392c105, 0x6c563d8b0abb13a5, 0x120eeada2764bd89, 0x91872c22a548436e, + 0x56e12938f16e7dce, 0xf13c7ef4929060ba, 0xd7172a3b90e0f85e, 0xa617c41f39e63509, + 0x287c5dc005087a09, 0xeacd597984c56f35, 0x4ed7886dad9c575c, 0x31aa01a94964900a, + 0x2f7bf1056e6c19ad, 0xaba4d401ed742250, 0x905cf49670844e54, 0x617becba85fc7c70, + 0xdfc98e481a34de4c, 0xafcd5e00cfd6d0d9, 0xf4cf2023fe4d3101, 0x9fdfc9ab3294d05d, + 0x6ca764d5908ff10e, 0x59b50dad3cd67c34, 0x4f13da29fed25d90, 0xdf6c93d97a1aa2d2, + 0xbc29df97a920e4ed, 0x08d0ee19d5376900, 0x2f6b88fe55c5acea, 0x8a08cab54c4718e2, + 0xed7e1ab21899dc6c, 0x872acd7cbe9da8dd, 0xb3fc05cd5b6239ac, 0x4a524c829e8b23ea, + 0xed311acc11e08933, 0xb0f16d23a74fe645, 0x980e444b682a9845, 0xb95f4095519c3fe2, + 0xf111b31a1797605a, 0xcc2bfe99ee65a4ad, 0x03b53f9089864673, 0x1f2bceb8115f0458, + 0x4e670e0c7f4d2d1a, 0x1cfad714abab0391, 0x2d677e826d1ebd00, 0xf840c088d8ef282c, + 0xfb0c3c0e9769fd5a, 0x201b6dfe79d1ee44, 0xd8f9f10c925b7ee5, 0x83228c30a0856857, + 0xe35a8122e51098b4, 0xfc140ab95b2604bc, 0x82e8faa5e23d1010, 0x0760654ee3570bcd, + 0x22f7d6e10b111fd7, 0xe849a767a5a3cd5e, 0xf46158fcba11c40b, 0xfbbd38059171926a, + 0x3ecf7588d4238dc2, 0x447b2fd50683cf2b, 0x52e4afd72a9f8f33, 0xb212a4902a93b17f, + 0x4c7a70627fec40cb, 0xdb2b1fbbeee580d9, 0x6228b281eec43834, 0x88845030c4d62857, + 0x087142235b2ceb9d, 0xd0506be613196d48, 0x872ba6e4502cdc85, 0xb6a2962ac13ac070, + 0xcccd77a783ae13a1, 0x3239ab4fd8df11a9, 0x3b1a873b8b26d62f, 0x3576b85fb65c83c5, + 0xf8abc5cd0c082b33, 0xa980c105bb5299d8, 0xcf0cd05aff348fea, 0xaf526ddf5ec270ee, + 0xa4cead7465e20916, 0xbc637b01ead98c50, 0xbac9cbdc4c482b35, 0x39dddd1b3988635a, + 0xad3876744b0ea9a1, 0x83bf558eca06888c, 0xef2e72d65b9ce4ba, 0x419b75f71e947881, + 0x08874f0049fb581c, 0xd65a8e40701e3ac5, 0x57aacb192b4002af, 0xea3ac58fbbb9ed30, + 0xda5e297cc254896b, 0xe90ae3f457c395ce, 0x0df4f2c5b3d4b9b7, 0xd5c350b298f21b11, + 0x22ddba3fe4701a1e, 0x5a7bf3c7b6cb444c, 0xbfc160dc45d38eb1, 0x52929b4348d726c7, + 0xf37d6d1f0cf0ab25, 0x821d3f162035f8b5, 0xcd1c396a30578748, 0xcdebae816ff01552, + 0xb19b6f7e3cba80d2, 0xba82705fab694f1b, 0xd7797d62f7df8249, 0x8ed4a406c4785f8c, + 0x4e14379aedaf8243, 0xfb257acddd3d523f, 0x7f70354b662cba01, 0xee5d70f638ed8382, + 0x0bb7591922631fc9, 0x871e89090fda1ef0, 0x34cc11bc4df9203c, 0x0609cd069806ba74, + 0x907484be16d75f4e, 0x22dce1b9c0288aac, 0xff7464dcbea5cb6b, 0x326ba60336161e63, + 0xc64da7370fd95088, 0xc8737effa3264203, 0x8698c6b9f4f99cf2, 0xfd6ebe008b3ccf8e, + 0x5e536d093cb845f9, 0xb4368342b45da646, 0xf8159613936d64e7, 0xf7f14e83b5e3e6e2, + 0x9e51f76ac4be0d7e, 0x527ca003cafef960, 0x39a6790b7ae53b0c, 0x8dbfeb13365e9637, + 0xc8595b330d552033, 0xc98c4f63bf04ad42, 0xde3b0ac250098871, 0xd5a0f86c5ab092c1, + 0xcd7b9fdd1a1655d1, 0xfd2f6c0d722db96d, 0x0afdd5f171b67772, 0x691c1873ce370856, + 0x9597215d545d8697, 0x454910c21bf1561b, 0xfb75a0a5164a5ea7, 0x21f28799dd9a8b10, + 0x2d0c36bd60ee44dc, 0xd3eb3d1e0ddb837d, 0x25a599c2eb8b22e2, 0xe6d8a5030cc1f15c, + 0xabb88ca189f02f72, 0x7d48376cbed985a8, 0xfd16679909a7900a, 0x29678d861be670bd, + 0x251ba1e01a47e8b3, 0x27cd303bc25f6210, 0x377288ece6dfa687, 0xd0a78cf4b48da76d, + 0x6140135d3c46b1a4, 0x959aeef6bbfd2687, 0x00c23da7c036ac33, 0xd87049989ff2a05a, + 0xd484146ed334d5cc, 0xf9aa593bdf9e8e33, 0xf8b35acde11d27a4, 0xbe5a247a6479c46e, + 0x1d7a9b2a0ef2d588, 0x13123b10dcbb133b, 0x5a93f7cea88bb29c, 0x0ad93302ef02e498, + 0x95ede844de9db014, 0xad8b7e46715c06ae, 0x873b8aa7983cdd71, 0x3d8469afde978a58, + 0x16a715d99083fb20, 0xd81fd4dbfb5345ac, 0x157a3d58119df0fb, 0x0070be0f86a6d6c4, + 0xb3a4b324ee87c381, 0xb4701afc5a2e1800, 0x8e4fa12ea1327071, 0x7bc9e55f46be6feb, + 0x9b7fba62714509da, 0xabf96fe3c4f94389, 0x2434bf57e0923c13, 0xf039814c7b5fbbc0, + 0xf62948f9d12de500, 0xe27a9c61ff29c363, 0x4c158bd0282ffcaa, 0xf005469c290be1a7, + 0x713255c977a11599, 0x3371a889ef8b93dc, 0x246ce79e9f5f9749, 0x256df3e3f93e4174, + 0x40570986a175394e, 0xbeb3184ca60427e3, 0x46eece3a96893bfe, 0x8319c48c5ae02fec, + 0x7e2f43ee60890de1, 0x680bade6e38e15f4, 0xc8bb01f781a549b4, 0x59d75a2f91ef9639, + 0xb6208cf32a5f5c2a, 0xbad59f75e07e26ec, 0xd8c040a0ca9f913a, 0xd96b1c39084540ba, + 0x49012aafafb0749a, 0x8316954f99465a40, 0xcc4616b7727811a7, 0x27d9ae5ba5aec630, + 0x62d7b918ab412f03, 0x01a999661c887da1, 0x182564ffc63dbb91, 0x8d220637d3c436a9, + 0x85de11d68f30f5af, 0xe8c3e2c18bca1e89, 0x5f2f253f2acfe2ee, 0x94a9f4cfb8f79236, + 0x06bdbe4b8a6caf87, 0x4d160a65b7ccaad0, 0x226ce5ada73f7c50, 0x0e327927e201e6c2, + 0x03478649d0dff484, 0x11294335e800e7a0, 0x591b89f8b03cfa8e, 0xb4c68c23eceb52d1, + 0x647c7ce1da2788c1, 0x913cb47d1ecf5d86, 0xef3e13a2f80e779d, 0x564ce4592ced1cd2, + 0x9b5e8d79a9b2769f, 0xab18d22e35694aed, 0x3f99bad99192d8c2, 0x0d12d6ba73754d2a, + 0x89c06bdb767233b0, 0x64faca09ef9f9792, 0x9e4d4787c52968d6, 0xadebff40c7245fd9, + 0x33a2430318f35c43, 0x9cc8b34cfc9b18ef, 0x64f66e7bfc30492c, 0x7c7c1c9533a95733, + 0x7ca0283d6019227e, 0x41e804495a7a30a2, 0xef8900296ab2c56a, 0x9be1a18369abfe69, + 0xc141427e8065408d, 0x8ba938d17cb402ff, 0x8a730af8ea1a8d52, 0xbfbbb67cbfd25bad, + 0xa23d505fc7d538c5, 0x0f05a46b6fdf1548, 0x89991b74878d21c4, 0x92fe6a0d6efdb62f, + 0x52378e523d38481b, 0x621da85e57e0771b, 0xaf5017b1fbe3acb8, 0x63dbab1dd3bafbc9, + 0x02f26a18db45556d, 0x112bca10cb100927, 0xe3910e1321b14eff, 0x7e2e657408cc6d45, + 0x5adbc1bf88ebef9e, 0xbccedc4a955706b9, 0x18350d8f6ef3653f, 0x0021550d0b29abee, + 0x8de975b8b953ab6a, 0x8b37133f46c0ee73, 0xeedcf73332c92ddc, 0x29ff849ec9632497, + 0x7c399ef612b95b16, 0x3d37cb300302f0d9, 0x0a3d8d316e6da2d8, 0x80cff5e89a293584, + 0x1b65ad23d2905210, 0x39e574471588b3b5, 0x0f2b362f319677a9, 0x7e33fda99fed03bc, + 0x91209738fba939f5, 0x332ec2936a144f15, 0x6b8aae9928f7d164, 0x186310cab5a6ce88, + 0xa02353b054cfc664, 0xfb90b6168c8a553e, 0x7783772e52f7bed6, 0x1ca6b1d2d93fd27c, + 0x2919c3c85d108c07, 0xe50d434dece73c49, 0xa67492acea15d718, 0x7d7f9e709625c657, + 0x3d92c6863fd40be4, 0xdfc59bc210e0e430, 0x4e76c24ed1d234cd, 0x49cbb6d2ea0f33f8, + 0xbcdf8d9a5e042e86, 0xd14e6f875815b512, 0xbf5e2074e8aeec02, 0x9e02a20e5131b05f, + 0x360ad4df7af6f624, 0xa93dd841e726c1e0, 0x76de1c577c038586, 0x9185f1fe9589a03f, + 0x392bc110b8dce0a7, 0x058d1b660f84067f, 0x6b85f1db5877d118, 0x4ff8a4af2c16aae3, + 0x7b4bb03622f7310a, 0x0a04cb78d9d7533f, 0xb7025901a6c083ac, 0x0b09966aefb3cb40, + 0xd0e69307f85e5c3a, 0x84e56a2ad975f315, 0x8a0e30ae3683730c, 0x398d1481c8f77458, + 0xd168765a21f564e7, 0xa6c0cda290d3a7de, 0xdaaea91538af2b40, 0x58a9d0e6ebeccce4, + 0x2c98c34b8707e751, 0xcb705de2df843d4b, 0x6abcb4977bd679cc, 0x66eae07f7ca3eb7e, + 0x0198d015228079ed, 0x1f5af0dcab0a961d, 0x11171b4bd9ea0411, 0x07509e5a234f7ca1, + 0xc6da9747a5e44c1d, 0xef58d859cb214cdf, 0x5e27bc81c39da0f0, 0x510ecaf8e6923bd4, + 0xf6d24bc7952b0266, 0xcb616d5c4ccaee5e, 0x964d0f42ab767e42, 0x6426a976385cfa3b, + 0x48c52b3e35b2a6ab, 0x7a83ce3559e8de74, 0x3a49a3a6807ec94e, 0x58b9b654692327e6, + 0xe5feac449fb7d844, 0xad68b5d2ab072006, 0xc6828f6826ca0097, 0x1088bcf33bd145d9, + 0xf7b02d61cb8d6e4c, 0xb6f8ccf41fc5a80f, 0x1db28e40b480db66, 0x80726481766d44d5, + 0x49caba6f8edd2328, 0xaa5e72ff6eb5a5cf, 0x89555ec7aea4890d, 0xa1d57437d7b99790, + 0x1f3d0083172c3dfa, 0xcf66d1c8b3050d0a, 0x9975e2903831f484, 0xc1663598ab4d535b, + 0x6f6c4a52295a3728, 0xa66d60c70ab4182f, 0xa7fb03c5913b78bf, 0x2f5144c88969eb37, + 0x171b8686ba0efb70, 0x3ee576b610f5f132, 0xf40dfe346f5b4bc8, 0xccf9058d902b3ec9, + 0x64ec951cf4aca808, 0xe2ed49d1c923ad14, 0xfbe06a225608e407, 0x6cd20ca28c0aa562, + 0xbe32262bb89e936d, 0xae28a8f9f3f56bbe, 0x2dd2dd181ef5124e, 0xa8f554eaa13efd64, + 0x41df04024af6c920, 0xb7e5210444f123b5, 0x4fcc36ac1b1be891, 0x3d8454480e77be6b, + 0xb57b992e101397d0, 0xc910450eb88abe75, 0xc215c72ee826a992, 0x75a5704b615c0864, + 0x74c35f9f426d57fd, 0xf02e1d3fbf344cb2, 0xebd59577da4067b1, 0x5f5d93684b2b5de3, + 0x13af3958f84f50a0, 0x35555eb8d0003ecd, 0x228e26aec68b1949, 0x51dd64cd057ecc84, + 0x9e0452f462ba789e, 0x48bcf742566d525b, 0x93e5514a8fefb005, 0xab5c500fd2ba2ef4, + 0x5a3b9b17e4a87c4c, 0x29a61751806998bc, 0x7fe6c019f39a68e4, 0xa24a22d788d14c29, + 0x83e7d3c298215759, 0xdc2b1c6d6bef4347, 0x640d51d84ed56834, 0xd613ca709f6ccb13, + 0x7f13198374c22a80, 0x909a5872238daaad, 0x4b96a56dd7ab3686, 0x73c265dc5bcc576b, + 0xaa303446b9af8b68, 0x9d0446cda0695515, 0xcfb11aaccb26125d, 0x141b6afe3b7922e8, + 0x7b39e5a5a9b5268d, 0x1574570a0fe3edc4, 0x7fb5c1976e9a8b0a, 0x89f99b08d73cd1c4, + 0xc264beffcd584506, 0x2c27c54de04b3e61, 0x9331d520fea42719, 0x08cebc837ffbe441, + 0xac4ea5401c06c775, 0x1d80118aab7d109d, 0x80bad2d976263da0, 0x6e9f6c33dcbee03d, + 0xabf37d960728fd5e, 0xe6611f6c26fe5ded, 0x44d3d9454eb9ed43, 0x15960550a922ab98, + 0x7000f8c46d6680ad, 0x446570f1e3da0705, 0x060c5aa8eb4f8180, 0x40729a6edace1b71, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x110319a95b6c0546, 0x3de75ee7ad2c63c7, 0xa55db193d9966ef6, 0x65681ac6ea84de14, + 0xa21c06e5c3d161cf, 0xbd77bd34b807e312, 0x6ecd2eb89a476d4e, 0x1aedda80c5247e06, + 0x30a4a00cd12bd5ee, 0x844d1c312e6ad357, 0x61e29c8f12d8b877, 0x1564f89cef169c28, + 0x94ea53df2559ef28, 0x87591f659b385833, 0x96020e68a0aa321e, 0x0c0786905578830b, + 0x474e8d4dc943f8ca, 0x6951da06938af9c0, 0xbb2551baf39271d8, 0x53743fda6c7e7bc5, + 0xfc1cf9e1c6e575d1, 0x086d344e8c362e2b, 0xf29ad418fefbcb54, 0xe6166484464442eb, + 0x4d9d6cf095bc1964, 0xc0e26677d220887e, 0xd257ae6bde3e236c, 0xefe8286d6b0efd42, + 0x2ec3a9684fdb8f08, 0x89ee7ca150dcc6f3, 0x4ef9b84b1dee73d5, 0xbbfd0787b5ae48f1, + 0x00f1f4ddb610551b, 0xe3c9488bf3d66bd6, 0xa9ba7f78920faf7c, 0x26b4801f47f97442, + 0x395c5644b51f20ab, 0x7097a1ade545045a, 0xb2f89a9fe0a81bf7, 0x2047b4070bbd5d02, + 0x8705ddb479d0a0a6, 0x290370f5f485ad96, 0x493f0d4bf5612cbe, 0x94a99f31ce11fff2, + 0xf1bb362434fe8bbc, 0x48339dd3fb3dab83, 0xdd96502b120981b4, 0xdcdebeee2c6f8f13, + 0x37d791bc702a1b76, 0x7667d65ef60e4108, 0xa7b79581c3398b5a, 0x67b2b4a621f222dd, + 0xf9f8423ce54edaa5, 0x207c467a2f73064a, 0x4ba0699a72fe5c39, 0x55539a1a69a299f5, + 0xcca96677c9b59f77, 0x2a0671e2b3c16897, 0x8c9e9ba0fcdbc326, 0xa1a49549856825f9, + 0xed96169b72244c80, 0x00384f7470a47820, 0x0623e51567c6cb7b, 0x9c2c40db6fb3ec1f, + 0x514f93bec06ea16d, 0xd68ce1bb75abd6f0, 0x9b1ec28c5c38fade, 0x9d67e2d2811908f2, + 0xafef80aede3321cd, 0x0982e3ca67380c73, 0xeac4d40fb33e8b23, 0xb4717eef350dbbf3, + 0x22c319e86acba70f, 0x28310c6c2d084a63, 0xf118502a2c00711a, 0x60843fd6a0a4b9d7, + 0x52e0d1d6d2f9975b, 0xb975ec91b91b3f31, 0x1b6f2d486b0e072a, 0x1cbb83e02c2a442f, + 0x9e97156b8ea23152, 0xb593e9f1619e9ba0, 0xd8a1664be8e9b64f, 0xe12da827362803f3, + 0x2d8a60d1441639b8, 0xea95fd5c0b5f753f, 0x96a38f9e1db193e3, 0xb024439632a98302, + 0x09fbf7a611973521, 0x56d7a4054e8aeb66, 0x7e5cd659bd7ead26, 0x3ac8eaaf28246ebb, + 0x2a64e860bfce66c0, 0xa490f83d6b1c4775, 0xb7edd37afb40f152, 0x37dd7f2da1e888ec, + 0x709f7e4b98a66e37, 0xa154918cfd64e042, 0xf52c7407bffead12, 0x43f5a97c6bffd86c, + 0x8bd80f9f83feee9a, 0x7eb952f9868847b8, 0x093034bb60335484, 0xad312651e22c3545, + 0xbeb2363426eb872b, 0x09552e5f6b515d67, 0x22a98a1553178c51, 0x6573c89364823566, + 0x770a4302490659ea, 0x34e4a775b8e7f38d, 0x6fbcfe12a404d2d8, 0xd8a07ef95fc29fff, + 0xf5ca702d67a98fc9, 0xbb717017fe665cd7, 0x99583727643ddfea, 0x0c3be40c19d36ed5, + 0xe24291ad8ad63bd5, 0xfadd3f7476aa3359, 0x975fa1dcc4f8ab61, 0x9f3025fbe03e80d9, + 0x43e595021faa54c7, 0xc311927829447a71, 0x751cbef4b9fd1ea7, 0xecb35d16ee4e539d, + 0xe111dfd9f78ecf4f, 0x679b22875f6d1bf3, 0x9f4249e0fe378d58, 0x8563e4ed075f6430, + 0xc0234db57951f1b7, 0x21b3e68128237636, 0x230df1bf74f0737c, 0x97010ecea703a2e3, + 0xe2f067a9956ac970, 0xafdf3db052e79e14, 0x8be8e8fef8a1c6d6, 0xbce086769f0ec5f0, + 0x05ac24f03c7a7f05, 0x3e6b65599cf1af49, 0xc136c60cbe18c03a, 0xcc5745ac48dbe0bc, + 0xc9ffc840bde2604b, 0xb6ae15f81e3c79ed, 0x465b537d59ad1b43, 0xcd53aa284ab22b4a, + 0xff00a8d8a1a8c189, 0x6d454f5019427629, 0xa6a30ebc559fa049, 0xe271a62d4678ff95, + 0x68ef8f7ff1b68e74, 0xb315c752a55dc46d, 0xd82f0ac159a3b6c2, 0x4b17b0430b24a6c5, + 0x254c32d96e97bb48, 0xef591ee884639000, 0x3a6792b9e3fa9bf5, 0x5154330d9f41393d, + 0x53d49b1acb2340ef, 0x82df9760b4bf7757, 0x37a8c3b57990092f, 0x7339c7a57930092f, + 0xe9ced756e229bf35, 0x955a54d41fb46ad5, 0x961c98922d3470b9, 0x401b23059b91574b, + 0xab3bb86f100c8e5a, 0x9a001529884642df, 0x204f2c00b195f6b4, 0x174f5427f2aaa41a, + 0x9bc50a52adeb52b4, 0x1eafc961abc16e83, 0x70615054da1af7cf, 0x018caf327b1891fa, + 0xee324b01319f3885, 0x24adcd1390e351eb, 0xfea08d11c004259d, 0x7a3679f87b8ee14d, + 0x12fc0553c507c957, 0x524884d7cd5d52bd, 0x70f5ee7e645b1fdd, 0x3065ffbbb2d60d77, + 0xba6daf2dee220e45, 0x24fb3351a1c7c6c8, 0xa7c5bf7a7b0acb0b, 0xa060c84f7f595853, + 0xed365a25a7889d40, 0xd99d9e7764205688, 0x1300b50c2a2eeea9, 0x760304140cff20a1, + 0x74aa860784ee79e7, 0x5702724d1de5f04d, 0xfd4e4235e00a9c48, 0xc12e003ec6b198a0, + 0x24bb2ba9fa0c6013, 0x4960f35c8c9de7a8, 0x6a5e3e5cb561fccd, 0xc22bc01e8146a936, + 0x5ec053a0f3f2f6f7, 0xc2b5e1343efe15e9, 0x35d9ec5075fc4cc9, 0x9eaaaa42252870d1, + 0x3039a50e5cbf950f, 0x97c9bf6c78a317e8, 0x3400db7a38dfb73e, 0x0c0cfd0b4fa96622, + 0x5b3898b23f1a7833, 0x1da402fc06aafd02, 0xcc1f37b76ce63eb5, 0x0bf88fc97df3ac20, + 0x4f288fd1cad2f418, 0x96d594cdafa24404, 0x09a33a2be5ed0c98, 0x9d4c9d4de4f7189b, + 0xfdc0255d4159e21a, 0x7c9f478b2b7ea9cb, 0x28711134b56e81ef, 0x2d6df6f259330bde, + 0x38447df1ea9f7eed, 0x48b72a97ed270576, 0xf3849eb60c5705cb, 0x03a32521ae37f919, + 0x8a793893be8b0cbe, 0x462d7e27b8b19630, 0x266fd8c18ff4fa6a, 0x9fe6e4b19ac0dcc3, + 0xdad9099c51afe9a2, 0x50e135cbb7dbe1e8, 0x8daf8a4820b35030, 0x7564c6514a0885b0, + 0x4cf0f4aadbb8010b, 0x5128b02fc3e21b18, 0xb96cf535981d3025, 0x2e74060a2516cfa8, + 0x05f5cbe87cd27ca8, 0xae1bc8fbfbe436cf, 0x43bd81273f0cea82, 0xd9b085eb3a215276, + 0x73e650eb7554bce9, 0x7d325b72389623cb, 0xd15f3096f17bce8b, 0xd9c15be44f34389f, + 0x8ac13f9b6f43de6f, 0x887a30e9470f18b2, 0x5f769821aae879b1, 0xf280c8951f19602f, + 0x3e07cd0af83503de, 0x1fde7e30725fb5b6, 0x7cca20d9e29d8307, 0x8fffe1cecca6f4cf, + 0x0e96533140b1c03a, 0x27521921a570556b, 0x763e261a444d4bf1, 0xef7c6f0a1c73cf19, + 0xba5c17da207c5e55, 0xd94beb4736962825, 0x26c73fc1417163ec, 0x65ca40af3f1badfd, + 0x3945050e1d6d14b9, 0x20ba1acc9e03d215, 0x26ded295d5d26305, 0x8e3c49e723de06ba, + 0xfb9cf3c292422f6a, 0x1e67cba58b6cc50d, 0x481588f66f2ad506, 0xd4a3fe73ffb80a43, + 0x68d68162ad57faaa, 0x893bd6c2b9f933a6, 0xcb4ffc06bea9e1ba, 0x0b1a8960495d7bf2, + 0x83a2d3ed275bed45, 0x6b24389fe489dab4, 0x359d5e1998d87182, 0x22b8e0524afbdc48, + 0x05ed3991a123e1d9, 0xba88b3be44360264, 0x4ce936986eb198ea, 0x77d5e7bb260ebddf, + 0x79c00ff65391c7f1, 0xfb3ce3d7486372ee, 0x9763dcc36e735225, 0xcc629b15630fe816, + 0xb6ee20d289f03746, 0x7368d902e063eda9, 0x3b0953e035c217e2, 0x3fa40b903f1df986, + 0xb4dc8e707fafaf8c, 0x43033a13a49247bf, 0x32dd6ce0847ec239, 0x2fd19a0ac9bd898f, + 0xacdbcbcf10febd4c, 0xfb90cdbb33661676, 0xccf1158d73f27c3a, 0xbd0f187bfa6837ca, + 0x9ccdd6c4dba52a59, 0x11ecba7ace49ed1f, 0xb35f43f97e969960, 0x877c9b37dba99a63, + 0x125c5a7117a2844b, 0x37bf4c204e810ca4, 0x303f0a3458bd1ad3, 0xdb2836671b32b28c, + 0x093898dae862ab78, 0x44edc71daebfc852, 0xdd87e80a8f6114f8, 0xb0d90fa567386cc7, + 0x25fba30982ae9955, 0x99e7c9040816c1dc, 0x38f366726d89feb9, 0x6e863bc2677f8873, + 0x13f871bd46d9626f, 0xd77e20e96f77fe2b, 0x66698ff04f2667d5, 0x82af26eb54ef8f0d, + 0xe799b72855015bce, 0xa38a86beb25590f0, 0x48c65d41b6fbce8f, 0x021ee22d7e621edc, + 0x197650638f23b4fd, 0x74b6330c4b041641, 0x0fd6452eca0702f1, 0x55e7d64e0e67a5f8, + 0x925be9a6e6bc59ad, 0x0b12e087229bfdaa, 0x613dd9811f0c831a, 0xafa19e96bf66542a, + 0x3a16818b956f7181, 0xcf9e07130bf24b2b, 0x013eb736a53ec147, 0x7e8707148a1d6c5a, + 0xbb28599d8a2c49b5, 0xc55c82f0361e18e2, 0x538dba514193fd89, 0x2e4273e73221570b, + 0xe86dead30ef27765, 0x4f99a56ff63cf24b, 0x16c38e98f64847de, 0x3ad02ccacfabde7e, + 0x670ec8811b9e9f55, 0x5a623b5c649fe0c8, 0x8390e02f133bcab0, 0x99dc90535d84fbc4, + 0xedcf55a769c573ad, 0x1ea66fb89d65e267, 0x6f1e9722f203fa9f, 0x2a620fb56ac77659, + 0xa9db271c065a19be, 0x97ff3bfa5c0563a0, 0x3c8fcdf749994a8c, 0x9e1bd3400aec31d1, + 0x3e6153f1d00d71de, 0x23fe340dba5c5d7d, 0x7bc34717ba57eee7, 0x51f07556d6d12779, + 0xb2db91b19e6ec9dc, 0x9466d79552fac32a, 0x5a7ef43d677c4226, 0xe4b3e3b44b4008d2, + 0x0d650ce5584def21, 0x55185b47b7ba1784, 0xd559b9ae107894ad, 0xe25ecde7bc6ce65f, + 0xdeef0fa9cecd9db5, 0x6e83194e36776b1a, 0x23ca5fbac8088d3b, 0x2ea2b5e13955a069, + 0x83ae0d51d534a204, 0x7db51fb2d27b92f7, 0x8066b0e1c195e2cf, 0x2ea2a715dcf5ca7a, + 0xf3aa79a2e4e8ba9a, 0xc9e38a2426ba1005, 0xe6965a4e3f8c3a3e, 0x723976df4e5d47ae, + 0x8b53c335d68e8dfd, 0x16e57a539c129b55, 0xa2ab04fe3170a748, 0xb1f3c9bf0408f6d5, + 0x79e4059b0ad702f4, 0x32cf27c54be88d73, 0x3701750a39367a6a, 0xe107278ee64f3777, + 0x82107d39acf8345d, 0x7804bf75a9abb466, 0x4b78494248485962, 0x3e06cd87b792262d, + 0x38d3bdab42c330c0, 0xeed432b27288d4bf, 0xb6d6d44763007956, 0xaf8c9eeddf473e74, + 0xb7ad16ba172dd0f2, 0x1d78b0319c0fbad3, 0xeaf749543d8717fb, 0xd24602a17c78960d, + 0x728b6c7da04edec4, 0x38328347df161db4, 0x7baaee2508e2f1f4, 0xcd1b1ce2fbd61c26, + 0x0d5ad712f8b27fe9, 0xd75eadcaf9c9ce9d, 0x359a7246144bf2fa, 0x90e9b12f9ba6dbb8, + 0xef9fa02db4067ee3, 0x02c4328216137e5e, 0x136bf05dd39fdfe0, 0x26345a89e17f1005, + 0x9ea317660a5000ff, 0x25b84f34fee962c5, 0x1608ed4a6ec81f05, 0x9300248eebc0086f, + 0x39829b8b250e37a3, 0xa7e9c104a193c7b2, 0xd3e05273f27f8db4, 0x1e4c54e9bebc29ef, + 0x9d7f591184200ee3, 0x4c039e2892a7cbf2, 0x0bc29b12b4b45494, 0xeeb6623ddb019322, + 0xf85026fe0cf55d8d, 0x42699ebad4565675, 0xbb3bc82a7c8e6894, 0x87d0f8d61d6eca87, + 0x33e20ddce045878e, 0xa18f7e74f6eb1aa5, 0x51af767f6bb63021, 0x143f36cddb813795, + 0x87caf66b88a3dd2c, 0xc29d9ca3c25b1abc, 0xde5c49f0a6ee9c9d, 0xf797a55522464f00, + 0x3204a86122ff2c39, 0x3316d28dd56d06fa, 0xadeb7ba08568b21d, 0x1bcdc72db4fbd094, + 0x5308b407e9c32143, 0x1a16e976c19ef57d, 0x79bff62950bb1f94, 0xb85768ce270bf229, + 0x5dbb3ae0026ed7d8, 0xef7e01126be6171b, 0xf2b127e1e38de0e5, 0x5472312c1b0cd21e, + 0xba48fd9c791e53cd, 0xe35ad4186a19d2a1, 0xd7a74e2b56551011, 0xaff43a397a6ed374, + 0xd2977eee69f3d7f4, 0xb1ec6685b70724b3, 0xf5a5805d928ad164, 0x0bb527a23002211a, + 0x240ba1fada8ee3af, 0xae8a0630c6671269, 0x0eb261ca9528fa58, 0x63dd02fc4e07b182, + 0x6e3237e5d46cc1ca, 0x495a763c6450a04b, 0x40f0f95effb96cae, 0x35d59542f938d603, + 0x219c756a60c2c33c, 0x3828648b7743df50, 0x6db50505b1222518, 0x175552b0602d682b, + 0x28b3852575fdeaa0, 0xf8f97bce8254197f, 0xa48c0b7b013589d4, 0x99d7202a722b9709, + 0x96f1f01b64d20533, 0x48471bec7ad43876, 0x2fca4d92d9f43e93, 0x2f461e135ef6efdf, + 0x8a84d4d507ace2cc, 0xe3bc43e1babd954d, 0xf880bf5505d73c78, 0x78ced931cc2a0b03, + 0x425975bc20eb0883, 0x536475c56d9582ad, 0x8b8300360c2310b1, 0xe4457d037678d3d8, + 0x4af41d427b43367d, 0x3d5788627db6e926, 0xff8b7da71dcbc874, 0xf1554f065042da98, + 0x90ef8cc83fd9f422, 0xce850a58e678518c, 0x2e31d8eb8b674b38, 0x027648b12c94f197, + 0xd80b3941a2a70b58, 0x3654bf0ab070a0c5, 0x2b277fa9933b4a89, 0x49b9ea19df437907, + 0x7ac1518756b6a72f, 0x79badbc1b40341a8, 0x1e7ca2f9792024d3, 0xa099b8e844792982, + 0x0ee137d167a96c11, 0x1b9f30559cf261d2, 0x144f3b47a60cd6c6, 0xb128ba3d4eff62f7, + 0x608ca6efd1691bb4, 0x1153d87d1b67355d, 0xc77d4b730cd67776, 0x477e0841a45a8a5c, + 0x71eda8ea81bfc348, 0x634959cabe3979c9, 0x1ffe7efb1943a971, 0x4a966f288927f153, + 0x303896d3129fb724, 0x26959cc3ac3dc8b6, 0x63403dad3af72ef1, 0x50529b68193a57dc, + 0x0a14819461c95883, 0x0f1c646acbf19e6b, 0x23988d3b3747c7ed, 0x241eccf5dbd612a2, + 0xd0efd3431b78e44a, 0xed9bc36f39b48af9, 0xd25f4c7bf17cd7ab, 0xb5164bc81c624134, + 0x990b4af88fd60824, 0x6ba893ecc7abd11a, 0x00b9d3bbb913c31a, 0x42d093dad1fb1522, + 0x3aff13397fb9a484, 0x0fca2853e571bbc6, 0x69a86bb74c5e8c0b, 0xe1260f194f624baa, + 0x09eed3be1e939c55, 0x1cc395fd73c4f85e, 0xfd9831c61a1c8ee6, 0xcd5c43b61e98bd49, + 0xcd990827d6716892, 0xa71f19004f5baaf4, 0xa6139ed032311a9b, 0x6bd781f7fc6f7b4b, + 0x40ec6b89009c6bbf, 0xb8b3612b6b8ebbc8, 0x2f995907f3a3eb8f, 0x5bc415e0821c1a01, + 0x0499c1c74c710498, 0x48746df1a6b7a6c9, 0xb8e1052a6de9064d, 0x9f61fc0ac37ec3fa, + 0xeb9707de7eac303b, 0xb52014d7f9391f4a, 0x58b2ed1b9532e44b, 0xb266fba1389c7af6, + 0x4fc53e4600a39d84, 0x2938a29922a33b49, 0x350fb8d6e38bf2b7, 0x579b8423e18018f0, + 0xc36d41b91081acf5, 0x98f934fd5da1e3a6, 0x12459fe348c32ab4, 0xb9ba720cc1be26b7, + 0x8eb9da20c03c7cd1, 0xcd439f1345770d2e, 0x3b87ed27ca34c540, 0x861889f2f1ccad76, + 0xc34ed859426f9453, 0x25db7d650eba6ca2, 0xa141e81a82614fed, 0xdfdd8eb056dddc80, + 0x3e095042ed05e98f, 0x783814eb104be3fb, 0xc651a3d56231f8c9, 0xe22b241d0eedf472, + 0x2230f0e0e0d45616, 0x2616bacaa4495cc4, 0xa8a8d3fd94f9a2f3, 0xe1fb9e13f5a6c0cb, + 0x4052358b230f23db, 0xce27e292a37425bf, 0xc9053046b8eaa47d, 0x715e25a4415aee7b, + 0xf1edfd790b81a143, 0xf68774111690ece3, 0xfe1259c258f0d552, 0xca4fb3e35d331e53, + 0x9d33ebb7c91eaf7e, 0x8b4fcf188794ebd6, 0x7928f1e8dc854f26, 0xfec66009031bab16, + 0xf4bc9957009f8e30, 0x8141edf76690735b, 0x0181ca3c2a52c997, 0xd64b87476bcfab99, + 0x04af88ba50b37c00, 0xe41e3184c38acc14, 0x302d1875730389a2, 0x7661aeed338ab638, + 0x394b285871294789, 0xaaa250990d92fa92, 0x8848a72fc6b57d12, 0x21088cde630faa9f, + 0xe8db6e6becdae418, 0x89d1ca14edfa1616, 0x068fefb1d93db112, 0xf5988a2fb6655a27, + 0xad5fc9c91a2ca6f0, 0x1a0bdfe4d06ccdb6, 0xcbb0e5025d1c32af, 0xcedd0229ff1a0c95, + 0xffdbf85613e523b7, 0x040c75cd5e116b18, 0x0a2af9c449a1ed7f, 0x89a1a510f8d63b1e, + 0x1be539bf8cdc9be2, 0xc91a7d097d2701b0, 0xa90a4b905a31309d, 0x5c5838ec4841ea4b, + 0x2acc1afb603cbe8b, 0x6fe96bad45c7d0da, 0x7e3c8ba1fa8a7bb2, 0xe351182578ad5da7, + 0xdce62e9114f87332, 0x246a9e9a19cb5a59, 0xc7a6ced89ecae528, 0x778c068fb401dfc2, + 0x19e24a0d62ac7cbf, 0x2f55f70e6c8caf67, 0x9b5c37294b67cb34, 0x5e69630f280c0f1c, + 0x2f0e2e918f199527, 0xb07c7ceb286ecf2c, 0x3430aa947a8a1acb, 0xc8084d8eeea6bc76, + 0xd3897685cd8c939f, 0x6d79a9f0a2d49581, 0x6cf2664a5e612805, 0x6cffea406ebea79f, + 0xe9f6ba9224bf2f3e, 0x8c171b09bec05027, 0x5d375da4bbac1194, 0x962ad2d49c986811, + 0xb809c54d29fc4f73, 0x274eb5b328273039, 0x7fe7f99e93c2ef46, 0xd162721dba9ff92d, + 0x8921d4c29918b280, 0x03268b8d337ce637, 0x4f6417eaa2a9ebdc, 0x1d66a055d5ca69d8, + 0x2d448d23a5c48196, 0xf3f6d07ee780c1a4, 0x1d963b408fe45063, 0xdd97b6322537c4f3, + 0x06e5abbd1fd71b62, 0x129f4beb5271a1da, 0x616a1e5ed786c88d, 0x613130f50bafe890, + 0xe4c17e1e18dc754d, 0x247d30e5e31fa670, 0xaf9c2e9cc9458e00, 0x794d4f75da8fcaf7, + 0xb298150e3855007d, 0xc8e2b8453d2896dc, 0x338ac13d16b55bbf, 0x6fc2e8949909d118, + 0x26c388aaf3ea0edf, 0xca979a2cbfc9042f, 0x1520f3979b3fc0bb, 0x7884661d27bdf882, + 0xa297894ec79232af, 0x85a9a8fc9f32eca1, 0x68649ce690c6341c, 0x3aa4de65cce17d20, + 0x47362f95931e2500, 0x954113cab95f2bb2, 0x111c6bb28d00b431, 0x66ebd5098f7b3733, + 0xb77f1a04a2356cfe, 0x11612886b8d1f410, 0xfcd8e097e11cbd23, 0xce7c77f431a417d7, + 0xe25ec1a8457472ab, 0x2b681c67742e69a3, 0x125808f196cc7c15, 0x7d27390646b39f48, + 0x17b9793d9b10854f, 0x32866e834bb1a9cf, 0x10846bcc19136873, 0xd5723701ed8d72a4, + 0x7f8846fc62033e1b, 0xd8f4c982190926df, 0x8eb015abca047d0a, 0xd21bbff9f31dbb7b, + 0x7280d63f54adf001, 0xb4b86a6c7fe7efe7, 0x79f7e892eeece54c, 0x19cf9fa60d55e625, + 0xa7124541e310ba31, 0x990c8c92c74a04b2, 0xbf5d40b41ca138d8, 0x607688fd0df8133c, + 0x1d2b1ac1dc499ecb, 0x32f123187ff61728, 0xdcf1277a5e09a776, 0xab712c95ae3481ba, + 0x6291f5d23ad26d9d, 0xc3a5327c7e015c39, 0xbe6e75f36ce7e8bc, 0xe18e868d74d1b509, + 0x6a85273d0452f186, 0x2cafaba620e67bc7, 0x73b73276117394f6, 0xced802aea9cee93e, + 0xe69c54e0eac00fab, 0xb44f5bb52388ef5d, 0x4e1a04b816c202eb, 0x6b7eca28df55e6f0, + 0xfb2b50f46a13c3fe, 0x963d18ecf6f82752, 0x3daa48129569eea4, 0xa6938a8727530fbc, + 0x90796990c2f98037, 0xfdcb4a2ce9611b99, 0xc1775d37e9f26b7b, 0xc0792e38194b2df8, + 0x464b82a63cfae5dd, 0x155899c28bf5ea1a, 0x92af09ac2d2d75ad, 0xa1b85444dc654ab8, + 0x8e5cb662be49f9a0, 0x54d36758fee4b81c, 0x3233b1820ebcdfc6, 0x71edc2f7ea1c168d, + 0x1ae81524f6ce36a4, 0x148cc829eb55e3a4, 0x1f1c9cbd77a50c41, 0x23d12bc2d78b8fd8, + 0x5f263dbae425fad9, 0xbf8a3f7106707318, 0x06e885d8b362b18d, 0x01c46d8127fd83d8, + 0x0e33276cb9bc3249, 0xfb5b4557d643a683, 0xa888556ef33cf2c0, 0x64c402231ac0756f, + 0x2b8189260f5fb10b, 0x794769ffa26eff72, 0x239ffe9cbaba00df, 0x51d4a0eed81d6018, + 0xfa341c8f1f102350, 0xa9ed425399332191, 0x8c0e275b6e4c8fa1, 0x1a0d76413c7af2bd, + 0x99a6522c0a7e4738, 0xa3e2eae9222e597e, 0x14e9a543da3a9855, 0x99bcec4a7eb07774, + 0x2b4bdcc8f3e89781, 0x5b445c1239901983, 0x8d760e86af0bb2dc, 0x18552411cef5d249, + 0x660eb657953c1a8b, 0xe169f74ca937d7f8, 0xfe21e8ba64c069a0, 0xe5a682ed777f9f4b, + 0xcbdf593bb033a217, 0xcd646e3f07326bf2, 0x0d098a7c404bf1c6, 0x90f1325681fd11e9, + 0xab271f1a27b21af0, 0x8f722260df412ac1, 0x61142bb39567b2da, 0x5702ab9ef092ae41, + 0x78a92be57261f236, 0x1e77ed4f8a11f266, 0x4ad7bf7c7d6b17dc, 0xabedbc57856ebb4a, + 0x7d18c28eb0361b1d, 0x58581cc08f09b65c, 0xdad12c1dbb2c8dbb, 0x69d8e48d3ec27b9e, + 0x9d361c482bbc3064, 0x19977638a1d959b1, 0xa287ca1ca96c84a7, 0xc9944d8a430c784b, + 0x8e97d6610f9deb42, 0xb99cc4c70b2f96f2, 0x4a1f07c07a53b9ac, 0x12f1e64e68882c69, + 0x9adcb5bb88d871ff, 0x2117cd026b609ca2, 0x7f9623dd7302a097, 0x7043eb9c8730e7a3, + 0x860162362d15d293, 0x1463607d930ef3b5, 0x9718216ad0c4d016, 0x001b351a86086a7d, + 0x06d00eef514699aa, 0xf6df9927a56af0b9, 0xf20e6713b17ca988, 0x70b876bdd4474b68, + 0x443bf18d9b3b3448, 0xb48dff93baffc7d1, 0x9401a4ab10ea9c5c, 0xeb6718f8fad04e77, + 0xd1ef1072112c20a1, 0x8fbcc8a0c50ac761, 0x75f0b40f2e341b77, 0x40778f298ca7ec59, + 0x82e88c9af6c4e7f4, 0x28ab3c216360636d, 0xf6d914d72baafe4f, 0xbdb539357040da2a, + 0xb1d4fe75d99f04ba, 0xabcbf861a50d3b75, 0x24d378cc13a14fba, 0x6e45545afdd39345, + 0x82a0b6fcd67c8341, 0x448c4f679800a85b, 0x05ed3b3e9c75a765, 0x3dfb2d1ba40431df, + 0xa2c9eeb56c803c9c, 0xf13e87eb913ed01f, 0xea47c5ae94e6fad9, 0x89ee601c9af0d8b7, + 0xd218d431d63e3695, 0xe2787d5a187ef71d, 0xf475c61e60bad04b, 0x1cc66fb035840585, + 0x6d824991555dbf6b, 0x35d5fbf1d4475ddf, 0x8f9888f9a6f2dfe9, 0x34ed4699fd8079ee, + 0xa57a8df8f633eee3, 0x9da207e3c2d68517, 0xeadcd5e0df7cf0e8, 0x03c3e5764f631089, + 0x0d492f9eb763e3f5, 0x8032957d2d6fabf8, 0xdd5355001ec864b0, 0x8587c358edbf82b6, + 0xbb19e4648dde4ed0, 0x6faf32e7ede1ec9b, 0xf12b04b4e8de2743, 0xc75d0d9394899fcf, + 0xd38ee9aecbfe8dbc, 0x409503645e539352, 0xe444a13cc5b877e7, 0xe9f5c3daa337a73f, + 0x0ba025884d79a250, 0xea7b4c4442e65d5c, 0x5f45387e569210fe, 0xa3ce1dd17157abe6, + 0x991bfe1e8114973e, 0x7b2cbbc18f702aff, 0x54441a039152629d, 0xdbebaafcb8bdd6f9, + 0xb22f22281b8cfa99, 0x26093fbdad9c1511, 0x93fb44a8c2b356c6, 0x1a4b2c94cd8faba2, + 0x5ce6a34d594d8fce, 0x69fdaf3ac4170a59, 0x6ee78bed3d6014dc, 0x022e7eafbc46d660, + 0x90726daa100b53cd, 0xcf2b2b5c2a971eaf, 0xdce45127fc8e9f79, 0xcd3b479108737ae0, + 0xf36d00bac24c90c2, 0x4747a1b077a7a32d, 0xc1f380bc4cf822c3, 0x3bb345ca291389bb, + 0xb75b33f0b656ab44, 0x4b52c76233d7bd8f, 0x3de014d76905ee81, 0x8570148c2da4443a, + 0xa68a37c0a34b9058, 0x32b24e784d05ca25, 0x5a3572d4e3eeb615, 0x50507ec52c5f6bd7, + 0xe006b00db10a6e1d, 0x8a35b746b9776f3c, 0xae5a28316bcc99e5, 0x88e3ec3d55483f3d, + 0x3eb937761f714ed0, 0x0521ea3b43318b49, 0x47639db12c1562d8, 0x02eba2791aac7ce6, + 0xda4d524ad56e4661, 0x6bf13132ab8558ab, 0x8b7d0a43d914bdb1, 0x6652eb0c58775be7, + 0x60275dc415e86b10, 0xdec080cf9220521c, 0xd10f787a12539eba, 0xfe3cf879085ec78b, + 0xfc8676950158553a, 0xe0740582315d4e2c, 0x9f9429aaa4f6359f, 0xf93bf7d8efea289f, + 0xb7b66c63b0f6760a, 0x3a05c33cf07f8ad9, 0x46f19879c89cbb3e, 0xba1a1535fec0ceb3, + 0x4c4c32a9d19fb1af, 0x22371b04dc14860b, 0x9d4d6d4d45bd8544, 0x5e2055b1a81546bd, + 0x77e6f32884f4cc7c, 0xb1648731f6ce6989, 0x3c4416504f7a850e, 0xf17339eb208dfe43, + 0xc10ac0b0652d566d, 0x801d0c0db0db4d3f, 0x67b6be6cfd9697bb, 0x6570e30819eb99ea, + 0xcf888b694ac2084d, 0xec0a0e9b3c2f9f5c, 0x5eb152d48869b6f4, 0x8b909bced54d8146, + 0x78ebf06af63d9125, 0x524c42d3eb35b54e, 0xebf444e2ca6a6b19, 0x87e43654876dcb23, + 0x4a4f4f3194b47b68, 0x6f9b264d728e743c, 0x969a1e63691801ca, 0x29d9144449d04464, + 0x82d6f5c2c7e12651, 0xc3fe192d52781bf8, 0x48312b06917ed27b, 0xc9c056ba2ba0592f, + 0xf70ed7a55864fa1e, 0xc8b1354c79ce3df9, 0x37a7694d595135ef, 0xf8e2c49c0c77a6e0, + 0x7d4710ef6a6745ea, 0xae7854899c31df41, 0xf36a5a835573ea3f, 0x6b3441d18d143020, + 0x07209cae3b5aaee3, 0x33dcb09702b5785f, 0xc724e6f1d66e8e22, 0xc1f46ac4c8852f06, + 0x52439ccbb96d293a, 0xf787ce97919f42c6, 0x6a7e974b5bf8d41a, 0xb11f2a3053d6e41d, + 0x1655c18045b717c3, 0x0410d2dbc4db0e85, 0x10bd39d4404d90d4, 0xc55296723f907f91, + 0x7d6213a90727f867, 0xe6922d1bb7f406b9, 0x8646b1861158623c, 0x61798eab120547ca, + 0x2a0f0c9f26eb00a7, 0x9849da6425d2f644, 0x19a6e9bbf397a3fd, 0x0149a75d9da0d4da, + 0xa1788b609420f4a0, 0x8c46e8ac02eb7d0d, 0x16de65945fc50bf1, 0xb69f6bb14048b6ef, + 0x5ca7a0919d7ec266, 0xbeeb05019bd875ec, 0xadf6b65913e9c7fc, 0xd2ce2f1b5db204f4, + 0xe238406912bf2c3d, 0x9fcd9c4b91e5ecc5, 0x12129796fdd574e6, 0x9b78dad975ca7e13, + 0xa7be6610805eddc7, 0x2ea7f691c6c88d4f, 0x5a66b183391cc748, 0xb3e65537c324b8bf, + 0x974693c4d4f1dbac, 0xda9d4385532b06dd, 0x0c0c2e7c0da7f019, 0x71ddbf5d8e4c35e2, + 0xc87351a8ece53efc, 0xb66f26091bc8c7af, 0x1e1c17478802dd62, 0x0c5141a9244a0843, + 0x0d85c8e0b7e01815, 0x4c776ac5f801258c, 0xa9d9df96ada36a7f, 0x1439c03a067aa679, + 0x289e9102a30520f1, 0xb1afc31844b842ae, 0xd39425d4ed153d69, 0x82bdb8eba98081a3, + 0x62fb70d2dca1a9a0, 0x61d55787b4ce0069, 0x92fa2b089567232d, 0x493c675753a03fe2, + 0x52426e2801f74190, 0x6f824e851f8fed37, 0x9372c372c69cb2e4, 0x60f70c9ec3c852e6, + 0x9ee3cacf8d5b4c2b, 0xcecefbe7c00f8eea, 0x68e7774eeb1b36c5, 0x90540710ae8428ea, + 0xcc7a9f46f495c7d0, 0xd4289c5192d5e7ff, 0x86b7372849c2b18a, 0x64e9c06e3cc7b6b6, + 0x0b21182f4b218168, 0x9596bbac9d929fdb, 0x1d7a7cf3270e3ccb, 0xf24d27f6854fd9ba, + 0x23fb17683c743421, 0xdeaae8226f9512f0, 0x458d7a5d250cdab0, 0x9858e8a64170c589, + 0x6b3a1e28b47ffb05, 0x15a8c2ced16360eb, 0xb2757d4efde9bbf7, 0x27ca3f1cafeff321, + 0x3e4f3587732add52, 0x4fdf006f481b3f57, 0xee616b126d3fc494, 0x1eb155e313b028c9, + 0x645b4679b2ec1585, 0xb195f3c3d5457354, 0x3ce0d2f914f694fd, 0x3d94b056aad122fa, + 0x056d61e3b8d18d7c, 0xbf8d5b91bc123da5, 0xa49848baf6d7212f, 0xcbfac25657dc0cab, + 0x8533c05378ab7f3a, 0xb4bc46d2a55019a9, 0x8960c9c57886f6c6, 0x43202db8103d3050, + 0xb317fd83e76c5bc1, 0x97825381c692d394, 0xa1a167c3f7f04b5d, 0x19be84a49a463879, + 0x484f5fb5d2794fc8, 0x47fd97a3883a5849, 0x1b1d2533e25e8997, 0xd3e98fc3cc7067c3, + 0x23fca5fbf1e4c938, 0x0430d318d8a400f3, 0x99eb9798dea8a36e, 0x879b9ae16531aedf, + 0xd566f23dc0cb27c8, 0x5afadce88d6eca8a, 0xe76247299a02984a, 0x264ea2f4eb4191f3, + 0x0f3f589d11d2a760, 0x89d11822c16c1591, 0x0fab106f59daeece, 0x1a706f952bd35207, + 0x1c06cb35f05ba264, 0x18ec9cf6a0a14818, 0x7bfe55dfb9b9d3a6, 0x12fa1fa930f80864, + 0x86173b648134a51d, 0x541c9cddacde91fd, 0x8853409833784363, 0xed412d19bedf9f1a, + 0xf2543ef9f980e929, 0x7cd02bed8cdfa416, 0xd5d19b79ff350acd, 0xfb51cf3d38c506b3, + 0x63f071f34359c75a, 0xf0c9601537283015, 0x82bbfa98eb5258c6, 0x1cd6a004580c3e08, + 0x0a404f149012240a, 0x390e4a043a5cefd7, 0x9672a29dad946085, 0x6364d767bb0d2a49, + 0xf74fb9a4a8df90a0, 0xcf9d8c3c25e1b6e2, 0xb82869928052b70b, 0xa406d152892662b3, + 0x5fcb892ed4199179, 0x509e7133f78d741e, 0x0ec7270858f825f1, 0xfe048744df2c06f3, + 0x057bbf6f0dd184d0, 0x8bd04bc333ac97d8, 0xbc5dfc613b2cbe0d, 0x3d2d9eb53bc78cb0, + 0x73ff26c278a51d2c, 0x07fcdbc6f763ae39, 0x189fe5193d589c6c, 0x11a4df75972c470d, + 0x0a4036f2de416123, 0xdc263dd70926f870, 0x448b3ba744c0cfe1, 0xeb49071980023db7, + 0x95737fdeb0f420cd, 0x750aab47237f3026, 0x8aca80174399a1fc, 0x19d730a05c33d3b6, + 0xac431d0064c8ff3d, 0x5b0653acc6050788, 0xeaa9af6f454e5383, 0xdd6a1f2a2beb13e3, + 0xa2e37e6153485663, 0x3de114e49a1a2ffd, 0xe0c574c22f05de5e, 0x697069d335fd6e07, + 0x772ce2f43ce3f89f, 0xfd3d6b2ecb2441ef, 0x7699aeb825fe54b3, 0x9aefd297c53b8015, + 0x2f3c312bc7f4b412, 0x23dbadef44f81a30, 0x47c4f4177ec4699f, 0x8bd58c7c36d6ed10, + 0x8969a84245ca0721, 0xe23ffa03e26d3719, 0x3c1c525bec5ee938, 0xac75267b3a3cee74, + 0xa19504bbd4bc31f3, 0x6d4247c373eaff78, 0xdc7aa971520357bb, 0x56898824cd5c9ed0, + 0x6cf6d0911e33f7cd, 0x3cf22d1c6f6dd933, 0x8f0ecd76e4964f3d, 0xceb558a39331a32f, + 0x80d3c2c59d7c714d, 0x848e1cc82bf69421, 0x2ac66fab51a0c235, 0x00f2ee7a73efceb3, + 0x4ddda78cb8b9eb8d, 0xf8993ab13ac4c555, 0xbdbba817fc0c67b6, 0x10682d84dd401197, + 0x00591d27b16e82c8, 0xa2abd332545aff96, 0x4662e16afc17966d, 0x967f2fcc88a8780e, + 0xfb94e72f94e37584, 0x4999cae7c1bfd0cf, 0x9b0529980c4f60c9, 0xf379adad23875b83, + 0xf4f93a1a90254c8b, 0x64dde87b0c86e213, 0x995c109a35e78d47, 0x5832984c3b2d05fa, + 0xf34776ccdf3f5758, 0x4f47895d3b9f4bac, 0x4992f5c3b3feeecd, 0x6c9e9a529a17f0e1, + 0xaa3c6bb83427261a, 0x412d42eec1c2eaaf, 0xe982b25a3c9ff0d9, 0x39e2cda6088c4499, + 0xd8d92b0e4ecada0d, 0xc721f579e91d5c63, 0x009ecec67e0eb399, 0xf10cf96d915fc0ad, + 0x597b338cb7b3e5d6, 0x8d6f40582957a2df, 0xb5e7029d7f6be5c2, 0x0e959da6aba2b9ba, + 0xe16975d343bccfc4, 0x5548f52383ccd02e, 0x6d7b1f7de3b3abbd, 0x0d9bbd9144915048, + 0xd803f904d44761c2, 0x3c8b1c6b2fae3cd7, 0x97d6caed61bdc77c, 0xb116f85b8bd8290e, + 0xe6248aa330187251, 0x36d64a9771824fb9, 0x6bd5c57cd10d6a19, 0xf5c97ba000d171cc, + 0xcaf422ccd00cd215, 0x90a6d701a5b16449, 0xaa8ec0290e4e16c0, 0xd0c8eb8429c5ff27, + 0xa8a52ce48ab19f75, 0x9a51bf7cd09c4b4c, 0x269f3b2a1d7606d2, 0xc8f1ff20e931594b, + 0xe8ea90c4596aed98, 0x098eb7f5d52def56, 0x9770178ff0976786, 0xc3d9af42a5a27bf3, + 0xfe8d29c1d884c898, 0xc9b8e9f067976cf7, 0x4c11492a10797016, 0x98d031ca66acccce, + 0xdb91da8176b3e331, 0x93d2dac7abb6a778, 0xbaae4d13a6d671dd, 0x9f5dc711451c1957, + 0xfeb01dde69dc884e, 0xb99321b6d9fca684, 0x0713e6be6d0bb2f6, 0xbbf396226ebe9c60, + 0xb20dd8a252bdd2ff, 0x120c7f806c9f1cf0, 0x85ffb423bb2b5ded, 0x3986b5aa974cd543, + 0xc8e99a9b2da0a0d0, 0xdf76afc5068ea879, 0xd8bc5a9f2589cd5b, 0x4424e7d368da66ad, + 0x53f8f345f87d82ff, 0xbcb767220c91bb87, 0x2d4d872cea95d9ae, 0x7e6a40cdf5d087bb, + 0x8db504dbe6e58280, 0x56195a98ac172805, 0xe48e2eb2f8048658, 0x6921958bc72ecc22, + 0x35c084366dc3fce2, 0x8bba65485bd94c33, 0xa39c0b1df7c7024e, 0x53c8ec87e8899e7a, + 0xabc78d1ec32222bb, 0x6b114e0aec857542, 0x72d3b5a7851a7993, 0xa01dc576208f2cfb, + 0x476915c473db3dab, 0x4dfb5548e9249f39, 0xcd9ee84a47d184b2, 0x17cabe30a776eae5, + 0x4befaaf414c9551c, 0x031ab4022e44db4c, 0x916e5ec186f0857e, 0x9dfc2372dcd1171c, + 0x40eda17991376373, 0xf34691c16ffd6559, 0x66b629e024ea5db6, 0x280e7be4b8f62bcc, + 0xb5d9884b48c02127, 0x2de021745f40fe79, 0xb45901c7840ebb9c, 0xb53280372d6bc2c2, + 0xcfc53a1266ec7244, 0x39cc7b12a9ddf8e7, 0x58649ed4be9ea050, 0x12d7ab4a8198cf44, + 0x6973f7c5c6ef64e0, 0x1368f3da6bdc472c, 0x654e95ca90f05dba, 0x8f979d8ae22841b0, + 0xc56ab715731272b4, 0x9adc5ead710dfafe, 0x682e8399214c88e3, 0xb325d13468c69042, + 0x758d9f23566f9bb5, 0x2d0993bb4f5d1994, 0x7df3fe051d6edf30, 0x9ff4ad6e06ab4553, + 0x7dfe899f561d29bd, 0xc1054498e1e5e6c4, 0xfc71ab80774d7d82, 0xe579bb4912dc0ced, + 0xdb2fb117ff86a65a, 0x1617621c014e3f26, 0x4a69e84d9fda8e66, 0x493055694f623c5d, + 0xd84607bb04066cc3, 0x22dffad0636cdd37, 0x12ca7f1200ce7ba9, 0xde56cc168b7f3d75, + 0x9a6dc5d68643e0a7, 0x1c443203d186ab2b, 0xaaef9ca1515cf8b2, 0xf1c6bf0d044a7d32, + 0xe04a3aaf4bc12934, 0xd1004d056a4ff84e, 0xf252eb32ab81f2c9, 0x601fcd963d062a73, + 0x6d9d8cb8746f6f92, 0x04aa49471adccc4d, 0x2848099ec7cbcb9c, 0x8b16eff76553b211, + 0x52b9dd61d1c38466, 0x26c0b08f1d0227ae, 0xee7abfdae21da540, 0xe0f3192cb020bace, + 0x0743f8c95d38d277, 0xfb802bcefcafecd6, 0x0a2a0ca5ff49099c, 0xe40a08f3e0bcc317, + 0x98bd7602dea8cfde, 0x181d54e11bca6b75, 0xc5a39b67104a3af5, 0x90982592e10be0d0, + 0xbe06bd7e72a8666d, 0x8778679344febf08, 0x42c137760a75cddb, 0x04b7850ea632f095, + 0x0d3c7772abeab924, 0xfa06cc90492c35cc, 0xd899b5aa1b634544, 0x7c84e27e9442217a, + 0xba3322a38eb86971, 0xe322aada108f745c, 0x21617e1c051aafd7, 0xd7adb59d40b532cb, + 0x6643601da79f8c3a, 0x7f78fe8fb3e1b110, 0x88f8d6c76139cba4, 0x051c706c0e5d6695, + 0xeeacc64c5be615b7, 0x5c27cbb0b2e60b9e, 0xb210e47c3c0dc4b5, 0xe68c49831ecb525a, + 0x3777d04d80c788cb, 0xd3c67d5a07e6590e, 0xc0b6161863747a84, 0x53002902fcdb927a, + 0x7081ff57df0267ba, 0x043a177490275cf2, 0x6621eb121f577d49, 0x844435827a9852da, + 0xd6e869b6c620ad63, 0x6220aa25fc0e4973, 0xccfa27c9bbcdbfb7, 0x73421b013ce76fed, + 0x9f8485080428c4f2, 0x59e90f79faf6329a, 0x9f61511c9a83cb76, 0x7fbec6bf0816863c, + 0xa0db5359ac781e07, 0xdb4a943960cbac1f, 0xb5a7f15ab81c436d, 0x9e415d395dc7ca18, + 0x9679b91768db92c4, 0x6a9e64071a0607fe, 0x880a6f8c7d41f8a9, 0x07f137c2d62a5e26, + 0xc9fdbec73b54ccd5, 0x8b430f607e612d2c, 0xc03744a51c5db831, 0xe7151522840e42c0, + 0x854520897e2ff7ba, 0x5890a1f9a6ee3587, 0x53ede4885dacaa0a, 0xdffac7398a97e25d, + 0x1d99a0592f5bbf4a, 0x5198be0f80d2f512, 0x372feadb269aa79d, 0xec7a9e2824e09dc0, + 0x8f5d8b96588babe6, 0x7803c8bbc39dfba1, 0xf7c3c4ebcdbcf077, 0x7c0ff8a9eecdb3db, + 0x71fdec2b6d34cfd9, 0x166557a3116e44f3, 0x86865eac4971d4d7, 0x961abf7ebaab6822, + 0xb0ddefab749077bf, 0x7a15c1ea0398b9fa, 0xb82bfc6c2af133f8, 0x4ed11d58475c6d7f, + 0x6e9289a1ff83882a, 0x7162a7f2596d356d, 0xcb486a7a2282825e, 0xacf7bab1d0287509, + 0x03ddf0070ae707fa, 0xd00fe1074d175bf4, 0xe0cd02b04cf93ed8, 0x90db138c945c4dff, + 0x6201bb5c6201360b, 0xb508e18ad9436c32, 0xfafe06826d9cb12b, 0xc49569fc9d56e3cc, + 0x17f9ecc8c72e58b1, 0x5feb264a1f383741, 0xf93a263639383df9, 0xf5c8ff2e0e2ed807, + 0x9472359bb886b557, 0x8b3412066cada5a3, 0xb1f60b0025c9d86d, 0x20434439b032ce3a, + 0x933ce92422b299eb, 0x8816d115d26d6d06, 0xed6346e72cf204b8, 0xe23645eed0f84037, + 0xfd86bcf14cf45748, 0xc7bc1b953bd6a71c, 0xe8e83b5564926fa5, 0x46d0ef1ff564cc43, + 0xf293ecc10bbc960b, 0x729432a8bf180dd6, 0xe642b77ef52a449b, 0xd8baab4b085585f5, + 0xc2019a4920d65413, 0x4da3d59c9cc5fc63, 0x0ae4a1ee66ee11dc, 0x6cd20702647fbbb0, + 0x046252e9c1be9cd3, 0x2a9cb692cbff87f1, 0x5d13edcf919a738e, 0xf91a1b3d7a0852ea, + 0x889e3e4b357766df, 0xeeaa64780a091dd8, 0x54bbb5355a145d9d, 0x57f4e2a6a317a96d, + 0x64b9eb764b0a1b32, 0x6da0e1a1d752e0fe, 0x60d2e309c53d7260, 0xffd3541e0adaf6f2, + 0x9c93d8349db1b40f, 0x335ac00b1b54c676, 0x616516766c88f062, 0x1438b7b48dba49c4, + 0x55b7a6ba3c79ea56, 0xc77317577b714e92, 0x9acaac22095ad972, 0xfddf82596867b42e, + 0x4357316745aa8210, 0xff488b052b8c60ad, 0xfaeb36520895e718, 0xa20197062f5c96be, + 0x273b0dd1fe669f32, 0x2071b5962216f425, 0xa0e463b79e0092b3, 0x5427ecc31c7d200a, + 0xab827c7ae99bee39, 0xaf8cb5a8a26b47ed, 0x91c143284d1908ad, 0xfdfa3f02fad2c27b, + 0x5a46304cab5dd072, 0xf82bb55be1c7b864, 0x0f5438c56693f19f, 0xa6ff08eaf673b6cc, + 0x617eff54dcbce725, 0x356e97654a23f704, 0x6987e45a16bb9151, 0x4861abce800476fa, + 0xa04c84c016629e4f, 0x10eb51e9fc46163a, 0x64c3094bd29aa86c, 0x8f313d126d2f212f, + 0x46d64bdf5dcdbf30, 0x9651428cf144f140, 0x080b77612c44dca8, 0xa279e848969d8e9a, + 0x06872e7172b063f7, 0xaba536032bba613a, 0x64f141e4f3477687, 0xc2150ba6b4c4aacd, + 0x2392684d54242668, 0xff055b89220da899, 0x1f633c3a15da8c68, 0x2152a91d528107ca, + 0x4d93fcb17b2a98dd, 0x75076bd1012faf75, 0x63d2bffef401c11f, 0x34208a163b5a0316, + 0x5c95f2acc210dd4e, 0x7d5844d81bbf67c7, 0xdb2f118269251a00, 0xd36d4b28c933c960, + 0x26e41181c299cf98, 0x2b8e4dc69845a927, 0x0d1e68f53150dee3, 0x11838d8af186083d, + 0xb55a022c7b69f09f, 0xc5f3f8cefc1d5484, 0x5ec8156234b9dd9b, 0x0ed9e2df39cc097f, + 0x5459fc2dc0f701cf, 0xb80a271ed121264a, 0xfbe6cfdd215b6902, 0x8f0c44793089029b, + 0x6ea2105c64393c65, 0xa5607481ab348d4a, 0x0dc2e04c759a0585, 0xfa94243536deff9c, + 0xc22645d7b8e933aa, 0xad3659d222d45736, 0x15d9fcafe1f45845, 0x2a34069cd26480d8, + 0x1cc0759070b715d2, 0x5dc180f075a2f59b, 0xad6ab98985ac3539, 0xffa3d82cc30ef61f, + 0x15bee23e4eba9854, 0x910824491b076a96, 0xee17851290203708, 0xc7d913720711adfb, + 0xab93619bb50c9f32, 0x52e0e73bebbe126f, 0xebe0a4ad83137864, 0xc052cec7354ebdff, + 0x9edd2e0d9158bdea, 0x545e232c848b7d72, 0x544e402c077d5fbb, 0xfb540f7080e8b6f1, + 0xb84ecd3108d17aa7, 0x5075c34d601f458b, 0x4963cce92e716406, 0x152b438adbe1dd1e, + 0xc1f8163163176e26, 0x628ff06ec0a95b45, 0x4560a386d04c832c, 0x55440de4a8d1c17d, + 0xdaccf26635073d96, 0x5f1cf8cfc9196f97, 0x032d6f13d2767961, 0x168595dfd3132374, + 0xe651cccbe16c2ce4, 0xffe6877a39407587, 0xc9e3cb8cf4914b23, 0xa5381c415a766ced, + 0x791a9520fc3b5cfb, 0x71c32bef5f0dd413, 0x05bc8c89f185dc7a, 0xd13576b14e2d3d92, + 0x3b91ebc306475991, 0x701af90c7966b979, 0xb5e84b1f436ce0a5, 0xfcfd998822fb82f8, + 0x2c9170dc1c13a137, 0x319f467aa45e6def, 0xf36d78022c680f40, 0x9044dbd3a295e05a, + 0x3a9ab2fd56716fc9, 0xc729c5ee1fc78cf8, 0x35c177fd1ab170dc, 0xb6b8c312ce538ae2, + 0x35a66ff7542daf8b, 0x5f6a3d2435261aec, 0xede8cd7d28717aa8, 0xab356889f1266bb1, + 0xd095b01716ca519a, 0xbc5073a677e4a853, 0xd6ba234972a3bf68, 0xd74e77aebdf622d4, + 0x50cfc14a66b19e09, 0x63082fe99cda4876, 0x09b4fd89b22dc52c, 0x842ea1e2b46e84f1, + 0xf776a8ae38ea15ff, 0xb458969036357958, 0xbeb3f08f3ad39c18, 0x7e441baa45687f4e, + 0xef8e9561b141df79, 0x51f1ea482103fd9d, 0x1701f914c5645ecd, 0xe5030e3d24f4af36, + 0xb898115b10d9f42e, 0xfba3c47b005eb12d, 0xc3407a4d45199512, 0x755a4efbbe95b8d4, + 0xc80df759e4761f21, 0x47e5e61d774ffd2c, 0x053729f38ae7577e, 0xba7b9e33de0c4566, + 0x7c144707dbcb0e0a, 0x1aaa46ac7a8bdfa9, 0x2589fc07a0b64c39, 0x3d7fdccbe4f8fe3b, + 0x33b4bd8c1a018515, 0x61dc8da5d8b7e66e, 0xd898bfb6afcca781, 0x3450d7c98026bdf0, + 0x3b0384f7a81fd0c5, 0x0a20296e97484b95, 0x39598dfd67b0472c, 0x49b0131fb54f24dc, + 0x1b66f7839669f7f5, 0xa2bd09cfb243c376, 0xf36207b52ec4824c, 0xb7578827c8750ecb, + 0xe917bd040e7c7fa5, 0x08baf34706d3ad7e, 0x913f9e916e7bba86, 0x0e4b353c2ee53376, + 0xb08972c457f18ebf, 0x8551ad7aeb0a2edc, 0x419d5ad82efb4b7a, 0x36c93ca62dd02fd5, + 0xc86798799972f164, 0x6db8e39b5a108654, 0x8be5f492da6eb5a1, 0x71e842d23f36bc55, + 0x04e94eb2d0810779, 0x7d6676554aecf981, 0x7cb74ff7bc010216, 0x6b6b218fdcff77b0, + 0x39aa991c6ae9e163, 0xbd153e0aed086903, 0x7d9b898051e358bc, 0x05b30f5d8480ce63, + 0xc8428dd45a80a1ff, 0xd27ed65f608c009a, 0x63a1c865c3118bae, 0x20f7acab9dc8eadb, + 0xc88fa87d29a249f6, 0xd4e591537708c2e5, 0x519c071da0cdffa3, 0x93b78a4ac9b7563e, + 0x6428b449c9070251, 0x28ffbbdd1d9db43e, 0x50947d97ba4320ec, 0x0f184d0c306858a7, + 0xff94f8f35a1586dd, 0x34acc6e206aa4860, 0x39dc1cc1fcf417f5, 0x085af7e502ff1fbc, + 0xddb8c54f41f2045a, 0xe343345e3ce33b8b, 0x996a5c697f68deff, 0x01ddc3bbb092db10, + 0x140f7cc7b0b1714f, 0xbd14c3d073b704af, 0x7925f4a7086558c0, 0xc48aa8865f5e8d4b, + 0xbffd568d8624a33a, 0x4cff6a435f92fdf6, 0x95fa56aed1001a8d, 0xa3c97016170f16f8, + 0xf3c81155a160c5aa, 0x3334d22ba61c4477, 0xfb9888ceece64eb6, 0x198b0bf4da3de4cb, + 0x6251d076d3129716, 0xc03c84b2562561e7, 0x7b375fca53825da9, 0x52a8cc16cb8d01e7, + 0x1b364eae2fed1e0c, 0x834ec87832127220, 0x95afbba2a2caa926, 0xd0fc8c6b810402b4, + 0xa43035a643602510, 0x354dbfaa190f71fa, 0x9afe1b556308f12a, 0x46c29ea2883895d9, + 0x4b6e1d42eb836307, 0x303476b422b798a4, 0x9cb51d2eb38c579e, 0xac8582b7550ba59d, + 0x63d5df574c1365a4, 0x1e446e8c4f7e3801, 0xc18f94bddee2092f, 0x5e4076292f693a41, + 0x9d9d6cc24f3a9866, 0x41cc84ce86b60707, 0x404b88d16f175222, 0x8251afb8cbaabedf, + 0x6f7e27755bcd1180, 0xf67a8f7770a4a6b8, 0xc291ca0add72fd6c, 0x6cb285de74b4768d, + 0x1274f094551a799c, 0x3f13dada535aa835, 0xc6d5ab45ff84909b, 0x31500a87211c204b, + 0xf970a3b85851f629, 0xa3636cb1d6ace4c4, 0x0fa72345021d3e75, 0x771ae73703475498, + 0x2ae644c30d7ab882, 0xee528ba92347c105, 0x9aad23d1b663d8e9, 0x761bc50ccd50440a, + 0x05b528d0b47d19db, 0x59fb7fd9c792bea0, 0xe9cee2d0a3d5dbb1, 0x586f0e6cc71b96fd, + 0x5b52baa2a3188661, 0xfb8b6ab325556dbd, 0xa9adfe73dc0962c0, 0x905a21f9c782597c, + 0x5b50d3779ae80640, 0xe650b77731009357, 0x49ecfd55f47d87a7, 0xb66f166bc3d78c80, + 0xc0afc3578fc32b11, 0xa6cd8cb23583229f, 0x44458c8444535edb, 0xb5d6c94570f072fa, + 0xbbc3ab9160974def, 0x33208248430d8494, 0xb057ee9b4e660300, 0x697cd4c0cecc5d94, + 0xa0416cf1c4ffae0b, 0x46f8f803edaf63da, 0x3f813712c9134718, 0x8515f28c818ac523, + 0xcaa251396a117942, 0x4920bbb45f67bf8f, 0x61b7b684ffd1395c, 0xe3a5d90a026194d4, + 0xe891c7cc404ee80f, 0x0901cf0718e84e38, 0xef1ada01d9d06815, 0x0693e25e4a2aadfd, + 0x65633e0d7500d474, 0x3d9e595326784697, 0x2327758056be78b3, 0x2b328d8432540701, + 0x009c721ea7a97bab, 0x6a48dd96b7f63b32, 0x5e6c429198ad01e6, 0x61e6a996433d3d25, + 0x06d1b4ff459b87a6, 0x4a17b114519a1632, 0x5922f46e5d5315ab, 0x7919fd3ef80ebe22, + 0xfd3248f90c99c984, 0xca0f31142c83b4ca, 0x72fdece85aad2221, 0xc3d5655b64bd54eb, + 0x65c4897d74d599cf, 0xd8c86c2a6a9624bc, 0x885010b9644f4408, 0x5c3840e7dec1ca07, + 0x3174d6db559e38a8, 0xb0256c555b40f8e5, 0xd2c7eac96947ecb3, 0x78ee146d5b56b282, + 0x3bba5babd2723a8d, 0x81a8e7e398388781, 0x2996535034cd151a, 0x961b3f3f5412ae8f, + 0xa3814d33381ef16a, 0xedaad662b82ac4dc, 0x6b925224c0f0a61a, 0x0a2b706cccb663ee, + 0xf06bdd4f0b052caa, 0x4bf353d2a6350a97, 0x02bcd33a866d9899, 0x20ae090e4b7d3173, + 0xff5155189b326025, 0xbc3229d5903e4657, 0xcc37ce7209d5db85, 0x73e88df224c36785, + 0x5bd0a0e01864dd25, 0xf607dc98b37442fd, 0x1dff97fae8e4404f, 0x81c70b6d9db0b322, + 0x00d9134c6ffc8b9e, 0xe4eb944fce9b875f, 0x32808a4657fad9dc, 0x5f71996376c959a8, + 0x7b17693ff3b5e780, 0x51ba2211a419c020, 0xdbb909fa40439dbd, 0xf8c9f446f75f0e8b, + 0xdb803df36516465b, 0x5d5ac9bf102f979b, 0xa02325776de37ab0, 0xb4f5520942fd5f42, + 0x2bb61b22a24f0e4b, 0x341f45f2d3122dc4, 0xb30ea44e6438755a, 0x49388a4980678ced, + 0xc33958744fec3a60, 0xd4660b8ad08ce771, 0x1972c91dd3567f34, 0x63492ce44a13a450, + 0x09742cacc3ef32ed, 0x84b2287dbdde1666, 0xae7a3711b52d0f42, 0x2920bcf98359441e, + 0x186018f6eab2a8d1, 0xd2915d2f8abe974b, 0xfb46a65bd08271a4, 0xc677bc1151b29dcb, + 0x40e3e362912bdcbf, 0xa45fdcfba95d613c, 0x4270d1bb365ee95f, 0xc16bfb0a66b65514, + 0x6af3694273aa7276, 0x8d984ee80d7b769f, 0xb2635235c694a035, 0x51671d63cd2459c4, + 0xe6c1504bd405de58, 0x74921f519222c49d, 0x5cb88d62fa7e1ab0, 0xbb8083e455f2f4e7, + 0x45151d668e9b8501, 0x320b255c9b61a105, 0xdd559ca7ea0ad55b, 0x34eef4162777c072, + 0x2d96a767e5be3cb4, 0x93f0a8c18d68735a, 0x92f13af222db468f, 0x5ac52e54eb60e548, + 0x33c4ac2bc2e1552a, 0xb4be3572c7c113fb, 0xc10ccaf1b077745b, 0x4207bf19fdd10eb2, + 0x3ae711936662ad6f, 0xa6944e9d12e195e2, 0x02bc1105c987a053, 0x391d5b42cac78e27, + 0xb6bde226a8ab169f, 0xa7e57c5541a9e6de, 0x793f979da9826a40, 0x0c2732011360f20c, + 0xc34415631eb5d360, 0x8bc5ee0230b3288f, 0xed90c0881de5b236, 0xad3c72d76342c3d8, + 0x06de1864cf1baf3c, 0x9836aa45861b183b, 0xb6a90970dd65e50e, 0xc03e55bf57fe6913, + 0x6d3ea5cf74e5cb89, 0x7b78163c5d4fc463, 0xe148ab8dd5d52eb6, 0x313edfe77dc71927, + 0x8030de85fa41a4b9, 0x8d1295d4b2dc2515, 0xebafe202d41c143c, 0x4a364c36aba048b9, + 0xc772de2572eb8f1b, 0x7ba918c139683c0f, 0x6c8d04fb8a3e9a9b, 0x6a787cf9258b749b, + 0x4d5c74e35bf634f3, 0x64800cf884364dc6, 0xe560f2118c9bb646, 0xcfa0c2a0a116173e, + 0xc5ec3923387c4994, 0x2d1facc538efdeb7, 0xdaff44f59d3f530e, 0x6193c962d40d8caf, + 0x3e63dfb476920052, 0xdfb354de97719a8d, 0xa1757d4f20ab1640, 0x902c9c6e6cc6a8af, + 0xac5c8bb08614421e, 0xc66285953ec95022, 0x025235d3b7417059, 0x623223b9a631c70f, + 0x7d4b2a3d19398efc, 0x3812298ecfe14eb2, 0xa0066ca00926e97a, 0x6284ade8cbe633ce, + 0x8d60a91d5aa91cfa, 0xf77973124dc532ca, 0xec228dad9d5eda7b, 0x4df3d692b95f83e3, + 0x63e72f390c8510e4, 0xdb1723f12927cbb1, 0x032b6431c12c6900, 0x2f34af1ba9624820, + 0x08afec13156c0341, 0x7e8918de80649a08, 0x40cb8e710f454b0b, 0x2adc124d60644bda, + 0xf72135f1b6b1cc9e, 0x9f4078a17f43d432, 0xa6279e85b370326d, 0xbb9e3004e6b5167f, + 0x87605a6772b0da4f, 0xa2616ce75bfca97e, 0xc5ec058e89b86b36, 0x3a92300cd299b629, + 0x0b5206628344b14e, 0x7f91a60d27308938, 0x3daecec1d891f9c4, 0x9f49c05d5f64dad6, + 0x93337e5f1caac6d1, 0x0bb40238c1bccf4f, 0xd8ab7f53c16ae336, 0x3357a0b9da9a85bc, + 0xcdd3846346650e16, 0x32d115ac58b8ed9f, 0xbe20f197313148e3, 0x382a6fe68b3a3b1f, + 0x1249de8024bd607e, 0x41f2c50284b8fbbe, 0xa105a4f494e4b4b9, 0xad8b0c8d9128c599, + 0x96c68c77d4bc0093, 0x09ca4ec166d6ae62, 0x6b6d1e18b3181c00, 0x8ad1b7b621a2fcf0, + 0xf8412f3bd851d24d, 0x8c9c2d1104b28f0f, 0x44adc8070a94be46, 0x05a5bebea59839b5, + 0x322b7deaddba32e1, 0x173ae323b060515a, 0x297a5c234e021eef, 0xacbc3611d47c6466, + 0xab59caa33317d2d0, 0xd0c2f627f89a6090, 0x026b2a1492531a33, 0xbc56e3c8b41dd004, + 0x6344b023b9d66c08, 0x9d7753b5f234b5f5, 0xfccb753d9cbdcf4a, 0x0f627ff682e41bab, + 0xe4e6392450ee4536, 0x974c5123f2a03706, 0x8bfa5bc8a7336c4c, 0xe341903389f8e756, + 0x5dbfcfda5572a102, 0x0996213240cc196b, 0x7872c8c268bf6508, 0xf7da9d899b88181b, + 0xa3a1e4c0ea4820e7, 0xccf0b52517cd994d, 0x5dc305d4a0d0cfbe, 0xfcbbd98b147fa46e, + 0xc59f8b29dfcc068a, 0x34115b975758f270, 0x2446e43acd2296ae, 0x11d106625b13164a, + 0xde7ab19f5e0839e6, 0xc5780f4579d1b9d2, 0xaaad0e63634b0673, 0x039df84f68de43d8, + 0xf1d66f944a893afe, 0xafa2109dceee753f, 0xa5a67af7fcd4a2c2, 0xca31ae7449ff36d7, + 0x78c1d76084463259, 0xde7c8a29cc9f3a04, 0x30ed6b9d28af4fb9, 0x62df82db1faeae1a, + 0xdf9a60f1fab60989, 0x2da3f791892b6536, 0x80bb450d424891aa, 0xcde3c3efa07a9f7b, + 0x9d6fff64d49c069d, 0xdef5ba81e77897bb, 0xe21d24ab76f82b90, 0x1c36f4860adc0293, + 0x2ad5cfe6704282e9, 0x692f873e1e9fb3a6, 0x732c363af56a06fe, 0x39ed3fcdaf01daa3, + 0xe041b35e855212ab, 0xdc746d5ea6bede79, 0x91e64c3cac9b1f7c, 0x2db0d4e3b83b4e27, + 0xae9a2420e43e2b1a, 0xa42e488d354bd011, 0xb8ef32e364709eb4, 0xa702983b2a70282b, + 0xe10f821759269aa9, 0x35d8496186e9cb93, 0x92426b4c47bbe851, 0x9bb27db1d18c72ba, + 0x08a1b1e4b234817a, 0x3ca40f8687493c15, 0x0bcb23b2d2bec7ed, 0xc36f9b81133bf276, + 0x3761ed796dbff31b, 0x06e093b27b16f0c1, 0x33d2dd92a0b68045, 0xeb589a61a6a086ef, + 0xe728eb240b3dfb98, 0x6fe904ddb72b5fa5, 0x1996290dc158a0e5, 0x3964f7ffaa3f3350, + 0xed7af5a73bf87da5, 0x2470421be6f82151, 0xbd004640e9a83e15, 0xf739e86e89920583, + 0x92e8d07e0375f3bf, 0xd2245da82ecca8d5, 0x74305486804c08af, 0xa8cddfad39aba17b, + 0x6c0d47448174734c, 0x379db8d5c4b25552, 0x45baa48f033ab5b3, 0x769584cf1644d5f2, + 0x8e4ac24e353acd60, 0x686e520926a1fe88, 0x59215612d838e715, 0x7ed026a62e6a0add, + 0x1fdcac8bc892b921, 0x9c27ab3f47981e3c, 0x1b90df6def4b8ff2, 0x063fd55105716d4a, + 0x9441164376b35ae1, 0x8bf705f9d70f7370, 0x1085dd0b3fd1d960, 0x308b35b29f535069, + 0x6ba2fd7616f8bd52, 0x489a6cc785c6b4b1, 0x12b38374796763ad, 0xc806e42a0fceef0e, + 0x42fd2f1739fd8540, 0x5a1db40c7f427894, 0x4057db8a1b992fa9, 0x1a01fdf24532de16, + 0x01f82a12929604f8, 0xe6145432c0bd380e, 0xfd53df2a8ad84115, 0x793683b9ba2c3efc, + 0xcf6e2b77fff5d528, 0xca8e7a2781af7203, 0x13f8b8c7cdde11ee, 0xd0eee90f372f6d34, + 0xf9477e0d18efc3c4, 0x55348a428b9f753a, 0x79ba454ba030db31, 0x3898a7ca933c5663, + 0xeec85533074803b9, 0x511dc788bda99e63, 0x01bd86f9b139362b, 0x07f55df507e3c79d, + 0xf4261fc6102f7601, 0x42165109dcd8d54e, 0x78e6acf5abc62c58, 0xc770ce401d243630, + 0x671321fb1f60a2a7, 0xb5191a1938a91ea6, 0x06c010a7c390ffa3, 0x6759d0f60d2a0c8e, + 0x5d6c089fce483892, 0xdd4fc558ab2d7579, 0xdaf9a23b7792d777, 0xcbeb4e159450dcbf, + 0x57d7fbc13f138747, 0x9b34072b9e346d57, 0x9ff3f24b2af02a25, 0xe371e95e3a3ce4bf, + 0x054762efebd2967b, 0xd21043fba73cd7e5, 0x05406e9ed7d11663, 0xdfbd9d419f692af4, + 0xc28d85f200b3f78f, 0x4a3e6a4efa8de514, 0x1e4928341d014968, 0x173082e207cc749e, + 0x71143a655f24b6c1, 0x5a563894bcf3ef9c, 0xc0d77d9ac032cd9c, 0x61997f46188ad284, + 0x737cebb678533d30, 0x384d8ac86e9b7627, 0xf312d6733d10ff12, 0x25d10e508a8afc64, + 0x702df6253fbc6a73, 0x33415da46f2058bb, 0x358ae90ea23e2149, 0x905d301d360451a4, + 0x5d2f490eabde671c, 0xa40911a3265e9330, 0xdf87f10ac0ca22fc, 0x379a032402ebbc89, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21ac3df849be2a1f, 0x11006e9fc51d112f, 0x9151aa584775c857, 0x5159d218ba04a8d9, + 0x98b7d1a925fd1866, 0x8f4753cafc2ad9d8, 0x8eb91ec1569c05a9, 0x4abbd1ae27e13f11, + 0xf099e607dbea8b56, 0x45384e961066aade, 0xe812ce3a6e619c13, 0x4ddb9dbb5aef9ba2, + 0x306430fa89d1e30a, 0x36c524282680bef0, 0x9ad0572140eac595, 0x81388541730ed3ca, + 0x599284607e63a320, 0xb17054f5dc39f1db, 0xa0017494131fa68d, 0x8438f43b78f5607c, + 0x95671dc71eb2d95a, 0x984865d97dc93cdf, 0x72f88b417b192b32, 0x5b912b480b982393, + 0xfce040e21ca55c33, 0xab6f10b872047a34, 0x43f589a2592ab80a, 0x9264ac8f97590f12, + 0xec44df1abadf2712, 0x6b80ff17d90f3dd9, 0x138d0c147946cc5c, 0xbdf858ef996cddc9, + 0x3f2f7f3811a4468f, 0x0bfbd8a915460a49, 0xd2155b5e930a0c15, 0x16a8deb827a1b15c, + 0x386a8078861228bb, 0xf969ccef8ae31064, 0xd4268ac23398213a, 0xf5ca6571b5ba306f, + 0x5c4e46c6e4873662, 0x2d6e3a54a2e97a8e, 0x7871bf3fa82e4677, 0x6ccf55fd51d27779, + 0x9101056d3018cf94, 0x0ecb1b58431ead27, 0x57240d7cad2abeac, 0xe311e77a16bfc4cf, + 0x3881910ed7de30ed, 0xcf3c4a226111418a, 0x83d9eeed2cb367f2, 0xcfa71e64af69ecea, + 0xd0287a51b44632a2, 0x85a4a266db33c8ab, 0x40216ed10dcaa137, 0x3a4eff89f90bd880, + 0x79a279de0bea72dd, 0xa6428b200ea515f7, 0xdba42e51081cb40a, 0x5d9054b9d413c536, + 0x388989d5cb47917a, 0x7c658a06055b1956, 0x8c6d5283990b8605, 0xd9a8060f12b6aeac, + 0xb0f2872d38c0bfad, 0x8e6f680d01c817cc, 0x4eb0f3eb37f1f35b, 0x5eaba40975eaf6c5, + 0x924cce1a72157b76, 0x43333f09ca6fbc3c, 0x8fd90c3acf4ea4bd, 0x51b5c74a6d522b6d, + 0x3199666f7304b16d, 0x486801ffb471b6e4, 0x0309e4180b375750, 0x5818a3e192b6e8da, + 0x23d0d3d6a6533245, 0x65a9785b77cc1dad, 0xd7d3da1059a9e09f, 0x7c0cb95463de4933, + 0xfcc4bbeba9ef2e64, 0xacc9b3747bef80c8, 0x91181da581d35a64, 0x1e48a1c42fb5f0a1, + 0x4228fc1ca178598d, 0x3a591a8e915da1a2, 0x344a3737275d25ab, 0x96689e13e0760278, + 0x06c26ecc4c97412e, 0xbbb5728183665b4e, 0xdbb7708c08effea6, 0xd1114a66b4185674, + 0xca4dfbc08b39b9f4, 0xf207bc96b40a9c13, 0xb184c8725f7f5b41, 0xbc6401524c7eb3f6, + 0x682dcd9ce36cf20b, 0xceac96bd3ed88b12, 0x015469f41f8d602b, 0x98c7a7e74459d421, + 0x37767be63030817d, 0xe4291d84f86ae3a5, 0xf2a4a22e323e55c2, 0x7c842d953bd38911, + 0x2841414a33c27393, 0x72d07a561a685fc5, 0x494783d68e30ceae, 0xdc58d9589104349c, + 0x296b5a7e240c1970, 0x1a93083f79534bf9, 0x766b9784fecda8ec, 0x1c512440b2bbac11, + 0xdd4b2df21d13f31b, 0x6e18149022b22c44, 0xca6b7937b7493478, 0x30391aa6c1b7437e, + 0x69b3e0cd8b3e0f68, 0x1ec280fc0eecf43d, 0x966f9bb34fcfe237, 0xd6bdd94aa249a0b3, + 0x4092088842f3ac99, 0xe3ecc9acae294025, 0x5bee2a0bc7fa0105, 0xc3615fcd71c08a10, + 0xd892e421a97d2bfe, 0xfadd8fb71f27510f, 0x67795f6db4b4355d, 0x402c9b3764f2feca, + 0x95cc76beef54455f, 0x8d7a14304ae208eb, 0xce81941ca5abbbc8, 0xfe571f6d3a3e715c, + 0x577353c3145840a3, 0x9277cb2f9c563b2f, 0x82e913fc88da4d23, 0x6c35b3688ddd30e2, + 0xfdaaf702046e057b, 0x34a5aec17dbf58bd, 0xefa12a78c1577177, 0xe7fb8cbc58b75a90, + 0x30de2f053f17c411, 0xcba1cf8cd568c856, 0xec2225771b9b9a66, 0xd1b0740a6e8c9962, + 0xe968d62b39c33a94, 0x2e860c2e752d0ae9, 0xe20b336e84c6657f, 0x12c2b5641a6afba4, + 0x7107f1b48f664c72, 0x53b8c8d4757803be, 0x942338c07a4cdefc, 0xee51af29af3a2b1f, + 0x6fb07d2c46a28941, 0xb3c22ada0fa6d123, 0x9da280eb103340cc, 0xb5fef6f2f1c9b7eb, + 0x71c947b678343e0b, 0x18ea992c5d3eb871, 0x313dfc4d8bea3313, 0x1bc5ffcb0090251d, + 0xa961c4452d1dcb71, 0xb1d123c52db37183, 0x196b6f1b4b39e1fe, 0x7ee3b00d208e9f69, + 0x65ed143b7234c8b4, 0xff30230550eb65cb, 0xc4e8de83f64fde99, 0x7f5bb3dfe5fbf92e, + 0x59b73583a5c0f665, 0xd70866ac91ff1cd3, 0xcc3dd1169f7b1f9c, 0x25f51ac247c2b225, + 0xf048dafb6271fd48, 0xec7899fb6ca75dcf, 0x93e3bfc7ac0edbfc, 0xf7dd0b07ef3f5b1f, + 0x81ce8aa5f438915d, 0x688e93ca31282cbb, 0x95c48ae1f2a00226, 0xd2d4bf5c437b4a5b, + 0xdd0c94f0044df901, 0x1e2f50a512a82ddc, 0x5697942f4803adc1, 0x31a944b3e8cdaa52, + 0xec8a74383680cdb1, 0xd2d24c9b34d49d65, 0x78f909eb185c1379, 0x15abf0ad46e065ab, + 0xe33cbca8b2f27747, 0x6fc28650078d57da, 0x1ed7d995572410ea, 0x59b0d11327301079, + 0xe92d296089e739aa, 0x4eb8637d6ae414ca, 0x7e1b3244e5a19d44, 0x44afe2f0a4c09dac, + 0xb6d2359c23e71cbe, 0xfc8ca2a6fe9d4fc7, 0x5400eb9a2543036f, 0xd20d7b9bd49fb670, + 0x8a80e16d8708b973, 0x1a9e476c68f4dd89, 0x8613d15cd2a271ca, 0x84b33c2dcdcd03b8, + 0x095c8a49654e0005, 0xe1c4877cfc2c3678, 0x575f5945610b798d, 0xe7ea478b6c34aa16, + 0x566dd8202d8f340e, 0x9704f735b9c3a64d, 0xf574ded4c8b60bc9, 0x1e55a3068f0e8b9a, + 0x6bb65cdcd62f3b2a, 0x2afca05a5f6bacf4, 0x5655970eb3b34c61, 0x2dda72cdac000457, + 0xd8abc54c07566f67, 0x39f4e4c899323fe9, 0xe6da1b9879aaacb3, 0x4f911c56e61e746e, + 0xb4ab4829d854f6ba, 0xade133209888d74c, 0xf049730717e84e23, 0xe2105867e69295d5, + 0x4d619257d2db28df, 0x549a6f8646b83818, 0xa5568977fdfdfc5d, 0x421dbffc9e3d38e4, + 0x139e7474d3cda417, 0xab644ee10e3b03b8, 0xab6d924a4cf66915, 0x0ba87ac05971d7ea, + 0x6766061027100721, 0x888a4d27842894d0, 0x89faeb50c0304e1e, 0x7a8384e1102c9c16, + 0x0681d0be7256ddbf, 0x8f95989ebd25cf8c, 0x9162107dbc58f3cb, 0x9f9c9f43e242e3fc, + 0x61a65cb1c14e3a32, 0xcdeb9b5d8bcefde2, 0x7baf2fc411ca5d2e, 0x95e0b2ba6c60af12, + 0x13871bee84a09667, 0xc513cf9e3122d9e5, 0x443b7755126e6d81, 0x47c55e76275ce0e2, + 0xc2532851c947ead5, 0xb42880597af094a5, 0x9e910ead5794f90c, 0x9c37e826e5a9bf46, + 0x323bca9df03743f3, 0x9367a0cc4496bdd3, 0xe79595a9f66cf485, 0xe8e7f7f2e8136a32, + 0xa02b7774600cb39a, 0xc848bf11e455bb0f, 0x4eb247d1955d7285, 0x62391861c9b997a4, + 0xd6e410dc5bbaea78, 0xfbebd415d173b1a6, 0x69780669ebb04711, 0xe8fd67598cfd94e3, + 0x1a51282269cd2012, 0xb627f55fba10fab4, 0x33ec0d96f74f8fb3, 0x7b34ef95636a933c, + 0x0613997a7940836b, 0x8747f93575ecd08b, 0xb7b6a468727aeed0, 0xd5ad2044c756a707, + 0x5b6b5552e2e50bc5, 0x1fa1ca40857d52a8, 0x32594c7a0f80ea46, 0xdf5b99af45ccad05, + 0x82ef5b989f91033e, 0xdb09b55dfc8653ab, 0x1cc13fe83e85d86f, 0xbc9d8b07f5e870d8, + 0x67c244de80b80226, 0xaabb7ccd4dd72cfa, 0x4ea108ec908ce18b, 0x971ea1ba0923a18f, + 0x6a6e8dfce54aeeb6, 0x9de10f64dae56514, 0x4abc0ee92ca798cd, 0x15f4cd025ae0432b, + 0xb9309ccd00b7b46a, 0x4918b3da432d686c, 0x5213ed869b8c8e28, 0x1f26651b2ed59c81, + 0xf87358871cacd263, 0xd2a542f9d6349ff2, 0x4d9e6c06181e8c91, 0x55d6821d9c2fda30, + 0x13564a56f6f24410, 0x6b08fd3d98df1e9b, 0xf404100b72799fc2, 0xb4c573429072e967, + 0x2363ad90e162314e, 0xe6028b199010f2ca, 0xe1e2f78fa29a4199, 0x55946c1a97f5c6c2, + 0x4dee6e96fff0267f, 0x3a9740e2bd7dd152, 0xb227b96a7038ac40, 0x59f5635c603e7a7f, + 0xee8d4f8742cd7c1d, 0xc5b1d0fa16e4205a, 0x4431a690e1cd3ead, 0x7d0493b3bf08d300, + 0xe539a6a09316482c, 0xb62effa68ccaeef2, 0xf72ddfaa61ff2ff1, 0x3bba9df5aab9cd06, + 0x598978f191d8b434, 0xa8b25c953c573143, 0xb8b9c8e2bbb96324, 0x3aafada00a747ecf, + 0x1b00fcb434038db4, 0x65a67483e752e368, 0x4edfe141004ca3f2, 0xe8d56deedc854b14, + 0x9b856bf78d099cbc, 0xb3bb7dcfc30fa492, 0x759958e3cbe4a347, 0xea7fd813830efd2a, + 0x695299836ebef661, 0x357d8355852fdf49, 0x0609642eabe12212, 0x1cba0e6948b4b37a, + 0xee65fdb9653cfcd1, 0x5a7e2afd709be9ab, 0xff768f5e03c00c32, 0x76c64d874ff38db9, + 0xd862c3b43c625e71, 0xa6bef207e52bf16e, 0x205c4964bb8b4dcb, 0xcb0f815b4281afa4, + 0x7319aa13cd0bc59a, 0x78ba6bbfb6f31928, 0x9714b16b5cc6a559, 0xec2c5d283d41eecf, + 0x904fc9b8a3609744, 0xca7b8bd21efdfc5f, 0xb9a71a6648de8ae0, 0x37fe90a0b68e594f, + 0xfe54cc1194adffcf, 0x6b971248c56b966e, 0x0d3dd551c9cddf5b, 0x475eb1dfc6edd9c8, + 0x72191586f807d3e2, 0x100c04d4fdcab2f3, 0xcf5982e4db3dbfb7, 0x72cb36cbede8a3e6, + 0xaaae782366a6df77, 0x9c0f7404fab86da4, 0xbaf3e4ffd697d620, 0x1ea1319d0b5ae315, + 0xedead1882ee55bc8, 0xac886f76095e37a0, 0x3c9fa4e34df74a87, 0x2b0ced3ceb88d596, + 0xd17aeddc7e2b06fb, 0xee80027d862ad1ca, 0x9e4e9e096a4c6e6e, 0x7feb261cb7e906ee, + 0xcfb4fd8d157c9c37, 0x4bbf5f01c169fa45, 0xa227db71193629f6, 0xf4278fc8ef940025, + 0xa0bbc33cfecdd276, 0x9eef97c7513fac4b, 0x6a5160539eea48ff, 0x334b8c7829f5cc9c, + 0xa09cd479d39f6624, 0xf699ad13403afeea, 0x6c48781d2ad5d691, 0x9255296ae9e507d2, + 0xdfaf7175b5c294f1, 0x93a1a8969963a917, 0x045535d13e98d652, 0xcccc28b180a80535, + 0x4b2dbcf12f850813, 0xf949d3c4dc708766, 0x6634b59e43b0f3a9, 0x61ae157f8eb9c45f, + 0x88a15f26815cac28, 0x62e28894b1ebe16d, 0xc1f0591b965f815a, 0xa1b82b79cbb5a95b, + 0xdd49a88e258525ad, 0x20742cadf95abd6f, 0x396091e873bb2a41, 0xba850dcf89c6d6ca, + 0x27ba660067976236, 0x2d87dac3fe8e3a4b, 0xd3ed4bb4daab95c5, 0x2ccd903d96fcae74, + 0xb2aa2518db87a7cd, 0xb7c1fc4715107ed0, 0x3cbf7c46aaa59d91, 0x399e42b18cfc9004, + 0x5b0168830cadb5d1, 0x4ef4c13df5499a07, 0x6438f49a8a794d3b, 0x23f278286504b223, + 0xeebdf54d0b9c84cb, 0x54d227d196ad4de0, 0x99d18c97be02f426, 0xbf0204952a18da33, + 0x6b9c24054c542958, 0xfa4931f9a8360643, 0x6cbaedb0393aee4b, 0xb44424a94a20e589, + 0x239b638bd234d58b, 0x5bd6d4ca4294f078, 0x7379e2fbedc1dde1, 0x265fb61573a8e1da, + 0xa95167eb27526360, 0x46b3237f729309df, 0xe3df48631b693084, 0xdb5bfde8b4bfae5b, + 0x23a6059b2b8d16ee, 0xf26486a658a03c0e, 0x64ce96378d313981, 0xe0d4755cf099e1da, + 0xfcd556652e4eba0c, 0xbc87e55b0ae8e5a8, 0x5377ade7a2bf6946, 0x777ef8251035b6ab, + 0x2bc471672f1da3b8, 0x337d13210adb5175, 0xff1c3c885fc99cd2, 0x5b0a7c65baf42d71, + 0x87e2d46431daca8e, 0x5b2813a3d8956acd, 0x0a70d69d91545646, 0xfefefb24bd3fb6f7, + 0xdff1d6280b080d9f, 0x8e42779b7938507d, 0xd97f149fb05140d0, 0x9c1edac5345184f1, + 0x47208009f08f0158, 0x785b6ab75dfb3abb, 0x92b872ba76f0e709, 0x40eb3233b005962c, + 0xc941ddc854aed1ac, 0xc94269a2381d9960, 0x9d58a7017d399f4c, 0x4ce10cf998d7ca78, + 0xb5f363f9aa82ba14, 0xd006ca37a2e8187d, 0x4bbedb0718201ce4, 0x0e56431df371a6d9, + 0x12cb0af2c3e39967, 0x1b28f0c321079617, 0xc4555ea30c9ec07e, 0xe78e5e6f3ee8e8a9, + 0xa2012c734ec96c41, 0x5a6db63f8c0fe25d, 0x2be4c45cb8f49a48, 0xa3f73761a93c2c22, + 0x4b9236b12e234d06, 0x2434f626e37a4ee5, 0x72b3c39452249313, 0x34df52c2cbe0473f, + 0x0da8e50e5ce318f8, 0xc08f5626106c9898, 0xda75e029a89f3074, 0x22132b1242442740, + 0x93252b144ccad48b, 0xdf375ebc1c3c5a46, 0x9050ad57212206aa, 0xe955e4728140ce1b, + 0x3ca172c073005cde, 0x276db6cd77d84ccb, 0xd3102e58f319a24b, 0xf14ff494ba8f62df, + 0xdfbdae8d076f0b40, 0x3632d1fcbdb9df1c, 0x2fa334e160e911b1, 0xc00c22ee2ecca96c, + 0x359c51489a63686e, 0xb7be9faa04f68f36, 0x045baf2ecf2b5219, 0xc89f9117c1edb726, + 0x9980e7cc490e3460, 0x9d583c192423ece7, 0xc4cb452fbb290438, 0x320d12d474ff5af2, + 0x1b6d16f068a309c7, 0x8d9cd5f266520731, 0xcd15e057eef65045, 0x4972e1bc94622a87, + 0x147f31b0d67a6374, 0xe4a98c59c80c3fb3, 0x817d6ec99c6d017c, 0x4eddfc12c918e59b, + 0xc821c1cca40da27c, 0xadc124ae549dfb7d, 0x754c880c6e36e4c6, 0x6df0ceae7a6623f8, + 0x39eac06111be893d, 0x63053090fb23d45c, 0x945f37fe9d2b3dba, 0x4e6d4a186a4a021b, + 0x2c29cd2f941fd695, 0x3845a49612c3f6c1, 0x8ce30f2d46f4abfd, 0x72279b205bd83dee, + 0x3b2d65df04701257, 0x8bcc9e109aba7a8e, 0x979b3da62e9bdd7a, 0xa7884c8f3de1d90a, + 0x992ec05c4ce73824, 0xcdffd7f22b03e951, 0x59ceca0bab0a7276, 0x554197cc221e8b69, + 0xb2a7dd6af58123bb, 0x1eaca5b58b81a3fb, 0x1920cca62746013f, 0x9e97ad3b49991bb9, + 0x54b7a5b046fa43b2, 0xafa18b8f535e6ff5, 0x4a6d985e1d6e3626, 0x42b09720a8fdc7a2, + 0xac40492eb2642eba, 0x69f8e57e562aca23, 0xa03b7863f26d04c9, 0x413d8bda24cfd3f8, + 0x3341569c1052989c, 0xe3fea2dfda634ee4, 0x7c41ef8524632677, 0xa07c6f80c5f4b74f, + 0x35299c485df5cb5d, 0x29154b40988b4e79, 0x8bb9a8c00d7880a8, 0x85ec0b5c253db0dc, + 0x97026cccc239b2b3, 0x33b71c4be2615e25, 0x7ec91debeaf4a487, 0x726d405f12f35cc4, + 0x4c47706dd9b3ef31, 0xc3fe0db91dea86f5, 0x3700721fd69d90b6, 0xb056a9cd2b271639, + 0x6f1d462a3b5b68c4, 0x78c58fa3aa2f9db3, 0x4f876b8a8c267787, 0xd2d38183c3bf177e, + 0x666028816ea29066, 0xd28e9ee135572af4, 0xd3c48259d2c2aa2c, 0x67f8dc6a217459ef, + 0x18bb970f89059601, 0x8c2640cf4ee6cbaf, 0xc63935ecee4ea3cd, 0xbfc70aa25ade5843, + 0x2acebb4189db05bc, 0xac2e08bd79f2f6c3, 0x68d9948c7044e59f, 0x0d2af72628aeba8d, + 0xa444bfcf703ddd2b, 0x927dcc5a2e117877, 0xcdb292b9dc8012e7, 0x60487702844ae092, + 0xbe1b6df255829fb3, 0x6161c36c92773523, 0x111db80eb7b6d60e, 0xb3afa170ddd84e05, + 0x04953b4cd5845fa8, 0x156d810a427f8a19, 0xed3ce37735965ffa, 0x069a462de8f654e2, + 0xafa654b443f8b081, 0x16666166080bfb17, 0x0d4eebd7d45eac39, 0x9022b33c853a256e, + 0x031a5ddd4a0749c7, 0x90f8ddfe03dea0be, 0x30744723fd7491c9, 0x1497c1b71c3a06c1, + 0x01283becfc4eefae, 0xf6b25d8db65cda59, 0x0e7a10dbdcd1ade5, 0x98841b4acda11a06, + 0x2749512e58b4ef6d, 0xef27a64c97b8f9a3, 0x1a7483f705bada71, 0x2a39820b01aeef50, + 0xaaab549f7d36bd3d, 0x0d554016d019a036, 0xe5a29cdfe2f47af8, 0x4941042580e2a95a, + 0x7526aa5ede922c73, 0xd083c7c8c0d8372c, 0x3d47910e571b8861, 0xd95c0eb613accc2c, + 0xfec268d8f9605d94, 0xb8d5eab93f7905fd, 0x1a75d14921b9ffb9, 0x7cea4aa15221be88, + 0xca0e5749d48277d0, 0xdfdfdbf59cf29ef7, 0x95189b60d07d1474, 0xf8865d10d3baccfc, + 0x9cc1cbb229f6c8e2, 0x9595d4ba24880826, 0x34e75ca88564ad4c, 0x9113900b38c26dd4, + 0xe81845cd548dfd33, 0x8772335e8f19e877, 0x27c92c2fb6669b12, 0xc5f7d7ca22ef476b, + 0x44a3719f36a059ff, 0x26610e49e9a741b8, 0x8eb0eb6a8ba6e542, 0xc137c8fa00b8145c, + 0xccf1f207d4331d23, 0x8706c85eb7146072, 0xaba44ced38bb1607, 0x7864451b2b1815cf, + 0x89d8983fa1f85907, 0xda0843cd1e212ad0, 0x00df8b62400214ab, 0xf9b16f63293e6774, + 0xfaf91800764e36cd, 0x6381d1f3802b0b9c, 0x00afef107a37baf3, 0x2286cf55119b331d, + 0x3e012d6033ba1063, 0x5d5fa60fabbe905a, 0x7825ee253157fbf8, 0x902ea09371b6e2b9, + 0x91b0411e30f3512e, 0xe78aa9c1b8f3d771, 0xa2688331f3b6ec17, 0x8440a9c231ddff04, + 0xed5c44e872e4696a, 0xb5295b037ec03f94, 0xf87792e544223823, 0xe9e9391b23826bc0, + 0x9bfcff10e5abed2e, 0x8efe784608de1bd8, 0x5365f61fa65568b5, 0x52b2054450063eee, + 0xdcbf463c78564296, 0xc2989570f55e8a53, 0x7e164e017b693f2f, 0xdde91125fd199861, + 0x2a169a7b33adc793, 0x9f4e17192850c3ea, 0x19c01991a707f3b0, 0x9c4e5092e8da0cec, + 0x3100e654d7d4a249, 0xda10dcc1374b8044, 0x9b7cc6aa9c377cda, 0x97eff108c6bd796a, + 0x470314e8d8b0f58c, 0xb23a8010eab286a4, 0xebd3adcc33105292, 0xb99c683797b076b3, + 0x63e7e0e675123a07, 0x517fef9b5537e714, 0x7e8957b0640f4547, 0x5c94e0cc35eacf7d, + 0x813110af9bb46694, 0x7af6126991893f78, 0x6fe50a35222607e7, 0x3dc8e5ee6ad06e34, + 0xfdf9411cc087c4ec, 0xe961afd929aa5316, 0x6ee5bfc05fc85cde, 0x80b78e685fe58fe2, + 0x2750e6b2e564b34b, 0xe54c5db1c9f00a11, 0xb7c92ef053a746f6, 0x8460c0b8047fadc5, + 0x3796f74d054b9020, 0x8ed62ca604f8ee3a, 0xdde74f43dc569e41, 0x1224e3fbc2f281a6, + 0x5e6550e648308f35, 0xbe224a6d14f817d9, 0x8c66d9c4b530758b, 0x3fec9a2d7d94e25e, + 0x14fa9d602e49a830, 0xda6536f360c3c933, 0x35b0fa2792798d15, 0xbf946fe0a1583d45, + 0xcb79ad96d674f0dd, 0x661eb3690f104f75, 0xa2f11f19ada9e561, 0xfe0e2c5ad05472ba, + 0xa978f5671b4c59ab, 0x8b8599584f359911, 0x5b5803331ba72a7f, 0x67c5a9fc6846ad44, + 0x55cf92c9b3598ac2, 0x2fb4148956f3b54d, 0x8c247989debde614, 0x7b40299c2cf4334c, + 0x680e91a0c779746e, 0x08e936fae53ee1a1, 0x8877287b86405689, 0xe8daf80895108c6b, + 0xd0c19835bd036162, 0x51141c4dc658bca7, 0x8913710d56e6b819, 0x6cb02a87e51da8c8, + 0x23e17b406a1290f3, 0x386cd4f648409b85, 0x8dcfbcbbd38d713d, 0x78f847960ada5253, + 0x3faaea970310df87, 0x2f1e84b2f2b4c8b7, 0x0eafeb4ad016c8e3, 0xdc881ff9f98a1cd9, + 0xefaab6bfbf8fa49d, 0x4cc4c92169fbcb43, 0x454014b534738f1a, 0x63a74e9c50989367, + 0x1a173a3dfbe7a4e5, 0x86ef30562fe559ac, 0xa638aaaeadba274e, 0xfe5dfc36d3e4cbf1, + 0x715b1369228faf13, 0xe856be2d0de525a7, 0xb7ea0284f33e7841, 0xf7963585639da36d, + 0x31db99a4ff6f1d9b, 0x665860017bd8a15a, 0xab655caf17544756, 0x03f9212052600ae4, + 0xbb4ddf712b253186, 0x77c4fbc3efb13d1c, 0xbf368924070fde5e, 0x796aee4ef778a395, + 0x0971eb60ed054b7f, 0xc671c3c60cdd4bee, 0x8c08840a316131be, 0xf5c13ddf06062f8f, + 0x8df18a849f9369ae, 0x29ad21b365b01dea, 0x36ac5ce99019e2a1, 0x3a3bb68a08bc6981, + 0x135a2bc2075de743, 0x0de6a6ac5fa70270, 0x08f4fbb4b8418ac1, 0xe092ced6d356925a, + 0x772ed44d9a6eab36, 0x2d857ea9d439ca06, 0xbf2dcbf2d1df94b3, 0xaaeee055ae75cf95, + 0xf62a302dfb56f24b, 0x75c5bec0923a7780, 0xd1f6a6f26f21a31d, 0xe868605d120636d3, + 0x7c12fb15b7220a0d, 0xfda84930d2dfebee, 0x6f83c02670970162, 0x793eac7e9f363558, + 0x901390babccbb454, 0x20bffc51851def23, 0x9527490f16494961, 0xb2012ffe8191c0a4, + 0xc707a8b31453e67c, 0x374e0368c43e166e, 0x8e9a37064cd0ecb7, 0x5fa8ef1c5783eebb, + 0x16b4d54ffd14ae23, 0xbbfda4b197b382df, 0x6f13e2da174ec49d, 0xee772bfa125c3189, + 0x3ca6f2d30e8c8146, 0x3dd4f96ba1c42ca4, 0xf7ed939e78391929, 0xa9d81922c673f321, + 0x48f6bee82965b2b3, 0xca2b71e056e62128, 0x42395b5f148b7905, 0xa62eae214e9a1d3e, + 0x90131a03e4a9f674, 0x190cb7d67e54fde0, 0x18c699d5a63f59a3, 0xa4faca83614d5550, + 0x5f6eef67f9ffdee2, 0xe4e457ff3d2b285d, 0xc047f1e7fba34515, 0x14370ed3b08e85d5, + 0xd8f69603f76a6f09, 0x564b702469c91d58, 0xc82a7f8cbce2ee55, 0xa255ae297e115b1f, + 0xce60738027e3eb96, 0xda416beffa2b9f9a, 0xc4c89c08801ebcb4, 0x9d3694aa40026cc5, + 0xc1c5b7dd8ae1690b, 0x59fa23e2892c46e9, 0xf02e6d01f4e00197, 0x4059e93278269334, + 0xcd61c1ee7dcc9fbd, 0x02ebb082c19ea031, 0xf9a418652ea070c7, 0xc8282f5fa3aeecf4, + 0xf83d1529021eef9b, 0x4580daef02ca20aa, 0x0233a9451f8c9f9e, 0x28107ad50409c8c0, + 0x0ed145f4e0319521, 0x529c135f4894247d, 0x0091ff02e142a10c, 0xb79aaf4c4855b7c1, + 0xe54b9f4cde954c02, 0x0295c469e37ebc46, 0x21f1c7056ed6b4a1, 0x4a51e84d34d5f031, + 0x0cb45eef82fbce13, 0x9766f8f46ea85ac6, 0x29c47696b2d03d47, 0x1305069cd4d7154b, + 0x899c5a533eb9a969, 0x062155c8548c5e58, 0x7b44c801621c375b, 0x6b72e3ce3516a236, + 0xf5da6b0dc95ee5e8, 0xea412791ac16fe01, 0x2cffd6b41bfbce69, 0x754a5257d5f2959e, + 0x812c51b554bb5891, 0x1589c0a360e2afca, 0x388228e7c284e90b, 0x944481a3bbac0331, + 0xb882241941c8062a, 0xd54e8baf4c72c3c9, 0x0c03a4b532e9a5b4, 0xd07b394027c1ac7a, + 0xb9f9857465df5c43, 0xbfdc439fcaa733a5, 0x00889ba3e98c01ea, 0xedece1f087061699, + 0xb81ebf8d4f961483, 0xbce411cf673d9d04, 0x76dc8b9981c20b40, 0xd26b9084b3305290, + 0x7c71da491805787b, 0x9b40856ca294e56d, 0x3f332e97225b020a, 0x6c2af72c8bda1718, + 0x51ee043970d68c9e, 0xcf69f93018e32e55, 0x91f243d48ae302bf, 0x6409f031e0519398, + 0xbd1fd105e0510cd6, 0x85e9d81f2e188fd3, 0x6b7c90e0aea463fa, 0x1541d0bbe69582c2, + 0x2c52dc4271c14e78, 0xf6943cf6ea4677ff, 0x5a58a9d8a9068c56, 0x3b21caa165e3521e, + 0x456c8b84896684d3, 0x3b4322388cdc72e1, 0xc94ce2664a2cb632, 0xe8c26b05a7bb7eb7, + 0x1c9d33b830e3a50d, 0x20390236af20b4b6, 0x4b604a89ac5f8e30, 0xa181c958d24b3890, + 0x1385d32e323744ba, 0x7577bc7072a560a7, 0x37e35a74d2326010, 0x468111dd7791c9ad, + 0xdac7402c34267857, 0xb72d12e0f290cd9b, 0x28618d52aca16823, 0x306eb3d980fee69c, + 0xef95d0886c479189, 0x3de5a56421aba09d, 0xc697b7d967cf5b54, 0x4f7e5aeae01bfe71, + 0x2ee5808cb4819b87, 0x19acabf7778021f4, 0x2624d7853746c06d, 0xc41f3a5b4a1bca94, + 0x7fe94f5d12053cdb, 0xd77c0c073ead1a80, 0xad89dec69e090bb9, 0x517ab3742902ae0c, + 0xc5143414b516cbf5, 0xad5800b1b6800acc, 0x48c44439d5f67184, 0x2b0c74b3de95ffb0, + 0xb2ceedc9a6f928e9, 0x27b6e56f05821fad, 0x2145bbf190f94e8d, 0x534bec5098366bd5, + 0x02c167c2194a6786, 0x3440dfcdb724b86e, 0xf5b3ef49089859ac, 0x4a16ec9907637947, + 0x55dccf60c580c4eb, 0x0fc4e0f5fe828680, 0xcbdc05ef0a086fa5, 0x69b1c6b943224200, + 0x10f32a975fa6a5a4, 0x6b57ef8280af169b, 0x42c9ec9b324b19ab, 0x88e1acc19315c2f9, + 0x290c1ea0c28618af, 0x5ee0f6082fc7d5c3, 0xa993988ff40638b8, 0x7d1a5d01d0ee2964, + 0x6f02d7a589eb3578, 0x7a34b9a164eb28c9, 0x3599bf6edc21b5f6, 0x42420084fa399e36, + 0xa55e6e3afb2591aa, 0xbd5cd8fd28d3d989, 0x692e982394e315de, 0x9c711b111f1da811, + 0x8b8a87c8b60797e7, 0x6f1e7b2e3d5d1517, 0x8a3fe3054d83148f, 0xf551a9540f13b3e3, + 0x72e76d96b89a8d4c, 0x7e3cc3f4c60385fc, 0x39c14978c7acc3b0, 0x0af55aae5bd863f7, + 0xaa30ef33dba4b3b9, 0x749828315dcafdb4, 0x475b3cfbe92cc03e, 0x67e72d4e823879a8, + 0xc9ee6f2c391929e7, 0xe18798a7d3c5aba8, 0xe807406fb30b67c6, 0xa61395aa639377d6, + 0xc29a73a2e8ab5af4, 0x5aaa55fccaf9d6c2, 0x967f04f118ad59d4, 0x17e31a7b0b58ad39, + 0x7cadef89e2b22c08, 0x0b276527a22d022c, 0xe11abc1bc3172ef7, 0x057b13c90951fa9e, + 0x70567928f3f80acf, 0x827dcf38b17df714, 0x2e64548f4b4c73fc, 0xaca68bbddd78e838, + 0xd5d5988bc8dc5e91, 0x042d45dc6223f976, 0x662e4de40d33e3ce, 0xdb7459f3c4fd5935, + 0x3110a17d14505d6e, 0x617d1352d87a5b35, 0x7c4685b33b223c27, 0x451e4d7a9152d8b8, + 0x1b65cecf8266a056, 0x5a45f9b0cd470d2b, 0x7d12941567cff145, 0xee1a3030777220c9, + 0x8e713d8beb663932, 0x4c6d8a061646bf2d, 0x9943de3068e54256, 0x5306bd826d06817d, + 0x150391330aef4eee, 0x911cddcaee00ebd8, 0x0635e0d0750de675, 0x0adb29d4c80b250a, + 0xbaa91b7bec14b6a3, 0x8bb251c4d626fdcf, 0xf3d93aa25b681937, 0xacee38b966ca8b8d, + 0x983afcf415e75dd0, 0xae57978afe3b7e84, 0x4fcea029c8c9e70c, 0x529baf14b98df6c4, + 0xba514be5eb3a23ca, 0xa7e0a13409099a78, 0xff6aebbbed579b2d, 0x0b144185e3d7c1b0, + 0xf11d74de9b1744f0, 0xa3e72be7187b1f46, 0x7504be394c45d09d, 0x83a2c8cc8a987a73, + 0x21c88b62d048776e, 0xadbde7f160d8c96d, 0x1dc8c52612577f79, 0xfbe9d2063442f7de, + 0xf5c473ec4a3fe6d5, 0xf31c5744e4170c19, 0xd4aac28d7905d189, 0xed45fcdc435fb588, + 0x97ab84c6236dc214, 0x5baf333780b21044, 0xfab05aa501a125c2, 0xecb022dc9ea08637, + 0xc7850a4da97998eb, 0x4c4f746292b87a75, 0xe68d9b8cb70327b3, 0x4f29c30fa4cd9080, + 0xd5f1e14b34fb1cda, 0xfd9ed31664a562df, 0xdacac110bc98391a, 0xbaa5b57e447a4a5f, + 0xa15730a1af8b9e30, 0xe5a655fba44d3c6c, 0x38529cec7f7c5e53, 0x83f47e73d444f65c, + 0x66ac5328bbc88282, 0x3e08698fa6f524a4, 0x90ec419fc541cf92, 0xec025eba8e545284, + 0x89ea3c5ac193e861, 0xf3e4e77ad74c5d24, 0x8a45df9502f4003f, 0x3cb8ca44c1701b26, + 0x2f7992a09552b596, 0xedd0c10d9ed880e9, 0x38b31f377d894555, 0xf298863b648a67b7, + 0xc1b870a7881b4f3e, 0x002674622a007ba5, 0x8092ad3244ed8148, 0x49ee2f6041b60776, + 0x632cf22888cc6dfc, 0xdba2959c64c16441, 0xc18b9a7b7be100f1, 0x6afe9be632112731, + 0xd6249417887b40a9, 0x0466b36f06b5a76b, 0xe7f0217708de6e0d, 0x166766578aa6bbc5, + 0xf7ab61b7a320b0e4, 0x07f942adbec4c7c0, 0xe7d1baa76a6c79cf, 0x328f25d5461bfbfc, + 0xb0e7869b3ecc4a2f, 0xf0947671eccac059, 0x1027a538087dea64, 0x1ba54441964d0a18, + 0x112db5f8d0e525cb, 0x2dc74cd3dd390033, 0xa12ae55e476839e8, 0x7132edf4304f89a5, + 0x6f00f4f6bc1c532b, 0x9af5b63e28331f5d, 0x3360d6a27304643d, 0x5941fc15dc93e55a, + 0x47a9241412672474, 0x0c4b9803622f4504, 0x0b5daa66678758c6, 0xf22c6cd02ed7ae9b, + 0x6c514a6331f9ad4e, 0xa3431ebc50ab68a1, 0x6f07ea6161fce9bd, 0x199c974715836554, + 0x04f3d15744f3cfbf, 0xcfc9b0c3824b76ef, 0x7c56af924c58a9ea, 0xba495e117970487d, + 0x25a7818abca760f2, 0x9a62797f2110d02a, 0x92646e1554e85c87, 0x6f9cb81486614150, + 0x468a07af46392cf5, 0xa3542cd002bef2c3, 0x54c5626c350ae580, 0xad4efc1fcfb98fe0, + 0x61a4801272ea40ed, 0x5837a739b88ec779, 0x53a4ae9741a27cd3, 0x1d65fce509baff3e, + 0x5147c4fa5aeb7abb, 0x0b91f3f1f6e4435a, 0xbc3100b284051308, 0x1ec2364d5f04bbce, + 0x4c1b4e17cf442a67, 0xacef09e475c7076c, 0xb42f7b67a91451a2, 0xb0b32efc85e68d40, + 0x5cd3c6921bd36f6e, 0x78c6c2d211fe14d7, 0x89663735f0fbb4f6, 0xe127e2a54c54c43f, + 0x111851c5e8b91353, 0xe19b80e61db2fbe6, 0x6ee301c0dab99f51, 0x90131120af1ea480, + 0xd0693289c2114cf4, 0x3ceaf348e2f52531, 0x01bb1ceb5fa67725, 0xfd6bf6946c05eace, + 0xdd8a988a014454b8, 0x0217f301a694921c, 0x677a83e3244ed994, 0x0a16f3ada3c3fe64, + 0xf273ac5541ed53fc, 0x99db037268853a76, 0xada181f2c03fdf1e, 0x15ef5e2b886dd6d4, + 0x19c56f4bdc451ded, 0x34d628483964ad21, 0x6e7f6f99484f1859, 0x3beb6c144845d786, + 0xaa7e9cdf3259b85b, 0x9e4d55291089acb5, 0xb3ce99d00c83d5f5, 0x3bdcc1d081f7b2f6, + 0x6f14e984708daaf9, 0x15e47d9d55c469d2, 0x1979e42fea2e3ca8, 0xbf9c6764d98bd4d2, + 0xdd767e710fb7d72f, 0xfb2a35a931454177, 0xcce476626a9fab9c, 0x8da6e86c9c774840, + 0x71a7f61f1656315c, 0x283fda98d127c7c0, 0x54d455e56378ea1d, 0x4614d2efcb6a15d6, + 0x59d4ea4c7b66027c, 0xfa401e892b8b3eeb, 0x0212b994aaeb7bce, 0x95e3713db591f828, + 0x7382420743d258f3, 0x69e365f2a41573fc, 0x557a5d8e2556518e, 0x46a1a9c2081a196b, + 0x526c8ef17421e4d6, 0x2978001336b6304f, 0xb055c728ee7d0ddd, 0xb482b8aadee7aecb, + 0x05c52e33c5e77a6f, 0x4a6247890e638a37, 0x255e52ac97b3d039, 0xaae35dfea1c75855, + 0x93552dd3f0fdb4ba, 0xfdcc3971e642120f, 0x91b1eef789b48648, 0x154787ca45dda206, + 0x722182f2639f7f18, 0xe3c3f7d3ef340f80, 0x7984022b21091573, 0xf7592b1149094ae3, + 0xeed6e38050d828ce, 0xebe7883eeb1eeaa5, 0x0588d7a1f8092279, 0x93771b4d3d8753bb, + 0x50e6f57bacf1753e, 0xcb512b90080a388a, 0x2b9aa10d3865578e, 0xd1f8d58cbbbbc8dc, + 0x0f1280f8121a4b34, 0x1320ddbe6468761e, 0x077475763e80bbf3, 0x3bddb635e1e10fb6, + 0x7ef40a13dc2fbcbb, 0x445a68774f3da827, 0x1a2454abb2b6cbf6, 0x10c01bcb7919d310, + 0x201a20c4f4ca33a5, 0xc35759e4477d5fcb, 0xafc29909aef70ac0, 0xe6b5b973d3bbb3ca, + 0x378102c9200fe5f0, 0x6e13607bea534c2e, 0x3489bea419ca61fd, 0x0a49dd8a953163e7, + 0xecfb6fe7651dcb91, 0x99e44e6d0e2641a8, 0x4cedd2b9dd5a3d3f, 0xbc09992842bf5116, + 0xd7337adbd8b5528e, 0x175813ec91ebdaff, 0x255c853bcb02fcba, 0x18a7e8f2688cebe4, + 0xec643c4e1bdbb99f, 0x416043b43391809e, 0xaa42198b6781ee85, 0x794540f865959da1, + 0x0050a8422f325acd, 0xda319ea82d4bd78d, 0xd02927fb87760e85, 0xbf5a7c04f13b35f4, + 0x4862bfbee6ab8190, 0xd1e459af39a7f4ac, 0x690f801d7dfff662, 0x6b57c814f57774ed, + 0xf1272d6c178150b1, 0x6b3dda4f9dcd3780, 0x488de59a4383b448, 0x0fad58d6016ef5b0, + 0x8f0419619fe5204d, 0x7d869ca214609e96, 0x83276a8178bdb643, 0x5efbd3f2882da912, + 0x024f5e85fc7c2fa2, 0xaa0c6acb744d482e, 0x3b08e30cde85af91, 0x0aa1c6a5f3ec49b7, + 0x1289c3b746490bdd, 0x280b0cfa9af3db3e, 0x0c313d24a7a6a454, 0x6b31f2aa6071f47a, + 0x8ec97f55532f752b, 0x123e614c49147c44, 0x047660c108bd9483, 0xfbc13db0ee398ce5, + 0xfa92467554571c2c, 0xa929cfd749ca4c68, 0x2a231fb294d7766f, 0x7e10fa8fc05ae42d, + 0x855e9e1ef643127e, 0x2aa4bf00bb360a2f, 0xa14b049ba80ade5f, 0xe7eac84ba0aecdfc, + 0xd2ad4a50fab5a98c, 0xc42e1289b7647656, 0xe0bc0c30ce0970cf, 0xcb702c8fb76311c1, + 0x111207795af0dddc, 0xb8cb9ed0cb21792b, 0xb1a41255f269cde1, 0x61bbc3a3c9176ec9, + 0x3e1d0cdd46f3ec84, 0xda74cb1b02d7058f, 0x2f0c7b9660ff64e3, 0xb1148b7899c83449, + 0xf0a44b4326f2efeb, 0xc84a100ffc441418, 0x57632cbc5beef647, 0x94e1a841204e9034, + 0x7f62ab66e60f764a, 0x9c6d14f1b1876d88, 0x49ab70f3525fe230, 0xeecf215953528f18, + 0xda0579aa12bab08d, 0xc34c4f69d74c0f26, 0x033037838762c843, 0xefcdcc077132b157, + 0x913883d318bcf844, 0x6f9b30e1a4bac00c, 0xa7861ade2e441a35, 0x622c5901979efc24, + 0xceb39a59ca37bad5, 0x3570963f05be6fd4, 0x62ad4895e02bf3a3, 0x7eba6f82b82dc832, + 0x95234a1b8fc71c39, 0xb6f09f13565b8a89, 0xdb57430808d951ce, 0xe4a4248118cf6ea3, + 0xc84cc632a2ae7bba, 0x22f475ac2508c468, 0x68cc3d1497393995, 0xe72aa6df700f15e9, + 0x6ac873c2b8bcb1d5, 0x3f6734836ae30a65, 0x37e5f02daeae3d13, 0xd39167dda66565a3, + 0xa153094a12d166cd, 0xe4c7603edda285bd, 0x923cf3f0a5b5ee0a, 0xf9fb2dd192954e48, + 0x306ac270c5b723e0, 0x8606c830122c2958, 0xe7aecac688a53701, 0xbf6dc059943218fd, + 0xa4535b9dd962ff5e, 0x25571849af3f9777, 0x4c9e418f6ca9e2c6, 0x3572d9f3f3f65cca, + 0xc0bbcdbc341a2058, 0xbd7b0453c63dbffc, 0x4f7a9ff3d29166e9, 0xd1de349e5a6b4d75, + 0x5fcb68a64bde964c, 0xc395d181d82b71f2, 0xac00398a33f51378, 0xf4a6337e47bf20f0, + 0xc64cb0b05163d0a9, 0x30bc5d8cee58e70a, 0x12a3ac6e4c40930c, 0x5d48a5fe9a94d7b8, + 0x0f54c0b4ec777fe2, 0x380a23e1f7d7708c, 0x5ad927039604c51f, 0x60d473456a62508c, + 0xe56dc76ca61fd1fe, 0xaa4433ddf04c3580, 0x0b4a5a54ac14ab10, 0x4f1d86d7edfb852d, + 0xa95fe9a70df1aeae, 0x885a5c7b28159a1d, 0x4409daae13a3a78f, 0xaea8705bcc2fd398, + 0xd02e202cd1edce96, 0x919bd3c74de1be9e, 0x1c2d6aa4d55419ba, 0xdf8a9c4a721b162b, + 0x73c3040c0fd1717a, 0x68b2eae14d78b77f, 0x105f8b2555d5bff1, 0xf9b8e9f43e2f7970, + 0x77f0a45d7862aa91, 0x26102398472d8203, 0x83c8f5a302078aeb, 0x4a781ef65e962e8b, + 0x3ce33d2a4b603fe1, 0x72a4b9d499c2e7de, 0xb58dbf4808d242aa, 0x66a8243e268c513b, + 0x12c2c8966fc7890a, 0xb56c2ffaa78f8762, 0x2ae7b38cd0435a50, 0x3d5e4d97ae34f69b, + 0x5fc317613d6bc59d, 0x6bf9af035c90894f, 0xc98ded5cd8befc15, 0x133678cbfcc1ef34, + 0x32cae0f08227a937, 0xaa3140622b9540f0, 0x4ae39fe55c80fa24, 0x9edfe7a36d6320cd, + 0x00ef4cbcb1e07d2c, 0x1295bb6e2c2a59af, 0x0fe5d0db1f1af0fa, 0xf6b309dfd7ebf79d, + 0x3d24f10e338eaa66, 0x4c77759419ae9087, 0x15fa2a1105528d06, 0x24b3de51ad631e56, + 0x6eac8f01e1ba4776, 0xfe6b5c12a342fe57, 0xda05caeacd2cbf3c, 0xe2491bf0f2121019, + 0x6d937814add0adb5, 0xd427ee433c9f55d0, 0xc98c3644102e4fc1, 0xba570518303ff9e4, + 0x8c778b744d7441d7, 0x6077c1fbdbbdd700, 0x6169ecc5d5b4d4bf, 0x3dfc98b1f0949933, + 0xe377495735c9968a, 0xe70e207f0734f8a8, 0x9f54ca53d6b1cd12, 0x14ae2af4e905f636, + 0x92f3d2649f629922, 0x1f0bc9353a1737ea, 0x14bb26ceead999eb, 0x438d3ae4330827ef, + 0x9d893a3f43533ad5, 0x6bbeb15d949d61b7, 0x0c39ce1075d3cbcd, 0x2366e5079088bff5, + 0x7f6570316888ca19, 0x19a9a32a062f4857, 0x4db801529d58a828, 0xe869d47ccbafcc63, + 0x995b788df0bb049a, 0x314d9467b0daf893, 0xbea1d1cd39fe207b, 0x41461bb994987ac9, + 0xc81440601f679d5f, 0x78bd9800ee5152c6, 0x5a5e9aad6755b22c, 0x159a2f65e39e4ad5, + 0x49427dd743a2fce7, 0xa16e0382d1ed0213, 0xb21ce1fed4a274cf, 0x845a5bad82144817, + 0x79c5470c70c1eb59, 0x16acabdfc6a24be9, 0xc228c144fffcd57a, 0xdeb2ebdc7bacadd1, + 0xa3bb31927e5fde99, 0x3627a2fc82dfda3d, 0x73b8730e93fdb147, 0x18daa73a840536c1, + 0x9818c222439b187c, 0xca6e21a4818c0a64, 0x48ab7a57cd0368dc, 0x29eb7e992ca89a45, + 0x986bb8f35ac73648, 0x8866033fdbf7efaf, 0x896a3f633808768b, 0x2824b27d3d4d12d9, + 0x77072444404f2f05, 0xc9765da8b44b4613, 0x9fa80e27aa9885f6, 0x200e50695055a1d1, + 0xa7fb47fdb7f3a1c4, 0x8b9b2358593dd320, 0xd41209b3b80b3276, 0xd2e7955bee72e392, + 0x23edfec0bed3dadd, 0x4cb470b56c34dfc7, 0x1e765ec4457559a1, 0xf89ce5a0dd65ac34, + 0xf7a814af0e779265, 0xca0724665937b162, 0xb5c114f720da5865, 0x5039a5b398dd42fb, + 0xe631a2259417f092, 0x4a17a751dc03a6d0, 0xfe60a8996914ff4f, 0xabe38daff37c6c12, + 0x257310e525eb4868, 0x2342c32ff4a66fab, 0xf461cfd108d72fc6, 0xf847c991519c331e, + 0x6f3433283b04d04b, 0x5d7a855b88c018bf, 0x139145254a8f665c, 0xa6c1a24cbdc643c1, + 0x4a0441fc756e9799, 0x3db67e8dda3a79bd, 0x8dcd0701383d00c8, 0xc09fde2b46ad746f, + 0xa7fd5f14a3be5172, 0x88aa7886946856bf, 0x6df41ce7f2093138, 0xaebb49c4b56cbf43, + 0x3db9dc96995cc9a7, 0x31b29a8c93c6da00, 0x4c63e4e477e1fb4f, 0x756b55ea39677a4f, + 0xb8edcc84bea0d5a1, 0xb0b0229a783ea671, 0x3b1ec4ae00aa9e5c, 0x80457adcf0ce90d1, + 0x85d604401c90a83b, 0xdb8183c10cbd58e4, 0x9b3cf795a40aaa7a, 0x479ad85728e3a916, + 0x94e91095d71dd760, 0xe905fa435df7bb42, 0xdb275065f61ee060, 0xd04c1b09a4319bdf, + 0x7cdec327135f6f09, 0xe68c2f63a87d1b7d, 0x87478d642a12c5f1, 0x8f2a981b281068e7, + 0xcf60eea69c88dea3, 0x6980a7dd7de75f9d, 0x7eb9e6ee86698335, 0x885fd803d339b9c3, + 0x3ace87b25e8defed, 0xd3c675f1a403299a, 0x82e63c157961bd64, 0x7141d349bf919aa3, + 0x6ef6e294cdc0550c, 0xe4a9e3d2555a5746, 0x2e87176c56f54ac5, 0xc97c150cacebfcc7, + 0x9b20e243d62f850e, 0x5286942fbacf03d3, 0x53cc0db87fea94ae, 0xf548b3ae31e2b97f, + 0x5da07b3fdd12e21f, 0x6bedb1df14ce3b9d, 0x93ae358a4946553e, 0x94abc7ff4018f266, + 0x10abe00593af976b, 0x8057ec6dc812681d, 0x63925f1f331d907d, 0xebd681a7bb8d1256, + 0x5aa08be9fa1d22e0, 0x0f7ea64c96cf0511, 0x662562c82444806e, 0x4ae40a185dbd94c1, + 0x9d3968e70f7ba938, 0x5f881f4a69721b71, 0x9091afb47f1b512d, 0xf7885ac9bf893ecf, + 0x33cb1efe88f4d452, 0xfd6113510645ae34, 0xd37cf694de44ff2f, 0xeb5ff280b7b11493, + 0xcb954699e164ceb2, 0x97d1464ad7cfcad5, 0x75f290b14e9c4726, 0x4112a619d5b25dd5, + 0x076f2fa85fd65473, 0x7bbe73e8f419814c, 0x778de35af34e527e, 0x1a588070b12e536d, + 0xfb36490f6427819c, 0x8e24ff52578492f1, 0xde221a9a3026c51f, 0x77d72bdccddb6857, + 0x35697b1a24ba8234, 0xaefdac5fc1c3d958, 0x8eaf2c832839aa17, 0xb5cc27d67ed90a76, + 0xc73310b2c4e00bef, 0x5159a37641e5ec0a, 0x3182e3f260bf07d6, 0xbbb56b448c9d909b, + 0xf73189b5636e24f4, 0xbb3b173f41640926, 0x976ff682fb1b3f55, 0x2ea50d94e738d099, + 0x9ededcaf185445db, 0x7aa537f8a79c24e5, 0xb2ac6d3a25657e17, 0xf837f424093d2361, + 0x73e345286fc44a9e, 0xf868deb80e1a7a5e, 0xfde4398805fe75d0, 0x80db7d0d57c4e8af, + 0x7021163973fd5347, 0x84b36f66ef5feb8e, 0xa756852ebe22fb12, 0x3d044cc3dfcab0e2, + 0x287226e432edc672, 0x26592697e340cf47, 0x5cc9d88b4d858f8e, 0xcccb174a1c7f6a72, + 0x503507386ff70d37, 0x297a3e743917c986, 0x1a5b0a4f5686c445, 0xa45334749d8715db, + 0x36c7ac287ef8fbe4, 0x60f6e17a89441b01, 0xbc664b82d970df38, 0xef310c6a90f90c40, + 0xe32dc9525f01207b, 0x96b7beb6f0ece79d, 0xe5819290148e39e5, 0x5a1d4782c194fa5f, + 0x528674f75431c382, 0x14875842d441b90d, 0x183034ef2ecae4ee, 0xb28ea719751dd32c, + 0x1f53d63e71615578, 0xf7385084c196adea, 0x24ced28a3528d72e, 0x0b539c0474e73a18, + 0x406beee4cc30cf2c, 0x2a38db5c2d45b770, 0xea4b145581c1dcdc, 0xafd6cddc4e5cf985, + 0x93c6774ca1dfbd40, 0xe61e141648c87739, 0x6d39e6eca3f2a644, 0x6ecf7424c4308e32, + 0x7b71ed72291a491d, 0x90e6c51bfbbf6ce4, 0x3d05c872ce7bda6c, 0x4c865775e74ff6f7, + 0xc9f695d365a87f7b, 0x5fc248b4fcda9fcc, 0xbcee29e64430ef84, 0xaf02531e001b8d4f, + 0x1a04b8d35573e8f1, 0xdb47fb8313b3d49e, 0x48df404200d17dfd, 0xf16a4fc5232de06d, + 0xcf00570cecaf5c28, 0x41ba3aea8d05ec3a, 0x3fee2096b4f1e029, 0x7d28d3a8c1daec1e, + 0x8b3b47a7a28115c7, 0xd4c3075c68002329, 0x844b730f369a111c, 0x21bb5898d33f51a5, + 0xa62b1ef268c00447, 0xe727403bab841fae, 0x78d25b5004a4dcce, 0x565bf6f3795b923b, + 0x58a9f405f55241f7, 0x590adcb520583a96, 0xcc6c883e8228557c, 0xdfddeb10a3731c54, + 0x29fa09f69fe66f6a, 0x59b37831a61702db, 0x28d9ed51555be8d1, 0x471d87feb3e123fb, + 0xfd23eed100957851, 0x633abb187658ad43, 0xd4d83b733dc086a9, 0x81565f012cd7b96d, + 0x727f8d648ee93eaf, 0xe5d2397531695575, 0x9b6180ce82e530b1, 0x93b5c4b8c0bd8cce, + 0xe36f427f893d512c, 0x75b74068f8fe7c2e, 0x663d1d5bcf823797, 0xc45211dc5271fb64, + 0x27fd105f22d7a9a0, 0x2120cc1ff804fa99, 0x01c4eaf68cd50c30, 0xf3d63dd18c547eab, + 0x98b49bafaca46cdc, 0x099191ef087e5545, 0xddd9167c31646df7, 0x55417e531e60c515, + 0x0bb2b7e61f5dfd50, 0x9ffd798287e92b16, 0xd2a341d52c7f6aeb, 0x4c1462a5da3e4ce1, + 0xa6bdb1b41d3c9224, 0x7e90c77f90059805, 0x06447f59b69919d0, 0x2c5e56261e9da87a, + 0xf5e63f4d13f96441, 0x6d991ec2c957e11a, 0x6b402feab2cfbaf2, 0x67412cef64ad2155, + 0xc18a1bbb883f29bf, 0x03b6ab1ae6fb62f7, 0xb23835b313cc11c0, 0x5fc27c2d75a5bb69, + 0x0803fc11649bbe32, 0xa181d87ffb77a4d8, 0x82321b5b1be382d6, 0xa79904127816e1a6, + 0xc67869956a520b51, 0x8606851c143fb46d, 0x3aeedf77f25a0e7f, 0x05623e2e88893acd, + 0xba9be34681a00aed, 0x510a7c318915f478, 0x9b61527f1d7f94b3, 0x9c4ead5c347b6281, + 0x5af6375f64e16861, 0x7d336bc7695c13d1, 0x4d8e5a85c1bd6c05, 0x4830ca3038a5a314, + 0x65b73446240056b1, 0xddfc3dd607ef0270, 0x16f87ce461c68554, 0xaaf43ac6f1476c61, + 0xa891dca0e4062659, 0x8732f710ab382b04, 0x25e1d761aee96d87, 0xabd56f434376b5eb, + 0x43ccf312ba0ad5c1, 0x808dcba81b1ebd80, 0x249e3bc54ce246a5, 0x684e6d453f524b4f, + 0x83e048ce4d1bdcb8, 0xb66553a0f90baedb, 0x910890b413f69024, 0xb2ef70e79c560fb3, + 0x6823b6091db9f135, 0x96cc7a0fb8f367a3, 0x65f692a165b834da, 0xe7357c521d500e96, + 0x684d5ac71cbf032a, 0xd9a726f0ce3279dc, 0xad34f430047f3e36, 0x1d4e372a2ceed63e, + 0xbe4fc281bb82918d, 0xfd5ce0a392151110, 0xd46f2e1af9d76627, 0x0772a938a7378281, + 0x76971f49ec497b86, 0xf5a9547f605254a1, 0x32c780dbcf09df39, 0x580bd05ffae7f505, + 0xd8db1a102d081647, 0x7e63fd7c0699cfac, 0x4c15a7e5aef41cec, 0xda6840b001aeaf49, + 0x2d7e7539a1ac0d53, 0x6709a1ec9f201f96, 0x4779adbaf87dc4f2, 0xc4910409a803bb1f, + 0x685a89f09c35b393, 0xe2306a7d3a7c6aa6, 0x7b0a675bcb05e19a, 0xdd1fed233a6fd0a1, + 0x90882c06940d9bc3, 0x2ae3c98822de6d03, 0x9be6c1a8fbda82f2, 0xe259032abe46b69d, + 0xe1b8d946a284fa8e, 0x93677e4b02cb3596, 0x1f729a4aac5802b4, 0x24ab3dd0ddcf61d0, + 0x34dc4891e3578e6f, 0x6e7471a4a2e77333, 0xbc26ba6a02827cd6, 0xfceb2490b6833c87, + 0x6434a18937675fff, 0x2306a59b7976a86c, 0xbaef50e7fa55f20b, 0x2bddb7618f4c7e90, + 0x4205652fad6ea252, 0x264a2e6aa709916c, 0xa030a2c473d2f71a, 0xf31098854b234ad6, + 0x804e7e9f0c4a9dab, 0x382832339273df40, 0xfcc46b0eb1b54cc5, 0xa94cc451abe97a93, + 0x8cece7870b88971c, 0x1e0c65caa7355471, 0x6c2264cf60776fb2, 0xeaf5ec18a27dbc7a, + 0x36477829fee42bc6, 0x3056362277e6f5dc, 0xb07e5390006c9f5e, 0x9d6aa4bec613d69f, + 0x268dd94e8fb79ee6, 0x58afa579f432c409, 0xf5f36134b3b328e8, 0x99447c50341f803f, + 0x82828834cdc3add8, 0x7ae4367dce33a745, 0xc85c0cc8651aae9d, 0x15081c914ed15242, + 0xdf41a015d2b684ea, 0x9bad6cc1df3997fb, 0x93e10b0ab4068641, 0x8e4d26b88036589e, + 0x4c1df3e9bf0cc443, 0x335d7d62bba635c3, 0xd7b39ac67f3a5935, 0x243bbb7233236e29, + 0x80465d5e7244e221, 0x23f093893f182ece, 0xc2a2aa79b83975bd, 0x711ae8288a3cdf5b, + 0xc959654b62dca92d, 0x408a97d7f15b8cd1, 0x264c96670697c117, 0x63ef135bc7d7532c, + 0x37ed42d2731c7ec0, 0x366455125f4c63f7, 0x666f6303c7b1910a, 0x99b2a2f1e8eba822, + 0x332842ee8cdad108, 0xb58a2ecfc378d561, 0x69bf4f4a98008521, 0xbff90048249012db, + 0xa2e4554d1b9e4a25, 0xbb07ad8f3bf961aa, 0x40af195fc56a3ab7, 0x981307c43341ee4e, + 0x21e6eb7706840f90, 0xca7a7303e985a647, 0xf4ab87438f192f41, 0x093e065e3dad6176, + 0xf7b929bd821b8464, 0x136d600c36b2b23f, 0xca95afbaa23cef2a, 0xe46211c3fc13d863, + 0x360430c9fdfaf387, 0x2edd4fdacc2f6704, 0x245895363cceaade, 0xbfec514249e068be, + 0x1d1eaa5789b43591, 0x81a3f10e930f7da9, 0x87c2e797d57b80d6, 0xd7cb8fb719b6ac5d, + 0xabeb64a4f08de2c6, 0x389eeb7bdc71c216, 0xa9d1de42e78fc9db, 0xe716c1a768c4391b, + 0x825e785d7b4941ea, 0xd1c1007fc6a658fe, 0xca0bfe4d92467c1f, 0x0daf88eb94455bdd, + 0xd7288d84279b589b, 0xa5dd65fa9eb77bec, 0x4d0e0d5896729f21, 0x9dfb76e96118c61c, + 0xb41181165f4939fd, 0x1541ae11df2e6ef5, 0x515cbbdfb11861e7, 0x54cf610e2cd0189b, + 0xe68e58490be5fb81, 0x91566e23c6c0e15d, 0xb5ed267c72127a68, 0x402ff2176df40b2e, + 0x14abefb696515907, 0x80d1b3d0f8526cc2, 0xf078f94be5f119a9, 0x57f8219881be23e1, + 0x74b8daa4a985e2bd, 0xf9579ffd3a01b100, 0x0337c6c555fc3d43, 0xd3cbc8bbb27c436e, + 0xd395e79e10fd7654, 0x3f3f73369153aaff, 0x00415fa2a8938b98, 0xfb8ef65e9907957a, + 0xdd8217849f074fa9, 0xdee3e443edee128c, 0x9a43103ae2eefd45, 0x2fc61b2679635213, + 0x1b3b701744cac761, 0x387cf8f7acdebcef, 0x306877d49c587760, 0x69115e0c0d900da1, + 0x4c23d443d2113f7d, 0x4998c38cf44c7211, 0x7a02cee634de414b, 0xddf010eda93d1dad, + 0x2d4256dd0a4763f2, 0x0eaa4afe6f0d38f4, 0x2dcec3fcaca44df0, 0x5fa70aadd027dccd, + 0x24267637668b3a26, 0xc30d6cf7147c87f2, 0xbe3d31ec89132555, 0x45d3ed4cb50db47b, + 0xad5e6c0a0b985944, 0x8562f4082d0d7388, 0x13bdde9b86f374cb, 0xe10df32ffdfb197e, + 0x4a01208d155e03ce, 0xb85730405595415f, 0x76354565b6ccc8fb, 0xb589a6405defb154, + 0xb8fc5b0cb8bc029b, 0x04865bf0797fd5e0, 0x59a438ee3bdab029, 0x3b52de9a1cf94cc9, + 0xf58ab22ba1d89784, 0x547266c2fbab1853, 0xe15689513baeeed9, 0x4ddf5229d633aca5, + 0x38646771ab65b1d1, 0xafbb9bb3ea018b0f, 0xeb56ad2c2d50e8d2, 0x70ecdbbc7ee922a2, + 0x227f2bf25fa07344, 0x36fd2aa7ac5d8c4b, 0xc2c14545f0a96fb8, 0x8ce7ebdf46f9f473, + 0x9763f8a62f730f7d, 0x11a0e5e06a99c20d, 0xa72c057c92b7530b, 0x35272c86ff82856c, + 0x71482c2b95dbb91a, 0x64c469d7e4a1da83, 0x895b31ddf670da00, 0x61dd19f531f5d885, + 0x3c02a1d9382b3ef5, 0x4628bbc17b4fe39a, 0xfe9aa810181effab, 0x7cd0922b124bf8fd, + 0x3f93894200d40e3a, 0x30d2a6bf3b52538e, 0x0fb14f4cac1e1ffe, 0xb953c821546b2143, + 0xdd8b4506149068e6, 0xd57bc5eacb03af1b, 0x45f96d441626cabc, 0x97aa316053e54219, + 0x1b4d6d2ef20e9f55, 0x98ad5b306a6a2094, 0x29e4b088df202cf0, 0x510b57b23a97051d, + 0x156f2be9295ed207, 0x9f54fdd531b3778b, 0xe70ef32e7ed45e76, 0x468c7348ab182005, + 0x7fb1dd47eae3edf8, 0x4a20f621de4a086e, 0x8ec1b6c8210efc16, 0x629f5e3d7ea79c59, + 0x837ecabe18b75cb9, 0x0ac2f9f6a116ccb3, 0x70f073ba100d9fa1, 0x1c5a6910476abb97, + 0xfb190e79db88578f, 0x2585e6a3eea83575, 0x7993e0b2e8a85816, 0xd7be0787824251e3, + 0xe03bde2e1cede8db, 0xce7934868d62b6be, 0x706ecc60842afbfb, 0xe4fa53e5f474b9d8, + 0x297cd577bf71458f, 0x4a4ae8469d4bd015, 0x89dedd171e4d6f15, 0xfb4563b3350d2c92, + 0x2716d5c1f73ab89e, 0x30e25a3a39dac00f, 0xd879595968ef785c, 0x3ef7788d52aade61, + 0x4fab8ad8b94c4fa0, 0x7affd9374f63587c, 0x5adc1438c60fb54c, 0xc0175fa648b7c9f8, + 0xe939faf7b1204165, 0xfc6c6aa4dcaae3cc, 0xc7a27c5d484a2ac2, 0xa8b935a322f8e744, + 0xf862b34c173cf93b, 0x980a2808ef5e9ecc, 0xe8e65145cf6c4035, 0x75eb874701b88a58, + 0x8e2c85045e7f2024, 0x36b069c8f2bda647, 0xd80a239d51d069ef, 0xc5c907ba6799ac3a, + 0x3534074c86ea3300, 0x00ecdad887b9ae88, 0x307c5e97b55f2de7, 0x23385bca91fb1a85, + 0x48a0cc149bf75c6d, 0x345f59f8074fbf04, 0x5aa0113a1523322e, 0x3a24139cc262ae2d, + 0x4c6f1321ccda02dc, 0x9ae78ab74154a2c5, 0xd11642326e2d2c9a, 0x294b84a0ec1177ed, + 0xeb2ce1ff386cf5b9, 0x0c5939e52eb3aff4, 0x0a90e4b3cef160d1, 0x800b5da8c86ba6c7, + 0x3dfaed35e82f4d30, 0x13a9abafe6b76632, 0x203f6306c3687a14, 0xf49f9699980df042, + 0x4f22932970e2c0c1, 0x43f7f6b6b2e794e8, 0xe2954459fbb8b92a, 0x22ece43749bd2884, + 0x59ccd7b681884e8c, 0x93111d3f52bfaf66, 0xee4b51712ed8a9cd, 0x3403866299e16e26, + 0x787c4918316cc74a, 0xcbbccf7906cc0000, 0xfabc43fe8fea98c0, 0x6baddb48137d5176, + 0xd65d27f59ce13144, 0x6ac3f12084f61776, 0x60d9b1c8a1a6ab89, 0x728d2f0646610f4a, + 0x4da8c28efa55282d, 0x818b23a8e3210ce5, 0x80f47f197bcb1196, 0xab9da675877fa668, + 0xfd8f509188637d3d, 0x88d585a30c4f1703, 0x5ce0fd781c66e7ec, 0xeee4b15d9fcf086e, + 0x49554d2149204eaf, 0x659da7d938223f68, 0x44f46a369292e9fd, 0xbc5762993f04e418, + 0x273284874a109851, 0x3737ab99a012e255, 0x2da06c53b726d70d, 0x3c7738d1b3b2cb48, + 0x9adf781f2213f2f6, 0x5b2b7a06cbff1c6c, 0xb41bfae69e9a9f3b, 0xe30ceacb385567bf, + 0x1edc93b08c78e26c, 0xc3afa196f4c051b2, 0xb1994ff603a07713, 0xf26e2e3a6c4fa6b5, + 0x857ea2100d3c9b7c, 0x45254d96be94d0b9, 0x4707a9d678a5a777, 0xc534beda0013c7be, + 0x5175dc8fa0edede8, 0x974efa8118a30c8f, 0xa4b631773c5ed5cb, 0xb8e606825007bae7, + 0xf18b18a6b97c8a54, 0x46f54f955be77492, 0xad9318fd9b2e74b5, 0xe2a4f606744bea4d, + 0x19bc6d62f86f27fe, 0x69684cfd957366dc, 0x0fc62f70fd9d1662, 0xcacc9d43d5e28772, + 0x7b075f2746355b96, 0xb25e7d1389c0dd77, 0x2e5c66c352d7c963, 0xcc76df5844d61fda, + 0x7f7a48ea108b1ddb, 0xe3781c94c62e39cf, 0x3a88189ceb798a26, 0x6c13240ce0db20c2, + 0x7cfd7ba68755a879, 0x1ef032f9dee3dc62, 0x5fb8ccda58c5cedc, 0x06eebedc2c016eb5, + 0xb1320f7f8f58620a, 0x3d2f3ee3e399afad, 0x5e9292f25a98fbcb, 0x6a731d39e9c14695, + 0xc32e2d6db8ad1d81, 0x0451dda8a19cdf3d, 0x08ade497c5caaa57, 0x502ee7a88a098f68, + 0x91244eb2fafcdcb8, 0x1706a6ee4e6e1905, 0x439dc2fd8d221d55, 0xc3fb4daa8a667870, + 0x6c3d4773da4b71ef, 0xaceeb2355d2c8764, 0x65e31b44972978a9, 0x5203c6b3403d1476, + 0x294f985280a75ef0, 0xe0f05d033f3aec7d, 0x3df31c683eeb8e8c, 0x2b7f3ec3ee59ba19, + 0xc880257415790c63, 0x246a714b11d6ebde, 0x307ce6213362cb45, 0xad806edac73940df, + 0xda796e87178f5289, 0x12c226be6da63315, 0xc97c1710522c697b, 0xd1b01966d04140b0, + 0xf6655e1f1d97f72d, 0x5bce31404a447d9a, 0xba4d3914278c2faa, 0x9670838c424ce830, + 0x52b5c62cc6ebf634, 0xc43e529e663eed69, 0x547c02f6646cb610, 0x26c1bfbe8aa69b85, + 0x1c9739315eae8850, 0x8c49a01368a15cdd, 0xd0e8f187387ef047, 0x03cb7684c0d6dba9, + 0x2b0879cef29c7ec1, 0x07d5b417a2eb5a44, 0xc8297b7929d31957, 0x04991b9ba75e2730, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x801c271e7760ec85, 0xa9317a6387a7a094, 0x520750b4cd1399ce, 0xcbc645dac7eee0bf, + 0xc4d68b0734f26b66, 0xaa42b0d47a3f3d5d, 0x2de39faa76c0d21a, 0x9938ceea34083e10, + 0x0083e12c6a0c51ac, 0xdeadc65894b44bfd, 0xca49a6ceef79a7ba, 0xfb7ebd678c0e36f7, + 0x5a0f75fc070875b3, 0x227e99f533e682e4, 0x3bc9852bf551ad9c, 0x94dc4e40ed690fc8, + 0xebd8e4f176f926ea, 0xc087a11c407aa178, 0x887bdf9de7565be0, 0xe0107bb51e81df12, + 0xb95d477fcd70d71a, 0x80904471f409cc36, 0x0dbb32d4590bdd46, 0x7080bee6624471a7, + 0xfd1df16870c5cb5b, 0x6ac49087fbf54857, 0xe40ab6ebeba46040, 0x7fe5386402befd18, + 0xc0cac70db6df8b98, 0x4b801585455d24ca, 0x5e15599cc3dc2305, 0xdab3e4a3e9686e15, + 0x83535b89d1a88792, 0x74bb1d99e7d7b42d, 0x3381ffab9acaef22, 0x2e035748bf97cdf3, + 0x5e424cc9a29d600a, 0x56c48d25a2e2f9b6, 0x11e6c24b7c57f64d, 0x82b63d7c7a225724, + 0x3d9297af144f5a93, 0x35cf96d8dcbe2fe9, 0x08bce0dc28fc3d63, 0x8146f953fc8ffd80, + 0xfaff0d76f6bbd0fd, 0xe7bfd75363659936, 0x8cfcfeb30dbd4401, 0x417f478acac6e0cf, + 0x135cb8046a496905, 0x8d5c60b74c982576, 0xa3903c43f9357b73, 0x4c687bf2484209d7, + 0x29aa80595c3c5422, 0xa9511b845f7eb2d8, 0xc102fdb4939a4438, 0x2306699ea83ccde1, + 0x6cbc2b983e1e1356, 0x8a1788b60c50bb85, 0x856700d0b3a6e5c4, 0x326db9b3c0404f94, + 0xf8a8b9784beb4290, 0xd0d605f7226a5bbe, 0x13188b88bad882c3, 0x80cc3a5cbab6d0dc, + 0xeaedfff98a4a86c6, 0x6a7aafb9f4829d14, 0x37506d8da844ab44, 0x9dd17dad6878028e, + 0x6c9619c300ed6521, 0x977271bb7ac3030b, 0x7dc0be0affa6c3f1, 0x4b79ba5856a5f181, + 0x11a6eb62037e1726, 0x32087e79cd06cdcd, 0x3e2371d5a604a170, 0x936fde062b3bb82b, + 0x571d24242bcb5d6c, 0xb5229dd650166f29, 0x1eadebdd04f53b1b, 0x523e4111ce815ced, + 0xf14a9f6516e160a8, 0x68d5af443ad0b479, 0xee53cf0d3f337165, 0xe9b4d8cc24708700, + 0xde5ed331df5af850, 0x6605a0902bdbf269, 0x70f621a554c0c70c, 0xb8b520b4f7f22732, + 0x84f4028582ea3d35, 0x81f8238fdc176fa6, 0xc020ca137b2922b9, 0x85ab53d7c41a1750, + 0xb3779c155b5acbfd, 0x89f74b1e9bf1febe, 0x9e99aedd615ef803, 0xb075f5df1359a25e, + 0xcba89d5aa007c355, 0x31f018852a6a536e, 0x0b6d968de79c3de7, 0xf204fd6fba23ae36, + 0x659c4483a1f56842, 0xe7048f0a742187e5, 0x9f0b8acb091e118c, 0x4281e98cd663b5e1, + 0xd966bef81e8c9703, 0x6d36a66a4d0d6ba3, 0xceef2e5814c40d6f, 0x93488666c713b175, + 0xd7dcb0d89732cd0e, 0xd7f88074f17064e1, 0x24cc2008d6388a44, 0x42696228cbe00b27, + 0x5da1ac82b08861b9, 0xc5cbc0ac8f18fb39, 0xb36fb764a940b85f, 0x840627546374fc07, + 0x6417b7f62435b1ce, 0x993fc0b967a23151, 0xb18f0a67180748ef, 0xb578092b7e77c876, + 0xa8d2601ec184fd3e, 0xed83db1bc70c3a49, 0x7a4c7e3296545da1, 0x6869c695f4f88657, + 0x9ecb4569d08a3a68, 0x6c5378a73f00dfd2, 0x05b4855ad4eb47c4, 0x568b230c0ff47c9e, + 0x707163eadf36e9d2, 0xe545bcceaba855c5, 0xbe070296ca521a8b, 0x656e6597d0ad3c26, + 0x82249f4726b54220, 0x25d7bf8bc003c402, 0x1dbca96147046985, 0x62ccd5be08b041f0, + 0xde3efd885b817e2f, 0x18c59744f7002832, 0xdc5edb93f5b368f0, 0xf04767b1dfb6d04e, + 0x20502afe7b38fc79, 0x694df0a5a842089d, 0x1bbdb871220f4bbc, 0x90acfa1af1c08b94, + 0x87cf16ad7c9cb2e4, 0x8934cf0a126eb764, 0x7f14dd61cb79cda0, 0x63022932268f9e2f, + 0xae8457d58b15b8c3, 0x9bae10e47d4ee327, 0xe41d6a74e2ddae51, 0xab19d62f90d56c48, + 0x3f59062a172855ab, 0x3413e1781f474745, 0x05bb12f2c0f34c98, 0x7fe9a13866610a9b, + 0x98c117de6b1c1447, 0x8cb31db8f85e2776, 0x7fa266a4b9ea45c3, 0x1e318becef88b641, + 0xafbf9038a4aa272f, 0xbbc5ba3de18d6535, 0x6b608f02beb10593, 0x65bf674003a43368, + 0xdd9ac75c3cf459e3, 0x0c7aa7cc5179320b, 0x1e7bacd8b8c52186, 0xc214d31edaeb27e4, + 0x6e3e1237baf2531b, 0x0be3e2fff1c3cbee, 0xf5eab3703ff565e1, 0x52d1ffcc8ea6d213, + 0x018fa2471bfbe9b9, 0xe211607243a0ffbb, 0x5cd09e8cb272fcc2, 0x00e039891daf5f7e, + 0xfc81110efca8aeb1, 0x7247e7d90969891d, 0xc60df4302845fc1a, 0xc983ad076c8a8411, + 0xb3b189f52cce4043, 0xcd5b07c93f67cd8c, 0x765d81f0c4c595fc, 0x77eb7dd4d2ed83b2, + 0x3457057796f912fd, 0x353c7747122bac3e, 0x19afe95b9fad0cc8, 0xf4398cb00b315b6e, + 0x570f4a850a1c1bd6, 0xa7acf5534a027bf3, 0x9208a7f04dbc1c5b, 0xb7caf3d84168e7cb, + 0xec3b8e3e4819f98c, 0x53de17187b86d985, 0x4f2f4660426222d0, 0x7d7844dd3a934a31, + 0x6710d84af7c821f5, 0x2ce48f4b79a06f29, 0xf2af15309c1a6383, 0x3cd204772bacfbde, + 0x4e8355f1c49f7953, 0xc1fcedb8e1211c1c, 0xaebd3e6b08f0fa9f, 0x5eac318a0a74ff8b, + 0xd0e0d3c8d4061249, 0xc5ec7c0e42614936, 0x1a1042abdbbfb37f, 0x1f90fc92256c1fd7, + 0xfda090ced6d764d7, 0xe0d11f9d6995f565, 0xff3be31dd37f82a3, 0x8b50155591069860, + 0x3fc5a2611174caf5, 0x6f93b1349e0469f5, 0xe250e357b9c102fb, 0x868509c9a23dfcaa, + 0xc31084953a321735, 0xd850265b971488d0, 0x816383c81938ded9, 0x59210f123cf9c713, + 0xc33f66ead557a2e9, 0xa558d0a86004c6fa, 0xccd332676294427f, 0x90c72d84934671da, + 0x2417a86ce3357267, 0xb5f91da54099ae1f, 0xcdaa8c1e74ee956e, 0xbd9d9b847e8afa4f, + 0x561e9a1ba25e8862, 0xc7ea7bd87f600396, 0x0c3e854d064ee3e2, 0x471e60b68bfd33d3, + 0x96ed8217de0fe7e2, 0xa80f406568173da3, 0xc4875e346009eb58, 0x98693ec8728dc3ee, + 0x343f9e4c69cae886, 0x70cc96a005ca2203, 0x8b6e531e5a8f1bce, 0xf34e5455751b6043, + 0xc1f256bd26ed80a2, 0xe4ca10ca16050e6d, 0x7a7596c36c905983, 0x212e6e3efa4a2259, + 0xcde182a041db2ff3, 0xef4c89adf7efe659, 0xa0f011e28ef150a6, 0x285085b50a7d9542, + 0x3af77b22a8fe128e, 0xe3b44771f46a4d09, 0x7fc4bb0dac7649b6, 0x1c064bd74397d42b, + 0x8ba74560d7001cfa, 0x063e822e4d8473b6, 0x494ba670dcb6f415, 0xb6bab3b73e0b4b99, + 0x07c49745a0bf8c0b, 0xa34dc14ee78c10d5, 0xbe06a7e1904dd3ee, 0x1037929facb9ea5e, + 0xfbd58788639e1c3c, 0xf301d6173d6915b3, 0xac306ee25193ddc3, 0xb2f2f195fe00cc28, + 0x653d7089c27e5ca4, 0xdc9cee1a35f56af4, 0x7bee13e3e2f337ae, 0xfc2ea276aefde915, + 0x86090e01fc9c1a9d, 0x0a53766ee5970b96, 0x9fc2f875815ffcc6, 0x163d4f8a490f2c40, + 0x0b2c410f75d18d37, 0x0e80d686c7601454, 0x2abd8edca1a87738, 0x61412c318ee87d77, + 0xf143ad18a09a9f86, 0xd9d81d9b03cd4cf7, 0x7cef6f3947843799, 0x91be54120ff5eab7, + 0xb2b26353f693045d, 0x0b4e56f98f13c1d1, 0x391d33169c91ac96, 0x9c01476addf99c1b, + 0xad6efcdfd52bd13b, 0x47412f40bf9fa89e, 0xb24cac335f07ba23, 0xbe9340384e6d149d, + 0x64952c8361b80745, 0x4d2b58326d1143e7, 0xe0285b6075261014, 0xa731378b287cdbd2, + 0x96f55253e34150df, 0xfab883020e987cf4, 0xfc463a95d63a73e5, 0xa26c8deb200ede49, + 0xa7cf9dce88667450, 0x52860504cd5c93e5, 0xd87c3d7a45932cd8, 0x433f032dceb0fc6b, + 0x875121590716a5bd, 0x4803b55d327d4fe7, 0xb6e6f39e6469e555, 0xa8684dee46960db6, + 0x4eed134c0a1f402d, 0xdfd7e4573ec5ce18, 0x9fa8c8a2627d9bbd, 0x617bf2fb3e3f169b, + 0xafd991f83e54454d, 0xdc84de07a35e6806, 0xb524da7c3edb37ca, 0x3dcc5c799950adce, + 0x96b73fc380cf2abf, 0x078acc97d354748d, 0xf7be1aa7e172ae88, 0x4aa421e56226f386, + 0x520a1618bc986407, 0x1d38912202329d2b, 0x10ceb5bcdd43f752, 0x4e0a4b88c8d83adc, + 0x3bf741c07e71f718, 0x131dd7a2bfdbb87f, 0x3bee148666ce6840, 0xf90edad8acbd9356, + 0x5a50a244e050f905, 0x4b1a9c864414b83d, 0x129050fa897c37b5, 0x6b035b1aeff5aefb, + 0x3771fc2e3ec65a19, 0xe424fa7246f4a628, 0xdc19da85a654cef7, 0x225ab3e5c93c4bfd, + 0x8b8e97f49c398658, 0x4b1578e17f4bf3b1, 0x110a12aa2e4d47a1, 0xd389d22d4ff9b5c7, + 0xa81e689d87f4540f, 0xbbf9bd5159f3994f, 0x458bd33dba5d8397, 0x534740957a701e9b, + 0x2bcf063b9990b309, 0x0617f7c7bd9089cd, 0x110d61beb89913d9, 0x8142fd7b63c3aff6, + 0xc6bb3438a85a4c18, 0xd1dba4afac7b46db, 0x839908a8bbc3a88f, 0x2bb12cb33d8c5b0c, + 0x28d6cf03f86430db, 0xa557d5cd203f72c5, 0x8c575d8a0b394b08, 0xff61e6eaa72cbb99, + 0x09bd093eada6c6f5, 0xb7377a1f3cf6f67e, 0xd558221107427496, 0x592b31e4d29a75d9, + 0x20d295b1963610ae, 0x08a4ffee12ed8fa7, 0xb86ed87ba9af012f, 0xcbccfcf501609504, + 0x8e741e681d0a1af3, 0x4b995cba014dad68, 0xed3d914714a001bd, 0xff44f2a6690e66a4, + 0x62306cf9322008cb, 0xc3fafaa2e01344df, 0x94d6da4ea7475710, 0x0860dcb584394991, + 0x0ab4e583303e1723, 0x69e449bc973e9164, 0x21bdd58a35e582fe, 0x0b5b30a5fe7d78ae, + 0x7a5c23dc865d07d7, 0x3a0f5c2593bf0d92, 0x93d406d674297a2b, 0xa38a98664ed99e03, + 0x87ffa5989a6896c3, 0x2ed5f62e9ea813d3, 0x8cd0b84dbd68c775, 0x7809069a33b28712, + 0x8466bbcd4413bb35, 0xe388324510467f5b, 0x25b955787bbde7c4, 0x75c27a6c60c461c0, + 0x3b8166432171549b, 0x3a823205668aba47, 0x36c293e582ff04b2, 0x264385f202952d87, + 0xfaab9340864e5c7e, 0x6d889d48e7f4e9c1, 0x8900259ac79f5222, 0xb547b653c88d6149, + 0xd6afdcd3897edfda, 0xe0f05f188bc9f655, 0xb13ce1f9db944da3, 0x87ccd90e72541b7d, + 0xc4f26039c63541e9, 0x02522c719f731706, 0xb4ffb8102d74a0c2, 0x2f84055a785f2326, + 0x29f01817e165ba0a, 0x39c495ee91ceb5b0, 0xd05a01ae7909a649, 0x1a1bb475c1c81462, + 0x7c74bc001ba89d2a, 0x84f5eed2799549ef, 0x4b4891ab4ff50c82, 0x7c89ff42f33bc5b8, + 0x2e5733a2b9f479b1, 0xe4ca58a6a18eff3c, 0xc770e23326aa05f1, 0x907e56fc1f9dcd22, + 0x8d62690c91367bce, 0x34ab1f13d58af911, 0xdbea5abe5cd0b816, 0x573d7096d5f52619, + 0x3eba638c69cc6586, 0x10fef37c1ca2e36e, 0x1259ff3417dc0789, 0x9f1247833f666b93, + 0xd425788e8ac8e18f, 0x913a1cb7130b48a7, 0xaeb3ddd2e8f21e3f, 0x8c5bfbf8e5c0a598, + 0x033484b783f30b83, 0x22698d990b374556, 0x52e2e7105d2f3ab3, 0x64190954c06b25ef, + 0x3e440b92e777dd21, 0xf9acb64cf302f6c2, 0x35a20cc8f356ce7c, 0x7df5171bec201407, + 0x7da508199981e454, 0xa1ec54120d410a2f, 0x339bb539a1750e19, 0xf8850620faa02fa8, + 0xe3714747038bbd48, 0x46a842b4bf3f0d5c, 0x1b3e57f6cac51921, 0xcc5beb16db336af2, + 0xc86f751325d07547, 0x15399118652c8725, 0x37fc1bd5a9eff988, 0x6fbff63ae0a20136, + 0xda6ef7d1e983ec66, 0x44e6b7a75666e745, 0x2dfcc47fd4cb7094, 0x0400478c07bc04fc, + 0x109984dbf506d4b5, 0x9044cf0ed0174bc1, 0x0440099246bc3ad4, 0xf0cf29f287278527, + 0xc65b53c18d85a65f, 0x0961ec15f81ee12c, 0x6dbbb4380a26a235, 0xae5c1761a61bdd6c, + 0x755e3b1630f34aa5, 0xb867374f0df468c1, 0xba16b2309f3e1ce7, 0x3ee62d136ee53d27, + 0x1fedf6d83176aa3a, 0xd51876c98a6f5771, 0x8d980a8ecfcc6af2, 0xd34206b5a061378d, + 0x86dcd9866f98b08e, 0xced6def3b2d4500b, 0xdc77e739018b80db, 0x16c88fca00d9200a, + 0x9f75aea1aba9256d, 0x172cd9e704c0af91, 0xea475961bdb03480, 0xebd93dbd622eccf3, + 0xe26bd41b28eaf120, 0x2180345482630955, 0x6afa80fece323eb4, 0xe25c89dff6d2ea21, + 0xce7934bc6a3aa6ad, 0x263814f9dd35999d, 0xc8ef558fc1240120, 0x7a5f27db9737987a, + 0xde981cc7e21695d8, 0x3129bd5505e8ce4b, 0xfae92b71673212f7, 0xb20496404d6e5c9e, + 0xe2b8f73728358c66, 0x2f33ef89062feb01, 0x3e56665ac9d6b54e, 0x8e51e86d9d72c4ed, + 0x45ff92456332cff0, 0xfeb563ee1e3c873c, 0x50bad587d42b749e, 0xd6a15371501d7081, + 0x19508a14f85f29b1, 0x74f0f985c8aef013, 0x46a779120204c6c0, 0xca00627addb31111, + 0x3b50e7231ba0acfc, 0xb1ac10744a392550, 0x6165fb05e9b2adb0, 0x29ee771c760735d1, + 0x1f6229b0efb15179, 0x378c982cad71217b, 0x09b9f9a9b5d9aa0b, 0x87730ca8f2fbef4d, + 0x6abd36334bdf9306, 0x8d7c2423e05c88f7, 0x53f6c0a6d64ac0bf, 0x329cd7a3b84adbb9, + 0x40235aee38bce5f6, 0x529bdbdd5e74d45f, 0xe0929b3e013a7a96, 0x7fa92cc321f99afe, + 0x47f3fcb6df5b2ae3, 0xadc9c92d3cfeda33, 0xa066ed40bd648fae, 0x0be1af2c320bd8c0, + 0xfbe10effade36b6b, 0x1b76f6727a759aa6, 0x580e252687431546, 0x203ae67bd15a9c98, + 0x2fda7132c1ef2906, 0x3099644e33e3e357, 0xec9d605a50861234, 0xd15d5c155537366c, + 0x33435ec10b85858a, 0x3ada635a9b080c26, 0xf3daee34226fbadc, 0x4169ce251eca04ae, + 0xdfd9dbd01ae1ab55, 0x8286f7c1c03c0ad0, 0x48373008c65b2a1b, 0xb3bcce22b638eb9d, + 0x09fcbfb2e2f722b0, 0xbff9d93aeb68c885, 0x50158c31924e47b8, 0xdf45e27734c91512, + 0x776c0814dade5516, 0x7db74e0618a9719e, 0xdc87aa046837e9de, 0x472ba09c24871f8c, + 0x2277ff1f5d5e63b7, 0xcf54b92bc186fe08, 0xf299681617929875, 0xc3ed1361d1da3d5c, + 0xf53156800386f2e9, 0x8d5d5a1c697e9f1e, 0x749c5cc0ea0df5b9, 0x7309dd3831f0de8b, + 0x417c2e6d818a7bce, 0xc69d54c9c8ae0632, 0x273c297c50004193, 0xed2a2f085888bc8c, + 0x395520913bffc09b, 0x3eed80d0f50c3048, 0x25b9099f2fda0e92, 0x6e36f9a521b7eae7, + 0x0dd3be978dfbceff, 0x5f0f64f8bb1991d1, 0x4e56d18b58bc7d98, 0x379868a8ec621302, + 0x26391fd3442a9989, 0xdc09c1617c295986, 0x301d690cfdac4dde, 0x5f73bbe01aac5d93, + 0xfa1d13edfc5b2ae8, 0xc48de27e576bfdeb, 0x66705d34b617f976, 0xe7001a9cabf8447e, + 0x1fb75d41de6598e7, 0x20a3dd4c53d71bbc, 0x3b0b5e12293ce057, 0x4add38f98989f5f7, + 0x7cc9beea66794cd2, 0xcd9b5ee7bec63649, 0x22464ceb180b9aa7, 0x5feab28127b2d474, + 0x45e2c29d030a55a7, 0x28a3bb0b4a01ef1a, 0x4c827ea69a951eaa, 0x230a7f2275c4d7cc, + 0x248bd6136811f6de, 0x3686339bc9bba600, 0xc6f049640a7e2279, 0xc4c82adfdc05b2e5, + 0x1a92cd8e300fd810, 0xd963dbc752e66e72, 0xab6213eec4e484fd, 0x625d6c18e0842db6, + 0x8231fc966fb9dddf, 0x7a335f0cd0bde9d1, 0x5958a7f218b545aa, 0x9bef1b58614e962d, + 0x5e6cbd175b72f0d8, 0xd9b5c67689142bd3, 0x30db97a59d952a7c, 0x76c682147f4ecc23, + 0xbf94b3e33f2fa069, 0x0782a62a5295fcbe, 0x4c13c22294676139, 0xe951b830ac104a75, + 0x9f239a1b3b905a94, 0x068301fb5f36cee4, 0xd72d66df3119e0c3, 0x5d96df06fa1d4b8a, + 0x863493dc5857f51d, 0x8c69467176f3d612, 0x5a66b5ff5bd73dab, 0xb8a965f931e7fe6c, + 0xb210a1fd24961b3b, 0xa63b6c125fe69945, 0x6206b098675c14f6, 0x99f82a0a3c2a1594, + 0x441bd372dc231074, 0x474c18cac4394d6a, 0xfa79786e7b691b7a, 0xc96d8147f3f21693, + 0xd642484c754e3abc, 0x18e53d06671cae01, 0xc948aafbbc419aa1, 0x43463e4d8ad9f102, + 0x78ae9be8905e5d8b, 0x9438264fa598b545, 0xb54762bc69a8b53a, 0x73f5e1c7304bfb6a, + 0x9a7c9e7500eb2303, 0x82b21eb66f7e3114, 0xc89311ff5429aecb, 0x04540d61fdcfd68f, + 0x0e687e812899afd5, 0x1edc4760d7d29274, 0xc9a2ec79dfc1b6a6, 0x808910d1e64bf954, + 0x0cf017773c366a0b, 0x33b512aa4f45ac82, 0xe7a3898e1450ccb4, 0xde10ebeb9d600f47, + 0x452bc4a1cc1931d7, 0xc4f8c33a2ba7cd9f, 0x680abf39fb259d30, 0x2ff5411005ca3d83, + 0x28ad488b36e4f7fc, 0xf32a0490438764a5, 0xc96b02cddfbb9826, 0xc4f46927e5734f46, + 0x5b5587b52aa68d89, 0x7300f8700f901ea5, 0x94365730fce49a3f, 0xbea377678daaf17f, + 0x6c6b19d6a3e81017, 0x987360e366328761, 0xef33dda5cd54f4ca, 0x257a04cdeb3639bd, + 0xb7003e018652ede2, 0xa10105f8f7d9cbe9, 0x7717a158347b73ed, 0x12392b607dcafaec, + 0xfe7146542d8de310, 0xfdaf79533f8aad37, 0x6799d6c0e34bcae3, 0x0bb8bb4af76c2deb, + 0x2e9e21904cccc003, 0x1316143a18046be3, 0x908ab828987f2f14, 0xa00ce308c1224dec, + 0x6e24e678db7357b4, 0xdd2d8478a942efd3, 0x5bb3c38cfeb78389, 0x34fafb46b3574009, + 0x66d06c7720ca007a, 0x4d0e8d4c4b5c805d, 0xa55595eb32ddd2e8, 0x7dc0cfc18f9c5e61, + 0xd166f00c6508ecd5, 0x2b2d5f9512df613e, 0x56ef13345a471148, 0x4da4517efc823011, + 0x8e53fdd527170d8a, 0x72a480e08de8729b, 0x3aebc0d716bab895, 0xca2ac40cc90fd573, + 0xa46d3f679a56eb6d, 0xfb71952e3c2af8ef, 0xf1ae5ea3cea789ca, 0x6e5520149af38cad, + 0x06cd44ac96246581, 0xd58a1082669eb147, 0x7791071bc345eb2f, 0x1fb37536a562b04b, + 0xa0c77cbfb68d50d8, 0x6835846de1c9eb79, 0x1c10f1b85e836c53, 0x4e5a6fac2ae4fbf4, + 0xcbea171f48e79989, 0xb8685330695139fe, 0x14985504b498ca34, 0x9a5a11c74c6e8c54, + 0x7f09c543205f0002, 0xfed94fc034159367, 0x43d880d95b61c2b0, 0x9230cc07c96cb9c8, + 0x342cdd7459da425c, 0x32b4197eb933ee08, 0x28fcf27efff09b89, 0xa220b1eadd974b70, + 0x838812b638aabb32, 0x8e3a37348b3fb4d6, 0x0c35a4b39654b654, 0xa9a1eb64d8173a2f, + 0x2ac377ac64aed9ba, 0x3347ec252311c9e2, 0xb3382258e77236e5, 0xe072bfb48557edff, + 0xa5df62b59c594627, 0xadaa3c35bfa86bbd, 0x050ac640e852ddcf, 0xdba35b9b79b5fcad, + 0x9ce7bcc219bcb7bc, 0xb295e0bfe3c1edf6, 0xa2f5f402b2dd57b5, 0xaa3202932e2186d9, + 0xf8c6ca1cde13e4a1, 0x1252d584a0265b4f, 0x3b2cf48bd7b521f4, 0x7a06b32bc4122e54, + 0xd012909a2daea6f5, 0x7bdf7e5da331f9bc, 0xff1927e7e1230da4, 0x7747f4e7414b814b, + 0x6708cf474a52e781, 0x5523956705f3261a, 0x035a77f43cec317a, 0xf75c1e79856955d2, + 0x351cc7cfbd592f70, 0xeb5db1943e8b940e, 0x209e79b715e9700a, 0x27e29b356aca1fb1, + 0x4bd7ca2ec64a05ab, 0xbe41375e0bbc294c, 0x1d70f15f9abe25ca, 0x30d0b1e74678bd69, + 0xeb471cdedd77695f, 0x4760e450a6c66968, 0x6d9162272ef2c297, 0xac921106513423a2, + 0x9b2f16392ac09ed3, 0x37e739f111cbe42b, 0x6143d85026de83a7, 0xf7270f1126030471, + 0x26690424713ff5f6, 0xe957a81e9a84ee4c, 0x698a9e98d6b98ce7, 0xb9b983da4c2d45a6, + 0x958d8bfe275777a5, 0x82dc33c3d6baad37, 0xcc037786296886a2, 0x475fa6058d42c976, + 0x4dd874421124f333, 0xd723862290301623, 0x379e5111f5bf9046, 0xee84a1db6e690dd9, + 0x7a3e286c84a854ae, 0x57c81a25c49515a9, 0xd63afd2743073fb7, 0x612f5111658c7daa, + 0x8b9df687ae7b6b48, 0x86f05d4dd543e18e, 0x774bc579ff6b6405, 0xfe45708eb1a6ccb0, + 0xa5d4e4364ef9c041, 0x04c88fbb1aa9c547, 0xd0e4bf7c8d39e62c, 0x41f860fbe8fce06a, + 0x2de83ccbfd1ac094, 0xc3ce2f80e0fce8e9, 0x86ed9b1a0c8def0b, 0x116e0144426adfb8, + 0xfd78921be5167fd5, 0xcd83d92b52136cdc, 0xabfad61c1539352f, 0x3e4cd550df4043f8, + 0x5754cfb87bd4f227, 0x2c24b4ec109bcad3, 0xa1dd0710b71ea5a6, 0x43e638a5f818fecd, + 0x12f318e7df523095, 0x33f7a07a7c723304, 0x2635a30153ae275d, 0x37c7df094a48d164, + 0xa8d6c8f952858308, 0x7f4623a6053b2556, 0x0dd25ae2a758fb51, 0x1d469fe8a5bde333, + 0x6763d1c9618f39dd, 0x041bec6279c756b0, 0x7a741d8733805fe8, 0x4d70defd6b327324, + 0x88c065a17ad19c3c, 0x24ed0da3a5edc777, 0xaf5e60604c85b16e, 0x65f88eb2a454f6fa, + 0xb13574b2d728ef34, 0x60c9bc022368155f, 0x0d9bca5081e50bf2, 0x610485d31289b338, + 0x397e225f601bb365, 0xbd1aa086053a48be, 0xf4572d22db8f125b, 0x4aad485f7aac325c, + 0xcf276d52ddc33b55, 0x637bcf12ed43fe58, 0xaaa35161486f1b86, 0xf5ac5165e47df597, + 0x0da32536b5e5c35a, 0x0ff43cff5de2a856, 0x872e23dd3f25435f, 0xa303a8f7b2697030, + 0x8934848e9d8fec01, 0xdcbe55dbc5eb13c4, 0xb1f412461b133130, 0x66f665175f207669, + 0x0678c27358912884, 0x4de84690f1312d37, 0xad88091c91f53094, 0x429a22c72a2a488d, + 0xb3a4122829259000, 0x002f99695410243b, 0xffdc89e0ab42822c, 0x08c94a3a89d895df, + 0x063b74450488a225, 0x1730c89ef2f3de37, 0xf0c1f0f99550778d, 0x454db280618eea7e, + 0x787deb2187ba379d, 0xfde199c7d7eec3b5, 0x09649f3da517d5db, 0x2fb9e6e4e51d5516, + 0xf2c97f9d3eb6c6c5, 0xe2fb63af84d5a623, 0x9fbda64c6baa62a2, 0xced24060270e75af, + 0x70cc2f97b7558f74, 0xf08d621c66630cf7, 0x3600fc580309138c, 0x50245e7c2236c75f, + 0xcc74a3ff00906ecb, 0x482b1a4de69b4a39, 0x6ba59e50f4c19a87, 0xebddec17fd4939e3, + 0x363600ddc796d9e5, 0xaae7d65a334c1678, 0x4ee0028825c61b6f, 0x144793541f59a194, + 0xfa61931e11726228, 0x19d42d170c4eac15, 0xddf5b943c269b683, 0x8a3fb2e8a4af6c1f, + 0x9e06ff8c378712d3, 0x0a64f84f4cb296e8, 0xf0b946488100011b, 0xa2f24aed45e4033a, + 0x060d6c531f4fa9da, 0x0dcdcca148160e2e, 0x7b15fdc0e51c056e, 0x8571c8893169662b, + 0xebdca8961db24d92, 0x592dfcaf7ae4d2cc, 0x453df6cc16dccdcf, 0xe0e4c14eabd00b9b, + 0x30e174c27ddac36b, 0xacd1b94f0a59c9e8, 0xe58b3c59fa53ff33, 0x5fbf90292afb7c92, + 0xab25d318867b753e, 0x2c3c121c9f5219c0, 0xa03e51efcba647b8, 0x538764f41e2bd44b, + 0xffa2883817f3e65a, 0x1dfd469cf7f0d3fa, 0xa73aa154a882e76e, 0xca4e32f72a101a58, + 0x84705f46b57d38d1, 0x6779821636393ab9, 0x241f6bf6246a91c6, 0x6c919a90dfd6b402, + 0x523f289e909d90d1, 0xcfa7170f9a779f7c, 0x5809befbc232c78b, 0x2313fec016554c73, + 0xd44b7f39b8b4149c, 0x76420e0d84c7d8e0, 0xa9f52f04db9045b9, 0xbee49bb2a137a8cc, + 0x59e2ed92623a86e2, 0x43f6b5ffc7c67e4c, 0x835a3c38e8d34b17, 0x1a2f600c8211912a, + 0x87ea59d910626e7d, 0x031990ad6f95c7a6, 0x50501101fb6f57c9, 0xa7415b33eaf73746, + 0x91a2bd5712227951, 0x864ea8083ca1cc96, 0xc6ff13e16598819d, 0x4f5d6fa10ab62f67, + 0x42cfab2790418130, 0x24b17b76bae4fe40, 0xa602eb62474a626d, 0xe424a91b2c023212, + 0x0d009a5d28175fee, 0xdf4bdbde09ed8f18, 0xe8062ad2f530d710, 0x6a175a1ad4f8eb59, + 0xade5db9504791e41, 0xf3de46739a868e3b, 0xb9218e693ae35116, 0x55d5c03b6b44aa63, + 0x62538d876da70dac, 0x8258bd53598bca63, 0x61e5d9970dc18902, 0x9bd7437e106e5908, + 0x2600057796ad5ada, 0x9e92d79f24ffd81c, 0xc6255ea184b4f129, 0x7fea5339a1b5c6a8, + 0x98b1e237f2cd6ab4, 0x44bfc24bea0dfebe, 0x310c92f4472c9afa, 0xc13672b884667927, + 0x1a19e9a878735364, 0xe626fe223a731e41, 0xa71e30710daae338, 0xea56117241f53416, + 0x4df1b81b833bca9a, 0x1a833c73b68db9c5, 0xc40118ee55ac2bf0, 0xb569ad6d9fd4d209, + 0x1c46476562b2334b, 0x9824ecf42f735560, 0xa8396b244e7be945, 0xf659aa22d2aec99e, + 0x032a375c2f764cc5, 0xe99222b7d5fd6609, 0x8af2b9338f51dfe1, 0xdc14cd6a9cf9182e, + 0xc2aac8a5fd198d63, 0x11520c8a1d7b42fa, 0x4f5c957aee98ba2b, 0xf8c73221ec3056d2, + 0x863ae3fcd4926155, 0xdfa1d3551bde5a0e, 0xe7ccd7cc5159743f, 0xfff12d0cda6e8215, + 0xa4123a90279ae8b1, 0x8c188230a016c60c, 0xa36d77d73b89772e, 0x58e28b702e0fee8b, + 0xd1abfa4e92028f34, 0x1d92d71df471f4b8, 0xeedeb23f952c8bdf, 0xa9110a198c3f0aa4, + 0x63ae1f52441530c5, 0x063f04d37e85a8ee, 0xd38a5441fbe5d452, 0xae240924ec5617b6, + 0xe96cf335e8968a36, 0x65a76bd10aa4298f, 0x4b58e24f57236a44, 0x7ecb4af94882339b, + 0xcaa7d4b52545f79c, 0x8d4adb8a0e6a8593, 0x99311288301c0d8e, 0x621496bb3f558f0f, + 0xa6b390072cb8f3b2, 0x9e9ec60586486e9f, 0xda2cf64ba06ee61a, 0xf0df488a0f065f61, + 0x9d6d2eb6acd75845, 0xb19b59801bec0938, 0x935f1ebc7af8cab9, 0xc82533ad41af0c33, + 0x317ef2b08867d1eb, 0xc09e3b6abf8ae567, 0x05ba1f408101d52f, 0xc3a0fb61de785a66, + 0x27313066704697bc, 0xfb7e7c218d400da7, 0x5da9da2ee881f599, 0xac9e0f8d72b31399, + 0xeff3c69fde28739a, 0xeb87b4b643590737, 0x45826f833feddc0b, 0x9dcaa555d756a8b5, + 0xa18d387235d3b972, 0xf2a8790ef300f856, 0x4dfef664672e214a, 0xd4febea00eef6475, + 0x9a97c7d97ac67707, 0xfb3f5e2d15d3d9f8, 0xe52754c8da1677bb, 0x43e36f42ccaa4933, + 0x9613d6d82e183609, 0xb6835fca18c1ce9c, 0x7bd7ef4d73b8d9f9, 0x6d00b20b29962b07, + 0x5e3cca4a840d0717, 0x659cdfaf7882c9fc, 0xdba27789f4758c32, 0xe8d0398ae794ebb1, + 0xb9c4d1a94dc4adda, 0x861f452c6552ed27, 0x820360b94da62afb, 0x8115f483cb399862, + 0x237884e299398899, 0x33de616ba36f5232, 0x8a49c6e6e6dac91c, 0x852a28316d07e48e, + 0xa042ecc71f823cd1, 0xe81facf64860d209, 0x5ba68b6b4f32a1e4, 0xc99102cb20c610c9, + 0x1126ece1b950e891, 0xbf149ada30137605, 0x52381e330f946f93, 0x95132a0e38acf477, + 0x7fd1c98b811bde3a, 0xddf18b3542ea4c9b, 0x802db7c1feee204e, 0x245775138833095e, + 0x40ff552ac4bc5d32, 0x0cdfda4b0638bba2, 0xa606d196cbb8c694, 0xd9d95fcdff5f7451, + 0x8b5557d6533b69a6, 0x8e88f9850cc2f852, 0x684a9e695b242115, 0x4876b7d3347a81f8, + 0xcbafb295bee2b83f, 0x0a5484a1c7780fcf, 0x379a84716b85f9c4, 0x5c3635f9756d00ac, + 0xd24deca07b61797a, 0xccd37c60cc9e3e8a, 0x94a31d31fc2789f7, 0x8214df5b2bbd2f68, + 0x6254213323cab4e5, 0x94be7e8dff8e5634, 0xbe1bd0b7871af504, 0x240c21bf719f816f, + 0x01c3c63066908fb3, 0x1d9e0ccef998da12, 0x5f766521e12bce37, 0xb270c10142ecfa23, + 0x014e0f358be85d68, 0x54f2b42c59fe38c0, 0xc24b58e3a51e7da1, 0x30592effa54aa2de, + 0x4143d2f2ad13d11a, 0xc1ded44911227f5e, 0x1fa501b45c6a370c, 0xfe8cd4bdf58908af, + 0x795f0aef03db7b7e, 0x94c58119d9e05de1, 0x06e5834300d7b908, 0xc824aa02f4fa9a03, + 0x7268ffd3c9b4c154, 0x55098bb851a26978, 0x0b6cd048964279b0, 0x78f9250b5cb5b86d, + 0xbe0bc33281e04428, 0xa3b4c7292a9637d5, 0xe5bd5144205fee15, 0xb999f068bde150bc, + 0x731695a867103c9b, 0x4c5dedda2a413479, 0x19860c4c68cf56db, 0x10613609c0e7ef69, + 0x28b6782fc15876cc, 0xe167c7892707727f, 0xcbdc49ef9d4aed08, 0x7aaf5d233ad39d1c, + 0xba1a083965d2a7a9, 0x7233a9b59210d680, 0x9868e5deaa900af7, 0xfffe4e1b775f163b, + 0xd5b11cc522bc04a3, 0x675d09684778a5d6, 0xf7f6fa6de487cf75, 0x700153765f780edf, + 0x5463ce19cff4f6d8, 0x3e00c8bf52f800b5, 0xb5b968ab19460284, 0xa26ebbe50f7bb10d, + 0x0ca3a0a275b9894a, 0xef81eaaa40281ebb, 0xc47ffb9125125c63, 0xd9ae3b433f7b0852, + 0x6ecbde3e063ecd03, 0x2caf0e1e1f13b480, 0x8637378dbc3f8ae7, 0xfcd393580ea5f21b, + 0xb9aab423906d70f4, 0x9ca2c07ef99df892, 0xf52843628826fd30, 0xaba37ed84ba81250, + 0x43d56fba2a12d0f4, 0xa3617a11a6973362, 0x380b8b016da5c85d, 0xb4a2e1ddc5d5f348, + 0x2a1a903ac4c79209, 0x3035042671bc6454, 0x03555c165408e963, 0x154c97f28413db39, + 0xd6d50dee18186c78, 0xa6e5dfa031222c0d, 0x3aed9b26e827673c, 0x64a6f8f56f2db5fb, + 0x889a7fa8d0f04dcb, 0xb8f4e5cf13109b35, 0x1e63f37590369cef, 0x559fa563efb5ca3f, + 0x9aa15574406f0536, 0x4910b6462567d60d, 0x666eab8030bf51b6, 0x478c428ba59e8b51, + 0x6b385f255d12ed39, 0xaf97b8d21d1c242f, 0xd6b9f9426574b3ed, 0x5490ff7f4159cda1, + 0x1ed0fb9337e39679, 0xae5fe635e1458915, 0xc0c8610cf6ccf6ea, 0x338268ac72c33b40, + 0xfa6b4a1f79eaa19a, 0xc94a08daa8b626f5, 0x330a64fec8dfd1c9, 0xcee9885dde949eeb, + 0x6c7a90b78545cf2f, 0x8c361abf391bd857, 0x8b2d258c91707521, 0xd1251b7eb6c92cd5, + 0xe18cb1350fe9e506, 0x3c6f264c64e021e6, 0xa904d9fcf9e98505, 0xe2f3179398d9e255, + 0x41fc05718e0efdca, 0x18694512f11e6f5c, 0x796d7d6de3c56cce, 0x8750c809f3187256, + 0x27b1ffe3b720d5a6, 0x549f16728cf85624, 0xf1e46a57f86fc22a, 0x2aa19c51650117bb, + 0x6ebb3384994de433, 0x8013e7b71d225d4a, 0x98f71e1ecb1d7e05, 0x5d3a68e0d70dd717, + 0x1016dd44033e6e58, 0x45655a280dd2ffc0, 0xac445c188cb83fa5, 0xee8794bf6e86eea5, + 0xe0b701793960373d, 0x0b5ea77784410900, 0xa559e735132de5aa, 0xf500e32b260c885a, + 0xb1e8576c036a135a, 0xccd8a322cb9b5454, 0x9c08dee4318a6c7e, 0x9c66212d00c5ed65, + 0xfaa161b2f0d8a84e, 0xd661eafe830a544e, 0xb2fbe19e4a001e57, 0xc69ddc3849e5a8ce, + 0x0202a97a4550a1cd, 0xbb5201ab15502834, 0xcc024394d4c14584, 0x41011d88f2574bee, + 0x6643243206eed0e6, 0x11556256cafd8582, 0x70f8253dec0926bf, 0xe8471cd32cc6c2ba, + 0x10e92be519994072, 0xa804e4eca3282925, 0x3504ccb577bc7866, 0x9578d853e6ab1234, + 0x1baa928dfd2a1894, 0x0543d2f849ac5c03, 0x251f607478d7e630, 0x39522e3fa80f8d35, + 0x018851a699b8154a, 0x00a01a798478e8e2, 0x4364dc7af98d9beb, 0xa20d40c41cba6f59, + 0x5cc492bd0042692c, 0xecbf19fce779da87, 0xff74a5fdf5b8acb6, 0x31f86a5c6add803e, + 0xda9e08a088049e35, 0x5587aff23b2058be, 0x14cb4446f2d1c3d1, 0x4671dc16e06bb9a2, + 0xda2538d25708e607, 0x909f4e64bbe4f9f6, 0xfd972f9b74acb689, 0xee5c9af65935af84, + 0xe6e1785416c52875, 0x5d02fc7e10041ffb, 0xae1673cb2a647c3a, 0xe1fe785a4c0b0ad4, + 0x083a329b97d0baf0, 0x23264b5a053a2ae5, 0x043cd21d02a08b4a, 0x706962b35833d46f, + 0x8abdf4b88ee771f3, 0xcb69e30641684dcb, 0x730daab85ccd3253, 0x30dc6048d99e65d3, + 0xe7874e20649af92b, 0xe396d9ca45aea0ae, 0x75250cd13887dad4, 0xc89d2dd53ec7465f, + 0x4f399644b67db281, 0x4ac371648c34c3da, 0xd857f45288b347e0, 0xea3ba39c166ae08e, + 0x3859af1f086cd7f3, 0x8293a3c9d61a3fe7, 0x3e7b025fa147730e, 0x224737783a94211c, + 0x32cb4a211cf7972f, 0x4276f35837e10451, 0xe052dadd1e347823, 0x85a1a94f1098c375, + 0x0827e7e5e855019a, 0x833080395f045293, 0x5e2e70b19bd1c5a7, 0xeb1097f7683526cc, + 0xc86ecefa804337ef, 0x4bde63709aadc777, 0x22a684087e4a8010, 0x0f8695cb99ca5e01, + 0x1e560d8b67f7bc74, 0xefe51845ba56e760, 0xd030f86ed9ee6ad8, 0x2ee42f15b048b3cc, + 0x3fd00c265c84f2f4, 0x85d4627a151bea4c, 0x3a6f606a482f1859, 0xd2e3fa4f1cf5b0f1, + 0x716849a30aede00d, 0x08b19859432b9752, 0xaabdd1ed72739964, 0xbc4daceec4df66dc, + 0x6b831158978777ac, 0x8328d232ba98a4a6, 0xb7f8f781388b7de4, 0x2c14cadf52e0388a, + 0xd2266b6da5a1683f, 0xfb0e7886b1fa2b99, 0xe2da049dc11f10c3, 0x0d43c3d03eda76d0, + 0x33e15a035ac05914, 0x2c19b3adc49c9176, 0x75185435bf9e2a5b, 0xcf281166491aba61, + 0x00ca1f0aefeef585, 0x1745814208184064, 0x451ba9f6b4f49551, 0x638cd6654f397015, + 0x0212ced2ce4c98eb, 0xbc05e6d2b2708cdf, 0x19c1f2140d929467, 0x3203eadda12e3174, + 0x6f67ef9cf81497f5, 0x9e402adeb5f1457e, 0x454b53629e60af41, 0x8023cf7104e9933e, + 0x36def0cc437a53e3, 0x8458074605a77a48, 0x77f87ba28e26b8c5, 0x3d542cc239167542, + 0x31be47f87d56c70f, 0x726f8c81e2c7f4dc, 0xafc7a0d93c66af34, 0xb61f0b62253e2d3f, + 0xbd773fa717890681, 0x40138543ce601c2d, 0xcf73e06624188758, 0x391dc28fc9ff2f4c, + 0x922a4f626675a851, 0x569478df62af0ddf, 0x89a7d06f32a02059, 0x625f2b869ced41c6, + 0xe1c1ff7d11d3cde1, 0xa9d48a4810e5c51a, 0x3c134a91e675bfa9, 0x09d8c7ed98218c47, + 0x12194e8028971e69, 0x55603e2de2ffb98b, 0xa925cc47c9928d9a, 0x80f9848802d50eb1, + 0x2c6ecfc2540cd507, 0xf2487cea7b1498d5, 0x66ba7bb95700ead9, 0x521d45543be69284, + 0x2d8d3561e66f22a1, 0x591e96366b295a83, 0x81a1ff8a05a7e5b2, 0x028ec9d94da3609b, + 0x28ac6c61fc61bfd9, 0x8250708c4ef07485, 0xc8125f1ab284b359, 0x13e6952a62e7bbde, + 0x623c56de1fd89c9d, 0x4e20acc54aaed848, 0x4ef457dbf0efecf5, 0x41e38ef446680dda, + 0x6197eb1528b376db, 0x13b39482fde8d77e, 0x109750a3314c391c, 0x9c70b0ce5f5ec51b, + 0xf453be341849e91b, 0xb8396b449edb9546, 0x0022e468baf82338, 0xad9ee0903f4929e3, + 0x5ec1234cb41517a5, 0xd141db281f004390, 0xc15625feef7ec18a, 0xa90066e00ea03aa8, + 0x1e047bd6711613e2, 0xd793c2026c0f2e60, 0x7abf117905229c8e, 0x226a709515315f70, + 0x5f9684d3c3612a1e, 0x562a30fb77554921, 0x97ead97b7b7e6b22, 0xe5cff3adda1cd02b, + 0x655f1af80fa15186, 0x7345face5c4482e2, 0x180c9c070c3ca83b, 0x1b658d13d49f8ac3, + 0xab58549b16a3887f, 0xa73ae60ffef6fa1d, 0x04115aff4d29c200, 0x26283a1bcf4ceac1, + 0x6fc3ae3305646025, 0x19dbb964e49be7d3, 0x2776df09550c1a39, 0xe91513f837b19cab, + 0xd20087dd46911281, 0x4a4569bb7e3ca076, 0xdf3d518e5697b2e3, 0xb1bece4faea8ac79, + 0x876fc66d101a515d, 0x0a1c0d78416692ad, 0x3886cdc1366045f4, 0x8b7647f44d9eaf43, + 0xc5a86f03d26d553b, 0xfc12ab5d91cee813, 0x7ad9d3998f6b0af1, 0xc778bfef06183622, + 0x9eb86932a37673bf, 0x8edb9abfc8f54c5d, 0x1bca142da9f38a19, 0x36b464c1d0fd37ba, + 0xee60f33d53fc2464, 0x727a8248f31ad112, 0x024ef6fd4bd75356, 0xfd90b916b572fb55, + 0x57078fb4b066503c, 0x1eb207a666c15a2e, 0xa785b22920436534, 0x77ac6e3d2bd96215, + 0xe630ee0b3ad5b288, 0x56f37915a453023c, 0x1c3de3dfcb8b4eb9, 0x479eadfe07352d21, + 0x76b48fdf728d1cfd, 0x74f2e71cd052f72b, 0x161747d06180c1f3, 0x054f22b764b05d94, + 0xa6b35c301d4c4d00, 0xad118c64d632af3b, 0x9156789f021745b9, 0xacaa151ffe95587b, + 0x93ba011a15d3f552, 0x6c38c7596e86f2e1, 0x4f2786b8c8dce81d, 0xe2f87565bdbfe0e0, + 0x29107eafedb6981b, 0x2fdc28728c80c606, 0xbe20c8463783b13a, 0xaa06cb808ce0037b, + 0xf3aa9ce4103e6f79, 0x907a939887d86dc7, 0x677178e8bced5b57, 0x5b1582a63dec5a4b, + 0x7d26d21504c621d7, 0x6ed2f3a34e3799a3, 0x53339e316d3008d2, 0xb4d11dacf011839b, + 0x4e7e388eabb29a89, 0x49097f4c623bcc8e, 0x722b6dde507cc24d, 0xa5326b4078cbb89e, + 0x491ad8c6e249dc3f, 0x43711c8337922bbb, 0xc5b51efea0b486c7, 0xf1ce1df772b22fd1, + 0xc403cd336be0b1e9, 0xb9146efa2db9a078, 0x61bb5b6afb229709, 0xfbbc021cfe25a799, + 0x1cfed07a04862332, 0x1a49b9af69536029, 0xb3ed4ad3993f88f8, 0x946802c4952d88dd, + 0x269a05fab8481f81, 0xedd3b5db65035079, 0x0ae491c1baca615a, 0x52000e1f174c924e, + 0x7f9192ba11bb2b27, 0xc97c35caf0344d14, 0x231de837bfd5221e, 0x5da764e851f442d3, + 0x76e065794601d62a, 0xe1b37c191213c10e, 0xc5e1856069aab680, 0x972a3f8b240d392e, + 0xa2fd25f6c1955f72, 0x54fb3eac001a7ad0, 0xba1531ba6d2f3936, 0x3fd58d0818ab0313, + 0x8c414597e15eb94d, 0x0ee41b52e0159459, 0x602b8a0189bd4ea8, 0x2c716b2e60c86107, + 0xb338446de8a48989, 0x0690883dc5920ded, 0xa40ab53477cf4ed2, 0xd576b3a92294ca76, + 0xbed9c2154aae2812, 0x8d37a9be2e47bb8f, 0xa20d4891d9027792, 0xe6eebe8f14af176f, + 0x4771974c22c03dcb, 0x9720809ad1da6154, 0xe5fb9cd6e3efb18c, 0xef80997d1a7f437c, + 0xb8f86924e3d9e2c8, 0x177fb4fb05173157, 0x099d6e7b998a734a, 0x2ab47ac36b48e367, + 0xfa6500074c71bf62, 0xc2e6b4ce767b0496, 0x01e55f7fa760326d, 0x7a97a7e56a954d88, + 0xbe2962d62a04185d, 0x888839de9820e529, 0x500edf47e0e04041, 0x3796395868aac21c, + 0xfb2aeb98e1e48f94, 0x6693dd65032fe96d, 0xe1bf07d6d6732db2, 0x7c64fca529adf93e, + 0x40bf58f1183b2a12, 0x1187d9a74a52d59a, 0xab34438b0f6bffa1, 0xf427b44b819e7d76, + 0x9dc6868428366ac7, 0x66173e587002f51d, 0xb299339d9a0b9f50, 0x78461075d04e91f4, + 0x465ed038aaa73c96, 0xb3c4734c25c18a56, 0xb13e363299925311, 0x4048bae92300aa84, + 0xa1f77346edfc2a3a, 0xae238dd794966cc6, 0xf228a2d5eb39a25c, 0xc4e8feb578a120c2, + 0x2c4f662b8052270c, 0x41bcfaa72d541fa1, 0x66a9895b5620df83, 0xef0e0f55ddbb933b, + 0x3ab039cbe0b7eb21, 0xbcb69bdfe916a98c, 0xe5cec9971be6d5c0, 0x2e5f5d48b7830410, + 0x5c6fbdf4606ddaff, 0xb2fcc8d0a5418f55, 0x8dea46cb2f0fef24, 0x8975970884dc4a75, + 0x73e366243a52b8b2, 0x24668c6f451f2fbf, 0x7e5627df587a9f29, 0x6d682aaac228c369, + 0x5279032048195017, 0xcc2dcde3d451a194, 0x7ec68ecc12ca1241, 0xec761a369113fac4, + 0xacca32093e839f34, 0xd8e85def68c7b937, 0x37f896381ba769a8, 0xf53ef3339c67293c, + 0xa3408ce70191acb9, 0xd07a6e2b61716155, 0x4522f7c85c5dcec9, 0x8015a5fbbd326d12, + 0xaed5dc14824341bc, 0x9df90292f8fae0c6, 0x4f6679d9b7698702, 0x1ec7b4e8e7ad950c, + 0x89780c6aaf7939ea, 0x2c273f2bb96c26ae, 0xb037e946828bdd31, 0x80abc571eed2c562, + 0x503c3f2050e44ecd, 0xf7f7942ebd014e83, 0x42a5e67bbcef697b, 0x1ddc59698b3d3dc2, + 0xb54f90bba83cc76b, 0x7d9864348962f362, 0x7a2d1117ac3d4a02, 0x85d76aeb682f984d, + 0x6b4c425d72fe783b, 0x19a9e12d770d0064, 0x34ea92d722ec8647, 0x88f2ed9ad464bb43, + 0xec027a664da1889b, 0xba6d671f92531026, 0x00d90c2a74ad1012, 0x533ecd35aad00cd6, + 0xd23c644e9360654a, 0x25c9448301ddb8a7, 0x3ad3bee2779d25d7, 0x181ce62da74ede33, + 0xb6ecb4c35bc8d42f, 0xbcfdc622ece12ffa, 0xa1870fb047a3d4e1, 0xd3eb9c4716f80738, + 0xd2a412096a3f4488, 0x01297abb74569639, 0x769264a279c90f13, 0xc751ed7184ab9a56, + 0x5240164dcf1c6fa9, 0xe83fb0f787d3e5d9, 0xce5e2eb53ea7f0a5, 0x874b28415ec70e9c, + 0xd6649614b59e5c36, 0xd6d63200186762bc, 0x22910b08da546a69, 0xb07de692d1daa480, + 0x46af88c708d45013, 0x9a9dede7382d8f36, 0xb8428155c6efd2fa, 0xb4580e336ddf42b6, + 0x6891205dabde1484, 0x760dfae37a143dbc, 0x03a36c4aa4199645, 0x7e65d0b89f655d95, + 0x9c218ad8ef9c78e6, 0xc3369f3491c2c9d2, 0x3cb96fd63384a50b, 0xc0dbad06f5f4bc0f, + 0xe71fe7ca546abf1e, 0x5a4405b477462888, 0x42bb56f29e04e9c6, 0x09f10f91138f4c39, + 0xd93803bc63a92c9b, 0xb915d6d8cf821bc0, 0xc65f626b8ff54aa3, 0x7f5c919eb7fbda62, + 0x65911c7a02cf283a, 0x73281cfd071190d4, 0x5d6e2943e10ae9bb, 0xef429df4a7f04db5, + 0xc0c656a699ed6d16, 0x0622d0792b9b3a21, 0xf5384ec459862cfa, 0xa7a9e4e92aa38ff8, + 0x2218759e25514541, 0x4f9f3a01de4986ef, 0xb10f98ae9866c810, 0x685b59dbf3114465, + 0x0b09e8ae7e3d2529, 0xf56ffa1452d773a1, 0xce55a6f6bc2bf562, 0x99bbd97c36355558, + 0x496831093a3e15a0, 0x8f9caec5345bbd63, 0xc0d86a417b911e03, 0xa33f6c31a74cc5a3, + 0x8ebc655438425902, 0xe381c4f7764373c0, 0xf55a1c9e527a2731, 0x823ec8c368aab1c6, + 0x3d56702357bfba4c, 0xe719e916b1d2c3cb, 0x05076d29150fb0ef, 0x34913ad9987f7c5d, + 0x3abe27794c37e45a, 0x6f98dcfb78cc87a4, 0x96a42c41305964e3, 0xe7c6a9fb11397a92, + 0xb23fe0b3755b644e, 0x38f3db604088ef31, 0x62ae789848c8c9d3, 0x239aa9413fbe563f, + 0x1dbbfd965acd3149, 0x25a1dc234de6fe2b, 0x709c33f91148c1c9, 0xadbe865b9f892a9b, + 0xadf74b56f106fa98, 0x91d26ecc00e05256, 0xc3328631fc94ebd4, 0x6f0179946661ce19, + 0xbc2cb204ab3bf7b7, 0xfe03a40b16bc4d16, 0x0f9176898d8f6153, 0xd6f4b68bcde84855, + 0x126dbedfd951547e, 0x8db675af0b95a7a9, 0x32e98cb64eac5dbe, 0x11423778266edeb6, + 0xa4f5d36923d2d92f, 0x27307061f552af7a, 0x0979aa7278c25258, 0xd538aa39ba8eb09e, + 0x3e333d60df10d31c, 0x1232e63b4e72d129, 0xff67f7208d677e79, 0x61201f03653e4de1, + 0x4409efdefe1a5420, 0x07227698fd2e0f4c, 0x0cabb47437416f3d, 0x1ae37b275ba4339a, + 0xd2d03031b8a6cb6e, 0x1ec07582dc32dd8f, 0xc6ddad706c85e52e, 0x2c719a6f0f892b07, + 0xca68bc87d3dca8e9, 0x20825984b6a7f4e8, 0x86349eb3c86d3f4c, 0x68c5a19b46738c9e, + 0x6c32fb552d91eecf, 0x7f5104999c712589, 0xdd20f345061021a4, 0x53db0e051a2691af, + 0x3420ea96e2b8707a, 0x53d4113a642189b6, 0xdcf6aa13a8620074, 0xbaceb1794477e8bf, + 0xc22e146650c567e8, 0x02d3c79ea404eae6, 0x6ff893a218106f2d, 0xd85d85a21739ea6c, + 0x100181abae3103a1, 0x032a3d5647aa66c1, 0xa556adf0c6446d9a, 0x0de36eaa1eedc0ec, + 0x3a6f5c82b6598293, 0x1ad09dd8f1f6a844, 0xc6012f0773e42d82, 0x0062e12c4b44c1cc, + 0x87a9b95a1246440f, 0x23bfb761f9409acc, 0xd80e34e1b0d0691b, 0xecac8111ea8f5acf, + 0xd69635d36870dcd8, 0xc6b136fc4ab64dec, 0xde37f8fb3ebda559, 0xf552b729252b4783, + 0x3f0950b5f68f7b48, 0xdeb07e8ae69d32ba, 0x63e66a9b127dd194, 0xae9e7170d5b2c12b, + 0xe56bf1ce883f8487, 0x1cdfdf0b63131f94, 0x9713659daca9e4fd, 0xf35734314e55e4be, + 0xc9e3b2643ebc2705, 0x355c1b09c368b25b, 0xc97cbb39df605ad8, 0x232291c66727d056, + 0x3eb39cda80c763ca, 0x7f2e4f127124dc35, 0x8f019ebbd1d82951, 0x90183ff36c13f27d, + 0x9cbda72f0537ea9a, 0xf0d1f96cb23654d0, 0xc1ec494c524b54ff, 0x4c563293f3ba922b, + 0xda9a3be3eb9a451f, 0x387582963ed394f9, 0x20a5000297ada968, 0xfe6ba93f9974c0c1, + 0x1105ea348744a8ba, 0x044a2085ba1e3a04, 0x72fc7523a1248809, 0x91588900b5471948, + 0x076a127be3cb2ac2, 0xf9069daa30d7828b, 0xe68ab5ef90c4ca66, 0xb24b4ef407ffebc1, + 0x0bbac86fa86e1615, 0xb21f73a153dfbb47, 0xb3cee6626d2e2294, 0xba166715653d2f0c, + 0x963babd45885f69f, 0xb79f1aa5d6b0279a, 0x4ae5916dbffd1b0c, 0x2f2f10f0c93fd6ad, + 0xbb34c9021619c092, 0x5511965d670d7036, 0x774cfac30a443bd8, 0xe66fd0d24a0658a5, + 0xee0dfc83cb040225, 0x8c633674dea5fd96, 0x59c00dbb213ed125, 0x2fea9af77622c77d, + 0xf3147a5b6c624209, 0xf515673029f99236, 0xf620be1322c847ed, 0x4ed126fde6a16377, + 0x669f15cf97f240f4, 0xe3496c8fafa842ac, 0xc83eaf3dce2da5b2, 0xdf6b5b3929b13b69, + 0x08f758972fb36325, 0x664e33d6b27cbae8, 0xc7a217b682d4facb, 0xcc34790025415f2b, + 0xa2c7ff1db20fbdaf, 0x3b8f8b680bc0588e, 0xfabdaeb9e9f35a5f, 0x9e46351eb59d85e0, + 0xd78a16b202bedb2d, 0xed428ba2725cd9d2, 0x8245f3e27d204362, 0x03e8419aa2670231, + 0x2819776aed364db1, 0x434e086a524af0e2, 0x5b890b46beeeb636, 0x9faab818988901ac, + 0x19ce5a720bcefda3, 0x668c6d504768d9c8, 0x938690724942bf44, 0xaf83e7d6b86fb97d, + 0xe237de1e926ba148, 0x63860d49e5b910b5, 0x8f31699c7045927e, 0xa6b7a6839a3ee5a5, + 0x172b2f39c88f6689, 0x2dcbb436d4c18bf2, 0xa3cd26016b3cde5c, 0xb97a6331729d1060, + 0x8c490834b4a8f011, 0x392c2deb71099e99, 0xcc26f008a6be7cf1, 0xb8b12ac4ce7c46cf, + 0x8dba8e9a44bd5384, 0x56fe2cd736e0b3e1, 0x781aef2b6842f9b8, 0xf93be6a99c87fc02, + 0x33c90e8ada400a19, 0x46e21ccfd03e5b83, 0x7c7e398e3611a9f4, 0xe2fe19a99002ca5d, + 0xdb9f7d911f337f1c, 0x9cd7cf5b5eaa3f8c, 0x2d905bedbdfd232b, 0x8b4dc17c91f912de, + 0x3aff094c26b5d588, 0x9600083d4afcd5a6, 0x9b5fd8d2d9412eef, 0xbdec0efdca269862, + 0xa5eeae604c8fca53, 0xe72f6db4e787ab70, 0xcf24eb18ba0b357c, 0xaf7c0b8c008818bf, + 0x3544569f11e18d8e, 0xe32f8363072f33f0, 0x479791ebd27756fe, 0x6dd2e11cb4133c40, + 0x2dbaec795927129e, 0x3ff3d18a6ef14166, 0xb9a885c175f77a7e, 0x6a9d193c55e56b3d, + 0x957190afff254fc4, 0xa267ecf33e716bda, 0xb0491a1f20aae7fa, 0x56a2653559317f64, + 0x5826bd7c4e824440, 0xcd38c5a39cf973de, 0x332b63f3edb2aab6, 0xab72c7d360075cfa, + 0xb59998dd9b46dfba, 0xa783864a68bb5951, 0xab3dc539b2e9f181, 0xdc6ace5b06cd2351, + 0xaa44c2b701f76bd5, 0x9570ef871d2c5671, 0x3abc1779dc4a1d91, 0xbe3f6dfdf397e236, + 0x8782703585e2402d, 0x40e0fae0369869be, 0x4372d02c3135fb71, 0x6990bc9942e34a90, + 0x9fe66fb1c398a25e, 0xd689259d8dbd9378, 0xc4bf8980c5e7899b, 0xa01436636760501a, + 0x7ea1e356af9ea92c, 0xce8aeb37255ba5af, 0x6054970044f75e20, 0x8f4ce8693aae56ba, + 0x2a2f54e3388c4166, 0x54aa2e98c47dc653, 0xa0401a1a6e50720e, 0x2be689184fb13ce6, + 0x934418f886377da4, 0xbc10847d7450b5d3, 0x2de67e260d1d21c3, 0x68451ffd44a4bf9f, + 0x30620b7318ff2f88, 0xfe73fccc80811845, 0x32eac98006d06412, 0x9695e22be28cb1fe, + 0xc0626be28e463065, 0x1d978f6ca8c1cb8d, 0x21c6a55cdf7de27c, 0x83108de4e95fd62a, + 0x43783f9693797980, 0xf00e8699ea8e0229, 0x961a83d2c37dec5d, 0xc13696499c774c7a, + 0x78cd0c371e1c457e, 0x407141d9790b5889, 0xa1609588b3e6b50e, 0x75105adfdc9b6ef6, + 0xe24585a05b278786, 0x4d95b02c0bc78d64, 0xa4e8a0add35cb044, 0x7f23f5be2787bfac, + 0x0a51a1924e4c0d82, 0x5b728185d7091af4, 0x78737260f43f4845, 0x4c23e562ac375339, + 0xaf9b1793dbf4e0cf, 0xde4e145d0f853896, 0x26c49f78b4e07403, 0x812102c6f16c0568, + 0x2ea7878a5663df55, 0xba66060ef6fb8d73, 0xdce96610cbc8e0e8, 0x488a0069ee3caba7, + 0xd5ffa8ba232d1439, 0xbc9c448692a7c421, 0x0dd00b8277a68b73, 0x355b52f0a5ce41f4, + 0xc4a8f9ed0380b160, 0x38e229e3b5ec0812, 0x601cc1b86d6ffe62, 0x688bc39703febabc, + 0x0f95a8c0ea5bed6f, 0x369ed8a1331494f1, 0xb1e4b427765eb4aa, 0x7a01668ea959449c, + 0x6073e6f15b1446aa, 0xc8c9e953bf0eaf4b, 0x0c194f14aa7846a2, 0xbf7ae10412664c59, + 0x694764ed3535dee2, 0x869b82f11065e11f, 0x1ac2299b6309224a, 0x1dd45d7176902db9, + 0xdecbaaa8fbfc0c20, 0xb699d6bf06d1fdfa, 0xbd7e4a1c8201a815, 0x46c1ca2a33d49629, + 0x271aa363bbb576ed, 0xef7fe423e9c97d86, 0x76ae31116e2d2966, 0x2bee96ad31fb00fc, + 0x71adf27aa7a6e1ee, 0x8c2cac353289422b, 0xb2378b3c1b99088f, 0x22991fbc87efbadf, + 0xd2d55186ffad6744, 0x05fe6be9606bda8b, 0xf86715945edcf68d, 0x015ff53fd82cf7bd, + 0x78d45eda5d37cfe9, 0x20abf5c21f84e8e9, 0xae73a1a15302c7ec, 0x9cb82f6ee82858b3, + 0x7f4f31ca941c61f1, 0x6b94557960d67c71, 0x31d0dfe8fc8944a1, 0x50f12a7628f2ea2d, + 0x2eaa5d4023623ec1, 0xeb1e499efbb32689, 0xaea21d3decfed5ec, 0x8944e826b1371175, + 0x95489f59c62a5848, 0xc3d31e459152ed34, 0xb0267f97a063595e, 0xa43eacdf7f650897, + 0x4d8cdcad2e8302f4, 0x1b55dd7ba996e99b, 0xade8c5d0ea304b28, 0x61ab212e3c84d64a, + 0xdb4534e0db75e5d4, 0xeeaa189d892ebf1d, 0xcba9c304824b6f3c, 0xc3a22b38c6c67eb5, + 0x8d5149ec4cdf3b41, 0xe25c78efdc648ed2, 0x06d5daa21960b7df, 0x169e8302da0f77de, + 0x77cb37a7ebdb8a2d, 0x6e68ea33dcad0eae, 0xfa3e08ce93f169be, 0xc757932177c4016a, + 0xe00a619a181b2150, 0x396470f5df5e8912, 0xa91a5e539cc898b2, 0x5768db8e917e934e, + 0x11e9daa7821b464c, 0x3911d856f15c3685, 0xce4cd7e6e2db81ba, 0x36b089acc742f065, + 0xa911a3fcf08e2b92, 0xafd509abdba05dcc, 0xe007d15d9ed3fa0e, 0xc0d7f1c43e5ea14a, + 0xce78a4bd34d58ba8, 0xa35ded7167645f5f, 0x16776dc4a2aacc15, 0x2d63bcb9c14d3e53, + 0x15fe78017cedb5af, 0x758a9cdd4c333287, 0x1246e841e73bdb0f, 0x17d22d203071b16b, + 0x664b2f1c121c85ea, 0xa274ef7d881ec1c9, 0xddaf37e0b89fb8b2, 0x47062aeb8fc193a9, + 0xcfb6b81ccc2e29e3, 0x91077bbb58ae3a8a, 0xe58a0a785deffa69, 0xd4e27c60bf9029c3, + 0xc489ca68daeeb151, 0x309bafe347a5b2b4, 0xebd9628dead55acc, 0x7985f049869fd476, + 0x51af7cee0d1854bd, 0xa26ab3e79440d934, 0xa294562d9cc0cae4, 0x6de3119419a0bf0b, + 0x45650c8f9fb6390d, 0x416c211c0199a699, 0x4c41fc045bf7c9b2, 0x7d1f3fceaaba3c90, + 0x553372cf673b2802, 0x98c5d72cef3cb60f, 0x3dd999174c21f06e, 0xa715b4c71e850056, + 0x1bf0fe75f44ba42b, 0x7569bf028bfd4afe, 0xc88dfb797cc611d4, 0x9d7eef787dc6c5f9, + 0xb983bef48c06dcce, 0x465c982534c2d6b4, 0xad82bccbb97eaad5, 0xab99c583f0e3533f, + 0x079b2cc30740b636, 0xc243f006c7ea6992, 0x6a47bc4cebfff325, 0x4f279336f7f37af7, + 0x35da4a7c18178644, 0x63d0e77ebe46d719, 0xcb3e316da4e2e649, 0xc2fced014d8d2ab3, + 0x3430b00e2fd590e0, 0x3e8bd9d4001f1250, 0xd5be1451c928d1b3, 0xa284a5fd14fb64b7, + 0xcaffe00098b69352, 0x676661d83b036624, 0x907e4945c93225cc, 0xe248376164a715d2, + 0x1b9f3e247e7ab874, 0x75b927b5c60ea8c5, 0xd7fc4b0586e2ceb1, 0x2960f3f477ef6b3f, + 0x9956715c9d9456c3, 0x2e6fd60508af45fe, 0x853fda99042ff206, 0xacaa0423fa213c47, + 0xed87c3f6fbd9670b, 0x30caa54de8318f69, 0xdcf48ff054741406, 0x625f6bce3a0f32e4, + 0xbd39dc1e51a31090, 0x8eefca612265be7f, 0xad1e144841a7c787, 0x26f22f048d3e4739, + 0xc41d817310fdb810, 0xa00876d1eecc42c8, 0xb12d734872ec4526, 0x7472acac9ba6cd87, + 0xd496db95a5cc9ba4, 0xeb27edb7979d560b, 0x0a7e9ce68b2726c8, 0xadaca9774f879e4e, + 0x2ca874c613a30479, 0xda7d8e8e44e6f7a7, 0xaf7f2cfc3e7c6d16, 0x8de4aaed8ab941e7, + 0x87fe8b1f8412783b, 0x072e41dcdc89be3e, 0x90a2ca3a210e8393, 0x1dfe6d2b30fedba5, + 0x296b29862b793233, 0x855a7cbde0441fee, 0xe8550c0f53709a59, 0xe05202a4c8c2ee37, + 0x19080e1fd23feafd, 0x9477af7f684d75b6, 0x7ace23526a936769, 0xea9fc1a2c973db32, + 0x4767a23de768ceb4, 0xa85cc028e989dbcf, 0x9a4e4859eea2ade6, 0x14a1fdafe526f87f, + 0x1012c1e66b5d88c3, 0xfa73c66aaa01ad68, 0xee8eed95879ccc63, 0xdba806dda672fb62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x568a5ada3d11fc00, 0xf16449014eb881a4, 0xfdb9a3a516062f82, 0x1eb2cc06c3a45f29, + 0x0551f4d6abb5a6b8, 0x7ac9d46537ca1cc5, 0xb1d327b4a4225f64, 0x2fe98d3ccbf07cf9, + 0x01ab2eed229b638a, 0x2d304352532157ce, 0x20a9e010c3e91cb9, 0x5b8a8c44c0b64697, + 0x439e51a156619c9f, 0x206ff7d6d7d38d10, 0x7c86d28241f5a31e, 0x0135897178a06022, + 0x803717c70bbd66f7, 0x70c7484ad9affc20, 0xa72f25c94c6c4e87, 0x3295f1837e9def4c, + 0x5a15a75e2a6ea548, 0x7a3ab24802462236, 0xa97406a52525fa97, 0x51f79023e3da2274, + 0x9f7be26831a750d2, 0xbf1eb51f9ff53dcb, 0x6b94b9838a900bda, 0x0690d6c697e4ed01, + 0xeb57310031239f7e, 0xc5e298b06574c7ae, 0x95ce7db9f7f02d7d, 0xccfc0328eac5ff5b, + 0xa5f2ba3335da361c, 0x76119ccf521cf5dd, 0x4b960103950903b3, 0xcbd165baec1b0d7b, + 0x3c107efb3644114f, 0x589b67b3a82455ca, 0x782cd45fe886f2ad, 0x93c3cc70cd80b778, + 0xeeeec1163e049cdc, 0x61e301fa4dd0cfe0, 0x1b5f9da885473c21, 0xdc1fe500535ab720, + 0xed20578accb83bc0, 0x61164536f8cad65e, 0x221e2c931390db07, 0xf904d426f61441d0, + 0x09cb112d880868b6, 0x48bf8767193d9bd4, 0x87a9c7aed7fbc606, 0x3b1304a237b1eab0, + 0xa7985c5452f6ce7e, 0x8884978b04f38903, 0x03abb5acbccebb5a, 0xcc7ef88f290aeb0f, + 0x9b4c78c486cba52a, 0xa2506b0510eaf0b7, 0xe522db17e374e49c, 0xdd1792e3aea9045e, + 0x882f1a964c88d5f8, 0x8a69a48cb23046e3, 0xd18cbf42cca7f759, 0x3a323e8c41b1588f, + 0x50d9a918871c494d, 0x0e149ce2fc437479, 0xa4625a1e2e3d7563, 0xe301aa6487651ef8, + 0x4720b1dfe57b07ca, 0x834c5274326e8620, 0x8e0de9c83e63fbf2, 0xb2e87a0a21a791bb, + 0x862dc8edb3ed53d9, 0x1ca8b34167be6fd6, 0xfe4d90d98efb6113, 0xd2d2690dc0daf693, + 0xa94dd4f992450db4, 0x47061a80019416c9, 0xf7ec4060827640b5, 0xc50f330288f2b8d2, + 0xded3541bc7013d3b, 0xae0872a63b62a51a, 0xf40e98ee53f12982, 0xe4763a5315234be7, + 0x90795978778dc380, 0xcfc8e6d0bb335bbf, 0x61c1503ed7c707da, 0x5e40d98579f2b455, + 0x2cc1fdff5c7a0462, 0xfd3fb8b6ffeadddd, 0x428577bd8edf1d42, 0x44b858d55fe3a2a9, + 0xfbcb0d9bab96c68b, 0xbe6be29273d7c9ee, 0x1d5d4d083f0971ef, 0x21356921dfcad62d, + 0x75dd51640467743b, 0xd21c9b4bee046531, 0xae0c0b45daee208a, 0x969723003200f0a4, + 0x16c5102ba9441ddb, 0xb90cdfd1b84b4d1b, 0x2fd6229db9ddc7ce, 0xa2e12c5689773733, + 0xaa50d03dfa1d4895, 0x7ee6e127b64229a6, 0x544b9c199cee8008, 0xbee1b3074e369c52, + 0xd95c712928b3fe09, 0x81677ae9c37a1420, 0xf8ee18b3dd2e4be6, 0x052d036927e04327, + 0x52452d0a461bb497, 0x5d3522f0b6c0f164, 0xb5c85c8d45e81752, 0x6b1deadfa5b55505, + 0x8eb084732935f50d, 0x8a5ad3e8d147b7bd, 0xe98c512914b8e039, 0x15ead3915feb8973, + 0xf9da8a2649db95ee, 0x0b3c802e4a00e8e9, 0xcf20a269b0f0c1de, 0x95c78d4ab5a752bf, + 0x135e46638d1b9a10, 0xce9e26da382c72b5, 0x5eb49349c86480fc, 0xd2b89c178927a8dd, + 0x18148b5af51d8282, 0x53310a3e5c09f72c, 0xaa3f5a57ea32ddc9, 0x95d00f2bab6a7816, + 0x1fe0a0371f87b3de, 0x2c2cfa4e665d2b42, 0xe044ba27f75b9bc6, 0xeb8f8c274f270a2d, + 0x6737f7e959c72894, 0xfad6a91b4a85cac3, 0x11439511cb50af28, 0xbefd92ca9f23148d, + 0x97c9297516003b41, 0x17fcc7038f6dfcb0, 0xa70fde4dc7f7e62e, 0x40d2e6371483c45c, + 0x2315e9aa327e8699, 0x536b540938a2a1ff, 0xb0dc0deb1c90f653, 0x26d7f36d5d7739b1, + 0xd48fa67d69407d44, 0x0d3b576dc5ebe830, 0x56c14e24ae356432, 0x367e0d0208fe79ce, + 0x89d0d108da330ea9, 0x8a35ca4f69e5f47f, 0x2c3603a5d8c8b62b, 0x0d6531523b7199e4, + 0xf7f918445e106a3a, 0x2a6529127debf1af, 0xabb7cad07a47e6c4, 0xf6af83171e34f627, + 0x038000fb2107289b, 0x6288e840ae379857, 0x032fc4cbd4edc911, 0xe93b4e69b409517e, + 0x2e1777c356e42e9e, 0xf2ecf6bd76058cf0, 0x7f01f1386b62ec89, 0x5b6e4126b125d292, + 0x7bec9fc94b601039, 0xe276224c94bf3e9d, 0xc4638f80747e4b8e, 0x80e657eb2cade2b1, + 0xeff49724d697e8a2, 0xda463e4ddd1e207e, 0x86d2b11e1664642e, 0xf6bc2c86cf31e4f0, + 0x6d2c0c400539a7cf, 0x6f4465bf7be39f39, 0x4278a5cdf515731c, 0x4b199f4191800018, + 0x6d2d3d308a429152, 0x2ec35f1caf45076d, 0xfaf6c3bcc842cd44, 0xa9c2d67a38eabd3e, + 0x785a10f6c189e76b, 0xbb365396b7fa07c4, 0xf14f6152b0728b18, 0x1c43d45daa46b17e, + 0x2ad55363ccebf6bf, 0x615ee4ad3878120f, 0xf752ce4465f79c02, 0xace1f0c9a53ff92e, + 0xe47ad69dd19f724f, 0x0ff88c2a5c663813, 0x207a142146536943, 0xbf3250861dc875c0, + 0xf3dc43de59f39b40, 0x523c480b8837a567, 0x130bfc1263cc409d, 0xdb7c6acbf3f704ee, + 0x68dfbeb2dd08df31, 0x056af3434b3c06ee, 0x47e7d39bd65b3291, 0x9c7c4aa3253634fa, + 0x680365fec4bc3512, 0xfb221356dd185c08, 0x7965842e5b887f04, 0x6d173903e3e16974, + 0xb741530501bc5c87, 0xd22d02546551d16d, 0x0c359d176e31bdb9, 0xfa42a081fa22c752, + 0xd35fc73da6b4957c, 0x57df7d193ced18b9, 0xcc05a496ad8cf7a9, 0xdb967409f70d431e, + 0x143e6a1f60904d17, 0xd43525a9c8b07391, 0x8f4c2172708366ed, 0x4d13fc90683b7306, + 0x40ff9c1630544cbb, 0xdd991d73e81a6e28, 0x1040dac94a993a07, 0x00b993a3f93e5791, + 0x511ce1b7bbcf810b, 0x32e2e0fd162876b1, 0x6e0f67bd35c807dc, 0x17d9e8b2d0a3fb69, + 0xfa493ece987557d8, 0xa400e8f4c9399aba, 0x13a19cfc0e3c0e3f, 0xb05368add2f05413, + 0xd5673f30ee46a39a, 0x357c820f62ddaae1, 0xc8d2865af5d10488, 0xdfc83cc45ab0454a, + 0xa976acb64c3dac03, 0x12c2add5b2e9fb67, 0x7a854f12a1041d28, 0x81ba41f7da2a9d0b, + 0x6e0c69322f03dc3d, 0x664989d53113974f, 0xb7a12dd99a5c1285, 0x9402b517f30eb11a, + 0x613ccd93ffff9a9b, 0x5570cddfa6e44922, 0x3c09c35ad52fc26d, 0xaaa902239697e3a6, + 0x2016a1b23ae3e7b1, 0xeeab4de64804ed97, 0x3cbfff1d346a0bea, 0xe114fc93514f1a81, + 0x674c2170a25a08a3, 0xf3badc0da3e54b38, 0xc38b9c44e04ac730, 0x0151b3acbe897bbb, + 0x87504ff42f7638cf, 0xfaa4a51515334b93, 0xbee748492ca76285, 0x1c7c0f92837088a0, + 0xaab8e574d421c17d, 0x7c012e5e742a38f1, 0xb97f335169aeec67, 0x2e9e831ce06fd29e, + 0x15bd714585a3c789, 0xcc270c1148326744, 0xbef7f5a1ff83174d, 0xed3d065c5a920bb0, + 0x38e0eecc923efe7a, 0xf2d4116a2ecd997b, 0x24d24edb9e613418, 0xc8dcdde3a08166c2, + 0xe05d31e24455b29e, 0x0afcf39628ff4213, 0x13aabb60f3007e6f, 0x16eb01a5bc429df1, + 0x716f6a1793c27c7c, 0xba2e02d8dec203b8, 0x4e3dba3457a1ddf8, 0x1a1f9cca94a5130c, + 0x8e8777e0f23ccaba, 0x7c0dbc444ee74691, 0x977237da8d645254, 0x4ac5424d3453c8e4, + 0x1a0b0277316ffd7d, 0x82fad9e118c513bd, 0x311876235da57cb4, 0x49c1183b71ecdb7e, + 0x229457a630851a10, 0xabf9eb7b0b9a81d3, 0x577e29dfbe1de31b, 0x1faedb746b3b16b1, + 0xd278fdbda5b46ac1, 0x7bff6563704f611f, 0xb57aba036f15d656, 0x26f2c278f543490c, + 0xb55e3062ed28ab5d, 0xa374c66894536f55, 0x5b38c7f50ea9d26c, 0x17c1e0b07968e36a, + 0x245aefd23200a60d, 0x6645f9b5cca8727c, 0x956fa31b8a4f978b, 0x63b99479b94867fb, + 0x9217864588b07288, 0x117bfc55c11f9376, 0x41c017c2829709da, 0xdc06e610e5421c66, + 0xaad1096b0e5d5c5a, 0x66f40baf58f84b6a, 0x1c300520fa117666, 0x2436b89d9d507f6d, + 0x73232016a74a26f8, 0x896fb9428da1372a, 0x78bc871241e5fd45, 0x94ab5f0a02a92a6a, + 0x6587b017f16a5b65, 0x60fa6d768eae50d4, 0x5635cd9075fbc8b2, 0x94bdc332c2856d75, + 0xc0d57fb2fa613bc1, 0x45e1d880c78e6cc6, 0x7a5ee2782c84b7c4, 0x2c846372a3c6ac02, + 0x160789b90db38a4c, 0xcc9726043ad1abda, 0x0d3830aa52bb130c, 0xd8097db94ad8a632, + 0xc856fe4b8e6bd8fb, 0x40e3ccf0ce65f9fe, 0xae858551eca04751, 0xab08be4905de0af1, + 0x0930a13d7cd91fd3, 0x97b7fa2cc060cecd, 0xc51694861649ff0c, 0x2af4cdc1952c5072, + 0x84f408173cb819d8, 0xd318aa469433c319, 0x435f96907c6be9ed, 0x70c7e4a5c3d67a1b, + 0xb55f13204e9badf0, 0xbf727b8d66860bb4, 0x1e0e0609d55cd7a0, 0x383df4fc376a2d4e, + 0x52a61376dbc181b5, 0xc446e72917f08eff, 0xd3e1bfd3d97a6f90, 0x5693d7e6cf9273ad, + 0x03c2d2e9fb94d7ca, 0x0f353bdac603a6d6, 0x0259df557a6113b9, 0x5714d4c6c5c94ac2, + 0xe41838aa75048b06, 0x3b6300f67c3bf5c4, 0xcb94178080bceb9f, 0xbcfe58b6bd75e77b, + 0x3e767c0e5edb5f94, 0x5142b6027f0abf90, 0x7a2fce6606e4ea72, 0xb8883bc5c491f2f8, + 0xdff19aa3a7cb078e, 0x6f69e961c01e7f56, 0x358dd38483bc56a7, 0xaa491c66f37613cd, + 0x8de0653bcabb5895, 0x0edc940ea2cff7bd, 0xca93755c778daec7, 0x92246204fcd4692b, + 0xb7183bec951ff4fc, 0xe82213001a581dc4, 0x634c45809962da6d, 0xe2d47c9fbf0f7968, + 0x072c6777a00778e8, 0xafad56d2c9cd20cd, 0x7f2aeccd1244eea2, 0x2f1b34c1d345f3c7, + 0x70766f74f5c7b9ae, 0x0d243d5b24940a1d, 0x374c546246c33dae, 0x07fe4ae2f07fd678, + 0x342823bd878bb983, 0xcf94ed0c1ff5abe7, 0x9a3a86af9b45dd03, 0x90dd6126c526c984, + 0x928bc6388f9cfb78, 0xf560fab5b9ef0749, 0xcae5aca6dca1f46a, 0x68976dc6152d301b, + 0x7938c6477511fd89, 0x51662e3bc5868c3c, 0x59d745d27816cd7c, 0xedc4e332d47ecd2b, + 0x8b8e87fdb17fdc54, 0x2874164201ab78c7, 0xc59b674f4507b731, 0x606e93cfd3b6d286, + 0x22b57d12521cc858, 0x5b1fbd81166d3211, 0xe0a7f249914d3890, 0x815e8a2844dbc69b, + 0x34e2c5c5ff77fcb8, 0xcd8c54a7650b585c, 0x5d4315174e304734, 0x765bbfce436c35f1, + 0x1d2e154b018d9786, 0xa355c053e93edcf2, 0x66422042fa6d290f, 0x704c8e58d16e6d89, + 0x3e522e2e28409e3c, 0x389f8e0aca07e027, 0xc572c58b8d810ce4, 0x8bb40c5c6c3a4181, + 0x5372fb927c306006, 0x2d67ee5830726fc0, 0xd536cd7f1d5bb6ce, 0x6b039a952883f4ec, + 0x9c39a9d8cc92c4ac, 0xd62064bda20ddd8a, 0x43b7de9dd7a20289, 0xb1e0161c3de9f421, + 0x580d6742c338ffb4, 0x130c02d6c4275e04, 0xf7027b65b6d6cc46, 0xc5ef278d19d66835, + 0xea58b381072287a4, 0x34295a21bdc78520, 0xc57bc1ba1456c77c, 0x87d6ca822cbd5e45, + 0x530bc0f3b37f68f7, 0x4a44501f50d1fd7c, 0xdece26346222a260, 0x83acf8229679d0a5, + 0x9dd7c64ed7dd9584, 0x75e9b801447a0630, 0x027c09f873db8ce0, 0xa28f69e02f37118e, + 0xb64754be4d199151, 0x9366522c3949f29f, 0xa13e0fe933233635, 0x38cc943d4c06146f, + 0x910f04c7cb58d5f8, 0x3e46518f515b1efb, 0x5f8099b758a52b85, 0xe0538a05b373845e, + 0x76bc68c969b80e5f, 0x6fdf367ead909aa6, 0x561b424b8c0bbfad, 0x8cbdaf30f6fbed8b, + 0x6a7d978eaa94a1fe, 0x5a269897d7b4d939, 0x24ecd3f1f0f5d149, 0xa67b1e183131ab80, + 0x61529e8005e10158, 0xec36127cfc747e94, 0x4dbd99faeb681112, 0xc3ddd4a167fa8ce8, + 0x467d85f044746067, 0x2e95477d94ff8c4e, 0x435b7a878b147f05, 0xb3b50d57e7980989, + 0xc2405b6479cc48bf, 0x5d81cc39dcd370c0, 0xa66173555f209e90, 0x7ac46a495ff5f86c, + 0x2dd5aa47fcccee04, 0xdac5035a159e4a1c, 0xa08ce6f435ea2138, 0x973357f72cb0a882, + 0xeb6c66d2a2d112c6, 0x5e89bafcecff1fd8, 0xc09b8fc60291242f, 0x7229f7de698fc5a3, + 0xa66f31dee25efc42, 0x96f6c9754983751a, 0x10316df05d8e8ef0, 0x2910e1c85a2914b9, + 0xa27d923ec237c8a8, 0x8323033cf2f378aa, 0xc6dded3a80497d38, 0xe431dce168dae71f, + 0xb58f76c041899528, 0x228647448ba5ddcd, 0xf0d46ea492196cc7, 0x62af12c26d31e980, + 0x9568ee72cd94c04f, 0x5349d4b6d107a08d, 0xf3377ab8357c1899, 0x4aebdc049cad0799, + 0xbca44c38888a2337, 0xad899409759ab96c, 0x680f96eb6fa8478a, 0xb6cb7f032676a5ff, + 0x85278ae2c9bac2fe, 0xdc892364fb579341, 0x3449955456861e23, 0x6249a5c106ca1787, + 0x85b8c2004a8ab612, 0x92529c209273421a, 0x07417f13f5f384d6, 0xf1099d62a77c9ff1, + 0x11d520e3d5e470d8, 0xd450e8e904a82851, 0xd09b1919adfacd3e, 0xd547ab1a516a8653, + 0x1a7dec308fdddae2, 0x13e305357f76c503, 0x27e230a6b9f8e822, 0x5d2a1d84cc901f25, + 0x357bd3d0874d9f6e, 0xb9dfeef9a194dc10, 0x9f040c17b480340f, 0x746fe39c52b0ec39, + 0x0dc2cf20ed9cd658, 0x41c3e53f0ea41a33, 0xdcc5f3db4e932614, 0x08ad92992cb66b4d, + 0xb53fa2c451116954, 0xe540f08d0dbc36e3, 0x9d571f462e502a0c, 0xe741cd3863c72962, + 0x7fc65ebcd9451625, 0x2a432ab221b9a940, 0xabab2a365cb953d8, 0x4c9a1ba1b6c0006c, + 0x9db2fe467025b1a1, 0xb5f1712e204e9fda, 0xf6a2e2d0a385513c, 0xf7663b8dd5bea33e, + 0x133f65320faae97c, 0xa602c6591ddca577, 0xf8378cc957222a40, 0xbb7925b3e37a5567, + 0x8827ca3ce14c4a76, 0x508045ec84ca6e63, 0x12a0291d018fe360, 0x92e6dcd32818975a, + 0xc0ed04512a291d8b, 0xe3be890913e754b8, 0x759dfc7f8cfffba5, 0xf8af08fad1d3ae26, + 0xde1af1b18509801b, 0x49e59b008bc5f611, 0x62f0ef15d167bff8, 0x50df9a13e749aa8d, + 0x3efda9f48fbf5ee9, 0x00ab4f41161fc9ac, 0x6318719beb3e30e6, 0x8aa9e73bdfad44f8, + 0x6287c6d8cfe6c799, 0xd1bc94273f5c0c13, 0xccf9ac0c27fa017b, 0x56c80f813fd9b394, + 0xe13710ff6b88cd66, 0x235c31fd08d63660, 0xa26ce49ca2b574a9, 0xf49fd2738d4ba6a4, + 0xbd9e09b8e06762ae, 0xfd696b50e7838481, 0x67b7c5c3fa0fcbea, 0x9521f66a69c4e898, + 0xdea6fe11d189df84, 0xbfa27e0317c0c24e, 0xde58be706d56d981, 0x482054ef38d997e7, + 0x92079fe545389db7, 0x32538a67db0fc2de, 0xd85766d17a5405bf, 0xf8e3b7e8a4c14f78, + 0xea72d901fca708a5, 0x168acf99837277ad, 0x6a668a1cf1b00a7b, 0x9b1b71145a809a11, + 0x656d61f15c515b03, 0x7388ee7f9e0f6e0d, 0x58ba4c117a9fd1aa, 0x367aa6b744c79653, + 0xf568e012649a77f9, 0x55a3be3b037f9604, 0xc426cb02d9b8334a, 0xb22e949290645a83, + 0x4417e99a3dcc2f07, 0x412a9a9c196fd6df, 0x4b8b952ed7a56cf7, 0x4513e04652fe7df4, + 0xe33eea33ff76092c, 0xb9c8b62383173232, 0x0acdd5523dbc72ba, 0xce104666bc704baf, + 0xa04c4e8ba98d009d, 0x3a1362c09b1be4e0, 0x3ef154c19c3da67e, 0x7a89bd53b111db5f, + 0xea336c550650701b, 0x6521ecdfbefa279e, 0xe847536db0df47a9, 0x0d22c1ffbe1c6423, + 0x32d1e7bef5c711dd, 0x0a5de790f764b939, 0x701529fac7d67384, 0xf87d60b0a85db33d, + 0x20599a1867a8d02f, 0xbffbd34d9be7d711, 0xfc4f95858be57155, 0x5936ed2737109e74, + 0x0fa8e0487cde4ace, 0x5650dc264d3ff821, 0x03cdf26ce9fae6d8, 0x6482c6272ddcc27f, + 0x59fed6a2e9dee32d, 0xdfd07329678f7edf, 0x03681202739f20fb, 0x02a2cc78381c5b94, + 0x06883e9ed5d43b34, 0x8a4b819e013f839a, 0x3c0699e315b56264, 0xba3cf5ec20cd57e4, + 0x35ca2c6f7f99c727, 0x484116606272b76c, 0xb9443fc1dd3f8c37, 0x7b08a364ac7b12b9, + 0x039369ee98cb3599, 0x321a6f6d5b932e4d, 0x2bdfa647ba4e284b, 0xc741ca8990a24ff3, + 0x6089177e29fe9bb7, 0xde2584a18abc1875, 0x4487ec60739ce95c, 0x6d892fb1074df203, + 0xd0cae2eb3535e603, 0xa64dcebc9e306c85, 0xff10015fe6694b1f, 0x1356029a976c2f29, + 0x89b15501665df15f, 0xbace4cef8ce7e12b, 0x85b75e2526357354, 0x41fa8dfa145d8db3, + 0x38758caeee196bfe, 0x6ff3a7a41d79dc7b, 0xb445e1f4215d03d5, 0x0afb0954bc0afb6d, + 0x762c7fc56d35ebd9, 0xa97a318a84efecd7, 0xb3a42290b2e49b7d, 0xa9fca826a8a247a5, + 0x5073476b1b625d57, 0xf9bcd68cf79cdb38, 0x5dd1fe47a31c2bab, 0x9a6d1c97cec9e570, + 0x9e502dd6e931cffc, 0x8c2f35e9b23b3f45, 0x8584c9c3282af82e, 0xd364b4d44623fde0, + 0x1cad7f9c6022e019, 0x6328d205c86e1cce, 0x74a0f384023d2b19, 0x6350049a7d30cf50, + 0x3abeffe3e641dc37, 0xb1982d27c9b9b133, 0x83381772749cbb67, 0xeb5050c7f7acc2b7, + 0xb9c0894d1a2f9e3f, 0x86270204cf47bef5, 0x928359d3b73eb69c, 0xb61022ae57ef1c54, + 0xb2e85b983fa28a74, 0xf1b26a64a2556298, 0x706ea3745ebe0c2d, 0x6bdf137cee4b1ca7, + 0x82ff6dbf0735f107, 0x3bb7be2a37ed279c, 0xbdedfbd2f533665b, 0x7e19acfc3b7ab1bf, + 0x55e30e0aa52f2fff, 0x36a31a4b7a59b650, 0x9be3a1589752495e, 0x5b120348cc395b73, + 0x01436a918587a535, 0xa9a89f52ff3d30bc, 0x189b23bf2b7468f2, 0xd75ace8752346e35, + 0xea915da0631516bb, 0x664e316ad84c5692, 0x4cc62476b32b1c60, 0x3aabb3b700b43caf, + 0xfbc51abc084500bd, 0xd6b8397f0e81ac8f, 0x4dc7afcfe9d37b5d, 0x15628037f268127e, + 0xfe9788a1b188edf9, 0x5b14fb987dfdd348, 0xab5f7757050e025f, 0x91963e0a2d10c60a, + 0x18b22e86edc3df6d, 0x5bb0484d9b9d72ce, 0xf25061ddf0909ada, 0x9c9b887220fe051e, + 0xd247e7ccfcf68352, 0xa0f219759454d79a, 0x6776e4fb90cbd66e, 0x0da20acfb5feff2a, + 0x5e4a4791e87dadbc, 0x19473ff9f7516917, 0x5b3bc3911a9a52d0, 0x087e7f095566e796, + 0x03a0f41e6242bb41, 0x5877cc6220573d3b, 0x48dc498b265140c4, 0x604a27b73bb80544, + 0xbd02edece9139cf0, 0x8c6f50f3d032c038, 0x1f4d2b691d625a3f, 0x8ad337ee55db64ca, + 0xa04f6a3f7e828667, 0xbbf93014591bc241, 0x334860806c9bf75a, 0x70acdc497d529d77, + 0x63b1c30947407564, 0xd922bb904a6e198c, 0x0f67f19c39c6abff, 0xcccab9aec6e45502, + 0x3e2e7b93fadca229, 0x532a14e4bc2e5383, 0xb62ae76373e6ef85, 0xa6da03440554f234, + 0x856d0d9620b0eef6, 0x0c6f6ca3a2189406, 0xae27a2779d68d4ff, 0x68e5795483388277, + 0x7ef8c35bf6d94d57, 0xc2dcf5ead80d4256, 0xc3dfc1ab7f07e2de, 0x3a689ef56e711c2a, + 0xc9880f226c8da978, 0x8c5e7dd2c97a283f, 0x6dd8b5cc6e174d93, 0xe12162e5098bc885, + 0x0b7656f641468bf3, 0xfc1d89e93a5ac4a9, 0xb80c7a4945c89348, 0x661c068cdb02a8fd, + 0x3449d52bd875961c, 0xefc615255c840f2b, 0x14581bcabaebf4b8, 0xdeeb0a1d6846196e, + 0x6504718cb718d2a6, 0x7458c833b16ee8a4, 0x46af57755e4a3042, 0xd9003ece8d48e164, + 0x8b497234bd94380d, 0xf6a3d8a16d023dd0, 0x8a8a434f755a507b, 0xcf4cd1e191858dea, + 0x83943d4a184f3f6a, 0xb6de61627dfad18d, 0xba24472e8e19330a, 0x81e4a70713be9107, + 0xa7431d750b31bd92, 0x1ecbe4d27f9c6a0b, 0x05af46f9b59db433, 0xa330ce3a95348166, + 0x50b05d276030dd52, 0x59c83f1b9a572afa, 0xb798b41f2f62f6c6, 0x886b1f3377bee660, + 0x247a361319fe3cc1, 0x1ed0bfbba66110e8, 0xb30d1712172942dd, 0x35ff6d0d87f5f362, + 0x602ecbd54d91ac0b, 0x6027d9f46849a24b, 0xca2d1a0bf21bcf9f, 0x94cf2758ecb9560f, + 0x7c75a404c13809a3, 0x6851fe12538a55d7, 0x5167534be9365c09, 0xce747962fed11088, + 0x1abeee155636014a, 0xd53549d52a88a696, 0xe5fdc7637c001165, 0xfa53a788d9104c3a, + 0x3f7192826530fb6d, 0xfbac8773a3fa881d, 0x9c73c0dbad46939e, 0xf7c86971b9bd653d, + 0x8ca4bacb98b89d8e, 0xa2711e64bc8964e9, 0xdac128b1251c3374, 0x808887d3587f457d, + 0x0578e0fcff6951ab, 0xa4067c9563cfea10, 0x2438ef1fc2662bc7, 0x2be6da2b0c8a6df7, + 0x6cb6515b6d72f6ae, 0x1465ac34c245d295, 0x7b6ad40d18849950, 0xe4d4ed7932535e69, + 0x958ca955742edfea, 0x41b76779856421b7, 0x5144234feb710ac2, 0x3ddf687c6aa5afde, + 0x5cf58ac857a9ebc1, 0x0b446b91fd3f3dac, 0x30bf4fec9aceb927, 0x03e1746e379c38c2, + 0x1ead3d7506ef0858, 0xde2169e1ff2e3f07, 0xa04e0e9bd63ae7d4, 0xd723ebcff9888de5, + 0x07395f4c1f59bb54, 0xf3417285af6c1cf5, 0xcc20b97d1e3cad3f, 0xd523b663f3b96bed, + 0xc04d01fe94b6ecb9, 0x737b157fe94a9517, 0x9ae1017eff9e95fe, 0xeedf2b6e5d248ab1, + 0x9fea27df0f34066a, 0x9495cc69f5897be5, 0x9e7a431095deb9b6, 0x976e9bdec5665954, + 0x6774bb6ea3a41010, 0xb5a3ff40d6976e39, 0x868a2cb72bc2aa24, 0x1327f8d580167076, + 0xff516b4eaff277b9, 0x86acef212449afe8, 0x5b05b8d828ebe8f4, 0x2a1086f215d30fc6, + 0xb088fcdcff756dc1, 0xd1320bbf14d15d34, 0xc1b54cf7a23aaab7, 0x76df4bcaa135e3af, + 0x22394843026fa14e, 0x239717369b5a6f5b, 0x7a65b8de810c53a1, 0x4ea996b735048fbb, + 0xc2790bf34d3aaeb1, 0x42b358c25644bf6f, 0x41806749bf33656e, 0xfcabb6b360a938a1, + 0xa209fc69b32a7250, 0x540ecff21f17461e, 0x34237448e52bd3c5, 0x86d0fb69cd1686fb, + 0xa24cd197524dd615, 0xfcfe89574a078b08, 0xb384bb449a2ccd00, 0x9260df4a6cdfbb60, + 0x628f4a903b89bfc7, 0x8c3ae895cd89ce78, 0x52bc23bb6dd7371f, 0x94bad6cceb5770b4, + 0x72db9342c4d96ea5, 0xdaada6078904893c, 0x73aa770755161063, 0x6200c141f5ce49de, + 0x44dc29a5fcf908b1, 0xf3bf9022243a5674, 0x53e3e214a144a50d, 0x6c4d7f9f9678ab2b, + 0xc983b2c47125dbda, 0xb84386319377606f, 0xd72d378cef9714b3, 0xdcbf0d8b0d005988, + 0x1bd5a00cf3810641, 0x6e81dfde423dfd05, 0x9c0ffc6a4669cef5, 0x5a07bc6f5fc7cad9, + 0x3c05a87171029383, 0xa6bb1ecd838d25ac, 0x2ca784a482e11dbc, 0xfca25c22f3e0a05d, + 0x0e7562182788f19c, 0xbc3bfc8fef428b33, 0xde769ed1b9596ac0, 0x3b2c557d379aeb41, + 0x3016c4d1f3503870, 0xf7e1e512f711b676, 0xb94a56bfdc097835, 0xcfa602904d20a6dc, + 0xa15719e90ddf9aeb, 0xe582939b10f07880, 0xb7ed3569791178bb, 0x0e3237ac0ddb87c1, + 0xf7091dad6cc2486b, 0x0457d27d35347a88, 0xd84c0af5df0f78b9, 0xc507c767296db091, + 0x3414fb0a26a72e28, 0xe08d8337e5469de6, 0xc8ef52fac6373441, 0x4d60213033451980, + 0x140543bfc5b5e8b2, 0xc1a558c89b6128f1, 0x910967cf8bf96cca, 0x6c7b45bff49ee439, + 0x1bcbf912b7a1cc1b, 0xfe47f2cde4ddb093, 0x34e1c207dce941ea, 0x7de7624a7b052a90, + 0x87913e672762ed9a, 0xd0061b05e28ce326, 0x08571cba21a427f5, 0xa6c037bc60f316cd, + 0x7b978502f079dee5, 0x901b9e1856a5037d, 0x70b2b4b6095f179c, 0x4e6a4dc22229ad67, + 0x97ae112ec3412f26, 0xdf314ea54317a921, 0x7b735d2260e33b25, 0x6bdaee40c7d82257, + 0xce5d31f2c79a204e, 0x5cf8f91b91da5ba2, 0xf5cf0377826d5d98, 0x1fef1277e9d1378e, + 0x4bb8bd681ff3d08e, 0x49862a3bbb913e2a, 0x8d43f8638871fd9c, 0x64ecbf9e0183abe7, + 0x13912c5d134d9a31, 0x629f1bf407f061d8, 0x6b504da625ff4a7e, 0x22a815d4363bd5fa, + 0x74045039b41eaa4a, 0xe92de7096c064de1, 0x3a3172130c23a5d0, 0xd127ca1040853087, + 0x3b330584a5dd63d1, 0x84e8dc94ef904232, 0x960072fa3eee3a0d, 0x5fc1519b6cc0a909, + 0xa116e3319e3131b5, 0x037cbfc41de366bf, 0xc2050e43acd7d87f, 0x42ea8aab9757c117, + 0x40b18c5dfe34d6ba, 0xd97869840f1e6c00, 0xb52027a297d0e333, 0x00f22ab0511f6cfa, + 0xe3537bb92658644b, 0x92613f78d00f4fe4, 0xec3b6b6e0dc85ec0, 0xd0268caf36469a59, + 0xcb2ccbf84bdb1f8d, 0x491d365afb90a3ab, 0xc4a66a1e6d7bb2b8, 0x57c80d2995a125f2, + 0xf5a434e48e0fa362, 0x006787fb608338a0, 0x11cd5e41042da958, 0x5bed15f11ff66fa2, + 0x2ea03b577df6667e, 0x13559234530e9bc3, 0x2dec044a47812776, 0x7880017de9bffae2, + 0xa1b0fcb4bc9de2d9, 0xaf37057bf722eac9, 0x2b89536c5b66b802, 0xaaf82082b9a6f757, + 0xae68a25ceab89cc4, 0xef27d927885febad, 0x5f0314a4808d44ca, 0x89b6ec34f65ce39b, + 0x43c1affac5922c55, 0x988016f7505df38c, 0x1f5f19c9b8c2df48, 0x267b299dd8a52172, + 0x912902c65159e640, 0x596d08e3aed3a5ab, 0x2466f25ccfa34ab0, 0xdbb56011729db861, + 0x16a011f378994c8f, 0x751c09a4583b9274, 0xd2f83628687e76f6, 0xf0ef063e40cfd4f3, + 0x4560584cf0fbe4f2, 0xfc0a671fa2c404a0, 0x97a9d9eaea08539f, 0x968fed869ad68bba, + 0x2b2a3e3a89797288, 0xdf291180cee6e9a8, 0x199ee4f6cc77f2f3, 0xb1b77cac840aac3f, + 0xfbcc922f9e5ee166, 0xb1a9d8bb9f3fedbe, 0x0fc73db4740e9bc2, 0xbab46a53c130a547, + 0x68fe84dbdf5211f0, 0x1f0d4340dfad0169, 0x1f89eeef1a392174, 0xec72a0c8991e3e82, + 0x73bfba62d6f72057, 0xf2170c6cf8c3a83f, 0x07949703eef32fce, 0x48b78d1069935b23, + 0x689bb1fda12bde4d, 0x3f90dc8c95759623, 0x554d254249f90104, 0xe922bba7d3ad3b2b, + 0xa869765eeeecf4dd, 0xf54c7e3ed567c4b3, 0x6a5d1a21d56a968c, 0xd7fd2ec024b7614b, + 0x6c2f7285684ffc04, 0xbb0d8a86cef640e6, 0xa919dadbeef1a357, 0x426bc7bc63477dea, + 0xa5246f31a056bb0e, 0x2e1e6ec4d8171bfb, 0x93acb646499dab68, 0x5b6919d4a6001ac0, + 0x96b39bc9c58e87ba, 0x6aa7086f1aa196a0, 0x965b854972c81648, 0xa2e812f20d195d10, + 0x8b3e95bd9d2ae66f, 0xaf800082eb3d5abf, 0xbf5100c6eb0265d5, 0x4ff246e3a43817b6, + 0x78f0fb470cea9b84, 0x3007a3f9f7f08b54, 0x9a92649c21c82053, 0x0ff1927b87a6afc4, + 0x19fe00b920e728e9, 0x0ac0a280535ec4fd, 0x411d37fd5bdec7b7, 0xfd52538c0bfd3f84, + 0xde0ac8247803e43c, 0x03cb6a8efec2e6e8, 0x6e1063fe1a824b28, 0x43684a136a1db68b, + 0x92e6963267461951, 0x4094e184df0588b6, 0x7626c7aca82e41ff, 0xee108c77a3eb8de8, + 0x4da6a71a157e489a, 0x5783c0f67c0a8852, 0xaac779307443dc14, 0xd9b6dfa78ddc092a, + 0xf950cb2f056adb8e, 0x0f70b18908caeef7, 0xf13de4a8beb86726, 0x5f4545bc7b51cd96, + 0x7ab617c6534f50e9, 0x25bfe7e25ee5d4f4, 0x19a57c3e0180dca9, 0x40676b7e934792c8, + 0x1818c7eb11804f13, 0x7b5ab6e7e95e1f14, 0xa459876df80f93de, 0x01bf28031e8c22bd, + 0x421fdaf5336e90ba, 0xeb858b705df8ac3b, 0x10ab78a7779d7692, 0xbf497bedfae0e10c, + 0x3a87d33617fca31f, 0xc335ec215617f624, 0x156cacfdd063499d, 0xc1825c7f89a77381, + 0x046b9232524ffa0c, 0x94c3db6bed91641b, 0xdd3cf98679aafe14, 0xec1a2a4bb8403931, + 0xbd292a821da2777d, 0xca6efe1421ee7bfb, 0xb7d3f8057cab37d2, 0x6e5114316bc8803c, + 0x4e5f0f6a9bdb923f, 0x0efad2edbb720428, 0xa3ebf4468768b1d6, 0x4e3932aecaae53de, + 0x0f2ee639ee2f50b2, 0x6d258c55990155ab, 0x6617a49f13670727, 0xda3c877ba24b3704, + 0xff05c1e8788023c3, 0x8fdb437fb4ff505c, 0x402dc3af9258bc83, 0x4c9f5babe515574c, + 0x315161857abc74e6, 0xf5239a2f51211fcb, 0x2d13454115b5dcf5, 0x4c9d5ffd636c44d9, + 0x759679fb3820b4ac, 0x6157d00b7e6be154, 0xe7ae41546892b795, 0x2c129445c1bc6ce6, + 0x69edab403fc67076, 0x1633797e5fa2d6fd, 0x972b26e1820c4f39, 0xb14df5f6ede81514, + 0x8b374e08489b3598, 0x9df9dffad20e99a2, 0x4bdd9477400f326b, 0xeefdb2242c5368f1, + 0xd50871baf86f3187, 0x468d924244856f79, 0xc5048f63816024b7, 0x29f11355098c5e8d, + 0x36fdf0ed9f3604b8, 0x33e044cc51b35e04, 0x030c9e99789cb0f3, 0x93e85531eee55b77, + 0x4caf72a73ea01e49, 0x54b8fe828b159c0f, 0x1b78893763bb428a, 0x26576065bf049985, + 0x7089ff9a5d93d2ef, 0xe55948711b3fc9aa, 0x73ee71b859068064, 0x90596ff35dff30e4, + 0xa8b90cc2bfddf48b, 0x238d343441bcb113, 0x3dcb3d08bf90e6ac, 0x475b494996961dc3, + 0x0bdaebd1b22a85fa, 0x487716ca1c030583, 0x3411613568e786be, 0x0c6272b1c032c8d9, + 0xebacbfb4bf7efaf1, 0xe5c019e988639c65, 0x7cadf975d350951c, 0xbf5890e724bd6f79, + 0xa8ce9ac12918a414, 0xaac7ca874abbcc34, 0x9e5b9c884c77a6ee, 0xaca47bb2a372804e, + 0x6bfafc38534e7a73, 0x8aa20df62d0785d4, 0xc354596c4804a8a0, 0x11f64b990a8e944e, + 0xd048b5edc61772e2, 0x55c5570e01dded8a, 0xa81666f3006afa8c, 0xdd1b5adb8f94fe73, + 0x19e522704d5190d8, 0x3d377668e8e93a72, 0xe8d7120b56bd395f, 0x92df61afd56a9acb, + 0x604289e7d323fe6e, 0xbc22caacb84f6b17, 0x25b54ee1c9c6a480, 0x3bb29eeb03d50cf9, + 0x40f24e1cb5921858, 0x09067142a033d3f7, 0x44aca7ea2b1ed06e, 0x83869c5472ff8689, + 0x5fc247e80ca1392e, 0x9ff46511c371a0c7, 0xd829de1e2e3c888a, 0xe54b8788b4621f79, + 0xbe0ac46c5ba02c0c, 0xace826a5cfe6b9f2, 0x6996113fd32f4092, 0xf96eadf18884d3af, + 0x77e6a1bf5e6da0d0, 0x180d2bbcd9fe5cf0, 0xafb431c82f533609, 0xe874af2f75b9e653, + 0xbe30a4bbe39caade, 0x53254adecdb0a0e3, 0xa77383a42af53bbd, 0x28a83612e56c0b50, + 0x2b434bd134d6d9fb, 0xcc9c99ce66301479, 0x038b1b2a55061329, 0x8777d17523b3db6d, + 0x15e4b78242f5dce9, 0x8dad3e679a208d27, 0x5ae20a736d20e296, 0x0dac101afd7d7873, + 0x8f14a36195941590, 0xa7f8f9e8c9d7b836, 0x38d153caa947ad3a, 0xb477be0e68dcba8c, + 0x6dadb71862cc8db8, 0xc17c847232eede89, 0xb5bec1fcce8c82c8, 0x35995be12cc2d38d, + 0xfe24d0ac6b54cb61, 0xc47c2da2e09a394b, 0xb4205c9468473d85, 0x9e24d966c7adc5b2, + 0x90c948dcd32aa680, 0xa70ad2c006e8c8a8, 0x94e246c515a91c56, 0xc1d79e9b3140be0d, + 0x41559ef5d90a9bb6, 0x187ba99f9851ae01, 0xe6309320fd3d822c, 0xb883a69994887b04, + 0xd06120a5ffb062e7, 0xde5a295348048260, 0x1b6b2b063210df98, 0xdea44e2478955075, + 0xa5c1add5f2089fa6, 0xd99dbc2da1ac2065, 0x615f687ed624f363, 0x8bd2210d82211f52, + 0xbb888ca79264ad96, 0x2eec574464ddeb01, 0x6f9c9a8dcd5ded65, 0x5d08f82a2e5b5a4c, + 0x904eead81b4ab8d6, 0x9361e2e265189bd0, 0xa13663e8ea34c362, 0x7c71f4f0fbf66013, + 0xc6a26a5080e782f3, 0xa114c705bf573de6, 0x08241a66faecd24b, 0x48d1c855eea49ef3, + 0x992554d13c859243, 0x297cdbe3273f0378, 0x336256c4155629c9, 0x42dceb3e91e8e464, + 0xf4235b6d098e7c20, 0x40fb73730e14e31c, 0x246465622bcfb22e, 0x9bc424a1939a5a6b, + 0x81b96309f7a48438, 0x7ce2554aced69cad, 0x2f43e3792cd67327, 0xc133df1044ed8ae7, + 0xdf6694c0ff01d3f6, 0xa9f8f681a8cf4e2d, 0x6281794be68dd87d, 0xbdf4b6a12873d4e4, + 0x5656fb3fabba5200, 0x0c526cce582a1a80, 0x1c14dc018d39406b, 0x613066a5d182e00e, + 0x32b97c1994f5afd3, 0xa6c2765e015abcf1, 0xc29b24c6fa88cb29, 0x6dc38dae844cc570, + 0x42e89d5dcfa952e8, 0xc270c5393e2b706f, 0x9765840c4c7ee345, 0x36901f913045a6c3, + 0xfc89a26a56f0d15f, 0xa3b90e55647ae7c1, 0xeaa7d9ac0ec235ef, 0xb5cdf0652da81c4e, + 0x400add737d0af027, 0x19c1133b09f8a755, 0x9051e7ab527a9eba, 0x15c1cb5a3666c0cd, + 0xc081a2b9fc1722a0, 0x7cd59aa9e21c75de, 0x41dbe9df0d0d7da7, 0x9cdba46dd1ed97bf, + 0xf8d2805bac5f265e, 0xb4db0cb43360f86c, 0x7856f20ddb5ea18d, 0x52469ac04673bb58, + 0xe1d1285a0eaff331, 0x7a56a5801deec2bd, 0x6ce54d35ac3e6c24, 0x76166f682a0c0bb8, + 0x13b0231b473f0f42, 0x37ad4c5c3dd7f41c, 0xd2917573078a9177, 0x1482dd3506717799, + 0xc25189313bd9aab6, 0xfe897c04673b89d0, 0x4289db8739cd2141, 0xb2e8ffe059173e83, + 0xde6518ad3263fe2c, 0x0b95c1e5528edd16, 0x738babcc430cd2c0, 0x4867b783baf44565, + 0x6b91e16e3e2f1e54, 0x36def7d01fe5549d, 0xc77bb054fcac8e88, 0x3b734208f5a74c13, + 0xfc9fb0ee355fe37f, 0x1d709883a4eac78c, 0xbae05dfdfa33724a, 0xf88ef75c2f849690, + 0x1507cb09be47d347, 0x148414e4d18e9dbf, 0xd74f9956764ee015, 0x1db91c80924ec5fa, + 0xb1c64da89445c47c, 0x6a2ce728104174cf, 0x02797fb80c55c177, 0x4e1c7a0eb1ec8beb, + 0x01c3061d8c4840de, 0x964c13e6fec21fac, 0x84aa25758dc15434, 0x30a319eaff9f6663, + 0x2c50885b603cd4ff, 0xb0be8a89da713a8f, 0xaca02b0db40572fa, 0x0ff8f36386d46f79, + 0xf5e55796a1f7aef8, 0xffec31a4a7266f7c, 0x79d01c7dfd735c6f, 0x255c4a0b089122d4, + 0xc9c3f1ee32953bdd, 0x30d95b3c0d78c4f5, 0x3a6015bbb61ef46f, 0xaf66029648dd1d68, + 0xb64ef57abbbd0e06, 0xd63cb049a4758732, 0x76ea17bd1d4210ec, 0x9fa2752f4894b56c, + 0x25c8846c10f8d55b, 0x0dfab296cf979189, 0xdf21f4b98c009e68, 0x8435a137f960b35f, + 0x5d7eaf3b707d9400, 0xd8111ae74dada1f1, 0x5ab8226aa7da47ba, 0x6b10ea654beaf7b2, + 0x784369f5aaf64200, 0xcf142951a084ff54, 0x512befc4573d0c4b, 0xbbdc099e7a6a65a2, + 0xea0436889eaf06e0, 0xa366c8b8a54ec18e, 0x67e70ad8773aa6d4, 0x1cdcddf0acddeea4, + 0x92bcf3c771cb6125, 0x1e332fa0690063bb, 0x18df0d46a5928472, 0x387ac829666fbd13, + 0xae5b4cb847b8b867, 0xfee71fb8c24d53ef, 0xcda3b5e4667156a6, 0xdf87fe30b575305a, + 0x35e254eb0ee12877, 0x2cad705906f0df75, 0xe3c80d6fed67696c, 0xed46a7fe556be8ad, + 0x6d8953dc010aa60f, 0x070441d8fd47d744, 0xa213b43ac64d036f, 0x893e5d6fee4ef015, + 0xe75b3d2b0cb2a7ba, 0x2883df2c1dafee8e, 0x794c6e8be46eb8f8, 0x93bed1e7351a39fd, + 0x1a14724246e2c570, 0x08545d4903bc372c, 0x194f4aa832981ba4, 0xd625b8a2814f8584, + 0x5b6274a3c48714f7, 0xeb2667e1047ca5a5, 0xc57170180b53ed9c, 0x134009b98a2ac155, + 0x946d346d1517bb1b, 0x9e35fbecdd94a50b, 0x0995116db467030c, 0x28e2b1860a96b857, + 0x5b678d488ef00e16, 0xe8826c8c3bcce1fe, 0xaeaeecdfe68bb3ca, 0x5e788088f54f4819, + 0xb4b336291bf85317, 0xabaa05d858c826eb, 0xef4843261009cdab, 0xbd875991eca352f8, + 0xee03701aea6f2c57, 0x4c31ecc7c06937f7, 0x59bfb40953bad9c9, 0x7ab89a63367ba78e, + 0x7bac880a27f357ad, 0x501306ce46aaff31, 0x8938e42f27f447d0, 0x9056450e67259fcd, + 0x0fea68db6e205d05, 0x47b30c045aa83856, 0x644a43721793c28f, 0x20320ed633c848ea, + 0x09a884710925a32e, 0xd739104d0d299654, 0xc5933acd834e50ae, 0x225f8ca6aeab4149, + 0x0ceec188bf00786d, 0x85ca981a1af35a4c, 0x196b19b897409e0d, 0xafa55465ab6137c7, + 0x0205c6c4aa9b11c5, 0xf7907f349e428b1e, 0xda1b37a73d8b70f7, 0x02c348db7df7f4cc, + 0x371b1e154f1d1684, 0x3d5add9cb8475499, 0x69d9a57f95d59449, 0x3cfac6962e9c28e1, + 0x4778a67f68b79e5a, 0x893c88409ef7e0da, 0x9378f43b73bdeef6, 0x2f9c8ebf31f7b642, + 0x08e42d70e6f3ea28, 0xe9be5adae098f8eb, 0xf51249ba1faa8dc7, 0x6c3585be5ec259ec, + 0x70269600f9911f5a, 0x7ea9af5c4f07a942, 0x075b6fc5f75ea390, 0xb21a6e60dfa29682, + 0x8c50146f804b1b9f, 0x0464aa73c73e8905, 0x0f49eb00487ad130, 0xd930e7e00697ec39, + 0x5167cc479646f250, 0x0d7abc736b7cdf87, 0xdb739ad6072cde57, 0x069b0f39ea3a1416, + 0x445a18743fea407f, 0x046e9c093fe700e1, 0xf8e752ee3da3a8c6, 0xf863a70808a74450, + 0xa2eb8916cda92cbb, 0x43e3a08c285ced75, 0xa52753033f922225, 0x163e1727f769e03f, + 0xedfeae114f39c095, 0xd02157263b636a69, 0xb53e411f438dc707, 0xede4308ec4ac50d4, + 0xb995c92e7e4bb094, 0x3c7e41f442461026, 0x83c450fb07c11807, 0xb07f4dc10c5dfb21, + 0x1ab433298f8a3408, 0x4c1a42953124a517, 0x868d013a56dce7a8, 0x87f0149aa6e3dc96, + 0xe4c68bc17dc5384b, 0xf0da45f665f997e2, 0xe1da31eb3f34c5ec, 0xb6a7d7e229e99c3a, + 0xccf77b129fa25ad3, 0xbfbf7f3962b81df4, 0x0c80539e69718dbb, 0x25d5bc9245d1ccb7, + 0xd068eafaa29a8ac9, 0xe47bb3e3ea8dbddb, 0x5c8186558455768e, 0x77c9798ddab39717, + 0x0c2fb364e736d720, 0x43e5200174a5879f, 0x90a641366f6b258d, 0x650f3cd224809799, + 0x3b3cf5f97c1ff1f6, 0x546d3eaad3b6e6ca, 0xd25eaa01b5fa4e8c, 0xd7be540c2775be94, + 0x08273d6257920d92, 0xe85d0ee8d94f2602, 0xe5368f9178b01c5c, 0x08ab0975fc6d7f66, + 0x36f958744416bbc5, 0x9290415ccc2a10da, 0xd1537fcde590f42f, 0xc16de6457a5585c5, + 0xe62ad2b95fa69dac, 0x50af2a68eb8b5056, 0x084fb06391c15569, 0xb4522963fbf9660c, + 0x5fe4f1d78ad59f5b, 0x838b1c9179758ddb, 0x55af2eb06635e7ea, 0xfe4adf4dc194a152, + 0x24127542657b265d, 0x132bec02a05a6b26, 0x5d08eaac00b41636, 0x765883bac67b1dba, + 0x0fdbc4c078ae73af, 0xb641ef36e19644c4, 0x502deafe3ba8b93c, 0x0cb7b96365d59bfc, + 0xaa1785724cd42afd, 0xb79df658520bfd8d, 0x8b4ed0a874202b43, 0x896e717dd161eff6, + 0x0515b453d9459832, 0xf2f94c55e3500a7c, 0xfa32f25066199447, 0x0bf427f233b9124c, + 0x84d39f8df58025fa, 0x8714b1d7dc8b3f83, 0xc18084fa9e8b1eb8, 0x721026b690eea7e4, + 0x049f529623a55ee5, 0xe0090e39c816f015, 0x36bb3779466142a2, 0x7b8535433fb93791, + 0x9c57bc9d1c208d31, 0x7548447ef77b5d0d, 0xd90049461be45f89, 0xbb9d3bd5ff3d2900, + 0xd6b50c63b25bef21, 0xd0ae157cdbefa488, 0xa3b90f2e43d5551d, 0x074c430aea06db50, + 0xa11703bce84a7072, 0xe9618cc289c4ecb9, 0xd00304e8d40dd9b8, 0xd55e9e038ad5314a, + 0x23bf04ec22e743ff, 0x3d516e9382f736a1, 0x0d381a166b1b4ca1, 0x24c9ca98c7b9ca53, + 0xe1c1d830fa7f5ba8, 0x5b675ca5f7bb21c9, 0x9fd1a02cd577544e, 0x6cf499feb06aea50, + 0x977dc00c65fd956c, 0x93679772865e409b, 0xaca4e42af914f858, 0x9ee092f92cdb1345, + 0x68ac7ca88ac06caf, 0x0af3d8c4dd40c1f9, 0xe7951de435c8283c, 0x97687faea51325ff, + 0xe1cc8f3ac35801e6, 0x25ed078bde8dddcc, 0x16ac207d74f0a358, 0xcf7de2add4517fe2, + 0x5443b9f7505c49a0, 0x7d485b7a4446761d, 0xde2d75f54692f462, 0x3b7ee4b97a19300d, + 0x2dcd3f8deab62f53, 0x10f64eccd4d5661a, 0x158c7a2c76d00abc, 0x7e12b5bcfe939b35, + 0xc8a419393bea5e40, 0x2c58e14cf1381f14, 0x64af1d99ee4e06c5, 0xca6fd43dfe3acf31, + 0x5fd63bab39eb3c43, 0xaa91f35280f7d9ea, 0xae1bb10c5927526b, 0x8a54be4ac20f48cc, + 0x0ae8b4a0bad91751, 0xeb67ff75ee124346, 0x1515546d1e979c55, 0x14f427ea08579062, + 0x417221524b32603d, 0x0c07be6363dc5696, 0x3069a027fefdbfcd, 0xde0a8a07c2fee3e2, + 0xc59db4df32b08ff7, 0x10fe9fe70a741496, 0x40ce7d70825e87ef, 0xd4ee68a360d4de49, + 0x23be82ca13ce0224, 0x4818b61cbd591346, 0x6d6bf93712ce7464, 0x623efd3623df3fcc, + 0x49803c72d33329fa, 0xf804762425597656, 0xf394c10d792761ca, 0x9e34c2d7f44c7d24, + 0x2befd74db9298810, 0x9425c0dd65402b81, 0x7da3ce88b6b1b56a, 0x1f8c171d276e9577, + 0x9f9910e7da773bfc, 0xa5171b7d3ad1037f, 0xbc6e9c797714726a, 0xb6e24b1ec9a08a17, + 0x1c96639e95980a01, 0xa3752e0d705a9fc7, 0x1fe5201d22672176, 0x95516019d82e11a9, + 0x6215f02966725e56, 0x659d490acaa494c7, 0xe667c001be396dc2, 0x6e280443baf82c2e, + 0x5da036f17f4748c4, 0x350e657a1651a233, 0x3057b08db6472855, 0x0e1ac9d88435a912, + 0x495aa2f5cc734dc1, 0xdcc0be4798631546, 0xed132b2c7b16ab1f, 0x26167f1e138c72f8, + 0xf1cf0c3c0ba50842, 0x7ddcbad78acbdfda, 0xd759ec70663d78d7, 0x9871251848dfa580, + 0x4691d4d7ef3eebc5, 0x52d9962c3fe7e406, 0x546a76323ef9c028, 0xf81639a7f4892429, + 0x6f47b71fbd2ef211, 0xa9aa1eb5c554759a, 0x5de7c7e8482deb45, 0xd4556bc5748dc84e, + 0x720022c1ac31fc1a, 0x8f3117ca2a0325ed, 0x21f1e02fde7327ba, 0xa3591f78e8811dde, + 0x041ca47c58c36a1d, 0x0ca3868fba651592, 0xfaafa93e97b50c6e, 0xad2f81dc4e030785, + 0x121a888d3fbe356f, 0xf1f665886adfd844, 0x5cd23fccb276cdb2, 0x7cafe4410eb8964b, + 0x302a7431516bbfe9, 0x1d9559d87f515393, 0x547b2aa97dabfbed, 0x81f4f876b3516f3c, + 0xe455da3cc9d8fbe0, 0x1e43664ba279f7ca, 0xdaba600180ab0825, 0xcf02371835bd53a6, + 0x8246c1368ec1bdfa, 0x10ba6cd521dae891, 0x181526480d0b44b3, 0x69341bf7381904d8, + 0x5e67552e790493ab, 0x0edb4212b05013d0, 0xc3775c491aef3cc3, 0x5926e8b08d74e5a3, + 0x0d360774a0bac8c2, 0x656cf785c1ee5c06, 0xa8cc674b4d56cf35, 0x908a613d6468bcbb, + 0x0b9edbebba23c8b2, 0xd2c9f982c2573f1b, 0xda0cf29a4144c5ae, 0xec20e2a2edf03a76, + 0x780675bf2762c334, 0xd48b43519b83a6fb, 0x161211289d9e759d, 0x8b4b66c077a71214, + 0xb4a3921c4f804865, 0xa27239bb7b5b400d, 0x16f2a7087f051c3e, 0xb5991a243b380571, + 0xe5f45026aff515ca, 0xfc037e5923a7bf8f, 0xbac2994a59bef6f6, 0xf0101337c165affb, + 0x2569833cfa264583, 0x940b8b0728f5d134, 0xdace65921960a40d, 0x6d97a08ec536e3ac, + 0x4d5df696f6657d1d, 0x2e01488e31fd69c1, 0x403bf7aad9fcc776, 0xc9ef410832f57057, + 0x100857d549fdadc4, 0xe6be79ee6164bf1f, 0xb1da3093ade11eba, 0x713fc73f8abdf80f, + 0xafeda1d704aa6be3, 0xfb185d6153b90797, 0x4263e3770a2e015d, 0x1b1bff41aa946c1e, + 0xde832c9b976e57f4, 0x2174681cf8d5188f, 0x1db8756313eddc8c, 0xd6077ccc4237901e, + 0xc4d82fc3af0a71b6, 0x9e410189c061f42c, 0x0bc1db01c9b5736e, 0xf3aff6b75046cdfa, + 0x5a5b799c8332d991, 0x29e61f65c3a30e2a, 0x8fdb0fb6359909a5, 0xbca4d75d1696fbe0, + 0xf081da38d0ab1f14, 0x2182a269101bfdfd, 0x11cef22081aca576, 0x284032f083e6ba2b, + 0x6f7ab311b66c126b, 0x78d9b20cd3c2f7b1, 0xd28adc93b1aef8fe, 0xebf4740b50657292, + 0xf138efea7d362793, 0x4b18c0cac0220dc7, 0x4a89f79b064e0773, 0xaedbeb1e815005e7, + 0x1469009125e8d770, 0x07147fcb58b01491, 0xdc7fc77dea85fa3a, 0xc6907260d9d9f1a6, + 0x342d1f2a45dde648, 0x39fc314db048f4ed, 0x03c154254e5a8325, 0x88c9804d83488d1b, + 0x7a313aa8bf35d9cf, 0x99e90306963483fd, 0x67fa5dbb3f919a77, 0x15e0ca3d7ceae94a, + 0x3b028350feba5ccb, 0x403324d8635462d0, 0x1a852cb0546d4e2d, 0xe3cd388d14232de3, + 0xa74f832cf5e103b8, 0x759018226ffe3a9b, 0xbae0641b6d9af50b, 0x88af72c72a1735b9, + 0x5a5e3d32754fce68, 0x732aea64c428ddfb, 0x5cdcc140659bb0c7, 0xdb39fbdad503ea86, + 0x0e32561516957cda, 0xf8b53d3547794eb5, 0x3903f263c3345c54, 0x95d3257f0813f011, + 0x69eb601369497929, 0x48a20bd9a9887f43, 0x297544f583a73551, 0x17e674489f5fe1c1, + 0xb4f94fdabcd4437f, 0x469306dcaade1f45, 0x4cca8bc8cea5d7ed, 0xb1e7152e7f812741, + 0x78f0b4a3d381c90a, 0x21129b9bf3c19485, 0xa68b422f6b7b5fec, 0xfdfdd1c380283fb5, + 0xb3ec690dbe654d44, 0xec02ab714b796f70, 0x53ac4a2792e55174, 0xbe89038f89d8c86a, + 0x1637a3045b672422, 0xafa0df471fb15049, 0x86aa975c79b4d651, 0xcec9b5dbd8e3bf68, + 0x172ee2e480ddabd3, 0x9e1eefce76c3ed06, 0x1316041826e0925e, 0xf97d6a6c9a680f42, + 0x8a57d9591bedc610, 0x24b5e20eb2ab3950, 0x0fae09f6727ca9a5, 0xa08b5adfb61f0ec4, + 0x85acb4736927841c, 0xffb27a2605983fe7, 0xdf185bffed6955ef, 0xffd95ddb9dae5f98, + 0x98b5e8c6350d660d, 0xffa09cc75b34d34b, 0xf8316acf61a85578, 0xd99da1a593625494, + 0xae721eef6ce7e3fd, 0x6e9e8f8a0ace30a6, 0xe310371ca0632214, 0xf011c7362b59c96a, + 0x0a2ab5bfdb8579e2, 0x26b735ba43772908, 0x67333142f56ba2e2, 0xf04e6ea0fcb036b2, + 0x5cff96ee4f7d2244, 0x1e63f10d32fa09c7, 0x345ef5049d946c83, 0x4755ab79b772bbda, + 0x7360ed00b0bd0e98, 0x0f28ce27f81e1146, 0x74f9c03f439ee23e, 0x5bbaf7949ab913e1, + 0x760006e8cf8a2d95, 0x73c72c68976f4109, 0xf3c2c188d1fbf78e, 0x7a84450f71b21405, + 0x5983b48f4db210c7, 0x6f812aa59a7d0920, 0x6a8d46113fc21984, 0x416e18941b374686, + 0x1a2c50d13012687b, 0xd3ea3ea214919d51, 0xb2a4d2fec7145208, 0x0bf1c295fb5ac741, + 0xee4852b85bd0c569, 0x5380f776724dbfce, 0x61b1fbb727b42137, 0x13b7317880b932cc, + 0x837b8f8051d4929d, 0x6e99b631f89130d7, 0xbd4a1cdd8857c699, 0x1cc4a20351f73f00, + 0x57638d9c60b719dc, 0xf6689f77f6f83171, 0xb4df983a0b0bf70f, 0xf59ae1562ba18dae, + 0x963bfccccfafc1cf, 0xdb4d2f74d57b2701, 0xaf4a34f60ef9d5ea, 0x6a65ff0450cbcc47, + 0xdbd8fbbb0098cad4, 0x5ae79b4296dd9f06, 0x02c3d3db41e352be, 0x3a5a04821d141f3a, + 0xe85831b1ac7aabdb, 0x109762a12d49bb88, 0x216d9eff75fb3424, 0x80289341c16292cd, + 0xc72ccb89114baf96, 0x7fe7717e3583dd3a, 0xa017fd4711a2aace, 0x7e0e66bffc736322, + 0xe9fee601f71953df, 0x87bf9aa7e70e55e3, 0x139b3a8011c7ce57, 0x91a2961d63429fdb, + 0xa8b1e5baaf9682f3, 0x778afe6dc054e7e0, 0xf8cd7ac9fbc68977, 0x53c1b40ca51890df, + 0xd288bf668e9f8f5e, 0x261ad8d7b74100b2, 0xb995a82fc8fa14c0, 0x2377d33f0c1ebf4a, + 0x464466bf2a4f7889, 0x5ea7d2dbed54a6f3, 0x8fc81bfc30701d06, 0xb03c5eeef6d9491f, + 0x98337168f7de7c59, 0x91b42b56dadc2f25, 0x7a1f5eaea3222afa, 0xd10464548858fb61, + 0x1418513fe2ed3b85, 0x55c29995c9bc85ed, 0x685bb0b9fe5e7831, 0xa55dae869a227f6b, + 0x4c23c6d4b18dc335, 0x7efb3cb3192db0b2, 0x58d3b08a0c5a6a9c, 0x39ccf8172529eff4, + 0xfa65e19f0a212f2a, 0x6a6538e8335de044, 0x799537d940f69da0, 0x4ef5db64ced9f4aa, + 0xdb0c01d97a675467, 0xbf8102c9d27a81df, 0x178a385775b7e807, 0xc0f5708e3b9d4604, + 0x18ff1ba6cd444785, 0x17c889fc54ae7388, 0xfed408c5202f3662, 0x0a4e39e0b18f6f00, + 0x8a3edf99a8455688, 0x6546ea1100d94444, 0x9c2dd7ca0c519b79, 0xd84353ccd06f0f84, + 0x11d184111eb9f9d1, 0x5a5b6e1cc5897e70, 0x25236e1b4b253360, 0x18b1e14ee642f13d, + 0x4b55a28e2f0bf78c, 0xd900cd65e3e040c1, 0xab342a44b9cff5ba, 0x4e1abb4c8332da69, + 0xca2c506136d968d0, 0x2bd3ea0f4aa52317, 0x6b6fabd4014072ae, 0x4bb7efd95ab6b5bd, + 0x9a4d42e391d35275, 0x7d5248093261990d, 0x459e358ea86a3b82, 0xb93f5513a8ef5aae, + 0xabfeefba99aadb53, 0x6311aa0de20538d6, 0x0a866343fa38d1c2, 0x3edd188b6daaa7cc, + 0x5bb5d9e52aa226a4, 0x91b984d169a77eef, 0xd963dd6d25886c27, 0x8c42c296156a8578, + 0x7c06357db744c2ad, 0x63c7554162da41aa, 0xf60042505cd32c4f, 0xfd0d00c0e5d8d81c, + 0xb2a86e3e9c492521, 0xa3761921215fe3f9, 0x9a7e85a3f9830186, 0x610455c30b627990, + 0x1480519d41b78c8c, 0xacf5fae042f389e1, 0x4e3c71c6a0922b5c, 0x7144a645ef671b9d, + 0x7c9caebc6485951c, 0x74f005c17e7643a3, 0xe12c423b59593205, 0xf0747ef10b12aa39, + 0x958474cf7aa92777, 0x680739c8ad1b6487, 0x17fb4af6687d0fb9, 0x456782f50a62da25, + 0xe6479a255195bd23, 0xd52f7da3dbb62661, 0x43ba9e45d21224c7, 0xa00c85b2f0353eb9, + 0x00cc9095afde7f59, 0xb5720c23d85b29bf, 0x98c9aab154ac077a, 0x6bbe875a6c28e02e, + 0xd927a64287dcb9e9, 0x88ea4d58e11c8631, 0x47484145e8216bd5, 0xc621e68a8bf5706c, + 0xa771bf92bf2cb846, 0x760e8dea5262a69d, 0x3e3e22a211886726, 0x679fba6dc925f014, + 0x47776e3fd7fb991e, 0x3426b5650095eac3, 0x05489588d1c7be72, 0x1bb06ce09a1147f5, + 0x68784d5b1ecb2f94, 0x3b1fca86e2fd4e86, 0x720b553fe5aa85ef, 0x9b9e9c18c7469115, + 0x12e6f7437b91fbec, 0xc2b352a9f774933c, 0xd660ac3a93ca1aa3, 0xa21a8212990eb4a7, + 0x2eeadcd367965ab9, 0xe8504b240f220d76, 0xc414c61ae2489c32, 0x343505b24e615a9a, + 0xc80504b4b188e4ce, 0x23b4e13ee270db69, 0x9b4a29960eea772f, 0x05f1b1bec2012b2b, + 0x9cb5917147ab5e55, 0x9b2e7cf39e67e0b0, 0xce142e9a567f1a3d, 0x492036154bc9385c, + 0xc7633ace53e058e5, 0x6ff55315764fb252, 0xb547c490d737bfc1, 0x3ba0dd8c4f1d62ea, + 0x98d378f883e9e4fb, 0x3a48637f37dab652, 0x469f122001321551, 0x2fedfc843a1ccc06, + 0x9c36b82c6956d6ca, 0x5c33b52e160ec8dc, 0x8892d331b30c4545, 0x6ac22c6dfe8ec1e2, + 0xe81ab043d7b9f339, 0x978ebc89af6c6d27, 0xcc346445a73fe790, 0x7260dc1a53e29432, + 0x8069447d490b73e6, 0x359fd59be64742c7, 0xd9d800290e0080c6, 0xa07c6ec91e964b92, + 0x9595e6d861f38dea, 0x7dcfaf54f9275cb7, 0xfcb0b80701e1fa64, 0xf5111f306a9eeb92, + 0xee63cbb405cd4c37, 0xfc53d1887aa00127, 0xc214cc1ec26961af, 0xf2308026c802f880, + 0xba076367e293be28, 0x857c09b243c05633, 0x4fb26b28a1c5ad8a, 0xeb5b349b0deefe63, + 0xcdb91e9c2fe6c1b6, 0x20a245ba4d49730b, 0xdbfbe0326ff70ba5, 0x2d330e5c629b4218, + 0xe642be090ce4a911, 0xb97a6999000ea74f, 0xd051cabe64a9ca18, 0xd3586499ae672f44, + 0x0d5d896178b808d7, 0x200ec59f48d0b2d1, 0xe382623ffb86a970, 0xccf0553cb78282df, + 0x7f5b621be4082b5c, 0x486caa27a0fb880b, 0x80de1725e7c20169, 0xb0dfbca1c882cfee, + 0xc987b1f4d1de4bac, 0xcfa100b3a53b4f59, 0xde0f923a549285dc, 0xef1c52eb27330c7f, + 0x0d378305373b8cd2, 0x5f37b8588fe833df, 0x9b74dbe60118b62a, 0xe17599fa643ffb7d, + 0x9eb91d4a40f91903, 0x199a5943f8253942, 0x097da93dfc8a0b50, 0xf21ee9d435c5c4f9, + 0x8e1e62d9bab403bb, 0x6824104aa8fbdbea, 0x1804a2a0ba867ab4, 0x01c40077c55f9600, + 0xa711afc0d8277a6c, 0x1d8cccde407bae46, 0xb1624a5794a1922a, 0x0d395ad2b703fd31, + 0x0fc26ea87fc887ef, 0x53fbee0f7bf1d96e, 0x6777b7a2732e76ab, 0xfb4c5b6f3cd92e28, + 0xfe5ab944959fb043, 0x3cda7eb55ef8de50, 0x38f3435cae705175, 0x471b3e4925bf69eb, + 0xc2f29b5df092023b, 0x495117f926ad4843, 0xf9f95bd69f2c275b, 0x0ed098292c3460aa, + 0x07aef0ebd3a20b35, 0x8823a9c27ae892d6, 0x83a0e3380a36e1c9, 0xc1015c4896835b13, + 0xe531d415e69369d1, 0x1cee39b21177c203, 0xaf918dcccce417cc, 0x2af0045ad0f4a672, + 0x94322d44bab8067b, 0xaa4330dd359fefaa, 0x40ba7e116b3d9b3f, 0x57695ba81d5261a3, + 0x7673fbbde34d5f50, 0xa899c1790c552c20, 0xebb9a6b8ea1ea32c, 0x04a686f0cab349c7, + 0x2052275a7b642aef, 0x2116b627ba1f9531, 0xa750e257524f611c, 0xa364cb782487ef46, + 0xcbb879ded6a5b1f3, 0xbadc046237e53da1, 0x4be9ea6946674874, 0x513be119cc49fdef, + 0xd0c9907476489ad2, 0xb0a365a535acc4f8, 0x62f1dc3e1f94aeb4, 0x40b06b62e1829fb1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xca542cdb412698f2, 0x4fe1352a149847fd, 0x253c6ab7ff1fe06b, 0x38920a6f5a7b3a7a, + 0xc203996f363b0362, 0x3c81172c1bbaefb7, 0xc8ed2c81f0946ee4, 0xcb3ff6929a5b190b, + 0x4895710e25ffbc49, 0xebcdf1a88a09b25c, 0x35b2118c1435c20a, 0x3ba2e4a4b73dfcee, + 0xc2a4ded28bff63b6, 0xe61e12701546657d, 0x8f9f2e9cc01a8e8d, 0x18fe777d842a4f3a, + 0x9354840eb4c6b0be, 0x9580b03bef7770a5, 0x15de050c15dfedfb, 0x722f0d54118855be, + 0x8863cc5cdbb80a35, 0xaa3b92204364a650, 0x3dfe40446d3d7a57, 0xafcfedd19bfe7094, + 0x107b4dfaa9e1ebbb, 0xf7ee4d8ac4c3d95f, 0x3672ef04d269ad96, 0xbf822abfd1ee162c, + 0x5aa76cc7b0d35ffa, 0x069afdbc39a0a204, 0x7e734908f3d1a9ae, 0x10c4def6fdb04a51, + 0x621767e85818784b, 0x3f077a9cef83a6aa, 0x3a4f6bd64bc047ff, 0xefc2556901e43847, + 0x2ca1842052079a67, 0xa64d538c318f4de8, 0x4d01b97221fa6ce0, 0x2c864d4bd2089e8b, + 0x271f45a9b403ad9b, 0xe85ee41a993e2bde, 0x8fdadd5ccead598f, 0xb7617ff66bc46ed8, + 0x019379f0caa3154d, 0xb6b2dcd0226711b6, 0x4ee064fd1922c930, 0xfc24496c13763d21, + 0x12686aa52b53cf21, 0xab1f72444b0a41b0, 0x43973298a330308f, 0x2b8fca4a350510ae, + 0x347df266db8b818d, 0x05e64769b5b46f78, 0x7e4fe50bcffe5021, 0x86afcbf747b0e06d, + 0x705802926b26329e, 0x5300a07e90521769, 0x548991830e03a58f, 0x6dcd63c828a15e52, + 0x17d6fb7d1b87ebcb, 0x5d9acfc636497674, 0x2cb1261378d4e408, 0x8b6e8f44c354ae5f, + 0x197ef54f3e12bff9, 0xf4113093d8f79dcf, 0x13b80cb3995534bd, 0x569d1bf30b0fa502, + 0x6430cf726836e5b0, 0x37416f13cabdd815, 0x8ff2dd8ff02f2f3e, 0x24f12eae9ffbbd14, + 0x3f67f8b7cd8fe85a, 0x4bd8afebc5171990, 0x298f2ce406588ece, 0x94f408558495097a, + 0xc6e61fca75dd4ca8, 0x317ab11d1dca6f51, 0xb59ec9819c0ad1b6, 0x2984fba6501365b9, + 0xbf96ec9b6a31c438, 0xacdd91a1bcc69e04, 0xed867b8438b6bca2, 0xaf82c6c039ab82bf, + 0x32939903881b4d3f, 0x6dd20ca0b1b5f101, 0xce9ed6af845f2bd9, 0xf2785284257bb443, + 0xf0ee36539251aa08, 0x8793ce0c732eca08, 0x1c7d5ba42f94144c, 0x9bf23b4911ed9ee6, + 0x8a0ad0b4f553cb88, 0x733229bd5fcb40ce, 0x133b9a981721963f, 0xe33b1e3526647681, + 0x7b65cdf437c85fe4, 0x578540579a49545c, 0x43e19c331c054ccf, 0x92d2e7bd80c7147c, + 0xd2d531cfbb27f2d9, 0xd57feaf66c2b28c7, 0x75796460aa352884, 0xf4f120c36c2dbae5, + 0x9ad43fcc44d3f45e, 0xf5d38b66d62cb6d6, 0xdadfee87d465b416, 0xaefc2efa00e9f86c, + 0x029d696c59e2b923, 0xec76f5dc830aae30, 0x57927a620d08b48e, 0x7efe6418968ddec3, + 0x3d0fef913c572198, 0x91bde403ca8f6de9, 0x6b92638b515b2fa0, 0x91c2fbeb1b9c2fda, + 0xf73cb79442d2a860, 0x5bfa950b9e174ad0, 0x28ae705b9ffa78c2, 0x7c865847d0ff854f, + 0x0f96d3f38986420b, 0xa48d049f96a84471, 0x1de174439a27bd9d, 0x0df68ea8e350b163, + 0xfad286b116126eb1, 0x83fcc047257596e1, 0x13b83ebfed772458, 0x8212268d3fcdf59c, + 0x873ec8347618de7e, 0xcacfd64794de34f7, 0xa304ddcc95a06c83, 0x2054171501db5a99, + 0x318e5adeeeac144c, 0x4b18d7be3e724965, 0xb788a118c9d7b8f4, 0xdf2eb71646e07d78, + 0x6d2a0e9de16e21ff, 0xf6f57b1b9b2177e5, 0x37cd2d09c4671edc, 0x6ecf09859efc225d, + 0xdb61ef4d0d57d7cc, 0xc40b48bc7dc7270f, 0x8f1d12e55f717841, 0x1fb9fd48c8acfa82, + 0x3a6cbaf0b992ba43, 0x47b9e4d679e7d89a, 0xbe62a0680083e6bb, 0x021aaeb6bbfc29d5, + 0xaa94a8104d39d973, 0xb5d3e8cf62ba3f86, 0xbdadd0b34005543f, 0x00c0bf98e12e1623, + 0x0e9f85157ded4102, 0x1ac277a70ef62372, 0x10897f3039068712, 0xc5c7c4517de3a2c5, + 0x14eb10e0edfc5b70, 0xd7b6e5cae42d74f1, 0x2b51d550b91638e8, 0x2ea372748bdff08c, + 0xdfe62dbb40877573, 0x444eaae83d4b4546, 0x6eecd0b396593df1, 0x6dc6a5e0e8e35123, + 0xac56fc243c23829c, 0x866097dd526b74d1, 0x629175c1c1783058, 0xd9f040c7d2f66d09, + 0x7252253f6339a75d, 0xbb6829c08e074f3e, 0x9a3586118f393b5b, 0xfd27c71c68996f74, + 0x5d10b33a097c0996, 0x06ed99e18b84f700, 0x1085a782307d3f61, 0xeb8c90d62375e292, + 0x434dacd0d2954a7f, 0x12f6341e203e26bf, 0xdf9168be72dad9a5, 0x17057cb44bd78cc4, + 0xc31debe76ccc90fc, 0xf77fce074c8caa92, 0xb9445e94de3b8bdc, 0xd800a15c6e7452ea, + 0xed96f03d68976027, 0xc4d7c6e3af6e8da6, 0xc5b413e4b47fea69, 0x7c4cbaed97d0de9d, + 0xf1900c8de14774fc, 0x41426091e5716f61, 0x09ccb84fc40086ae, 0x1cc35e9bf2074776, + 0x0a275cf337d59d4b, 0x3974a4298c37468f, 0x95b5ecd44da403d8, 0xc521b62e2d5f614d, + 0x8d03224243b244e2, 0xa10d5958a4793089, 0xbc1c5737c81e2047, 0x1bc86bd13dee8d31, + 0x34d4e55e8e586b30, 0x5bead4a4439efdd1, 0xc4b2899b5d73d5a4, 0x9bd56aef624255af, + 0x0075ba8b8e782b46, 0x31b7001e8972101b, 0xf36e5c0a64c75a01, 0xeeaa9536595276d6, + 0x115a9594b45d709c, 0x44bdc8c3ce74b728, 0xc088f6b75307b5db, 0x4ac2ee2ffe352c74, + 0xa97b9403f302ade2, 0x99aba346d50e1b64, 0xb0a27d8ecad68e1f, 0xd5c3bce8bf88e176, + 0x6238fa7472fc15f8, 0x0193fb0658cfe5cd, 0x6903c93374fab7d2, 0x18d7e2053ec6afef, + 0xfcd6cb5e5b6c23ee, 0x80659e2041881669, 0x51a1aa99f6d0557a, 0xb937a825ea1c421e, + 0x98f0aa8673807776, 0xeabf7256be842ddf, 0xb6eb56b64f61213e, 0x04c765b283cc018f, + 0x181c5c7929caed11, 0x7e730cbba3f24128, 0x2da688955cb1424d, 0xf7ad0cd131bef18e, + 0x1506f350b53fa5f0, 0x8b017838727c83ff, 0xd97cc85a86a0dd5b, 0x5fee32732e1e4302, + 0xe11eaf20d6abb238, 0xa97d2abc66144aab, 0xc217722da3f9d46a, 0x51557cd7c90a6777, + 0xa62e3b5cffb65d08, 0xbf54efa2120417af, 0xcd7badfd7b702402, 0xfe31d5804efcd7a8, + 0xc6368d5cadcda961, 0xf59a434768c640f6, 0xe16793a753d53c41, 0x0d3576489244922c, + 0x13506238a50eb516, 0x44e4da075a34d5e8, 0x9b84a7383bec0045, 0x3674d61ee7e8705c, + 0xa75b6a55bcf296f7, 0xd66564c9f1de1bb9, 0x95e83737db190399, 0x0770b79ac94ff9c3, + 0x137d8a91cbd41a4e, 0xb9e3e3b0a6e51450, 0x50086ce0297950c5, 0xd6533927d85dc99c, + 0xc57500e690f3d693, 0x2b01b28edb06f16a, 0xc6c35505f54f0469, 0xee6c8a873f429ef6, + 0x7d0608e7c0543a50, 0x38d9a23c9156d124, 0x1205602e6fee8755, 0x43ce9325c1c760b2, + 0x21c155576dc245ad, 0x363e2170e80e4653, 0x786bd19dc5f25811, 0x5044fd592ebe33f4, + 0x8ab1c2ffc39f0bb2, 0xabe586efc3d51956, 0x20b2b427464224d9, 0x0c87d8d88d9545cb, + 0x9cac3fd265d1625d, 0x9891a23725ea25c9, 0x66ffdd52250741eb, 0xb2c64e0cffefb8a1, + 0x05ff99eb1e80c2aa, 0x127cec655c54c936, 0xb2f409127ac3b569, 0x116010d2dbf26f92, + 0xdb0188dc239ce264, 0xab36c117dae86d0d, 0x88e61d55ece6046c, 0x80724e50916fa23e, + 0x31849d054fc4c74e, 0xc670b886cde40afb, 0x945839817418daa4, 0x06094f085a390f10, + 0x32683e18b94cb90f, 0x13ef55fbb6944cbd, 0xca62067197fc843f, 0xc08b5eb082383aad, + 0x4e38f0fbc8038433, 0x421e6f15ab233e2f, 0x86386b85a6ab0e84, 0xc2f40c50e0690bf9, + 0xcbbb0b2d762f75ac, 0x8b09a1dd2bd56014, 0xa8fbdd5233605a58, 0xc118b665a0637e2e, + 0x09701d3c74682da1, 0x163682ee82212dd7, 0x2c232ca5b26da21d, 0x547ab2a1bc8f7cc9, + 0xac198be0512f7d20, 0x7357e9fd307959d0, 0xd567a106b7c0f5bd, 0xdede6eb186aabb16, + 0xb211d1a9434d4d7c, 0xca9b3ac5e5da10a8, 0x3fb66834e62859f2, 0x79d1146dbb9f90ca, + 0x6a33910ea8c55129, 0x6de8d6ec461559ea, 0x97abfa119f429a89, 0x9de3d9abaa2cc297, + 0xeb945077311c0012, 0xfbeae2f7f25ac082, 0x96dcb71bc60e51c2, 0xf118fb542fd24e4e, + 0x78b32042a085ec8f, 0x54d8ed659192580b, 0x8491f7c6f1800046, 0x7bf2be50587e2a09, + 0x2d53b8eb5462f7b1, 0x36854119cf4b622b, 0x22caf19cec8bc08d, 0x94b5d4232a87e751, + 0x8f81507ae939e121, 0x30bbc69ac82212e5, 0xa42c08a88b6b766c, 0xfff9f329b607a353, + 0xea741e3c69cd2624, 0x70c14ee756989c78, 0xb3d582694e0e7611, 0x1b92a851488944ab, + 0xf139973acc591897, 0x64e8f0a050a51e0b, 0x111f4fe1f6109dda, 0xed5b7498d25606ef, + 0x3379a56371b73e60, 0x127ece581b4d8b72, 0x200c404016f88733, 0xcbb09d18513fd83b, + 0x4dd4e41bf7ff149c, 0xaef71150b6bb4d3f, 0x803526f19ea4eb9a, 0x86da6c0f9a5837a0, + 0x0e43c47ca4251efa, 0x528ba07c02caebd2, 0xb86bff5360b7d3e0, 0x23ac5180b3a95349, + 0x4dfae89639b0ab50, 0xc95fe2ba17d790b3, 0xaa48bc568d569677, 0x2ee1cea326184b80, + 0x63c255d06574a857, 0x15735e3ab6f36147, 0xd81949e52cb1755c, 0x1f81179b6a0353d0, + 0x19d5e9f915fa1858, 0x0a58a1a805728add, 0x8f978ae803aeabf1, 0x1248cd87a505da9b, + 0xbafb8459fa942df4, 0x728329d64013de33, 0x8b30f66510d8d73c, 0xf8b8f2c1735e4f01, + 0x49303f6a119220c6, 0x166a747d9d88f916, 0x3ff37cfe1e29e0a4, 0x0e95d685b7a21484, + 0x3960a2fbc61b07d8, 0xc929f9bf454d7df4, 0x3282129d4295cffb, 0xe79d981b672565f0, + 0x7827ab08d65eeaec, 0x78443d7c51db14f8, 0xa4a4dcb4d6839df7, 0xcd2d881119219b8c, + 0x0fea66a899b8161a, 0x6b2589fee55fc23a, 0xb6ad6c0155532284, 0xebdb1454f4af90a5, + 0xae3519840292d1ec, 0x6ed0c81d39fcf9b4, 0xade582463481c4b8, 0xfc44336057ad370c, + 0xc3ff360705b5bbd8, 0x153da7a62e8d7327, 0xb6359dcd0e256812, 0x9224fa49d95d2026, + 0x0094863e268530b9, 0x6efc1da7f5a6bf8c, 0x630d58f1bf94d603, 0x2eb084ad3d8cf835, + 0x07f945a2098705c7, 0xdf98d91ee25b1dbe, 0xf842bcf61f58c063, 0xd4738b4f8d6f583c, + 0x190cd81accdb8cc9, 0xf55feab78d0bc07e, 0xdabde2bab5c1564e, 0xbca9f9f3f35dce81, + 0xdba3be7723e54176, 0x2d950165b245c062, 0x9f6362d8e215cc04, 0x5bff2cb0a2bb93c9, + 0x173545d3287366c9, 0x9031a75685128ee2, 0x3c090269906b7b2f, 0x856e74e3a3ae3c44, + 0x1dcd734b48884f43, 0xf2023762625b45f5, 0x5866b7a6d275b688, 0x7f29417affb6a6c5, + 0x47566d33f6b0f081, 0xab1f9b2707276a2b, 0x8dd1f1bac1160a3d, 0x40ce5c896adaeb26, + 0xf6bdbc8902691e49, 0xdba94a25ada41840, 0x15984af0862225da, 0x40572febd8dd75c1, + 0xbe61829c065dec68, 0x267203788af36c05, 0x47546315b704e9de, 0xf21d43800ac647e3, + 0x9ebe53234afed8d1, 0x2bda6f6656dbf042, 0x0f8bd727c21a79a7, 0x88723293822f2d09, + 0xfb06991bcb45d108, 0xe6f14dc1ba19da20, 0x486ca02e47aa0175, 0x781fb0b433535498, + 0x30e3e14c3968e795, 0x2d149602709817eb, 0x12c98249aa4e87f1, 0x28ad459a6781b897, + 0x72856390164c256e, 0x86635d696eb7c609, 0x80a6b2d16e9aa9a9, 0xe809fdf74284de92, + 0x75cb37b4c63378a4, 0xe1c6aa91d569422a, 0x5b5b80aa06b28c32, 0xcfcbdb4bba662e57, + 0x2390b6068198b4a6, 0xb16193f07607a5c6, 0xaf2160f11896b536, 0x063d67de09590776, + 0xe25e62c3c5d11bae, 0xfadc804cdc39b9ee, 0xee360ba293e2c645, 0x10f715fd445808eb, + 0x4134c9b9e56af9ca, 0x2a3acb81a167f014, 0x64e31c8eb1b4044a, 0x0c2f9be4775c4de5, + 0xe9525bbef12e52f6, 0x42ece0c99a3cb49e, 0xf01ff8d3cc135b4f, 0x017af1916a235a55, + 0xfb6e8f4e7551eb5d, 0xc58beacabb45be6f, 0x77793e4973600f88, 0x89fbf9939bb6c8f3, + 0xdbfe19cacb4267ab, 0xe5ccb6ea49751abc, 0xb89454f51281f80b, 0x5dc8f49b0cce3a94, + 0xc82abc9a6fb024c3, 0x9419e2710009de15, 0x7c2a3546c1c45a28, 0x69abd0296368ae15, + 0x8abf7e07389f9810, 0x314dba595bd7bca6, 0xf3a4bff3bdc066cc, 0x2e7d81a6bca963a1, + 0x915f1335ff0cdcd8, 0xa21f582338707546, 0x0213931226428eab, 0x178b4509d70c9a9c, + 0xe49decc943c93f88, 0xa321327448013ccd, 0x05ecb36cb3bd8d8a, 0xdbee1a9f76bfa274, + 0x09c6ad3fcb4aa292, 0x0990d619071787e4, 0x4574986ddb2f6df7, 0x50f81b52aad7396f, + 0xb7a324f62ab9c972, 0xa55fbfe48b6c91a8, 0x087fc60d4057f909, 0x4830bdd4ced35346, + 0x2cefc2482fd07229, 0xdf36eb0c47598ccf, 0x5c334f62b2c0a6af, 0xffa33dd5f8573feb, + 0x768202a17f2458b9, 0xbbff35584af5190a, 0xebfc0313228dbb41, 0x5961861780176fb3, + 0xb64f401e44df426d, 0xef26313fc040a9c4, 0xcd30b333da08ef6c, 0x4055d40d836058a6, + 0xf5c9482014fa1612, 0x9db0fb44509c0b42, 0x5f67683efe7bec9a, 0x6c00e33642ef399f, + 0x68b64050729d50c2, 0x98658a31ac74c9a6, 0x0fac0957602b15f4, 0x0471d04ef3e8b99a, + 0x42f5968bc25946f8, 0x1bf3ecd0d48bf648, 0x692232d5cdde7f32, 0x7f3accead8de4db8, + 0xc89454a9a00e0ce2, 0x48a3a385e9384751, 0x6a8d8ac180574b04, 0x8daf933b08e7a3d8, + 0x0614b6526a4f9335, 0xa685994539540c98, 0x0cd02e6b27b1bdaa, 0x6a8f3e56d3493671, + 0xa446c0a40ce7fa36, 0xc4d38bb9377106bc, 0x22d9b40eefece45a, 0x24dfea061770f319, + 0x3682d43d9e6acbee, 0x942770aae0ddc133, 0x26fc12a3e06fda22, 0x241ee9a530d815c1, + 0x76948e593c5f673a, 0x6e01659071d81d9c, 0xa27bc40353043e00, 0x13382352d181f82f, + 0xc12930ded68136e5, 0x82617dcc69f59e4d, 0x98047379ddd48eb2, 0xb68d3a5b7e41b441, + 0x83ba4d004b58671a, 0x48a9ff1d39b11592, 0xff2b31e0e41acd76, 0x9812a3bcacbba48f, + 0x7ae252b654c75f93, 0x5b21c92cc2d804d6, 0x1a5690931200c763, 0xc5883ef42e6003ca, + 0xed2e2ec83e4f5e29, 0xaeea91523734edbc, 0x59435bab3af17f37, 0x680ca8ea3d4c7717, + 0xfdc4501d915e7e06, 0xf85e4d35718b829f, 0x79a38d1d00d26f30, 0x6e13412726d655e8, + 0x2d33517560e85824, 0x7d75c23eca415688, 0x1c6fa64779c0f0c2, 0x241583ea38d8e6ae, + 0xe3506a3b2cd29483, 0x2735b0ae612c0c98, 0xd1f92f0210154fea, 0x6b6879478362463a, + 0xe7363375ce994758, 0x58cf74270bd60333, 0x3bfeb9312c30e5be, 0xf7007c76b5e2166e, + 0x2cd448787e559029, 0x947e87ebca861a11, 0xb733ed110fd885c3, 0xf995b9bb41e7a875, + 0x8174e88e3753fbf4, 0xa0aa7b452c5f7728, 0xee58cbdc163c5d06, 0x76041444fee7668e, + 0x4590bb69a1d726c8, 0x3eabacb57bfab13f, 0x7dbbf2caedfde20e, 0xe0abf86b8d4e2992, + 0xf4a5ad330b852898, 0x0efb9dd678a25583, 0x6b3452fd8fcb0235, 0x927cc48b883c8223, + 0xccffc692d2c931d2, 0x60b4bb1ff16dc08a, 0xdf90b0af11485aa7, 0xac8534e8f65a5e16, + 0xaae849df3309931b, 0xdd741e2909d1f3a7, 0x61e5ad18543c4570, 0x17aaea62b07b2fbe, + 0x5a1c652afcb897e2, 0x5d8ce4e0fb478381, 0x306f2724cb358cde, 0xb9618e69b272df95, + 0xc50f972362c0b896, 0xbe24c6ab4428c6c3, 0xaefa08b4981df8b0, 0x7aa7948f968ed4a3, + 0x7360ee23ccdb9bbc, 0xc3c46d28eda07e9a, 0x4df27e8932ce905e, 0xbebb4106419c4753, + 0x3e655f66cdbe390a, 0x8b8cf7ce28e69722, 0xf5dba7cd58f45bd1, 0xcc93695a4e3e6770, + 0x13d9bd5b97d04dbd, 0x4af9fc4b5859b15c, 0x8d76802c17a65522, 0x1fc5a23adfbe934d, + 0xa90840c37ba00cf0, 0x94efd81dfb222d52, 0x2b25b83c4251293f, 0xc7c0f30962aafe4a, + 0x577c2bd98de8193c, 0xeab7376deb5b30af, 0xf5f475c788780d03, 0xab255d58f5e540ec, + 0xb0b74b76b090ecf4, 0x0da626e359051e2a, 0x20ad1eb96e558789, 0x69c7e6ab03031a96, + 0x1185df19dd325fda, 0x75b8672156c80e8e, 0xa7d2bff5e1d61a7f, 0x594ac8c5dd0b8740, + 0xf2b1d4ee0474f6b3, 0xe5ccae5f99c9d3f5, 0xc2414fc5edb03443, 0xeb3cae2727007f97, + 0x09659277335914ed, 0xf2b436c00758eb47, 0x1ba939696f569cf5, 0x9ab7cc2c54f14cad, + 0xa26d3db8f552c0c2, 0x0edf2d2d65c93cd1, 0x189440474eaa6554, 0x20c09ec98b6b0361, + 0x58641ac31dd71959, 0x0ef2dfb2dfff77e6, 0x4ff3bd9980f2250e, 0xfd567957cc291983, + 0x95d70c47fda7a12b, 0x0cf016143c39f108, 0xf2b24d81e08a5891, 0x36856a3a9128658a, + 0xfbd34ea25dd9ccbe, 0x089f4019546ab76c, 0x1cdd49dd02a94e3b, 0x0035ee58b7a0c22e, + 0xa51efae6e7d7f46c, 0x09bfeb3e647708ef, 0xf69b13ad1c4db7ce, 0x2159b438ecab21d1, + 0x6633c665ee69894a, 0xbf5ef6a780924aac, 0x96ec0ed946877a18, 0x8e3761db8c422725, + 0x48c655f96542b2a5, 0x8892187473d2c244, 0x75a6ee7a77450d5b, 0x5526059c2e25af00, + 0x7494729b7c6ef1cd, 0x896fa4aabdc51516, 0x199bb9c27ad4fa24, 0xa60207c24311fdc6, + 0x198e52bdd066b6aa, 0x613e8de7ecabd481, 0xef288b5957f1b392, 0xf2e0cfaa0973f834, + 0x0232bde74c0b5c9a, 0xa0d103e117a48d37, 0xb7ed9cd6736bd5ab, 0x5c90f7b28746db46, + 0xc562150857485d1c, 0xe1f62f202bf8f8c3, 0x512a009983bd196e, 0x4f19f7d92fc95681, + 0x0ea9a9c5fd9bb708, 0x11af5e653f35510d, 0x37a1106d875cae6b, 0x7076163612b12ac5, + 0x1ee1404ee9b490b9, 0xa9046dc945106ec0, 0xdd713f83b7859c48, 0xffb9fefb281beccf, + 0x2b566f1497a16fc0, 0xc7223e8a18b4d7fc, 0xec4449a14858a2a0, 0xd29ecf117899038a, + 0x324b3ff394ec1485, 0x7f2906de505f280b, 0xeef288159d2264ec, 0x85dfe9b3f9dad94e, + 0xe621f1273379d408, 0xb8dce25d03787e7d, 0x9d374dee62bfd534, 0xacdaa8f73d1d1557, + 0xd2ba808b409dd3da, 0xedb90c73fad31c76, 0x2efe6e05d258ed58, 0xb655e6e2ce0934dc, + 0x248b7a999d7e8a2b, 0xb9981aa22064e91c, 0x9472355b5e0a5ca4, 0x5a29215cf279182d, + 0x24d8a12d48f6be15, 0xa07a2b5bd877983c, 0x839e06c59cec3d0f, 0x6282156f61a91fa2, + 0x9beb7a65ba82d3ee, 0x77630b01f0383216, 0xb326910c1d0a4022, 0xa4f4cd36ab1d3316, + 0xf4f5d62fda6f2d94, 0xced8e9bf22296312, 0xaa8df61ea31aaf62, 0x2e1d4567d585569a, + 0x557b28a2d6527810, 0x42e96860b7d12b9e, 0x0315898de306506d, 0xec2506492dbe3307, + 0xb01a66ac8046a09f, 0x9fa552e01b6da177, 0x0859d132693b1a39, 0x4ee835c331eecb61, + 0x2aa97cd7d615c3fb, 0xe93d661decf44479, 0x3d7dca951befb89d, 0xe962aa4515ffb160, + 0x0da9d7026c2da22a, 0x1cd7a55fd12ef9d8, 0x59b614e552dd4e58, 0x13746e7ae220b691, + 0x4fc3b4d7914c690d, 0x8ce7f18c3b521f59, 0x5efc0e445d17f956, 0x05f78722453854d3, + 0x023d80e01844f5f2, 0x440297cd76cfbff1, 0x5f6e31f1a2c8ef44, 0x8e55ef16f2ae20e0, + 0x7641a1f3c2c1739d, 0x5c1647fe253a769f, 0xd67d51e03fe22596, 0x8080116ea94bca94, + 0x7f0d9d2b28904537, 0x76a546bb8f44d549, 0x77cf867d6ff10ff5, 0x595c629e3dac6e80, + 0x72897264ab1795e5, 0x6596e3f4ea36f4e9, 0xb23d471b5c60b2d9, 0xf72c2f6f987a64b3, + 0x313757eeac051c5a, 0x01ebdfd01ccef1e0, 0xa3013edb4eed4b3f, 0xc0c53405c261f40c, + 0x9de0ad40ead43585, 0x2a01e3ee9840ad8b, 0x222316a54e72862c, 0x008ab59a7939ba83, + 0xafdac7626e1214a4, 0xae1f97acf03f4e5a, 0x643851f70105d89a, 0x20c97b38c9b7edde, + 0x84b610b97dbf9b7d, 0xdd2e6e907145f083, 0x90772e49e590687c, 0x21fa461c0d55bb29, + 0xa89ba9fec9c119e9, 0x2200577c6d2b0028, 0x6d2e0d621be52090, 0x719b87af6209ad28, + 0xbb68ebba5c94b6f7, 0xc50018abcb2c2e95, 0x6bff705f0cb55340, 0x021e0e6efede77a5, + 0x8458806ec8ad213a, 0x744d441220bcc135, 0x4dcb18b732218a97, 0x810964a35a1a7054, + 0xa60c20e070ac0c7e, 0xfe0b5d813a87bc03, 0xb317d5ada1293804, 0xd247f1bb7a6bd79e, + 0x35d4d7627d2845b9, 0x18194abc3f8e889f, 0x8a4fc7259a38ea72, 0xab9c0963d0f279c6, + 0x31fd8954d3abc2bd, 0x7bdea8d86f45ee46, 0x790b2dd070d476d3, 0x7e84733265449ae4, + 0xda279b5c4107bda8, 0x9ef646f55daec08a, 0x08d6238182ab3a3d, 0xd115ea53861dd161, + 0x46fd37826ed49f5b, 0x8bf13396330a2d58, 0xdb242489c6c7baf2, 0x5e425c41cb56bd7f, + 0xed3709b31b1b5137, 0x1eaa0a137cd3ff9c, 0xfa70c183b069f825, 0xa6ebb73039531411, + 0x0d635666ebadc09b, 0x32fb28967f49b3f9, 0x2f3a89a0bb0c7bef, 0x39a201e9252b9f35, + 0xe299b45fa22a6696, 0x5759442df4532210, 0xd2f334bef314a896, 0x14bfbf5ec56a0356, + 0xd03a5b56a21f684e, 0x2535e76d44aa3359, 0x9f10b274ba7e68fd, 0x2870f846956d3f03, + 0xb98b13b9e69dd7d3, 0x8f2b658e456d8df9, 0x8da93e9e6aa01979, 0xb4e036323883ee18, + 0x434d0198206a2f77, 0x7d5e8bc029d0ed33, 0xaba8d55c204720d3, 0xa43ba25296139e33, + 0x45b49d723ab649be, 0x78827d0f2d26aa73, 0x3c8d7c52e5db845a, 0xc69a10eb65d5088e, + 0x44d8e672769b7154, 0xa09d79fec39bc791, 0xb6e422577f97a75b, 0xae39daf45d318882, + 0x1f333fb03546763c, 0x8991ff3d1a1702cf, 0x6fd2aad213e7870f, 0xd52164abe50a8b58, + 0x41cbdda07406ee28, 0x5765efe56cfb2406, 0xfd173b286426200e, 0xca95b6946febe63f, + 0xd92cc847dd8e1c91, 0x290d3e39b97ba2a1, 0xf259fdc019e36b09, 0xee24204c090124b0, + 0xeddc179e981e7f43, 0xd04aece1caf65c0a, 0xa6c52d7d54f66f36, 0x14edb8b3c3ca38e1, + 0x84adc30c6d57261b, 0x3e078e1bbbd18dc3, 0x05c807755e414ff6, 0x69ee344b7614302c, + 0xd5ddaf802c8616a7, 0xf24562388184a930, 0xdc6774c6bded223d, 0x36c9dd9edb6d374c, + 0x8a69fc135d2c3736, 0xe06fbef0c8c1de40, 0x6ad36ba8e15969b7, 0xedbfea7ff81f734c, + 0x2c04d6c97a52ec0f, 0x77ce8f388c90ba2c, 0xc5b9037802ae6bc2, 0xf3be49dd89902490, + 0xa5562fd8acdf7fba, 0x6e786496659c3e3a, 0xaa73fbc10b15ca9b, 0xab3808f20bb96618, + 0xd5af76a2696a45b3, 0xa9a9ba59f5c8d4a1, 0xba4f37cad3000e47, 0xf452fac57a712dbc, + 0x6ec63c64ddd05c5a, 0x5ed1ccc4120930a9, 0xc525e9242b7b6b11, 0x05e46865cc9b178d, + 0x6cb6167e4cf54c5a, 0x767ffaff8420b992, 0x4db251da2d63b1fd, 0x5d85ce4e4747b9c5, + 0xb4c1a526b754e697, 0x20caaf3a153c90d9, 0xa8ce1f3bfadfb338, 0x6975a5cb8c7f2fc3, + 0x64ced6e78a4f4a07, 0x86f58968e9bd7c1b, 0xe1be94ea65e267c3, 0x9cce66441c3373db, + 0xf9d5fc615fbb4590, 0xfece86266e56c223, 0xba6e9cfe5f4b53b2, 0x542820d4a60d4cbd, + 0x353089047bfd66a6, 0x16acfef8a66c5fa0, 0x54234b7996e14f59, 0x178b4eb1cae70d15, + 0x343eb676d7d77221, 0xc2d7fa2fe58a8b70, 0x1e934adcc8a15216, 0x48e5ba7391de0ea4, + 0x71e5e77974415212, 0x8e916fb9f2bd7d54, 0xf9b462aa2de3037e, 0x237c437ddcf6acbd, + 0x79962fc4c49cf427, 0x5fd207fcd9a45592, 0xf5494f2536311c9b, 0xb4caf5b520a95cdf, + 0x7963708cf2d50dc3, 0x269c2c9cda4c3442, 0x6dc0a13cd28478e9, 0xb9a999db6710d907, + 0x965d39ddd6a6862f, 0x990cac6e42f9bcd7, 0xc2b604dc4aa811c7, 0x4dadd75970bcc69d, + 0xb0375275889d4aa2, 0x6222e7797d0a7848, 0x8f37688cc15be1a7, 0xd5441064f503da0f, + 0x12a97b9b4d2e0b9f, 0xcfeeaf5959bbe111, 0xc9fee47f3b82f3f2, 0x5a5232b90f558f65, + 0x2bcbe0a8534bfca9, 0x9e9ad7503df2212e, 0x5db3a8c53c2622cc, 0x1b5c9fdf31bd1a1c, + 0xa42d32d7a37d8406, 0x4c3f5c4a1cc699ba, 0x7a7ad82e4998ab6c, 0x58d345aba5163341, + 0x95960ccccbca8c07, 0x3b5de6a1a8631f9a, 0xef51f440afbcbbcf, 0xf2ed17b0e516fd90, + 0xef47edbd84a346a7, 0x3239fb7d8727d26a, 0xd2cbb17be874b979, 0x398fa455fce8f9a9, + 0x2debfb3897614c22, 0x523133997e7a3508, 0x0e56bbab921e2630, 0xe332c5f953da83a5, + 0x90899d3af1c96cba, 0x3b3c2187b1487928, 0xd06e9ff717df6d0b, 0xe38ba14fc6573ef8, + 0xe40e3e521b700b13, 0xfcf6b32e574402d3, 0xa9d721a580d91ba3, 0x2e8dc55132619fab, + 0x3690b8f5a263aa03, 0xfe6993e227543a5c, 0x3b33dd70f464e221, 0xb8fed1b3cbcb275f, + 0xe193a91a8ed73a7c, 0x01477f905eb3c8d2, 0xaaebd3a73936ede5, 0xd002195bb8eab2e9, + 0x458b56b3bf8499b2, 0xee8442fce3064224, 0x294014c6cf1921e2, 0xe5a74db989152da0, + 0x4449a0d75367ece6, 0x7adb5e646178e7ab, 0x29226d7478671086, 0x420b14b1e0facb4a, + 0xba6ec1fe108cfe02, 0x2c8a3356b997a16c, 0x350a3d0cdaf7f94a, 0xc9460fd5b75d22e1, + 0x515834ba4aaaaf6d, 0x0445886ec969cd2d, 0x7bcb1ad709e49082, 0x3dddec714da63eef, + 0xcd73e4b630eb18ad, 0x0692ffd2899e3912, 0xc034c7d5730f633a, 0xf985ad589d81ffbf, + 0xd5fc86c14fd27e82, 0xd18ef06f0105a277, 0x04c63c5931ed15fc, 0xa6804830cd9f2331, + 0x4e839a923de2bf15, 0x080fa3bac1dc50ed, 0x4b5e5abd3b0693f0, 0x5e0e00b70da4e695, + 0x00c5a8ea9312f9fa, 0xcda9881c1e8a6674, 0x397536e380ab329e, 0x1ed53f8762969718, + 0x9f442101f508916f, 0x77304d1a0f514347, 0x22886e73d8e3b0d2, 0xf8c1d26a63a4f264, + 0xfe37193ade6c9f52, 0x47f0c10fe1ee9e62, 0x94cc0bd6413f5940, 0x001e2c362dbecc5f, + 0xad91f11fa67f55d3, 0x05ebe3bbc72b1d1a, 0x0d035d69733baf72, 0x1df08ddd7e93829b, + 0x48bb387a1529db42, 0xa3fa4bfbdaeda1eb, 0x881158cfe779f44a, 0xdcb53eb5b07c0513, + 0x63d0aca20746e1aa, 0x083d8d22bc547380, 0xf0ab2ad4e5fd9181, 0x571adb13e629a820, + 0x489f5d32e996f0eb, 0x423071d932bf8fb9, 0xec98205eccad710d, 0xfa02d3bc59186241, + 0x8d45f25ce5f1ef62, 0x9ea3d1fc4963524a, 0xe07560a0fcd601cc, 0x9a99ba576a2a6135, + 0x27ce68c01b275294, 0xc291163d8e5cb923, 0x15517c943cf06d8a, 0xf758b0bfc7db6973, + 0x6fa389a0609cb2e3, 0x5d467e3177544945, 0xba0b036d40002949, 0xff464bd941433e41, + 0xb7ebb887f127f6b5, 0x9b6f9a4fc4e670e2, 0x86a7547d4cabe301, 0x1fa00e960145b926, + 0xa1e65d78c56faf2d, 0xddfd0e51260915d7, 0xb2e365f0095af899, 0x87657f8d29a78178, + 0xd7a64b017a17e8d4, 0x804feb49f35e33b4, 0x7af40e23399d65d1, 0x3b3afc51f4fcfb9c, + 0x8f64ee6f157bfa6f, 0x6af3b85b5db3fe81, 0x39fcb1fe7def4e6a, 0xdf2e084a2110ff8a, + 0x1e2ef6971f16e0e5, 0x0d24a5c000094a14, 0xb9e2d4847f937ea7, 0x93196a75e502a5d5, + 0xabdb3f094b23a038, 0x5347cb2d3d7d3dac, 0x2fb4d960a261523d, 0xda116d25859c76d0, + 0x7eb64241df444db4, 0x352b982fc4f91e56, 0x1b8574d08f582a81, 0xd85547c95de83669, + 0xfc2b976a8e971611, 0x1b6f101599067293, 0x70a87c99a2e40254, 0x5e3ca88b20e6491c, + 0xad9bd115056fc1ac, 0x0d4d6d12fc7f30ce, 0x56f7636abd73d903, 0xeeb85919ce21fc5a, + 0x40ad65eba458f594, 0x9e02e1513085c280, 0xad4907e90ef70e47, 0x6fe78e839d396975, + 0x6df2cf92869528d1, 0xa2a6ae23bf37526e, 0x0971102407dfef53, 0x1f22d89ffae23bd7, + 0x90e278c8b777d35a, 0x92a326a7ec229a9a, 0xcae88775c31eeb98, 0xbc17096954d3381a, + 0x7104c74b9b70c9c7, 0xebae7d1bdb2a294b, 0xd5ab0b4044b7fc3e, 0x37afc964464381be, + 0xaaf57874040bf849, 0x83526e97d73af243, 0xc2ecf434ba31a3e1, 0x392de1defd7a7a37, + 0xe805974cc87b393f, 0xebb86ab291bde06a, 0xe02e490d7869aff1, 0x146715cb379858f0, + 0x6405cd9d81221023, 0x59ace0405c1fd269, 0x67e024da544a4d4a, 0x3f493b53be229d45, + 0x32c9b0675929bdcc, 0x0f2f9b6e2b366815, 0x37e4fedf112c7ce6, 0x00099c88d92eb67f, + 0x2f6ab5fd34501946, 0xdf7b1d2a8b6ff8c6, 0xeb7af02dd2fdeb72, 0xe560d7c57385bd39, + 0x90213486a5f4e792, 0xa191d1c295c89a0e, 0xdfef91829df74a84, 0x883d2d9feff83efc, + 0x7140b6afebbeaaed, 0x9fb857898d9fc352, 0x82415f5b7b99437e, 0x807b6d1a13b0c261, + 0x01bce4a93c1a8f05, 0x7418c0f662ae29cf, 0x5b1186423e23ae67, 0xad057894d5aba800, + 0xca5f8a94f7181736, 0xa0b7892d0af40287, 0x7f7e8f9cc43bc05a, 0x234082c603f5ea36, + 0x58f1ab4049e1c04a, 0xfa5887b9ad27f7bc, 0xae8afb83072054dd, 0x0e8c560c1cc3464d, + 0x26d98f4113e90970, 0xe5328645ac5a1526, 0xed80b99145ea1378, 0x439baed52198b536, + 0x8830e93aac0319f7, 0x47aaf5a2763b74c1, 0x77ab909ce9b868da, 0x2d0a42cc9fa1b27b, + 0xf1d4c25697ab06fe, 0x9f6f2e0a3add1ee0, 0x2e1ba1ae77ece607, 0xf14fc2742cedfddb, + 0x4b6723bb9502cf02, 0x37173334ee97501c, 0xf059b30105754744, 0x0aee0a9eaceb15a4, + 0x1857f0588bc36324, 0x0d242677361d5d4c, 0x8584ec5264d19375, 0x4439b6a3f09dce90, + 0x5c5139426334f49e, 0x87370c15b7592af2, 0xfa4ed67401389d2a, 0x10df13e997a37a10, + 0x8592eccecf7a9de4, 0x6897f8a94cf77113, 0xe2db77c6ae0731bc, 0xbe78750195fcaadf, + 0x843f78a6af3c8859, 0x3369c71114eb7762, 0x3f5683f3270e44f4, 0xdbd6a1a8a2a76619, + 0xb52ccb4b8c2fb4e8, 0xfe2f60c18b9bb11a, 0x5701a268aabb951c, 0x16df69f23d900017, + 0x181aec189bb0ef6f, 0x46ade44faea07f86, 0xe30d7a4026b75b3b, 0xcba3fe87c310bbb6, + 0x5e76276fb66609ca, 0x6efd398f13bcd754, 0xc1b9ad5d6905f589, 0xba160ae57ee181fb, + 0xa14140106b763bf8, 0x194ea43677f34e30, 0xc667c5114eec40ce, 0x49789068a92d1446, + 0x84d0c53a0f1363df, 0x3feb5ff45623f3dd, 0x56e81185c273c3f4, 0x69b6e9a3ed5c4d6d, + 0x16e655338066c3ea, 0xd96c3912f94fd4e3, 0x936509c46dc217cd, 0xb6828dc765f15219, + 0x0f18bd16c04a259a, 0xef2f55fb080016f5, 0x7bb463d37a955682, 0xbcf256277cad00aa, + 0x716b49fe3c7447ad, 0x419c16ecb35136c3, 0x5415fbdb428e1a07, 0x47d134c6100b8d27, + 0x5be942918fc274cd, 0xc56a9dd95cfb1f85, 0x3adfe008ea36b851, 0x46bfde4354870c20, + 0x155b8df6c4b8a2a1, 0x46bbca4cbe7ab4a2, 0x392ae1f3b74805b4, 0xa786e69bba907b03, + 0x3e6a07a8dd58d574, 0x0b52af34c7a11851, 0x8aa5e6a774aab7f1, 0xe7c73a7101b60a4e, + 0x54c3e9bf07e3eaca, 0x12acee59db65c0d2, 0x40e2b6c5891a34de, 0x62fb0b67e499dec7, + 0x37827e3b0da6e0a9, 0x9cf8178c0c3b0de3, 0x37a20ef39d785a86, 0x1ec9f673fac6d41e, + 0x9c8d57b4ad98a48c, 0x11be0cc0cf83abaa, 0xf23b110987a85d84, 0xb9a8f66123d74b47, + 0xd5701ea405389567, 0xcc6876764a52fda3, 0xd246b8d958ea0547, 0x261f87580478a9f8, + 0x81a6c68775ff4e83, 0xfb740135b59ee494, 0x5788f8d4aff26410, 0xa78e99330c0f39a5, + 0x1b8a8eacd0524a68, 0xe61a6d89e3d0bf28, 0x052fd9439ca22709, 0xce8968884ef74aa3, + 0x867f054c610327f2, 0x4f194ef2f886d6a1, 0x1c138a9f339e7c55, 0xda7111e73c988965, + 0xda9eabaacad26fc9, 0x85b12cd7082e95d6, 0x870b154f5dbfa19d, 0x5e0584aa87fcc667, + 0x4630a466e2c2f646, 0x0a16bcc533f31bf7, 0xcab259648142ab32, 0x43e563f3f19dcdb2, + 0xa7491bed48e1a102, 0xd821ce02c0b736cb, 0xae1a097b0577e13a, 0xb7c598754ffe976b, + 0xf87feb4f3e6a9e17, 0x7a121514bb5e58ae, 0x6fdbe1a4e8a5ea2b, 0xa635c475909a83b7, + 0x58b84497a777f88e, 0x882bbfac3a103d9c, 0x11d3a1037a19ae74, 0xa8f50f5db2f9793b, + 0x6a9374b8499dbde8, 0x2f56917d5a3efbc5, 0x15aaa4936d6ccef4, 0xf267cda6eec7de1f, + 0x2e26423634e430ee, 0x4073363ffe09f1b0, 0x63a51c2a59c36938, 0xaf9a4135a748e4b6, + 0x7668f07677a55764, 0x919765086a157e10, 0x0fa426c1fdf9ed17, 0x8adc92f83385f03c, + 0x2e8757c67bd90b2e, 0xe9dfbcea514936b6, 0x044257b30abd3484, 0xcafb7610ce69f914, + 0x8f0b505705fc226a, 0x3db43bae46f2259a, 0xe135386227c8aeb6, 0xf94407a87071abc6, + 0x4f44f59283b2c631, 0x3d1c43aee4a54dcf, 0xd95a4ce3ddb58ee3, 0xebb7b58598a496dc, + 0x134f392a6647c3a2, 0xb9b31a231abeb2ec, 0xd00dc23b8389d61e, 0x62fa45c1d22af99a, + 0xffca039284fa66e0, 0x62aaf428eb30a910, 0xe2bfcd617a80267c, 0x8bbe5a78c96bd308, + 0x57ca8f41c25ca19e, 0x75f77472e5bae7f9, 0x5b86fecf23357438, 0xe3fdd099fc5a02e8, + 0x1359bc21501aecca, 0xfdb398dbcdf8e7d4, 0xe6546fc40a1ff1c5, 0xb26bad98c677e07a, + 0x83d308cdbb85b87c, 0xfa4f9145bdcc3d0b, 0xe468dfbe2d4ba8ad, 0xe653641ae1c545f3, + 0xe88e1bb2b60cb491, 0x3491384a2df23957, 0xbf8832f794d9316d, 0x694ff13ea2c65a1b, + 0xa3a5655986764018, 0x1cef0cab66214f40, 0x98152f736bf9eacd, 0x1107c6dd2bc5451f, + 0x14697bac801c14e1, 0x65d7d9e446a9c064, 0x51000a346a500c68, 0x1a585cc0934137b6, + 0x2cf2441f8a1505c8, 0x1b12a69ca1487b98, 0x49d770d40bb1f6cb, 0xe2638905db0d2c6e, + 0xeff329b752ec53af, 0x563cec571428aa22, 0xa578a53e8ff5a2f6, 0xf8463f7479a3f4c3, + 0x376bddfc21915b24, 0x978ebbc4fa34f93d, 0x0dbdb92e91939e97, 0xe80c9a80a50540d1, + 0x4b9603c3cd742132, 0x8f521552b319dcdc, 0x531a619dfae39f54, 0xf445095415959a45, + 0x5ce75d4315dfdb9d, 0x52b4426c9876f0e4, 0xdfc0b9790860bf94, 0x90f6862ffa5f4476, + 0xa3a5990c442d3b0a, 0x68348653cbb8815c, 0x7e5a6f1db30c07cd, 0x0a139f2d83e7b73f, + 0x170d349b1f32455d, 0x13b400ad88593a3b, 0x547ebd2bebda62a5, 0xa93088d09fdad479, + 0x467099acdc3f14ae, 0xf756f149a056c976, 0x07b6cb3f6840923a, 0xd34b187ba04003db, + 0xcf94df4d0730b5f1, 0x71020802bf84a0d5, 0x48a2a06e0cf33230, 0x0c28769b785c4831, + 0x124e7a51a12ada47, 0xde5f3e4bffb5af8c, 0xb6e69b87ffde7173, 0x6294cff861f6e697, + 0xebb4c003b89c6963, 0x65603abd917c1f5a, 0x52c96dddf46d9d44, 0x7a64a2d1496746ca, + 0xc9dafe3bf3b56b58, 0x9f62fdd2006cc2df, 0x893d571f975b3017, 0xfe2a41bfc0cc119f, + 0x3ab341941b5c7f3d, 0xeff1e81829d718e8, 0x6a1b9394171bc4e4, 0xcaee7d319ab6101e, + 0x50431a13d323b103, 0xc249dba239e82650, 0xd9d58a2964fc0428, 0x7e2bd2c45eb1db7e, + 0x3a4feb66a7849267, 0xbd367f590532fe30, 0x14fa726b7bc21780, 0xf6afe897a3e48b2e, + 0x7cee020297670959, 0x15be94fed44d6cc5, 0xc93ba7bd1e4d9989, 0x190c40915487fe04, + 0xf87349a71968613f, 0xf3be0d04519c7089, 0x7112722eb374f90a, 0x9354b39a6a9eff54, + 0xe4e715db38af8d87, 0x91fc81aa7b1e7e6c, 0xd6be530dfc32c144, 0x95b38bc42a98cc55, + 0x6864340363796f53, 0x1e4ab2e5e2586154, 0x7238c14778427b8d, 0x127baf8a81802bc5, + 0x71dc19261aa94a9b, 0x7eddc56338fdaa65, 0xff14c4c90f1119dd, 0x109c87ae5843fe67, + 0xb1b4ae93b4661a23, 0xf1fb7819a0756819, 0xeb93220394529a64, 0x594295b0063f12ff, + 0x171cec42566f3fc0, 0x73f8c43392bc82e6, 0x403d3926ed42a199, 0x971af5cd1475410f, + 0x1f0b9af15c6c64b5, 0x015982d1e455c8c2, 0xe205c3b93b4c1e04, 0x61aca977984ed798, + 0xcc18424aa9f8a486, 0x8c727eaecd3d18b2, 0xaa58d7d42eefa20d, 0xeca1f676454746e0, + 0x138a9393e57eb68e, 0xd45df69342378b64, 0x12db66de05caa0f1, 0xb808bc9e5685694e, + 0x11b7fd2f923bc101, 0x8cdc1897c7653012, 0x867dc9e3701c1094, 0x244483d4595a12c7, + 0x0a8fc852bd2323ee, 0x600e716e58381826, 0xfdd7f6b3902cd24b, 0xbf9ca3ec9bb96c04, + 0xfed1603ffec2c511, 0x63cb4ff3e63cf0e0, 0xebd3738648695187, 0x2043f75469a6905c, + 0x0b6e81dd2d8217d5, 0x2d48da5dec78b14c, 0x9ce6fa6545d4d807, 0x39158c2a69a9ff27, + 0xab5f7d00d37caaea, 0xb195ca1a18b476a0, 0x215bddb0b84eee7c, 0x75d3ef8363a0d388, + 0x2088ab196cd55f04, 0x37fde1657d587f18, 0xe78737679807fb8c, 0xa665b99486e6fdef, + 0x871b8dda0c2b7146, 0x4ea57fa53a9de660, 0x8b7becb250b711f4, 0xc2a23f1e79eb1212, + 0xea81404d16c921fa, 0x49636a0d4789c880, 0xb238eb1a3983e8af, 0x62a640c5fe793255, + 0xb5cf281434ef3d59, 0xae2101903ac510fd, 0xb7c21600defeaca7, 0xf0c9aac47cd67d9d, + 0x3e11099413f2bbfc, 0xabb20112d8701c7b, 0xadefee5b8d593c77, 0x1945df112e96b4e1, + 0xbb0c6aca887223ab, 0x4f7fc757e43cf788, 0x8f6cac56b106c181, 0x9ea047aac5c53aae, + 0x7863ba25bc0002f1, 0x0c5e6d17ace75606, 0xcdeebaf9104b4067, 0xd7dac4ffdf8c2905, + 0xd5c41d2f3ca9613a, 0x6bf9d113c08a433f, 0xd8c4c80184056c1d, 0x6c78ed3270b9b6d8, + 0xf26042e3b8fd823a, 0xc83a5fb453520ef6, 0x3cafcffecc15e491, 0xb524bb96c2947401, + 0x20983e5ee74f6a39, 0xad82b0eefa94e02b, 0xf1a29e2f6b92a996, 0xf6777a3be2517ab5, + 0xf8e4991f03e2b986, 0x3dc5714139c599ec, 0xbfa8eb24918e24e7, 0x903e1859346a4c96, + 0xebb8ee69bf1bff9f, 0xacb63ff98f273443, 0xe655024ced97b0d8, 0xaf7c8e9c3f80c20d, + 0x17d16d12a8cc94ae, 0x2d7241e8a63f9dbb, 0x3bad111dbcef470b, 0xddb43bac81e231a9, + 0xca63be00df85463a, 0x13c443f3f2ebe302, 0x83b1ae7f852e447e, 0x2565241e0229bd4a, + 0x2a1998b95ef75215, 0xf0b72abf5afcd5f8, 0xed0d5ff3c83ec4d0, 0x88887505fae32502, + 0x281a8aae1a865cc5, 0x4d63d8bab4e5f8a5, 0x03d7a249297593f8, 0xfa0a54931d901885, + 0x03f3fb7e306903ea, 0x194e2ce31af7f7f6, 0x5bbaafad9b17c94e, 0x712dbf9dab181251, + 0xab65ee1fd0784fd1, 0x9a39336c8b6e210d, 0xb2f20378ffeffcb5, 0xe7f0e60fb2caa498, + 0x1e68de0090dd83d6, 0x6cc1a8e86c4853d9, 0x53fb424a8e77b2c1, 0xda4d3149515adb1d, + 0x35ebeacb5b531b56, 0x2dde9ca9ab6f87e9, 0x184dd222857feb94, 0x2c55f28df31c3a3b, + 0xb5d6e441c28db030, 0xc5c70433507739e4, 0xa3d84a5df31e3c34, 0xba6574fda74db917, + 0x86ee3300ada0b382, 0xd52440a78d087e66, 0xc940b4ab46d1adaf, 0x06959f9f48a7cb46, + 0x9c61ce0c4a169ba5, 0x58bf42533151c1d4, 0xf30c5aa9c4eb272f, 0x6abd22760402947e, + 0x7c807415c0175a5e, 0x88272de46d8d7728, 0xc250b67f242c77da, 0xca4d065e326c1ae4, + 0xf0995fc38ea7bcc5, 0xe7d7390d1dd21c35, 0x4cbc1eec0a144561, 0x77bb6a58776aa0b8, + 0x50d51620d1aafed0, 0xa8f75699dac2b6c7, 0x1ce624835a5de460, 0x41101b81b8e97163, + 0x5b6584f07c8b2866, 0x776b86e3e698dc02, 0x4a17a3a874cb3160, 0xe6048956f3a7c6cd, + 0xbd3fc7b8cd7307e0, 0x4afb7d1dafcaf706, 0xc10cce67bb6bbdf5, 0x3f89edb5ed7fb283, + 0x05f2cc676569bfb8, 0x1076e29528e11d90, 0xc65db64f34a750b6, 0xf34ffeb63c1e0d7f, + 0x2e5f461e52bd7dc4, 0xbbb0799e8293da5a, 0x42a0dce540509869, 0x191d477e9e280ee4, + 0xdc21b16644658471, 0xc52b43795ed61add, 0xaaaaca7f6c6c1eee, 0x480d72d3111dc6ff, + 0x55bbbc36698d2aa4, 0x1f04df2e9708873f, 0x9426cc3670a1b15e, 0x524a21a76af5056a, + 0x150ae6fd07f93e40, 0x69b28ba3d7d14982, 0xb49172191743de27, 0x756bbadbe2c33e55, + 0xf30e5591ad44518a, 0x04d1bc3ffc1d7e46, 0xd8ab2e8efdf0bdc0, 0xbff538d1e0ef7851, + 0x83898ea51c964108, 0xdf1e2668fac26182, 0xa76c253c399f7402, 0x5389735e5cbd4bfd, + 0x30a8a5274e40bd27, 0x8247144331a44303, 0x22bb3c9341735c64, 0x3dc19739e6a1819d, + 0xed4cd0c59d08a812, 0x646d0f00fb547502, 0x2d041c0229c141ba, 0x4afc31929b1ea2ad, + 0x90195a5becda81b2, 0x2cc50b1cac7102f3, 0xa141965dcbf3960a, 0x30347121e789c1a9, + 0x991eb3964f651fd1, 0x026a009275b8d959, 0xfe715d97852014c6, 0x3c353c8272a7e04f, + 0xe80542cd0ce8a08e, 0xa4e049a8bbe081e7, 0xecc3dc4dbede7a4a, 0xfdb3b51cae71c5a6, + 0x0dfbae3b2393c2a5, 0xb257270aad21f33a, 0xfc8c55c002dffd63, 0xa5634df41735fc85, + 0x06ee058d20495933, 0xd557443dd34bf962, 0xddb172bfeb877e51, 0x8a2d836c9252857f, + 0xd98f4f19f6ff4d29, 0xb2ffd315cd977958, 0x4392581d1ddcc256, 0x981953a1152168a0, + 0x11676218b22c47bb, 0x437e936355c99c69, 0xce3e67a67f975d0f, 0xd94ac478182baf6d, + 0x1e72a8712c0e1094, 0x526ffc973d59728a, 0xe8de4ff3d76782cd, 0xe051fe503e9d1304, + 0x00c1e4b0de42feed, 0xa21819370e4abeda, 0x975bc579bf5c5b37, 0x232e5d34a24842df, + 0xfbaca81adaee82de, 0x0f447fd3dcc25a8e, 0x26a04d5eec2dcf88, 0x7ce27c2abc257339, + 0xfcee65f724d136b2, 0xb6e7b6dcc42c3b62, 0xd11e605f09ababfa, 0x7d724ac35f2767d8, + 0x2bcd6d76ac3feb3e, 0x4d97a36d94eadfda, 0x61b6d3637f5cce92, 0xd90cd9ebf0cd9feb, + 0x5944c4d774209e69, 0x2b8c199f2f9cd449, 0xcfdbd3bb25e499d2, 0x5c22ee4e195f0248, + 0xee253c7bdb5e65eb, 0xd8d43ae6715b2ea2, 0xb2868617f42ca4ff, 0x6690857cc463533f, + 0x005b0303a02f27ee, 0x410969717e432ef5, 0xa650b351025b2680, 0xceb8881349eb377d, + 0x9a3d969ca087b1b1, 0x8da924954df86b2e, 0x60074a7ac5554acb, 0xe210859fef7c36a0, + 0x1b403176d0454963, 0xb238b8d4c4553aaf, 0x172e037bfec7d771, 0x129d0c3f75da68c7, + 0x0881ccce752db1dd, 0xd3b243280608f1ef, 0x1913635cd239a5ed, 0x6c994870809b7bbc, + 0x344680ef8fd418bf, 0x46f3feb544e7b9b8, 0x86d9c4f8dae38753, 0x5a9fb822e5ef113e, + 0x59d33eaa0e348c8d, 0x66ba5244432972e4, 0xa99ec36e26df8e47, 0x674ff09bf5ce2d5b, + 0x3a0c57d06eee0d67, 0x71c97b05f6c5866d, 0x80dd5fa0bf35be4c, 0x13524362ae5f1db4, + 0x17dce6e2ae6820ff, 0xc881e83f32221729, 0x7f5553ad2965ac59, 0x8647c7f22907e715, + 0x62ef4d3badeb588c, 0x29ecb0c1b24fc1a2, 0xbfe650e4982806f2, 0x2cd405077c358cff, + 0x65c2bbe0c43cd919, 0x0e8f35ec30b0bc01, 0x08244de0e4e3a95c, 0x844f73b1f30bacfb, + 0xdb85da7657a84717, 0x2f22e93ba6318885, 0xe312b7fc62d993db, 0x7fc93c4904c74f53, + 0x2f68fc80f5f115a5, 0x1e8919565eb5687c, 0x4d5204cd5a96b1db, 0x28d3056029c34e40, + 0x842e8b14f5725d38, 0xed6e80af169ff711, 0xe36e479519579a2b, 0xf2d9ed21b2570d6e, + 0x65d2b078ed0712eb, 0x3a42fc74b41cacc1, 0x7b1f0e56c4b12cdd, 0x4cfac05dd835bea4, + 0x5fe32b621ccb8d95, 0x6059259384eac85c, 0x2bc0b612cc22e559, 0x1d31040fcd81859d, + 0xaea4e13318cd9fb0, 0x3b53bfb970e86aa3, 0xb2dd16f3bcf7596c, 0xe7537b4c8f0c9501, + 0x8a0f824d41213f42, 0xd922ed29c715edbf, 0x79244f20ee30de36, 0xcf523cfba46abf89, + 0x896368c1d0be7766, 0x311fd2a367d5082e, 0x8176e7225aea51a9, 0x1757d632d7d98eb7, + 0x38c7203051aefe7a, 0x63428c43985e119e, 0xefc79a08daf39ad8, 0x545c1d858784bdb1, + 0xf70b98ef0e6eb20b, 0xd5ac8a2229277e40, 0x7764cdd6e4c4b4ba, 0xc856ac44d0224b44, + 0xf8c2bafe6cafc3ea, 0x2284959771587488, 0x6d5dadd0470fb8b5, 0x9701a89343c7411d, + 0xedebc1114abe1724, 0x091852c6f3fc18d7, 0x5eb0a16d80c5f46c, 0xab9316be0fbcfc4e, + 0x805f75e838096030, 0xa1788001b4618dd2, 0x6a506e1266276f20, 0x7384e4321763b344, + 0xfed32314e35ed692, 0x1c90e8a85342fb36, 0xc1d600ab95893d69, 0x62e6ecc3dd269d32, + 0x291d4115260d0e27, 0xa4596ff520f8da42, 0xd063d8ae070fd080, 0x44520a9da928c6ee, + 0xf8530d4ac6992d42, 0xa2bdc07d30cebdc5, 0xc34a56a262d383c6, 0xaade45e868d8e145, + 0x9e77a8400a2a2ce9, 0xc5dd100e3a463dd0, 0x39d97c7485c9c11b, 0x90e8791c86b9e9e0, + 0xa42815ecba6f6cb0, 0x08a6bf14e6377cc0, 0x243e8ba548085447, 0x76e86de95445e177, + 0xc0036c9fd957e7b2, 0x637526fa8d6ac90b, 0xedf07599e940d1d3, 0x41ae5ef4fcad2bb6, + 0xa22dd183c1156b76, 0xea799fbe273e62a3, 0xf5c44c7dd4742e12, 0x71f88c2d35182e4b, + 0xcba84e538201f7da, 0x91a5dcc5aa8df96c, 0xf559c92da6f130b8, 0x816259eb813ef7ec, + 0x921f650abd50e426, 0x9044bc34edcc5427, 0x3ed63258145ded72, 0xed4b39eedb53e444, + 0x42ec8eeecd95e973, 0xd8914c22e58535dd, 0x18c89b389ca25e60, 0x835c44d99f443f4c, + 0x7aba8cd0ddc0bd5a, 0x9aa1ef2f0e6d2226, 0x49aeea7c96e39f00, 0x0c946447e87ba4b9, + 0x6729ca0cb0a7e0d8, 0x20a4833a45b2fdc6, 0xcc5d7491d083ba51, 0x3ad921c0da791eeb, + 0x401df7dbd7d6a812, 0xdbfe46a6aca199e6, 0x2c6fadc847580f40, 0x1542a5c83753e9b5, + 0x1caa4a2cadf60bea, 0x8781a33a0d88f683, 0xc63a4e33769877e0, 0x9c49622dc5f2ca9d, + 0xdcface9923dd98c9, 0x108587d7ace67548, 0x73c785aa0079ed28, 0xd2182bf8ebe7cd17, + 0x68202163b7f22d01, 0xaafdb8cea21bc3f1, 0xbe6fb61ba5009f2b, 0xf92a4a43c49c515a, + 0xe3565c359e17b346, 0x98c8711a15d4cf01, 0xc3502aa8d2ae83f7, 0x84b1c7694d8ef559, + 0xd635f8af5398e3a5, 0x3d7585a1fcdfbbb5, 0x1a0ccfb505725777, 0x3e6b0354a9d27efe, + 0x872455abf0543021, 0x172969f5082f8a37, 0xf3f4d526164f46d5, 0x51357ae9b6792730, + 0x6d8015674bc66fab, 0x85335775a6e43bb8, 0x7bb30c057cf0e078, 0x1559affa39309efe, + 0x9a3590f9a9b550f8, 0x68079f0ccbe8ad58, 0xedf4e5b5adf66113, 0x7912aba0d953f662, + 0xc5580366906f02c1, 0xe404d793a1e8fa8e, 0x35a026bb95a255ce, 0x847c7a2231883ab9, + 0x566495915cc2f375, 0x23fb0e28199220f1, 0xa2e5b935732ecf02, 0xb0c52902952b53ed, + 0xf79872ef461fdfaf, 0x5494638881d2fc86, 0x715d786d7da41de7, 0x95516bbecbfa6167, + 0x10ff08a5e22020d9, 0x87e29f27ac6abfed, 0x4b90993591d821fb, 0xf189c6737184285f, + 0x108993c4fcc1c5eb, 0xa369dfbe7b6e6871, 0x35d8b0f514abb1d7, 0x73ed1ad3274276d3, + 0x40ad8585fedcbfbb, 0x5057cb690e51c590, 0xb0d2d2eb9b130af8, 0x32b160707ed2b251, + 0x16568fbb4e7232fb, 0x8dc55110ab248167, 0xbd050e4500865356, 0xa397e5ac5ba2a576, + 0xd025614cd01cc80d, 0x5f06d34865819cb5, 0x45c43c3e117c235f, 0x9eed55756efbcc43, + 0xa408304fb8305397, 0x00bd449bb5e55004, 0xbbcae7ca38aa6225, 0x0d4ef39450c97860, + 0x0cf7cedf683bb133, 0xfff8476a0384a059, 0xe98fb76051b87594, 0x0cd95d0b48b2ddef, + 0x9a53aa2693419d79, 0xcf63d8a4ae17f623, 0x56017663a4d4584b, 0xc070a807db611a4c, + 0x0acfffea81936050, 0xa4dd81e3c2500ab6, 0x133a72803fc0fd86, 0x0c1d5640fcc6d4eb, + 0x9a905acdecd70898, 0x0a832ab0dc91189a, 0xad295fcf00d94c2c, 0x1a7d49153a349d45, + 0x7bf859d4478d2bc4, 0xa23d3e001e178dcc, 0x5a19288292119724, 0x7324693c833afcd9, + 0x568880c28891762b, 0x791109be7b52d10e, 0xa639fb506e789c6f, 0x68a7fcf408bc1b29, + 0x3d4834b0e7b89b03, 0x80378c31b3cb28f1, 0x0b686e2354f0f916, 0x50c7be955debe0e7, + 0x73ae40212a7ff22f, 0xa63e52b3efcf14d7, 0xd95fa3f1f0167326, 0x551304b3e157a9bb, + 0xc07121222b861230, 0xbd0513345ac59964, 0x8d12404259d7ef1a, 0x963711fc56b526a5, + 0xb3b1e9c18fe23068, 0x8063d9b4990cc33c, 0x679270ac2da3d484, 0x248441b37fd4c6c7, + 0xdbafabe2989e9b16, 0xf511c53516d8f4c6, 0x643f704d00cdba12, 0x8ff4091defe80837, + 0x1d8a18c8e427a49b, 0x3868df864ea6dfe9, 0x580e1923973b6b74, 0xba56b3d778c7a078, + 0x420b4960650dae71, 0x433623cc7f8913d8, 0xbb704a1372680a88, 0x105fc46e6c8b393e, + 0x6418ce16bcad0851, 0x6351985bffe1f8ba, 0x0409ad4d28d6ccf1, 0xd9147ae04d7a214c, + 0xb2c1162a16ffd179, 0xddcd005b7a95897d, 0xfae577761799ce0b, 0x4fc64d6ceceb7197, + 0xbb8d887b360dd9b3, 0x8add2612d289471a, 0x025ce64f77577eef, 0x7f33a4942616d6ba, + 0x74bafa991fc1ffbd, 0xccf760eda80ef0f6, 0xd6c8749143d46d4b, 0x6f08c4d37213cc69, + 0xc290b8ef99f67952, 0xb38641440c0279e5, 0x60e2b64e7674eeee, 0x8de2f124f6efdf5f, + 0x9e563a789655d2b1, 0xdb35e26d1dccc985, 0xc2309cf23ff53f61, 0x9495c85069a0bab4, + 0x37d0e273fac205f1, 0x675f44fcf7866825, 0x5203cc412fb3bbb2, 0xa142a8c605554b80, + 0x26fb5f9ade3f170a, 0x2cd6cb6debc1a7ac, 0xe304c2a6a6add3aa, 0xf47e80b7f8e858d3, + 0x80fe2acfa8fd4476, 0xdc60de24b5a6fc19, 0xd298272486d3f8ce, 0x0e047237a77f922e, + 0xc4745b35122cc657, 0x06487cb1997bc45d, 0x64e0e41aa72cf6e9, 0x2d02282f99d75823, + 0xf81ac1e1d44032ca, 0xf15a03bea3dbed4e, 0xe7c4c1f3346ebf80, 0xf086ac1c39268bec, + 0xba0940095584636f, 0x12b274c13fe5bd4e, 0x8bdaa80dfa6d4998, 0x534e403a0cd2be2b, + 0x5a3433edfd3918b5, 0x770caf904ba076ff, 0x8557b50ff773270e, 0x0184af3ef759e12c, + 0x9a19a234321c833d, 0x7042a8398d4aba7d, 0x5ddc7ea76b0596d0, 0x0801ee3dbaec1ecb, + 0xc7b58665a699438b, 0xd08c488c2e397d7a, 0x547d5d536ec45a9a, 0x89c3c359310e93ae, + 0x82d394074769230e, 0x331adf7180bff49f, 0x3150d7a6b5d9d7fd, 0x42d603bae42b075b, + 0xea6d476bc8779b31, 0x66596427885a80fd, 0xeff1a6307eeb6cba, 0xec651c71b80590b1, + 0x423709523bf0ea29, 0x80f0da57ff550b66, 0x0829b599cbd38cde, 0x22fcc23ca86c6d36, + 0x14b5678161dc44d1, 0x05a745a52be98f4d, 0x8b93ec98870f8b90, 0xd775534901bf7758, + 0xdba89dbbf023f4c6, 0x3d53832454e2ac1f, 0x9f04e6f8558f3d53, 0x97860cb0d21f03c6, + 0x4e86931d816a4dd4, 0x6c4042bad608c7c4, 0x4ed848a0213e5856, 0x0b542408eed49bc5, + 0x336ed821111c8856, 0x87f61959f2811ec3, 0xdc00afb8c213b638, 0x71a0bcc12922f5ad, + 0x3399c168d6098256, 0x001f7bdd3310eb8b, 0xeb7a52be3d826686, 0x4b6fd5d4d8fa5b75, + 0x84e06a9ce249fb6b, 0xe98f2f20e139be1a, 0x3bc7736c7928e64a, 0xf5be36ff11a04d6a, + 0x0bbaaa244658445d, 0x4131dd1909f86a87, 0x30be054a628ba5ac, 0x769b20fdf83c137a, + 0xde68f5981ee65f3c, 0xf533d0a2dfb31792, 0x2c111775770b918e, 0x8b30515fc7f8dd2b, + 0x7c589985e06b31fe, 0xa83de698c86d7e89, 0x89373f7d9a6e7297, 0xa2d12871e280ae3f, + 0xd4f3b17d43d8256c, 0x9cc26b2ad483ba76, 0xd61867b2dadb4dee, 0x8f39db56af4a87d4, + 0x92f8bc892b51faba, 0x41dfa0537b565d27, 0xa178d6bdd3c12f37, 0xec5ba2b64a160d67, + 0x766d2432e1fd1294, 0xcbccfbe1cee8ec26, 0xbecca3d1443b58a4, 0x88c4861eb8f2278a, + 0x8bb5bae190557746, 0x3b63c532468dd64d, 0x1aa2c322d145d43b, 0x96b2a74655ee197f, + 0xefd3f233bc177187, 0x16fb653c3c6eabfb, 0xf4cc9f36d64f4ba2, 0xfa6ba7a73ead99d7, + 0xd79e4c6ed4e7c060, 0x778fdc5920d7584a, 0xfd630d6782d4075c, 0xaa2a9f34b8b855e9, + 0x772011a98a6fc073, 0x25fc7a0eb613e652, 0xe63467ab90cee061, 0x3b6538372b9fe7b1, + 0xbb8132158fd258a6, 0xfe86da623f19c422, 0x5811290e8b89e54e, 0x75a8bf15a08cb3e5 +}; diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index dab9001fb3..112a4f0a2f 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -258,7 +258,7 @@ int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, if (ctx == NULL) { ctx = new_ctx = BN_CTX_new_ex(group->libctx); if (ctx == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto err; } } @@ -1423,8 +1423,8 @@ int ossl_ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, /*- * Apply randomization of EC point projective coordinates: * - * (X, Y ,Z ) = (lambda^2*X, lambda^3*Y, lambda*Z) - * lambda = [1,group->field) + * (X, Y, Z) = (lambda^2*X, lambda^3*Y, lambda*Z) + * lambda = [1, group->field) * */ int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, @@ -1438,7 +1438,7 @@ int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, lambda = BN_CTX_get(ctx); temp = BN_CTX_get(ctx); if (temp == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto end; } diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index 2ab7611be9..943a6bb370 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -110,22 +110,16 @@ ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } - - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - OPENSSL_free(ret); - return NULL; - } ret->libctx = key->libctx; ret->haspubkey = key->haspubkey; ret->keylen = key->keylen; ret->type = key->type; - ret->references = 1; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) + goto err; if (key->propq != NULL) { ret->propq = OPENSSL_strdup(key->propq); @@ -138,16 +132,18 @@ ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection) if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && key->privkey != NULL) { - if (ossl_ecx_key_allocate_privkey(ret) == NULL) + if (ossl_ecx_key_allocate_privkey(ret) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; + } memcpy(ret->privkey, key->privkey, ret->keylen); } return ret; err: + CRYPTO_FREE_REF(&ret->references); ossl_ecx_key_free(ret); - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } @@ -186,7 +182,7 @@ ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } pubkey = key->pubkey; @@ -196,7 +192,7 @@ ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, } else { privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (op == KEY_OP_KEYGEN) { diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c index dcec26c2e9..ba725eb573 100644 --- a/crypto/ec/ecx_key.c +++ b/crypto/ec/ecx_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,7 +9,13 @@ #include #include +#include #include "crypto/ecx.h" +#include "internal/common.h" /* for ossl_assert() */ + +#ifdef S390X_EC_ASM +# include "s390x_arch.h" +#endif ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, const char *propq) @@ -36,20 +42,21 @@ ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey break; } ret->type = type; - ret->references = 1; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) + goto err; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); if (ret->propq == NULL) goto err; } - - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) - goto err; return ret; err: - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (ret != NULL) { + OPENSSL_free(ret->propq); + CRYPTO_FREE_REF(&ret->references); + } OPENSSL_free(ret); return NULL; } @@ -61,7 +68,7 @@ void ossl_ecx_key_free(ECX_KEY *key) if (key == NULL) return; - CRYPTO_DOWN_REF(&key->references, &i, key->lock); + CRYPTO_DOWN_REF(&key->references, &i); REF_PRINT_COUNT("ECX_KEY", key); if (i > 0) return; @@ -69,7 +76,7 @@ void ossl_ecx_key_free(ECX_KEY *key) OPENSSL_free(key->propq); OPENSSL_secure_clear_free(key->privkey, key->keylen); - CRYPTO_THREAD_lock_free(key->lock); + CRYPTO_FREE_REF(&key->references); OPENSSL_free(key); } @@ -82,7 +89,7 @@ int ossl_ecx_key_up_ref(ECX_KEY *key) { int i; - if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0) + if (CRYPTO_UP_REF(&key->references, &i) <= 0) return 0; REF_PRINT_COUNT("ECX_KEY", key); @@ -96,3 +103,61 @@ unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key) return key->privkey; } + +int ossl_ecx_compute_key(ECX_KEY *peer, ECX_KEY *priv, size_t keylen, + unsigned char *secret, size_t *secretlen, size_t outlen) +{ + if (priv == NULL + || priv->privkey == NULL + || peer == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); + return 0; + } + + if (!ossl_assert(keylen == X25519_KEYLEN + || keylen == X448_KEYLEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + + if (secret == NULL) { + *secretlen = keylen; + return 1; + } + if (outlen < keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (keylen == X25519_KEYLEN) { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) { + if (s390x_x25519_mul(secret, peer->pubkey, priv->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif + if (ossl_x25519(secret, priv->privkey, peer->pubkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) { + if (s390x_x448_mul(secret, peer->pubkey, priv->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif + if (ossl_x448(secret, priv->privkey, peer->pubkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } + *secretlen = keylen; + return 1; +} diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index c97dc472ac..6c445f9121 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -39,15 +39,13 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) } penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey)); - if (penc == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + if (penc == NULL) return 0; - } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) { OPENSSL_free(penc); - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_X509_LIB); return 0; } return 1; @@ -115,14 +113,14 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) penclen = i2d_ASN1_OCTET_STRING(&oct, &penc); if (penclen < 0) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); return 0; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, V_ASN1_UNDEF, NULL, penc, penclen)) { OPENSSL_clear_free(penc, penclen); - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_ASN1_LIB); return 0; } @@ -138,7 +136,7 @@ static int ecx_bits(const EVP_PKEY *pkey) { if (IS25519(pkey->ameth->pkey_id)) { return X25519_BITS; - } else if(ISX448(pkey->ameth->pkey_id)) { + } else if (ISX448(pkey->ameth->pkey_id)) { return X448_BITS; } else { return ED448_BITS; @@ -392,7 +390,7 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, pctx->propquery); if (ecx == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_EC_LIB); return 0; } @@ -561,17 +559,23 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, return 2; } +static int ecd_item_sign(X509_ALGOR *alg1, X509_ALGOR *alg2, int nid) +{ + /* Note that X509_ALGOR_set0(..., ..., V_ASN1_UNDEF, ...) cannot fail */ + /* Set algorithms identifiers */ + (void)X509_ALGOR_set0(alg1, OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + if (alg2 != NULL) + (void)X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + /* Algorithm identifiers set: carry on as normal */ + return 3; +} + static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { - /* Set algorithms identifiers */ - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); - if (alg2) - X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); - /* Algorithm identifiers set: carry on as normal */ - return 3; + return ecd_item_sign(alg1, alg2, NID_ED25519); } static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg, @@ -587,12 +591,7 @@ static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { - /* Set algorithm identifier */ - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL); - if (alg2 != NULL) - X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL); - /* Algorithm identifier set: carry on as normal */ - return 3; + return ecd_item_sign(alg1, alg2, NID_ED448); } static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg, @@ -822,8 +821,10 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig, return 0; } - if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL, - NULL) == 0) + if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, + 0, 0, 0, + NULL, 0, + NULL, NULL) == 0) return 0; *siglen = ED25519_SIGSIZE; return 1; @@ -850,7 +851,7 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, } if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, - edkey->privkey, NULL, 0, edkey->propq) == 0) + edkey->privkey, NULL, 0, 0, edkey->propq) == 0) return 0; *siglen = ED448_SIGSIZE; return 1; @@ -871,6 +872,8 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, return 0; return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, + 0, 0, 0, + NULL, 0, edkey->libctx, edkey->propq); } @@ -889,7 +892,7 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, return 0; return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, - NULL, 0, edkey->propq); + NULL, 0, 0, edkey->propq); } static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -945,7 +948,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) unsigned char *privkey = NULL, *pubkey; if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -953,7 +956,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -988,7 +991,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) unsigned char *privkey = NULL, *pubkey; if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -996,7 +999,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1037,7 +1040,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int rv; if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1045,7 +1048,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1103,7 +1106,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int rv; if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } @@ -1111,7 +1114,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index 952d55b96d..2e74816ee1 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -224,10 +224,8 @@ OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, return 0; } - if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) return 0; - } prov = OSSL_DECODER_get0_provider(decoder); libctx = ossl_provider_libctx(prov); @@ -283,6 +281,37 @@ void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst) } } +OSSL_DECODER_INSTANCE *ossl_decoder_instance_dup(const OSSL_DECODER_INSTANCE *src) +{ + OSSL_DECODER_INSTANCE *dest; + const OSSL_PROVIDER *prov; + void *provctx; + + if ((dest = OPENSSL_zalloc(sizeof(*dest))) == NULL) + return NULL; + + *dest = *src; + if (!OSSL_DECODER_up_ref(dest->decoder)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + goto err; + } + prov = OSSL_DECODER_get0_provider(dest->decoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + dest->decoderctx = dest->decoder->newctx(provctx); + if (dest->decoderctx == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + OSSL_DECODER_free(dest->decoder); + goto err; + } + + return dest; + + err: + OPENSSL_free(dest); + return NULL; +} + int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, OSSL_DECODER_INSTANCE *di) { @@ -291,7 +320,7 @@ int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, if (ctx->decoder_insts == NULL && (ctx->decoder_insts = sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); return 0; } @@ -508,7 +537,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, skdecoders = sk_OSSL_DECODER_new_null(); if (skdecoders == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); return 0; } OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders); @@ -825,7 +854,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg) } if ((cbio = ossl_core_bio_new_from_bio(bio)) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB); goto end; } diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 74c86a8fe8..2e70e8aa37 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,15 +29,13 @@ static OSSL_DECODER *ossl_decoder_new(void) { OSSL_DECODER *decoder = NULL; - if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL - || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&decoder->base.refcnt, 1)) { OSSL_DECODER_free(decoder); - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); return NULL; } - decoder->base.refcnt = 1; - return decoder; } @@ -45,7 +43,7 @@ int OSSL_DECODER_up_ref(OSSL_DECODER *decoder) { int ref = 0; - CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + CRYPTO_UP_REF(&decoder->base.refcnt, &ref); return 1; } @@ -56,13 +54,13 @@ void OSSL_DECODER_free(OSSL_DECODER *decoder) if (decoder == NULL) return; - CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref); if (ref > 0) return; OPENSSL_free(decoder->base.name); ossl_property_free(decoder->base.parsed_propdef); ossl_provider_free(decoder->base.prov); - CRYPTO_THREAD_lock_free(decoder->base.lock); + CRYPTO_FREE_REF(&decoder->base.refcnt); OPENSSL_free(decoder); } @@ -625,9 +623,7 @@ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void) { OSSL_DECODER_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); - + ctx = OPENSSL_zalloc(sizeof(*ctx)); return ctx; } diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c index 5afad9bd88..24f61fbf15 100644 --- a/crypto/encode_decode/decoder_pkey.c +++ b/crypto/encode_decode/decoder_pkey.c @@ -18,8 +18,10 @@ #include "crypto/evp.h" #include "crypto/decoder.h" #include "crypto/evp/evp_local.h" +#include "crypto/lhash.h" #include "encoder_local.h" #include "internal/namemap.h" +#include "internal/sizes.h" int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, const unsigned char *kstr, @@ -373,10 +375,10 @@ static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) * searches for decoders matching 'keytype', which is a string like "RSA", "DH", * etc. If 'keytype' is NULL, decoders for all keytypes are bound. */ -int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, - EVP_PKEY **pkey, const char *keytype, - OSSL_LIB_CTX *libctx, - const char *propquery) +static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, + const char *keytype, + OSSL_LIB_CTX *libctx, + const char *propquery) { int ok = 0; struct decoder_pkey_data_st *process_data = NULL; @@ -399,21 +401,20 @@ int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, } OSSL_TRACE_END(DECODER); /* Allocate data. */ - if ((process_data = OPENSSL_zalloc(sizeof(*process_data))) == NULL - || (propquery != NULL - && (process_data->propq = OPENSSL_strdup(propquery)) == NULL)) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + if ((process_data = OPENSSL_zalloc(sizeof(*process_data))) == NULL) + goto err; + if ((propquery != NULL + && (process_data->propq = OPENSSL_strdup(propquery)) == NULL)) goto err; - } /* Allocate our list of EVP_KEYMGMTs. */ keymgmts = sk_EVP_KEYMGMT_new_null(); if (keymgmts == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); goto err; } - process_data->object = (void **)pkey; + process_data->object = NULL; process_data->libctx = libctx; process_data->selection = ctx->selection; process_data->keymgmts = keymgmts; @@ -475,6 +476,268 @@ int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, return ok; } +/* Only const here because deep_copy requires it */ +static EVP_KEYMGMT *keymgmt_dup(const EVP_KEYMGMT *keymgmt) +{ + if (!EVP_KEYMGMT_up_ref((EVP_KEYMGMT *)keymgmt)) + return NULL; + + return (EVP_KEYMGMT *)keymgmt; +} + +/* + * Duplicates a template OSSL_DECODER_CTX that has been setup for an EVP_PKEY + * operation and sets up the duplicate for a new operation. + * It does not duplicate the pwdata on the assumption that this does not form + * part of the template. That is set up later. + */ +static OSSL_DECODER_CTX * +ossl_decoder_ctx_for_pkey_dup(OSSL_DECODER_CTX *src, + EVP_PKEY **pkey, + const char *input_type, + const char *input_structure) +{ + OSSL_DECODER_CTX *dest; + struct decoder_pkey_data_st *process_data_src, *process_data_dest = NULL; + + if (src == NULL) + return NULL; + + if ((dest = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + return NULL; + } + + if (!OSSL_DECODER_CTX_set_input_type(dest, input_type) + || !OSSL_DECODER_CTX_set_input_structure(dest, input_structure)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + goto err; + } + dest->selection = src->selection; + + if (src->decoder_insts != NULL) { + dest->decoder_insts + = sk_OSSL_DECODER_INSTANCE_deep_copy(src->decoder_insts, + ossl_decoder_instance_dup, + ossl_decoder_instance_free); + if (dest->decoder_insts == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + goto err; + } + } + + if (!OSSL_DECODER_CTX_set_construct(dest, + OSSL_DECODER_CTX_get_construct(src))) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + process_data_src = OSSL_DECODER_CTX_get_construct_data(src); + if (process_data_src != NULL) { + process_data_dest = OPENSSL_zalloc(sizeof(*process_data_dest)); + if (process_data_dest == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); + goto err; + } + if (process_data_src->propq != NULL) { + process_data_dest->propq = OPENSSL_strdup(process_data_src->propq); + if (process_data_dest->propq == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); + goto err; + } + } + + if (process_data_src->keymgmts != NULL) { + process_data_dest->keymgmts + = sk_EVP_KEYMGMT_deep_copy(process_data_src->keymgmts, + keymgmt_dup, + EVP_KEYMGMT_free); + if (process_data_dest->keymgmts == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_EVP_LIB); + goto err; + } + } + + process_data_dest->object = (void **)pkey; + process_data_dest->libctx = process_data_src->libctx; + process_data_dest->selection = process_data_src->selection; + if (!OSSL_DECODER_CTX_set_construct_data(dest, process_data_dest)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + goto err; + } + process_data_dest = NULL; + } + + if (!OSSL_DECODER_CTX_set_cleanup(dest, + OSSL_DECODER_CTX_get_cleanup(src))) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + return dest; + err: + if (process_data_dest != NULL) { + OPENSSL_free(process_data_dest->propq); + sk_EVP_KEYMGMT_pop_free(process_data_dest->keymgmts, EVP_KEYMGMT_free); + OPENSSL_free(process_data_dest); + } + OSSL_DECODER_CTX_free(dest); + return NULL; +} + +typedef struct { + char *input_type; + char *input_structure; + char *keytype; + int selection; + char *propquery; + OSSL_DECODER_CTX *template; +} DECODER_CACHE_ENTRY; + +DEFINE_LHASH_OF_EX(DECODER_CACHE_ENTRY); + +typedef struct { + CRYPTO_RWLOCK *lock; + LHASH_OF(DECODER_CACHE_ENTRY) *hashtable; +} DECODER_CACHE; + +static void decoder_cache_entry_free(DECODER_CACHE_ENTRY *entry) +{ + if (entry == NULL) + return; + OPENSSL_free(entry->input_type); + OPENSSL_free(entry->input_structure); + OPENSSL_free(entry->keytype); + OPENSSL_free(entry->propquery); + OSSL_DECODER_CTX_free(entry->template); + OPENSSL_free(entry); +} + +static unsigned long decoder_cache_entry_hash(const DECODER_CACHE_ENTRY *cache) +{ + unsigned long hash = 17; + + hash = (hash * 23) + + (cache->propquery == NULL + ? 0 : ossl_lh_strcasehash(cache->propquery)); + hash = (hash * 23) + + (cache->input_structure == NULL + ? 0 : ossl_lh_strcasehash(cache->input_structure)); + hash = (hash * 23) + + (cache->input_type == NULL + ? 0 : ossl_lh_strcasehash(cache->input_type)); + hash = (hash * 23) + + (cache->keytype == NULL + ? 0 : ossl_lh_strcasehash(cache->keytype)); + + hash ^= cache->selection; + + return hash; +} + +static ossl_inline int nullstrcmp(const char *a, const char *b, int casecmp) +{ + if (a == NULL || b == NULL) { + if (a == NULL) { + if (b == NULL) + return 0; + else + return 1; + } else { + return -1; + } + } else { + if (casecmp) + return OPENSSL_strcasecmp(a, b); + else + return strcmp(a, b); + } +} + +static int decoder_cache_entry_cmp(const DECODER_CACHE_ENTRY *a, + const DECODER_CACHE_ENTRY *b) +{ + int cmp; + + if (a->selection != b->selection) + return (a->selection < b->selection) ? -1 : 1; + + cmp = nullstrcmp(a->keytype, b->keytype, 1); + if (cmp != 0) + return cmp; + + cmp = nullstrcmp(a->input_type, b->input_type, 1); + if (cmp != 0) + return cmp; + + cmp = nullstrcmp(a->input_structure, b->input_structure, 1); + if (cmp != 0) + return cmp; + + cmp = nullstrcmp(a->propquery, b->propquery, 0); + + return cmp; +} + +void *ossl_decoder_cache_new(OSSL_LIB_CTX *ctx) +{ + DECODER_CACHE *cache = OPENSSL_malloc(sizeof(*cache)); + + if (cache == NULL) + return NULL; + + cache->lock = CRYPTO_THREAD_lock_new(); + if (cache->lock == NULL) { + OPENSSL_free(cache); + return NULL; + } + cache->hashtable = lh_DECODER_CACHE_ENTRY_new(decoder_cache_entry_hash, + decoder_cache_entry_cmp); + if (cache->hashtable == NULL) { + CRYPTO_THREAD_lock_free(cache->lock); + OPENSSL_free(cache); + return NULL; + } + + return cache; +} + +void ossl_decoder_cache_free(void *vcache) +{ + DECODER_CACHE *cache = (DECODER_CACHE *)vcache; + + lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free); + lh_DECODER_CACHE_ENTRY_free(cache->hashtable); + CRYPTO_THREAD_lock_free(cache->lock); + OPENSSL_free(cache); +} + +/* + * Called whenever a provider gets activated/deactivated. In that case the + * decoders that are available might change so we flush our cache. + */ +int ossl_decoder_cache_flush(OSSL_LIB_CTX *libctx) +{ + DECODER_CACHE *cache + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX); + + if (cache == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + return 0; + } + + if (!CRYPTO_THREAD_write_lock(cache->lock)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + return 0; + } + + lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free); + lh_DECODER_CACHE_ENTRY_flush(cache->hashtable); + + CRYPTO_THREAD_unlock(cache->lock); + return 1; +} + OSSL_DECODER_CTX * OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey, const char *input_type, @@ -483,33 +746,135 @@ OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey, OSSL_LIB_CTX *libctx, const char *propquery) { OSSL_DECODER_CTX *ctx = NULL; - - if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + OSSL_PARAM decoder_params[] = { + OSSL_PARAM_END, + OSSL_PARAM_END + }; + DECODER_CACHE *cache + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX); + DECODER_CACHE_ENTRY cacheent, *res, *newcache = NULL; + + if (cache == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + return NULL; + } + if (propquery != NULL) + decoder_params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, + (char *)propquery, 0); + + /* It is safe to cast away the const here */ + cacheent.input_type = (char *)input_type; + cacheent.input_structure = (char *)input_structure; + cacheent.keytype = (char *)keytype; + cacheent.selection = selection; + cacheent.propquery = (char *)propquery; + + if (!CRYPTO_THREAD_read_lock(cache->lock)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); return NULL; } - OSSL_TRACE_BEGIN(DECODER) { - BIO_printf(trc_out, - "(ctx %p) Looking for %s decoders with selection %d\n", - (void *)ctx, keytype, selection); - BIO_printf(trc_out, " input type: %s, input structure: %s\n", - input_type, input_structure); - } OSSL_TRACE_END(DECODER); + /* First see if we have a template OSSL_DECODER_CTX */ + res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent); + + if (res == NULL) { + /* + * There is no template so we will have to construct one. This will be + * time consuming so release the lock and we will later upgrade it to a + * write lock. + */ + CRYPTO_THREAD_unlock(cache->lock); + + if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + return NULL; + } - if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) - && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure) - && OSSL_DECODER_CTX_set_selection(ctx, selection) - && ossl_decoder_ctx_setup_for_pkey(ctx, pkey, keytype, - libctx, propquery) - && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) { OSSL_TRACE_BEGIN(DECODER) { - BIO_printf(trc_out, "(ctx %p) Got %d decoders\n", - (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx)); + BIO_printf(trc_out, + "(ctx %p) Looking for %s decoders with selection %d\n", + (void *)ctx, keytype, selection); + BIO_printf(trc_out, " input type: %s, input structure: %s\n", + input_type, input_structure); } OSSL_TRACE_END(DECODER); - return ctx; + + if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) + && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure) + && OSSL_DECODER_CTX_set_selection(ctx, selection) + && ossl_decoder_ctx_setup_for_pkey(ctx, keytype, libctx, propquery) + && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery) + && (propquery == NULL + || OSSL_DECODER_CTX_set_params(ctx, decoder_params))) { + OSSL_TRACE_BEGIN(DECODER) { + BIO_printf(trc_out, "(ctx %p) Got %d decoders\n", + (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx)); + } OSSL_TRACE_END(DECODER); + } else { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + OSSL_DECODER_CTX_free(ctx); + return NULL; + } + + newcache = OPENSSL_zalloc(sizeof(*newcache)); + if (newcache == NULL) { + OSSL_DECODER_CTX_free(ctx); + return NULL; + } + + if (input_type != NULL) { + newcache->input_type = OPENSSL_strdup(input_type); + if (newcache->input_type == NULL) + goto err; + } + if (input_structure != NULL) { + newcache->input_structure = OPENSSL_strdup(input_structure); + if (newcache->input_structure == NULL) + goto err; + } + if (keytype != NULL) { + newcache->keytype = OPENSSL_strdup(keytype); + if (newcache->keytype == NULL) + goto err; + } + if (propquery != NULL) { + newcache->propquery = OPENSSL_strdup(propquery); + if (newcache->propquery == NULL) + goto err; + } + newcache->selection = selection; + newcache->template = ctx; + + if (!CRYPTO_THREAD_write_lock(cache->lock)) { + ctx = NULL; + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); + goto err; + } + res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent); + if (res == NULL) { + (void)lh_DECODER_CACHE_ENTRY_insert(cache->hashtable, newcache); + if (lh_DECODER_CACHE_ENTRY_error(cache->hashtable)) { + ctx = NULL; + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); + goto err; + } + } else { + /* + * We raced with another thread to construct this and lost. Free + * what we just created and use the entry from the hashtable instead + */ + decoder_cache_entry_free(newcache); + ctx = res->template; + } + } else { + ctx = res->template; } + ctx = ossl_decoder_ctx_for_pkey_dup(ctx, pkey, input_type, input_structure); + CRYPTO_THREAD_unlock(cache->lock); + + return ctx; + err: + decoder_cache_entry_free(newcache); OSSL_DECODER_CTX_free(ctx); return NULL; } diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c index 7868da79b7..28dae99dc8 100644 --- a/crypto/encode_decode/encoder_lib.c +++ b/crypto/encode_decode/encoder_lib.c @@ -193,10 +193,8 @@ static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder, return 0; } - if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) return 0; - } if (!OSSL_ENCODER_up_ref(encoder)) { ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); @@ -259,7 +257,7 @@ static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx, if (ctx->encoder_insts == NULL && (ctx->encoder_insts = sk_OSSL_ENCODER_INSTANCE_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_CRYPTO_LIB); return 0; } diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h index 6a5bf16ae9..91e601aeaf 100644 --- a/crypto/encode_decode/encoder_local.h +++ b/crypto/encode_decode/encoder_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,7 +25,6 @@ struct ossl_endecode_base_st { OSSL_PROPERTY_LIST *parsed_propdef; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; }; struct ossl_encoder_st { diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c index 7092ba7ef8..adf34bbb9f 100644 --- a/crypto/encode_decode/encoder_meth.c +++ b/crypto/encode_decode/encoder_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,15 +29,13 @@ static OSSL_ENCODER *ossl_encoder_new(void) { OSSL_ENCODER *encoder = NULL; - if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL - || (encoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&encoder->base.refcnt, 1)) { OSSL_ENCODER_free(encoder); - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); return NULL; } - encoder->base.refcnt = 1; - return encoder; } @@ -45,7 +43,7 @@ int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder) { int ref = 0; - CRYPTO_UP_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + CRYPTO_UP_REF(&encoder->base.refcnt, &ref); return 1; } @@ -56,13 +54,13 @@ void OSSL_ENCODER_free(OSSL_ENCODER *encoder) if (encoder == NULL) return; - CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref); if (ref > 0) return; OPENSSL_free(encoder->base.name); ossl_property_free(encoder->base.parsed_propdef); ossl_provider_free(encoder->base.prov); - CRYPTO_THREAD_lock_free(encoder->base.lock); + CRYPTO_FREE_REF(&encoder->base.refcnt); OPENSSL_free(encoder); } @@ -609,9 +607,7 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(void) { OSSL_ENCODER_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); - + ctx = OPENSSL_zalloc(sizeof(*ctx)); return ctx; } diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index 7b9584953d..29060c5f9d 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -247,10 +247,8 @@ static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx, struct collected_encoder_st encoder_data; struct collected_names_st keymgmt_data; - if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) goto err; - } /* * Select the first encoder implementations in two steps. @@ -258,7 +256,7 @@ static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx, */ keymgmt_data.names = sk_OPENSSL_CSTRING_new_null(); if (keymgmt_data.names == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_CRYPTO_LIB); goto err; } @@ -313,7 +311,7 @@ static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx, OPENSSL_free(encoder_data.id_names); sk_OPENSSL_CSTRING_free(keymgmt_data.names); if (encoder_data.error_occurred) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_CRYPTO_LIB); goto err; } } @@ -360,7 +358,7 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey, } if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_OSSL_ENCODER_LIB); return NULL; } diff --git a/crypto/engine/eng_ctrl.c b/crypto/engine/eng_ctrl.c index 5d7e15634e..f1da9b23bb 100644 --- a/crypto/engine/eng_ctrl.c +++ b/crypto/engine/eng_ctrl.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -127,20 +127,15 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) { - int ctrl_exists, ref_exists; + int ctrl_exists; + if (e == NULL) { ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (!CRYPTO_THREAD_write_lock(global_engine_lock)) - return 0; - ref_exists = ((e->struct_ref > 0) ? 1 : 0); - CRYPTO_THREAD_unlock(global_engine_lock); + ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); - if (!ref_exists) { - ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE); - return 0; - } + /* * Intercept any "root-level" commands before trying to hand them on to * ctrl() handlers. diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c index 6d402927c5..cc3a2b0aa3 100644 --- a/crypto/engine/eng_dyn.c +++ b/crypto/engine/eng_dyn.c @@ -159,13 +159,11 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c)); int ret = 0; - if (c == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + if (c == NULL) return 0; - } c->dirs = sk_OPENSSL_STRING_new_null(); if (c->dirs == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); goto end; } c->DYNAMIC_F1 = "v_check"; @@ -357,13 +355,11 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) } { char *tmp_str = OPENSSL_strdup(p); - if (tmp_str == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + if (tmp_str == NULL) return 0; - } if (!sk_OPENSSL_STRING_push(ctx->dirs, tmp_str)) { OPENSSL_free(tmp_str); - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return 0; } } diff --git a/crypto/engine/eng_init.c b/crypto/engine/eng_init.c index 4bccab56aa..0ac91ff5ed 100644 --- a/crypto/engine/eng_init.c +++ b/crypto/engine/eng_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,11 +28,16 @@ int engine_unlocked_init(ENGINE *e) */ to_return = e->init(e); if (to_return) { + int ref; + /* * OK, we return a functional reference which is also a structural * reference. */ - e->struct_ref++; + if (!CRYPTO_UP_REF(&e->struct_ref, &ref)) { + e->finish(e); + return 0; + } e->funct_ref++; ENGINE_REF_PRINT(e, 0, 1); ENGINE_REF_PRINT(e, 1, 1); @@ -86,7 +91,8 @@ int ENGINE_init(ENGINE *e) return 0; } if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return 0; } if (!CRYPTO_THREAD_write_lock(global_engine_lock)) diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c index 9ef71a21af..412363fa37 100644 --- a/crypto/engine/eng_lib.c +++ b/crypto/engine/eng_lib.c @@ -28,14 +28,20 @@ ENGINE *ENGINE_new(void) { ENGINE *ret; - if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init) - || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return 0; + } + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&ret->struct_ref, 1)) { + OPENSSL_free(ret); return NULL; } - ret->struct_ref = 1; ENGINE_REF_PRINT(ret, 0, 1); if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data)) { + CRYPTO_FREE_REF(&ret->struct_ref); OPENSSL_free(ret); return NULL; } @@ -74,10 +80,7 @@ int engine_free_util(ENGINE *e, int not_locked) if (e == NULL) return 1; - if (not_locked) - CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock); - else - i = --e->struct_ref; + CRYPTO_DOWN_REF(&e->struct_ref, &i); ENGINE_REF_PRINT(e, 0, -1); if (i > 0) return 1; @@ -93,6 +96,7 @@ int engine_free_util(ENGINE *e, int not_locked) e->destroy(e); engine_remove_dynamic_id(e, not_locked); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); + CRYPTO_FREE_REF(&e->struct_ref); OPENSSL_free(e); return 1; } @@ -125,10 +129,8 @@ static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) { ENGINE_CLEANUP_ITEM *item; - if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + if ((item = OPENSSL_malloc(sizeof(*item))) == NULL) return NULL; - } item->cb = cb; return item; } diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c index f2eed3b071..a2c151d64a 100644 --- a/crypto/engine/eng_list.c +++ b/crypto/engine/eng_list.c @@ -58,6 +58,7 @@ static int engine_list_add(ENGINE *e) { int conflict = 0; ENGINE *iterator = NULL; + int ref; if (e == NULL) { ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); @@ -72,9 +73,19 @@ static int engine_list_add(ENGINE *e) ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID); return 0; } + + /* + * Having the engine in the list assumes a structural reference. + */ + if (!CRYPTO_UP_REF(&e->struct_ref, &ref)) { + ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + ENGINE_REF_PRINT(e, 0, 1); if (engine_list_head == NULL) { /* We are adding to an empty list. */ - if (engine_list_tail) { + if (engine_list_tail != NULL) { + CRYPTO_DOWN_REF(&e->struct_ref, &ref); ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } @@ -82,6 +93,7 @@ static int engine_list_add(ENGINE *e) * The first time the list allocates, we should register the cleanup. */ if (!engine_cleanup_add_last(engine_list_cleanup)) { + CRYPTO_DOWN_REF(&e->struct_ref, &ref); ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } @@ -90,17 +102,14 @@ static int engine_list_add(ENGINE *e) } else { /* We are adding to the tail of an existing list. */ if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { + CRYPTO_DOWN_REF(&e->struct_ref, &ref); ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR); return 0; } engine_list_tail->next = e; e->prev = engine_list_tail; } - /* - * Having the engine in the list assumes a structural reference. - */ - e->struct_ref++; - ENGINE_REF_PRINT(e, 0, 1); + /* However it came to be, e is the last item in the list. */ engine_list_tail = e; e->next = NULL; @@ -222,7 +231,8 @@ ENGINE *ENGINE_get_first(void) ENGINE *ret; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return NULL; } @@ -230,7 +240,12 @@ ENGINE *ENGINE_get_first(void) return NULL; ret = engine_list_head; if (ret) { - ret->struct_ref++; + int ref; + + if (!CRYPTO_UP_REF(&ret->struct_ref, &ref)) { + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); @@ -242,7 +257,8 @@ ENGINE *ENGINE_get_last(void) ENGINE *ret; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return NULL; } @@ -250,7 +266,12 @@ ENGINE *ENGINE_get_last(void) return NULL; ret = engine_list_tail; if (ret) { - ret->struct_ref++; + int ref; + + if (!CRYPTO_UP_REF(&ret->struct_ref, &ref)) { + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); @@ -269,8 +290,13 @@ ENGINE *ENGINE_get_next(ENGINE *e) return NULL; ret = e->next; if (ret) { + int ref; + /* Return a valid structural reference to the next ENGINE */ - ret->struct_ref++; + if (!CRYPTO_UP_REF(&ret->struct_ref, &ref)) { + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); @@ -290,8 +316,13 @@ ENGINE *ENGINE_get_prev(ENGINE *e) return NULL; ret = e->prev; if (ret) { + int ref; + /* Return a valid structural reference to the next ENGINE */ - ret->struct_ref++; + if (!CRYPTO_UP_REF(&ret->struct_ref, &ref)) { + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(ret, 0, 1); } CRYPTO_THREAD_unlock(global_engine_lock); @@ -381,7 +412,8 @@ ENGINE *ENGINE_by_id(const char *id) ENGINE_load_builtin_engines(); if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return NULL; } @@ -405,7 +437,13 @@ ENGINE *ENGINE_by_id(const char *id) iterator = cp; } } else { - iterator->struct_ref++; + int ref; + + if (!CRYPTO_UP_REF(&iterator->struct_ref, &ref)) { + CRYPTO_THREAD_unlock(global_engine_lock); + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(iterator, 0, 1); } } @@ -442,6 +480,6 @@ int ENGINE_up_ref(ENGINE *e) ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock); + CRYPTO_UP_REF(&e->struct_ref, &i); return 1; } diff --git a/crypto/engine/eng_local.h b/crypto/engine/eng_local.h index a3e637a4d2..24920973e7 100644 --- a/crypto/engine/eng_local.h +++ b/crypto/engine/eng_local.h @@ -31,8 +31,8 @@ extern CRYPTO_RWLOCK *global_engine_lock; (void *)(e), (isfunct ? "funct" : "struct"), \ ((isfunct) \ ? ((e)->funct_ref - (diff)) \ - : ((e)->struct_ref - (diff))), \ - ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ + : (eng_struct_ref(e) - (diff))), \ + ((isfunct) ? (e)->funct_ref : eng_struct_ref(e)), \ (OPENSSL_FILE), (OPENSSL_LINE)) /* @@ -158,4 +158,12 @@ typedef struct st_engine_pile ENGINE_PILE; DEFINE_LHASH_OF_EX(ENGINE_PILE); +static ossl_unused ossl_inline int eng_struct_ref(ENGINE *e) +{ + int res; + + CRYPTO_GET_REF(&e->struct_ref, &res); + return res; +} + #endif /* OSSL_CRYPTO_ENGINE_ENG_LOCAL_H */ diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index 91656e6b80..8b39e3dec7 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -450,10 +450,8 @@ static int ossl_hmac_init(EVP_PKEY_CTX *ctx) { OSSL_HMAC_PKEY_CTX *hctx; - if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) return 0; - } hctx->ktmp.type = V_ASN1_OCTET_STRING; hctx->ctx = HMAC_CTX_new(); if (hctx->ctx == NULL) { diff --git a/crypto/engine/tb_asnmth.c b/crypto/engine/tb_asnmth.c index bd65ede2f2..c74fc4700b 100644 --- a/crypto/engine/tb_asnmth.c +++ b/crypto/engine/tb_asnmth.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -196,16 +196,23 @@ const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, fstr.len = len; if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { - ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); + /* Maybe this should be raised in do_engine_lock_init() */ + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); return NULL; } - if (!CRYPTO_THREAD_write_lock(global_engine_lock)) + if (!CRYPTO_THREAD_read_lock(global_engine_lock)) return NULL; engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); /* If found obtain a structural reference to engine */ - if (fstr.e) { - fstr.e->struct_ref++; + if (fstr.e != NULL) { + int ref; + + if (!CRYPTO_UP_REF(&fstr.e->struct_ref, &ref)) { + CRYPTO_THREAD_unlock(global_engine_lock); + ERR_raise(ERR_LIB_ENGINE, ERR_R_CRYPTO_LIB); + return NULL; + } ENGINE_REF_PRINT(fstr.e, 0, 1); } *pe = fstr.e; diff --git a/crypto/err/build.info b/crypto/err/build.info index 98f8801e34..8552d7c393 100644 --- a/crypto/err/build.info +++ b/crypto/err/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - err_blocks.c err.c err_all.c err_all_legacy.c err_prn.c + err_blocks.c err_mark.c err.c err_all.c err_all_legacy.c err_prn.c err_save.c diff --git a/crypto/err/err.c b/crypto/err/err.c index 672a55bcfd..b95182d702 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,7 +33,6 @@ ERR_STATE *ERR_get_state(void); static int err_load_strings(const ERR_STRING_DATA *str); #endif -static void ERR_STATE_free(ERR_STATE *s); #ifndef OPENSSL_NO_ERR static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"}, @@ -199,16 +198,16 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) } #endif -static void ERR_STATE_free(ERR_STATE *s) +void OSSL_ERR_STATE_free(ERR_STATE *state) { int i; - if (s == NULL) + if (state == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear(s, i, 1); + err_clear(state, i, 1); } - OPENSSL_free(s); + CRYPTO_free(state, OPENSSL_FILE, OPENSSL_LINE); } DEFINE_RUN_ONCE_STATIC(do_err_strings_init) @@ -552,7 +551,8 @@ void ossl_err_string_int(unsigned long e, const char *func, } #endif if (rs == NULL) { - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", + r & ~(ERR_RFLAGS_MASK << ERR_RFLAGS_OFFSET)); rs = rsbuf; } @@ -648,7 +648,7 @@ static void err_delete_thread_state(void *unused) return; CRYPTO_THREAD_set_local(&err_thread_local, NULL); - ERR_STATE_free(state); + OSSL_ERR_STATE_free(state); } #ifndef OPENSSL_NO_DEPRECATED_1_1_0 @@ -688,14 +688,15 @@ ERR_STATE *ossl_err_get_state_int(void) if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1)) return NULL; - if ((state = OPENSSL_zalloc(sizeof(*state))) == NULL) { + state = OSSL_ERR_STATE_new(); + if (state == NULL) { CRYPTO_THREAD_set_local(&err_thread_local, NULL); return NULL; } if (!ossl_init_thread_start(NULL, NULL, err_delete_thread_state) || !CRYPTO_THREAD_set_local(&err_thread_local, state)) { - ERR_STATE_free(state); + OSSL_ERR_STATE_free(state); CRYPTO_THREAD_set_local(&err_thread_local, NULL); return NULL; } @@ -830,10 +831,11 @@ void ERR_add_error_vdata(int num, va_list args) i = es->top; /* - * If err_data is allocated already, re-use the space. + * If err_data is allocated already, reuse the space. * Otherwise, allocate a small new buffer. */ - if ((es->err_data_flags[i] & flags) == flags) { + if ((es->err_data_flags[i] & flags) == flags + && ossl_assert(es->err_data[i] != NULL)) { str = es->err_data[i]; size = es->err_data_size[i]; @@ -875,61 +877,6 @@ void ERR_add_error_vdata(int num, va_list args) OPENSSL_free(str); } -int ERR_set_mark(void) -{ - ERR_STATE *es; - - es = ossl_err_get_state_int(); - if (es == NULL) - return 0; - - if (es->bottom == es->top) - return 0; - es->err_marks[es->top]++; - return 1; -} - -int ERR_pop_to_mark(void) -{ - ERR_STATE *es; - - es = ossl_err_get_state_int(); - if (es == NULL) - return 0; - - while (es->bottom != es->top - && es->err_marks[es->top] == 0) { - err_clear(es, es->top, 0); - es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; - } - - if (es->bottom == es->top) - return 0; - es->err_marks[es->top]--; - return 1; -} - -int ERR_clear_last_mark(void) -{ - ERR_STATE *es; - int top; - - es = ossl_err_get_state_int(); - if (es == NULL) - return 0; - - top = es->top; - while (es->bottom != top - && es->err_marks[top] == 0) { - top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; - } - - if (es->bottom == top) - return 0; - es->err_marks[top]--; - return 1; -} - void err_clear_last_constant_time(int clear) { ERR_STATE *es; diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 55aa2b8dbd..86b609a555 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -85,7 +85,9 @@ int ossl_err_load_crypto_strings(void) # ifndef OPENSSL_NO_ENGINE || ossl_err_load_ENGINE_strings() == 0 # endif +# ifndef OPENSSL_NO_HTTP || ossl_err_load_HTTP_strings() == 0 +# endif # ifndef OPENSSL_NO_OCSP || ossl_err_load_OCSP_strings() == 0 # endif diff --git a/crypto/err/err_local.h b/crypto/err/err_local.h index d4e19dff24..c5c5bf45ba 100644 --- a/crypto/err/err_local.h +++ b/crypto/err/err_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include @@ -56,14 +57,18 @@ static ossl_inline void err_set_debug(ERR_STATE *es, size_t i, OPENSSL_free(es->err_file[i]); if (file == NULL || file[0] == '\0') es->err_file[i] = NULL; - else - es->err_file[i] = OPENSSL_strdup(file); + else if ((es->err_file[i] = CRYPTO_malloc(strlen(file) + 1, + NULL, 0)) != NULL) + /* We cannot use OPENSSL_strdup due to possible recursion */ + strcpy(es->err_file[i], file); + es->err_line[i] = line; OPENSSL_free(es->err_func[i]); if (fn == NULL || fn[0] == '\0') es->err_func[i] = NULL; - else - es->err_func[i] = OPENSSL_strdup(fn); + else if ((es->err_func[i] = CRYPTO_malloc(strlen(fn) + 1, + NULL, 0)) != NULL) + strcpy(es->err_func[i], fn); } static ossl_inline void err_set_data(ERR_STATE *es, size_t i, diff --git a/crypto/err/err_mark.c b/crypto/err/err_mark.c new file mode 100644 index 0000000000..82dc4764c4 --- /dev/null +++ b/crypto/err/err_mark.c @@ -0,0 +1,88 @@ +/* + * Copyright 2003-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define OSSL_FORCE_ERR_STATE + +#include +#include "err_local.h" + +int ERR_set_mark(void) +{ + ERR_STATE *es; + + es = ossl_err_get_state_int(); + if (es == NULL) + return 0; + + if (es->bottom == es->top) + return 0; + es->err_marks[es->top]++; + return 1; +} + +int ERR_pop_to_mark(void) +{ + ERR_STATE *es; + + es = ossl_err_get_state_int(); + if (es == NULL) + return 0; + + while (es->bottom != es->top + && es->err_marks[es->top] == 0) { + err_clear(es, es->top, 0); + es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; + } + + if (es->bottom == es->top) + return 0; + es->err_marks[es->top]--; + return 1; +} + +int ERR_count_to_mark(void) +{ + ERR_STATE *es; + int count = 0, top; + + es = ossl_err_get_state_int(); + if (es == NULL) + return 0; + + top = es->top; + while (es->bottom != top + && es->err_marks[top] == 0) { + ++count; + top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; + } + + return count; +} + +int ERR_clear_last_mark(void) +{ + ERR_STATE *es; + int top; + + es = ossl_err_get_state_int(); + if (es == NULL) + return 0; + + top = es->top; + while (es->bottom != top + && es->err_marks[top] == 0) { + top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; + } + + if (es->bottom == top) + return 0; + es->err_marks[top]--; + return 1; +} + diff --git a/crypto/err/err_save.c b/crypto/err/err_save.c new file mode 100644 index 0000000000..1994c26cee --- /dev/null +++ b/crypto/err/err_save.c @@ -0,0 +1,156 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define OSSL_FORCE_ERR_STATE + +#include +#include "err_local.h" + +/* + * Save and restore error state. + * We are using CRYPTO_zalloc(.., NULL, 0) instead of OPENSSL_malloc() in + * these functions to prevent mem alloc error loop. + */ + +ERR_STATE *OSSL_ERR_STATE_new(void) +{ + return CRYPTO_zalloc(sizeof(ERR_STATE), NULL, 0); +} + +void OSSL_ERR_STATE_save(ERR_STATE *es) +{ + size_t i; + ERR_STATE *thread_es; + + if (es == NULL) + return; + + for (i = 0; i < ERR_NUM_ERRORS; i++) + err_clear(es, i, 1); + + thread_es = ossl_err_get_state_int(); + if (thread_es == NULL) + return; + + memcpy(es, thread_es, sizeof(*es)); + /* Taking over the pointers, just clear the thread state. */ + memset(thread_es, 0, sizeof(*thread_es)); +} + +void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es) +{ + size_t i, j, count; + int top; + ERR_STATE *thread_es; + + if (es == NULL) + return; + + thread_es = ossl_err_get_state_int(); + if (thread_es == NULL) { + for (i = 0; i < ERR_NUM_ERRORS; ++i) + err_clear(es, i, 1); + + es->top = es->bottom = 0; + return; + } + + /* Determine number of errors we are going to move. */ + for (count = 0, top = thread_es->top; + thread_es->bottom != top + && thread_es->err_marks[top] == 0; + ++count) + top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; + + /* Move the errors, preserving order. */ + for (i = 0, j = top; i < count; ++i) { + j = (j + 1) % ERR_NUM_ERRORS; + + err_clear(es, i, 1); + + /* Move the error entry to the given ERR_STATE. */ + es->err_flags[i] = thread_es->err_flags[j]; + es->err_marks[i] = 0; + es->err_buffer[i] = thread_es->err_buffer[j]; + es->err_data[i] = thread_es->err_data[j]; + es->err_data_size[i] = thread_es->err_data_size[j]; + es->err_data_flags[i] = thread_es->err_data_flags[j]; + es->err_file[i] = thread_es->err_file[j]; + es->err_line[i] = thread_es->err_line[j]; + es->err_func[i] = thread_es->err_func[j]; + + thread_es->err_flags[j] = 0; + thread_es->err_buffer[j] = 0; + thread_es->err_data[j] = NULL; + thread_es->err_data_size[j] = 0; + thread_es->err_data_flags[j] = 0; + thread_es->err_file[j] = NULL; + thread_es->err_line[j] = 0; + thread_es->err_func[j] = NULL; + } + + if (i > 0) { + thread_es->top = top; + /* If we moved anything, es's stack always starts at [0]. */ + es->top = i - 1; + es->bottom = ERR_NUM_ERRORS - 1; + } else { + /* Didn't move anything - empty stack */ + es->top = es->bottom = 0; + } + + /* Erase extra space as a precaution. */ + for (; i < ERR_NUM_ERRORS; ++i) + err_clear(es, i, 1); +} + +void OSSL_ERR_STATE_restore(const ERR_STATE *es) +{ + size_t i; + ERR_STATE *thread_es; + + if (es == NULL || es->bottom == es->top) + return; + + thread_es = ossl_err_get_state_int(); + if (thread_es == NULL) + return; + + for (i = (size_t)es->bottom; i != (size_t)es->top;) { + size_t top; + + i = (i + 1) % ERR_NUM_ERRORS; + if ((es->err_flags[i] & ERR_FLAG_CLEAR) != 0) + continue; + + err_get_slot(thread_es); + top = thread_es->top; + err_clear(thread_es, top, 0); + + thread_es->err_flags[top] = es->err_flags[i]; + thread_es->err_buffer[top] = es->err_buffer[i]; + + err_set_debug(thread_es, top, es->err_file[i], es->err_line[i], + es->err_func[i]); + + if (es->err_data[i] != NULL && es->err_data_size[i] != 0) { + void *data; + size_t data_sz = es->err_data_size[i]; + + data = CRYPTO_malloc(data_sz, NULL, 0); + if (data != NULL) { + memcpy(data, es->err_data[i], data_sz); + err_set_data(thread_es, top, data, data_sz, + es->err_data_flags[i] | ERR_TXT_MALLOCED); + } + } else { + err_clear_data(thread_es, top, 0); + } + } +} diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 3612c195f0..f1917136d8 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -76,6 +76,4 @@ R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 -R TLS1_AD_UNKNOWN_PSK_IDENTITY 1115 R SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 -R TLS1_AD_NO_APPLICATION_PROTOCOL 1120 diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index a1e6bbb617..5f60bd52d2 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -142,14 +142,20 @@ BIO_R_INVALID_SOCKET:135:invalid socket BIO_R_IN_USE:123:in use BIO_R_LENGTH_TOO_LONG:102:length too long BIO_R_LISTEN_V6_ONLY:136:listen v6 only +BIO_R_LOCAL_ADDR_NOT_AVAILABLE:111:local addr not available BIO_R_LOOKUP_RETURNED_NOTHING:142:lookup returned nothing BIO_R_MALFORMED_HOST_OR_SERVICE:130:malformed host or service BIO_R_NBIO_CONNECT_ERROR:110:nbio connect error +BIO_R_NON_FATAL:112:non fatal BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED:143:\ no accept addr or service specified BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified BIO_R_NO_PORT_DEFINED:113:no port defined BIO_R_NO_SUCH_FILE:128:no such file +BIO_R_PEER_ADDR_NOT_AVAILABLE:114:peer addr not available +BIO_R_PORT_MISMATCH:150:port mismatch +BIO_R_TFO_DISABLED:106:tfo disabled +BIO_R_TFO_NO_KERNEL_SUPPORT:108:tfo no kernel support BIO_R_TRANSFER_ERROR:104:transfer error BIO_R_TRANSFER_TIMEOUT:105:transfer timeout BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket @@ -158,6 +164,7 @@ BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive BIO_R_UNABLE_TO_LISTEN_SOCKET:119:unable to listen socket BIO_R_UNABLE_TO_NODELAY:138:unable to nodelay BIO_R_UNABLE_TO_REUSEADDR:139:unable to reuseaddr +BIO_R_UNABLE_TO_TFO:109:unable to tfo BIO_R_UNAVAILABLE_IP_FAMILY:145:unavailable ip family BIO_R_UNINITIALIZED:120:uninitialized BIO_R_UNKNOWN_INFO_TYPE:140:unknown info type @@ -224,8 +231,11 @@ CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range +CMP_R_GETTING_GENP:192:getting genp CMP_R_INVALID_ARGS:100:invalid args +CMP_R_INVALID_GENP:193:invalid genp CMP_R_INVALID_OPTION:174:invalid option +CMP_R_INVALID_ROOTCAKEYUPDATE:195:invalid rootcakeyupdate CMP_R_MISSING_CERTID:165:missing certid CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\ missing key input for creating protection @@ -261,6 +271,7 @@ CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG:151:srvcert does not validate msg CMP_R_TOTAL_TIMEOUT:184:total timeout CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched CMP_R_TRANSFER_ERROR:159:transfer error +CMP_R_UNCLEAN_CTX:191:unclean ctx CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus CMP_R_UNEXPECTED_PVNO:153:unexpected pvno @@ -345,6 +356,7 @@ CMS_R_NO_PRIVATE_KEY:133:no private key CMS_R_NO_PUBLIC_KEY:134:no public key CMS_R_NO_RECEIPT_REQUEST:168:no receipt request CMS_R_NO_SIGNERS:135:no signers +CMS_R_OPERATION_UNSUPPORTED:182:operation unsupported CMS_R_PEER_KEY_ERROR:188:peer key error CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE:136:\ private key does not match certificate @@ -381,9 +393,18 @@ CMS_R_UNWRAP_ERROR:157:unwrap error CMS_R_UNWRAP_FAILURE:180:unwrap failure CMS_R_VERIFICATION_FAILURE:158:verification failure CMS_R_WRAP_ERROR:159:wrap error +COMP_R_BROTLI_DECODE_ERROR:102:brotli decode error +COMP_R_BROTLI_DEFLATE_ERROR:103:brotli deflate error +COMP_R_BROTLI_ENCODE_ERROR:106:brotli encode error +COMP_R_BROTLI_INFLATE_ERROR:104:brotli inflate error +COMP_R_BROTLI_NOT_SUPPORTED:105:brotli not supported COMP_R_ZLIB_DEFLATE_ERROR:99:zlib deflate error COMP_R_ZLIB_INFLATE_ERROR:100:zlib inflate error COMP_R_ZLIB_NOT_SUPPORTED:101:zlib not supported +COMP_R_ZSTD_COMPRESS_ERROR:107:zstd compress error +COMP_R_ZSTD_DECODE_ERROR:108:zstd decode error +COMP_R_ZSTD_DECOMPRESS_ERROR:109:zstd decompress error +COMP_R_ZSTD_NOT_SUPPORTED:110:zstd not supported CONF_R_ERROR_LOADING_DSO:110:error loading dso CONF_R_INVALID_PRAGMA:122:invalid pragma CONF_R_LIST_CANNOT_BE_NULL:115:list cannot be null @@ -503,6 +524,7 @@ DH_R_INVALID_PARAMETER_NAME:110:invalid parameter name DH_R_INVALID_PARAMETER_NID:114:invalid parameter nid DH_R_INVALID_PUBKEY:102:invalid public key DH_R_INVALID_SECRET:128:invalid secret +DH_R_INVALID_SIZE:129:invalid size DH_R_KDF_PARAMETER_ERROR:112:kdf parameter error DH_R_KEYS_NOT_SET:108:keys not set DH_R_MISSING_PUBKEY:125:missing pubkey @@ -513,6 +535,7 @@ DH_R_NO_PARAMETERS_SET:107:no parameters set DH_R_NO_PRIVATE_VALUE:100:no private value DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error +DH_R_Q_TOO_LARGE:130:q too large DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters @@ -759,11 +782,14 @@ EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE:215:unable to get maximum request size EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH:216:unable to get random strength EVP_R_UNABLE_TO_LOCK_CONTEXT:211:unable to lock context EVP_R_UNABLE_TO_SET_CALLBACKS:217:unable to set callbacks +EVP_R_UNKNOWN_BITS:166:unknown bits EVP_R_UNKNOWN_CIPHER:160:unknown cipher EVP_R_UNKNOWN_DIGEST:161:unknown digest EVP_R_UNKNOWN_KEY_TYPE:207:unknown key type +EVP_R_UNKNOWN_MAX_SIZE:167:unknown max size EVP_R_UNKNOWN_OPTION:169:unknown option EVP_R_UNKNOWN_PBE_ALGORITHM:121:unknown pbe algorithm +EVP_R_UNKNOWN_SECURITY_BITS:168:unknown security bits EVP_R_UNSUPPORTED_ALGORITHM:156:unsupported algorithm EVP_R_UNSUPPORTED_CIPHER:107:unsupported cipher EVP_R_UNSUPPORTED_KEYLENGTH:123:unsupported keylength @@ -906,7 +932,8 @@ PEM_R_UNSUPPORTED_CIPHER:113:unsupported cipher PEM_R_UNSUPPORTED_ENCRYPTION:114:unsupported encryption PEM_R_UNSUPPORTED_KEY_COMPONENTS:126:unsupported key components PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE:110:unsupported public key type -PKCS12_R_CANT_PACK_STRUCTURE:100:cant pack structure +PKCS12_R_CALLBACK_FAILED:115:callback failed +PKCS12_R_CANT_PACK_STRUCTURE:100:can't pack structure PKCS12_R_CONTENT_TYPE_NOT_DATA:121:content type not data PKCS12_R_DECODE_ERROR:101:decode error PKCS12_R_ENCODE_ERROR:102:encode error @@ -1011,6 +1038,7 @@ PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ PROV_R_INDICATOR_INTEGRITY_FAILURE:210:indicator integrity failure PROV_R_INSUFFICIENT_DRBG_STRENGTH:181:insufficient drbg strength PROV_R_INVALID_AAD:108:invalid aad +PROV_R_INVALID_AEAD:231:invalid aead PROV_R_INVALID_CONFIG_DATA:211:invalid config data PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length PROV_R_INVALID_CURVE:176:invalid curve @@ -1022,9 +1050,11 @@ PROV_R_INVALID_DIGEST_SIZE:218:invalid digest size PROV_R_INVALID_INPUT_LENGTH:230:invalid input length PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count PROV_R_INVALID_IV_LENGTH:109:invalid iv length +PROV_R_INVALID_KDF:232:invalid kdf PROV_R_INVALID_KEY:158:invalid key PROV_R_INVALID_KEY_LENGTH:105:invalid key length PROV_R_INVALID_MAC:151:invalid mac +PROV_R_INVALID_MEMORY_SIZE:235:invalid memory size PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md PROV_R_INVALID_MODE:125:invalid mode PROV_R_INVALID_OUTPUT_LENGTH:217:invalid output length @@ -1036,6 +1066,7 @@ PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size PROV_R_INVALID_STATE:212:invalid state PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAG_LENGTH:118:invalid tag length +PROV_R_INVALID_THREAD_POOL_SIZE:234:invalid thread pool size PROV_R_INVALID_UKM_LENGTH:200:invalid ukm length PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest PROV_R_IN_ERROR_STATE:192:in error state @@ -1261,8 +1292,10 @@ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\ attempt to reuse session in different context SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE:158:\ at least (D)TLS 1.2 needed in Suite B mode +SSL_R_BAD_CERTIFICATE:348:bad certificate SSL_R_BAD_CHANGE_CIPHER_SPEC:103:bad change cipher spec SSL_R_BAD_CIPHER:186:bad cipher +SSL_R_BAD_COMPRESSION_ALGORITHM:326:bad compression algorithm SSL_R_BAD_DATA:390:bad data SSL_R_BAD_DATA_RETURNED_BY_CALLBACK:106:bad data returned by callback SSL_R_BAD_DECOMPRESSION:107:bad decompression @@ -1319,6 +1352,7 @@ SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE:307:\ compression id not within private range SSL_R_COMPRESSION_LIBRARY_ERROR:142:compression library error SSL_R_CONNECTION_TYPE_NOT_SET:144:connection type not set +SSL_R_CONN_USE_ONLY:356:conn use only SSL_R_CONTEXT_NOT_DANE_ENABLED:167:context not dane enabled SSL_R_COOKIE_GEN_CALLBACK_FAILURE:400:cookie gen callback failure SSL_R_COOKIE_MISMATCH:308:cookie mismatch @@ -1349,6 +1383,7 @@ SSL_R_DUPLICATE_COMPRESSION_ID:309:duplicate compression id SSL_R_ECC_CERT_NOT_FOR_SIGNING:318:ecc cert not for signing SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE:374:ecdh required for suiteb mode SSL_R_EE_KEY_TOO_SMALL:399:ee key too small +SSL_R_EMPTY_RAW_PUBLIC_KEY:349:empty raw public key SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST:354:empty srtp protection profile list SSL_R_ENCRYPTED_LENGTH_TOO_LONG:150:encrypted length too long SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST:151:error in received cipher list @@ -1358,6 +1393,7 @@ SSL_R_EXCESSIVE_MESSAGE_SIZE:152:excessive message size SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch +SSL_R_FAILED_TO_GET_PARAMETER:316:failed to get parameter SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs @@ -1383,6 +1419,8 @@ SSL_R_INVALID_CT_VALIDATION_TYPE:212:invalid ct validation type SSL_R_INVALID_KEY_UPDATE_TYPE:120:invalid key update type SSL_R_INVALID_MAX_EARLY_DATA:174:invalid max early data SSL_R_INVALID_NULL_CMD_NAME:385:invalid null cmd name +SSL_R_INVALID_RAW_PUBLIC_KEY:350:invalid raw public key +SSL_R_INVALID_RECORD:317:invalid record SSL_R_INVALID_SEQUENCE_NUMBER:402:invalid sequence number SSL_R_INVALID_SERVERINFO_DATA:388:invalid serverinfo data SSL_R_INVALID_SESSION_ID:999:invalid session id @@ -1396,6 +1434,7 @@ SSL_R_LENGTH_TOO_LONG:404:length too long SSL_R_LENGTH_TOO_SHORT:160:length too short SSL_R_LIBRARY_BUG:274:library bug SSL_R_LIBRARY_HAS_NO_CIPHERS:161:library has no ciphers +SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED:395:maximum encrypted pkts reached SSL_R_MISSING_DSA_SIGNING_CERT:165:missing dsa signing cert SSL_R_MISSING_ECDSA_SIGNING_CERT:381:missing ecdsa signing cert SSL_R_MISSING_FATAL:256:missing fatal @@ -1438,9 +1477,11 @@ SSL_R_NO_SHARED_CIPHER:193:no shared cipher SSL_R_NO_SHARED_GROUPS:410:no shared groups SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS:376:no shared signature algorithms SSL_R_NO_SRTP_PROFILES:359:no srtp profiles +SSL_R_NO_STREAM:355:no stream SSL_R_NO_SUITABLE_DIGEST_ALGORITHM:297:no suitable digest algorithm SSL_R_NO_SUITABLE_GROUPS:295:no suitable groups SSL_R_NO_SUITABLE_KEY_SHARE:101:no suitable key share +SSL_R_NO_SUITABLE_RECORD_LAYER:322:no suitable record layer SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM:118:no suitable signature algorithm SSL_R_NO_VALID_SCTS:216:no valid scts SSL_R_NO_VERIFY_COOKIE_CALLBACK:403:no verify cookie callback @@ -1464,10 +1505,16 @@ SSL_R_PROTOCOL_IS_SHUTDOWN:207:protocol is shutdown SSL_R_PSK_IDENTITY_NOT_FOUND:223:psk identity not found SSL_R_PSK_NO_CLIENT_CB:224:psk no client cb SSL_R_PSK_NO_SERVER_CB:225:psk no server cb +SSL_R_QUIC_HANDSHAKE_LAYER_ERROR:393:quic handshake layer error +SSL_R_QUIC_NETWORK_ERROR:387:quic network error +SSL_R_QUIC_PROTOCOL_ERROR:382:quic protocol error SSL_R_READ_BIO_NOT_SET:211:read bio not set SSL_R_READ_TIMEOUT_EXPIRED:312:read timeout expired +SSL_R_RECORDS_NOT_RELEASED:321:records not released +SSL_R_RECORD_LAYER_FAILURE:313:record layer failure SSL_R_RECORD_LENGTH_MISMATCH:213:record length mismatch SSL_R_RECORD_TOO_SMALL:298:record too small +SSL_R_REMOTE_PEER_ADDRESS_NOT_SET:346:remote peer address not set SSL_R_RENEGOTIATE_EXT_TOO_LONG:335:renegotiate ext too long SSL_R_RENEGOTIATION_ENCODING_ERR:336:renegotiation encoding err SSL_R_RENEGOTIATION_MISMATCH:337:renegotiation mismatch @@ -1478,6 +1525,7 @@ SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING:342:\ required compression algorithm missing SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:345:scsv received when renegotiating SSL_R_SCT_VERIFICATION_FAILED:208:sct verification failed +SSL_R_SEQUENCE_CTR_WRAPPED:327:sequence ctr wrapped SSL_R_SERVERHELLO_TLSEXT:275:serverhello tlsext SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED:277:session id context uninitialized SSL_R_SHUTDOWN_WHILE_IN_INIT:407:shutdown while in init @@ -1494,6 +1542,18 @@ SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH:232:\ SSL_R_SSL3_EXT_INVALID_SERVERNAME:319:ssl3 ext invalid servername SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE:320:ssl3 ext invalid servername type SSL_R_SSL3_SESSION_ID_TOO_LONG:300:ssl3 session id too long +SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:1042:ssl/tls alert bad certificate +SSL_R_SSLV3_ALERT_BAD_RECORD_MAC:1020:ssl/tls alert bad record mac +SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:1045:ssl/tls alert certificate expired +SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:1044:ssl/tls alert certificate revoked +SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:1046:ssl/tls alert certificate unknown +SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE:1030:ssl/tls alert decompression failure +SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE:1040:ssl/tls alert handshake failure +SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER:1047:ssl/tls alert illegal parameter +SSL_R_SSLV3_ALERT_NO_CERTIFICATE:1041:ssl/tls alert no certificate +SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE:1010:ssl/tls alert unexpected message +SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE:1043:\ + ssl/tls alert unsupported certificate SSL_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty SSL_R_SSL_COMMAND_SECTION_NOT_FOUND:125:ssl command section not found SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION:228:ssl ctx has no default ssl version @@ -1509,6 +1569,32 @@ SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH:303:ssl session id has bad length SSL_R_SSL_SESSION_ID_TOO_LONG:408:ssl session id too long SSL_R_SSL_SESSION_VERSION_MISMATCH:210:ssl session version mismatch SSL_R_STILL_IN_INIT:121:still in init +SSL_R_STREAM_COUNT_LIMITED:411:stream count limited +SSL_R_STREAM_FINISHED:365:stream finished +SSL_R_STREAM_RECV_ONLY:366:stream recv only +SSL_R_STREAM_RESET:375:stream reset +SSL_R_STREAM_SEND_ONLY:379:stream send only +SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED:1116:tlsv13 alert certificate required +SSL_R_TLSV13_ALERT_MISSING_EXTENSION:1109:tlsv13 alert missing extension +SSL_R_TLSV1_ALERT_ACCESS_DENIED:1049:tlsv1 alert access denied +SSL_R_TLSV1_ALERT_DECODE_ERROR:1050:tlsv1 alert decode error +SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:1021:tlsv1 alert decryption failed +SSL_R_TLSV1_ALERT_DECRYPT_ERROR:1051:tlsv1 alert decrypt error +SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION:1060:tlsv1 alert export restriction +SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK:1086:tlsv1 alert inappropriate fallback +SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY:1071:tlsv1 alert insufficient security +SSL_R_TLSV1_ALERT_INTERNAL_ERROR:1080:tlsv1 alert internal error +SSL_R_TLSV1_ALERT_NO_RENEGOTIATION:1100:tlsv1 alert no renegotiation +SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:1070:tlsv1 alert protocol version +SSL_R_TLSV1_ALERT_RECORD_OVERFLOW:1022:tlsv1 alert record overflow +SSL_R_TLSV1_ALERT_UNKNOWN_CA:1048:tlsv1 alert unknown ca +SSL_R_TLSV1_ALERT_USER_CANCELLED:1090:tlsv1 alert user cancelled +SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE:1114:tlsv1 bad certificate hash value +SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE:1113:\ + tlsv1 bad certificate status response +SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE:1111:tlsv1 certificate unobtainable +SSL_R_TLSV1_UNRECOGNIZED_NAME:1112:tlsv1 unrecognized name +SSL_R_TLSV1_UNSUPPORTED_EXTENSION:1110:tlsv1 unsupported extension SSL_R_TLS_ILLEGAL_EXPORTER_LABEL:367:tls illegal exporter label SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST:157:tls invalid ecpointformat list SSL_R_TOO_MANY_KEY_UPDATES:132:too many key updates @@ -1533,6 +1619,7 @@ SSL_R_UNKNOWN_CMD_NAME:386:unknown cmd name SSL_R_UNKNOWN_COMMAND:139:unknown command SSL_R_UNKNOWN_DIGEST:368:unknown digest SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE:250:unknown key exchange type +SSL_R_UNKNOWN_MANDATORY_PARAMETER:323:unknown mandatory parameter SSL_R_UNKNOWN_PKEY_TYPE:251:unknown pkey type SSL_R_UNKNOWN_PROTOCOL:252:unknown protocol SSL_R_UNKNOWN_SSL_VERSION:254:unknown ssl version @@ -1551,6 +1638,7 @@ SSL_R_VERSION_TOO_LOW:396:version too low SSL_R_WRONG_CERTIFICATE_TYPE:383:wrong certificate type SSL_R_WRONG_CIPHER_RETURNED:261:wrong cipher returned SSL_R_WRONG_CURVE:378:wrong curve +SSL_R_WRONG_RPK_TYPE:351:wrong rpk type SSL_R_WRONG_SIGNATURE_LENGTH:264:wrong signature length SSL_R_WRONG_SIGNATURE_SIZE:265:wrong signature size SSL_R_WRONG_SIGNATURE_TYPE:370:wrong signature type @@ -1613,6 +1701,8 @@ UI_R_UNKNOWN_TTYGET_ERRNO_VALUE:108:unknown ttyget errno value UI_R_USER_DATA_DUPLICATION_UNSUPPORTED:112:user data duplication unsupported X509V3_R_BAD_IP_ADDRESS:118:bad ip address X509V3_R_BAD_OBJECT:119:bad object +X509V3_R_BAD_OPTION:170:bad option +X509V3_R_BAD_VALUE:171:bad value X509V3_R_BN_DEC2BN_ERROR:100:bn dec2bn error X509V3_R_BN_TO_ASN1_INTEGER_ERROR:101:bn to asn1 integer error X509V3_R_DIRNAME_ERROR:149:dirname error @@ -1679,6 +1769,7 @@ X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT:111:unknown bit string argument X509V3_R_UNKNOWN_EXTENSION:129:unknown extension X509V3_R_UNKNOWN_EXTENSION_NAME:130:unknown extension name X509V3_R_UNKNOWN_OPTION:120:unknown option +X509V3_R_UNKNOWN_VALUE:172:unknown value X509V3_R_UNSUPPORTED_OPTION:117:unsupported option X509V3_R_UNSUPPORTED_TYPE:167:unsupported type X509V3_R_USER_TOO_LONG:132:user too long @@ -1686,7 +1777,7 @@ X509_R_AKID_MISMATCH:110:akid mismatch X509_R_BAD_SELECTOR:133:bad selector X509_R_BAD_X509_FILETYPE:100:bad x509 filetype X509_R_BASE64_DECODE_ERROR:118:base64 decode error -X509_R_CANT_CHECK_DH_KEY:114:cant check dh key +X509_R_CANT_CHECK_DH_KEY:114:can't check dh key X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table X509_R_CRL_ALREADY_DELTA:127:crl already delta diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c index 65444d383f..0612e68ee6 100644 --- a/crypto/ess/ess_lib.c +++ b/crypto/ess/ess_lib.c @@ -29,28 +29,38 @@ ESS_SIGNING_CERT *OSSL_ESS_signing_cert_new_init(const X509 *signcert, ESS_SIGNING_CERT *sc; int i; - if ((sc = ESS_SIGNING_CERT_new()) == NULL) + if ((sc = ESS_SIGNING_CERT_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; + } if (sc->cert_ids == NULL - && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) + && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } if ((cid = ESS_CERT_ID_new_init(signcert, set_issuer_serial)) == NULL - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; + } for (i = 0; i < sk_X509_num(certs); ++i) { X509 *cert = sk_X509_value(certs, i); - if ((cid = ESS_CERT_ID_new_init(cert, 1)) == NULL - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + if ((cid = ESS_CERT_ID_new_init(cert, 1)) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); + goto err; + } + if (!sk_ESS_CERT_ID_push(sc->cert_ids, cid)) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } } return sc; err: ESS_SIGNING_CERT_free(sc); ESS_CERT_ID_free(cid); - ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); return NULL; } @@ -61,38 +71,53 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(const X509 *cert, GENERAL_NAME *name = NULL; unsigned char cert_sha1[SHA_DIGEST_LENGTH]; - if ((cid = ESS_CERT_ID_new()) == NULL) + if ((cid = ESS_CERT_ID_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; - if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) + } + if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) { + ERR_raise(ERR_LIB_ESS, ERR_R_X509_LIB); goto err; - if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) + } + if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } /* Setting the issuer/serial if requested. */ if (!set_issuer_serial) return cid; if (cid->issuer_serial == NULL - && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) + && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; - if ((name = GENERAL_NAME_new()) == NULL) + } + if ((name = GENERAL_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } name->type = GEN_DIRNAME; - if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) + if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_X509_LIB); goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + } + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } name = NULL; /* Ownership is lost. */ ASN1_INTEGER_free(cid->issuer_serial->serial); - if ((cid->issuer_serial->serial = - ASN1_INTEGER_dup(X509_get0_serialNumber(cert))) == NULL) + if ((cid->issuer_serial->serial + = ASN1_INTEGER_dup(X509_get0_serialNumber(cert))) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } return cid; err: GENERAL_NAME_free(name); ESS_CERT_ID_free(cid); - ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); return NULL; } @@ -106,22 +131,32 @@ ESS_SIGNING_CERT_V2 *OSSL_ESS_signing_cert_v2_new_init(const EVP_MD *hash_alg, ESS_SIGNING_CERT_V2 *sc; int i; - if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL) + if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; + } cid = ESS_CERT_ID_V2_new_init(hash_alg, signcert, set_issuer_serial); - if (cid == NULL) + if (cid == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; - if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) + } + if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } cid = NULL; for (i = 0; i < sk_X509_num(certs); ++i) { X509 *cert = sk_X509_value(certs, i); - if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, cert, 1)) == NULL) + if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, cert, 1)) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; - if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) + } + if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } cid = NULL; } @@ -129,7 +164,6 @@ ESS_SIGNING_CERT_V2 *OSSL_ESS_signing_cert_v2_new_init(const EVP_MD *hash_alg, err: ESS_SIGNING_CERT_V2_free(sc); ESS_CERT_ID_V2_free(cid); - ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); return NULL; } @@ -145,52 +179,71 @@ static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, memset(hash, 0, sizeof(hash)); - if ((cid = ESS_CERT_ID_V2_new()) == NULL) + if ((cid = ESS_CERT_ID_V2_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; + } if (!EVP_MD_is_a(hash_alg, SN_sha256)) { alg = X509_ALGOR_new(); - if (alg == NULL) + if (alg == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } X509_ALGOR_set_md(alg, hash_alg); - if (alg->algorithm == NULL) + if (alg->algorithm == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } cid->hash_alg = alg; alg = NULL; } else { cid->hash_alg = NULL; } - if (!X509_digest(cert, hash_alg, hash, &hash_len)) + if (!X509_digest(cert, hash_alg, hash, &hash_len)) { + ERR_raise(ERR_LIB_ESS, ERR_R_X509_LIB); goto err; + } - if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len)) + if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len)) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } if (!set_issuer_serial) return cid; - if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) + if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ESS_LIB); goto err; - if ((name = GENERAL_NAME_new()) == NULL) + } + if ((name = GENERAL_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } name->type = GEN_DIRNAME; - if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) + if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + } + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) { + ERR_raise(ERR_LIB_ESS, ERR_R_CRYPTO_LIB); goto err; + } name = NULL; /* Ownership is lost. */ ASN1_INTEGER_free(cid->issuer_serial->serial); cid->issuer_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); - if (cid->issuer_serial->serial == NULL) + if (cid->issuer_serial->serial == NULL) { + ERR_raise(ERR_LIB_ESS, ERR_R_ASN1_LIB); goto err; + } return cid; err: X509_ALGOR_free(alg); GENERAL_NAME_free(name); ESS_CERT_ID_V2_free(cid); - ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/evp/asymcipher.c b/crypto/evp/asymcipher.c index b7784c8994..d22ab2a01a 100644 --- a/crypto/evp/asymcipher.c +++ b/crypto/evp/asymcipher.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -189,7 +189,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation, ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } - switch(ctx->operation) { + switch (ctx->operation) { case EVP_PKEY_OP_ENCRYPT: if (ctx->pmeth->encrypt_init == NULL) return 1; @@ -298,25 +298,38 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); } +/* decrypt to new buffer of dynamic size, checking any pre-determined size */ +int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, + size_t *outlenp, size_t expected_outlen, + const unsigned char *in, size_t inlen) +{ + if (EVP_PKEY_decrypt(ctx, NULL, outlenp, in, inlen) <= 0 + || (*outp = OPENSSL_malloc(*outlenp)) == NULL) + return -1; + if (EVP_PKEY_decrypt(ctx, *outp, outlenp, in, inlen) <= 0 + || *outlenp == 0 + || (expected_outlen != 0 && *outlenp != expected_outlen)) { + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); + OPENSSL_clear_free(*outp, *outlenp); + *outp = NULL; + return 0; + } + return 1; +} static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov) { EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER)); - if (cipher == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (cipher == NULL) return NULL; - } - cipher->lock = CRYPTO_THREAD_lock_new(); - if (cipher->lock == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&cipher->refcnt, 1)) { OPENSSL_free(cipher); return NULL; } cipher->prov = prov; ossl_provider_up_ref(prov); - cipher->refcnt = 1; return cipher; } @@ -331,7 +344,7 @@ static void *evp_asym_cipher_from_algorithm(int name_id, int gparamfncnt = 0, sparamfncnt = 0; if ((cipher = evp_asym_cipher_new(prov)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -444,12 +457,12 @@ void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher) if (cipher == NULL) return; - CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + CRYPTO_DOWN_REF(&cipher->refcnt, &i); if (i > 0) return; OPENSSL_free(cipher->type_name); ossl_provider_free(cipher->prov); - CRYPTO_THREAD_lock_free(cipher->lock); + CRYPTO_FREE_REF(&cipher->refcnt); OPENSSL_free(cipher); } @@ -457,7 +470,7 @@ int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher) { int ref = 0; - CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + CRYPTO_UP_REF(&cipher->refcnt, &ref); return 1; } diff --git a/crypto/evp/bio_b64.c b/crypto/evp/bio_b64.c index 81d2609c30..8700315a6b 100644 --- a/crypto/evp/bio_b64.c +++ b/crypto/evp/bio_b64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,8 +39,8 @@ typedef struct b64_struct { int start; /* have we started decoding yet? */ int cont; /* <= 0 when finished */ EVP_ENCODE_CTX *base64; - char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; - char tmp[B64_BLOCK_SIZE]; + unsigned char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; + unsigned char tmp[B64_BLOCK_SIZE]; } BIO_B64_CTX; static const BIO_METHOD methods_b64 = { @@ -58,7 +58,6 @@ static const BIO_METHOD methods_b64 = { b64_callback_ctrl, }; - const BIO_METHOD *BIO_f_base64(void) { return &methods_b64; @@ -68,10 +67,8 @@ static int b64_new(BIO *bi) { BIO_B64_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) return 0; - } ctx->cont = 1; ctx->start = 1; @@ -90,6 +87,7 @@ static int b64_new(BIO *bi) static int b64_free(BIO *a) { BIO_B64_CTX *ctx; + if (a == NULL) return 0; @@ -117,7 +115,7 @@ static int b64_read(BIO *b, char *out, int outl) ctx = (BIO_B64_CTX *)BIO_get_data(b); next = BIO_next(b); - if ((ctx == NULL) || (next == NULL)) + if (ctx == NULL || next == NULL) return 0; BIO_clear_retry_flags(b); @@ -185,11 +183,10 @@ static int b64_read(BIO *b, char *out, int outl) * We need to scan, a line at a time until we have a valid line if we * are starting. */ - if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { - /* ctx->start=1; */ + if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) != 0) { ctx->tmp_len = 0; } else if (ctx->start) { - q = p = (unsigned char *)ctx->tmp; + q = p = ctx->tmp; num = 0; for (j = 0; j < i; j++) { if (*(q++) != '\n') @@ -206,16 +203,12 @@ static int b64_read(BIO *b, char *out, int outl) continue; } - k = EVP_DecodeUpdate(ctx->base64, - (unsigned char *)ctx->buf, - &num, p, q - p); - if ((k <= 0) && (num == 0) && (ctx->start)) + k = EVP_DecodeUpdate(ctx->base64, ctx->buf, &num, p, q - p); + if (k <= 0 && num == 0 && ctx->start) { EVP_DecodeInit(ctx->base64); - else { - if (p != (unsigned char *) - &(ctx->tmp[0])) { - i -= (p - (unsigned char *) - &(ctx->tmp[0])); + } else { + if (p != ctx->tmp) { + i -= p - ctx->tmp; for (x = 0; x < i; x++) ctx->tmp[x] = p[x]; } @@ -227,12 +220,12 @@ static int b64_read(BIO *b, char *out, int outl) } /* we fell off the end without starting */ - if ((j == i) && (num == 0)) { + if (j == i && num == 0) { /* * Is this is one long chunk?, if so, keep on reading until a * new line. */ - if (p == (unsigned char *)&(ctx->tmp[0])) { + if (p == ctx->tmp) { /* Check buffer full */ if (i == B64_BLOCK_SIZE) { ctx->tmp_nl = 1; @@ -249,7 +242,7 @@ static int b64_read(BIO *b, char *out, int outl) } else { ctx->tmp_len = 0; } - } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { + } else if (i < B64_BLOCK_SIZE && ctx->cont > 0) { /* * If buffer isn't full and we can retry then restart to read in * more data. @@ -257,12 +250,11 @@ static int b64_read(BIO *b, char *out, int outl) continue; } - if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if ((BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) != 0) { int z, jj; jj = i & ~3; /* process per 4 */ - z = EVP_DecodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, jj); + z = EVP_DecodeBlock(ctx->buf, ctx->tmp, jj); if (jj > 2) { if (ctx->tmp[jj - 1] == '=') { z--; @@ -283,9 +275,8 @@ static int b64_read(BIO *b, char *out, int outl) } i = z; } else { - i = EVP_DecodeUpdate(ctx->base64, - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)ctx->tmp, i); + i = EVP_DecodeUpdate(ctx->base64, ctx->buf, &ctx->buf_len, + ctx->tmp, i); ctx->tmp_len = 0; } /* @@ -320,7 +311,7 @@ static int b64_read(BIO *b, char *out, int outl) } /* BIO_clear_retry_flags(b); */ BIO_copy_next_retry(b); - return ((ret == 0) ? ret_code : ret); + return ret == 0 ? ret_code : ret; } static int b64_write(BIO *b, const char *in, int inl) @@ -333,7 +324,7 @@ static int b64_write(BIO *b, const char *in, int inl) ctx = (BIO_B64_CTX *)BIO_get_data(b); next = BIO_next(b); - if ((ctx == NULL) || (next == NULL)) + if (ctx == NULL || next == NULL) return 0; BIO_clear_retry_flags(b); @@ -366,13 +357,13 @@ static int b64_write(BIO *b, const char *in, int inl) ctx->buf_off = 0; ctx->buf_len = 0; - if ((in == NULL) || (inl <= 0)) + if (in == NULL || inl <= 0) return 0; while (inl > 0) { - n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; + n = inl > B64_BLOCK_SIZE ? B64_BLOCK_SIZE : inl; - if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if ((BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) != 0) { if (ctx->tmp_len > 0) { OPENSSL_assert(ctx->tmp_len <= 3); n = 3 - ctx->tmp_len; @@ -387,8 +378,7 @@ static int b64_write(BIO *b, const char *in, int inl) if (ctx->tmp_len < 3) break; ctx->buf_len = - EVP_EncodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, ctx->tmp_len); + EVP_EncodeBlock(ctx->buf, ctx->tmp, ctx->tmp_len); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); /* @@ -405,17 +395,15 @@ static int b64_write(BIO *b, const char *in, int inl) } n -= n % 3; ctx->buf_len = - EVP_EncodeBlock((unsigned char *)ctx->buf, - (const unsigned char *)in, n); + EVP_EncodeBlock(ctx->buf, (unsigned char *)in, n); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret += n; } } else { - if (!EVP_EncodeUpdate(ctx->base64, - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)in, n)) - return ((ret == 0) ? -1 : ret); + if (!EVP_EncodeUpdate(ctx->base64, ctx->buf, &ctx->buf_len, + (unsigned char *)in, n)) + return ret == 0 ? -1 : ret; OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret += n; @@ -429,7 +417,7 @@ static int b64_write(BIO *b, const char *in, int inl) i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); if (i <= 0) { BIO_copy_next_retry(b); - return ((ret == 0) ? i : ret); + return ret == 0 ? i : ret; } OPENSSL_assert(i <= n); n -= i; @@ -452,7 +440,7 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) ctx = (BIO_B64_CTX *)BIO_get_data(b); next = BIO_next(b); - if ((ctx == NULL) || (next == NULL)) + if (ctx == NULL || next == NULL) return 0; switch (cmd) { @@ -471,8 +459,8 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_WPENDING: /* More to write in buffer */ OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret = ctx->buf_len - ctx->buf_off; - if ((ret == 0) && (ctx->encode != B64_NONE) - && (EVP_ENCODE_CTX_num(ctx->base64) != 0)) + if (ret == 0 && ctx->encode != B64_NONE + && EVP_ENCODE_CTX_num(ctx->base64) != 0) ret = 1; else if (ret <= 0) ret = BIO_ctrl(next, cmd, num, ptr); @@ -493,9 +481,8 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) } if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { if (ctx->tmp_len != 0) { - ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, - ctx->tmp_len); + ctx->buf_len = EVP_EncodeBlock(ctx->buf, + ctx->tmp, ctx->tmp_len); ctx->buf_off = 0; ctx->tmp_len = 0; goto again; @@ -503,13 +490,13 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) } else if (ctx->encode != B64_NONE && EVP_ENCODE_CTX_num(ctx->base64) != 0) { ctx->buf_off = 0; - EVP_EncodeFinal(ctx->base64, - (unsigned char *)ctx->buf, &(ctx->buf_len)); + EVP_EncodeFinal(ctx->base64, ctx->buf, &(ctx->buf_len)); /* push out the bytes */ goto again; } /* Finally flush the underlying BIO */ ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(b); break; case BIO_C_DO_STATE_MACHINE: diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c index 304030bcb3..ece3f6d57f 100644 --- a/crypto/evp/bio_enc.c +++ b/crypto/evp/bio_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -65,10 +65,8 @@ static int enc_new(BIO *bi) { BIO_ENC_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) return 0; - } ctx->cipher = EVP_CIPHER_CTX_new(); if (ctx->cipher == NULL) { @@ -362,6 +360,7 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) /* Finally flush the underlying BIO */ ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(b); break; case BIO_C_GET_CIPHER_STATUS: ret = (long)ctx->ok; diff --git a/crypto/evp/bio_ok.c b/crypto/evp/bio_ok.c index 97e67fcb68..2aa1ed7558 100644 --- a/crypto/evp/bio_ok.c +++ b/crypto/evp/bio_ok.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -132,10 +132,8 @@ static int ok_new(BIO *bi) { BIO_OK_CTX *ctx; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) return 0; - } ctx->cont = 1; ctx->sigio = 1; @@ -374,6 +372,7 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) /* Finally flush the underlying BIO */ ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(b); break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index d556b5ab28..c74b3dcd75 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -149,6 +149,7 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aes_128_wrap()); EVP_add_cipher_alias(SN_id_aes128_wrap, "aes128-wrap"); EVP_add_cipher(EVP_aes_128_wrap_pad()); + EVP_add_cipher_alias(SN_id_aes128_wrap_pad, "aes128-wrap-pad"); EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); EVP_add_cipher(EVP_aes_192_ecb()); @@ -166,6 +167,7 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aes_192_wrap()); EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap"); EVP_add_cipher(EVP_aes_192_wrap_pad()); + EVP_add_cipher_alias(SN_id_aes192_wrap_pad, "aes192-wrap-pad"); EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); EVP_add_cipher(EVP_aes_256_ecb()); @@ -184,6 +186,7 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aes_256_wrap()); EVP_add_cipher_alias(SN_id_aes256_wrap, "aes256-wrap"); EVP_add_cipher(EVP_aes_256_wrap_pad()); + EVP_add_cipher_alias(SN_id_aes256_wrap_pad, "aes256-wrap-pad"); EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); diff --git a/crypto/evp/cmeth_lib.c b/crypto/evp/cmeth_lib.c index a806ec5f9e..41a1bade2c 100644 --- a/crypto/evp/cmeth_lib.c +++ b/crypto/evp/cmeth_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -46,10 +46,10 @@ EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size, cipher->key_len)) != NULL) { - CRYPTO_RWLOCK *lock = to->lock; + CRYPTO_REF_COUNT refcnt = to->refcnt; memcpy(to, cipher, sizeof(*to)); - to->lock = lock; + to->refcnt = refcnt; to->origin = EVP_ORIG_METH; } return to; diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c index 80947b0932..54e589054c 100644 --- a/crypto/evp/ctrl_params_translate.c +++ b/crypto/evp/ctrl_params_translate.c @@ -458,11 +458,9 @@ static int default_fixup_args(enum state state, if (ctx->p2 != NULL) { if (ctx->action_type == SET) { ctx->buflen = BN_num_bytes(ctx->p2); - if ((ctx->allocated_buf = - OPENSSL_malloc(ctx->buflen)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((ctx->allocated_buf + = OPENSSL_malloc(ctx->buflen)) == NULL) return 0; - } if (BN_bn2nativepad(ctx->p2, ctx->allocated_buf, ctx->buflen) < 0) { OPENSSL_free(ctx->allocated_buf); @@ -784,7 +782,7 @@ static int fix_cipher_md(enum state state, if (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) { /* - * Here's how we re-use |ctx->orig_p2| that was set in the + * Here's how we reuse |ctx->orig_p2| that was set in the * PRE_CTRL_TO_PARAMS state above. */ *(void **)ctx->orig_p2 = @@ -1660,6 +1658,64 @@ static int get_payload_public_key(enum state state, return ret; } +static int get_payload_public_key_ec(enum state state, + const struct translation_st *translation, + struct translation_ctx_st *ctx) +{ +#ifndef OPENSSL_NO_EC + EVP_PKEY *pkey = ctx->p2; + const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); + BN_CTX *bnctx; + const EC_POINT *point; + const EC_GROUP *ecg; + BIGNUM *x = NULL; + BIGNUM *y = NULL; + int ret = 0; + + ctx->p2 = NULL; + + if (eckey == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + + bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey)); + if (bnctx == NULL) + return 0; + + point = EC_KEY_get0_public_key(eckey); + ecg = EC_KEY_get0_group(eckey); + + /* Caller should have requested a BN, fail if not */ + if (ctx->params->data_type != OSSL_PARAM_UNSIGNED_INTEGER) + goto out; + + x = BN_CTX_get(bnctx); + y = BN_CTX_get(bnctx); + if (y == NULL) + goto out; + + if (!EC_POINT_get_affine_coordinates(ecg, point, x, y, bnctx)) + goto out; + + if (strncmp(ctx->params->key, OSSL_PKEY_PARAM_EC_PUB_X, 2) == 0) + ctx->p2 = x; + else if (strncmp(ctx->params->key, OSSL_PKEY_PARAM_EC_PUB_Y, 2) == 0) + ctx->p2 = y; + else + goto out; + + /* Return the payload */ + ret = default_fixup_args(state, translation, ctx); +out: + BN_CTX_free(bnctx); + return ret; +#else + ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE); + return 0; +#endif +} + static int get_payload_bn(enum state state, const struct translation_st *translation, struct translation_ctx_st *ctx, const BIGNUM *bn) @@ -2265,6 +2321,12 @@ static const struct translation_st evp_pkey_ctx_translations[] = { EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, NULL, NULL, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, NULL }, + { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_IMPLICIT_REJECTION, NULL, + "rsa_pkcs1_implicit_rejection", + OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, OSSL_PARAM_UNSIGNED_INTEGER, + NULL }, + { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN, EVP_PKEY_CTRL_MD, "rsa_pss_keygen_md", NULL, OSSL_ALG_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md }, @@ -2396,6 +2458,12 @@ static const struct translation_st evp_pkey_translations[] = { OSSL_PKEY_PARAM_PUB_KEY, 0 /* no data type, let get_payload_public_key() handle that */, get_payload_public_key }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_EC_PUB_X, OSSL_PARAM_UNSIGNED_INTEGER, + get_payload_public_key_ec }, + { GET, -1, -1, -1, 0, NULL, NULL, + OSSL_PKEY_PARAM_EC_PUB_Y, OSSL_PARAM_UNSIGNED_INTEGER, + get_payload_public_key_ec }, /* DH and DSA */ { GET, -1, -1, -1, 0, NULL, NULL, diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 28efbddb47..42331703da 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -110,7 +110,7 @@ EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, if ((ctx = EVP_MD_CTX_new()) == NULL || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } @@ -181,7 +181,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, } #endif - EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED + | EVP_MD_CTX_FLAG_FINALISED); if (type != NULL) { ctx->reqdigest = type; @@ -236,7 +237,6 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, /* If we were using provided hash before, cleanup algctx */ if (!evp_md_ctx_free_algctx(ctx)) return 0; - if (ctx->digest == ctx->fetched_digest) ctx->digest = NULL; EVP_MD_free(ctx->fetched_digest); @@ -343,10 +343,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type, if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { ctx->update = type->update; ctx->md_data = OPENSSL_zalloc(type->ctx_size); - if (ctx->md_data == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ctx->md_data == NULL) return 0; - } } } #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) @@ -390,6 +388,11 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) if (count == 0) return 1; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + if (ctx->pctx != NULL && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) && ctx->pctx->op.sig.algctx != NULL) { @@ -451,13 +454,29 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) if (ctx->digest->prov == NULL) goto legacy; + if (ctx->digest->gettable_ctx_params != NULL) { + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, + &mdsize); + if (!EVP_MD_CTX_get_params(ctx, params)) + return 0; + } + if (ctx->digest->dfinal == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); return 0; } + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + ret = ctx->digest->dfinal(ctx->algctx, md, &size, mdsize); + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + if (isize != NULL) { if (size <= UINT_MAX) { *isize = (unsigned int)size; @@ -502,12 +521,19 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size) return 0; } + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size); params[i++] = OSSL_PARAM_construct_end(); if (EVP_MD_CTX_set_params(ctx, params) > 0) ret = ctx->digest->dfinal(ctx->algctx, md, &size, size); + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + return ret; legacy: @@ -641,10 +667,8 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) out->md_data = tmp_buf; else { out->md_data = OPENSSL_malloc(out->digest->ctx_size); - if (out->md_data == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (out->md_data == NULL) return 0; - } } memcpy(out->md_data, in->md_data, out->digest->ctx_size); } @@ -886,13 +910,9 @@ EVP_MD *evp_md_new(void) { EVP_MD *md = OPENSSL_zalloc(sizeof(*md)); - if (md != NULL) { - md->lock = CRYPTO_THREAD_lock_new(); - if (md->lock == NULL) { - OPENSSL_free(md); - return NULL; - } - md->refcnt = 1; + if (md != NULL && !CRYPTO_NEW_REF(&md->refcnt, 1)) { + OPENSSL_free(md); + return NULL; } return md; } @@ -965,7 +985,7 @@ static void *evp_md_from_algorithm(int name_id, /* EVP_MD_fetch() will set the legacy NID if available */ if ((md = evp_md_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } @@ -1105,7 +1125,7 @@ int EVP_MD_up_ref(EVP_MD *md) int ref = 0; if (md->origin == EVP_ORIG_DYNAMIC) - CRYPTO_UP_REF(&md->refcnt, &ref, md->lock); + CRYPTO_UP_REF(&md->refcnt, &ref); return 1; } @@ -1116,7 +1136,7 @@ void EVP_MD_free(EVP_MD *md) if (md == NULL || md->origin != EVP_ORIG_DYNAMIC) return; - CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock); + CRYPTO_DOWN_REF(&md->refcnt, &i); if (i > 0) return; evp_md_free_int(md); diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 1ac3e60c56..450ebe8a0d 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -1475,10 +1475,8 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); - if ((gctx->iv = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx->iv = OPENSSL_malloc(len)) == NULL) return 0; - } } /* Add padding. */ memset(gctx->iv + arg, 0, len - arg - 8); @@ -1594,10 +1592,8 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) } else { len = S390X_gcm_ivpadlen(gctx->ivlen); - if ((gctx_out->iv = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx_out->iv = OPENSSL_malloc(len)) == NULL) return 0; - } memcpy(gctx_out->iv, gctx->iv, len); } @@ -1675,7 +1671,7 @@ static int s390x_aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * communication to fail after 2^64 - 1 keys. We do this on the encrypting * side only. */ - if (ctx->encrypt && ++gctx->tls_enc_records == 0) { + if (enc && ++gctx->tls_enc_records == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS); goto err; } @@ -2249,7 +2245,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (!enc || !cctx->aes.ccm.tag_set) return 0; - if(arg < cctx->aes.ccm.m) + if (arg < cctx->aes.ccm.m) return 0; memcpy(ptr, cctx->aes.ccm.kmac_param.icv.b, cctx->aes.ccm.m); @@ -2682,10 +2678,8 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); - if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) return 0; - } } gctx->ivlen = arg; return 1; @@ -2784,10 +2778,8 @@ 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 { - if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) return 0; - } memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); } return 1; @@ -2903,7 +2895,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * communication to fail after 2^64 - 1 keys. We do this on the encrypting * side only. */ - if (ctx->encrypt && ++gctx->tls_enc_records == 0) { + if (EVP_CIPHER_CTX_is_encrypting(ctx) && ++gctx->tls_enc_records == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS); goto err; } @@ -2912,18 +2904,20 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * Set IV from start of buffer or generate IV and write to start of * buffer. */ - if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? EVP_CTRL_GCM_IV_GEN - : EVP_CTRL_GCM_SET_IV_INV, + if (EVP_CIPHER_CTX_ctrl(ctx, + EVP_CIPHER_CTX_is_encrypting(ctx) ? + EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; /* Use saved AAD */ - if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) + if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), + gctx->tls_aad_len)) goto err; /* Fix buffer and length to point to payload */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - if (ctx->encrypt) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { /* Encrypt payload */ if (gctx->ctr) { size_t bulk = 0; @@ -3002,9 +2996,11 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, goto err; } /* Retrieve tag */ - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); + CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), + EVP_GCM_TLS_TAG_LEN); /* If tag mismatch wipe buffer */ - if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { + if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len, + EVP_GCM_TLS_TAG_LEN)) { OPENSSL_cleanse(out, len); goto err; } @@ -3061,7 +3057,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * where setting the IV externally is the only option available. */ if (!gctx->iv_set) { - if (!ctx->encrypt || !aes_gcm_iv_generate(gctx, 0)) + if (!EVP_CIPHER_CTX_is_encrypting(ctx) || !aes_gcm_iv_generate(gctx, 0)) return -1; CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; @@ -3076,7 +3072,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) return -1; - } else if (ctx->encrypt) { + } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) { if (gctx->ctr) { size_t bulk = 0; #if defined(AES_GCM_ASM) @@ -3167,15 +3163,17 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } return len; } else { - if (!ctx->encrypt) { + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (gctx->taglen < 0) return -1; - if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) + if (CRYPTO_gcm128_finish(&gctx->gcm, + EVP_CIPHER_CTX_buf_noconst(ctx), + gctx->taglen) != 0) return -1; gctx->iv_set = 0; return 0; } - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16); gctx->taglen = 16; /* Don't reuse the IV */ gctx->iv_set = 0; diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index 059dd1e5a6..5a894fbb9b 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -73,7 +73,7 @@ static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, EVP_CIPHER_CTX_get_cipher_data(ctx)); if (ret < 0) { - ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } return 1; @@ -216,7 +216,7 @@ static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int ret; - EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); if (!iv && !key) return 1; @@ -227,7 +227,7 @@ static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) ossl_aria_encrypt); if (ret < 0) { - ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } @@ -255,7 +255,7 @@ static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { - EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,c); + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, c); switch (type) { case EVP_CTRL_INIT: @@ -279,10 +279,8 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); - if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) return 0; - } } gctx->ivlen = arg; return 1; @@ -375,7 +373,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_COPY: { EVP_CIPHER_CTX *out = ptr; - EVP_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX,out); + EVP_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX, out); if (gctx->gcm.key) { if (gctx->gcm.key != &gctx->ks) return 0; @@ -384,10 +382,8 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv == c->iv) gctx_out->iv = out->iv; else { - if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) return 0; - } memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); } return 1; @@ -402,7 +398,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); int rv = -1; /* Encrypt/decrypt must be performed in place */ @@ -458,7 +454,7 @@ static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); /* If not set up, return error */ if (!gctx->key_set) @@ -513,7 +509,7 @@ static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int ret; - EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx); if (!iv && !key) return 1; @@ -525,7 +521,7 @@ static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, &cctx->ks, (block128_f) ossl_aria_encrypt); if (ret < 0) { - ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); + ERR_raise(ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED); return 0; } cctx->str = NULL; @@ -540,7 +536,7 @@ static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { - EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,c); + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, c); switch (type) { case EVP_CTRL_INIT: @@ -624,7 +620,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_COPY: { EVP_CIPHER_CTX *out = ptr; - EVP_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX,out); + EVP_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX, out); if (cctx->ccm.key) { if (cctx->ccm.key != &cctx->ks) return 0; @@ -641,7 +637,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx); CCM128_CONTEXT *ccm = &cctx->ccm; /* Encrypt/decrypt must be performed in place */ @@ -689,7 +685,7 @@ static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX, ctx); CCM128_CONTEXT *ccm = &cctx->ccm; /* If not set up, return error */ @@ -765,10 +761,10 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \ | EVP_CIPH_CUSTOM_IV_LENGTH) -#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +#define BLOCK_CIPHER_aead(keylen,mode,MODE) \ static const EVP_CIPHER aria_##keylen##_##mode = { \ - nid##_##keylen##_##nmode, \ - blocksize, keylen/8, ivlen, \ + NID_aria_##keylen##_##mode, \ + 1, keylen/8, 12, \ ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \ EVP_ORIG_GLOBAL, \ aria_##mode##_init_key, \ @@ -779,12 +775,12 @@ static const EVP_CIPHER aria_##keylen##_##mode = { \ const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \ { return (EVP_CIPHER*)&aria_##keylen##_##mode; } -BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, gcm, gcm, GCM, 0) -BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, gcm, gcm, GCM, 0) -BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, gcm, gcm, GCM, 0) +BLOCK_CIPHER_aead(128, gcm, GCM) +BLOCK_CIPHER_aead(192, gcm, GCM) +BLOCK_CIPHER_aead(256, gcm, GCM) -BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, ccm, ccm, CCM, 0) -BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, ccm, ccm, CCM, 0) -BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, ccm, ccm, CCM, 0) +BLOCK_CIPHER_aead(128, ccm, CCM) +BLOCK_CIPHER_aead(192, ccm, CCM) +BLOCK_CIPHER_aead(256, ccm, CCM) #endif diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c index 4f1f4822dc..cb69516bde 100644 --- a/crypto/evp/e_camellia.c +++ b/crypto/evp/e_camellia.c @@ -193,7 +193,7 @@ static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { int ret, mode; - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); ret = Camellia_set_key(key, EVP_CIPHER_CTX_get_key_length(ctx) * 8, &dat->ks); @@ -220,7 +220,7 @@ static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); if (dat->stream.cbc) (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, @@ -238,7 +238,7 @@ static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { size_t bl = EVP_CIPHER_CTX_get_block_size(ctx); size_t i; - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); if (len < bl) return 1; @@ -252,7 +252,7 @@ static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, dat->block); @@ -263,7 +263,7 @@ static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, @@ -275,7 +275,7 @@ static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); int num = EVP_CIPHER_CTX_get_num(ctx); CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &num, @@ -287,7 +287,7 @@ static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) { int num = EVP_CIPHER_CTX_get_num(ctx); @@ -326,7 +326,7 @@ static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { int snum = EVP_CIPHER_CTX_get_num(ctx); unsigned int num; - EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); + EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY, ctx); if (snum < 0) return 0; diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c index 18e1c0b5ac..731c1a1dc7 100644 --- a/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/evp/e_chacha20_poly1305.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -55,7 +55,7 @@ static int chacha_init_key(EVP_CIPHER_CTX *ctx, return 1; } -static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, +static int chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *inp, size_t len) { EVP_CHACHA_KEY *key = data(ctx); @@ -239,7 +239,7 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, actx->len.text = plen; if (plen) { - if (ctx->encrypt) + if (EVP_CIPHER_CTX_is_encrypting(ctx)) ctr = xor128_encrypt_n_pad(out, in, ctr, plen); else ctr = xor128_decrypt_n_pad(out, in, ctr, plen); @@ -263,7 +263,7 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; actx->len.text = plen; - if (ctx->encrypt) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { for (i = 0; i < plen; i++) { out[i] = ctr[i] ^= in[i]; } @@ -297,7 +297,7 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; actx->len.text = plen; - if (ctx->encrypt) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter); Poly1305_Update(POLY1305_ctx(actx), out, plen); } else { @@ -340,12 +340,12 @@ static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len); OPENSSL_cleanse(buf, buf_len); - Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag - : tohash); + Poly1305_Final(POLY1305_ctx(actx), + EVP_CIPHER_CTX_is_encrypting(ctx) ? actx->tag : tohash); actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - if (ctx->encrypt) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { memcpy(out, actx->tag, POLY1305_BLOCK_SIZE); } else { if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) { @@ -408,7 +408,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, else if (len != plen + POLY1305_BLOCK_SIZE) return -1; - if (ctx->encrypt) { /* plaintext */ + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { /* plaintext */ chacha_cipher(ctx, out, in, plen); Poly1305_Update(POLY1305_ctx(actx), out, plen); in += plen; @@ -463,12 +463,12 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE); } - Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag - : temp); + Poly1305_Final(POLY1305_ctx(actx), + EVP_CIPHER_CTX_is_encrypting(ctx) ? actx->tag : temp); actx->mac_inited = 0; if (in != NULL && len != plen) { /* tls mode */ - if (ctx->encrypt) { + if (EVP_CIPHER_CTX_is_encrypting(ctx)) { memcpy(out, actx->tag, POLY1305_BLOCK_SIZE); } else { if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) { @@ -477,7 +477,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } } } - else if (!ctx->encrypt) { + else if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len)) return -1; } @@ -498,7 +498,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, { EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - switch(type) { + switch (type) { case EVP_CTRL_INIT: if (actx == NULL) actx = ctx->cipher_data @@ -561,7 +561,8 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, return 1; case EVP_CTRL_AEAD_GET_TAG: - if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !ctx->encrypt) + if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || + !EVP_CIPHER_CTX_is_encrypting(ctx)) return 0; memcpy(ptr, actx->tag, arg); return 1; @@ -577,7 +578,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 | aad[EVP_AEAD_TLS1_AAD_LEN - 1]; aad = actx->tls_aad; - if (!ctx->encrypt) { + if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { if (len < POLY1305_BLOCK_SIZE) return 0; len -= POLY1305_BLOCK_SIZE; /* discount attached tag */ diff --git a/crypto/evp/e_des.c b/crypto/evp/e_des.c index cd6e5af8d0..6eb49c0339 100644 --- a/crypto/evp/e_des.c +++ b/crypto/evp/e_des.c @@ -149,7 +149,8 @@ static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t n, chunk = EVP_MAXCHUNK / 8; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; /* Appease Coverity */ if (inl < chunk) chunk = inl; diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 1e15918344..c0bc7fdd8f 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -165,7 +165,8 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t n; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; /* Appease Coverity */ if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) inl *= 8; diff --git a/crypto/evp/e_idea.c b/crypto/evp/e_idea.c index 4a4df4b925..93da93823d 100644 --- a/crypto/evp/e_idea.c +++ b/crypto/evp/e_idea.c @@ -42,7 +42,7 @@ static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { BLOCK_CIPHER_ecb_loop() - IDEA_ecb_encrypt(in + i, out + i, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks); + IDEA_ecb_encrypt(in + i, out + i, &EVP_C_DATA(EVP_IDEA_KEY, ctx)->ks); return 1; } @@ -64,12 +64,12 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, enc = 1; } if (enc) - IDEA_set_encrypt_key(key, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks); + IDEA_set_encrypt_key(key, &EVP_C_DATA(EVP_IDEA_KEY, ctx)->ks); else { IDEA_KEY_SCHEDULE tmp; IDEA_set_encrypt_key(key, &tmp); - IDEA_set_decrypt_key(&tmp, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks); + IDEA_set_decrypt_key(&tmp, &EVP_C_DATA(EVP_IDEA_KEY, ctx)->ks); OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE)); } return 1; diff --git a/crypto/evp/e_seed.c b/crypto/evp/e_seed.c index 98c7385f61..65ddb57335 100644 --- a/crypto/evp/e_seed.c +++ b/crypto/evp/e_seed.c @@ -36,6 +36,6 @@ IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - SEED_set_key(key, &EVP_C_DATA(EVP_SEED_KEY,ctx)->ks); + SEED_set_key(key, &EVP_C_DATA(EVP_SEED_KEY, ctx)->ks); return 1; } diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 2b8b9f4b6f..e9faf31057 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -24,9 +24,12 @@ #include "internal/cryptlib.h" #include "internal/provider.h" #include "internal/core.h" +#include "internal/safe_math.h" #include "crypto/evp.h" #include "evp_local.h" +OSSL_SAFE_MATH_SIGNED(int, int) + int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { if (ctx == NULL) @@ -208,6 +211,8 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, return 0; } EVP_CIPHER_free(ctx->fetched_cipher); + /* Coverity false positive, the reference counting is confusing it */ + /* coverity[use_after_free] */ ctx->fetched_cipher = (EVP_CIPHER *)cipher; } ctx->cipher = cipher; @@ -349,7 +354,6 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size); if (ctx->cipher_data == NULL) { ctx->cipher = NULL; - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -567,7 +571,7 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx, int i, j, bl, cmpl = inl; if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) - cmpl = (cmpl + 7) / 8; + cmpl = safe_div_round_up_int(cmpl, 8, NULL); bl = ctx->cipher->block_size; @@ -658,7 +662,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, size_t soutl, inl_ = (size_t)inl; int blocksize; - if (outl != NULL) { + if (likely(outl != NULL)) { *outl = 0; } else { ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); @@ -666,22 +670,22 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } /* Prevent accidental use of decryption context when encrypting */ - if (!ctx->encrypt) { + if (unlikely(!ctx->encrypt)) { ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return 0; } - if (ctx->cipher == NULL) { + if (unlikely(ctx->cipher == NULL)) { ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); return 0; } - if (ctx->cipher->prov == NULL) + if (unlikely(ctx->cipher->prov == NULL)) goto legacy; blocksize = ctx->cipher->block_size; - if (ctx->cipher->cupdate == NULL || blocksize < 1) { + if (unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) { ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); return 0; } @@ -690,7 +694,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), in, inl_); - if (ret) { + if (likely(ret)) { if (soutl > INT_MAX) { ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); return 0; @@ -807,7 +811,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, size_t soutl, inl_ = (size_t)inl; int blocksize; - if (outl != NULL) { + if (likely(outl != NULL)) { *outl = 0; } else { ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); @@ -815,21 +819,21 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } /* Prevent accidental use of encryption context when decrypting */ - if (ctx->encrypt) { + if (unlikely(ctx->encrypt)) { ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return 0; } - if (ctx->cipher == NULL) { + if (unlikely(ctx->cipher == NULL)) { ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); return 0; } - if (ctx->cipher->prov == NULL) + if (unlikely(ctx->cipher->prov == NULL)) goto legacy; blocksize = EVP_CIPHER_CTX_get_block_size(ctx); - if (ctx->cipher->cupdate == NULL || blocksize < 1) { + if (unlikely(ctx->cipher->cupdate == NULL || blocksize < 1)) { ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); return 0; } @@ -837,7 +841,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, inl_ + (size_t)(blocksize == 1 ? 0 : blocksize), in, inl_); - if (ret) { + if (likely(ret)) { if (soutl > INT_MAX) { ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); return 0; @@ -853,7 +857,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, b = ctx->cipher->block_size; if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) - cmpl = (cmpl + 7) / 8; + cmpl = safe_div_round_up_int(cmpl, 8, NULL); if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { if (b == 1 && ossl_is_partially_overlapping(out, in, cmpl)) { @@ -1502,7 +1506,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 == NULL) { out->cipher = NULL; - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return 0; } memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); @@ -1521,13 +1524,9 @@ EVP_CIPHER *evp_cipher_new(void) { EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER)); - if (cipher != NULL) { - cipher->lock = CRYPTO_THREAD_lock_new(); - if (cipher->lock == NULL) { - OPENSSL_free(cipher); - return NULL; - } - cipher->refcnt = 1; + if (cipher != NULL && !CRYPTO_NEW_REF(&cipher->refcnt, 1)) { + OPENSSL_free(cipher); + return NULL; } return cipher; } @@ -1572,7 +1571,7 @@ static void *evp_cipher_from_algorithm(const int name_id, int fnciphcnt = 0, fnctxcnt = 0; if ((cipher = evp_cipher_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } @@ -1727,7 +1726,7 @@ int EVP_CIPHER_up_ref(EVP_CIPHER *cipher) int ref = 0; if (cipher->origin == EVP_ORIG_DYNAMIC) - CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + CRYPTO_UP_REF(&cipher->refcnt, &ref); return 1; } @@ -1735,7 +1734,7 @@ void evp_cipher_free_int(EVP_CIPHER *cipher) { OPENSSL_free(cipher->type_name); ossl_provider_free(cipher->prov); - CRYPTO_THREAD_lock_free(cipher->lock); + CRYPTO_FREE_REF(&cipher->refcnt); OPENSSL_free(cipher); } @@ -1746,7 +1745,7 @@ void EVP_CIPHER_free(EVP_CIPHER *cipher) if (cipher == NULL || cipher->origin != EVP_ORIG_DYNAMIC) return; - CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + CRYPTO_DOWN_REF(&cipher->refcnt, &i); if (i > 0) return; evp_cipher_free_int(cipher); diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index c0d9232103..42dd7e4009 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -160,12 +160,16 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "unable to lock context"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_SET_CALLBACKS), "unable to set callbacks"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_BITS), "unknown bits"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_KEY_TYPE), "unknown key type"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MAX_SIZE), "unknown max size"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_SECURITY_BITS), + "unknown security bits"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 4908f6cfee..c643ae8f9a 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,7 @@ #include "internal/core.h" #include "internal/provider.h" #include "internal/namemap.h" +#include "crypto/decoder.h" #include "crypto/evp.h" /* evp_local.h needs it */ #include "evp_local.h" @@ -422,6 +423,7 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx, OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); if (plp != NULL && store != NULL) { + int ret; #ifndef FIPS_MODULE char *propstr = NULL; size_t strsz; @@ -455,8 +457,12 @@ static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx, #endif ossl_property_free(*plp); *plp = def_prop; - if (store != NULL) - return ossl_method_store_cache_flush_all(store); + + ret = ossl_method_store_cache_flush_all(store); +#ifndef FIPS_MODULE + ossl_decoder_cache_flush(libctx); +#endif + return ret; } ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); return 0; @@ -500,7 +506,7 @@ static int evp_default_properties_merge(OSSL_LIB_CTX *libctx, const char *propq, pl2 = ossl_property_merge(pl1, *plp); ossl_property_free(pl1); if (pl2 == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); return 0; } if (!evp_set_parsed_default_properties(libctx, pl2, 0, 0)) { @@ -552,10 +558,8 @@ char *evp_get_global_properties_str(OSSL_LIB_CTX *libctx, int loadconfig) } propstr = OPENSSL_malloc(sz); - if (propstr == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (propstr == NULL) return NULL; - } if (ossl_property_list_to_string(libctx, *plp, propstr, sz) == 0) { ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); OPENSSL_free(propstr); diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 5dec2dffd9..f29d592e0f 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -852,10 +852,10 @@ EVP_MD *EVP_MD_meth_dup(const EVP_MD *md) return NULL; if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) != NULL) { - CRYPTO_RWLOCK *lock = to->lock; + CRYPTO_REF_COUNT refcnt = to->refcnt; memcpy(to, md, sizeof(*to)); - to->lock = lock; + to->refcnt = refcnt; to->origin = EVP_ORIG_METH; } return to; @@ -865,7 +865,7 @@ void evp_md_free_int(EVP_MD *md) { OPENSSL_free(md->type_name); ossl_provider_free(md->prov); - CRYPTO_THREAD_lock_free(md->lock); + CRYPTO_FREE_REF(&md->refcnt); OPENSSL_free(md); } diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index a853174452..9e4059d703 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -99,7 +99,6 @@ struct evp_keymgmt_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; @@ -128,8 +127,10 @@ struct evp_keymgmt_st { /* Import and export routines */ OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; + OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; + OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; OSSL_FUNC_keymgmt_dup_fn *dup; } /* EVP_KEYMGMT */ ; @@ -139,7 +140,6 @@ struct evp_keyexch_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_keyexch_newctx_fn *newctx; OSSL_FUNC_keyexch_init_fn *init; @@ -159,7 +159,6 @@ struct evp_signature_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; @@ -194,7 +193,6 @@ struct evp_asym_cipher_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_asym_cipher_newctx_fn *newctx; OSSL_FUNC_asym_cipher_encrypt_init_fn *encrypt_init; @@ -215,7 +213,6 @@ struct evp_kem_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_kem_newctx_fn *newctx; OSSL_FUNC_kem_encapsulate_init_fn *encapsulate_init; @@ -228,6 +225,8 @@ struct evp_kem_st { OSSL_FUNC_kem_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_kem_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_kem_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_kem_auth_encapsulate_init_fn *auth_encapsulate_init; + OSSL_FUNC_kem_auth_decapsulate_init_fn *auth_decapsulate_init; } /* EVP_KEM */; int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index f6df38a7bc..9153ecfaab 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -83,6 +83,9 @@ static const EVP_PBE_CTL builtin_pbe[] = { {EVP_PBE_TYPE_PRF, NID_hmac_sha3_512, -1, NID_sha3_512, 0}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_224, -1, NID_sha512_224, 0}, {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_256, -1, NID_sha512_256, 0}, +#ifndef OPENSSL_NO_SM3 + {EVP_PBE_TYPE_PRF, NID_hmacWithSM3, -1, NID_sm3, 0}, +#endif {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen, &PKCS5_v2_PBKDF2_keyivgen_ex}, #ifndef OPENSSL_NO_SCRYPT {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen, &PKCS5_v2_scrypt_keyivgen_ex} @@ -196,12 +199,14 @@ static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, EVP_PBE_KEYGEN *keygen) { - EVP_PBE_CTL *pbe_tmp; + EVP_PBE_CTL *pbe_tmp = NULL; if (pbe_algs == NULL) { pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); - if (pbe_algs == NULL) + if (pbe_algs == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); goto err; + } } if ((pbe_tmp = OPENSSL_zalloc(sizeof(*pbe_tmp))) == NULL) @@ -214,13 +219,13 @@ int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, pbe_tmp->keygen = keygen; if (!sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp)) { - OPENSSL_free(pbe_tmp); + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); goto err; } return 1; err: - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(pbe_tmp); return 0; } @@ -254,6 +259,8 @@ int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid, pbelu.pbe_nid = pbe_nid; if (pbe_algs != NULL) { + /* Ideally, this would be done under lock */ + sk_EVP_PBE_CTL_sort(pbe_algs); i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); } diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c index 21e906267e..a4505a9d03 100644 --- a/crypto/evp/evp_pkey.c +++ b/crypto/evp/evp_pkey.c @@ -33,7 +33,7 @@ EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *lib return NULL; if ((pkey = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } @@ -151,7 +151,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) } else { p8 = PKCS8_PRIV_KEY_INFO_new(); if (p8 == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_ASN1_LIB); return NULL; } diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index 89d41312b5..50334042a9 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -27,7 +27,6 @@ struct evp_rand_st { char *type_name; const char *description; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *refcnt_lock; const OSSL_DISPATCH *dispatch; OSSL_FUNC_rand_newctx_fn *newctx; @@ -57,7 +56,7 @@ static int evp_rand_up_ref(void *vrand) int ref = 0; if (rand != NULL) - return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock); + return CRYPTO_UP_REF(&rand->refcnt, &ref); return 1; } @@ -68,12 +67,12 @@ static void evp_rand_free(void *vrand) if (rand == NULL) return; - CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock); + CRYPTO_DOWN_REF(&rand->refcnt, &ref); if (ref > 0) return; OPENSSL_free(rand->type_name); ossl_provider_free(rand->prov); - CRYPTO_THREAD_lock_free(rand->refcnt_lock); + CRYPTO_FREE_REF(&rand->refcnt); OPENSSL_free(rand); } @@ -81,12 +80,13 @@ static void *evp_rand_new(void) { EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); - if (rand == NULL - || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + if (rand == NULL) + return NULL; + + if (!CRYPTO_NEW_REF(&rand->refcnt, 1)) { OPENSSL_free(rand); return NULL; } - rand->refcnt = 1; return rand; } @@ -126,7 +126,7 @@ static void *evp_rand_from_algorithm(int name_id, #endif if ((rand = evp_rand_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } rand->name_id = name_id; @@ -336,7 +336,7 @@ int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx) { int ref = 0; - return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); + return CRYPTO_UP_REF(&ctx->refcnt, &ref); } EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) @@ -351,15 +351,16 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) } ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + if (ctx == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&ctx->refcnt, 1)) { OPENSSL_free(ctx); - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return NULL; } if (parent != NULL) { if (!EVP_RAND_CTX_up_ref(parent)) { ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + CRYPTO_FREE_REF(&ctx->refcnt); OPENSSL_free(ctx); return NULL; } @@ -369,16 +370,15 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, parent_dispatch)) == NULL || !EVP_RAND_up_ref(rand)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); rand->freectx(ctx->algctx); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + CRYPTO_FREE_REF(&ctx->refcnt); OPENSSL_free(ctx); EVP_RAND_CTX_free(parent); return NULL; } ctx->meth = rand; ctx->parent = parent; - ctx->refcnt = 1; return ctx; } @@ -390,14 +390,14 @@ void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) if (ctx == NULL) return; - CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); + CRYPTO_DOWN_REF(&ctx->refcnt, &ref); if (ref > 0) return; parent = ctx->parent; ctx->meth->freectx(ctx->algctx); ctx->algctx = NULL; EVP_RAND_free(ctx->meth); - CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + CRYPTO_FREE_REF(&ctx->refcnt); OPENSSL_free(ctx); EVP_RAND_CTX_free(parent); } diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index d7a4ad142a..d9eed1cea5 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,20 +22,15 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) { EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH)); - if (exchange == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (exchange == NULL) return NULL; - } - exchange->lock = CRYPTO_THREAD_lock_new(); - if (exchange->lock == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&exchange->refcnt, 1)) { OPENSSL_free(exchange); return NULL; } exchange->prov = prov; ossl_provider_up_ref(prov); - exchange->refcnt = 1; return exchange; } @@ -49,7 +44,7 @@ static void *evp_keyexch_from_algorithm(int name_id, int fncnt = 0, sparamfncnt = 0, gparamfncnt = 0; if ((exchange = evp_keyexch_new(prov)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -150,12 +145,12 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange) if (exchange == NULL) return; - CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock); + CRYPTO_DOWN_REF(&exchange->refcnt, &i); if (i > 0) return; OPENSSL_free(exchange->type_name); ossl_provider_free(exchange->prov); - CRYPTO_THREAD_lock_free(exchange->lock); + CRYPTO_FREE_REF(&exchange->refcnt); OPENSSL_free(exchange); } @@ -163,7 +158,7 @@ int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange) { int ref = 0; - CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock); + CRYPTO_UP_REF(&exchange->refcnt, &ref); return 1; } @@ -332,7 +327,11 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) /* No more legacy from here down to legacy: */ + /* A Coverity false positive with up_ref/down_ref and free */ + /* coverity[use_after_free] */ ctx->op.kex.exchange = exchange; + /* A Coverity false positive with up_ref/down_ref and free */ + /* coverity[deref_arg] */ ctx->op.kex.algctx = exchange->newctx(ossl_provider_ctx(exchange->prov)); if (ctx->op.kex.algctx == NULL) { /* The provider key can stay in the cache */ @@ -420,6 +419,8 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer, EVP_KEYMGMT_get0_name(ctx->keymgmt), ctx->propquery); if (tmp_keymgmt != NULL) + /* A Coverity issue with up_ref/down_ref and free */ + /* coverity[pass_freed_arg] */ provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &tmp_keymgmt, ctx->propquery); EVP_KEYMGMT_free(tmp_keymgmt_tofree); diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 6a6bb31e63..1093aac29e 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -31,7 +31,7 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) if (ctx == NULL || (ctx->algctx = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL || !EVP_KDF_up_ref(kdf)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); if (ctx != NULL) kdf->freectx(ctx->algctx); OPENSSL_free(ctx); @@ -60,14 +60,12 @@ EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) return NULL; dst = OPENSSL_malloc(sizeof(*dst)); - if (dst == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (dst == NULL) return NULL; - } memcpy(dst, src, sizeof(*dst)); if (!EVP_KDF_up_ref(dst->meth)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); OPENSSL_free(dst); return NULL; } diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c index 94af5d40a0..5ee36b2b42 100644 --- a/crypto/evp/kdf_meth.c +++ b/crypto/evp/kdf_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,7 +22,7 @@ static int evp_kdf_up_ref(void *vkdf) EVP_KDF *kdf = (EVP_KDF *)vkdf; int ref = 0; - CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); + CRYPTO_UP_REF(&kdf->refcnt, &ref); return 1; } @@ -34,12 +34,12 @@ static void evp_kdf_free(void *vkdf) if (kdf == NULL) return; - CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); + CRYPTO_DOWN_REF(&kdf->refcnt, &ref); if (ref > 0) return; OPENSSL_free(kdf->type_name); ossl_provider_free(kdf->prov); - CRYPTO_THREAD_lock_free(kdf->lock); + CRYPTO_FREE_REF(&kdf->refcnt); OPENSSL_free(kdf); } @@ -48,11 +48,10 @@ static void *evp_kdf_new(void) EVP_KDF *kdf = NULL; if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL - || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { + || !CRYPTO_NEW_REF(&kdf->refcnt, 1)) { OPENSSL_free(kdf); return NULL; } - kdf->refcnt = 1; return kdf; } @@ -65,7 +64,7 @@ static void *evp_kdf_from_algorithm(int name_id, int fnkdfcnt = 0, fnctxcnt = 0; if ((kdf = evp_kdf_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } kdf->name_id = name_id; diff --git a/crypto/evp/kem.c b/crypto/evp/kem.c index 1786ae6553..f96012ccf0 100644 --- a/crypto/evp/kem.c +++ b/crypto/evp/kem.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,13 +18,13 @@ #include "evp_local.h" static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, - const OSSL_PARAM params[]) + const OSSL_PARAM params[], EVP_PKEY *authkey) { int ret = 0; EVP_KEM *kem = NULL; EVP_KEYMGMT *tmp_keymgmt = NULL; const OSSL_PROVIDER *tmp_prov = NULL; - void *provkey = NULL; + void *provkey = NULL, *provauthkey = NULL; const char *supported_kem = NULL; int iter; @@ -40,7 +40,10 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); goto err; } - + if (authkey != NULL && authkey->type != ctx->pkey->type) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } /* * Try to derive the supported kem from |ctx->keymgmt|. */ @@ -114,16 +117,26 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, * same property query as when fetching the kem method. * With the keymgmt we found (if we did), we try to export |ctx->pkey| * to it (evp_pkey_export_to_provider() is smart enough to only actually - * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) */ tmp_keymgmt_tofree = tmp_keymgmt = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, EVP_KEYMGMT_get0_name(ctx->keymgmt), ctx->propquery); - if (tmp_keymgmt != NULL) + if (tmp_keymgmt != NULL) { provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, &tmp_keymgmt, ctx->propquery); + if (provkey != NULL && authkey != NULL) { + provauthkey = evp_pkey_export_to_provider(authkey, ctx->libctx, + &tmp_keymgmt, + ctx->propquery); + if (provauthkey == NULL) { + EVP_KEM_free(kem); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + } if (tmp_keymgmt == NULL) EVP_KEYMGMT_free(tmp_keymgmt_tofree); } @@ -144,20 +157,28 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, switch (operation) { case EVP_PKEY_OP_ENCAPSULATE: - if (kem->encapsulate_init == NULL) { + if (provauthkey != NULL && kem->auth_encapsulate_init != NULL) { + ret = kem->auth_encapsulate_init(ctx->op.encap.algctx, provkey, + provauthkey, params); + } else if (provauthkey == NULL && kem->encapsulate_init != NULL) { + ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params); + } else { ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params); break; case EVP_PKEY_OP_DECAPSULATE: - if (kem->decapsulate_init == NULL) { + if (provauthkey != NULL && kem->auth_decapsulate_init != NULL) { + ret = kem->auth_decapsulate_init(ctx->op.encap.algctx, provkey, + provauthkey, params); + } else if (provauthkey == NULL && kem->encapsulate_init != NULL) { + ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params); + } else { ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params); break; default: ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); @@ -178,9 +199,17 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, return ret; } +int EVP_PKEY_auth_encapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpriv, + const OSSL_PARAM params[]) +{ + if (authpriv == NULL) + return 0; + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params, authpriv); +} + int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) { - return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params); + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params, NULL); } int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, @@ -209,7 +238,15 @@ int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) { - return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params); + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params, NULL); +} + +int EVP_PKEY_auth_decapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpub, + const OSSL_PARAM params[]) +{ + if (authpub == NULL) + return 0; + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params, authpub); } int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, @@ -238,20 +275,15 @@ static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov) { EVP_KEM *kem = OPENSSL_zalloc(sizeof(EVP_KEM)); - if (kem == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (kem == NULL) return NULL; - } - kem->lock = CRYPTO_THREAD_lock_new(); - if (kem->lock == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&kem->refcnt, 1)) { OPENSSL_free(kem); return NULL; } kem->prov = prov; ossl_provider_up_ref(prov); - kem->refcnt = 1; return kem; } @@ -265,7 +297,7 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, int gparamfncnt = 0, sparamfncnt = 0; if ((kem = evp_kem_new(prov)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -288,6 +320,12 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, kem->encapsulate_init = OSSL_FUNC_kem_encapsulate_init(fns); encfncnt++; break; + case OSSL_FUNC_KEM_AUTH_ENCAPSULATE_INIT: + if (kem->auth_encapsulate_init != NULL) + break; + kem->auth_encapsulate_init = OSSL_FUNC_kem_auth_encapsulate_init(fns); + encfncnt++; + break; case OSSL_FUNC_KEM_ENCAPSULATE: if (kem->encapsulate != NULL) break; @@ -300,6 +338,12 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, kem->decapsulate_init = OSSL_FUNC_kem_decapsulate_init(fns); decfncnt++; break; + case OSSL_FUNC_KEM_AUTH_DECAPSULATE_INIT: + if (kem->auth_decapsulate_init != NULL) + break; + kem->auth_decapsulate_init = OSSL_FUNC_kem_auth_decapsulate_init(fns); + decfncnt++; + break; case OSSL_FUNC_KEM_DECAPSULATE: if (kem->decapsulate != NULL) break; @@ -348,19 +392,21 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, } } if (ctxfncnt != 2 - || (encfncnt != 0 && encfncnt != 2) - || (decfncnt != 0 && decfncnt != 2) - || (encfncnt != 2 && decfncnt != 2) + || (encfncnt != 0 && encfncnt != 2 && encfncnt != 3) + || (decfncnt != 0 && decfncnt != 2 && decfncnt != 3) + || (encfncnt != decfncnt) || (gparamfncnt != 0 && gparamfncnt != 2) || (sparamfncnt != 0 && sparamfncnt != 2)) { /* * In order to be a consistent set of functions we must have at least - * a set of context functions (newctx and freectx) as well as a pair of - * "kem" functions: (encapsulate_init, encapsulate) or - * (decapsulate_init, decapsulate). set_ctx_params and settable_ctx_params are - * optional, but if one of them is present then the other one must also - * be present. The same applies to get_ctx_params and - * gettable_ctx_params. The dupctx function is optional. + * a set of context functions (newctx and freectx) as well as a pair + * (or triplet) of "kem" functions: + * (encapsulate_init, (and/or auth_encapsulate_init), encapsulate) or + * (decapsulate_init, (and/or auth_decapsulate_init), decapsulate). + * set_ctx_params and settable_ctx_params are optional, but if one of + * them is present then the other one must also be present. The same + * applies to get_ctx_params and gettable_ctx_params. + * The dupctx function is optional. */ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); goto err; @@ -379,12 +425,12 @@ void EVP_KEM_free(EVP_KEM *kem) if (kem == NULL) return; - CRYPTO_DOWN_REF(&kem->refcnt, &i, kem->lock); + CRYPTO_DOWN_REF(&kem->refcnt, &i); if (i > 0) return; OPENSSL_free(kem->type_name); ossl_provider_free(kem->prov); - CRYPTO_THREAD_lock_free(kem->lock); + CRYPTO_FREE_REF(&kem->refcnt); OPENSSL_free(kem); } @@ -392,7 +438,7 @@ int EVP_KEM_up_ref(EVP_KEM *kem) { int ref = 0; - CRYPTO_UP_REF(&kem->refcnt, &ref, kem->lock); + CRYPTO_UP_REF(&kem->refcnt, &ref); return 1; } diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 8369d9578c..6408076b1f 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,7 @@ int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg) /* Just in time creation of keydata */ if (data->keydata == NULL) { if ((data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } delete_on_error = 1; @@ -194,7 +194,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, * operation cache. In that case, we know that |i| is zero. */ if (pk->dirty_cnt != pk->dirty_cnt_copy) - evp_keymgmt_util_clear_operation_cache(pk, 0); + evp_keymgmt_util_clear_operation_cache(pk); /* Add the new export to the operation cache */ if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata, @@ -219,15 +219,11 @@ static void op_cache_free(OP_CACHE_ELEM *e) OPENSSL_free(e); } -int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking) +int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk) { if (pk != NULL) { - if (locking && pk->lock != NULL && !CRYPTO_THREAD_write_lock(pk->lock)) - return 0; sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free); pk->operation_cache = NULL; - if (locking && pk->lock != NULL) - CRYPTO_THREAD_unlock(pk->lock); } return 1; diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index d3026d9fc3..1d7031f33c 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -21,15 +21,12 @@ static void *keymgmt_new(void) { EVP_KEYMGMT *keymgmt = NULL; - if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL - || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) { + if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&keymgmt->refcnt, 1)) { EVP_KEYMGMT_free(keymgmt); - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); return NULL; } - - keymgmt->refcnt = 1; - return keymgmt; } @@ -42,6 +39,7 @@ static void *keymgmt_from_algorithm(int name_id, int setparamfncnt = 0, getparamfncnt = 0; int setgenparamfncnt = 0; int importfncnt = 0, exportfncnt = 0; + int importtypesfncnt = 0, exporttypesfncnt = 0; if ((keymgmt = keymgmt_new()) == NULL) return NULL; @@ -153,10 +151,20 @@ static void *keymgmt_from_algorithm(int name_id, break; case OSSL_FUNC_KEYMGMT_IMPORT_TYPES: if (keymgmt->import_types == NULL) { - importfncnt++; + if (importtypesfncnt == 0) + importfncnt++; + importtypesfncnt++; keymgmt->import_types = OSSL_FUNC_keymgmt_import_types(fns); } break; + case OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX: + if (keymgmt->import_types_ex == NULL) { + if (importtypesfncnt == 0) + importfncnt++; + importtypesfncnt++; + keymgmt->import_types_ex = OSSL_FUNC_keymgmt_import_types_ex(fns); + } + break; case OSSL_FUNC_KEYMGMT_EXPORT: if (keymgmt->export == NULL) { exportfncnt++; @@ -165,10 +173,20 @@ static void *keymgmt_from_algorithm(int name_id, break; case OSSL_FUNC_KEYMGMT_EXPORT_TYPES: if (keymgmt->export_types == NULL) { - exportfncnt++; + if (exporttypesfncnt == 0) + exportfncnt++; + exporttypesfncnt++; keymgmt->export_types = OSSL_FUNC_keymgmt_export_types(fns); } break; + case OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX: + if (keymgmt->export_types_ex == NULL) { + if (exporttypesfncnt == 0) + exportfncnt++; + exporttypesfncnt++; + keymgmt->export_types_ex = OSSL_FUNC_keymgmt_export_types_ex(fns); + } + break; } } /* @@ -227,7 +245,7 @@ int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt) { int ref = 0; - CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + CRYPTO_UP_REF(&keymgmt->refcnt, &ref); return 1; } @@ -238,12 +256,12 @@ void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) if (keymgmt == NULL) return; - CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock); + CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref); if (ref > 0) return; OPENSSL_free(keymgmt->type_name); ossl_provider_free(keymgmt->prov); - CRYPTO_THREAD_lock_free(keymgmt->lock); + CRYPTO_FREE_REF(&keymgmt->refcnt); OPENSSL_free(keymgmt); } @@ -328,7 +346,7 @@ void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection, } int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, - void *template) + void *templ) { /* * It's arguable if we actually should return success in this case, as @@ -338,7 +356,7 @@ int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, */ if (keymgmt->gen_set_template == NULL) return 1; - return keymgmt->gen_set_template(genctx, template); + return keymgmt->gen_set_template(genctx, templ); } int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, @@ -455,6 +473,10 @@ int evp_keymgmt_import(const EVP_KEYMGMT *keymgmt, void *keydata, const OSSL_PARAM *evp_keymgmt_import_types(const EVP_KEYMGMT *keymgmt, int selection) { + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->import_types_ex != NULL) + return keymgmt->import_types_ex(provctx, selection); if (keymgmt->import_types == NULL) return NULL; return keymgmt->import_types(selection); @@ -471,6 +493,10 @@ int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata, const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt, int selection) { + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); + + if (keymgmt->export_types_ex != NULL) + return keymgmt->export_types_ex(provctx, selection); if (keymgmt->export_types == NULL) return NULL; return keymgmt->export_types(selection); diff --git a/crypto/evp/legacy_blake2.c b/crypto/evp/legacy_blake2.c index 6a18e5fe01..5a5f05044c 100644 --- a/crypto/evp/legacy_blake2.c +++ b/crypto/evp/legacy_blake2.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,11 +11,31 @@ #include "prov/blake2.h" /* diverse BLAKE2 macros */ #include "legacy_meth.h" -#define ossl_blake2b_init ossl_blake2b512_init -#define ossl_blake2s_init ossl_blake2s256_init +/* + * Local hack to adapt the BLAKE2 init functions to what the + * legacy function signatures demand. + */ +static int blake2s_init(BLAKE2S_CTX *C) +{ + BLAKE2S_PARAM P; + + ossl_blake2s_param_init(&P); + return ossl_blake2s_init(C, &P); +} +static int blake2b_init(BLAKE2B_CTX *C) +{ + BLAKE2B_PARAM P; + + ossl_blake2b_param_init(&P); + return ossl_blake2b_init(C, &P); +} +#define blake2s_update ossl_blake2s_update +#define blake2b_update ossl_blake2b_update +#define blake2s_final ossl_blake2s_final +#define blake2b_final ossl_blake2b_final -IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, ossl_blake2s) -IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, ossl_blake2b) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, blake2s) +IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, blake2b) static const EVP_MD blake2b_md = { NID_blake2b512, diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 630d339c35..3a979f4bd4 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,6 +64,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, if (ctx->pctx == NULL) return 0; + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_FINALISED); + locpctx = ctx->pctx; ERR_set_mark(); @@ -401,6 +403,11 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) { EVP_PKEY_CTX *pctx = ctx->pctx; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + if (pctx == NULL || pctx->operation != EVP_PKEY_OP_SIGNCTX || pctx->op.sig.algctx == NULL @@ -431,6 +438,11 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) { EVP_PKEY_CTX *pctx = ctx->pctx; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR); + return 0; + } + if (pctx == NULL || pctx->operation != EVP_PKEY_OP_VERIFYCTX || pctx->op.sig.algctx == NULL @@ -462,7 +474,12 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) { int sctx = 0, r = 0; - EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; + EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx; + + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } if (pctx == NULL || pctx->operation != EVP_PKEY_OP_SIGNCTX @@ -470,18 +487,19 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, || pctx->op.sig.signature == NULL) goto legacy; - if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) - return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, - sigret, siglen, - sigret == NULL ? 0 : *siglen); - dctx = EVP_PKEY_CTX_dup(pctx); - if (dctx == NULL) - return 0; - - r = dctx->op.sig.signature->digest_sign_final(dctx->op.sig.algctx, + if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) { + /* try dup */ + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx != NULL) + pctx = dctx; + } + r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen, - *siglen); - EVP_PKEY_CTX_free(dctx); + sigret == NULL ? 0 : *siglen); + if (dctx == NULL && sigret != NULL) + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + else + EVP_PKEY_CTX_free(dctx); return r; legacy: @@ -499,9 +517,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { if (sigret == NULL) return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); - if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) { r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); - else { + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + } else { dctx = EVP_PKEY_CTX_dup(pctx); if (dctx == NULL) return 0; @@ -562,15 +581,23 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, { EVP_PKEY_CTX *pctx = ctx->pctx; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + if (pctx != NULL && pctx->operation == EVP_PKEY_OP_SIGNCTX && pctx->op.sig.algctx != NULL && pctx->op.sig.signature != NULL) { - if (pctx->op.sig.signature->digest_sign != NULL) + if (pctx->op.sig.signature->digest_sign != NULL) { + if (sigret != NULL) + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx, sigret, siglen, sigret == NULL ? 0 : *siglen, tbs, tbslen); + } } else { /* legacy */ if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL) @@ -589,7 +616,12 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, int r = 0; unsigned int mdlen = 0; int vctx = 0; - EVP_PKEY_CTX *dctx, *pctx = ctx->pctx; + EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx; + + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } if (pctx == NULL || pctx->operation != EVP_PKEY_OP_VERIFYCTX @@ -597,16 +629,18 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, || pctx->op.sig.signature == NULL) goto legacy; - if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) - return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, - sig, siglen); - dctx = EVP_PKEY_CTX_dup(pctx); - if (dctx == NULL) - return 0; - - r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx, + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) { + /* try dup */ + dctx = EVP_PKEY_CTX_dup(pctx); + if (dctx != NULL) + pctx = dctx; + } + r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen); - EVP_PKEY_CTX_free(dctx); + if (dctx == NULL) + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + else + EVP_PKEY_CTX_free(dctx); return r; legacy: @@ -626,9 +660,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, else vctx = 0; if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { - if (vctx) + if (vctx) { r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx); - else + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; + } else r = EVP_DigestFinal_ex(ctx, md, &mdlen); } else { EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); @@ -655,14 +690,21 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, { EVP_PKEY_CTX *pctx = ctx->pctx; + if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR); + return 0; + } + if (pctx != NULL && pctx->operation == EVP_PKEY_OP_VERIFYCTX && pctx->op.sig.algctx != NULL && pctx->op.sig.signature != NULL) { - if (pctx->op.sig.signature->digest_verify != NULL) + if (pctx->op.sig.signature->digest_verify != NULL) { + ctx->flags |= EVP_MD_CTX_FLAG_FINALISED; return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen); + } } else { /* legacy */ if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL) diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index 90c79715d7..c6b021fcd8 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,16 +23,15 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) { EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX)); - if (ctx == NULL - || (ctx->algctx = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL - || !EVP_MAC_up_ref(mac)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - if (ctx != NULL) - mac->freectx(ctx->algctx); - OPENSSL_free(ctx); - ctx = NULL; - } else { + if (ctx != NULL) { ctx->meth = mac; + if ((ctx->algctx = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL + || !EVP_MAC_up_ref(mac)) { + mac->freectx(ctx->algctx); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); + OPENSSL_free(ctx); + ctx = NULL; + } } return ctx; } @@ -56,14 +55,12 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) return NULL; dst = OPENSSL_malloc(sizeof(*dst)); - if (dst == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (dst == NULL) return NULL; - } *dst = *src; if (!EVP_MAC_up_ref(dst->meth)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); OPENSSL_free(dst); return NULL; } diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c index 85fe7704fd..a3e7a02208 100644 --- a/crypto/evp/mac_meth.c +++ b/crypto/evp/mac_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,7 +21,7 @@ static int evp_mac_up_ref(void *vmac) EVP_MAC *mac = vmac; int ref = 0; - CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock); + CRYPTO_UP_REF(&mac->refcnt, &ref); return 1; } @@ -33,12 +33,12 @@ static void evp_mac_free(void *vmac) if (mac == NULL) return; - CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock); + CRYPTO_DOWN_REF(&mac->refcnt, &ref); if (ref > 0) return; OPENSSL_free(mac->type_name); ossl_provider_free(mac->prov); - CRYPTO_THREAD_lock_free(mac->lock); + CRYPTO_FREE_REF(&mac->refcnt); OPENSSL_free(mac); } @@ -47,13 +47,10 @@ static void *evp_mac_new(void) EVP_MAC *mac = NULL; if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL - || (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) { + || !CRYPTO_NEW_REF(&mac->refcnt, 1)) { evp_mac_free(mac); return NULL; } - - mac->refcnt = 1; - return mac; } @@ -66,7 +63,7 @@ static void *evp_mac_from_algorithm(int name_id, int fnmaccnt = 0, fnctxcnt = 0; if ((mac = evp_mac_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } mac->name_id = name_id; diff --git a/crypto/evp/p_dec.c b/crypto/evp/p_dec.c index d77eed1428..29ea3f5fbc 100644 --- a/crypto/evp/p_dec.c +++ b/crypto/evp/p_dec.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/evp/p_enc.c b/crypto/evp/p_enc.c index 433c1a9e17..64e6751456 100644 --- a/crypto/evp/p_enc.c +++ b/crypto/evp/p_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index dcb359d106..06a127a820 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -68,7 +68,11 @@ int EVP_PKEY_get_bits(const EVP_PKEY *pkey) if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL) size = pkey->ameth->pkey_bits(pkey); } - return size < 0 ? 0 : size; + if (size <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_BITS); + return 0; + } + return size; } int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey) @@ -80,7 +84,11 @@ int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey) if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL) size = pkey->ameth->pkey_security_bits(pkey); } - return size < 0 ? 0 : size; + if (size <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_SECURITY_BITS); + return 0; + } + return size; } int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) @@ -442,7 +450,7 @@ static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx, pkey = EVP_PKEY_new(); if (pkey == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -874,7 +882,7 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) } # endif /* OPENSSL_NO_DSA */ -# ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type) { if (EVP_PKEY_get_base_id(pkey) != type) { @@ -903,7 +911,7 @@ IMPLEMENT_ECX_VARIANT(X448) IMPLEMENT_ECX_VARIANT(ED25519) IMPLEMENT_ECX_VARIANT(ED448) -# endif +# endif /* OPENSSL_NO_ECX */ # if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0) @@ -1446,31 +1454,32 @@ EVP_PKEY *EVP_PKEY_new(void) { EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->type = EVP_PKEY_NONE; ret->save_type = EVP_PKEY_NONE; - ret->references = 1; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) + goto err; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - EVPerr(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); goto err; } #ifndef FIPS_MODULE ret->save_parameters = 1; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); goto err; } #endif return ret; err: + CRYPTO_FREE_REF(&ret->references); CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; @@ -1660,7 +1669,7 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey) { int i; - if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0) + if (CRYPTO_UP_REF(&pkey->references, &i) <= 0) return 0; REF_PRINT_COUNT("EVP_PKEY", pkey); @@ -1762,7 +1771,7 @@ void evp_pkey_free_legacy(EVP_PKEY *x) static void evp_pkey_free_it(EVP_PKEY *x) { /* internal function; x is never NULL */ - evp_keymgmt_util_clear_operation_cache(x, 1); + evp_keymgmt_util_clear_operation_cache(x); #ifndef FIPS_MODULE evp_pkey_free_legacy(x); #endif @@ -1783,7 +1792,7 @@ void EVP_PKEY_free(EVP_PKEY *x) if (x == NULL) return; - CRYPTO_DOWN_REF(&x->references, &i, x->lock); + CRYPTO_DOWN_REF(&x->references, &i); REF_PRINT_COUNT("EVP_PKEY", x); if (i > 0) return; @@ -1793,6 +1802,7 @@ void EVP_PKEY_free(EVP_PKEY *x) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data); #endif CRYPTO_THREAD_lock_free(x->lock); + CRYPTO_FREE_REF(&x->references); #ifndef FIPS_MODULE sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); #endif @@ -1810,7 +1820,11 @@ int EVP_PKEY_get_size(const EVP_PKEY *pkey) size = pkey->ameth->pkey_size(pkey); #endif } - return size < 0 ? 0 : size; + if (size <= 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_MAX_SIZE); + return 0; + } + return size; } const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey) @@ -1941,7 +1955,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, if (!CRYPTO_THREAD_write_lock(pk->lock)) goto end; if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy - && !evp_keymgmt_util_clear_operation_cache(pk, 0)) { + && !evp_keymgmt_util_clear_operation_cache(pk)) { CRYPTO_THREAD_unlock(pk->lock); evp_keymgmt_freedata(tmp_keymgmt, keydata); keydata = NULL; @@ -2035,7 +2049,7 @@ int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src) if (*dest == NULL) { allocpkey = *dest = EVP_PKEY_new(); if (*dest == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } } else { @@ -2061,7 +2075,7 @@ int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src) EVP_PKEY_CTX_new_from_pkey(libctx, *dest, NULL); if (pctx == NULL) - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); if (pctx != NULL && evp_keymgmt_export(keymgmt, keydata, diff --git a/crypto/evp/p_open.c b/crypto/evp/p_open.c index 8ee8b7a027..8630553e79 100644 --- a/crypto/evp/p_open.c +++ b/crypto/evp/p_open.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,7 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, return 1; if ((pctx = EVP_PKEY_CTX_new(priv, NULL)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -42,10 +42,8 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, || EVP_PKEY_decrypt(pctx, NULL, &keylen, ek, ekl) <= 0) goto err; - if ((key = OPENSSL_malloc(keylen)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if ((key = OPENSSL_malloc(keylen)) == NULL) goto err; - } if (EVP_PKEY_decrypt(pctx, key, &keylen, ek, ekl) <= 0) goto err; diff --git a/crypto/evp/p_seal.c b/crypto/evp/p_seal.c index d84d012975..94c8462ab4 100644 --- a/crypto/evp/p_seal.c +++ b/crypto/evp/p_seal.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -58,7 +58,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pubk[i], NULL); if (pctx == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index 8e430f4704..e5555281a6 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,12 +33,14 @@ int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *sigret, EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); if (tmp_ctx == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); if (rv) rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len); + else + rv = EVP_DigestFinal_ex(ctx, m, &m_len); EVP_MD_CTX_free(tmp_ctx); if (!rv) return 0; diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index e5667afb7c..02db143d13 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,12 +31,14 @@ int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); if (tmp_ctx == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); if (rv) rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len); + else + rv = EVP_DigestFinal_ex(ctx, m, &m_len); EVP_MD_CTX_free(tmp_ctx); if (!rv) return 0; diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 8e4940ed59..74cca96f4d 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -145,7 +145,7 @@ int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) *ppkey = allocated_pkey = EVP_PKEY_new(); if (*ppkey == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return -1; } @@ -153,7 +153,7 @@ int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) goto legacy; /* - * Asssigning gentmp to ctx->keygen_info is something our legacy + * Assigning gentmp to ctx->keygen_info is something our legacy * implementations do. Because the provider implementations aren't * allowed to reach into our EVP_PKEY_CTX, we need to provide similar * space for backward compatibility. It's ok that we attach a local @@ -378,7 +378,7 @@ int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, allocated_pkey = *ppkey = EVP_PKEY_new(); if (*ppkey == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return -1; } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index ba1971ce46..268b1617e3 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -66,11 +66,9 @@ static pmeth_fn standard_methods[] = { # ifndef OPENSSL_NO_DH ossl_dhx_pkey_method, # endif -# ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX ossl_ecx25519_pkey_method, ossl_ecx448_pkey_method, -# endif -# ifndef OPENSSL_NO_EC ossl_ed25519_pkey_method, ossl_ed448_pkey_method, # endif @@ -128,10 +126,8 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) EVP_PKEY_METHOD *pmeth; pmeth = OPENSSL_zalloc(sizeof(*pmeth)); - if (pmeth == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (pmeth == NULL) return NULL; - } pmeth->pkey_id = id; pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; @@ -317,8 +313,6 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM); } else { ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); } #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) @@ -482,10 +476,8 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) } # endif rctx = OPENSSL_zalloc(sizeof(*rctx)); - if (rctx == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (rctx == NULL) return NULL; - } if (pctx->pkey != NULL) EVP_PKEY_up_ref(pctx->pkey); @@ -627,13 +619,13 @@ int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) { if (app_pkey_methods == NULL) { app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); - if (app_pkey_methods == NULL){ - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (app_pkey_methods == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); return 0; } } if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_CRYPTO_LIB); return 0; } sk_EVP_PKEY_METHOD_sort(app_pkey_methods); @@ -879,7 +871,7 @@ int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) for (p = params; p->key != NULL; p++) { /* Check the ctx actually understands this parameter */ - if (OSSL_PARAM_locate_const(settable, p->key) == NULL ) + if (OSSL_PARAM_locate_const(settable, p->key) == NULL) return -2; } } @@ -902,9 +894,9 @@ int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) const OSSL_PARAM *gettable = EVP_PKEY_CTX_gettable_params(ctx); const OSSL_PARAM *p; - for (p = params; p->key != NULL; p++ ) { + for (p = params; p->key != NULL; p++) { /* Check the ctx actually understands this parameter */ - if (OSSL_PARAM_locate_const(gettable, p->key) == NULL ) + if (OSSL_PARAM_locate_const(gettable, p->key) == NULL) return -2; } } @@ -1212,77 +1204,12 @@ int EVP_PKEY_CTX_set_kem_op(EVP_PKEY_CTX *ctx, const char *op) return EVP_PKEY_CTX_set_params(ctx, params); } -int evp_pkey_ctx_set1_id_prov(EVP_PKEY_CTX *ctx, const void *id, int len) -{ - OSSL_PARAM params[2], *p = params; - int ret; - - if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - /* Uses the same return values as EVP_PKEY_CTX_ctrl */ - return -2; - } - - *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DIST_ID, - /* - * Cast away the const. This is - * read only so should be safe - */ - (void *)id, (size_t)len); - *p++ = OSSL_PARAM_construct_end(); - - ret = evp_pkey_ctx_set_params_strict(ctx, params); - if (ret == -2) - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - return ret; -} - int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len) { return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_SET1_ID, (int)len, (void*)(id)); } -static int get1_id_data(EVP_PKEY_CTX *ctx, void *id, size_t *id_len) -{ - int ret; - void *tmp_id = NULL; - OSSL_PARAM params[2], *p = params; - - if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - /* Uses the same return values as EVP_PKEY_CTX_ctrl */ - return -2; - } - - *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_PKEY_PARAM_DIST_ID, - &tmp_id, 0); - *p++ = OSSL_PARAM_construct_end(); - - ret = evp_pkey_ctx_get_params_strict(ctx, params); - if (ret == -2) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - } else if (ret > 0) { - size_t tmp_id_len = params[0].return_size; - - if (id != NULL) - memcpy(id, tmp_id, tmp_id_len); - if (id_len != NULL) - *id_len = tmp_id_len; - } - return ret; -} - -int evp_pkey_ctx_get1_id_prov(EVP_PKEY_CTX *ctx, void *id) -{ - return get1_id_data(ctx, id, NULL); -} - -int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len) -{ - return get1_id_data(ctx, NULL, id_len); -} - int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id) { return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET1_ID, 0, (void*)id); @@ -1498,17 +1425,13 @@ static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, evp_pkey_ctx_free_cached_data(ctx, cmd, name); if (name != NULL) { ctx->cached_parameters.dist_id_name = OPENSSL_strdup(name); - if (ctx->cached_parameters.dist_id_name == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ctx->cached_parameters.dist_id_name == NULL) return 0; - } } if (data_len > 0) { ctx->cached_parameters.dist_id = OPENSSL_memdup(data, data_len); - if (ctx->cached_parameters.dist_id == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (ctx->cached_parameters.dist_id == NULL) return 0; - } } ctx->cached_parameters.dist_id_set = 1; ctx->cached_parameters.dist_id_len = data_len; diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c index fb269b3bfd..379b344f0d 100644 --- a/crypto/evp/signature.c +++ b/crypto/evp/signature.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,20 +22,16 @@ static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov) { EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE)); - if (signature == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (signature == NULL) return NULL; - } - signature->lock = CRYPTO_THREAD_lock_new(); - if (signature->lock == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&signature->refcnt, 1)) { OPENSSL_free(signature); return NULL; } + signature->prov = prov; ossl_provider_up_ref(prov); - signature->refcnt = 1; return signature; } @@ -51,7 +47,7 @@ static void *evp_signature_from_algorithm(int name_id, int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0; if ((signature = evp_signature_new(prov)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); goto err; } @@ -283,12 +279,12 @@ void EVP_SIGNATURE_free(EVP_SIGNATURE *signature) if (signature == NULL) return; - CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock); + CRYPTO_DOWN_REF(&signature->refcnt, &i); if (i > 0) return; OPENSSL_free(signature->type_name); ossl_provider_free(signature->prov); - CRYPTO_THREAD_lock_free(signature->lock); + CRYPTO_FREE_REF(&signature->refcnt); OPENSSL_free(signature); } @@ -296,7 +292,7 @@ int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature) { int ref = 0; - CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock); + CRYPTO_UP_REF(&signature->refcnt, &ref); return 1; } diff --git a/crypto/ex_data.c b/crypto/ex_data.c index f92d0505fd..0412f38e9b 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -173,16 +173,14 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, || !sk_EX_CALLBACK_push(ip->meth, NULL)) { sk_EX_CALLBACK_free(ip->meth); ip->meth = NULL; - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); goto err; } } a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a)); - if (a == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (a == NULL) goto err; - } a->argl = argl; a->argp = argp; a->new_func = new_func; @@ -191,7 +189,7 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, a->priority = priority; if (!sk_EX_CALLBACK_push(ip->meth, NULL)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); OPENSSL_free(a); goto err; } @@ -249,10 +247,8 @@ int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, } CRYPTO_THREAD_unlock(global->ex_data_lock); - if (mx > 0 && storage == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (mx > 0 && storage == NULL) return 0; - } for (i = 0; i < mx; i++) { if (storage[i] != NULL && storage[i]->new_func != NULL) { ptr = CRYPTO_get_ex_data(ad, i); @@ -315,10 +311,8 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (mx == 0) return 1; - if (storage == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (storage == NULL) return 0; - } /* * Make sure the ex_data stack is at least |mx| elements long to avoid * issues in the for loop that follows; so go get the |mx|'th element @@ -478,14 +472,14 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) if (ad->sk == NULL) { if ((ad->sk = sk_void_new_null()) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return 0; } } for (i = sk_void_num(ad->sk); i <= idx; ++i) { if (!sk_void_push(ad->sk, NULL)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return 0; } } diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c index fe0a82eac8..c12a88148f 100644 --- a/crypto/ffc/ffc_backend.c +++ b/crypto/ffc/ffc_backend.c @@ -24,9 +24,6 @@ int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) BIGNUM *p = NULL, *q = NULL, *g = NULL, *j = NULL; int i; - if (ffc == NULL) - return 0; - prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (prm != NULL) { /* @@ -76,9 +73,8 @@ int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) } prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED); if (prm != NULL) { - if (prm->data_type != OSSL_PARAM_OCTET_STRING) - goto err; - if (!ossl_ffc_params_set_seed(ffc, prm->data, prm->data_size)) + if (prm->data_type != OSSL_PARAM_OCTET_STRING + || !ossl_ffc_params_set_seed(ffc, prm->data, prm->data_size)) goto err; } prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_PQ); @@ -113,10 +109,8 @@ int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) goto err; props = p1->data; } - if (!ossl_ffc_set_digest(ffc, prm->data, props)) - goto err; + ossl_ffc_set_digest(ffc, prm->data, props); } - ossl_ffc_params_set0_pqg(ffc, p, q, g); ossl_ffc_params_set0_j(ffc, j); return 1; diff --git a/crypto/ffc/ffc_key_generate.c b/crypto/ffc/ffc_key_generate.c index d02c657527..cb895f2abd 100644 --- a/crypto/ffc/ffc_key_generate.c +++ b/crypto/ffc/ffc_key_generate.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index 3536efd1ad..680f85ffaf 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -75,9 +75,6 @@ void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) int ossl_ffc_params_set_seed(FFC_PARAMS *params, const unsigned char *seed, size_t seedlen) { - if (params == NULL) - return 0; - if (params->seed != NULL) { if (params->seed == seed) return 1; @@ -125,11 +122,10 @@ void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, params->flags &= ~flags; } -int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) +void ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) { params->mdname = alg; params->mdprops = props; - return 1; } int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, @@ -214,9 +210,6 @@ int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, { int test_flags; - if (ffc == NULL) - return 0; - if (ffc->p != NULL && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_P, ffc->p)) return 0; diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c index 522525b9c4..8294fbec36 100644 --- a/crypto/ffc/ffc_params_generate.c +++ b/crypto/ffc/ffc_params_generate.c @@ -324,7 +324,7 @@ static int generate_q_fips186_4(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, /* find q */ for (;;) { - if(!BN_GENCB_call(cb, 0, m++)) + if (!BN_GENCB_call(cb, 0, m++)) goto err; /* A.1.1.2 Step (5) : generate seed with size seed_len */ @@ -673,7 +673,7 @@ int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, * A.1.1.3 Step (10) * n = floor(L / hash_outlen) - 1 */ - n = (L - 1 ) / (mdsize << 3); + n = (L - 1) / (mdsize << 3); /* Calculate 2^(L-1): Used in step A.1.1.2 Step (11.3) */ if (!BN_lshift(test, BN_value_one(), L - 1)) @@ -688,9 +688,9 @@ int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, *res = FFC_CHECK_Q_MISMATCH; goto err; } - if(!BN_GENCB_call(cb, 2, 0)) + if (!BN_GENCB_call(cb, 2, 0)) goto err; - if(!BN_GENCB_call(cb, 3, 0)) + if (!BN_GENCB_call(cb, 3, 0)) goto err; memcpy(seed_tmp, seed, seedlen); diff --git a/crypto/hpke/build.info b/crypto/hpke/build.info new file mode 100644 index 0000000000..033c243dac --- /dev/null +++ b/crypto/hpke/build.info @@ -0,0 +1,5 @@ +LIBS=../../libcrypto + +$COMMON=hpke_util.c hpke.c + +SOURCE[../../libcrypto]=$COMMON diff --git a/crypto/hpke/hpke.c b/crypto/hpke/hpke.c new file mode 100644 index 0000000000..5e976d6150 --- /dev/null +++ b/crypto/hpke/hpke.c @@ -0,0 +1,1463 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* An OpenSSL-based HPKE implementation of RFC9180 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/hpke_util.h" +#include "internal/nelem.h" +#include "internal/common.h" + +/* default buffer size for keys and internal buffers we use */ +#define OSSL_HPKE_MAXSIZE 512 + +/* Define HPKE labels from RFC9180 in hex for EBCDIC compatibility */ +/* "HPKE" - "suite_id" label for section 5.1 */ +static const char OSSL_HPKE_SEC51LABEL[] = "\x48\x50\x4b\x45"; +/* "psk_id_hash" - in key_schedule_context */ +static const char OSSL_HPKE_PSKIDHASH_LABEL[] = "\x70\x73\x6b\x5f\x69\x64\x5f\x68\x61\x73\x68"; +/* "info_hash" - in key_schedule_context */ +static const char OSSL_HPKE_INFOHASH_LABEL[] = "\x69\x6e\x66\x6f\x5f\x68\x61\x73\x68"; +/* "base_nonce" - base nonce calc label */ +static const char OSSL_HPKE_NONCE_LABEL[] = "\x62\x61\x73\x65\x5f\x6e\x6f\x6e\x63\x65"; +/* "exp" - internal exporter secret generation label */ +static const char OSSL_HPKE_EXP_LABEL[] = "\x65\x78\x70"; +/* "sec" - external label for exporting secret */ +static const char OSSL_HPKE_EXP_SEC_LABEL[] = "\x73\x65\x63"; +/* "key" - label for use when generating key from shared secret */ +static const char OSSL_HPKE_KEY_LABEL[] = "\x6b\x65\x79"; +/* "secret" - for generating shared secret */ +static const char OSSL_HPKE_SECRET_LABEL[] = "\x73\x65\x63\x72\x65\x74"; + +/** + * @brief sender or receiver context + */ +struct ossl_hpke_ctx_st +{ + OSSL_LIB_CTX *libctx; /* library context */ + char *propq; /* properties */ + int mode; /* HPKE mode */ + OSSL_HPKE_SUITE suite; /* suite */ + const OSSL_HPKE_KEM_INFO *kem_info; + const OSSL_HPKE_KDF_INFO *kdf_info; + const OSSL_HPKE_AEAD_INFO *aead_info; + EVP_CIPHER *aead_ciph; + int role; /* sender(0) or receiver(1) */ + uint64_t seq; /* aead sequence number */ + unsigned char *shared_secret; /* KEM output, zz */ + size_t shared_secretlen; + unsigned char *key; /* final aead key */ + size_t keylen; + unsigned char *nonce; /* aead base nonce */ + size_t noncelen; + unsigned char *exportersec; /* exporter secret */ + size_t exporterseclen; + char *pskid; /* PSK stuff */ + unsigned char *psk; + size_t psklen; + EVP_PKEY *authpriv; /* sender's authentication private key */ + unsigned char *authpub; /* auth public key */ + size_t authpublen; + unsigned char *ikme; /* IKM for sender deterministic key gen */ + size_t ikmelen; +}; + +/** + * @brief check if KEM uses NIST curve or not + * @param kem_id is the externally supplied kem_id + * @return 1 for NIST curves, 0 for other + */ +static int hpke_kem_id_nist_curve(uint16_t kem_id) +{ + const OSSL_HPKE_KEM_INFO *kem_info; + + kem_info = ossl_HPKE_KEM_INFO_find_id(kem_id); + return kem_info != NULL && kem_info->groupname != NULL; +} + +/** + * @brief wrapper to import NIST curve public key as easily as x25519/x448 + * @param libctx is the context to use + * @param propq is a properties string + * @param gname is the curve groupname + * @param buf is the binary buffer with the (uncompressed) public value + * @param buflen is the length of the private key buffer + * @return a working EVP_PKEY * or NULL + * + * Note that this could be a useful function to make public in + * future, but would likely require a name change. + */ +static EVP_PKEY *evp_pkey_new_raw_nist_public_key(OSSL_LIB_CTX *libctx, + const char *propq, + const char *gname, + const unsigned char *buf, + size_t buflen) +{ + OSSL_PARAM params[2]; + EVP_PKEY *ret = NULL; + EVP_PKEY_CTX *cctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + (char *)gname, 0); + params[1] = OSSL_PARAM_construct_end(); + if (cctx == NULL + || EVP_PKEY_paramgen_init(cctx) <= 0 + || EVP_PKEY_CTX_set_params(cctx, params) <= 0 + || EVP_PKEY_paramgen(cctx, &ret) <= 0 + || EVP_PKEY_set1_encoded_public_key(ret, buf, buflen) != 1) { + EVP_PKEY_CTX_free(cctx); + EVP_PKEY_free(ret); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return NULL; + } + EVP_PKEY_CTX_free(cctx); + return ret; +} + +/** + * @brief do the AEAD decryption + * @param hctx is the context to use + * @param iv is the initialisation vector + * @param aad is the additional authenticated data + * @param aadlen is the length of the aad + * @param ct is the ciphertext buffer + * @param ctlen is the ciphertext length (including tag). + * @param pt is the output buffer + * @param ptlen input/output, better be big enough on input, exact on output + * @return 1 on success, 0 otherwise + */ +static int hpke_aead_dec(OSSL_HPKE_CTX *hctx, const unsigned char *iv, + const unsigned char *aad, size_t aadlen, + const unsigned char *ct, size_t ctlen, + unsigned char *pt, size_t *ptlen) +{ + int erv = 0; + EVP_CIPHER_CTX *ctx = NULL; + int len = 0; + size_t taglen; + + taglen = hctx->aead_info->taglen; + if (ctlen <= taglen || *ptlen < ctlen - taglen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* Create and initialise the context */ + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + return 0; + /* Initialise the decryption operation. */ + if (EVP_DecryptInit_ex(ctx, hctx->aead_ciph, NULL, NULL, NULL) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + hctx->noncelen, NULL) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Initialise key and IV */ + if (EVP_DecryptInit_ex(ctx, NULL, NULL, hctx->key, iv) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Provide AAD. */ + if (aadlen != 0 && aad != NULL) { + if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } + if (EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen - taglen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *ptlen = len; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + taglen, (void *)(ct + ctlen - taglen))) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Finalise decryption. */ + if (EVP_DecryptFinal_ex(ctx, pt + len, &len) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + erv = 1; + +err: + if (erv != 1) + OPENSSL_cleanse(pt, *ptlen); + EVP_CIPHER_CTX_free(ctx); + return erv; +} + +/** + * @brief do AEAD encryption as per the RFC + * @param hctx is the context to use + * @param iv is the initialisation vector + * @param aad is the additional authenticated data + * @param aadlen is the length of the aad + * @param pt is the plaintext buffer + * @param ptlen is the length of pt + * @param ct is the output buffer + * @param ctlen input/output, needs space for tag on input, exact on output + * @return 1 for success, 0 otherwise + */ +static int hpke_aead_enc(OSSL_HPKE_CTX *hctx, const unsigned char *iv, + const unsigned char *aad, size_t aadlen, + const unsigned char *pt, size_t ptlen, + unsigned char *ct, size_t *ctlen) +{ + int erv = 0; + EVP_CIPHER_CTX *ctx = NULL; + int len; + size_t taglen = 0; + unsigned char tag[EVP_MAX_AEAD_TAG_LENGTH]; + + taglen = hctx->aead_info->taglen; + if (*ctlen <= taglen || ptlen > *ctlen - taglen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (!ossl_assert(taglen <= sizeof(tag))) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* Create and initialise the context */ + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + return 0; + /* Initialise the encryption operation. */ + if (EVP_EncryptInit_ex(ctx, hctx->aead_ciph, NULL, NULL, NULL) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, + hctx->noncelen, NULL) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Initialise key and IV */ + if (EVP_EncryptInit_ex(ctx, NULL, NULL, hctx->key, iv) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Provide any AAD data. */ + if (aadlen != 0 && aad != NULL) { + if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } + if (EVP_EncryptUpdate(ctx, ct, &len, pt, ptlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *ctlen = len; + /* Finalise the encryption. */ + if (EVP_EncryptFinal_ex(ctx, ct + len, &len) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *ctlen += len; + /* Get tag. Not a duplicate so needs to be added to the ciphertext */ + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(ct + *ctlen, tag, taglen); + *ctlen += taglen; + erv = 1; + +err: + if (erv != 1) + OPENSSL_cleanse(ct, *ctlen); + EVP_CIPHER_CTX_free(ctx); + return erv; +} + +/** + * @brief check mode is in-range and supported + * @param mode is the caller's chosen mode + * @return 1 for good mode, 0 otherwise + */ +static int hpke_mode_check(unsigned int mode) +{ + switch (mode) { + case OSSL_HPKE_MODE_BASE: + case OSSL_HPKE_MODE_PSK: + case OSSL_HPKE_MODE_AUTH: + case OSSL_HPKE_MODE_PSKAUTH: + break; + default: + return 0; + } + return 1; +} + +/** + * @brief check if a suite is supported locally + * @param suite is the suite to check + * @return 1 for good, 0 otherwise + */ +static int hpke_suite_check(OSSL_HPKE_SUITE suite, + const OSSL_HPKE_KEM_INFO **kem_info, + const OSSL_HPKE_KDF_INFO **kdf_info, + const OSSL_HPKE_AEAD_INFO **aead_info) +{ + const OSSL_HPKE_KEM_INFO *kem_info_; + const OSSL_HPKE_KDF_INFO *kdf_info_; + const OSSL_HPKE_AEAD_INFO *aead_info_; + + /* check KEM, KDF and AEAD are supported here */ + if ((kem_info_ = ossl_HPKE_KEM_INFO_find_id(suite.kem_id)) == NULL) + return 0; + if ((kdf_info_ = ossl_HPKE_KDF_INFO_find_id(suite.kdf_id)) == NULL) + return 0; + if ((aead_info_ = ossl_HPKE_AEAD_INFO_find_id(suite.aead_id)) == NULL) + return 0; + + if (kem_info != NULL) + *kem_info = kem_info_; + if (kdf_info != NULL) + *kdf_info = kdf_info_; + if (aead_info != NULL) + *aead_info = aead_info_; + + return 1; +} + +/* + * @brief randomly pick a suite + * @param libctx is the context to use + * @param propq is a properties string + * @param suite is the result + * @return 1 for success, 0 otherwise + */ +static int hpke_random_suite(OSSL_LIB_CTX *libctx, + const char *propq, + OSSL_HPKE_SUITE *suite) +{ + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + const OSSL_HPKE_KDF_INFO *kdf_info = NULL; + const OSSL_HPKE_AEAD_INFO *aead_info = NULL; + + /* random kem, kdf and aead */ + kem_info = ossl_HPKE_KEM_INFO_find_random(libctx); + if (kem_info == NULL) + return 0; + suite->kem_id = kem_info->kem_id; + kdf_info = ossl_HPKE_KDF_INFO_find_random(libctx); + if (kdf_info == NULL) + return 0; + suite->kdf_id = kdf_info->kdf_id; + aead_info = ossl_HPKE_AEAD_INFO_find_random(libctx); + if (aead_info == NULL) + return 0; + suite->aead_id = aead_info->aead_id; + return 1; +} + +/* + * @brief tell the caller how big the ciphertext will be + * + * AEAD algorithms add a tag for data authentication. + * Those are almost always, but not always, 16 octets + * long, and who knows what will be true in the future. + * So this function allows a caller to find out how + * much data expansion they will see with a given suite. + * + * "enc" is the name used in RFC9180 for the encapsulated + * public value of the sender, who calls OSSL_HPKE_seal(), + * that is sent to the recipient, who calls OSSL_HPKE_open(). + * + * @param suite is the suite to be used + * @param enclen points to what will be enc length + * @param clearlen is the length of plaintext + * @param cipherlen points to what will be ciphertext length (including tag) + * @return 1 for success, 0 otherwise + */ +static int hpke_expansion(OSSL_HPKE_SUITE suite, + size_t *enclen, + size_t clearlen, + size_t *cipherlen) +{ + const OSSL_HPKE_AEAD_INFO *aead_info = NULL; + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + + if (cipherlen == NULL || enclen == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (hpke_suite_check(suite, &kem_info, NULL, &aead_info) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + *cipherlen = clearlen + aead_info->taglen; + *enclen = kem_info->Nenc; + return 1; +} + +/* + * @brief expand and XOR the 64-bit unsigned seq with (nonce) buffer + * @param ctx is the HPKE context + * @param buf is the buffer for the XOR'd seq and nonce + * @param blen is the size of buf + * @return 0 for error, otherwise blen + */ +static size_t hpke_seqnonce2buf(OSSL_HPKE_CTX *ctx, + unsigned char *buf, size_t blen) +{ + size_t i; + uint64_t seq_copy; + + if (ctx == NULL || blen < sizeof(seq_copy) || blen != ctx->noncelen) + return 0; + seq_copy = ctx->seq; + memset(buf, 0, blen); + for (i = 0; i < sizeof(seq_copy); i++) { + buf[blen - i - 1] = seq_copy & 0xff; + seq_copy >>= 8; + } + for (i = 0; i < blen; i++) + buf[i] ^= ctx->nonce[i]; + return blen; +} + +/* + * @brief call the underlying KEM to encap + * @param ctx is the OSSL_HPKE_CTX + * @param enc is a buffer for the sender's ephemeral public value + * @param enclen is the size of enc on input, number of octets used on output + * @param pub is the recipient's public value + * @param publen is the length of pub + * @return 1 for success, 0 for error + */ +static int hpke_encap(OSSL_HPKE_CTX *ctx, unsigned char *enc, size_t *enclen, + const unsigned char *pub, size_t publen) +{ + int erv = 0; + OSSL_PARAM params[3], *p = params; + size_t lsslen = 0, lenclen = 0; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkR = NULL; + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + + if (ctx == NULL || enc == NULL || enclen == NULL || *enclen == 0 + || pub == NULL || publen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->shared_secret != NULL) { + /* only run the KEM once per OSSL_HPKE_CTX */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + kem_info = ossl_HPKE_KEM_INFO_find_id(ctx->suite.kem_id); + if (kem_info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + if (hpke_kem_id_nist_curve(ctx->suite.kem_id) == 1) { + pkR = evp_pkey_new_raw_nist_public_key(ctx->libctx, ctx->propq, + kem_info->groupname, + pub, publen); + } else { + pkR = EVP_PKEY_new_raw_public_key_ex(ctx->libctx, + kem_info->keytype, + ctx->propq, pub, publen); + } + if (pkR == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkR, ctx->propq); + if (pctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION, + OSSL_KEM_PARAM_OPERATION_DHKEM, + 0); + if (ctx->ikme != NULL) { + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KEM_PARAM_IKME, + ctx->ikme, ctx->ikmelen); + } + *p = OSSL_PARAM_construct_end(); + if (ctx->mode == OSSL_HPKE_MODE_AUTH + || ctx->mode == OSSL_HPKE_MODE_PSKAUTH) { + if (EVP_PKEY_auth_encapsulate_init(pctx, ctx->authpriv, + params) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + if (EVP_PKEY_encapsulate_init(pctx, params) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } + lenclen = *enclen; + if (EVP_PKEY_encapsulate(pctx, NULL, &lenclen, NULL, &lsslen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (lenclen > *enclen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ctx->shared_secret = OPENSSL_malloc(lsslen); + if (ctx->shared_secret == NULL) + goto err; + ctx->shared_secretlen = lsslen; + if (EVP_PKEY_encapsulate(pctx, enc, enclen, ctx->shared_secret, + &ctx->shared_secretlen) != 1) { + ctx->shared_secretlen = 0; + OPENSSL_free(ctx->shared_secret); + ctx->shared_secret = NULL; + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + erv = 1; + +err: + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(pkR); + return erv; +} + +/* + * @brief call the underlying KEM to decap + * @param ctx is the OSSL_HPKE_CTX + * @param enc is a buffer for the sender's ephemeral public value + * @param enclen is the length of enc + * @param priv is the recipient's private value + * @return 1 for success, 0 for error + */ +static int hpke_decap(OSSL_HPKE_CTX *ctx, + const unsigned char *enc, size_t enclen, + EVP_PKEY *priv) +{ + int erv = 0; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *spub = NULL; + OSSL_PARAM params[2], *p = params; + size_t lsslen = 0; + + if (ctx == NULL || enc == NULL || enclen == 0 || priv == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->shared_secret != NULL) { + /* only run the KEM once per OSSL_HPKE_CTX */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, priv, ctx->propq); + if (pctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION, + OSSL_KEM_PARAM_OPERATION_DHKEM, + 0); + *p = OSSL_PARAM_construct_end(); + if (ctx->mode == OSSL_HPKE_MODE_AUTH + || ctx->mode == OSSL_HPKE_MODE_PSKAUTH) { + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + + kem_info = ossl_HPKE_KEM_INFO_find_id(ctx->suite.kem_id); + if (kem_info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (hpke_kem_id_nist_curve(ctx->suite.kem_id) == 1) { + spub = evp_pkey_new_raw_nist_public_key(ctx->libctx, ctx->propq, + kem_info->groupname, + ctx->authpub, + ctx->authpublen); + } else { + spub = EVP_PKEY_new_raw_public_key_ex(ctx->libctx, + kem_info->keytype, + ctx->propq, + ctx->authpub, + ctx->authpublen); + } + if (spub == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_PKEY_auth_decapsulate_init(pctx, spub, params) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + if (EVP_PKEY_decapsulate_init(pctx, params) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } + if (EVP_PKEY_decapsulate(pctx, NULL, &lsslen, enc, enclen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + ctx->shared_secret = OPENSSL_malloc(lsslen); + if (ctx->shared_secret == NULL) + goto err; + if (EVP_PKEY_decapsulate(pctx, ctx->shared_secret, &lsslen, + enc, enclen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + ctx->shared_secretlen = lsslen; + erv = 1; + +err: + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(spub); + if (erv == 0) { + OPENSSL_free(ctx->shared_secret); + ctx->shared_secret = NULL; + ctx->shared_secretlen = 0; + } + return erv; +} + +/* + * @brief do "middle" of HPKE, between KEM and AEAD + * @param ctx is the OSSL_HPKE_CTX + * @param info is a buffer for the added binding information + * @param infolen is the length of info + * @return 0 for error, 1 for success + * + * This does all the HPKE extracts and expands as defined in RFC9180 + * section 5.1, (badly termed there as a "key schedule") and sets the + * ctx fields for the shared_secret, nonce, key and exporter_secret + */ +static int hpke_do_middle(OSSL_HPKE_CTX *ctx, + const unsigned char *info, size_t infolen) +{ + int erv = 0; + size_t ks_contextlen = OSSL_HPKE_MAXSIZE; + unsigned char ks_context[OSSL_HPKE_MAXSIZE]; + size_t halflen = 0; + size_t pskidlen = 0; + const OSSL_HPKE_AEAD_INFO *aead_info = NULL; + const OSSL_HPKE_KDF_INFO *kdf_info = NULL; + size_t secretlen = OSSL_HPKE_MAXSIZE; + unsigned char secret[OSSL_HPKE_MAXSIZE]; + EVP_KDF_CTX *kctx = NULL; + unsigned char suitebuf[6]; + const char *mdname = NULL; + + /* only let this be done once */ + if (ctx->exportersec != NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ossl_HPKE_KEM_INFO_find_id(ctx->suite.kem_id) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + aead_info = ossl_HPKE_AEAD_INFO_find_id(ctx->suite.aead_id); + if (aead_info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + kdf_info = ossl_HPKE_KDF_INFO_find_id(ctx->suite.kdf_id); + if (kdf_info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + mdname = kdf_info->mdname; + /* create key schedule context */ + memset(ks_context, 0, sizeof(ks_context)); + ks_context[0] = (unsigned char)(ctx->mode % 256); + ks_contextlen--; /* remaining space */ + halflen = kdf_info->Nh; + if ((2 * halflen) > ks_contextlen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + /* check a psk was set if in that mode */ + if (ctx->mode == OSSL_HPKE_MODE_PSK + || ctx->mode == OSSL_HPKE_MODE_PSKAUTH) { + if (ctx->psk == NULL || ctx->psklen == 0 || ctx->pskid == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + } + kctx = ossl_kdf_ctx_create("HKDF", mdname, ctx->libctx, ctx->propq); + if (kctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + pskidlen = (ctx->psk == NULL ? 0 : strlen(ctx->pskid)); + /* full suite details as per RFC9180 sec 5.1 */ + suitebuf[0] = ctx->suite.kem_id / 256; + suitebuf[1] = ctx->suite.kem_id % 256; + suitebuf[2] = ctx->suite.kdf_id / 256; + suitebuf[3] = ctx->suite.kdf_id % 256; + suitebuf[4] = ctx->suite.aead_id / 256; + suitebuf[5] = ctx->suite.aead_id % 256; + /* Extract and Expand variously... */ + if (ossl_hpke_labeled_extract(kctx, ks_context + 1, halflen, + NULL, 0, OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_PSKIDHASH_LABEL, + (unsigned char *)ctx->pskid, pskidlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (ossl_hpke_labeled_extract(kctx, ks_context + 1 + halflen, halflen, + NULL, 0, OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_INFOHASH_LABEL, + (unsigned char *)info, infolen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + ks_contextlen = 1 + 2 * halflen; + secretlen = kdf_info->Nh; + if (secretlen > OSSL_HPKE_MAXSIZE) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (ossl_hpke_labeled_extract(kctx, secret, secretlen, + ctx->shared_secret, ctx->shared_secretlen, + OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_SECRET_LABEL, + ctx->psk, ctx->psklen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (ctx->suite.aead_id != OSSL_HPKE_AEAD_ID_EXPORTONLY) { + /* we only need nonce/key for non export AEADs */ + ctx->noncelen = aead_info->Nn; + ctx->nonce = OPENSSL_malloc(ctx->noncelen); + if (ctx->nonce == NULL) + goto err; + if (ossl_hpke_labeled_expand(kctx, ctx->nonce, ctx->noncelen, + secret, secretlen, OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_NONCE_LABEL, + ks_context, ks_contextlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + ctx->keylen = aead_info->Nk; + ctx->key = OPENSSL_malloc(ctx->keylen); + if (ctx->key == NULL) + goto err; + if (ossl_hpke_labeled_expand(kctx, ctx->key, ctx->keylen, + secret, secretlen, OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_KEY_LABEL, + ks_context, ks_contextlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } + ctx->exporterseclen = kdf_info->Nh; + ctx->exportersec = OPENSSL_malloc(ctx->exporterseclen); + if (ctx->exportersec == NULL) + goto err; + if (ossl_hpke_labeled_expand(kctx, ctx->exportersec, ctx->exporterseclen, + secret, secretlen, OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_EXP_LABEL, + ks_context, ks_contextlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + erv = 1; + +err: + OPENSSL_cleanse(ks_context, OSSL_HPKE_MAXSIZE); + OPENSSL_cleanse(secret, OSSL_HPKE_MAXSIZE); + EVP_KDF_CTX_free(kctx); + return erv; +} + +/* + * externally visible functions from below here, API documentation is + * in doc/man3/OSSL_HPKE_CTX_new.pod to avoid duplication + */ + +OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role, + OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_HPKE_CTX *ctx = NULL; + const OSSL_HPKE_KEM_INFO *kem_info; + const OSSL_HPKE_KDF_INFO *kdf_info; + const OSSL_HPKE_AEAD_INFO *aead_info; + + if (hpke_mode_check(mode) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + if (hpke_suite_check(suite, &kem_info, &kdf_info, &aead_info) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + if (role != OSSL_HPKE_ROLE_SENDER && role != OSSL_HPKE_ROLE_RECEIVER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + ctx->libctx = libctx; + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) + goto err; + } + if (suite.aead_id != OSSL_HPKE_AEAD_ID_EXPORTONLY) { + ctx->aead_ciph = EVP_CIPHER_fetch(libctx, aead_info->name, propq); + if (ctx->aead_ciph == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_FETCH_FAILED); + goto err; + } + } + ctx->role = role; + ctx->mode = mode; + ctx->suite = suite; + ctx->kem_info = kem_info; + ctx->kdf_info = kdf_info; + ctx->aead_info = aead_info; + return ctx; + + err: + EVP_CIPHER_free(ctx->aead_ciph); + OPENSSL_free(ctx); + return NULL; +} + +void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx) +{ + if (ctx == NULL) + return; + EVP_CIPHER_free(ctx->aead_ciph); + OPENSSL_free(ctx->propq); + OPENSSL_clear_free(ctx->exportersec, ctx->exporterseclen); + OPENSSL_free(ctx->pskid); + OPENSSL_clear_free(ctx->psk, ctx->psklen); + OPENSSL_clear_free(ctx->key, ctx->keylen); + OPENSSL_clear_free(ctx->nonce, ctx->noncelen); + OPENSSL_clear_free(ctx->shared_secret, ctx->shared_secretlen); + OPENSSL_clear_free(ctx->ikme, ctx->ikmelen); + EVP_PKEY_free(ctx->authpriv); + OPENSSL_free(ctx->authpub); + + OPENSSL_free(ctx); + return; +} + +int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx, + const char *pskid, + const unsigned char *psk, size_t psklen) +{ + if (ctx == NULL || pskid == NULL || psk == NULL || psklen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (psklen > OSSL_HPKE_MAX_PARMLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (psklen < OSSL_HPKE_MIN_PSKLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (strlen(pskid) > OSSL_HPKE_MAX_PARMLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (strlen(pskid) == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->mode != OSSL_HPKE_MODE_PSK + && ctx->mode != OSSL_HPKE_MODE_PSKAUTH) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* free previous values if any */ + OPENSSL_clear_free(ctx->psk, ctx->psklen); + ctx->psk = OPENSSL_memdup(psk, psklen); + if (ctx->psk == NULL) + return 0; + ctx->psklen = psklen; + OPENSSL_free(ctx->pskid); + ctx->pskid = OPENSSL_strdup(pskid); + if (ctx->pskid == NULL) { + OPENSSL_clear_free(ctx->psk, ctx->psklen); + ctx->psk = NULL; + ctx->psklen = 0; + return 0; + } + return 1; +} + +int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx, + const unsigned char *ikme, size_t ikmelen) +{ + if (ctx == NULL || ikme == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ikmelen == 0 || ikmelen > OSSL_HPKE_MAX_PARMLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_SENDER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + OPENSSL_clear_free(ctx->ikme, ctx->ikmelen); + ctx->ikme = OPENSSL_memdup(ikme, ikmelen); + if (ctx->ikme == NULL) + return 0; + ctx->ikmelen = ikmelen; + return 1; +} + +int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv) +{ + if (ctx == NULL || priv == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ctx->mode != OSSL_HPKE_MODE_AUTH + && ctx->mode != OSSL_HPKE_MODE_PSKAUTH) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_SENDER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + EVP_PKEY_free(ctx->authpriv); + ctx->authpriv = EVP_PKEY_dup(priv); + if (ctx->authpriv == NULL) + return 0; + return 1; +} + +int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx, + const unsigned char *pub, size_t publen) +{ + int erv = 0; + EVP_PKEY *pubp = NULL; + unsigned char *lpub = NULL; + size_t lpublen = 0; + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + + if (ctx == NULL || pub == NULL || publen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ctx->mode != OSSL_HPKE_MODE_AUTH + && ctx->mode != OSSL_HPKE_MODE_PSKAUTH) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_RECEIVER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* check the value seems like a good public key for this kem */ + kem_info = ossl_HPKE_KEM_INFO_find_id(ctx->suite.kem_id); + if (kem_info == NULL) + return 0; + if (hpke_kem_id_nist_curve(ctx->suite.kem_id) == 1) { + pubp = evp_pkey_new_raw_nist_public_key(ctx->libctx, ctx->propq, + kem_info->groupname, + pub, publen); + } else { + pubp = EVP_PKEY_new_raw_public_key_ex(ctx->libctx, + kem_info->keytype, + ctx->propq, + pub, publen); + } + if (pubp == NULL) { + /* can happen based on external input - buffer value may be garbage */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + /* + * extract out the public key in encoded form so we + * should be fine even if given compressed form + */ + lpub = OPENSSL_malloc(OSSL_HPKE_MAXSIZE); + if (lpub == NULL) + goto err; + if (EVP_PKEY_get_octet_string_param(pubp, + OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + lpub, OSSL_HPKE_MAXSIZE, &lpublen) + != 1) { + OPENSSL_free(lpub); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* free up old value */ + OPENSSL_free(ctx->authpub); + ctx->authpub = lpub; + ctx->authpublen = lpublen; + erv = 1; + +err: + EVP_PKEY_free(pubp); + return erv; +} + +int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq) +{ + if (ctx == NULL || seq == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + *seq = ctx->seq; + return 1; +} + +int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* + * We disallow senders from doing this as it's dangerous + * Receivers are ok to use this, as no harm should ensue + * if they go wrong. + */ + if (ctx->role == OSSL_HPKE_ROLE_SENDER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + ctx->seq = seq; + return 1; +} + +int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx, + unsigned char *enc, size_t *enclen, + const unsigned char *pub, size_t publen, + const unsigned char *info, size_t infolen) +{ + int erv = 1; + size_t minenc = 0; + + if (ctx == NULL || enc == NULL || enclen == NULL || *enclen == 0 + || pub == NULL || publen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_SENDER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (infolen > OSSL_HPKE_MAX_INFOLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (infolen > 0 && info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + minenc = OSSL_HPKE_get_public_encap_size(ctx->suite); + if (minenc == 0 || minenc > *enclen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->shared_secret != NULL) { + /* only allow one encap per OSSL_HPKE_CTX */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (hpke_encap(ctx, enc, enclen, pub, publen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + /* + * note that the info is not part of the context as it + * only needs to be used once here so doesn't need to + * be stored + */ + erv = hpke_do_middle(ctx, info, infolen); + return erv; +} + +int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx, + const unsigned char *enc, size_t enclen, + EVP_PKEY *recippriv, + const unsigned char *info, size_t infolen) +{ + int erv = 1; + size_t minenc = 0; + + if (ctx == NULL || enc == NULL || enclen == 0 || recippriv == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_RECEIVER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (infolen > OSSL_HPKE_MAX_INFOLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (infolen > 0 && info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + minenc = OSSL_HPKE_get_public_encap_size(ctx->suite); + if (minenc == 0 || minenc > enclen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->shared_secret != NULL) { + /* only allow one encap per OSSL_HPKE_CTX */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + erv = hpke_decap(ctx, enc, enclen, recippriv); + if (erv != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + /* + * note that the info is not part of the context as it + * only needs to be used once here so doesn't need to + * be stored + */ + erv = hpke_do_middle(ctx, info, infolen); + return erv; +} + +int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx, + unsigned char *ct, size_t *ctlen, + const unsigned char *aad, size_t aadlen, + const unsigned char *pt, size_t ptlen) +{ + unsigned char seqbuf[OSSL_HPKE_MAX_NONCELEN]; + size_t seqlen = 0; + + if (ctx == NULL || ct == NULL || ctlen == NULL || *ctlen == 0 + || pt == NULL || ptlen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_SENDER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if ((ctx->seq + 1) == 0) { /* wrap around imminent !!! */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->key == NULL || ctx->nonce == NULL) { + /* need to have done an encap first, info can be NULL */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + seqlen = hpke_seqnonce2buf(ctx, seqbuf, sizeof(seqbuf)); + if (seqlen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + if (hpke_aead_enc(ctx, seqbuf, aad, aadlen, pt, ptlen, ct, ctlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + OPENSSL_cleanse(seqbuf, sizeof(seqbuf)); + return 0; + } else { + ctx->seq++; + } + OPENSSL_cleanse(seqbuf, sizeof(seqbuf)); + return 1; +} + +int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx, + unsigned char *pt, size_t *ptlen, + const unsigned char *aad, size_t aadlen, + const unsigned char *ct, size_t ctlen) +{ + unsigned char seqbuf[OSSL_HPKE_MAX_NONCELEN]; + size_t seqlen = 0; + + if (ctx == NULL || pt == NULL || ptlen == NULL || *ptlen == 0 + || ct == NULL || ctlen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->role != OSSL_HPKE_ROLE_RECEIVER) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if ((ctx->seq + 1) == 0) { /* wrap around imminent !!! */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (ctx->key == NULL || ctx->nonce == NULL) { + /* need to have done an encap first, info can be NULL */ + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + seqlen = hpke_seqnonce2buf(ctx, seqbuf, sizeof(seqbuf)); + if (seqlen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + if (hpke_aead_dec(ctx, seqbuf, aad, aadlen, ct, ctlen, pt, ptlen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + OPENSSL_cleanse(seqbuf, sizeof(seqbuf)); + return 0; + } + ctx->seq++; + OPENSSL_cleanse(seqbuf, sizeof(seqbuf)); + return 1; +} + +int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx, + unsigned char *secret, size_t secretlen, + const unsigned char *label, size_t labellen) +{ + int erv = 0; + EVP_KDF_CTX *kctx = NULL; + unsigned char suitebuf[6]; + const char *mdname = NULL; + const OSSL_HPKE_KDF_INFO *kdf_info = NULL; + + if (ctx == NULL || secret == NULL || secretlen == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (labellen > OSSL_HPKE_MAX_PARMLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (labellen > 0 && label == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (ctx->exportersec == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + kdf_info = ossl_HPKE_KDF_INFO_find_id(ctx->suite.kdf_id); + if (kdf_info == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + mdname = kdf_info->mdname; + kctx = ossl_kdf_ctx_create("HKDF", mdname, ctx->libctx, ctx->propq); + if (kctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + /* full suiteid as per RFC9180 sec 5.3 */ + suitebuf[0] = ctx->suite.kem_id / 256; + suitebuf[1] = ctx->suite.kem_id % 256; + suitebuf[2] = ctx->suite.kdf_id / 256; + suitebuf[3] = ctx->suite.kdf_id % 256; + suitebuf[4] = ctx->suite.aead_id / 256; + suitebuf[5] = ctx->suite.aead_id % 256; + erv = ossl_hpke_labeled_expand(kctx, secret, secretlen, + ctx->exportersec, ctx->exporterseclen, + OSSL_HPKE_SEC51LABEL, + suitebuf, sizeof(suitebuf), + OSSL_HPKE_EXP_SEC_LABEL, + label, labellen); + EVP_KDF_CTX_free(kctx); + if (erv != 1) + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return erv; +} + +int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite, + unsigned char *pub, size_t *publen, EVP_PKEY **priv, + const unsigned char *ikm, size_t ikmlen, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int erv = 0; /* Our error return value - 1 is success */ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *skR = NULL; + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + OSSL_PARAM params[3], *p = params; + + if (pub == NULL || publen == NULL || *publen == 0 || priv == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (hpke_suite_check(suite, &kem_info, NULL, NULL) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if ((ikmlen > 0 && ikm == NULL) + || (ikmlen == 0 && ikm != NULL) + || ikmlen > OSSL_HPKE_MAX_PARMLEN) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (hpke_kem_id_nist_curve(suite.kem_id) == 1) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + (char *)kem_info->groupname, 0); + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq); + } else { + pctx = EVP_PKEY_CTX_new_from_name(libctx, kem_info->keytype, propq); + } + if (pctx == NULL + || EVP_PKEY_keygen_init(pctx) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (ikm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, + (char *)ikm, ikmlen); + *p = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_set_params(pctx, params) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_PKEY_generate(pctx, &skR) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_PKEY_CTX_free(pctx); + pctx = NULL; + if (EVP_PKEY_get_octet_string_param(skR, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + pub, *publen, publen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *priv = skR; + erv = 1; + +err: + if (erv != 1) + EVP_PKEY_free(skR); + EVP_PKEY_CTX_free(pctx); + return erv; +} + +int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite) +{ + return hpke_suite_check(suite, NULL, NULL, NULL); +} + +int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in, + OSSL_HPKE_SUITE *suite, + unsigned char *enc, size_t *enclen, + unsigned char *ct, size_t ctlen, + OSSL_LIB_CTX *libctx, const char *propq) +{ + OSSL_HPKE_SUITE chosen; + size_t plen = 0; + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + const OSSL_HPKE_AEAD_INFO *aead_info = NULL; + EVP_PKEY *fakepriv = NULL; + + if (enc == NULL || enclen == 0 + || ct == NULL || ctlen == 0 || suite == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + if (suite_in == NULL) { + /* choose a random suite */ + if (hpke_random_suite(libctx, propq, &chosen) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + chosen = *suite_in; + } + if (hpke_suite_check(chosen, &kem_info, NULL, &aead_info) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + *suite = chosen; + /* make sure room for tag and one plaintext octet */ + if (aead_info->taglen >= ctlen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* publen */ + plen = kem_info->Npk; + if (plen > *enclen) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + /* + * In order for our enc to look good for sure, we generate and then + * delete a real key for that curve - bit OTT but it ensures we do + * get the encoding right (e.g. 0x04 as 1st octet for NIST curves in + * uncompressed form) and that the value really does map to a point on + * the relevant curve. + */ + if (OSSL_HPKE_keygen(chosen, enc, enclen, &fakepriv, NULL, 0, + libctx, propq) != 1) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_PKEY_free(fakepriv); + if (RAND_bytes_ex(libctx, ct, ctlen, 0) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + goto err; + } + return 1; +err: + return 0; +} + +int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite) +{ + return ossl_hpke_str2suite(str, suite); +} + +size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen) +{ + size_t enclen = 0; + size_t cipherlen = 0; + + if (hpke_expansion(suite, &enclen, clearlen, &cipherlen) != 1) + return 0; + return cipherlen; +} + +size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite) +{ + size_t enclen = 0; + size_t cipherlen = 0; + size_t clearlen = 16; + + if (hpke_expansion(suite, &enclen, clearlen, &cipherlen) != 1) + return 0; + return enclen; +} + +size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite) +{ + const OSSL_HPKE_KEM_INFO *kem_info = NULL; + + if (hpke_suite_check(suite, &kem_info, NULL, NULL) != 1) + return 0; + if (kem_info == NULL) + return 0; + + return kem_info->Nsk; +} diff --git a/crypto/hpke/hpke_util.c b/crypto/hpke/hpke_util.c new file mode 100644 index 0000000000..a9d86a9355 --- /dev/null +++ b/crypto/hpke/hpke_util.c @@ -0,0 +1,528 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crypto/ecx.h" +#include "crypto/rand.h" +#include "internal/hpke_util.h" +#include "internal/packet.h" +#include "internal/nelem.h" +#include "internal/common.h" + +/* + * Delimiter used in OSSL_HPKE_str2suite + */ +#define OSSL_HPKE_STR_DELIMCHAR ',' + +/* + * table with identifier and synonym strings + * right now, there are 4 synonyms for each - a name, a hex string + * a hex string with a leading zero and a decimal string - more + * could be added but that seems like enough + */ +typedef struct { + uint16_t id; + char *synonyms[4]; +} synonymttab_t; + +/* max length of string we'll try map to a suite */ +#define OSSL_HPKE_MAX_SUITESTR 38 + +/* Define HPKE labels from RFC9180 in hex for EBCDIC compatibility */ +/* ASCII: "HPKE-v1", in hex for EBCDIC compatibility */ +static const char LABEL_HPKEV1[] = "\x48\x50\x4B\x45\x2D\x76\x31"; + +/* + * Note that if additions are made to the set of IANA codepoints + * and the tables below, corresponding additions should also be + * made to the synonymtab tables a little further down so that + * OSSL_HPKE_str2suite() continues to function correctly. + * + * The canonical place to check for IANA registered codepoints + * is: https://www.iana.org/assignments/hpke/hpke.xhtml + */ + +/* + * @brief table of KEMs + * See RFC9180 Section 7.1 "Table 2 KEM IDs" + */ +static const OSSL_HPKE_KEM_INFO hpke_kem_tab[] = { +#ifndef OPENSSL_NO_EC + { OSSL_HPKE_KEM_ID_P256, "EC", OSSL_HPKE_KEMSTR_P256, + LN_sha256, SHA256_DIGEST_LENGTH, 65, 65, 32, 0xFF }, + { OSSL_HPKE_KEM_ID_P384, "EC", OSSL_HPKE_KEMSTR_P384, + LN_sha384, SHA384_DIGEST_LENGTH, 97, 97, 48, 0xFF }, + { OSSL_HPKE_KEM_ID_P521, "EC", OSSL_HPKE_KEMSTR_P521, + LN_sha512, SHA512_DIGEST_LENGTH, 133, 133, 66, 0x01 }, +# ifndef OPENSSL_NO_ECX + { OSSL_HPKE_KEM_ID_X25519, OSSL_HPKE_KEMSTR_X25519, NULL, + LN_sha256, SHA256_DIGEST_LENGTH, + X25519_KEYLEN, X25519_KEYLEN, X25519_KEYLEN, 0x00 }, + { OSSL_HPKE_KEM_ID_X448, OSSL_HPKE_KEMSTR_X448, NULL, + LN_sha512, SHA512_DIGEST_LENGTH, + X448_KEYLEN, X448_KEYLEN, X448_KEYLEN, 0x00 } +# endif +#else + { OSSL_HPKE_KEM_ID_RESERVED, NULL, NULL, NULL, 0, 0, 0, 0, 0x00 } +#endif +}; + +/* + * @brief table of AEADs + * See RFC9180 Section 7.2 "Table 3 KDF IDs" + */ +static const OSSL_HPKE_AEAD_INFO hpke_aead_tab[] = { + { OSSL_HPKE_AEAD_ID_AES_GCM_128, LN_aes_128_gcm, 16, 16, + OSSL_HPKE_MAX_NONCELEN }, + { OSSL_HPKE_AEAD_ID_AES_GCM_256, LN_aes_256_gcm, 16, 32, + OSSL_HPKE_MAX_NONCELEN }, +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + { OSSL_HPKE_AEAD_ID_CHACHA_POLY1305, LN_chacha20_poly1305, 16, 32, + OSSL_HPKE_MAX_NONCELEN }, +#endif + { OSSL_HPKE_AEAD_ID_EXPORTONLY, NULL, 0, 0, 0 } +}; + +/* + * @brief table of KDFs + * See RFC9180 Section 7.3 "Table 5 AEAD IDs" + */ +static const OSSL_HPKE_KDF_INFO hpke_kdf_tab[] = { + { OSSL_HPKE_KDF_ID_HKDF_SHA256, LN_sha256, SHA256_DIGEST_LENGTH }, + { OSSL_HPKE_KDF_ID_HKDF_SHA384, LN_sha384, SHA384_DIGEST_LENGTH }, + { OSSL_HPKE_KDF_ID_HKDF_SHA512, LN_sha512, SHA512_DIGEST_LENGTH } +}; + +/** + * Synonym tables for KEMs, KDFs and AEADs: idea is to allow + * mapping strings to suites with a little flexibility in terms + * of allowing a name or a couple of forms of number (for + * the IANA codepoint). If new IANA codepoints are allocated + * then these tables should be updated at the same time as the + * others above. + * + * The function to use these is ossl_hpke_str2suite() further down + * this file and shouldn't need modification so long as the table + * sizes (i.e. allow exactly 4 synonyms) don't change. + */ +static const synonymttab_t kemstrtab[] = { + {OSSL_HPKE_KEM_ID_P256, + {OSSL_HPKE_KEMSTR_P256, "0x10", "0x10", "16" }}, + {OSSL_HPKE_KEM_ID_P384, + {OSSL_HPKE_KEMSTR_P384, "0x11", "0x11", "17" }}, + {OSSL_HPKE_KEM_ID_P521, + {OSSL_HPKE_KEMSTR_P521, "0x12", "0x12", "18" }}, +# ifndef OPENSSL_NO_ECX + {OSSL_HPKE_KEM_ID_X25519, + {OSSL_HPKE_KEMSTR_X25519, "0x20", "0x20", "32" }}, + {OSSL_HPKE_KEM_ID_X448, + {OSSL_HPKE_KEMSTR_X448, "0x21", "0x21", "33" }} +# endif +}; +static const synonymttab_t kdfstrtab[] = { + {OSSL_HPKE_KDF_ID_HKDF_SHA256, + {OSSL_HPKE_KDFSTR_256, "0x1", "0x01", "1"}}, + {OSSL_HPKE_KDF_ID_HKDF_SHA384, + {OSSL_HPKE_KDFSTR_384, "0x2", "0x02", "2"}}, + {OSSL_HPKE_KDF_ID_HKDF_SHA512, + {OSSL_HPKE_KDFSTR_512, "0x3", "0x03", "3"}} +}; +static const synonymttab_t aeadstrtab[] = { + {OSSL_HPKE_AEAD_ID_AES_GCM_128, + {OSSL_HPKE_AEADSTR_AES128GCM, "0x1", "0x01", "1"}}, + {OSSL_HPKE_AEAD_ID_AES_GCM_256, + {OSSL_HPKE_AEADSTR_AES256GCM, "0x2", "0x02", "2"}}, + {OSSL_HPKE_AEAD_ID_CHACHA_POLY1305, + {OSSL_HPKE_AEADSTR_CP, "0x3", "0x03", "3"}}, + {OSSL_HPKE_AEAD_ID_EXPORTONLY, + {OSSL_HPKE_AEADSTR_EXP, "ff", "0xff", "255"}} +}; + +/* Return an object containing KEM constants associated with a EC curve name */ +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_curve(const char *curve) +{ + int i, sz = OSSL_NELEM(hpke_kem_tab); + + for (i = 0; i < sz; ++i) { + const char *group = hpke_kem_tab[i].groupname; + + if (group == NULL) + group = hpke_kem_tab[i].keytype; + if (OPENSSL_strcasecmp(curve, group) == 0) + return &hpke_kem_tab[i]; + } + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); + return NULL; +} + +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_id(uint16_t kemid) +{ + int i, sz = OSSL_NELEM(hpke_kem_tab); + + /* + * this check can happen if we're in a no-ec build and there are no + * KEMS available + */ + if (kemid == OSSL_HPKE_KEM_ID_RESERVED) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); + return NULL; + } + for (i = 0; i != sz; ++i) { + if (hpke_kem_tab[i].kem_id == kemid) + return &hpke_kem_tab[i]; + } + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); + return NULL; +} + +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_random(OSSL_LIB_CTX *ctx) +{ + uint32_t rval = 0; + int err = 0; + size_t sz = OSSL_NELEM(hpke_kem_tab); + + rval = ossl_rand_uniform_uint32(ctx, sz, &err); + return (err == 1 ? NULL : &hpke_kem_tab[rval]); +} + +const OSSL_HPKE_KDF_INFO *ossl_HPKE_KDF_INFO_find_id(uint16_t kdfid) +{ + int i, sz = OSSL_NELEM(hpke_kdf_tab); + + for (i = 0; i != sz; ++i) { + if (hpke_kdf_tab[i].kdf_id == kdfid) + return &hpke_kdf_tab[i]; + } + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KDF); + return NULL; +} + +const OSSL_HPKE_KDF_INFO *ossl_HPKE_KDF_INFO_find_random(OSSL_LIB_CTX *ctx) +{ + uint32_t rval = 0; + int err = 0; + size_t sz = OSSL_NELEM(hpke_kdf_tab); + + rval = ossl_rand_uniform_uint32(ctx, sz, &err); + return (err == 1 ? NULL : &hpke_kdf_tab[rval]); +} + +const OSSL_HPKE_AEAD_INFO *ossl_HPKE_AEAD_INFO_find_id(uint16_t aeadid) +{ + int i, sz = OSSL_NELEM(hpke_aead_tab); + + for (i = 0; i != sz; ++i) { + if (hpke_aead_tab[i].aead_id == aeadid) + return &hpke_aead_tab[i]; + } + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AEAD); + return NULL; +} + +const OSSL_HPKE_AEAD_INFO *ossl_HPKE_AEAD_INFO_find_random(OSSL_LIB_CTX *ctx) +{ + uint32_t rval = 0; + int err = 0; + /* the minus 1 below is so we don't pick the EXPORTONLY codepoint */ + size_t sz = OSSL_NELEM(hpke_aead_tab) - 1; + + rval = ossl_rand_uniform_uint32(ctx, sz, &err); + return (err == 1 ? NULL : &hpke_aead_tab[rval]); +} + +static int kdf_derive(EVP_KDF_CTX *kctx, + unsigned char *out, size_t outlen, int mode, + const unsigned char *salt, size_t saltlen, + const unsigned char *ikm, size_t ikmlen, + const unsigned char *info, size_t infolen) +{ + int ret; + OSSL_PARAM params[5], *p = params; + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + if (salt != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (char *)salt, saltlen); + if (ikm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (char *)ikm, ikmlen); + if (info != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + (char *)info, infolen); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; + if (!ret) + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return ret; +} + +int ossl_hpke_kdf_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const unsigned char *ikm, size_t ikmlen) +{ + return kdf_derive(kctx, prk, prklen, EVP_KDF_HKDF_MODE_EXTRACT_ONLY, + salt, saltlen, ikm, ikmlen, NULL, 0); +} + +/* Common code to perform a HKDF expand */ +int ossl_hpke_kdf_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const unsigned char *info, size_t infolen) +{ + return kdf_derive(kctx, okm, okmlen, EVP_KDF_HKDF_MODE_EXPAND_ONLY, + NULL, 0, prk, prklen, info, infolen); +} + +/* + * See RFC 9180 Section 4 LabelExtract() + */ +int ossl_hpke_labeled_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const char *protocol_label, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *ikm, size_t ikmlen) +{ + int ret = 0; + size_t label_hpkev1len = 0; + size_t protocol_labellen = 0; + size_t labellen = 0; + size_t labeled_ikmlen = 0; + unsigned char *labeled_ikm = NULL; + WPACKET pkt; + + label_hpkev1len = strlen(LABEL_HPKEV1); + protocol_labellen = strlen(protocol_label); + labellen = strlen(label); + labeled_ikmlen = label_hpkev1len + protocol_labellen + + suiteidlen + labellen + ikmlen; + labeled_ikm = OPENSSL_malloc(labeled_ikmlen); + if (labeled_ikm == NULL) + return 0; + + /* labeled_ikm = concat("HPKE-v1", suiteid, label, ikm) */ + if (!WPACKET_init_static_len(&pkt, labeled_ikm, labeled_ikmlen, 0) + || !WPACKET_memcpy(&pkt, LABEL_HPKEV1, label_hpkev1len) + || !WPACKET_memcpy(&pkt, protocol_label, protocol_labellen) + || !WPACKET_memcpy(&pkt, suiteid, suiteidlen) + || !WPACKET_memcpy(&pkt, label, labellen) + || !WPACKET_memcpy(&pkt, ikm, ikmlen) + || !WPACKET_get_total_written(&pkt, &labeled_ikmlen) + || !WPACKET_finish(&pkt)) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + goto end; + } + + ret = ossl_hpke_kdf_extract(kctx, prk, prklen, salt, saltlen, + labeled_ikm, labeled_ikmlen); +end: + WPACKET_cleanup(&pkt); + OPENSSL_cleanse(labeled_ikm, labeled_ikmlen); + OPENSSL_free(labeled_ikm); + return ret; +} + +/* + * See RFC 9180 Section 4 LabelExpand() + */ +int ossl_hpke_labeled_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const char *protocol_label, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *info, size_t infolen) +{ + int ret = 0; + size_t label_hpkev1len = 0; + size_t protocol_labellen = 0; + size_t labellen = 0; + size_t labeled_infolen = 0; + unsigned char *labeled_info = NULL; + WPACKET pkt; + + label_hpkev1len = strlen(LABEL_HPKEV1); + protocol_labellen = strlen(protocol_label); + labellen = strlen(label); + labeled_infolen = 2 + okmlen + prklen + label_hpkev1len + + protocol_labellen + suiteidlen + labellen + infolen; + labeled_info = OPENSSL_malloc(labeled_infolen); + if (labeled_info == NULL) + return 0; + + /* labeled_info = concat(okmlen, "HPKE-v1", suiteid, label, info) */ + if (!WPACKET_init_static_len(&pkt, labeled_info, labeled_infolen, 0) + || !WPACKET_put_bytes_u16(&pkt, okmlen) + || !WPACKET_memcpy(&pkt, LABEL_HPKEV1, label_hpkev1len) + || !WPACKET_memcpy(&pkt, protocol_label, protocol_labellen) + || !WPACKET_memcpy(&pkt, suiteid, suiteidlen) + || !WPACKET_memcpy(&pkt, label, labellen) + || !WPACKET_memcpy(&pkt, info, infolen) + || !WPACKET_get_total_written(&pkt, &labeled_infolen) + || !WPACKET_finish(&pkt)) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + goto end; + } + + ret = ossl_hpke_kdf_expand(kctx, okm, okmlen, + prk, prklen, labeled_info, labeled_infolen); +end: + WPACKET_cleanup(&pkt); + OPENSSL_free(labeled_info); + return ret; +} + +/* Common code to create a HKDF ctx */ +EVP_KDF_CTX *ossl_kdf_ctx_create(const char *kdfname, const char *mdname, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_KDF *kdf; + EVP_KDF_CTX *kctx = NULL; + + kdf = EVP_KDF_fetch(libctx, kdfname, propq); + if (kdf == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_FETCH_FAILED); + return NULL; + } + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx != NULL && mdname != NULL) { + OSSL_PARAM params[3], *p = params; + + if (mdname != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)propq, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + EVP_KDF_CTX_free(kctx); + return NULL; + } + } + return kctx; +} + +/* + * @brief look for a label into the synonym tables, and return its id + * @param st is the string value + * @param synp is the synonyms labels array + * @param arrsize is the previous array size + * @return 0 when not found, else the matching item id. + */ +static uint16_t synonyms_name2id(const char *st, const synonymttab_t *synp, + size_t arrsize) +{ + size_t i, j; + + for (i = 0; i < arrsize; ++i) { + for (j = 0; j < OSSL_NELEM(synp[i].synonyms); ++j) { + if (OPENSSL_strcasecmp(st, synp[i].synonyms[j]) == 0) + return synp[i].id; + } + } + return 0; +} + +/* + * @brief map a string to a HPKE suite based on synonym tables + * @param str is the string value + * @param suite is the resulting suite + * @return 1 for success, otherwise failure + */ +int ossl_hpke_str2suite(const char *suitestr, OSSL_HPKE_SUITE *suite) +{ + uint16_t kem = 0, kdf = 0, aead = 0; + char *st = NULL, *instrcp = NULL; + size_t inplen; + int labels = 0, result = 0; + int delim_count = 0; + + if (suitestr == NULL || suitestr[0] == 0x00 || suite == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + inplen = OPENSSL_strnlen(suitestr, OSSL_HPKE_MAX_SUITESTR); + if (inplen >= OSSL_HPKE_MAX_SUITESTR) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + /* + * we don't want a delimiter at the end of the string; + * strtok_r/s() doesn't care about that, so we should + */ + if (suitestr[inplen - 1] == OSSL_HPKE_STR_DELIMCHAR) + return 0; + /* We want exactly two delimiters in the input string */ + for (st = (char *)suitestr; *st != '\0'; st++) { + if (*st == OSSL_HPKE_STR_DELIMCHAR) + delim_count++; + } + if (delim_count != 2) + return 0; + + /* Duplicate `suitestr` to allow its parsing */ + instrcp = OPENSSL_memdup(suitestr, inplen + 1); + if (instrcp == NULL) + goto fail; + + /* See if it contains a mix of our strings and numbers */ + st = instrcp; + + while (st != NULL && labels < 3) { + char *cp = strchr(st, OSSL_HPKE_STR_DELIMCHAR); + + /* add a NUL like strtok would if we're not at the end */ + if (cp != NULL) + *cp = '\0'; + + /* check if string is known or number and if so handle appropriately */ + if (labels == 0 + && (kem = synonyms_name2id(st, kemstrtab, + OSSL_NELEM(kemstrtab))) == 0) + goto fail; + else if (labels == 1 + && (kdf = synonyms_name2id(st, kdfstrtab, + OSSL_NELEM(kdfstrtab))) == 0) + goto fail; + else if (labels == 2 + && (aead = synonyms_name2id(st, aeadstrtab, + OSSL_NELEM(aeadstrtab))) == 0) + goto fail; + + if (cp == NULL) + st = NULL; + else + st = cp + 1; + ++labels; + } + if (st != NULL || labels != 3) + goto fail; + suite->kem_id = kem; + suite->kdf_id = kdf; + suite->aead_id = aead; + result = 1; + +fail: + OPENSSL_free(instrcp); + return result; +} diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index 92481d4751..acc32769a8 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -22,9 +22,8 @@ #include #include #include "internal/sockets.h" -#include "internal/cryptlib.h" /* for ossl_assert() */ +#include "internal/common.h" /* for ossl_assert() */ -#define HAS_PREFIX(str, prefix) (strncmp(str, prefix, sizeof(prefix) - 1) == 0) #define HTTP_PREFIX "HTTP/" #define HTTP_VERSION_PATT "1." /* allow 1.x */ #define HTTP_VERSION_STR_LEN sizeof(HTTP_VERSION_PATT) /* == strlen("1.0") */ @@ -57,6 +56,7 @@ struct ossl_http_req_ctx_st { BIO *mem; /* Mem BIO holding request header or response */ BIO *req; /* BIO holding the request provided by caller */ int method_POST; /* HTTP method is POST (else GET) */ + int text; /* Request content type is (likely) text */ char *expected_ct; /* Optional expected Content-Type */ int expect_asn1; /* Response must be ASN.1-encoded */ unsigned char *pos; /* Current position sending data */ @@ -75,16 +75,18 @@ struct ossl_http_req_ctx_st { #define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */ #define OHS_ADD_HEADERS (1 | OHS_NOREAD) /* Adding header lines to request */ #define OHS_WRITE_INIT (2 | OHS_NOREAD) /* 1st call: ready to start send */ -#define OHS_WRITE_HDR (3 | OHS_NOREAD) /* Request header being sent */ -#define OHS_WRITE_REQ (4 | OHS_NOREAD) /* Request contents being sent */ -#define OHS_FLUSH (5 | OHS_NOREAD) /* Request being flushed */ +#define OHS_WRITE_HDR1 (3 | OHS_NOREAD) /* Request header to be sent */ +#define OHS_WRITE_HDR (4 | OHS_NOREAD) /* Request header being sent */ +#define OHS_WRITE_REQ (5 | OHS_NOREAD) /* Request content being sent */ +#define OHS_FLUSH (6 | OHS_NOREAD) /* Request being flushed */ #define OHS_FIRSTLINE 1 /* First line of response being read */ #define OHS_HEADERS 2 /* MIME headers of response being read */ -#define OHS_REDIRECT 3 /* MIME headers being read, expecting Location */ -#define OHS_ASN1_HEADER 4 /* ASN1 sequence header (tag+length) being read */ -#define OHS_ASN1_CONTENT 5 /* ASN1 content octets being read */ -#define OHS_ASN1_DONE (6 | OHS_NOREAD) /* ASN1 content read completed */ -#define OHS_STREAM (7 | OHS_NOREAD) /* HTTP content stream to be read */ +#define OHS_HEADERS_ERROR 3 /* MIME headers of resp. being read after error */ +#define OHS_REDIRECT 4 /* MIME headers being read, expecting Location */ +#define OHS_ASN1_HEADER 5 /* ASN1 sequence header (tag+length) being read */ +#define OHS_ASN1_CONTENT 6 /* ASN1 content octets being read */ +#define OHS_ASN1_DONE (7 | OHS_NOREAD) /* ASN1 content read completed */ +#define OHS_STREAM (8 | OHS_NOREAD) /* HTTP content stream to be read */ /* Low-level HTTP API implementation */ @@ -297,9 +299,14 @@ static int set1_content(OSSL_HTTP_REQ_CTX *rctx, return 0; } - if (content_type != NULL - && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0) - return 0; + if (content_type == NULL) { + rctx->text = 1; /* assuming text by default, used just for tracing */ + } else { + if (OPENSSL_strncasecmp(content_type, "text/", 5) == 0) + rctx->text = 1; + if (BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0) + return 0; + } /* * BIO_CTRL_INFO yields the data length at least for memory BIOs, but for @@ -413,10 +420,10 @@ static int parse_http_line1(char *line, int *found_keep_alive) int i, retcode, err; char *code, *reason, *end; - if (!HAS_PREFIX(line, HTTP_PREFIX_VERSION)) + if (!CHECK_AND_SKIP_PREFIX(line, HTTP_PREFIX_VERSION)) goto err; /* above HTTP 1.0, connection persistence is the default */ - *found_keep_alive = line[strlen(HTTP_PREFIX_VERSION)] > '0'; + *found_keep_alive = *line > '0'; /* Skip to first whitespace (past protocol info) */ for (code = line; *code != '\0' && !ossl_isspace(*code); code++) @@ -488,13 +495,17 @@ static int parse_http_line1(char *line, int *found_keep_alive) static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len) { - if (rctx->max_resp_len != 0 && len > rctx->max_resp_len) + if (rctx->max_resp_len != 0 && len > rctx->max_resp_len) { ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED, "length=%zu, max=%zu", len, rctx->max_resp_len); - if (rctx->resp_len != 0 && rctx->resp_len != len) + return 0; + } + if (rctx->resp_len != 0 && rctx->resp_len != len) { ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH, "ASN.1 length=%zu, Content-Length=%zu", len, rctx->resp_len); + return 0; + } rctx->resp_len = len; return 1; } @@ -521,7 +532,7 @@ static int may_still_retry(time_t max_time, int *ptimeout) int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) { int i, found_expected_ct = 0, found_keep_alive = 0; - int found_text_ct = 0; + int got_text = 1; long n; size_t resp_len; const unsigned char *p; @@ -545,7 +556,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) } else { (void)ERR_set_mark(); n = BIO_gets(rctx->rbio, buf, rctx->buf_size); - if (n == -2) { /* unsupported method */ + if (n == -2) { /* some BIOs, such as SSL, do not support "gets" */ (void)ERR_pop_to_mark(); n = BIO_get_line(rctx->rbio, buf, rctx->buf_size); } else { @@ -576,30 +587,32 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) /* fall through */ case OHS_WRITE_INIT: rctx->len_to_send = BIO_get_mem_data(rctx->mem, &rctx->pos); - rctx->state = OHS_WRITE_HDR; - if (OSSL_TRACE_ENABLED(HTTP)) - OSSL_TRACE(HTTP, "Sending request header:\n"); + rctx->state = OHS_WRITE_HDR1; /* fall through */ + case OHS_WRITE_HDR1: case OHS_WRITE_HDR: /* Copy some chunk of data from rctx->mem to rctx->wbio */ case OHS_WRITE_REQ: /* Copy some chunk of data from rctx->req to rctx->wbio */ if (rctx->len_to_send > 0) { - if (OSSL_TRACE_ENABLED(HTTP) - && rctx->state == OHS_WRITE_HDR && rctx->len_to_send <= INT_MAX) - OSSL_TRACE2(HTTP, "%.*s", (int)rctx->len_to_send, rctx->pos); + size_t sz; - i = BIO_write(rctx->wbio, rctx->pos, rctx->len_to_send); - if (i <= 0) { + if (!BIO_write_ex(rctx->wbio, rctx->pos, rctx->len_to_send, &sz)) { if (BIO_should_retry(rctx->wbio)) return -1; rctx->state = OHS_ERROR; return 0; } - rctx->pos += i; - rctx->len_to_send -= i; + if (OSSL_TRACE_ENABLED(HTTP) && rctx->state == OHS_WRITE_HDR1) + OSSL_TRACE(HTTP, "Sending request: [\n"); + OSSL_TRACE_STRING(HTTP, rctx->state != OHS_WRITE_REQ || rctx->text, + rctx->state != OHS_WRITE_REQ, rctx->pos, sz); + if (rctx->state == OHS_WRITE_HDR1) + rctx->state = OHS_WRITE_HDR; + rctx->pos += sz; + rctx->len_to_send -= sz; goto next_io; } if (rctx->state == OHS_WRITE_HDR) { @@ -618,6 +631,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) rctx->len_to_send = n; goto next_io; } + if (OSSL_TRACE_ENABLED(HTTP)) + OSSL_TRACE(HTTP, "]\n"); rctx->state = OHS_FLUSH; /* fall through */ @@ -677,7 +692,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) /* dump all response header lines */ if (OSSL_TRACE_ENABLED(HTTP)) { if (rctx->state == OHS_FIRSTLINE) - OSSL_TRACE(HTTP, "Received response header:\n"); + OSSL_TRACE(HTTP, "Received response header: [\n"); OSSL_TRACE1(HTTP, "%s", buf); } @@ -697,8 +712,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) /* redirection is not supported/recommended for POST */ /* fall through */ default: - rctx->state = OHS_ERROR; - goto next_line; + rctx->state = OHS_HEADERS_ERROR; + goto next_line; /* continue parsing and reporting header */ } } key = buf; @@ -720,9 +735,18 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) return 0; } if (OPENSSL_strcasecmp(key, "Content-Type") == 0) { + got_text = OPENSSL_strncasecmp(value, "text/", 5) == 0; if (rctx->state == OHS_HEADERS && rctx->expected_ct != NULL) { - if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0) { + const char *semicolon; + + if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0 + /* ignore past ';' unless expected_ct contains ';' */ + && (strchr(rctx->expected_ct, ';') != NULL + || (semicolon = strchr(value, ';')) == NULL + || (size_t)(semicolon - value) != strlen(rctx->expected_ct) + || OPENSSL_strncasecmp(rctx->expected_ct, value, + semicolon - value) != 0)) { ERR_raise_data(ERR_LIB_HTTP, HTTP_R_UNEXPECTED_CONTENT_TYPE, "expected=%s, actual=%s", @@ -731,8 +755,6 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) } found_expected_ct = 1; } - if (OPENSSL_strncasecmp(value, "text/", 5) == 0) - found_text_ct = 1; } /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */ @@ -761,6 +783,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) } if (*p != '\0') /* not end of headers */ goto next_line; + if (OSSL_TRACE_ENABLED(HTTP)) + OSSL_TRACE(HTTP, "]\n"); if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */ && !found_keep_alive /* otherwise there is no change */) { @@ -772,10 +796,20 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) rctx->keep_alive = 0; } - if (rctx->state == OHS_ERROR) { - if (OSSL_TRACE_ENABLED(HTTP) - && found_text_ct && BIO_get_mem_data(rctx->mem, &p) > 0) - OSSL_TRACE1(HTTP, "%s", p); + if (rctx->state == OHS_HEADERS_ERROR) { + if (OSSL_TRACE_ENABLED(HTTP)) { + int printed_final_nl = 0; + + OSSL_TRACE(HTTP, "Received error response body: [\n"); + while ((n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size)) > 0 + || (OSSL_sleep(100), BIO_should_retry(rctx->rbio))) { + OSSL_TRACE_STRING(HTTP, got_text, 1, rctx->buf, n); + if (n > 0) + printed_final_nl = rctx->buf[n - 1] == '\n'; + } + OSSL_TRACE1(HTTP, "%s]\n", printed_final_nl ? "" : "\n"); + (void)printed_final_nl; /* avoid warning unless enable-trace */ + } return 0; } @@ -1147,13 +1181,12 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, const char *expected_ct, int expect_asn1, size_t max_resp_len, int timeout) { - char *current_url, *redirection_url = NULL; + char *current_url; int n_redirs = 0; char *host; char *port; char *path; int use_ssl; - OSSL_HTTP_REQ_CTX *rctx = NULL; BIO *resp = NULL; time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; @@ -1165,6 +1198,9 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, return NULL; for (;;) { + OSSL_HTTP_REQ_CTX *rctx; + char *redirection_url; + if (!OSSL_HTTP_parse_url(current_url, &use_ssl, NULL /* user */, &host, &port, NULL /* port_num */, &path, NULL, NULL)) break; @@ -1173,6 +1209,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, use_ssl, bio, rbio, bio_update_fn, arg, buf_size, timeout); new_rpath: + redirection_url = NULL; if (rctx != NULL) { if (!OSSL_HTTP_set1_request(rctx, path, headers, NULL /* content_type */, @@ -1182,9 +1219,9 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, 0 /* no keep_alive */)) { OSSL_HTTP_REQ_CTX_free(rctx); rctx = NULL; - } else { + } else { resp = OSSL_HTTP_exchange(rctx, &redirection_url); - } + } } OPENSSL_free(path); if (resp == NULL && redirection_url != NULL) { @@ -1199,7 +1236,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, OPENSSL_free(host); OPENSSL_free(port); (void)OSSL_HTTP_close(rctx, 1); - rctx = NULL; BIO_free(resp); OPENSSL_free(current_url); return NULL; @@ -1209,7 +1245,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, OPENSSL_free(host); OPENSSL_free(port); (void)OSSL_HTTP_close(rctx, 1); - rctx = NULL; continue; } /* if redirection not allowed, ignore it */ @@ -1219,7 +1254,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, OPENSSL_free(port); if (!OSSL_HTTP_close(rctx, resp != NULL)) { BIO_free(resp); - rctx = NULL; resp = NULL; } break; @@ -1404,15 +1438,15 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, continue; /* Check for HTTP/1.x */ - if (!HAS_PREFIX(mbuf, HTTP_PREFIX) != 0) { + mbufp = mbuf; + if (!CHECK_AND_SKIP_PREFIX(mbufp, HTTP_PREFIX)) { ERR_raise(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR); BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n", prog); /* Wrong protocol, not even HTTP, so stop reading headers */ goto end; } - mbufp = mbuf + strlen(HTTP_PREFIX); - if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT) != 0) { + if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT)) { ERR_raise(ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION); BIO_printf(bio_err, "%s: HTTP CONNECT failed, bad HTTP version %.*s\n", @@ -1423,6 +1457,8 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, /* RFC 7231 4.3.6: any 2xx status code is valid */ if (!HAS_PREFIX(mbufp, " 2")) { + if (ossl_isspace(*mbufp)) + mbufp++; /* chop any trailing whitespace */ while (read_len > 0 && ossl_isspace(mbuf[read_len - 1])) read_len--; @@ -1441,7 +1477,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, do { /* * This does not necessarily catch the case when the full - * HTTP response came in in more than a single TCP message. + * HTTP response came in more than a single TCP message. */ read_len = BIO_gets(fbio, mbuf, BUF_SIZE); } while (read_len > 2); diff --git a/crypto/init.c b/crypto/init.c index 983d76e457..33c739c30e 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -186,8 +186,15 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) * pulling in all the error strings during static linking */ #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) + void *err; + + if (!err_shelve_state(&err)) + return 0; + OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n"); ret = ossl_err_load_crypto_strings(); + + err_unshelve_state(err); #endif return ret; } @@ -389,6 +396,10 @@ void OPENSSL_cleanup(void) #ifndef OPENSSL_NO_COMP OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n"); ossl_comp_zlib_cleanup(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_brotli_cleanup()\n"); + ossl_comp_brotli_cleanup(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zstd_cleanup()\n"); + ossl_comp_zstd_cleanup(); #endif if (async_inited) { @@ -706,10 +717,8 @@ int OPENSSL_atexit(void (*handler)(void)) } #endif - if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) return 0; - } newhand->handler = handler; newhand->next = stop_handlers; diff --git a/crypto/lhash/lh_stats.c b/crypto/lhash/lh_stats.c index ea0a3252a6..f128c0ba42 100644 --- a/crypto/lhash/lh_stats.c +++ b/crypto/lhash/lh_stats.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index 217f28179b..0a475b71d8 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -48,14 +48,8 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c) { OPENSSL_LHASH *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { - /* - * Do not set the error code, because the ERR code uses LHASH - * and we want to avoid possible endless error loop. - * ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); - */ + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) return NULL; - } if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL) goto err; ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c); @@ -264,7 +258,7 @@ static void contract(OPENSSL_LHASH *lh) n = OPENSSL_realloc(lh->b, (unsigned int)(sizeof(OPENSSL_LH_NODE *) * lh->pmax)); if (n == NULL) { - /* fputs("realloc error in lhash",stderr); */ + /* fputs("realloc error in lhash", stderr); */ lh->error++; } else { lh->b = n; diff --git a/crypto/mem.c b/crypto/mem.c index cc19856771..eef1165708 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -176,9 +176,15 @@ void ossl_malloc_setup_failures(void) void *CRYPTO_malloc(size_t num, const char *file, int line) { + void *ptr; + INCREMENT(malloc_count); - if (malloc_impl != CRYPTO_malloc) - return malloc_impl(num, file, line); + if (malloc_impl != CRYPTO_malloc) { + ptr = malloc_impl(num, file, line); + if (ptr != NULL || num == 0) + return ptr; + goto err; + } if (num == 0) return NULL; @@ -193,7 +199,20 @@ void *CRYPTO_malloc(size_t num, const char *file, int line) allow_customize = 0; } - return malloc(num); + ptr = malloc(num); + if (ptr != NULL) + return ptr; + err: + /* + * ossl_err_get_state_int() in err.c uses CRYPTO_zalloc(num, NULL, 0) for + * ERR_STATE allocation. Prevent mem alloc error loop while reporting error. + */ + if (file != NULL || line != 0) { + ERR_new(); + ERR_set_debug(file, line, NULL); + ERR_set_error(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE, NULL); + } + return NULL; } void *CRYPTO_zalloc(size_t num, const char *file, int line) diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index e1a3193477..557c697c9a 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -17,6 +17,7 @@ */ #include "internal/e_os.h" #include +#include #include @@ -65,6 +66,18 @@ VirtualLock( # include # include #endif +#ifndef HAVE_MADVISE +# if defined(MADV_DONTDUMP) +# define HAVE_MADVISE 1 +# else +# define HAVE_MADVISE 0 +# endif +#endif +#if HAVE_MADVISE +# undef NO_MADVISE +#else +# define NO_MADVISE +#endif #define CLEAR(p, s) OPENSSL_cleanse(p, s) #ifndef PAGE_SIZE @@ -141,18 +154,27 @@ int CRYPTO_secure_malloc_initialized(void) void *CRYPTO_secure_malloc(size_t num, const char *file, int line) { #ifndef OPENSSL_NO_SECURE_MEMORY - void *ret; + void *ret = NULL; size_t actual_size; + int reason = CRYPTO_R_SECURE_MALLOC_FAILURE; if (!secure_mem_initialized) { return CRYPTO_malloc(num, file, line); } - if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) - return NULL; + if (!CRYPTO_THREAD_write_lock(sec_malloc_lock)) { + reason = ERR_R_CRYPTO_LIB; + goto err; + } ret = sh_malloc(num); actual_size = ret ? sh_actual_size(ret) : 0; secure_mem_used += actual_size; CRYPTO_THREAD_unlock(sec_malloc_lock); + err: + if (ret == NULL && (file != NULL || line != 0)) { + ERR_new(); + ERR_set_debug(file, line, NULL); + ERR_set_error(ERR_LIB_CRYPTO, reason, NULL); + } return ret; #else return CRYPTO_malloc(num, file, line); @@ -557,7 +579,7 @@ static int sh_init(size_t size, size_t minsize) if (mlock(sh.arena, sh.arena_size) < 0) ret = 2; #endif -#ifdef MADV_DONTDUMP +#ifndef NO_MADVISE if (madvise(sh.arena, sh.arena_size, MADV_DONTDUMP) < 0) ret = 2; #endif diff --git a/crypto/modes/aes-gcm-armv8-unroll8_64.S b/crypto/modes/aes-gcm-armv8-unroll8_64.S index 66d4b41499..a53d209f2c 100644 --- a/crypto/modes/aes-gcm-armv8-unroll8_64.S +++ b/crypto/modes/aes-gcm-armv8-unroll8_64.S @@ -1062,7 +1062,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: ins v18.d[0], v24.d[1] //GHASH final-7 block - mid eor v27.8b, v27.8b, v8.8b //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in .inst 0xce017529 //eor3 v9.16b, v9.16b, v1.16b, v29.16b //AES final-6 block - result @@ -1083,7 +1083,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: pmull v26.1q, v8.1d, v23.1d //GHASH final-6 block - low eor v27.8b, v27.8b, v8.8b //GHASH final-6 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v27.1q, v27.1d, v24.1d //GHASH final-6 block - mid pmull2 v28.1q, v8.2d, v23.2d //GHASH final-6 block - high @@ -1112,7 +1112,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: .inst 0xce037529 //eor3 v9.16b, v9.16b, v3.16b, v29.16b //AES final-4 block - result pmull v26.1q, v8.1d, v22.1d //GHASH final-5 block - low - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v27.1q, v27.2d, v21.2d //GHASH final-5 block - mid eor v19.16b, v19.16b, v26.16b //GHASH final-5 block - low @@ -1129,7 +1129,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: eor v8.16b, v8.16b, v16.16b //feed in partial tag ins v27.d[0], v8.d[1] //GHASH final-4 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v28.1q, v8.2d, v20.2d //GHASH final-4 block - high eor v27.8b, v27.8b, v8.8b //GHASH final-4 block - mid @@ -1153,7 +1153,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: rev64 v8.16b, v9.16b //GHASH final-3 block eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-3 block - mid ldr q24, [x3, #96] //load h4k | h3k @@ -1186,7 +1186,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: ins v27.d[0], v8.d[1] //GHASH final-2 block - mid ldr q23, [x3, #80] //load h3l | h3h ext v23.16b, v23.16b, v23.16b, #8 - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v27.8b, v27.8b, v8.8b //GHASH final-2 block - mid .inst 0xce067529 //eor3 v9.16b, v9.16b, v6.16b, v29.16b //AES final-1 block - result @@ -1211,7 +1211,7 @@ unroll8_eor3_aes_gcm_enc_128_kernel: eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-1 block - mid .inst 0xce077529 //eor3 v9.16b, v9.16b, v7.16b, v29.16b //AES final block - result @@ -2354,7 +2354,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: pmull v19.1q, v8.1d, v25.1d //GHASH final-7 block - low ins v27.d[0], v8.d[1] //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ldr q9, [x0], #16 //AES final-6 block - load ciphertext eor v27.8b, v27.8b, v8.8b //GHASH final-7 block - mid @@ -2376,7 +2376,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: pmull v26.1q, v8.1d, v23.1d //GHASH final-6 block - low ldr q9, [x0], #16 //AES final-5 block - load ciphertext - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v27.1q, v27.1d, v24.1d //GHASH final-6 block - mid st1 { v12.16b}, [x2], #16 //AES final-6 block - store result @@ -2404,7 +2404,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: ins v27.d[1], v27.d[0] //GHASH final-5 block - mid pmull v26.1q, v8.1d, v22.1d //GHASH final-5 block - low - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v27.1q, v27.2d, v21.2d //GHASH final-5 block - mid pmull2 v28.1q, v8.2d, v22.2d //GHASH final-5 block - high @@ -2420,7 +2420,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: ldr q9, [x0], #16 //AES final-3 block - load ciphertext ins v27.d[0], v8.d[1] //GHASH final-4 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v28.1q, v8.2d, v20.2d //GHASH final-4 block - high pmull v26.1q, v8.1d, v20.1d //GHASH final-4 block - low @@ -2457,7 +2457,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: pmull v26.1q, v8.1d, v25.1d //GHASH final-3 block - low pmull2 v28.1q, v8.2d, v25.2d //GHASH final-3 block - high - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in .inst 0xce05752c //eor3 v12.16b, v9.16b, v5.16b, v29.16b //AES final-2 block - result eor v19.16b, v19.16b, v26.16b //GHASH final-3 block - low @@ -2474,7 +2474,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: eor v8.16b, v8.16b, v16.16b //feed in partial tag ldr q23, [x3, #80] //load h3l | h3h ext v23.16b, v23.16b, v23.16b, #8 - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-2 block - mid @@ -2502,7 +2502,7 @@ unroll8_eor3_aes_gcm_dec_128_kernel: eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-1 block - mid @@ -3773,7 +3773,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: ldr q9, [x0], #16 //AES final-6 block - load plaintext eor v27.8b, v27.8b, v8.8b //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v19.1q, v8.1d, v25.1d //GHASH final-7 block - low pmull2 v17.1q, v8.2d, v25.2d //GHASH final-7 block - high @@ -3795,7 +3795,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: pmull v26.1q, v8.1d, v23.1d //GHASH final-6 block - low .inst 0xce027529 //eor3 v9.16b, v9.16b, v2.16b, v29.16b //AES final-5 block - result - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v28.1q, v8.2d, v23.2d //GHASH final-6 block - high eor v27.8b, v27.8b, v8.8b //GHASH final-6 block - mid @@ -3828,7 +3828,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: pmull2 v27.1q, v27.2d, v21.2d //GHASH final-5 block - mid .inst 0xce037529 //eor3 v9.16b, v9.16b, v3.16b, v29.16b //AES final-4 block - result - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v18.16b, v18.16b, v27.16b //GHASH final-5 block - mid .L192_enc_blocks_more_than_4: //blocks left > 4 @@ -3848,7 +3848,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: eor v27.8b, v27.8b, v8.8b //GHASH final-4 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v19.16b, v19.16b, v26.16b //GHASH final-4 block - low pmull v27.1q, v27.1d, v21.1d //GHASH final-4 block - mid @@ -3863,7 +3863,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: rev64 v8.16b, v9.16b //GHASH final-3 block eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ldr q9, [x0], #16 //AES final-2 block - load plaintext ldr q25, [x3, #112] //load h4l | h4h @@ -3901,7 +3901,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: pmull v26.1q, v8.1d, v23.1d //GHASH final-2 block - low pmull2 v28.1q, v8.2d, v23.2d //GHASH final-2 block - high - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v27.1q, v27.1d, v24.1d //GHASH final-2 block - mid @@ -3935,7 +3935,7 @@ unroll8_eor3_aes_gcm_enc_192_kernel: .inst 0xce077529 //eor3 v9.16b, v9.16b, v7.16b, v29.16b //AES final block - result pmull2 v27.1q, v27.2d, v21.2d //GHASH final-1 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v18.16b, v18.16b, v27.16b //GHASH final-1 block - mid eor v17.16b, v17.16b, v28.16b //GHASH final-1 block - high @@ -5191,7 +5191,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: .inst 0xce01752c //eor3 v12.16b, v9.16b, v1.16b, v29.16b //AES final-6 block - result pmull v18.1q, v27.1d, v18.1d //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in .L192_dec_blocks_more_than_6: //blocks left > 6 rev64 v8.16b, v9.16b //GHASH final-6 block @@ -5202,7 +5202,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: ins v27.d[0], v8.d[1] //GHASH final-6 block - mid eor v27.8b, v27.8b, v8.8b //GHASH final-6 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v28.1q, v8.2d, v23.2d //GHASH final-6 block - high st1 { v12.16b}, [x2], #16 //AES final-6 block - store result @@ -5235,7 +5235,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: pmull2 v27.1q, v27.2d, v21.2d //GHASH final-5 block - mid eor v19.16b, v19.16b, v26.16b //GHASH final-5 block - low - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in st1 { v12.16b}, [x2], #16 //AES final-5 block - store result eor v18.16b, v18.16b, v27.16b //GHASH final-5 block - mid @@ -5245,7 +5245,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: rev64 v8.16b, v9.16b //GHASH final-4 block eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ldr q9, [x0], #16 //AES final-3 block - load ciphertext ins v27.d[0], v8.d[1] //GHASH final-4 block - mid @@ -5276,7 +5276,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: pmull2 v28.1q, v8.2d, v25.2d //GHASH final-3 block - high eor v17.16b, v17.16b, v28.16b //GHASH final-3 block - high - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v26.1q, v8.1d, v25.1d //GHASH final-3 block - low st1 { v12.16b}, [x2], #16 //AES final-3 block - store result @@ -5310,7 +5310,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: pmull v26.1q, v8.1d, v23.1d //GHASH final-2 block - low pmull v27.1q, v27.1d, v24.1d //GHASH final-2 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v19.16b, v19.16b, v26.16b //GHASH final-2 block - low st1 { v12.16b}, [x2], #16 //AES final-2 block - store result @@ -5325,7 +5325,7 @@ unroll8_eor3_aes_gcm_dec_192_kernel: ext v22.16b, v22.16b, v22.16b, #8 eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ldr q21, [x3, #48] //load h2k | h1k pmull v26.1q, v8.1d, v22.1d //GHASH final-1 block - low @@ -6710,7 +6710,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: ins v27.d[0], v8.d[1] //GHASH final-7 block - mid ins v18.d[0], v24.d[1] //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v27.8b, v27.8b, v8.8b //GHASH final-7 block - mid .inst 0xce017529 //eor3 v9.16b, v9.16b, v1.16b, v29.16b //AES final-6 block - result @@ -6738,7 +6738,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: pmull v27.1q, v27.1d, v24.1d //GHASH final-6 block - mid .inst 0xce027529 //eor3 v9.16b, v9.16b, v2.16b, v29.16b //AES final-5 block - result - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v18.16b, v18.16b, v27.16b //GHASH final-6 block - mid eor v17.16b, v17.16b, v28.16b //GHASH final-6 block - high @@ -6763,7 +6763,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: pmull v26.1q, v8.1d, v22.1d //GHASH final-5 block - low pmull2 v27.1q, v27.2d, v21.2d //GHASH final-5 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v19.16b, v19.16b, v26.16b //GHASH final-5 block - low eor v18.16b, v18.16b, v27.16b //GHASH final-5 block - mid @@ -6789,7 +6789,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: pmull v27.1q, v27.1d, v21.1d //GHASH final-4 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v18.16b, v18.16b, v27.16b //GHASH final-4 block - mid eor v17.16b, v17.16b, v28.16b //GHASH final-4 block - high @@ -6817,7 +6817,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: pmull v26.1q, v8.1d, v25.1d //GHASH final-3 block - low .inst 0xce057529 //eor3 v9.16b, v9.16b, v5.16b, v29.16b //AES final-2 block - result - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v18.16b, v18.16b, v27.16b //GHASH final-3 block - mid eor v19.16b, v19.16b, v26.16b //GHASH final-3 block - low @@ -6835,7 +6835,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: ins v27.d[0], v8.d[1] //GHASH final-2 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v28.1q, v8.2d, v23.2d //GHASH final-2 block - high .inst 0xce067529 //eor3 v9.16b, v9.16b, v6.16b, v29.16b //AES final-1 block - result @@ -6859,7 +6859,7 @@ unroll8_eor3_aes_gcm_enc_256_kernel: ldr q9, [x0], #16 //AES final block - load plaintext eor v8.16b, v8.16b, v16.16b //feed in partial tag - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-1 block - mid pmull2 v28.1q, v8.2d, v22.2d //GHASH final-1 block - high @@ -8243,7 +8243,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: pmull2 v17.1q, v8.2d, v25.2d //GHASH final-7 block - high eor v27.8b, v27.8b, v8.8b //GHASH final-7 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v19.1q, v8.1d, v25.1d //GHASH final-7 block - low pmull v18.1q, v27.1d, v18.1d //GHASH final-7 block - mid @@ -8253,7 +8253,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: eor v8.16b, v8.16b, v16.16b //feed in partial tag ldr q9, [x0], #16 //AES final-5 block - load ciphertext - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in ins v27.d[0], v8.d[1] //GHASH final-6 block - mid st1 { v12.16b}, [x2], #16 //AES final-6 block - store result @@ -8293,7 +8293,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: eor v19.16b, v19.16b, v26.16b //GHASH final-5 block - low eor v18.16b, v18.16b, v27.16b //GHASH final-5 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in .L256_dec_blocks_more_than_4: //blocks left > 4 rev64 v8.16b, v9.16b //GHASH final-4 block @@ -8303,7 +8303,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: ins v27.d[0], v8.d[1] //GHASH final-4 block - mid ldr q9, [x0], #16 //AES final-3 block - load ciphertext - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v26.1q, v8.1d, v20.1d //GHASH final-4 block - low pmull2 v28.1q, v8.2d, v20.2d //GHASH final-4 block - high @@ -8340,7 +8340,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: pmull v26.1q, v8.1d, v25.1d //GHASH final-3 block - low pmull2 v28.1q, v8.2d, v25.2d //GHASH final-3 block - high - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull2 v27.1q, v27.2d, v24.2d //GHASH final-3 block - mid eor v19.16b, v19.16b, v26.16b //GHASH final-3 block - low @@ -8365,7 +8365,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: eor v27.8b, v27.8b, v8.8b //GHASH final-2 block - mid eor v19.16b, v19.16b, v26.16b //GHASH final-2 block - low - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in pmull v27.1q, v27.1d, v24.1d //GHASH final-2 block - mid pmull2 v28.1q, v8.2d, v23.2d //GHASH final-2 block - high @@ -8398,7 +8398,7 @@ unroll8_eor3_aes_gcm_dec_256_kernel: pmull2 v27.1q, v27.2d, v21.2d //GHASH final-1 block - mid - movi v16.8b, #0 //supress further partial tag feed in + movi v16.8b, #0 //suppress further partial tag feed in eor v17.16b, v17.16b, v28.16b //GHASH final-1 block - high eor v18.16b, v18.16b, v27.16b //GHASH final-1 block - mid diff --git a/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl b/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl index 47b6c50fb1..d516359eb8 100644 --- a/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl +++ b/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl @@ -249,12 +249,12 @@ ######################################################################################### -# size_t unroll8_eor3_aes_gcm_enc_128_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, -# unsigned char ivec[16], -# u64 *Xi); +# size_t unroll8_eor3_aes_gcm_enc_128_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_enc_128_kernel @@ -1100,7 +1100,7 @@ ins $acc_m.d[0], $h78k.d[1] @ GHASH final-7 block - mid eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor3 $res1b, $ctr_t1b, $ctr1b, $t1.16b @ AES final-6 block - result @@ -1121,7 +1121,7 @@ pmull $rk3q1, $res0.1d, $h7.1d @ GHASH final-6 block - low eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-6 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk4v.1q, $rk4v.1d, $h78k.1d @ GHASH final-6 block - mid pmull2 $rk2q1, $res0.2d, $h7.2d @ GHASH final-6 block - high @@ -1150,7 +1150,7 @@ eor3 $res1b, $ctr_t1b, $ctr3b, $t1.16b @ AES final-4 block - result pmull $rk3q1, $res0.1d, $h6.1d @ GHASH final-5 block - low - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk4v.1q, $rk4v.2d, $h56k.2d @ GHASH final-5 block - mid eor $acc_lb, $acc_lb, $rk3 @ GHASH final-5 block - low @@ -1167,7 +1167,7 @@ eor $res0b, $res0b, $t0.16b @ feed in partial tag ins $rk4v.d[0], $res0.d[1] @ GHASH final-4 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk2q1, $res0.2d, $h5.2d @ GHASH final-4 block - high eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-4 block - mid @@ -1191,7 +1191,7 @@ rev64 $res0b, $res1b @ GHASH final-3 block eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-3 block - mid ldr $h34kq, [$current_tag, #96] @ load h4k | h3k @@ -1224,7 +1224,7 @@ ins $rk4v.d[0], $res0.d[1] @ GHASH final-2 block - mid ldr $h3q, [$current_tag, #80] @ load h3l | h3h ext $h3.16b, $h3.16b, $h3.16b, #8 - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid eor3 $res1b, $ctr_t1b, $ctr6b, $t1.16b @ AES final-1 block - result @@ -1249,7 +1249,7 @@ eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-1 block - mid eor3 $res1b, $ctr_t1b, $ctr7b, $t1.16b @ AES final block - result @@ -1348,12 +1348,12 @@ ___ ######################################################################################### -# size_t unroll8_eor3_aes_gcm_dec_128_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# u64 *Xi, -# unsigned char ivec[16], -# const void *key); +# size_t unroll8_eor3_aes_gcm_dec_128_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_dec_128_kernel @@ -2187,7 +2187,7 @@ pmull $acc_l.1q, $res0.1d, $h8.1d @ GHASH final-7 block - low ins $rk4v.d[0], $res0.d[1] @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ldr $res1q, [$input_ptr], #16 @ AES final-6 block - load ciphertext eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-7 block - mid @@ -2209,7 +2209,7 @@ pmull $rk3q1, $res0.1d, $h7.1d @ GHASH final-6 block - low ldr $res1q, [$input_ptr], #16 @ AES final-5 block - load ciphertext - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk4v.1q, $rk4v.1d, $h78k.1d @ GHASH final-6 block - mid st1 { $res4b}, [$output_ptr], #16 @ AES final-6 block - store result @@ -2237,7 +2237,7 @@ ins $rk4v.d[1], $rk4v.d[0] @ GHASH final-5 block - mid pmull $rk3q1, $res0.1d, $h6.1d @ GHASH final-5 block - low - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk4v.1q, $rk4v.2d, $h56k.2d @ GHASH final-5 block - mid pmull2 $rk2q1, $res0.2d, $h6.2d @ GHASH final-5 block - high @@ -2253,7 +2253,7 @@ ldr $res1q, [$input_ptr], #16 @ AES final-3 block - load ciphertext ins $rk4v.d[0], $res0.d[1] @ GHASH final-4 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk2q1, $res0.2d, $h5.2d @ GHASH final-4 block - high pmull $rk3q1, $res0.1d, $h5.1d @ GHASH final-4 block - low @@ -2290,7 +2290,7 @@ pmull $rk3q1, $res0.1d, $h4.1d @ GHASH final-3 block - low pmull2 $rk2q1, $res0.2d, $h4.2d @ GHASH final-3 block - high - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor3 $res4b, $res1b, $ctr5b, $t1.16b @ AES final-2 block - result eor $acc_lb, $acc_lb, $rk3 @ GHASH final-3 block - low @@ -2307,7 +2307,7 @@ eor $res0b, $res0b, $t0.16b @ feed in partial tag ldr $h3q, [$current_tag, #80] @ load h3l | h3h ext $h3.16b, $h3.16b, $h3.16b, #8 - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-2 block - mid @@ -2335,7 +2335,7 @@ eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-1 block - mid @@ -2502,12 +2502,12 @@ my $rk4v="v27"; ######################################################################################### -# size_t unroll8_eor3_aes_gcm_enc_192_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, -# unsigned char ivec[16], -# u64 *Xi); +# size_t unroll8_eor3_aes_gcm_enc_192_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_enc_192_kernel @@ -3416,7 +3416,7 @@ ldr $ctr_t1q, [$input_ptr], #16 @ AES final-6 block - load plaintext eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $acc_l.1q, $res0.1d, $h8.1d @ GHASH final-7 block - low pmull2 $acc_h.1q, $res0.2d, $h8.2d @ GHASH final-7 block - high @@ -3438,7 +3438,7 @@ pmull $rk3q1, $res0.1d, $h7.1d @ GHASH final-6 block - low eor3 $res1b, $ctr_t1b, $ctr2b, $t1.16b @ AES final-5 block - result - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk2q1, $res0.2d, $h7.2d @ GHASH final-6 block - high eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-6 block - mid @@ -3471,7 +3471,7 @@ pmull2 $rk4v.1q, $rk4v.2d, $h56k.2d @ GHASH final-5 block - mid eor3 $res1b, $ctr_t1b, $ctr3b, $t1.16b @ AES final-4 block - result - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-5 block - mid .L192_enc_blocks_more_than_4: @ blocks left > 4 @@ -3491,7 +3491,7 @@ eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-4 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_lb, $acc_lb, $rk3 @ GHASH final-4 block - low pmull $rk4v.1q, $rk4v.1d, $h56k.1d @ GHASH final-4 block - mid @@ -3506,7 +3506,7 @@ rev64 $res0b, $res1b @ GHASH final-3 block eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ldr $ctr_t1q, [$input_ptr], #16 @ AES final-2 block - load plaintext ldr $h4q, [$current_tag, #112] @ load h4l | h4h @@ -3544,7 +3544,7 @@ pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid @@ -3578,7 +3578,7 @@ eor3 $res1b, $ctr_t1b, $ctr7b, $t1.16b @ AES final block - result pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high @@ -3664,12 +3664,12 @@ ___ ######################################################################################### -# size_t unroll8_eor3_aes_gcm_dec_192_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, -# unsigned char ivec[16], -# u64 *Xi); +# size_t unroll8_eor3_aes_gcm_dec_192_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_dec_192_kernel @@ -4581,7 +4581,7 @@ eor3 $res4b, $res1b, $ctr1b, $t1.16b @ AES final-6 block - result pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in .L192_dec_blocks_more_than_6: @ blocks left > 6 rev64 $res0b, $res1b @ GHASH final-6 block @@ -4592,7 +4592,7 @@ ins $rk4v.d[0], $res0.d[1] @ GHASH final-6 block - mid eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-6 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk2q1, $res0.2d, $h7.2d @ GHASH final-6 block - high st1 { $res4b}, [$output_ptr], #16 @ AES final-6 block - store result @@ -4625,7 +4625,7 @@ pmull2 $rk4v.1q, $rk4v.2d, $h56k.2d @ GHASH final-5 block - mid eor $acc_lb, $acc_lb, $rk3 @ GHASH final-5 block - low - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in st1 { $res4b}, [$output_ptr], #16 @ AES final-5 block - store result eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-5 block - mid @@ -4635,7 +4635,7 @@ rev64 $res0b, $res1b @ GHASH final-4 block eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ldr $res1q, [$input_ptr], #16 @ AES final-3 block - load ciphertext ins $rk4v.d[0], $res0.d[1] @ GHASH final-4 block - mid @@ -4666,7 +4666,7 @@ pmull2 $rk2q1, $res0.2d, $h4.2d @ GHASH final-3 block - high eor $acc_hb, $acc_hb, $rk2 @ GHASH final-3 block - high - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk3q1, $res0.1d, $h4.1d @ GHASH final-3 block - low st1 { $res4b}, [$output_ptr], #16 @ AES final-3 block - store result @@ -4700,7 +4700,7 @@ pmull $rk3q1, $res0.1d, $h3.1d @ GHASH final-2 block - low pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low st1 { $res4b}, [$output_ptr], #16 @ AES final-2 block - store result @@ -4715,7 +4715,7 @@ ext $h2.16b, $h2.16b, $h2.16b, #8 eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ldr $h12kq, [$current_tag, #48] @ load h2k | h1k pmull $rk3q1, $res0.1d, $h2.1d @ GHASH final-1 block - low @@ -4879,12 +4879,12 @@ my $rk3q1="v26.1q"; my $rk4v="v27"; ######################################################################################### -# size_t unroll8_eor3_aes_gcm_enc_256_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, -# unsigned char ivec[16], -# u64 *Xi); +# size_t unroll8_eor3_aes_gcm_enc_256_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_enc_256_kernel @@ -5862,7 +5862,7 @@ ins $rk4v.d[0], $res0.d[1] @ GHASH final-7 block - mid ins $acc_m.d[0], $h78k.d[1] @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-7 block - mid eor3 $res1b, $ctr_t1b, $ctr1b, $t1.16b @ AES final-6 block - result @@ -5890,7 +5890,7 @@ pmull $rk4v.1q, $rk4v.1d, $h78k.1d @ GHASH final-6 block - mid eor3 $res1b, $ctr_t1b, $ctr2b, $t1.16b @ AES final-5 block - result - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-6 block - mid eor $acc_hb, $acc_hb, $rk2 @ GHASH final-6 block - high @@ -5915,7 +5915,7 @@ pmull $rk3q1, $res0.1d, $h6.1d @ GHASH final-5 block - low pmull2 $rk4v.1q, $rk4v.2d, $h56k.2d @ GHASH final-5 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_lb, $acc_lb, $rk3 @ GHASH final-5 block - low eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-5 block - mid @@ -5941,7 +5941,7 @@ pmull $rk4v.1q, $rk4v.1d, $h56k.1d @ GHASH final-4 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-4 block - mid eor $acc_hb, $acc_hb, $rk2 @ GHASH final-4 block - high @@ -5969,7 +5969,7 @@ pmull $rk3q1, $res0.1d, $h4.1d @ GHASH final-3 block - low eor3 $res1b, $ctr_t1b, $ctr5b, $t1.16b @ AES final-2 block - result - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-3 block - mid eor $acc_lb, $acc_lb, $rk3 @ GHASH final-3 block - low @@ -5987,7 +5987,7 @@ ins $rk4v.d[0], $res0.d[1] @ GHASH final-2 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high eor3 $res1b, $ctr_t1b, $ctr6b, $t1.16b @ AES final-1 block - result @@ -6011,7 +6011,7 @@ ldr $ctr_t1q, [$input_ptr], #16 @ AES final block - load plaintext eor $res0b, $res0b, $t0.16b @ feed in partial tag - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-1 block - mid pmull2 $rk2q1, $res0.2d, $h2.2d @ GHASH final-1 block - high @@ -6110,12 +6110,12 @@ { ######################################################################################### -# size_t unroll8_eor3_aes_gcm_dec_256_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, -# unsigned char ivec[16], -# u64 *Xi); +# size_t unroll8_eor3_aes_gcm_dec_256_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, +# unsigned char ivec[16], +# const void *key); # $code.=<<___; .global unroll8_eor3_aes_gcm_dec_256_kernel @@ -7095,7 +7095,7 @@ pmull2 $acc_h.1q, $res0.2d, $h8.2d @ GHASH final-7 block - high eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-7 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $acc_l.1q, $res0.1d, $h8.1d @ GHASH final-7 block - low pmull $acc_m.1q, $rk4v.1d, $acc_m.1d @ GHASH final-7 block - mid @@ -7105,7 +7105,7 @@ eor $res0b, $res0b, $t0.16b @ feed in partial tag ldr $res1q, [$input_ptr], #16 @ AES final-5 block - load ciphertext - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in ins $rk4v.d[0], $res0.d[1] @ GHASH final-6 block - mid st1 { $res4b}, [$output_ptr], #16 @ AES final-6 block - store result @@ -7145,7 +7145,7 @@ eor $acc_lb, $acc_lb, $rk3 @ GHASH final-5 block - low eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-5 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in .L256_dec_blocks_more_than_4: @ blocks left > 4 rev64 $res0b, $res1b @ GHASH final-4 block @@ -7155,7 +7155,7 @@ ins $rk4v.d[0], $res0.d[1] @ GHASH final-4 block - mid ldr $res1q, [$input_ptr], #16 @ AES final-3 block - load ciphertext - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk3q1, $res0.1d, $h5.1d @ GHASH final-4 block - low pmull2 $rk2q1, $res0.2d, $h5.2d @ GHASH final-4 block - high @@ -7192,7 +7192,7 @@ pmull $rk3q1, $res0.1d, $h4.1d @ GHASH final-3 block - low pmull2 $rk2q1, $res0.2d, $h4.2d @ GHASH final-3 block - high - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull2 $rk4v.1q, $rk4v.2d, $h34k.2d @ GHASH final-3 block - mid eor $acc_lb, $acc_lb, $rk3 @ GHASH final-3 block - low @@ -7217,7 +7217,7 @@ eor $rk4v.8b, $rk4v.8b, $res0.8b @ GHASH final-2 block - mid eor $acc_lb, $acc_lb, $rk3 @ GHASH final-2 block - low - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in pmull $rk4v.1q, $rk4v.1d, $h34k.1d @ GHASH final-2 block - mid pmull2 $rk2q1, $res0.2d, $h3.2d @ GHASH final-2 block - high @@ -7250,7 +7250,7 @@ pmull2 $rk4v.1q, $rk4v.2d, $h12k.2d @ GHASH final-1 block - mid - movi $t0.8b, #0 @ supress further partial tag feed in + movi $t0.8b, #0 @ suppress further partial tag feed in eor $acc_hb, $acc_hb, $rk2 @ GHASH final-1 block - high eor $acc_mb, $acc_mb, $rk4v.16b @ GHASH final-1 block - mid diff --git a/crypto/modes/asm/aes-gcm-armv8_64.pl b/crypto/modes/asm/aes-gcm-armv8_64.pl index ac061f797d..e7b1a17895 100755 --- a/crypto/modes/asm/aes-gcm-armv8_64.pl +++ b/crypto/modes/asm/aes-gcm-armv8_64.pl @@ -245,12 +245,12 @@ ___ ######################################################################################### -# size_t aes_gcm_enc_128_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_enc_128_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_enc_128_kernel @@ -1131,12 +1131,12 @@ ___ ######################################################################################### -# size_t aes_gcm_dec_128_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_dec_128_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_dec_128_kernel @@ -2089,12 +2089,12 @@ my $rk4d="d22"; ######################################################################################### -# size_t aes_gcm_enc_192_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_enc_192_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_enc_192_kernel @@ -3026,12 +3026,12 @@ ___ ######################################################################################### -# size_t aes_gcm_dec_192_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_dec_192_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_dec_192_kernel @@ -4034,12 +4034,12 @@ my $rk4d="d22"; ######################################################################################### -# size_t aes_gcm_enc_256_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_enc_256_kernel(const uint8_t * plaintext, +# uint64_t plaintext_length, +# uint8_t * ciphertext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_enc_256_kernel @@ -5019,12 +5019,12 @@ my $t9="v6"; my $t9d="d6"; ######################################################################################### -# size_t aes_gcm_dec_256_kernel(const unsigned char *in, -# size_t len, -# unsigned char *out, -# const void *key, +# size_t aes_gcm_dec_256_kernel(const uint8_t * ciphertext, +# uint64_t plaintext_length, +# uint8_t * plaintext, +# uint64_t *Xi, # unsigned char ivec[16], -# u64 *Xi); +# const void *key); # $code.=<<___; .global aes_gcm_dec_256_kernel diff --git a/crypto/modes/asm/aes-gcm-avx512.S b/crypto/modes/asm/aes-gcm-avx512.S index 74ed8a77b6..19ddba6df3 100644 --- a/crypto/modes/asm/aes-gcm-avx512.S +++ b/crypto/modes/asm/aes-gcm-avx512.S @@ -24,14 +24,14 @@ ossl_aes_gcm_init_avx512: movl 240(%rdi),%eax cmpl $9,%eax - je .Laes_128_odfFyphirxGhDrj + je .Laes_128_0 cmpl $11,%eax - je .Laes_192_odfFyphirxGhDrj + je .Laes_192_0 cmpl $13,%eax - je .Laes_256_odfFyphirxGhDrj - jmp .Lexit_aes_odfFyphirxGhDrj + je .Laes_256_0 + jmp .Lexit_aes_0 .align 32 -.Laes_128_odfFyphirxGhDrj: +.Laes_128_0: vpxorq 0(%rdi),%xmm16,%xmm16 vaesenc 16(%rdi),%xmm16,%xmm16 @@ -53,9 +53,9 @@ ossl_aes_gcm_init_avx512: vaesenc 144(%rdi),%xmm16,%xmm16 vaesenclast 160(%rdi),%xmm16,%xmm16 - jmp .Lexit_aes_odfFyphirxGhDrj + jmp .Lexit_aes_0 .align 32 -.Laes_192_odfFyphirxGhDrj: +.Laes_192_0: vpxorq 0(%rdi),%xmm16,%xmm16 vaesenc 16(%rdi),%xmm16,%xmm16 @@ -81,9 +81,9 @@ ossl_aes_gcm_init_avx512: vaesenc 176(%rdi),%xmm16,%xmm16 vaesenclast 192(%rdi),%xmm16,%xmm16 - jmp .Lexit_aes_odfFyphirxGhDrj + jmp .Lexit_aes_0 .align 32 -.Laes_256_odfFyphirxGhDrj: +.Laes_256_0: vpxorq 0(%rdi),%xmm16,%xmm16 vaesenc 16(%rdi),%xmm16,%xmm16 @@ -113,8 +113,8 @@ ossl_aes_gcm_init_avx512: vaesenc 208(%rdi),%xmm16,%xmm16 vaesenclast 224(%rdi),%xmm16,%xmm16 - jmp .Lexit_aes_odfFyphirxGhDrj -.Lexit_aes_odfFyphirxGhDrj: + jmp .Lexit_aes_0 +.Lexit_aes_0: vpshufb SHUF_MASK(%rip),%xmm16,%xmm16 @@ -352,14 +352,14 @@ ossl_aes_gcm_setiv_avx512: movq %rdx,%r10 movq %rcx,%r11 orq %r11,%r11 - jz .L_CALC_AAD_done_vrxGfkkBAdBjnyf + jz .L_CALC_AAD_done_1 xorq %rbx,%rbx vmovdqa64 SHUF_MASK(%rip),%zmm16 -.L_get_AAD_loop48x16_vrxGfkkBAdBjnyf: +.L_get_AAD_loop48x16_1: cmpq $768,%r11 - jl .L_exit_AAD_loop48x16_vrxGfkkBAdBjnyf + jl .L_exit_AAD_loop48x16_1 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 vmovdqu64 128(%r10),%zmm4 @@ -369,7 +369,7 @@ ossl_aes_gcm_setiv_avx512: vpshufb %zmm16,%zmm4,%zmm4 vpshufb %zmm16,%zmm5,%zmm5 testq %rbx,%rbx - jnz .L_skip_hkeys_precomputation_FqcdCaGqcqsAspi + jnz .L_skip_hkeys_precomputation_2 vmovdqu64 288(%rsi),%zmm1 vmovdqu64 %zmm1,704(%rsp) @@ -625,7 +625,7 @@ ossl_aes_gcm_setiv_avx512: vpternlogq $0x96,%zmm15,%zmm13,%zmm12 vmovdqu64 %zmm12,0(%rsp) -.L_skip_hkeys_precomputation_FqcdCaGqcqsAspi: +.L_skip_hkeys_precomputation_2: movq $1,%rbx vpxorq %zmm2,%zmm11,%zmm11 vmovdqu64 0(%rsp),%zmm19 @@ -759,15 +759,15 @@ ossl_aes_gcm_setiv_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm2 subq $768,%r11 - je .L_CALC_AAD_done_vrxGfkkBAdBjnyf + je .L_CALC_AAD_done_1 addq $768,%r10 - jmp .L_get_AAD_loop48x16_vrxGfkkBAdBjnyf + jmp .L_get_AAD_loop48x16_1 -.L_exit_AAD_loop48x16_vrxGfkkBAdBjnyf: +.L_exit_AAD_loop48x16_1: cmpq $512,%r11 - jl .L_less_than_32x16_vrxGfkkBAdBjnyf + jl .L_less_than_32x16_1 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 @@ -778,7 +778,7 @@ ossl_aes_gcm_setiv_avx512: vpshufb %zmm16,%zmm4,%zmm4 vpshufb %zmm16,%zmm5,%zmm5 testq %rbx,%rbx - jnz .L_skip_hkeys_precomputation_aczcoxtefngFFlD + jnz .L_skip_hkeys_precomputation_3 vmovdqu64 288(%rsi),%zmm1 vmovdqu64 %zmm1,704(%rsp) @@ -914,7 +914,7 @@ ossl_aes_gcm_setiv_avx512: vpternlogq $0x96,%zmm15,%zmm13,%zmm12 vmovdqu64 %zmm12,256(%rsp) -.L_skip_hkeys_precomputation_aczcoxtefngFFlD: +.L_skip_hkeys_precomputation_3: movq $1,%rbx vpxorq %zmm2,%zmm11,%zmm11 vmovdqu64 256(%rsp),%zmm19 @@ -1011,14 +1011,14 @@ ossl_aes_gcm_setiv_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm2 subq $512,%r11 - je .L_CALC_AAD_done_vrxGfkkBAdBjnyf + je .L_CALC_AAD_done_1 addq $512,%r10 - jmp .L_less_than_16x16_vrxGfkkBAdBjnyf + jmp .L_less_than_16x16_1 -.L_less_than_32x16_vrxGfkkBAdBjnyf: +.L_less_than_32x16_1: cmpq $256,%r11 - jl .L_less_than_16x16_vrxGfkkBAdBjnyf + jl .L_less_than_16x16_1 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 @@ -1086,11 +1086,11 @@ ossl_aes_gcm_setiv_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm2 subq $256,%r11 - je .L_CALC_AAD_done_vrxGfkkBAdBjnyf + je .L_CALC_AAD_done_1 addq $256,%r10 -.L_less_than_16x16_vrxGfkkBAdBjnyf: +.L_less_than_16x16_1: leaq byte64_len_to_mask_table(%rip),%r12 leaq (%r12,%r11,8),%r12 @@ -1099,29 +1099,29 @@ ossl_aes_gcm_setiv_avx512: addl $15,%r11d shrl $4,%r11d cmpl $2,%r11d - jb .L_AAD_blocks_1_vrxGfkkBAdBjnyf - je .L_AAD_blocks_2_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_1_1 + je .L_AAD_blocks_2_1 cmpl $4,%r11d - jb .L_AAD_blocks_3_vrxGfkkBAdBjnyf - je .L_AAD_blocks_4_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_3_1 + je .L_AAD_blocks_4_1 cmpl $6,%r11d - jb .L_AAD_blocks_5_vrxGfkkBAdBjnyf - je .L_AAD_blocks_6_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_5_1 + je .L_AAD_blocks_6_1 cmpl $8,%r11d - jb .L_AAD_blocks_7_vrxGfkkBAdBjnyf - je .L_AAD_blocks_8_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_7_1 + je .L_AAD_blocks_8_1 cmpl $10,%r11d - jb .L_AAD_blocks_9_vrxGfkkBAdBjnyf - je .L_AAD_blocks_10_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_9_1 + je .L_AAD_blocks_10_1 cmpl $12,%r11d - jb .L_AAD_blocks_11_vrxGfkkBAdBjnyf - je .L_AAD_blocks_12_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_11_1 + je .L_AAD_blocks_12_1 cmpl $14,%r11d - jb .L_AAD_blocks_13_vrxGfkkBAdBjnyf - je .L_AAD_blocks_14_vrxGfkkBAdBjnyf + jb .L_AAD_blocks_13_1 + je .L_AAD_blocks_14_1 cmpl $15,%r11d - je .L_AAD_blocks_15_vrxGfkkBAdBjnyf -.L_AAD_blocks_16_vrxGfkkBAdBjnyf: + je .L_AAD_blocks_15_1 +.L_AAD_blocks_16_1: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1189,8 +1189,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_15_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_15_1: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1260,8 +1260,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_14_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_14_1: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1330,8 +1330,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_13_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_13_1: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1400,8 +1400,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_12_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_12_1: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1458,8 +1458,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_11_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_11_1: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1522,8 +1522,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_10_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_10_1: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1585,8 +1585,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_9_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_9_1: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1648,8 +1648,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_8_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_8_1: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1699,8 +1699,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_7_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_7_1: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1752,8 +1752,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_6_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_6_1: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1804,8 +1804,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_5_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_5_1: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -1856,8 +1856,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_4_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_4_1: kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11{%k1}{z} vpshufb %zmm16,%zmm11,%zmm11 @@ -1895,8 +1895,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_3_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_3_1: kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11{%k1}{z} vpshufb %zmm16,%zmm11,%zmm11 @@ -1935,8 +1935,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_2_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_2_1: kmovq (%r12),%k1 vmovdqu8 0(%r10),%ymm11{%k1}{z} vpshufb %ymm16,%ymm11,%ymm11 @@ -1974,8 +1974,8 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 - jmp .L_CALC_AAD_done_vrxGfkkBAdBjnyf -.L_AAD_blocks_1_vrxGfkkBAdBjnyf: + jmp .L_CALC_AAD_done_1 +.L_AAD_blocks_1_1: kmovq (%r12),%k1 vmovdqu8 0(%r10),%xmm11{%k1}{z} vpshufb %xmm16,%xmm11,%xmm11 @@ -2013,7 +2013,7 @@ ossl_aes_gcm_setiv_avx512: vpslldq $4,%xmm2,%xmm2 vpternlogq $0x96,%xmm1,%xmm8,%xmm2 -.L_CALC_AAD_done_vrxGfkkBAdBjnyf: +.L_CALC_AAD_done_1: movq %rcx,%r10 shlq $3,%r10 vmovq %r10,%xmm3 @@ -2066,14 +2066,14 @@ skip_iv_len_12_init_IV: movl 240(%rdi),%r10d cmpl $9,%r10d - je .Laes_128_isEpywinmtmcbpz + je .Laes_128_4 cmpl $11,%r10d - je .Laes_192_isEpywinmtmcbpz + je .Laes_192_4 cmpl $13,%r10d - je .Laes_256_isEpywinmtmcbpz - jmp .Lexit_aes_isEpywinmtmcbpz + je .Laes_256_4 + jmp .Lexit_aes_4 .align 32 -.Laes_128_isEpywinmtmcbpz: +.Laes_128_4: vpxorq 0(%rdi),%xmm1,%xmm1 vaesenc 16(%rdi),%xmm1,%xmm1 @@ -2095,9 +2095,9 @@ skip_iv_len_12_init_IV: vaesenc 144(%rdi),%xmm1,%xmm1 vaesenclast 160(%rdi),%xmm1,%xmm1 - jmp .Lexit_aes_isEpywinmtmcbpz + jmp .Lexit_aes_4 .align 32 -.Laes_192_isEpywinmtmcbpz: +.Laes_192_4: vpxorq 0(%rdi),%xmm1,%xmm1 vaesenc 16(%rdi),%xmm1,%xmm1 @@ -2123,9 +2123,9 @@ skip_iv_len_12_init_IV: vaesenc 176(%rdi),%xmm1,%xmm1 vaesenclast 192(%rdi),%xmm1,%xmm1 - jmp .Lexit_aes_isEpywinmtmcbpz + jmp .Lexit_aes_4 .align 32 -.Laes_256_isEpywinmtmcbpz: +.Laes_256_4: vpxorq 0(%rdi),%xmm1,%xmm1 vaesenc 16(%rdi),%xmm1,%xmm1 @@ -2155,8 +2155,8 @@ skip_iv_len_12_init_IV: vaesenc 208(%rdi),%xmm1,%xmm1 vaesenclast 224(%rdi),%xmm1,%xmm1 - jmp .Lexit_aes_isEpywinmtmcbpz -.Lexit_aes_isEpywinmtmcbpz: + jmp .Lexit_aes_4 +.Lexit_aes_4: vmovdqu %xmm1,32(%rsi) @@ -2164,7 +2164,7 @@ skip_iv_len_12_init_IV: vpshufb SHUF_MASK(%rip),%xmm2,%xmm2 vmovdqu %xmm2,0(%rsi) cmpq $256,%rcx - jbe .Lskip_hkeys_cleanup_rcDlkzbwxFzBbEs + jbe .Lskip_hkeys_cleanup_5 vpxor %xmm0,%xmm0,%xmm0 vmovdqa64 %zmm0,0(%rsp) vmovdqa64 %zmm0,64(%rsp) @@ -2178,7 +2178,7 @@ skip_iv_len_12_init_IV: vmovdqa64 %zmm0,576(%rsp) vmovdqa64 %zmm0,640(%rsp) vmovdqa64 %zmm0,704(%rsp) -.Lskip_hkeys_cleanup_rcDlkzbwxFzBbEs: +.Lskip_hkeys_cleanup_5: vzeroupper leaq (%rbp),%rsp .cfi_def_cfa_register %rsp @@ -2257,14 +2257,14 @@ ossl_aes_gcm_update_aad_avx512: movq %rsi,%r10 movq %rdx,%r11 orq %r11,%r11 - jz .L_CALC_AAD_done_nGbCkwBuzixFzEj + jz .L_CALC_AAD_done_6 xorq %rbx,%rbx vmovdqa64 SHUF_MASK(%rip),%zmm16 -.L_get_AAD_loop48x16_nGbCkwBuzixFzEj: +.L_get_AAD_loop48x16_6: cmpq $768,%r11 - jl .L_exit_AAD_loop48x16_nGbCkwBuzixFzEj + jl .L_exit_AAD_loop48x16_6 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 vmovdqu64 128(%r10),%zmm4 @@ -2274,7 +2274,7 @@ ossl_aes_gcm_update_aad_avx512: vpshufb %zmm16,%zmm4,%zmm4 vpshufb %zmm16,%zmm5,%zmm5 testq %rbx,%rbx - jnz .L_skip_hkeys_precomputation_sjeuCppfBAbChio + jnz .L_skip_hkeys_precomputation_7 vmovdqu64 288(%rdi),%zmm1 vmovdqu64 %zmm1,704(%rsp) @@ -2530,7 +2530,7 @@ ossl_aes_gcm_update_aad_avx512: vpternlogq $0x96,%zmm15,%zmm13,%zmm12 vmovdqu64 %zmm12,0(%rsp) -.L_skip_hkeys_precomputation_sjeuCppfBAbChio: +.L_skip_hkeys_precomputation_7: movq $1,%rbx vpxorq %zmm14,%zmm11,%zmm11 vmovdqu64 0(%rsp),%zmm19 @@ -2664,15 +2664,15 @@ ossl_aes_gcm_update_aad_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm14 subq $768,%r11 - je .L_CALC_AAD_done_nGbCkwBuzixFzEj + je .L_CALC_AAD_done_6 addq $768,%r10 - jmp .L_get_AAD_loop48x16_nGbCkwBuzixFzEj + jmp .L_get_AAD_loop48x16_6 -.L_exit_AAD_loop48x16_nGbCkwBuzixFzEj: +.L_exit_AAD_loop48x16_6: cmpq $512,%r11 - jl .L_less_than_32x16_nGbCkwBuzixFzEj + jl .L_less_than_32x16_6 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 @@ -2683,7 +2683,7 @@ ossl_aes_gcm_update_aad_avx512: vpshufb %zmm16,%zmm4,%zmm4 vpshufb %zmm16,%zmm5,%zmm5 testq %rbx,%rbx - jnz .L_skip_hkeys_precomputation_smhlmCdjvpexsEu + jnz .L_skip_hkeys_precomputation_8 vmovdqu64 288(%rdi),%zmm1 vmovdqu64 %zmm1,704(%rsp) @@ -2819,7 +2819,7 @@ ossl_aes_gcm_update_aad_avx512: vpternlogq $0x96,%zmm15,%zmm13,%zmm12 vmovdqu64 %zmm12,256(%rsp) -.L_skip_hkeys_precomputation_smhlmCdjvpexsEu: +.L_skip_hkeys_precomputation_8: movq $1,%rbx vpxorq %zmm14,%zmm11,%zmm11 vmovdqu64 256(%rsp),%zmm19 @@ -2916,14 +2916,14 @@ ossl_aes_gcm_update_aad_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm14 subq $512,%r11 - je .L_CALC_AAD_done_nGbCkwBuzixFzEj + je .L_CALC_AAD_done_6 addq $512,%r10 - jmp .L_less_than_16x16_nGbCkwBuzixFzEj + jmp .L_less_than_16x16_6 -.L_less_than_32x16_nGbCkwBuzixFzEj: +.L_less_than_32x16_6: cmpq $256,%r11 - jl .L_less_than_16x16_nGbCkwBuzixFzEj + jl .L_less_than_16x16_6 vmovdqu64 0(%r10),%zmm11 vmovdqu64 64(%r10),%zmm3 @@ -2991,11 +2991,11 @@ ossl_aes_gcm_update_aad_avx512: vpternlogq $0x96,%xmm6,%xmm9,%xmm14 subq $256,%r11 - je .L_CALC_AAD_done_nGbCkwBuzixFzEj + je .L_CALC_AAD_done_6 addq $256,%r10 -.L_less_than_16x16_nGbCkwBuzixFzEj: +.L_less_than_16x16_6: leaq byte64_len_to_mask_table(%rip),%r12 leaq (%r12,%r11,8),%r12 @@ -3004,29 +3004,29 @@ ossl_aes_gcm_update_aad_avx512: addl $15,%r11d shrl $4,%r11d cmpl $2,%r11d - jb .L_AAD_blocks_1_nGbCkwBuzixFzEj - je .L_AAD_blocks_2_nGbCkwBuzixFzEj + jb .L_AAD_blocks_1_6 + je .L_AAD_blocks_2_6 cmpl $4,%r11d - jb .L_AAD_blocks_3_nGbCkwBuzixFzEj - je .L_AAD_blocks_4_nGbCkwBuzixFzEj + jb .L_AAD_blocks_3_6 + je .L_AAD_blocks_4_6 cmpl $6,%r11d - jb .L_AAD_blocks_5_nGbCkwBuzixFzEj - je .L_AAD_blocks_6_nGbCkwBuzixFzEj + jb .L_AAD_blocks_5_6 + je .L_AAD_blocks_6_6 cmpl $8,%r11d - jb .L_AAD_blocks_7_nGbCkwBuzixFzEj - je .L_AAD_blocks_8_nGbCkwBuzixFzEj + jb .L_AAD_blocks_7_6 + je .L_AAD_blocks_8_6 cmpl $10,%r11d - jb .L_AAD_blocks_9_nGbCkwBuzixFzEj - je .L_AAD_blocks_10_nGbCkwBuzixFzEj + jb .L_AAD_blocks_9_6 + je .L_AAD_blocks_10_6 cmpl $12,%r11d - jb .L_AAD_blocks_11_nGbCkwBuzixFzEj - je .L_AAD_blocks_12_nGbCkwBuzixFzEj + jb .L_AAD_blocks_11_6 + je .L_AAD_blocks_12_6 cmpl $14,%r11d - jb .L_AAD_blocks_13_nGbCkwBuzixFzEj - je .L_AAD_blocks_14_nGbCkwBuzixFzEj + jb .L_AAD_blocks_13_6 + je .L_AAD_blocks_14_6 cmpl $15,%r11d - je .L_AAD_blocks_15_nGbCkwBuzixFzEj -.L_AAD_blocks_16_nGbCkwBuzixFzEj: + je .L_AAD_blocks_15_6 +.L_AAD_blocks_16_6: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3094,8 +3094,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_15_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_15_6: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3165,8 +3165,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_14_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_14_6: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3235,8 +3235,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_13_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_13_6: subq $1536,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3305,8 +3305,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_12_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_12_6: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3363,8 +3363,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_11_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_11_6: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3427,8 +3427,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_10_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_10_6: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3490,8 +3490,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_9_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_9_6: subq $1024,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3553,8 +3553,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_8_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_8_6: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3604,8 +3604,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_7_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_7_6: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3657,8 +3657,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_6_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_6_6: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3709,8 +3709,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_5_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_5_6: subq $512,%r12 kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11 @@ -3761,8 +3761,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_4_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_4_6: kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11{%k1}{z} vpshufb %zmm16,%zmm11,%zmm11 @@ -3800,8 +3800,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_3_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_3_6: kmovq (%r12),%k1 vmovdqu8 0(%r10),%zmm11{%k1}{z} vpshufb %zmm16,%zmm11,%zmm11 @@ -3840,8 +3840,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_2_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_2_6: kmovq (%r12),%k1 vmovdqu8 0(%r10),%ymm11{%k1}{z} vpshufb %ymm16,%ymm11,%ymm11 @@ -3879,8 +3879,8 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 - jmp .L_CALC_AAD_done_nGbCkwBuzixFzEj -.L_AAD_blocks_1_nGbCkwBuzixFzEj: + jmp .L_CALC_AAD_done_6 +.L_AAD_blocks_1_6: kmovq (%r12),%k1 vmovdqu8 0(%r10),%xmm11{%k1}{z} vpshufb %xmm16,%xmm11,%xmm11 @@ -3918,10 +3918,10 @@ ossl_aes_gcm_update_aad_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm1,%xmm8,%xmm14 -.L_CALC_AAD_done_nGbCkwBuzixFzEj: +.L_CALC_AAD_done_6: vmovdqu64 %xmm14,64(%rdi) cmpq $256,%rdx - jbe .Lskip_hkeys_cleanup_GwlvfgaDpaydbta + jbe .Lskip_hkeys_cleanup_9 vpxor %xmm0,%xmm0,%xmm0 vmovdqa64 %zmm0,0(%rsp) vmovdqa64 %zmm0,64(%rsp) @@ -3935,7 +3935,7 @@ ossl_aes_gcm_update_aad_avx512: vmovdqa64 %zmm0,576(%rsp) vmovdqa64 %zmm0,640(%rsp) vmovdqa64 %zmm0,704(%rsp) -.Lskip_hkeys_cleanup_GwlvfgaDpaydbta: +.Lskip_hkeys_cleanup_9: vzeroupper leaq (%rbp),%rsp .cfi_def_cfa_register %rsp @@ -4024,13 +4024,13 @@ ossl_aes_gcm_encrypt_avx512: .align 32 .Laes_gcm_encrypt_128_avx512: orq %r8,%r8 - je .L_enc_dec_done_lzCeFkjwAopsEcs + je .L_enc_dec_done_10 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_fsBfxpgBswcpzpz + je .L_partial_block_done_11 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -4052,9 +4052,9 @@ ossl_aes_gcm_encrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_fsBfxpgBswcpzpz + jge .L_no_extra_mask_11 subq %r13,%r12 -.L_no_extra_mask_fsBfxpgBswcpzpz: +.L_no_extra_mask_11: @@ -4064,7 +4064,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 vpxorq %xmm3,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_fsBfxpgBswcpzpz + jl .L_partial_incomplete_11 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -4099,13 +4099,13 @@ ossl_aes_gcm_encrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_fsBfxpgBswcpzpz + jmp .L_enc_dec_done_11 -.L_partial_incomplete_fsBfxpgBswcpzpz: +.L_partial_incomplete_11: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_fsBfxpgBswcpzpz: +.L_enc_dec_done_11: leaq byte_len_to_mask_table(%rip),%r12 @@ -4116,12 +4116,12 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_fsBfxpgBswcpzpz: +.L_partial_block_done_11: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_lzCeFkjwAopsEcs + je .L_enc_dec_done_10 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_lzCeFkjwAopsEcs + jbe .L_message_below_equal_16_blocks_10 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -4141,13 +4141,13 @@ ossl_aes_gcm_encrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_yeDAevFkpbodhed + jae .L_next_16_overflow_12 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_yeDAevFkpbodhed -.L_next_16_overflow_yeDAevFkpbodhed: + jmp .L_next_16_ok_12 +.L_next_16_overflow_12: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -4158,7 +4158,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_yeDAevFkpbodhed: +.L_next_16_ok_12: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -4246,7 +4246,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_brdupgngoBGiEzu + jnz .L_skip_hkeys_precomputation_13 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -4262,20 +4262,20 @@ ossl_aes_gcm_encrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_brdupgngoBGiEzu: +.L_skip_hkeys_precomputation_13: cmpq $512,%r8 - jb .L_message_below_32_blocks_lzCeFkjwAopsEcs + jb .L_message_below_32_blocks_10 cmpb $240,%r15b - jae .L_next_16_overflow_lEszhErgbnGcucm + jae .L_next_16_overflow_14 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_lEszhErgbnGcucm -.L_next_16_overflow_lEszhErgbnGcucm: + jmp .L_next_16_ok_14 +.L_next_16_overflow_14: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -4286,7 +4286,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_lEszhErgbnGcucm: +.L_next_16_ok_14: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -4374,7 +4374,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_wszjnpeoxAtloxo + jnz .L_skip_hkeys_precomputation_15 vmovdqu64 640(%rsp),%zmm3 @@ -4622,22 +4622,22 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_wszjnpeoxAtloxo: +.L_skip_hkeys_precomputation_15: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_lzCeFkjwAopsEcs -.L_encrypt_big_nblocks_lzCeFkjwAopsEcs: + jb .L_no_more_big_nblocks_10 +.L_encrypt_big_nblocks_10: cmpb $240,%r15b - jae .L_16_blocks_overflow_kaabkhCFxwftqvD + jae .L_16_blocks_overflow_16 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_kaabkhCFxwftqvD -.L_16_blocks_overflow_kaabkhCFxwftqvD: + jmp .L_16_blocks_ok_16 +.L_16_blocks_overflow_16: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -4648,7 +4648,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_kaabkhCFxwftqvD: +.L_16_blocks_ok_16: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -4813,13 +4813,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_BBfthmCnicfzcEn + jae .L_16_blocks_overflow_17 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_BBfthmCnicfzcEn -.L_16_blocks_overflow_BBfthmCnicfzcEn: + jmp .L_16_blocks_ok_17 +.L_16_blocks_overflow_17: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -4830,7 +4830,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_BBfthmCnicfzcEn: +.L_16_blocks_ok_17: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -4995,13 +4995,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_uwseDjljigianhs + jae .L_16_blocks_overflow_18 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_uwseDjljigianhs -.L_16_blocks_overflow_uwseDjljigianhs: + jmp .L_16_blocks_ok_18 +.L_16_blocks_overflow_18: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -5012,7 +5012,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_uwseDjljigianhs: +.L_16_blocks_ok_18: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -5207,16 +5207,16 @@ ossl_aes_gcm_encrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_lzCeFkjwAopsEcs + jae .L_encrypt_big_nblocks_10 -.L_no_more_big_nblocks_lzCeFkjwAopsEcs: +.L_no_more_big_nblocks_10: cmpq $512,%r8 - jae .L_encrypt_32_blocks_lzCeFkjwAopsEcs + jae .L_encrypt_32_blocks_10 cmpq $256,%r8 - jae .L_encrypt_16_blocks_lzCeFkjwAopsEcs -.L_encrypt_0_blocks_ghash_32_lzCeFkjwAopsEcs: + jae .L_encrypt_16_blocks_10 +.L_encrypt_0_blocks_ghash_32_10: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -5259,61 +5259,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_mlwyCypwkirBzdm + je .L_last_num_blocks_is_0_19 cmpl $8,%r10d - je .L_last_num_blocks_is_8_mlwyCypwkirBzdm - jb .L_last_num_blocks_is_7_1_mlwyCypwkirBzdm + je .L_last_num_blocks_is_8_19 + jb .L_last_num_blocks_is_7_1_19 cmpl $12,%r10d - je .L_last_num_blocks_is_12_mlwyCypwkirBzdm - jb .L_last_num_blocks_is_11_9_mlwyCypwkirBzdm + je .L_last_num_blocks_is_12_19 + jb .L_last_num_blocks_is_11_9_19 cmpl $15,%r10d - je .L_last_num_blocks_is_15_mlwyCypwkirBzdm - ja .L_last_num_blocks_is_16_mlwyCypwkirBzdm + je .L_last_num_blocks_is_15_19 + ja .L_last_num_blocks_is_16_19 cmpl $14,%r10d - je .L_last_num_blocks_is_14_mlwyCypwkirBzdm - jmp .L_last_num_blocks_is_13_mlwyCypwkirBzdm + je .L_last_num_blocks_is_14_19 + jmp .L_last_num_blocks_is_13_19 -.L_last_num_blocks_is_11_9_mlwyCypwkirBzdm: +.L_last_num_blocks_is_11_9_19: cmpl $10,%r10d - je .L_last_num_blocks_is_10_mlwyCypwkirBzdm - ja .L_last_num_blocks_is_11_mlwyCypwkirBzdm - jmp .L_last_num_blocks_is_9_mlwyCypwkirBzdm + je .L_last_num_blocks_is_10_19 + ja .L_last_num_blocks_is_11_19 + jmp .L_last_num_blocks_is_9_19 -.L_last_num_blocks_is_7_1_mlwyCypwkirBzdm: +.L_last_num_blocks_is_7_1_19: cmpl $4,%r10d - je .L_last_num_blocks_is_4_mlwyCypwkirBzdm - jb .L_last_num_blocks_is_3_1_mlwyCypwkirBzdm + je .L_last_num_blocks_is_4_19 + jb .L_last_num_blocks_is_3_1_19 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_mlwyCypwkirBzdm - je .L_last_num_blocks_is_6_mlwyCypwkirBzdm - jmp .L_last_num_blocks_is_5_mlwyCypwkirBzdm + ja .L_last_num_blocks_is_7_19 + je .L_last_num_blocks_is_6_19 + jmp .L_last_num_blocks_is_5_19 -.L_last_num_blocks_is_3_1_mlwyCypwkirBzdm: +.L_last_num_blocks_is_3_1_19: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_mlwyCypwkirBzdm - je .L_last_num_blocks_is_2_mlwyCypwkirBzdm -.L_last_num_blocks_is_1_mlwyCypwkirBzdm: + ja .L_last_num_blocks_is_3_19 + je .L_last_num_blocks_is_2_19 +.L_last_num_blocks_is_1_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_FymzAunapeyydiw + jae .L_16_blocks_overflow_20 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_FymzAunapeyydiw + jmp .L_16_blocks_ok_20 -.L_16_blocks_overflow_FymzAunapeyydiw: +.L_16_blocks_overflow_20: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_FymzAunapeyydiw: +.L_16_blocks_ok_20: @@ -5397,7 +5397,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_badripyoEBzbFrh + jl .L_small_initial_partial_block_21 @@ -5441,8 +5441,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_badripyoEBzbFrh -.L_small_initial_partial_block_badripyoEBzbFrh: + jmp .L_small_initial_compute_done_21 +.L_small_initial_partial_block_21: @@ -5494,24 +5494,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_badripyoEBzbFrh -.L_small_initial_compute_done_badripyoEBzbFrh: -.L_after_reduction_badripyoEBzbFrh: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_2_mlwyCypwkirBzdm: + jmp .L_after_reduction_21 +.L_small_initial_compute_done_21: +.L_after_reduction_21: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_2_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_BmbbCbtwFgeymku + jae .L_16_blocks_overflow_22 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_BmbbCbtwFgeymku + jmp .L_16_blocks_ok_22 -.L_16_blocks_overflow_BmbbCbtwFgeymku: +.L_16_blocks_overflow_22: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_BmbbCbtwFgeymku: +.L_16_blocks_ok_22: @@ -5596,7 +5596,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dqpDAqAsqwAlAth + jl .L_small_initial_partial_block_23 @@ -5640,8 +5640,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dqpDAqAsqwAlAth -.L_small_initial_partial_block_dqpDAqAsqwAlAth: + jmp .L_small_initial_compute_done_23 +.L_small_initial_partial_block_23: @@ -5688,27 +5688,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dqpDAqAsqwAlAth: +.L_small_initial_compute_done_23: orq %r8,%r8 - je .L_after_reduction_dqpDAqAsqwAlAth + je .L_after_reduction_23 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dqpDAqAsqwAlAth: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_3_mlwyCypwkirBzdm: +.L_after_reduction_23: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_3_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_lvhfrjACGciwhsf + jae .L_16_blocks_overflow_24 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_lvhfrjACGciwhsf + jmp .L_16_blocks_ok_24 -.L_16_blocks_overflow_lvhfrjACGciwhsf: +.L_16_blocks_overflow_24: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_lvhfrjACGciwhsf: +.L_16_blocks_ok_24: @@ -5793,7 +5793,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lGEroisctpjGmAc + jl .L_small_initial_partial_block_25 @@ -5838,8 +5838,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lGEroisctpjGmAc -.L_small_initial_partial_block_lGEroisctpjGmAc: + jmp .L_small_initial_compute_done_25 +.L_small_initial_partial_block_25: @@ -5886,27 +5886,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lGEroisctpjGmAc: +.L_small_initial_compute_done_25: orq %r8,%r8 - je .L_after_reduction_lGEroisctpjGmAc + je .L_after_reduction_25 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lGEroisctpjGmAc: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_4_mlwyCypwkirBzdm: +.L_after_reduction_25: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_4_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_bCxgzuyBqruCbGi + jae .L_16_blocks_overflow_26 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_bCxgzuyBqruCbGi + jmp .L_16_blocks_ok_26 -.L_16_blocks_overflow_bCxgzuyBqruCbGi: +.L_16_blocks_overflow_26: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_bCxgzuyBqruCbGi: +.L_16_blocks_ok_26: @@ -5991,7 +5991,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vdoEhgqglqcCCds + jl .L_small_initial_partial_block_27 @@ -6036,8 +6036,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vdoEhgqglqcCCds -.L_small_initial_partial_block_vdoEhgqglqcCCds: + jmp .L_small_initial_compute_done_27 +.L_small_initial_partial_block_27: @@ -6085,32 +6085,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vdoEhgqglqcCCds: +.L_small_initial_compute_done_27: orq %r8,%r8 - je .L_after_reduction_vdoEhgqglqcCCds + je .L_after_reduction_27 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vdoEhgqglqcCCds: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_5_mlwyCypwkirBzdm: +.L_after_reduction_27: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_5_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_tceDFouqkwbhpGa + jae .L_16_blocks_overflow_28 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_tceDFouqkwbhpGa + jmp .L_16_blocks_ok_28 -.L_16_blocks_overflow_tceDFouqkwbhpGa: +.L_16_blocks_overflow_28: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_tceDFouqkwbhpGa: +.L_16_blocks_ok_28: @@ -6210,7 +6210,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jipxbaCcpqfelhA + jl .L_small_initial_partial_block_29 @@ -6261,8 +6261,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jipxbaCcpqfelhA -.L_small_initial_partial_block_jipxbaCcpqfelhA: + jmp .L_small_initial_compute_done_29 +.L_small_initial_partial_block_29: @@ -6310,32 +6310,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jipxbaCcpqfelhA: +.L_small_initial_compute_done_29: orq %r8,%r8 - je .L_after_reduction_jipxbaCcpqfelhA + je .L_after_reduction_29 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jipxbaCcpqfelhA: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_6_mlwyCypwkirBzdm: +.L_after_reduction_29: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_6_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_bhAandlsDsncdpk + jae .L_16_blocks_overflow_30 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_bhAandlsDsncdpk + jmp .L_16_blocks_ok_30 -.L_16_blocks_overflow_bhAandlsDsncdpk: +.L_16_blocks_overflow_30: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_bhAandlsDsncdpk: +.L_16_blocks_ok_30: @@ -6435,7 +6435,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cGyhAhzdmpoCdvg + jl .L_small_initial_partial_block_31 @@ -6486,8 +6486,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cGyhAhzdmpoCdvg -.L_small_initial_partial_block_cGyhAhzdmpoCdvg: + jmp .L_small_initial_compute_done_31 +.L_small_initial_partial_block_31: @@ -6541,32 +6541,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cGyhAhzdmpoCdvg: +.L_small_initial_compute_done_31: orq %r8,%r8 - je .L_after_reduction_cGyhAhzdmpoCdvg + je .L_after_reduction_31 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cGyhAhzdmpoCdvg: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_7_mlwyCypwkirBzdm: +.L_after_reduction_31: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_7_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_ixFxvahFcGyxdsb + jae .L_16_blocks_overflow_32 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_ixFxvahFcGyxdsb + jmp .L_16_blocks_ok_32 -.L_16_blocks_overflow_ixFxvahFcGyxdsb: +.L_16_blocks_overflow_32: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_ixFxvahFcGyxdsb: +.L_16_blocks_ok_32: @@ -6666,7 +6666,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tiusChomznjoeDo + jl .L_small_initial_partial_block_33 @@ -6718,8 +6718,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tiusChomznjoeDo -.L_small_initial_partial_block_tiusChomznjoeDo: + jmp .L_small_initial_compute_done_33 +.L_small_initial_partial_block_33: @@ -6773,32 +6773,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tiusChomznjoeDo: +.L_small_initial_compute_done_33: orq %r8,%r8 - je .L_after_reduction_tiusChomznjoeDo + je .L_after_reduction_33 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tiusChomznjoeDo: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_8_mlwyCypwkirBzdm: +.L_after_reduction_33: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_8_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_dopAepDhwbqhuqj + jae .L_16_blocks_overflow_34 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_dopAepDhwbqhuqj + jmp .L_16_blocks_ok_34 -.L_16_blocks_overflow_dopAepDhwbqhuqj: +.L_16_blocks_overflow_34: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_dopAepDhwbqhuqj: +.L_16_blocks_ok_34: @@ -6898,7 +6898,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GyqsqDzCFBtAlpz + jl .L_small_initial_partial_block_35 @@ -6952,8 +6952,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GyqsqDzCFBtAlpz -.L_small_initial_partial_block_GyqsqDzCFBtAlpz: + jmp .L_small_initial_compute_done_35 +.L_small_initial_partial_block_35: @@ -7008,26 +7008,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GyqsqDzCFBtAlpz: +.L_small_initial_compute_done_35: orq %r8,%r8 - je .L_after_reduction_GyqsqDzCFBtAlpz + je .L_after_reduction_35 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GyqsqDzCFBtAlpz: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_9_mlwyCypwkirBzdm: +.L_after_reduction_35: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_9_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_ECwcukirdurdueG + jae .L_16_blocks_overflow_36 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_ECwcukirdurdueG + jmp .L_16_blocks_ok_36 -.L_16_blocks_overflow_ECwcukirdurdueG: +.L_16_blocks_overflow_36: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -7036,7 +7036,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_ECwcukirdurdueG: +.L_16_blocks_ok_36: @@ -7151,7 +7151,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zakyyybECukdlrD + jl .L_small_initial_partial_block_37 @@ -7211,8 +7211,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zakyyybECukdlrD -.L_small_initial_partial_block_zakyyybECukdlrD: + jmp .L_small_initial_compute_done_37 +.L_small_initial_partial_block_37: @@ -7269,26 +7269,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zakyyybECukdlrD: +.L_small_initial_compute_done_37: orq %r8,%r8 - je .L_after_reduction_zakyyybECukdlrD + je .L_after_reduction_37 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zakyyybECukdlrD: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_10_mlwyCypwkirBzdm: +.L_after_reduction_37: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_10_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_fikAepqkgbwnqAp + jae .L_16_blocks_overflow_38 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_fikAepqkgbwnqAp + jmp .L_16_blocks_ok_38 -.L_16_blocks_overflow_fikAepqkgbwnqAp: +.L_16_blocks_overflow_38: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -7297,7 +7297,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_fikAepqkgbwnqAp: +.L_16_blocks_ok_38: @@ -7412,7 +7412,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cEjqkDtdfxxsrnj + jl .L_small_initial_partial_block_39 @@ -7472,8 +7472,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cEjqkDtdfxxsrnj -.L_small_initial_partial_block_cEjqkDtdfxxsrnj: + jmp .L_small_initial_compute_done_39 +.L_small_initial_partial_block_39: @@ -7536,26 +7536,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cEjqkDtdfxxsrnj: +.L_small_initial_compute_done_39: orq %r8,%r8 - je .L_after_reduction_cEjqkDtdfxxsrnj + je .L_after_reduction_39 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cEjqkDtdfxxsrnj: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_11_mlwyCypwkirBzdm: +.L_after_reduction_39: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_11_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_uhBCuzelfsqdvbe + jae .L_16_blocks_overflow_40 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_uhBCuzelfsqdvbe + jmp .L_16_blocks_ok_40 -.L_16_blocks_overflow_uhBCuzelfsqdvbe: +.L_16_blocks_overflow_40: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -7564,7 +7564,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_uhBCuzelfsqdvbe: +.L_16_blocks_ok_40: @@ -7679,7 +7679,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EDvDxgDtsdjjkye + jl .L_small_initial_partial_block_41 @@ -7740,8 +7740,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EDvDxgDtsdjjkye -.L_small_initial_partial_block_EDvDxgDtsdjjkye: + jmp .L_small_initial_compute_done_41 +.L_small_initial_partial_block_41: @@ -7804,26 +7804,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EDvDxgDtsdjjkye: +.L_small_initial_compute_done_41: orq %r8,%r8 - je .L_after_reduction_EDvDxgDtsdjjkye + je .L_after_reduction_41 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EDvDxgDtsdjjkye: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_12_mlwyCypwkirBzdm: +.L_after_reduction_41: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_12_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_vvGybiowhiEjjhv + jae .L_16_blocks_overflow_42 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_vvGybiowhiEjjhv + jmp .L_16_blocks_ok_42 -.L_16_blocks_overflow_vvGybiowhiEjjhv: +.L_16_blocks_overflow_42: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -7832,7 +7832,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_vvGybiowhiEjjhv: +.L_16_blocks_ok_42: @@ -7947,7 +7947,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_iFhjvcxypnbuhvs + jl .L_small_initial_partial_block_43 @@ -8006,8 +8006,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_iFhjvcxypnbuhvs -.L_small_initial_partial_block_iFhjvcxypnbuhvs: + jmp .L_small_initial_compute_done_43 +.L_small_initial_partial_block_43: @@ -8071,27 +8071,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_iFhjvcxypnbuhvs: +.L_small_initial_compute_done_43: orq %r8,%r8 - je .L_after_reduction_iFhjvcxypnbuhvs + je .L_after_reduction_43 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_iFhjvcxypnbuhvs: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_13_mlwyCypwkirBzdm: +.L_after_reduction_43: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_13_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_cvoDCneGarpdspC + jae .L_16_blocks_overflow_44 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_cvoDCneGarpdspC + jmp .L_16_blocks_ok_44 -.L_16_blocks_overflow_cvoDCneGarpdspC: +.L_16_blocks_overflow_44: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -8102,7 +8102,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_cvoDCneGarpdspC: +.L_16_blocks_ok_44: @@ -8232,7 +8232,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dbnAEpbjbaCgfzC + jl .L_small_initial_partial_block_45 @@ -8297,8 +8297,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dbnAEpbjbaCgfzC -.L_small_initial_partial_block_dbnAEpbjbaCgfzC: + jmp .L_small_initial_compute_done_45 +.L_small_initial_partial_block_45: @@ -8360,27 +8360,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dbnAEpbjbaCgfzC: +.L_small_initial_compute_done_45: orq %r8,%r8 - je .L_after_reduction_dbnAEpbjbaCgfzC + je .L_after_reduction_45 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dbnAEpbjbaCgfzC: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_14_mlwyCypwkirBzdm: +.L_after_reduction_45: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_14_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_hdGdsixcoklvFzo + jae .L_16_blocks_overflow_46 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_hdGdsixcoklvFzo + jmp .L_16_blocks_ok_46 -.L_16_blocks_overflow_hdGdsixcoklvFzo: +.L_16_blocks_overflow_46: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -8391,7 +8391,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_hdGdsixcoklvFzo: +.L_16_blocks_ok_46: @@ -8521,7 +8521,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EwqzzBBaoveDrAF + jl .L_small_initial_partial_block_47 @@ -8586,8 +8586,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EwqzzBBaoveDrAF -.L_small_initial_partial_block_EwqzzBBaoveDrAF: + jmp .L_small_initial_compute_done_47 +.L_small_initial_partial_block_47: @@ -8655,27 +8655,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EwqzzBBaoveDrAF: +.L_small_initial_compute_done_47: orq %r8,%r8 - je .L_after_reduction_EwqzzBBaoveDrAF + je .L_after_reduction_47 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EwqzzBBaoveDrAF: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_15_mlwyCypwkirBzdm: +.L_after_reduction_47: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_15_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_zzkgklGxjyzrhtG + jae .L_16_blocks_overflow_48 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_zzkgklGxjyzrhtG + jmp .L_16_blocks_ok_48 -.L_16_blocks_overflow_zzkgklGxjyzrhtG: +.L_16_blocks_overflow_48: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -8686,7 +8686,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_zzkgklGxjyzrhtG: +.L_16_blocks_ok_48: @@ -8816,7 +8816,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xuzcyflqChzaomB + jl .L_small_initial_partial_block_49 @@ -8882,8 +8882,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xuzcyflqChzaomB -.L_small_initial_partial_block_xuzcyflqChzaomB: + jmp .L_small_initial_compute_done_49 +.L_small_initial_partial_block_49: @@ -8951,27 +8951,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xuzcyflqChzaomB: +.L_small_initial_compute_done_49: orq %r8,%r8 - je .L_after_reduction_xuzcyflqChzaomB + je .L_after_reduction_49 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xuzcyflqChzaomB: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_16_mlwyCypwkirBzdm: +.L_after_reduction_49: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_16_19: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_hsjsiokhvhqCsuF + jae .L_16_blocks_overflow_50 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_hsjsiokhvhqCsuF + jmp .L_16_blocks_ok_50 -.L_16_blocks_overflow_hsjsiokhvhqCsuF: +.L_16_blocks_overflow_50: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -8982,7 +8982,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_hsjsiokhvhqCsuF: +.L_16_blocks_ok_50: @@ -9109,7 +9109,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_vbicziAksonxcyl: +.L_small_initial_partial_block_51: @@ -9178,11 +9178,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vbicziAksonxcyl: +.L_small_initial_compute_done_51: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vbicziAksonxcyl: - jmp .L_last_blocks_done_mlwyCypwkirBzdm -.L_last_num_blocks_is_0_mlwyCypwkirBzdm: +.L_after_reduction_51: + jmp .L_last_blocks_done_19 +.L_last_num_blocks_is_0_19: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -9243,18 +9243,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_mlwyCypwkirBzdm: +.L_last_blocks_done_19: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_lzCeFkjwAopsEcs -.L_encrypt_32_blocks_lzCeFkjwAopsEcs: + jmp .L_ghash_done_10 +.L_encrypt_32_blocks_10: cmpb $240,%r15b - jae .L_16_blocks_overflow_dGGDApsErcyjgAG + jae .L_16_blocks_overflow_52 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_dGGDApsErcyjgAG -.L_16_blocks_overflow_dGGDApsErcyjgAG: + jmp .L_16_blocks_ok_52 +.L_16_blocks_overflow_52: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -9265,7 +9265,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_dGGDApsErcyjgAG: +.L_16_blocks_ok_52: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -9430,13 +9430,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_nuxkhCGiEwndcAA + jae .L_16_blocks_overflow_53 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_nuxkhCGiEwndcAA -.L_16_blocks_overflow_nuxkhCGiEwndcAA: + jmp .L_16_blocks_ok_53 +.L_16_blocks_overflow_53: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -9447,7 +9447,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_nuxkhCGiEwndcAA: +.L_16_blocks_ok_53: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -9680,61 +9680,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_yCoasknksvcxrbz + je .L_last_num_blocks_is_0_54 cmpl $8,%r10d - je .L_last_num_blocks_is_8_yCoasknksvcxrbz - jb .L_last_num_blocks_is_7_1_yCoasknksvcxrbz + je .L_last_num_blocks_is_8_54 + jb .L_last_num_blocks_is_7_1_54 cmpl $12,%r10d - je .L_last_num_blocks_is_12_yCoasknksvcxrbz - jb .L_last_num_blocks_is_11_9_yCoasknksvcxrbz + je .L_last_num_blocks_is_12_54 + jb .L_last_num_blocks_is_11_9_54 cmpl $15,%r10d - je .L_last_num_blocks_is_15_yCoasknksvcxrbz - ja .L_last_num_blocks_is_16_yCoasknksvcxrbz + je .L_last_num_blocks_is_15_54 + ja .L_last_num_blocks_is_16_54 cmpl $14,%r10d - je .L_last_num_blocks_is_14_yCoasknksvcxrbz - jmp .L_last_num_blocks_is_13_yCoasknksvcxrbz + je .L_last_num_blocks_is_14_54 + jmp .L_last_num_blocks_is_13_54 -.L_last_num_blocks_is_11_9_yCoasknksvcxrbz: +.L_last_num_blocks_is_11_9_54: cmpl $10,%r10d - je .L_last_num_blocks_is_10_yCoasknksvcxrbz - ja .L_last_num_blocks_is_11_yCoasknksvcxrbz - jmp .L_last_num_blocks_is_9_yCoasknksvcxrbz + je .L_last_num_blocks_is_10_54 + ja .L_last_num_blocks_is_11_54 + jmp .L_last_num_blocks_is_9_54 -.L_last_num_blocks_is_7_1_yCoasknksvcxrbz: +.L_last_num_blocks_is_7_1_54: cmpl $4,%r10d - je .L_last_num_blocks_is_4_yCoasknksvcxrbz - jb .L_last_num_blocks_is_3_1_yCoasknksvcxrbz + je .L_last_num_blocks_is_4_54 + jb .L_last_num_blocks_is_3_1_54 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_yCoasknksvcxrbz - je .L_last_num_blocks_is_6_yCoasknksvcxrbz - jmp .L_last_num_blocks_is_5_yCoasknksvcxrbz + ja .L_last_num_blocks_is_7_54 + je .L_last_num_blocks_is_6_54 + jmp .L_last_num_blocks_is_5_54 -.L_last_num_blocks_is_3_1_yCoasknksvcxrbz: +.L_last_num_blocks_is_3_1_54: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_yCoasknksvcxrbz - je .L_last_num_blocks_is_2_yCoasknksvcxrbz -.L_last_num_blocks_is_1_yCoasknksvcxrbz: + ja .L_last_num_blocks_is_3_54 + je .L_last_num_blocks_is_2_54 +.L_last_num_blocks_is_1_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_bgFgFkkmrGvFujm + jae .L_16_blocks_overflow_55 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_bgFgFkkmrGvFujm + jmp .L_16_blocks_ok_55 -.L_16_blocks_overflow_bgFgFkkmrGvFujm: +.L_16_blocks_overflow_55: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_bgFgFkkmrGvFujm: +.L_16_blocks_ok_55: @@ -9818,7 +9818,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lanzDhyxGCdmwtd + jl .L_small_initial_partial_block_56 @@ -9862,8 +9862,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lanzDhyxGCdmwtd -.L_small_initial_partial_block_lanzDhyxGCdmwtd: + jmp .L_small_initial_compute_done_56 +.L_small_initial_partial_block_56: @@ -9915,24 +9915,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_lanzDhyxGCdmwtd -.L_small_initial_compute_done_lanzDhyxGCdmwtd: -.L_after_reduction_lanzDhyxGCdmwtd: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_2_yCoasknksvcxrbz: + jmp .L_after_reduction_56 +.L_small_initial_compute_done_56: +.L_after_reduction_56: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_2_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_oAxdwmzDttnfxrb + jae .L_16_blocks_overflow_57 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_oAxdwmzDttnfxrb + jmp .L_16_blocks_ok_57 -.L_16_blocks_overflow_oAxdwmzDttnfxrb: +.L_16_blocks_overflow_57: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_oAxdwmzDttnfxrb: +.L_16_blocks_ok_57: @@ -10017,7 +10017,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rmlicyhaCuksFka + jl .L_small_initial_partial_block_58 @@ -10061,8 +10061,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rmlicyhaCuksFka -.L_small_initial_partial_block_rmlicyhaCuksFka: + jmp .L_small_initial_compute_done_58 +.L_small_initial_partial_block_58: @@ -10109,27 +10109,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rmlicyhaCuksFka: +.L_small_initial_compute_done_58: orq %r8,%r8 - je .L_after_reduction_rmlicyhaCuksFka + je .L_after_reduction_58 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rmlicyhaCuksFka: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_3_yCoasknksvcxrbz: +.L_after_reduction_58: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_3_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_FlcptspGAfyiqxE + jae .L_16_blocks_overflow_59 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_FlcptspGAfyiqxE + jmp .L_16_blocks_ok_59 -.L_16_blocks_overflow_FlcptspGAfyiqxE: +.L_16_blocks_overflow_59: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_FlcptspGAfyiqxE: +.L_16_blocks_ok_59: @@ -10214,7 +10214,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FipAdjmyyyeyzva + jl .L_small_initial_partial_block_60 @@ -10259,8 +10259,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FipAdjmyyyeyzva -.L_small_initial_partial_block_FipAdjmyyyeyzva: + jmp .L_small_initial_compute_done_60 +.L_small_initial_partial_block_60: @@ -10307,27 +10307,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FipAdjmyyyeyzva: +.L_small_initial_compute_done_60: orq %r8,%r8 - je .L_after_reduction_FipAdjmyyyeyzva + je .L_after_reduction_60 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FipAdjmyyyeyzva: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_4_yCoasknksvcxrbz: +.L_after_reduction_60: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_4_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_zbACEBDauizbtgw + jae .L_16_blocks_overflow_61 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_zbACEBDauizbtgw + jmp .L_16_blocks_ok_61 -.L_16_blocks_overflow_zbACEBDauizbtgw: +.L_16_blocks_overflow_61: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_zbACEBDauizbtgw: +.L_16_blocks_ok_61: @@ -10412,7 +10412,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ugbqDDimEpcebth + jl .L_small_initial_partial_block_62 @@ -10457,8 +10457,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ugbqDDimEpcebth -.L_small_initial_partial_block_ugbqDDimEpcebth: + jmp .L_small_initial_compute_done_62 +.L_small_initial_partial_block_62: @@ -10506,32 +10506,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ugbqDDimEpcebth: +.L_small_initial_compute_done_62: orq %r8,%r8 - je .L_after_reduction_ugbqDDimEpcebth + je .L_after_reduction_62 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ugbqDDimEpcebth: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_5_yCoasknksvcxrbz: +.L_after_reduction_62: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_5_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_whnpxcGiiqAwyzh + jae .L_16_blocks_overflow_63 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_whnpxcGiiqAwyzh + jmp .L_16_blocks_ok_63 -.L_16_blocks_overflow_whnpxcGiiqAwyzh: +.L_16_blocks_overflow_63: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_whnpxcGiiqAwyzh: +.L_16_blocks_ok_63: @@ -10631,7 +10631,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vdmtGlyqavdgxds + jl .L_small_initial_partial_block_64 @@ -10682,8 +10682,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vdmtGlyqavdgxds -.L_small_initial_partial_block_vdmtGlyqavdgxds: + jmp .L_small_initial_compute_done_64 +.L_small_initial_partial_block_64: @@ -10731,32 +10731,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vdmtGlyqavdgxds: +.L_small_initial_compute_done_64: orq %r8,%r8 - je .L_after_reduction_vdmtGlyqavdgxds + je .L_after_reduction_64 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vdmtGlyqavdgxds: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_6_yCoasknksvcxrbz: +.L_after_reduction_64: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_6_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_hEkukgbuBklfAxe + jae .L_16_blocks_overflow_65 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_hEkukgbuBklfAxe + jmp .L_16_blocks_ok_65 -.L_16_blocks_overflow_hEkukgbuBklfAxe: +.L_16_blocks_overflow_65: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_hEkukgbuBklfAxe: +.L_16_blocks_ok_65: @@ -10856,7 +10856,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_Btrqfjdicmqzbiu + jl .L_small_initial_partial_block_66 @@ -10907,8 +10907,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_Btrqfjdicmqzbiu -.L_small_initial_partial_block_Btrqfjdicmqzbiu: + jmp .L_small_initial_compute_done_66 +.L_small_initial_partial_block_66: @@ -10962,32 +10962,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_Btrqfjdicmqzbiu: +.L_small_initial_compute_done_66: orq %r8,%r8 - je .L_after_reduction_Btrqfjdicmqzbiu + je .L_after_reduction_66 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_Btrqfjdicmqzbiu: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_7_yCoasknksvcxrbz: +.L_after_reduction_66: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_7_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_qmvgyuEEotwbcGm + jae .L_16_blocks_overflow_67 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_qmvgyuEEotwbcGm + jmp .L_16_blocks_ok_67 -.L_16_blocks_overflow_qmvgyuEEotwbcGm: +.L_16_blocks_overflow_67: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_qmvgyuEEotwbcGm: +.L_16_blocks_ok_67: @@ -11087,7 +11087,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DaaqzwgAxvvkqDC + jl .L_small_initial_partial_block_68 @@ -11139,8 +11139,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DaaqzwgAxvvkqDC -.L_small_initial_partial_block_DaaqzwgAxvvkqDC: + jmp .L_small_initial_compute_done_68 +.L_small_initial_partial_block_68: @@ -11194,32 +11194,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DaaqzwgAxvvkqDC: +.L_small_initial_compute_done_68: orq %r8,%r8 - je .L_after_reduction_DaaqzwgAxvvkqDC + je .L_after_reduction_68 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DaaqzwgAxvvkqDC: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_8_yCoasknksvcxrbz: +.L_after_reduction_68: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_8_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_qsvmACcwxGzazwG + jae .L_16_blocks_overflow_69 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_qsvmACcwxGzazwG + jmp .L_16_blocks_ok_69 -.L_16_blocks_overflow_qsvmACcwxGzazwG: +.L_16_blocks_overflow_69: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_qsvmACcwxGzazwG: +.L_16_blocks_ok_69: @@ -11319,7 +11319,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_luejwGylbbqttxD + jl .L_small_initial_partial_block_70 @@ -11373,8 +11373,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_luejwGylbbqttxD -.L_small_initial_partial_block_luejwGylbbqttxD: + jmp .L_small_initial_compute_done_70 +.L_small_initial_partial_block_70: @@ -11429,26 +11429,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_luejwGylbbqttxD: +.L_small_initial_compute_done_70: orq %r8,%r8 - je .L_after_reduction_luejwGylbbqttxD + je .L_after_reduction_70 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_luejwGylbbqttxD: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_9_yCoasknksvcxrbz: +.L_after_reduction_70: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_9_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_BFGyztoirptABqf + jae .L_16_blocks_overflow_71 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_BFGyztoirptABqf + jmp .L_16_blocks_ok_71 -.L_16_blocks_overflow_BFGyztoirptABqf: +.L_16_blocks_overflow_71: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -11457,7 +11457,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_BFGyztoirptABqf: +.L_16_blocks_ok_71: @@ -11572,7 +11572,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vwsDgenrpsinatA + jl .L_small_initial_partial_block_72 @@ -11632,8 +11632,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vwsDgenrpsinatA -.L_small_initial_partial_block_vwsDgenrpsinatA: + jmp .L_small_initial_compute_done_72 +.L_small_initial_partial_block_72: @@ -11690,26 +11690,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vwsDgenrpsinatA: +.L_small_initial_compute_done_72: orq %r8,%r8 - je .L_after_reduction_vwsDgenrpsinatA + je .L_after_reduction_72 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vwsDgenrpsinatA: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_10_yCoasknksvcxrbz: +.L_after_reduction_72: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_10_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_BvpouEdxtnAzhcb + jae .L_16_blocks_overflow_73 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_BvpouEdxtnAzhcb + jmp .L_16_blocks_ok_73 -.L_16_blocks_overflow_BvpouEdxtnAzhcb: +.L_16_blocks_overflow_73: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -11718,7 +11718,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_BvpouEdxtnAzhcb: +.L_16_blocks_ok_73: @@ -11833,7 +11833,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AAfhgDnmzkhEpcy + jl .L_small_initial_partial_block_74 @@ -11893,8 +11893,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AAfhgDnmzkhEpcy -.L_small_initial_partial_block_AAfhgDnmzkhEpcy: + jmp .L_small_initial_compute_done_74 +.L_small_initial_partial_block_74: @@ -11957,26 +11957,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AAfhgDnmzkhEpcy: +.L_small_initial_compute_done_74: orq %r8,%r8 - je .L_after_reduction_AAfhgDnmzkhEpcy + je .L_after_reduction_74 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AAfhgDnmzkhEpcy: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_11_yCoasknksvcxrbz: +.L_after_reduction_74: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_11_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_mmtypFqeagAsznG + jae .L_16_blocks_overflow_75 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_mmtypFqeagAsznG + jmp .L_16_blocks_ok_75 -.L_16_blocks_overflow_mmtypFqeagAsznG: +.L_16_blocks_overflow_75: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -11985,7 +11985,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_mmtypFqeagAsznG: +.L_16_blocks_ok_75: @@ -12100,7 +12100,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oDzFCkpkpEkjAll + jl .L_small_initial_partial_block_76 @@ -12161,8 +12161,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oDzFCkpkpEkjAll -.L_small_initial_partial_block_oDzFCkpkpEkjAll: + jmp .L_small_initial_compute_done_76 +.L_small_initial_partial_block_76: @@ -12225,26 +12225,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oDzFCkpkpEkjAll: +.L_small_initial_compute_done_76: orq %r8,%r8 - je .L_after_reduction_oDzFCkpkpEkjAll + je .L_after_reduction_76 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_oDzFCkpkpEkjAll: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_12_yCoasknksvcxrbz: +.L_after_reduction_76: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_12_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_jigvdlhsqxusgzv + jae .L_16_blocks_overflow_77 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_jigvdlhsqxusgzv + jmp .L_16_blocks_ok_77 -.L_16_blocks_overflow_jigvdlhsqxusgzv: +.L_16_blocks_overflow_77: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -12253,7 +12253,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_jigvdlhsqxusgzv: +.L_16_blocks_ok_77: @@ -12368,7 +12368,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BztygblGrCvnamF + jl .L_small_initial_partial_block_78 @@ -12427,8 +12427,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BztygblGrCvnamF -.L_small_initial_partial_block_BztygblGrCvnamF: + jmp .L_small_initial_compute_done_78 +.L_small_initial_partial_block_78: @@ -12492,27 +12492,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BztygblGrCvnamF: +.L_small_initial_compute_done_78: orq %r8,%r8 - je .L_after_reduction_BztygblGrCvnamF + je .L_after_reduction_78 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BztygblGrCvnamF: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_13_yCoasknksvcxrbz: +.L_after_reduction_78: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_13_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_nCmFdlrEctfwynG + jae .L_16_blocks_overflow_79 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_nCmFdlrEctfwynG + jmp .L_16_blocks_ok_79 -.L_16_blocks_overflow_nCmFdlrEctfwynG: +.L_16_blocks_overflow_79: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -12523,7 +12523,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_nCmFdlrEctfwynG: +.L_16_blocks_ok_79: @@ -12653,7 +12653,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dtpxlGFwrvwweur + jl .L_small_initial_partial_block_80 @@ -12718,8 +12718,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dtpxlGFwrvwweur -.L_small_initial_partial_block_dtpxlGFwrvwweur: + jmp .L_small_initial_compute_done_80 +.L_small_initial_partial_block_80: @@ -12781,27 +12781,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dtpxlGFwrvwweur: +.L_small_initial_compute_done_80: orq %r8,%r8 - je .L_after_reduction_dtpxlGFwrvwweur + je .L_after_reduction_80 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dtpxlGFwrvwweur: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_14_yCoasknksvcxrbz: +.L_after_reduction_80: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_14_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_pEocmDmlECvduGF + jae .L_16_blocks_overflow_81 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_pEocmDmlECvduGF + jmp .L_16_blocks_ok_81 -.L_16_blocks_overflow_pEocmDmlECvduGF: +.L_16_blocks_overflow_81: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -12812,7 +12812,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_pEocmDmlECvduGF: +.L_16_blocks_ok_81: @@ -12942,7 +12942,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FevpdlBzDiGAmkn + jl .L_small_initial_partial_block_82 @@ -13007,8 +13007,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FevpdlBzDiGAmkn -.L_small_initial_partial_block_FevpdlBzDiGAmkn: + jmp .L_small_initial_compute_done_82 +.L_small_initial_partial_block_82: @@ -13076,27 +13076,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FevpdlBzDiGAmkn: +.L_small_initial_compute_done_82: orq %r8,%r8 - je .L_after_reduction_FevpdlBzDiGAmkn + je .L_after_reduction_82 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FevpdlBzDiGAmkn: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_15_yCoasknksvcxrbz: +.L_after_reduction_82: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_15_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_ngzCfxddkveBxdu + jae .L_16_blocks_overflow_83 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ngzCfxddkveBxdu + jmp .L_16_blocks_ok_83 -.L_16_blocks_overflow_ngzCfxddkveBxdu: +.L_16_blocks_overflow_83: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -13107,7 +13107,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ngzCfxddkveBxdu: +.L_16_blocks_ok_83: @@ -13237,7 +13237,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tjDhmjvbxeoydem + jl .L_small_initial_partial_block_84 @@ -13303,8 +13303,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tjDhmjvbxeoydem -.L_small_initial_partial_block_tjDhmjvbxeoydem: + jmp .L_small_initial_compute_done_84 +.L_small_initial_partial_block_84: @@ -13372,27 +13372,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tjDhmjvbxeoydem: +.L_small_initial_compute_done_84: orq %r8,%r8 - je .L_after_reduction_tjDhmjvbxeoydem + je .L_after_reduction_84 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tjDhmjvbxeoydem: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_16_yCoasknksvcxrbz: +.L_after_reduction_84: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_16_54: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_xchCsiGcxhfAbta + jae .L_16_blocks_overflow_85 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_xchCsiGcxhfAbta + jmp .L_16_blocks_ok_85 -.L_16_blocks_overflow_xchCsiGcxhfAbta: +.L_16_blocks_overflow_85: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -13403,7 +13403,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_xchCsiGcxhfAbta: +.L_16_blocks_ok_85: @@ -13530,7 +13530,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_hFzDxrwyiwtqwAe: +.L_small_initial_partial_block_86: @@ -13599,11 +13599,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hFzDxrwyiwtqwAe: +.L_small_initial_compute_done_86: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hFzDxrwyiwtqwAe: - jmp .L_last_blocks_done_yCoasknksvcxrbz -.L_last_num_blocks_is_0_yCoasknksvcxrbz: +.L_after_reduction_86: + jmp .L_last_blocks_done_54 +.L_last_num_blocks_is_0_54: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -13665,18 +13665,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_yCoasknksvcxrbz: +.L_last_blocks_done_54: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_lzCeFkjwAopsEcs -.L_encrypt_16_blocks_lzCeFkjwAopsEcs: + jmp .L_ghash_done_10 +.L_encrypt_16_blocks_10: cmpb $240,%r15b - jae .L_16_blocks_overflow_gxeyciouArFndur + jae .L_16_blocks_overflow_87 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_gxeyciouArFndur -.L_16_blocks_overflow_gxeyciouArFndur: + jmp .L_16_blocks_ok_87 +.L_16_blocks_overflow_87: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -13687,7 +13687,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_gxeyciouArFndur: +.L_16_blocks_ok_87: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -13889,61 +13889,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_BuoycnDoulvvizd + je .L_last_num_blocks_is_0_88 cmpl $8,%r10d - je .L_last_num_blocks_is_8_BuoycnDoulvvizd - jb .L_last_num_blocks_is_7_1_BuoycnDoulvvizd + je .L_last_num_blocks_is_8_88 + jb .L_last_num_blocks_is_7_1_88 cmpl $12,%r10d - je .L_last_num_blocks_is_12_BuoycnDoulvvizd - jb .L_last_num_blocks_is_11_9_BuoycnDoulvvizd + je .L_last_num_blocks_is_12_88 + jb .L_last_num_blocks_is_11_9_88 cmpl $15,%r10d - je .L_last_num_blocks_is_15_BuoycnDoulvvizd - ja .L_last_num_blocks_is_16_BuoycnDoulvvizd + je .L_last_num_blocks_is_15_88 + ja .L_last_num_blocks_is_16_88 cmpl $14,%r10d - je .L_last_num_blocks_is_14_BuoycnDoulvvizd - jmp .L_last_num_blocks_is_13_BuoycnDoulvvizd + je .L_last_num_blocks_is_14_88 + jmp .L_last_num_blocks_is_13_88 -.L_last_num_blocks_is_11_9_BuoycnDoulvvizd: +.L_last_num_blocks_is_11_9_88: cmpl $10,%r10d - je .L_last_num_blocks_is_10_BuoycnDoulvvizd - ja .L_last_num_blocks_is_11_BuoycnDoulvvizd - jmp .L_last_num_blocks_is_9_BuoycnDoulvvizd + je .L_last_num_blocks_is_10_88 + ja .L_last_num_blocks_is_11_88 + jmp .L_last_num_blocks_is_9_88 -.L_last_num_blocks_is_7_1_BuoycnDoulvvizd: +.L_last_num_blocks_is_7_1_88: cmpl $4,%r10d - je .L_last_num_blocks_is_4_BuoycnDoulvvizd - jb .L_last_num_blocks_is_3_1_BuoycnDoulvvizd + je .L_last_num_blocks_is_4_88 + jb .L_last_num_blocks_is_3_1_88 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_BuoycnDoulvvizd - je .L_last_num_blocks_is_6_BuoycnDoulvvizd - jmp .L_last_num_blocks_is_5_BuoycnDoulvvizd + ja .L_last_num_blocks_is_7_88 + je .L_last_num_blocks_is_6_88 + jmp .L_last_num_blocks_is_5_88 -.L_last_num_blocks_is_3_1_BuoycnDoulvvizd: +.L_last_num_blocks_is_3_1_88: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_BuoycnDoulvvizd - je .L_last_num_blocks_is_2_BuoycnDoulvvizd -.L_last_num_blocks_is_1_BuoycnDoulvvizd: + ja .L_last_num_blocks_is_3_88 + je .L_last_num_blocks_is_2_88 +.L_last_num_blocks_is_1_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_pksscjjkgBywAtt + jae .L_16_blocks_overflow_89 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_pksscjjkgBywAtt + jmp .L_16_blocks_ok_89 -.L_16_blocks_overflow_pksscjjkgBywAtt: +.L_16_blocks_overflow_89: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_pksscjjkgBywAtt: +.L_16_blocks_ok_89: @@ -14050,7 +14050,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_iCegDcofaFgyAdo + jl .L_small_initial_partial_block_90 @@ -14092,8 +14092,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_iCegDcofaFgyAdo -.L_small_initial_partial_block_iCegDcofaFgyAdo: + jmp .L_small_initial_compute_done_90 +.L_small_initial_partial_block_90: @@ -14117,24 +14117,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_iCegDcofaFgyAdo -.L_small_initial_compute_done_iCegDcofaFgyAdo: -.L_after_reduction_iCegDcofaFgyAdo: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_2_BuoycnDoulvvizd: + jmp .L_after_reduction_90 +.L_small_initial_compute_done_90: +.L_after_reduction_90: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_2_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_uEAqnbDFrGDyfDv + jae .L_16_blocks_overflow_91 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_uEAqnbDFrGDyfDv + jmp .L_16_blocks_ok_91 -.L_16_blocks_overflow_uEAqnbDFrGDyfDv: +.L_16_blocks_overflow_91: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_uEAqnbDFrGDyfDv: +.L_16_blocks_ok_91: @@ -14242,7 +14242,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cCycbDfAihCmGuD + jl .L_small_initial_partial_block_92 @@ -14284,8 +14284,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cCycbDfAihCmGuD -.L_small_initial_partial_block_cCycbDfAihCmGuD: + jmp .L_small_initial_compute_done_92 +.L_small_initial_partial_block_92: @@ -14330,27 +14330,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cCycbDfAihCmGuD: +.L_small_initial_compute_done_92: orq %r8,%r8 - je .L_after_reduction_cCycbDfAihCmGuD + je .L_after_reduction_92 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cCycbDfAihCmGuD: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_3_BuoycnDoulvvizd: +.L_after_reduction_92: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_3_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_tdsclgzaphzezBr + jae .L_16_blocks_overflow_93 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_tdsclgzaphzezBr + jmp .L_16_blocks_ok_93 -.L_16_blocks_overflow_tdsclgzaphzezBr: +.L_16_blocks_overflow_93: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_tdsclgzaphzezBr: +.L_16_blocks_ok_93: @@ -14458,7 +14458,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vessyjqipofivra + jl .L_small_initial_partial_block_94 @@ -14501,8 +14501,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vessyjqipofivra -.L_small_initial_partial_block_vessyjqipofivra: + jmp .L_small_initial_compute_done_94 +.L_small_initial_partial_block_94: @@ -14547,27 +14547,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vessyjqipofivra: +.L_small_initial_compute_done_94: orq %r8,%r8 - je .L_after_reduction_vessyjqipofivra + je .L_after_reduction_94 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vessyjqipofivra: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_4_BuoycnDoulvvizd: +.L_after_reduction_94: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_4_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_BtzndArGfxAjmzd + jae .L_16_blocks_overflow_95 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_BtzndArGfxAjmzd + jmp .L_16_blocks_ok_95 -.L_16_blocks_overflow_BtzndArGfxAjmzd: +.L_16_blocks_overflow_95: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_BtzndArGfxAjmzd: +.L_16_blocks_ok_95: @@ -14675,7 +14675,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vBbpjsCpcpbfheG + jl .L_small_initial_partial_block_96 @@ -14717,8 +14717,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vBbpjsCpcpbfheG -.L_small_initial_partial_block_vBbpjsCpcpbfheG: + jmp .L_small_initial_compute_done_96 +.L_small_initial_partial_block_96: @@ -14764,32 +14764,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vBbpjsCpcpbfheG: +.L_small_initial_compute_done_96: orq %r8,%r8 - je .L_after_reduction_vBbpjsCpcpbfheG + je .L_after_reduction_96 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vBbpjsCpcpbfheG: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_5_BuoycnDoulvvizd: +.L_after_reduction_96: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_5_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_ycEywfuBvizmpgg + jae .L_16_blocks_overflow_97 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_ycEywfuBvizmpgg + jmp .L_16_blocks_ok_97 -.L_16_blocks_overflow_ycEywfuBvizmpgg: +.L_16_blocks_overflow_97: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_ycEywfuBvizmpgg: +.L_16_blocks_ok_97: @@ -14912,7 +14912,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ngtwkfvbdByyCfs + jl .L_small_initial_partial_block_98 @@ -14964,8 +14964,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ngtwkfvbdByyCfs -.L_small_initial_partial_block_ngtwkfvbdByyCfs: + jmp .L_small_initial_compute_done_98 +.L_small_initial_partial_block_98: @@ -15010,32 +15010,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ngtwkfvbdByyCfs: +.L_small_initial_compute_done_98: orq %r8,%r8 - je .L_after_reduction_ngtwkfvbdByyCfs + je .L_after_reduction_98 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ngtwkfvbdByyCfs: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_6_BuoycnDoulvvizd: +.L_after_reduction_98: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_6_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_ufoBeEaDpgdqGAF + jae .L_16_blocks_overflow_99 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_ufoBeEaDpgdqGAF + jmp .L_16_blocks_ok_99 -.L_16_blocks_overflow_ufoBeEaDpgdqGAF: +.L_16_blocks_overflow_99: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_ufoBeEaDpgdqGAF: +.L_16_blocks_ok_99: @@ -15158,7 +15158,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FDBhlDqpiBBBkin + jl .L_small_initial_partial_block_100 @@ -15210,8 +15210,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FDBhlDqpiBBBkin -.L_small_initial_partial_block_FDBhlDqpiBBBkin: + jmp .L_small_initial_compute_done_100 +.L_small_initial_partial_block_100: @@ -15266,32 +15266,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FDBhlDqpiBBBkin: +.L_small_initial_compute_done_100: orq %r8,%r8 - je .L_after_reduction_FDBhlDqpiBBBkin + je .L_after_reduction_100 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FDBhlDqpiBBBkin: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_7_BuoycnDoulvvizd: +.L_after_reduction_100: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_7_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_EnldzDvbFsxudDB + jae .L_16_blocks_overflow_101 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_EnldzDvbFsxudDB + jmp .L_16_blocks_ok_101 -.L_16_blocks_overflow_EnldzDvbFsxudDB: +.L_16_blocks_overflow_101: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_EnldzDvbFsxudDB: +.L_16_blocks_ok_101: @@ -15414,7 +15414,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xaGcCawFDhaucDt + jl .L_small_initial_partial_block_102 @@ -15467,8 +15467,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xaGcCawFDhaucDt -.L_small_initial_partial_block_xaGcCawFDhaucDt: + jmp .L_small_initial_compute_done_102 +.L_small_initial_partial_block_102: @@ -15523,32 +15523,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xaGcCawFDhaucDt: +.L_small_initial_compute_done_102: orq %r8,%r8 - je .L_after_reduction_xaGcCawFDhaucDt + je .L_after_reduction_102 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xaGcCawFDhaucDt: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_8_BuoycnDoulvvizd: +.L_after_reduction_102: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_8_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_EvBzjrpplobxhsp + jae .L_16_blocks_overflow_103 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_EvBzjrpplobxhsp + jmp .L_16_blocks_ok_103 -.L_16_blocks_overflow_EvBzjrpplobxhsp: +.L_16_blocks_overflow_103: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_EvBzjrpplobxhsp: +.L_16_blocks_ok_103: @@ -15671,7 +15671,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hnfxrytabzGpDze + jl .L_small_initial_partial_block_104 @@ -15722,8 +15722,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hnfxrytabzGpDze -.L_small_initial_partial_block_hnfxrytabzGpDze: + jmp .L_small_initial_compute_done_104 +.L_small_initial_partial_block_104: @@ -15779,26 +15779,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hnfxrytabzGpDze: +.L_small_initial_compute_done_104: orq %r8,%r8 - je .L_after_reduction_hnfxrytabzGpDze + je .L_after_reduction_104 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hnfxrytabzGpDze: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_9_BuoycnDoulvvizd: +.L_after_reduction_104: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_9_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_mfyeDgnGaACDqoe + jae .L_16_blocks_overflow_105 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_mfyeDgnGaACDqoe + jmp .L_16_blocks_ok_105 -.L_16_blocks_overflow_mfyeDgnGaACDqoe: +.L_16_blocks_overflow_105: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -15807,7 +15807,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_mfyeDgnGaACDqoe: +.L_16_blocks_ok_105: @@ -15945,7 +15945,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DdihFzytwBhpGdu + jl .L_small_initial_partial_block_106 @@ -16006,8 +16006,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DdihFzytwBhpGdu -.L_small_initial_partial_block_DdihFzytwBhpGdu: + jmp .L_small_initial_compute_done_106 +.L_small_initial_partial_block_106: @@ -16061,26 +16061,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DdihFzytwBhpGdu: +.L_small_initial_compute_done_106: orq %r8,%r8 - je .L_after_reduction_DdihFzytwBhpGdu + je .L_after_reduction_106 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DdihFzytwBhpGdu: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_10_BuoycnDoulvvizd: +.L_after_reduction_106: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_10_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_GxsvkqtsrDEtGuA + jae .L_16_blocks_overflow_107 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_GxsvkqtsrDEtGuA + jmp .L_16_blocks_ok_107 -.L_16_blocks_overflow_GxsvkqtsrDEtGuA: +.L_16_blocks_overflow_107: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -16089,7 +16089,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_GxsvkqtsrDEtGuA: +.L_16_blocks_ok_107: @@ -16227,7 +16227,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tAdqwAwmmudhgnx + jl .L_small_initial_partial_block_108 @@ -16288,8 +16288,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tAdqwAwmmudhgnx -.L_small_initial_partial_block_tAdqwAwmmudhgnx: + jmp .L_small_initial_compute_done_108 +.L_small_initial_partial_block_108: @@ -16353,26 +16353,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tAdqwAwmmudhgnx: +.L_small_initial_compute_done_108: orq %r8,%r8 - je .L_after_reduction_tAdqwAwmmudhgnx + je .L_after_reduction_108 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tAdqwAwmmudhgnx: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_11_BuoycnDoulvvizd: +.L_after_reduction_108: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_11_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_xiqcEDtyDyGwkBr + jae .L_16_blocks_overflow_109 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_xiqcEDtyDyGwkBr + jmp .L_16_blocks_ok_109 -.L_16_blocks_overflow_xiqcEDtyDyGwkBr: +.L_16_blocks_overflow_109: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -16381,7 +16381,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_xiqcEDtyDyGwkBr: +.L_16_blocks_ok_109: @@ -16519,7 +16519,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uoFmhCcDchipCvt + jl .L_small_initial_partial_block_110 @@ -16581,8 +16581,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uoFmhCcDchipCvt -.L_small_initial_partial_block_uoFmhCcDchipCvt: + jmp .L_small_initial_compute_done_110 +.L_small_initial_partial_block_110: @@ -16646,26 +16646,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uoFmhCcDchipCvt: +.L_small_initial_compute_done_110: orq %r8,%r8 - je .L_after_reduction_uoFmhCcDchipCvt + je .L_after_reduction_110 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_uoFmhCcDchipCvt: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_12_BuoycnDoulvvizd: +.L_after_reduction_110: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_12_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_emmqcahqycrbAvy + jae .L_16_blocks_overflow_111 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_emmqcahqycrbAvy + jmp .L_16_blocks_ok_111 -.L_16_blocks_overflow_emmqcahqycrbAvy: +.L_16_blocks_overflow_111: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -16674,7 +16674,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_emmqcahqycrbAvy: +.L_16_blocks_ok_111: @@ -16812,7 +16812,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yrofwmknufBhqkg + jl .L_small_initial_partial_block_112 @@ -16868,8 +16868,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yrofwmknufBhqkg -.L_small_initial_partial_block_yrofwmknufBhqkg: + jmp .L_small_initial_compute_done_112 +.L_small_initial_partial_block_112: @@ -16934,27 +16934,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yrofwmknufBhqkg: +.L_small_initial_compute_done_112: orq %r8,%r8 - je .L_after_reduction_yrofwmknufBhqkg + je .L_after_reduction_112 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yrofwmknufBhqkg: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_13_BuoycnDoulvvizd: +.L_after_reduction_112: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_13_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_gyyvpyrBamvxicd + jae .L_16_blocks_overflow_113 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_gyyvpyrBamvxicd + jmp .L_16_blocks_ok_113 -.L_16_blocks_overflow_gyyvpyrBamvxicd: +.L_16_blocks_overflow_113: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -16965,7 +16965,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_gyyvpyrBamvxicd: +.L_16_blocks_ok_113: @@ -17118,7 +17118,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gejEbitlocEoFpj + jl .L_small_initial_partial_block_114 @@ -17184,8 +17184,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gejEbitlocEoFpj -.L_small_initial_partial_block_gejEbitlocEoFpj: + jmp .L_small_initial_compute_done_114 +.L_small_initial_partial_block_114: @@ -17244,27 +17244,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gejEbitlocEoFpj: +.L_small_initial_compute_done_114: orq %r8,%r8 - je .L_after_reduction_gejEbitlocEoFpj + je .L_after_reduction_114 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gejEbitlocEoFpj: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_14_BuoycnDoulvvizd: +.L_after_reduction_114: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_14_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_hyFgdkqlfCEoeCm + jae .L_16_blocks_overflow_115 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_hyFgdkqlfCEoeCm + jmp .L_16_blocks_ok_115 -.L_16_blocks_overflow_hyFgdkqlfCEoeCm: +.L_16_blocks_overflow_115: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -17275,7 +17275,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_hyFgdkqlfCEoeCm: +.L_16_blocks_ok_115: @@ -17428,7 +17428,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_daxGpkfmviuqtkm + jl .L_small_initial_partial_block_116 @@ -17494,8 +17494,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_daxGpkfmviuqtkm -.L_small_initial_partial_block_daxGpkfmviuqtkm: + jmp .L_small_initial_compute_done_116 +.L_small_initial_partial_block_116: @@ -17564,27 +17564,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_daxGpkfmviuqtkm: +.L_small_initial_compute_done_116: orq %r8,%r8 - je .L_after_reduction_daxGpkfmviuqtkm + je .L_after_reduction_116 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_daxGpkfmviuqtkm: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_15_BuoycnDoulvvizd: +.L_after_reduction_116: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_15_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_tuelGvmqaeAhhmd + jae .L_16_blocks_overflow_117 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_tuelGvmqaeAhhmd + jmp .L_16_blocks_ok_117 -.L_16_blocks_overflow_tuelGvmqaeAhhmd: +.L_16_blocks_overflow_117: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -17595,7 +17595,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_tuelGvmqaeAhhmd: +.L_16_blocks_ok_117: @@ -17748,7 +17748,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aqtprFqqDktCCtx + jl .L_small_initial_partial_block_118 @@ -17815,8 +17815,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aqtprFqqDktCCtx -.L_small_initial_partial_block_aqtprFqqDktCCtx: + jmp .L_small_initial_compute_done_118 +.L_small_initial_partial_block_118: @@ -17885,27 +17885,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aqtprFqqDktCCtx: +.L_small_initial_compute_done_118: orq %r8,%r8 - je .L_after_reduction_aqtprFqqDktCCtx + je .L_after_reduction_118 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aqtprFqqDktCCtx: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_16_BuoycnDoulvvizd: +.L_after_reduction_118: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_16_88: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_pcvkptvvvrwnmdr + jae .L_16_blocks_overflow_119 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_pcvkptvvvrwnmdr + jmp .L_16_blocks_ok_119 -.L_16_blocks_overflow_pcvkptvvvrwnmdr: +.L_16_blocks_overflow_119: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -17916,7 +17916,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_pcvkptvvvrwnmdr: +.L_16_blocks_ok_119: @@ -18066,7 +18066,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_GdmkuGblwdrtsjm: +.L_small_initial_partial_block_120: @@ -18136,11 +18136,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GdmkuGblwdrtsjm: +.L_small_initial_compute_done_120: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GdmkuGblwdrtsjm: - jmp .L_last_blocks_done_BuoycnDoulvvizd -.L_last_num_blocks_is_0_BuoycnDoulvvizd: +.L_after_reduction_120: + jmp .L_last_blocks_done_88 +.L_last_num_blocks_is_0_88: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -18201,18 +18201,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_BuoycnDoulvvizd: +.L_last_blocks_done_88: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_lzCeFkjwAopsEcs + jmp .L_ghash_done_10 -.L_message_below_32_blocks_lzCeFkjwAopsEcs: +.L_message_below_32_blocks_10: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_ahiskmgfntrjFdo + jnz .L_skip_hkeys_precomputation_121 vmovdqu64 640(%rsp),%zmm3 @@ -18340,7 +18340,7 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_ahiskmgfntrjFdo: +.L_skip_hkeys_precomputation_121: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -18348,61 +18348,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_0_122 cmpl $8,%r10d - je .L_last_num_blocks_is_8_jpCbfqoGugGzzuz - jb .L_last_num_blocks_is_7_1_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_8_122 + jb .L_last_num_blocks_is_7_1_122 cmpl $12,%r10d - je .L_last_num_blocks_is_12_jpCbfqoGugGzzuz - jb .L_last_num_blocks_is_11_9_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_12_122 + jb .L_last_num_blocks_is_11_9_122 cmpl $15,%r10d - je .L_last_num_blocks_is_15_jpCbfqoGugGzzuz - ja .L_last_num_blocks_is_16_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_15_122 + ja .L_last_num_blocks_is_16_122 cmpl $14,%r10d - je .L_last_num_blocks_is_14_jpCbfqoGugGzzuz - jmp .L_last_num_blocks_is_13_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_14_122 + jmp .L_last_num_blocks_is_13_122 -.L_last_num_blocks_is_11_9_jpCbfqoGugGzzuz: +.L_last_num_blocks_is_11_9_122: cmpl $10,%r10d - je .L_last_num_blocks_is_10_jpCbfqoGugGzzuz - ja .L_last_num_blocks_is_11_jpCbfqoGugGzzuz - jmp .L_last_num_blocks_is_9_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_10_122 + ja .L_last_num_blocks_is_11_122 + jmp .L_last_num_blocks_is_9_122 -.L_last_num_blocks_is_7_1_jpCbfqoGugGzzuz: +.L_last_num_blocks_is_7_1_122: cmpl $4,%r10d - je .L_last_num_blocks_is_4_jpCbfqoGugGzzuz - jb .L_last_num_blocks_is_3_1_jpCbfqoGugGzzuz + je .L_last_num_blocks_is_4_122 + jb .L_last_num_blocks_is_3_1_122 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_jpCbfqoGugGzzuz - je .L_last_num_blocks_is_6_jpCbfqoGugGzzuz - jmp .L_last_num_blocks_is_5_jpCbfqoGugGzzuz + ja .L_last_num_blocks_is_7_122 + je .L_last_num_blocks_is_6_122 + jmp .L_last_num_blocks_is_5_122 -.L_last_num_blocks_is_3_1_jpCbfqoGugGzzuz: +.L_last_num_blocks_is_3_1_122: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_jpCbfqoGugGzzuz - je .L_last_num_blocks_is_2_jpCbfqoGugGzzuz -.L_last_num_blocks_is_1_jpCbfqoGugGzzuz: + ja .L_last_num_blocks_is_3_122 + je .L_last_num_blocks_is_2_122 +.L_last_num_blocks_is_1_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_cEtkbFsluzmifan + jae .L_16_blocks_overflow_123 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_cEtkbFsluzmifan + jmp .L_16_blocks_ok_123 -.L_16_blocks_overflow_cEtkbFsluzmifan: +.L_16_blocks_overflow_123: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_cEtkbFsluzmifan: +.L_16_blocks_ok_123: @@ -18486,7 +18486,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_pjaofmycugtfpqf + jl .L_small_initial_partial_block_124 @@ -18530,8 +18530,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_pjaofmycugtfpqf -.L_small_initial_partial_block_pjaofmycugtfpqf: + jmp .L_small_initial_compute_done_124 +.L_small_initial_partial_block_124: @@ -18583,24 +18583,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_pjaofmycugtfpqf -.L_small_initial_compute_done_pjaofmycugtfpqf: -.L_after_reduction_pjaofmycugtfpqf: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_2_jpCbfqoGugGzzuz: + jmp .L_after_reduction_124 +.L_small_initial_compute_done_124: +.L_after_reduction_124: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_2_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_DpvcmqCisGpGwGd + jae .L_16_blocks_overflow_125 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_DpvcmqCisGpGwGd + jmp .L_16_blocks_ok_125 -.L_16_blocks_overflow_DpvcmqCisGpGwGd: +.L_16_blocks_overflow_125: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_DpvcmqCisGpGwGd: +.L_16_blocks_ok_125: @@ -18685,7 +18685,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CrDslAwddrtubet + jl .L_small_initial_partial_block_126 @@ -18729,8 +18729,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CrDslAwddrtubet -.L_small_initial_partial_block_CrDslAwddrtubet: + jmp .L_small_initial_compute_done_126 +.L_small_initial_partial_block_126: @@ -18777,27 +18777,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CrDslAwddrtubet: +.L_small_initial_compute_done_126: orq %r8,%r8 - je .L_after_reduction_CrDslAwddrtubet + je .L_after_reduction_126 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CrDslAwddrtubet: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_3_jpCbfqoGugGzzuz: +.L_after_reduction_126: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_3_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_vGCsoGAxuhlfCAg + jae .L_16_blocks_overflow_127 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_vGCsoGAxuhlfCAg + jmp .L_16_blocks_ok_127 -.L_16_blocks_overflow_vGCsoGAxuhlfCAg: +.L_16_blocks_overflow_127: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_vGCsoGAxuhlfCAg: +.L_16_blocks_ok_127: @@ -18882,7 +18882,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lqzFgFBpwwknxwd + jl .L_small_initial_partial_block_128 @@ -18927,8 +18927,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lqzFgFBpwwknxwd -.L_small_initial_partial_block_lqzFgFBpwwknxwd: + jmp .L_small_initial_compute_done_128 +.L_small_initial_partial_block_128: @@ -18975,27 +18975,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lqzFgFBpwwknxwd: +.L_small_initial_compute_done_128: orq %r8,%r8 - je .L_after_reduction_lqzFgFBpwwknxwd + je .L_after_reduction_128 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lqzFgFBpwwknxwd: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_4_jpCbfqoGugGzzuz: +.L_after_reduction_128: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_4_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_qGdeoEGzqjAtsEv + jae .L_16_blocks_overflow_129 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_qGdeoEGzqjAtsEv + jmp .L_16_blocks_ok_129 -.L_16_blocks_overflow_qGdeoEGzqjAtsEv: +.L_16_blocks_overflow_129: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_qGdeoEGzqjAtsEv: +.L_16_blocks_ok_129: @@ -19080,7 +19080,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yDhjepihmppntDz + jl .L_small_initial_partial_block_130 @@ -19125,8 +19125,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yDhjepihmppntDz -.L_small_initial_partial_block_yDhjepihmppntDz: + jmp .L_small_initial_compute_done_130 +.L_small_initial_partial_block_130: @@ -19174,32 +19174,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yDhjepihmppntDz: +.L_small_initial_compute_done_130: orq %r8,%r8 - je .L_after_reduction_yDhjepihmppntDz + je .L_after_reduction_130 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yDhjepihmppntDz: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_5_jpCbfqoGugGzzuz: +.L_after_reduction_130: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_5_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_wqfiDzxfapbFAxx + jae .L_16_blocks_overflow_131 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_wqfiDzxfapbFAxx + jmp .L_16_blocks_ok_131 -.L_16_blocks_overflow_wqfiDzxfapbFAxx: +.L_16_blocks_overflow_131: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_wqfiDzxfapbFAxx: +.L_16_blocks_ok_131: @@ -19299,7 +19299,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yjakqsCiAeACmDA + jl .L_small_initial_partial_block_132 @@ -19350,8 +19350,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yjakqsCiAeACmDA -.L_small_initial_partial_block_yjakqsCiAeACmDA: + jmp .L_small_initial_compute_done_132 +.L_small_initial_partial_block_132: @@ -19399,32 +19399,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yjakqsCiAeACmDA: +.L_small_initial_compute_done_132: orq %r8,%r8 - je .L_after_reduction_yjakqsCiAeACmDA + je .L_after_reduction_132 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yjakqsCiAeACmDA: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_6_jpCbfqoGugGzzuz: +.L_after_reduction_132: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_6_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_vDpyprgABGpAtls + jae .L_16_blocks_overflow_133 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_vDpyprgABGpAtls + jmp .L_16_blocks_ok_133 -.L_16_blocks_overflow_vDpyprgABGpAtls: +.L_16_blocks_overflow_133: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_vDpyprgABGpAtls: +.L_16_blocks_ok_133: @@ -19524,7 +19524,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wEbqcegdEDyEnez + jl .L_small_initial_partial_block_134 @@ -19575,8 +19575,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wEbqcegdEDyEnez -.L_small_initial_partial_block_wEbqcegdEDyEnez: + jmp .L_small_initial_compute_done_134 +.L_small_initial_partial_block_134: @@ -19630,32 +19630,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wEbqcegdEDyEnez: +.L_small_initial_compute_done_134: orq %r8,%r8 - je .L_after_reduction_wEbqcegdEDyEnez + je .L_after_reduction_134 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wEbqcegdEDyEnez: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_7_jpCbfqoGugGzzuz: +.L_after_reduction_134: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_7_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_CGxECAnvzGlfqff + jae .L_16_blocks_overflow_135 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_CGxECAnvzGlfqff + jmp .L_16_blocks_ok_135 -.L_16_blocks_overflow_CGxECAnvzGlfqff: +.L_16_blocks_overflow_135: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_CGxECAnvzGlfqff: +.L_16_blocks_ok_135: @@ -19755,7 +19755,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DDAbEjgjlayDwuh + jl .L_small_initial_partial_block_136 @@ -19807,8 +19807,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DDAbEjgjlayDwuh -.L_small_initial_partial_block_DDAbEjgjlayDwuh: + jmp .L_small_initial_compute_done_136 +.L_small_initial_partial_block_136: @@ -19862,32 +19862,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DDAbEjgjlayDwuh: +.L_small_initial_compute_done_136: orq %r8,%r8 - je .L_after_reduction_DDAbEjgjlayDwuh + je .L_after_reduction_136 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DDAbEjgjlayDwuh: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_8_jpCbfqoGugGzzuz: +.L_after_reduction_136: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_8_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_wfjjunzjbgueygm + jae .L_16_blocks_overflow_137 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_wfjjunzjbgueygm + jmp .L_16_blocks_ok_137 -.L_16_blocks_overflow_wfjjunzjbgueygm: +.L_16_blocks_overflow_137: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_wfjjunzjbgueygm: +.L_16_blocks_ok_137: @@ -19987,7 +19987,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zagbvdDpuuGnysG + jl .L_small_initial_partial_block_138 @@ -20041,8 +20041,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zagbvdDpuuGnysG -.L_small_initial_partial_block_zagbvdDpuuGnysG: + jmp .L_small_initial_compute_done_138 +.L_small_initial_partial_block_138: @@ -20097,26 +20097,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zagbvdDpuuGnysG: +.L_small_initial_compute_done_138: orq %r8,%r8 - je .L_after_reduction_zagbvdDpuuGnysG + je .L_after_reduction_138 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zagbvdDpuuGnysG: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_9_jpCbfqoGugGzzuz: +.L_after_reduction_138: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_9_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_FkirsAyzfbljhxg + jae .L_16_blocks_overflow_139 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_FkirsAyzfbljhxg + jmp .L_16_blocks_ok_139 -.L_16_blocks_overflow_FkirsAyzfbljhxg: +.L_16_blocks_overflow_139: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -20125,7 +20125,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_FkirsAyzfbljhxg: +.L_16_blocks_ok_139: @@ -20240,7 +20240,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jhAAwghgigseemB + jl .L_small_initial_partial_block_140 @@ -20300,8 +20300,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jhAAwghgigseemB -.L_small_initial_partial_block_jhAAwghgigseemB: + jmp .L_small_initial_compute_done_140 +.L_small_initial_partial_block_140: @@ -20358,26 +20358,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jhAAwghgigseemB: +.L_small_initial_compute_done_140: orq %r8,%r8 - je .L_after_reduction_jhAAwghgigseemB + je .L_after_reduction_140 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jhAAwghgigseemB: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_10_jpCbfqoGugGzzuz: +.L_after_reduction_140: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_10_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_vyaCsCeBwgFiAjF + jae .L_16_blocks_overflow_141 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_vyaCsCeBwgFiAjF + jmp .L_16_blocks_ok_141 -.L_16_blocks_overflow_vyaCsCeBwgFiAjF: +.L_16_blocks_overflow_141: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -20386,7 +20386,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_vyaCsCeBwgFiAjF: +.L_16_blocks_ok_141: @@ -20501,7 +20501,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BDfFypvGGGelziE + jl .L_small_initial_partial_block_142 @@ -20561,8 +20561,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BDfFypvGGGelziE -.L_small_initial_partial_block_BDfFypvGGGelziE: + jmp .L_small_initial_compute_done_142 +.L_small_initial_partial_block_142: @@ -20625,26 +20625,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BDfFypvGGGelziE: +.L_small_initial_compute_done_142: orq %r8,%r8 - je .L_after_reduction_BDfFypvGGGelziE + je .L_after_reduction_142 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BDfFypvGGGelziE: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_11_jpCbfqoGugGzzuz: +.L_after_reduction_142: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_11_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_GdktpFFwnbByrcE + jae .L_16_blocks_overflow_143 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_GdktpFFwnbByrcE + jmp .L_16_blocks_ok_143 -.L_16_blocks_overflow_GdktpFFwnbByrcE: +.L_16_blocks_overflow_143: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -20653,7 +20653,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_GdktpFFwnbByrcE: +.L_16_blocks_ok_143: @@ -20768,7 +20768,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EGkdlABaCFCeiic + jl .L_small_initial_partial_block_144 @@ -20829,8 +20829,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EGkdlABaCFCeiic -.L_small_initial_partial_block_EGkdlABaCFCeiic: + jmp .L_small_initial_compute_done_144 +.L_small_initial_partial_block_144: @@ -20893,26 +20893,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EGkdlABaCFCeiic: +.L_small_initial_compute_done_144: orq %r8,%r8 - je .L_after_reduction_EGkdlABaCFCeiic + je .L_after_reduction_144 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EGkdlABaCFCeiic: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_12_jpCbfqoGugGzzuz: +.L_after_reduction_144: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_12_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_gmmmDpxtjyvfhel + jae .L_16_blocks_overflow_145 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_gmmmDpxtjyvfhel + jmp .L_16_blocks_ok_145 -.L_16_blocks_overflow_gmmmDpxtjyvfhel: +.L_16_blocks_overflow_145: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -20921,7 +20921,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_gmmmDpxtjyvfhel: +.L_16_blocks_ok_145: @@ -21036,7 +21036,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xfswggahvljdbBp + jl .L_small_initial_partial_block_146 @@ -21095,8 +21095,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xfswggahvljdbBp -.L_small_initial_partial_block_xfswggahvljdbBp: + jmp .L_small_initial_compute_done_146 +.L_small_initial_partial_block_146: @@ -21160,27 +21160,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xfswggahvljdbBp: +.L_small_initial_compute_done_146: orq %r8,%r8 - je .L_after_reduction_xfswggahvljdbBp + je .L_after_reduction_146 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xfswggahvljdbBp: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_13_jpCbfqoGugGzzuz: +.L_after_reduction_146: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_13_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_kofAeFCEmiCGlpk + jae .L_16_blocks_overflow_147 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_kofAeFCEmiCGlpk + jmp .L_16_blocks_ok_147 -.L_16_blocks_overflow_kofAeFCEmiCGlpk: +.L_16_blocks_overflow_147: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -21191,7 +21191,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_kofAeFCEmiCGlpk: +.L_16_blocks_ok_147: @@ -21321,7 +21321,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EbdBGdunrlvsrkF + jl .L_small_initial_partial_block_148 @@ -21386,8 +21386,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EbdBGdunrlvsrkF -.L_small_initial_partial_block_EbdBGdunrlvsrkF: + jmp .L_small_initial_compute_done_148 +.L_small_initial_partial_block_148: @@ -21449,27 +21449,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EbdBGdunrlvsrkF: +.L_small_initial_compute_done_148: orq %r8,%r8 - je .L_after_reduction_EbdBGdunrlvsrkF + je .L_after_reduction_148 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EbdBGdunrlvsrkF: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_14_jpCbfqoGugGzzuz: +.L_after_reduction_148: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_14_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_bAzDwrrmtwFlhxC + jae .L_16_blocks_overflow_149 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_bAzDwrrmtwFlhxC + jmp .L_16_blocks_ok_149 -.L_16_blocks_overflow_bAzDwrrmtwFlhxC: +.L_16_blocks_overflow_149: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -21480,7 +21480,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_bAzDwrrmtwFlhxC: +.L_16_blocks_ok_149: @@ -21610,7 +21610,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xhFuzvedBfnrcsm + jl .L_small_initial_partial_block_150 @@ -21675,8 +21675,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xhFuzvedBfnrcsm -.L_small_initial_partial_block_xhFuzvedBfnrcsm: + jmp .L_small_initial_compute_done_150 +.L_small_initial_partial_block_150: @@ -21744,27 +21744,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xhFuzvedBfnrcsm: +.L_small_initial_compute_done_150: orq %r8,%r8 - je .L_after_reduction_xhFuzvedBfnrcsm + je .L_after_reduction_150 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xhFuzvedBfnrcsm: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_15_jpCbfqoGugGzzuz: +.L_after_reduction_150: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_15_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_aAutogzlhjupvBp + jae .L_16_blocks_overflow_151 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_aAutogzlhjupvBp + jmp .L_16_blocks_ok_151 -.L_16_blocks_overflow_aAutogzlhjupvBp: +.L_16_blocks_overflow_151: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -21775,7 +21775,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_aAutogzlhjupvBp: +.L_16_blocks_ok_151: @@ -21905,7 +21905,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nhezthvFnxtuGCA + jl .L_small_initial_partial_block_152 @@ -21971,8 +21971,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nhezthvFnxtuGCA -.L_small_initial_partial_block_nhezthvFnxtuGCA: + jmp .L_small_initial_compute_done_152 +.L_small_initial_partial_block_152: @@ -22040,27 +22040,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nhezthvFnxtuGCA: +.L_small_initial_compute_done_152: orq %r8,%r8 - je .L_after_reduction_nhezthvFnxtuGCA + je .L_after_reduction_152 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nhezthvFnxtuGCA: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_16_jpCbfqoGugGzzuz: +.L_after_reduction_152: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_16_122: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_DDrqwAsdakzdjjn + jae .L_16_blocks_overflow_153 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_DDrqwAsdakzdjjn + jmp .L_16_blocks_ok_153 -.L_16_blocks_overflow_DDrqwAsdakzdjjn: +.L_16_blocks_overflow_153: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -22071,7 +22071,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_DDrqwAsdakzdjjn: +.L_16_blocks_ok_153: @@ -22198,7 +22198,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_gmngxddcExbEDrt: +.L_small_initial_partial_block_154: @@ -22267,11 +22267,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gmngxddcExbEDrt: +.L_small_initial_compute_done_154: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gmngxddcExbEDrt: - jmp .L_last_blocks_done_jpCbfqoGugGzzuz -.L_last_num_blocks_is_0_jpCbfqoGugGzzuz: +.L_after_reduction_154: + jmp .L_last_blocks_done_122 +.L_last_num_blocks_is_0_122: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -22333,65 +22333,65 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_jpCbfqoGugGzzuz: +.L_last_blocks_done_122: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_lzCeFkjwAopsEcs + jmp .L_ghash_done_10 -.L_message_below_equal_16_blocks_lzCeFkjwAopsEcs: +.L_message_below_equal_16_blocks_10: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_wijDzFksCtEctgd - jl .L_small_initial_num_blocks_is_7_1_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_8_155 + jl .L_small_initial_num_blocks_is_7_1_155 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_wijDzFksCtEctgd - jl .L_small_initial_num_blocks_is_11_9_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_12_155 + jl .L_small_initial_num_blocks_is_11_9_155 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_16_155 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_15_155 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_wijDzFksCtEctgd - jmp .L_small_initial_num_blocks_is_13_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_14_155 + jmp .L_small_initial_num_blocks_is_13_155 -.L_small_initial_num_blocks_is_11_9_wijDzFksCtEctgd: +.L_small_initial_num_blocks_is_11_9_155: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_11_155 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_wijDzFksCtEctgd - jmp .L_small_initial_num_blocks_is_9_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_10_155 + jmp .L_small_initial_num_blocks_is_9_155 -.L_small_initial_num_blocks_is_7_1_wijDzFksCtEctgd: +.L_small_initial_num_blocks_is_7_1_155: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_wijDzFksCtEctgd - jl .L_small_initial_num_blocks_is_3_1_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_4_155 + jl .L_small_initial_num_blocks_is_3_1_155 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_7_155 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_wijDzFksCtEctgd - jmp .L_small_initial_num_blocks_is_5_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_6_155 + jmp .L_small_initial_num_blocks_is_5_155 -.L_small_initial_num_blocks_is_3_1_wijDzFksCtEctgd: +.L_small_initial_num_blocks_is_3_1_155: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_3_155 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_wijDzFksCtEctgd + je .L_small_initial_num_blocks_is_2_155 -.L_small_initial_num_blocks_is_1_wijDzFksCtEctgd: +.L_small_initial_num_blocks_is_1_155: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -22432,7 +22432,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cdAvgtnbxxzgBEE + jl .L_small_initial_partial_block_156 @@ -22474,8 +22474,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cdAvgtnbxxzgBEE -.L_small_initial_partial_block_cdAvgtnbxxzgBEE: + jmp .L_small_initial_compute_done_156 +.L_small_initial_partial_block_156: @@ -22499,11 +22499,11 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_cdAvgtnbxxzgBEE -.L_small_initial_compute_done_cdAvgtnbxxzgBEE: -.L_after_reduction_cdAvgtnbxxzgBEE: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_2_wijDzFksCtEctgd: + jmp .L_after_reduction_156 +.L_small_initial_compute_done_156: +.L_after_reduction_156: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_2_155: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -22546,7 +22546,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gpBucAtECbpwEFx + jl .L_small_initial_partial_block_157 @@ -22588,8 +22588,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gpBucAtECbpwEFx -.L_small_initial_partial_block_gpBucAtECbpwEFx: + jmp .L_small_initial_compute_done_157 +.L_small_initial_partial_block_157: @@ -22634,14 +22634,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gpBucAtECbpwEFx: +.L_small_initial_compute_done_157: orq %r8,%r8 - je .L_after_reduction_gpBucAtECbpwEFx + je .L_after_reduction_157 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_gpBucAtECbpwEFx: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_3_wijDzFksCtEctgd: +.L_after_reduction_157: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_3_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -22684,7 +22684,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rpnDyjbCAFatcpG + jl .L_small_initial_partial_block_158 @@ -22727,8 +22727,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rpnDyjbCAFatcpG -.L_small_initial_partial_block_rpnDyjbCAFatcpG: + jmp .L_small_initial_compute_done_158 +.L_small_initial_partial_block_158: @@ -22773,14 +22773,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rpnDyjbCAFatcpG: +.L_small_initial_compute_done_158: orq %r8,%r8 - je .L_after_reduction_rpnDyjbCAFatcpG + je .L_after_reduction_158 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_rpnDyjbCAFatcpG: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_4_wijDzFksCtEctgd: +.L_after_reduction_158: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_4_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -22823,7 +22823,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_smeDbbjDqesjGDp + jl .L_small_initial_partial_block_159 @@ -22865,8 +22865,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_smeDbbjDqesjGDp -.L_small_initial_partial_block_smeDbbjDqesjGDp: + jmp .L_small_initial_compute_done_159 +.L_small_initial_partial_block_159: @@ -22912,14 +22912,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_smeDbbjDqesjGDp: +.L_small_initial_compute_done_159: orq %r8,%r8 - je .L_after_reduction_smeDbbjDqesjGDp + je .L_after_reduction_159 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_smeDbbjDqesjGDp: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_5_wijDzFksCtEctgd: +.L_after_reduction_159: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_5_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -22980,7 +22980,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fDFhCFygAdApCbm + jl .L_small_initial_partial_block_160 @@ -23032,8 +23032,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fDFhCFygAdApCbm -.L_small_initial_partial_block_fDFhCFygAdApCbm: + jmp .L_small_initial_compute_done_160 +.L_small_initial_partial_block_160: @@ -23078,14 +23078,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fDFhCFygAdApCbm: +.L_small_initial_compute_done_160: orq %r8,%r8 - je .L_after_reduction_fDFhCFygAdApCbm + je .L_after_reduction_160 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_fDFhCFygAdApCbm: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_6_wijDzFksCtEctgd: +.L_after_reduction_160: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_6_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -23146,7 +23146,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ovicpoebcCGGnqr + jl .L_small_initial_partial_block_161 @@ -23198,8 +23198,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ovicpoebcCGGnqr -.L_small_initial_partial_block_ovicpoebcCGGnqr: + jmp .L_small_initial_compute_done_161 +.L_small_initial_partial_block_161: @@ -23254,14 +23254,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ovicpoebcCGGnqr: +.L_small_initial_compute_done_161: orq %r8,%r8 - je .L_after_reduction_ovicpoebcCGGnqr + je .L_after_reduction_161 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ovicpoebcCGGnqr: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_7_wijDzFksCtEctgd: +.L_after_reduction_161: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_7_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -23322,7 +23322,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zgDAchseBvzBuyv + jl .L_small_initial_partial_block_162 @@ -23375,8 +23375,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zgDAchseBvzBuyv -.L_small_initial_partial_block_zgDAchseBvzBuyv: + jmp .L_small_initial_compute_done_162 +.L_small_initial_partial_block_162: @@ -23431,14 +23431,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zgDAchseBvzBuyv: +.L_small_initial_compute_done_162: orq %r8,%r8 - je .L_after_reduction_zgDAchseBvzBuyv + je .L_after_reduction_162 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_zgDAchseBvzBuyv: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_8_wijDzFksCtEctgd: +.L_after_reduction_162: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_8_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -23499,7 +23499,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_noDemAfhlyicirA + jl .L_small_initial_partial_block_163 @@ -23550,8 +23550,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_noDemAfhlyicirA -.L_small_initial_partial_block_noDemAfhlyicirA: + jmp .L_small_initial_compute_done_163 +.L_small_initial_partial_block_163: @@ -23607,14 +23607,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_noDemAfhlyicirA: +.L_small_initial_compute_done_163: orq %r8,%r8 - je .L_after_reduction_noDemAfhlyicirA + je .L_after_reduction_163 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_noDemAfhlyicirA: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_9_wijDzFksCtEctgd: +.L_after_reduction_163: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_9_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -23692,7 +23692,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_leACxlrecbFaxxu + jl .L_small_initial_partial_block_164 @@ -23753,8 +23753,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_leACxlrecbFaxxu -.L_small_initial_partial_block_leACxlrecbFaxxu: + jmp .L_small_initial_compute_done_164 +.L_small_initial_partial_block_164: @@ -23808,14 +23808,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_leACxlrecbFaxxu: +.L_small_initial_compute_done_164: orq %r8,%r8 - je .L_after_reduction_leACxlrecbFaxxu + je .L_after_reduction_164 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_leACxlrecbFaxxu: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_10_wijDzFksCtEctgd: +.L_after_reduction_164: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_10_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -23893,7 +23893,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ohycDCEtckixpxv + jl .L_small_initial_partial_block_165 @@ -23954,8 +23954,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ohycDCEtckixpxv -.L_small_initial_partial_block_ohycDCEtckixpxv: + jmp .L_small_initial_compute_done_165 +.L_small_initial_partial_block_165: @@ -24019,14 +24019,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ohycDCEtckixpxv: +.L_small_initial_compute_done_165: orq %r8,%r8 - je .L_after_reduction_ohycDCEtckixpxv + je .L_after_reduction_165 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ohycDCEtckixpxv: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_11_wijDzFksCtEctgd: +.L_after_reduction_165: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_11_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -24104,7 +24104,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EduChntaFbpelre + jl .L_small_initial_partial_block_166 @@ -24166,8 +24166,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EduChntaFbpelre -.L_small_initial_partial_block_EduChntaFbpelre: + jmp .L_small_initial_compute_done_166 +.L_small_initial_partial_block_166: @@ -24231,14 +24231,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EduChntaFbpelre: +.L_small_initial_compute_done_166: orq %r8,%r8 - je .L_after_reduction_EduChntaFbpelre + je .L_after_reduction_166 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_EduChntaFbpelre: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_12_wijDzFksCtEctgd: +.L_after_reduction_166: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_12_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -24316,7 +24316,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BDfdqCilqdtdboq + jl .L_small_initial_partial_block_167 @@ -24372,8 +24372,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BDfdqCilqdtdboq -.L_small_initial_partial_block_BDfdqCilqdtdboq: + jmp .L_small_initial_compute_done_167 +.L_small_initial_partial_block_167: @@ -24438,14 +24438,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BDfdqCilqdtdboq: +.L_small_initial_compute_done_167: orq %r8,%r8 - je .L_after_reduction_BDfdqCilqdtdboq + je .L_after_reduction_167 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_BDfdqCilqdtdboq: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_13_wijDzFksCtEctgd: +.L_after_reduction_167: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_13_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -24540,7 +24540,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zirgafvblskfhfG + jl .L_small_initial_partial_block_168 @@ -24606,8 +24606,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zirgafvblskfhfG -.L_small_initial_partial_block_zirgafvblskfhfG: + jmp .L_small_initial_compute_done_168 +.L_small_initial_partial_block_168: @@ -24666,14 +24666,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zirgafvblskfhfG: +.L_small_initial_compute_done_168: orq %r8,%r8 - je .L_after_reduction_zirgafvblskfhfG + je .L_after_reduction_168 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_zirgafvblskfhfG: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_14_wijDzFksCtEctgd: +.L_after_reduction_168: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_14_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -24768,7 +24768,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hqBladADqvzsmDo + jl .L_small_initial_partial_block_169 @@ -24834,8 +24834,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hqBladADqvzsmDo -.L_small_initial_partial_block_hqBladADqvzsmDo: + jmp .L_small_initial_compute_done_169 +.L_small_initial_partial_block_169: @@ -24904,14 +24904,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hqBladADqvzsmDo: +.L_small_initial_compute_done_169: orq %r8,%r8 - je .L_after_reduction_hqBladADqvzsmDo + je .L_after_reduction_169 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_hqBladADqvzsmDo: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_15_wijDzFksCtEctgd: +.L_after_reduction_169: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_15_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -25006,7 +25006,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ichkEFdjicxsfBw + jl .L_small_initial_partial_block_170 @@ -25073,8 +25073,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ichkEFdjicxsfBw -.L_small_initial_partial_block_ichkEFdjicxsfBw: + jmp .L_small_initial_compute_done_170 +.L_small_initial_partial_block_170: @@ -25143,14 +25143,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ichkEFdjicxsfBw: +.L_small_initial_compute_done_170: orq %r8,%r8 - je .L_after_reduction_ichkEFdjicxsfBw + je .L_after_reduction_170 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ichkEFdjicxsfBw: - jmp .L_small_initial_blocks_encrypted_wijDzFksCtEctgd -.L_small_initial_num_blocks_is_16_wijDzFksCtEctgd: +.L_after_reduction_170: + jmp .L_small_initial_blocks_encrypted_155 +.L_small_initial_num_blocks_is_16_155: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -25242,7 +25242,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_uqzDyuiwEoxxmyu: +.L_small_initial_partial_block_171: @@ -25312,25 +25312,25 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uqzDyuiwEoxxmyu: +.L_small_initial_compute_done_171: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_uqzDyuiwEoxxmyu: -.L_small_initial_blocks_encrypted_wijDzFksCtEctgd: -.L_ghash_done_lzCeFkjwAopsEcs: +.L_after_reduction_171: +.L_small_initial_blocks_encrypted_155: +.L_ghash_done_10: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_lzCeFkjwAopsEcs: +.L_enc_dec_done_10: jmp .Lexit_gcm_encrypt .align 32 .Laes_gcm_encrypt_192_avx512: orq %r8,%r8 - je .L_enc_dec_done_uygCycEksAzDBkF + je .L_enc_dec_done_172 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_avtoynvscnevCsc + je .L_partial_block_done_173 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -25352,9 +25352,9 @@ ossl_aes_gcm_encrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_avtoynvscnevCsc + jge .L_no_extra_mask_173 subq %r13,%r12 -.L_no_extra_mask_avtoynvscnevCsc: +.L_no_extra_mask_173: @@ -25364,7 +25364,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 vpxorq %xmm3,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_avtoynvscnevCsc + jl .L_partial_incomplete_173 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -25399,13 +25399,13 @@ ossl_aes_gcm_encrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_avtoynvscnevCsc + jmp .L_enc_dec_done_173 -.L_partial_incomplete_avtoynvscnevCsc: +.L_partial_incomplete_173: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_avtoynvscnevCsc: +.L_enc_dec_done_173: leaq byte_len_to_mask_table(%rip),%r12 @@ -25416,12 +25416,12 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_avtoynvscnevCsc: +.L_partial_block_done_173: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_uygCycEksAzDBkF + je .L_enc_dec_done_172 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_uygCycEksAzDBkF + jbe .L_message_below_equal_16_blocks_172 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -25441,13 +25441,13 @@ ossl_aes_gcm_encrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_nijtGaqavDwFnCo + jae .L_next_16_overflow_174 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_nijtGaqavDwFnCo -.L_next_16_overflow_nijtGaqavDwFnCo: + jmp .L_next_16_ok_174 +.L_next_16_overflow_174: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -25458,7 +25458,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_nijtGaqavDwFnCo: +.L_next_16_ok_174: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -25556,7 +25556,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_Cjoxtbrddqyewif + jnz .L_skip_hkeys_precomputation_175 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -25572,20 +25572,20 @@ ossl_aes_gcm_encrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_Cjoxtbrddqyewif: +.L_skip_hkeys_precomputation_175: cmpq $512,%r8 - jb .L_message_below_32_blocks_uygCycEksAzDBkF + jb .L_message_below_32_blocks_172 cmpb $240,%r15b - jae .L_next_16_overflow_chaAbahDBuexCqc + jae .L_next_16_overflow_176 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_chaAbahDBuexCqc -.L_next_16_overflow_chaAbahDBuexCqc: + jmp .L_next_16_ok_176 +.L_next_16_overflow_176: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -25596,7 +25596,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_chaAbahDBuexCqc: +.L_next_16_ok_176: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -25694,7 +25694,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_mgEtihCaEBdbsrp + jnz .L_skip_hkeys_precomputation_177 vmovdqu64 640(%rsp),%zmm3 @@ -25942,22 +25942,22 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_mgEtihCaEBdbsrp: +.L_skip_hkeys_precomputation_177: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_uygCycEksAzDBkF -.L_encrypt_big_nblocks_uygCycEksAzDBkF: + jb .L_no_more_big_nblocks_172 +.L_encrypt_big_nblocks_172: cmpb $240,%r15b - jae .L_16_blocks_overflow_hazEzhzaufyAlsq + jae .L_16_blocks_overflow_178 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_hazEzhzaufyAlsq -.L_16_blocks_overflow_hazEzhzaufyAlsq: + jmp .L_16_blocks_ok_178 +.L_16_blocks_overflow_178: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -25968,7 +25968,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_hazEzhzaufyAlsq: +.L_16_blocks_ok_178: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -26144,13 +26144,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_eDmdehdnndfjdxl + jae .L_16_blocks_overflow_179 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_eDmdehdnndfjdxl -.L_16_blocks_overflow_eDmdehdnndfjdxl: + jmp .L_16_blocks_ok_179 +.L_16_blocks_overflow_179: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -26161,7 +26161,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_eDmdehdnndfjdxl: +.L_16_blocks_ok_179: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -26337,13 +26337,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_ctordfBgipjklwx + jae .L_16_blocks_overflow_180 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ctordfBgipjklwx -.L_16_blocks_overflow_ctordfBgipjklwx: + jmp .L_16_blocks_ok_180 +.L_16_blocks_overflow_180: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -26354,7 +26354,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ctordfBgipjklwx: +.L_16_blocks_ok_180: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -26560,16 +26560,16 @@ ossl_aes_gcm_encrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_uygCycEksAzDBkF + jae .L_encrypt_big_nblocks_172 -.L_no_more_big_nblocks_uygCycEksAzDBkF: +.L_no_more_big_nblocks_172: cmpq $512,%r8 - jae .L_encrypt_32_blocks_uygCycEksAzDBkF + jae .L_encrypt_32_blocks_172 cmpq $256,%r8 - jae .L_encrypt_16_blocks_uygCycEksAzDBkF -.L_encrypt_0_blocks_ghash_32_uygCycEksAzDBkF: + jae .L_encrypt_16_blocks_172 +.L_encrypt_0_blocks_ghash_32_172: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -26612,61 +26612,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_zapDrCqlGeDwujs + je .L_last_num_blocks_is_0_181 cmpl $8,%r10d - je .L_last_num_blocks_is_8_zapDrCqlGeDwujs - jb .L_last_num_blocks_is_7_1_zapDrCqlGeDwujs + je .L_last_num_blocks_is_8_181 + jb .L_last_num_blocks_is_7_1_181 cmpl $12,%r10d - je .L_last_num_blocks_is_12_zapDrCqlGeDwujs - jb .L_last_num_blocks_is_11_9_zapDrCqlGeDwujs + je .L_last_num_blocks_is_12_181 + jb .L_last_num_blocks_is_11_9_181 cmpl $15,%r10d - je .L_last_num_blocks_is_15_zapDrCqlGeDwujs - ja .L_last_num_blocks_is_16_zapDrCqlGeDwujs + je .L_last_num_blocks_is_15_181 + ja .L_last_num_blocks_is_16_181 cmpl $14,%r10d - je .L_last_num_blocks_is_14_zapDrCqlGeDwujs - jmp .L_last_num_blocks_is_13_zapDrCqlGeDwujs + je .L_last_num_blocks_is_14_181 + jmp .L_last_num_blocks_is_13_181 -.L_last_num_blocks_is_11_9_zapDrCqlGeDwujs: +.L_last_num_blocks_is_11_9_181: cmpl $10,%r10d - je .L_last_num_blocks_is_10_zapDrCqlGeDwujs - ja .L_last_num_blocks_is_11_zapDrCqlGeDwujs - jmp .L_last_num_blocks_is_9_zapDrCqlGeDwujs + je .L_last_num_blocks_is_10_181 + ja .L_last_num_blocks_is_11_181 + jmp .L_last_num_blocks_is_9_181 -.L_last_num_blocks_is_7_1_zapDrCqlGeDwujs: +.L_last_num_blocks_is_7_1_181: cmpl $4,%r10d - je .L_last_num_blocks_is_4_zapDrCqlGeDwujs - jb .L_last_num_blocks_is_3_1_zapDrCqlGeDwujs + je .L_last_num_blocks_is_4_181 + jb .L_last_num_blocks_is_3_1_181 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_zapDrCqlGeDwujs - je .L_last_num_blocks_is_6_zapDrCqlGeDwujs - jmp .L_last_num_blocks_is_5_zapDrCqlGeDwujs + ja .L_last_num_blocks_is_7_181 + je .L_last_num_blocks_is_6_181 + jmp .L_last_num_blocks_is_5_181 -.L_last_num_blocks_is_3_1_zapDrCqlGeDwujs: +.L_last_num_blocks_is_3_1_181: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_zapDrCqlGeDwujs - je .L_last_num_blocks_is_2_zapDrCqlGeDwujs -.L_last_num_blocks_is_1_zapDrCqlGeDwujs: + ja .L_last_num_blocks_is_3_181 + je .L_last_num_blocks_is_2_181 +.L_last_num_blocks_is_1_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_eBrrlGxwGudslqk + jae .L_16_blocks_overflow_182 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_eBrrlGxwGudslqk + jmp .L_16_blocks_ok_182 -.L_16_blocks_overflow_eBrrlGxwGudslqk: +.L_16_blocks_overflow_182: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_eBrrlGxwGudslqk: +.L_16_blocks_ok_182: @@ -26754,7 +26754,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DCiisayfwhlqFEj + jl .L_small_initial_partial_block_183 @@ -26798,8 +26798,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DCiisayfwhlqFEj -.L_small_initial_partial_block_DCiisayfwhlqFEj: + jmp .L_small_initial_compute_done_183 +.L_small_initial_partial_block_183: @@ -26851,24 +26851,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_DCiisayfwhlqFEj -.L_small_initial_compute_done_DCiisayfwhlqFEj: -.L_after_reduction_DCiisayfwhlqFEj: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_2_zapDrCqlGeDwujs: + jmp .L_after_reduction_183 +.L_small_initial_compute_done_183: +.L_after_reduction_183: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_2_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_boElArsFmFpsBzn + jae .L_16_blocks_overflow_184 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_boElArsFmFpsBzn + jmp .L_16_blocks_ok_184 -.L_16_blocks_overflow_boElArsFmFpsBzn: +.L_16_blocks_overflow_184: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_boElArsFmFpsBzn: +.L_16_blocks_ok_184: @@ -26957,7 +26957,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uGmdcvGhfhxGEkm + jl .L_small_initial_partial_block_185 @@ -27001,8 +27001,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uGmdcvGhfhxGEkm -.L_small_initial_partial_block_uGmdcvGhfhxGEkm: + jmp .L_small_initial_compute_done_185 +.L_small_initial_partial_block_185: @@ -27049,27 +27049,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uGmdcvGhfhxGEkm: +.L_small_initial_compute_done_185: orq %r8,%r8 - je .L_after_reduction_uGmdcvGhfhxGEkm + je .L_after_reduction_185 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_uGmdcvGhfhxGEkm: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_3_zapDrCqlGeDwujs: +.L_after_reduction_185: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_3_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_hnuhjslkpcyykfc + jae .L_16_blocks_overflow_186 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_hnuhjslkpcyykfc + jmp .L_16_blocks_ok_186 -.L_16_blocks_overflow_hnuhjslkpcyykfc: +.L_16_blocks_overflow_186: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_hnuhjslkpcyykfc: +.L_16_blocks_ok_186: @@ -27158,7 +27158,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_bkarAbmevFBdxib + jl .L_small_initial_partial_block_187 @@ -27203,8 +27203,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_bkarAbmevFBdxib -.L_small_initial_partial_block_bkarAbmevFBdxib: + jmp .L_small_initial_compute_done_187 +.L_small_initial_partial_block_187: @@ -27251,27 +27251,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_bkarAbmevFBdxib: +.L_small_initial_compute_done_187: orq %r8,%r8 - je .L_after_reduction_bkarAbmevFBdxib + je .L_after_reduction_187 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_bkarAbmevFBdxib: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_4_zapDrCqlGeDwujs: +.L_after_reduction_187: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_4_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_mGciyElrdaGuDAy + jae .L_16_blocks_overflow_188 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_mGciyElrdaGuDAy + jmp .L_16_blocks_ok_188 -.L_16_blocks_overflow_mGciyElrdaGuDAy: +.L_16_blocks_overflow_188: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_mGciyElrdaGuDAy: +.L_16_blocks_ok_188: @@ -27360,7 +27360,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_iFqEcEkAyEEDlky + jl .L_small_initial_partial_block_189 @@ -27405,8 +27405,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_iFqEcEkAyEEDlky -.L_small_initial_partial_block_iFqEcEkAyEEDlky: + jmp .L_small_initial_compute_done_189 +.L_small_initial_partial_block_189: @@ -27454,32 +27454,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_iFqEcEkAyEEDlky: +.L_small_initial_compute_done_189: orq %r8,%r8 - je .L_after_reduction_iFqEcEkAyEEDlky + je .L_after_reduction_189 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_iFqEcEkAyEEDlky: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_5_zapDrCqlGeDwujs: +.L_after_reduction_189: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_5_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_BqwffalsGwtvFym + jae .L_16_blocks_overflow_190 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_BqwffalsGwtvFym + jmp .L_16_blocks_ok_190 -.L_16_blocks_overflow_BqwffalsGwtvFym: +.L_16_blocks_overflow_190: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_BqwffalsGwtvFym: +.L_16_blocks_ok_190: @@ -27585,7 +27585,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mGAiBbyaGqFtnxt + jl .L_small_initial_partial_block_191 @@ -27636,8 +27636,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mGAiBbyaGqFtnxt -.L_small_initial_partial_block_mGAiBbyaGqFtnxt: + jmp .L_small_initial_compute_done_191 +.L_small_initial_partial_block_191: @@ -27685,32 +27685,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mGAiBbyaGqFtnxt: +.L_small_initial_compute_done_191: orq %r8,%r8 - je .L_after_reduction_mGAiBbyaGqFtnxt + je .L_after_reduction_191 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mGAiBbyaGqFtnxt: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_6_zapDrCqlGeDwujs: +.L_after_reduction_191: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_6_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_cvsBibEvwApizyD + jae .L_16_blocks_overflow_192 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_cvsBibEvwApizyD + jmp .L_16_blocks_ok_192 -.L_16_blocks_overflow_cvsBibEvwApizyD: +.L_16_blocks_overflow_192: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_cvsBibEvwApizyD: +.L_16_blocks_ok_192: @@ -27816,7 +27816,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rvrobaurAdpqekq + jl .L_small_initial_partial_block_193 @@ -27867,8 +27867,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rvrobaurAdpqekq -.L_small_initial_partial_block_rvrobaurAdpqekq: + jmp .L_small_initial_compute_done_193 +.L_small_initial_partial_block_193: @@ -27922,32 +27922,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rvrobaurAdpqekq: +.L_small_initial_compute_done_193: orq %r8,%r8 - je .L_after_reduction_rvrobaurAdpqekq + je .L_after_reduction_193 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rvrobaurAdpqekq: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_7_zapDrCqlGeDwujs: +.L_after_reduction_193: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_7_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_lrEmanbkqciEzug + jae .L_16_blocks_overflow_194 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_lrEmanbkqciEzug + jmp .L_16_blocks_ok_194 -.L_16_blocks_overflow_lrEmanbkqciEzug: +.L_16_blocks_overflow_194: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_lrEmanbkqciEzug: +.L_16_blocks_ok_194: @@ -28053,7 +28053,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gptpjGuFylcEspm + jl .L_small_initial_partial_block_195 @@ -28105,8 +28105,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gptpjGuFylcEspm -.L_small_initial_partial_block_gptpjGuFylcEspm: + jmp .L_small_initial_compute_done_195 +.L_small_initial_partial_block_195: @@ -28160,32 +28160,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gptpjGuFylcEspm: +.L_small_initial_compute_done_195: orq %r8,%r8 - je .L_after_reduction_gptpjGuFylcEspm + je .L_after_reduction_195 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gptpjGuFylcEspm: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_8_zapDrCqlGeDwujs: +.L_after_reduction_195: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_8_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_rektidpvoecghBr + jae .L_16_blocks_overflow_196 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_rektidpvoecghBr + jmp .L_16_blocks_ok_196 -.L_16_blocks_overflow_rektidpvoecghBr: +.L_16_blocks_overflow_196: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_rektidpvoecghBr: +.L_16_blocks_ok_196: @@ -28291,7 +28291,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FzyfwyDAgetDkFC + jl .L_small_initial_partial_block_197 @@ -28345,8 +28345,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FzyfwyDAgetDkFC -.L_small_initial_partial_block_FzyfwyDAgetDkFC: + jmp .L_small_initial_compute_done_197 +.L_small_initial_partial_block_197: @@ -28401,26 +28401,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FzyfwyDAgetDkFC: +.L_small_initial_compute_done_197: orq %r8,%r8 - je .L_after_reduction_FzyfwyDAgetDkFC + je .L_after_reduction_197 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FzyfwyDAgetDkFC: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_9_zapDrCqlGeDwujs: +.L_after_reduction_197: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_9_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_wzknnrzsBjBGjhq + jae .L_16_blocks_overflow_198 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_wzknnrzsBjBGjhq + jmp .L_16_blocks_ok_198 -.L_16_blocks_overflow_wzknnrzsBjBGjhq: +.L_16_blocks_overflow_198: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -28429,7 +28429,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_wzknnrzsBjBGjhq: +.L_16_blocks_ok_198: @@ -28552,7 +28552,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uuCxnyuAymhshmh + jl .L_small_initial_partial_block_199 @@ -28612,8 +28612,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uuCxnyuAymhshmh -.L_small_initial_partial_block_uuCxnyuAymhshmh: + jmp .L_small_initial_compute_done_199 +.L_small_initial_partial_block_199: @@ -28670,26 +28670,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uuCxnyuAymhshmh: +.L_small_initial_compute_done_199: orq %r8,%r8 - je .L_after_reduction_uuCxnyuAymhshmh + je .L_after_reduction_199 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_uuCxnyuAymhshmh: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_10_zapDrCqlGeDwujs: +.L_after_reduction_199: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_10_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_dkFvwwnBGvqtCdq + jae .L_16_blocks_overflow_200 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_dkFvwwnBGvqtCdq + jmp .L_16_blocks_ok_200 -.L_16_blocks_overflow_dkFvwwnBGvqtCdq: +.L_16_blocks_overflow_200: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -28698,7 +28698,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_dkFvwwnBGvqtCdq: +.L_16_blocks_ok_200: @@ -28821,7 +28821,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EpfusirBooivaaw + jl .L_small_initial_partial_block_201 @@ -28881,8 +28881,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EpfusirBooivaaw -.L_small_initial_partial_block_EpfusirBooivaaw: + jmp .L_small_initial_compute_done_201 +.L_small_initial_partial_block_201: @@ -28945,26 +28945,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EpfusirBooivaaw: +.L_small_initial_compute_done_201: orq %r8,%r8 - je .L_after_reduction_EpfusirBooivaaw + je .L_after_reduction_201 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EpfusirBooivaaw: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_11_zapDrCqlGeDwujs: +.L_after_reduction_201: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_11_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_jdaCqtmbomEFrxq + jae .L_16_blocks_overflow_202 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_jdaCqtmbomEFrxq + jmp .L_16_blocks_ok_202 -.L_16_blocks_overflow_jdaCqtmbomEFrxq: +.L_16_blocks_overflow_202: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -28973,7 +28973,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_jdaCqtmbomEFrxq: +.L_16_blocks_ok_202: @@ -29096,7 +29096,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BEfqcturFnzEtBh + jl .L_small_initial_partial_block_203 @@ -29157,8 +29157,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BEfqcturFnzEtBh -.L_small_initial_partial_block_BEfqcturFnzEtBh: + jmp .L_small_initial_compute_done_203 +.L_small_initial_partial_block_203: @@ -29221,26 +29221,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BEfqcturFnzEtBh: +.L_small_initial_compute_done_203: orq %r8,%r8 - je .L_after_reduction_BEfqcturFnzEtBh + je .L_after_reduction_203 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BEfqcturFnzEtBh: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_12_zapDrCqlGeDwujs: +.L_after_reduction_203: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_12_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_FybgoadpoAGCust + jae .L_16_blocks_overflow_204 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_FybgoadpoAGCust + jmp .L_16_blocks_ok_204 -.L_16_blocks_overflow_FybgoadpoAGCust: +.L_16_blocks_overflow_204: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -29249,7 +29249,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_FybgoadpoAGCust: +.L_16_blocks_ok_204: @@ -29372,7 +29372,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aadsmDBEsjtpjsm + jl .L_small_initial_partial_block_205 @@ -29431,8 +29431,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aadsmDBEsjtpjsm -.L_small_initial_partial_block_aadsmDBEsjtpjsm: + jmp .L_small_initial_compute_done_205 +.L_small_initial_partial_block_205: @@ -29496,27 +29496,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aadsmDBEsjtpjsm: +.L_small_initial_compute_done_205: orq %r8,%r8 - je .L_after_reduction_aadsmDBEsjtpjsm + je .L_after_reduction_205 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aadsmDBEsjtpjsm: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_13_zapDrCqlGeDwujs: +.L_after_reduction_205: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_13_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_gniltrjqvioaxpx + jae .L_16_blocks_overflow_206 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_gniltrjqvioaxpx + jmp .L_16_blocks_ok_206 -.L_16_blocks_overflow_gniltrjqvioaxpx: +.L_16_blocks_overflow_206: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -29527,7 +29527,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_gniltrjqvioaxpx: +.L_16_blocks_ok_206: @@ -29667,7 +29667,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EgmArahsjsEtkiw + jl .L_small_initial_partial_block_207 @@ -29732,8 +29732,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EgmArahsjsEtkiw -.L_small_initial_partial_block_EgmArahsjsEtkiw: + jmp .L_small_initial_compute_done_207 +.L_small_initial_partial_block_207: @@ -29795,27 +29795,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EgmArahsjsEtkiw: +.L_small_initial_compute_done_207: orq %r8,%r8 - je .L_after_reduction_EgmArahsjsEtkiw + je .L_after_reduction_207 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EgmArahsjsEtkiw: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_14_zapDrCqlGeDwujs: +.L_after_reduction_207: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_14_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_fdlbmjovyDaEsFg + jae .L_16_blocks_overflow_208 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_fdlbmjovyDaEsFg + jmp .L_16_blocks_ok_208 -.L_16_blocks_overflow_fdlbmjovyDaEsFg: +.L_16_blocks_overflow_208: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -29826,7 +29826,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_fdlbmjovyDaEsFg: +.L_16_blocks_ok_208: @@ -29966,7 +29966,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ddCzAGelmohdblc + jl .L_small_initial_partial_block_209 @@ -30031,8 +30031,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ddCzAGelmohdblc -.L_small_initial_partial_block_ddCzAGelmohdblc: + jmp .L_small_initial_compute_done_209 +.L_small_initial_partial_block_209: @@ -30100,27 +30100,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ddCzAGelmohdblc: +.L_small_initial_compute_done_209: orq %r8,%r8 - je .L_after_reduction_ddCzAGelmohdblc + je .L_after_reduction_209 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ddCzAGelmohdblc: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_15_zapDrCqlGeDwujs: +.L_after_reduction_209: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_15_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_drkvxzqfmdkgyai + jae .L_16_blocks_overflow_210 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_drkvxzqfmdkgyai + jmp .L_16_blocks_ok_210 -.L_16_blocks_overflow_drkvxzqfmdkgyai: +.L_16_blocks_overflow_210: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -30131,7 +30131,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_drkvxzqfmdkgyai: +.L_16_blocks_ok_210: @@ -30271,7 +30271,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aacuyFuwxngnrox + jl .L_small_initial_partial_block_211 @@ -30337,8 +30337,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aacuyFuwxngnrox -.L_small_initial_partial_block_aacuyFuwxngnrox: + jmp .L_small_initial_compute_done_211 +.L_small_initial_partial_block_211: @@ -30406,27 +30406,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aacuyFuwxngnrox: +.L_small_initial_compute_done_211: orq %r8,%r8 - je .L_after_reduction_aacuyFuwxngnrox + je .L_after_reduction_211 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aacuyFuwxngnrox: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_16_zapDrCqlGeDwujs: +.L_after_reduction_211: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_16_181: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_dtsxckkEomAhtpr + jae .L_16_blocks_overflow_212 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_dtsxckkEomAhtpr + jmp .L_16_blocks_ok_212 -.L_16_blocks_overflow_dtsxckkEomAhtpr: +.L_16_blocks_overflow_212: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -30437,7 +30437,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_dtsxckkEomAhtpr: +.L_16_blocks_ok_212: @@ -30574,7 +30574,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_lrdDmswCfvdpABc: +.L_small_initial_partial_block_213: @@ -30643,11 +30643,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lrdDmswCfvdpABc: +.L_small_initial_compute_done_213: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lrdDmswCfvdpABc: - jmp .L_last_blocks_done_zapDrCqlGeDwujs -.L_last_num_blocks_is_0_zapDrCqlGeDwujs: +.L_after_reduction_213: + jmp .L_last_blocks_done_181 +.L_last_num_blocks_is_0_181: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -30708,18 +30708,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_zapDrCqlGeDwujs: +.L_last_blocks_done_181: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_uygCycEksAzDBkF -.L_encrypt_32_blocks_uygCycEksAzDBkF: + jmp .L_ghash_done_172 +.L_encrypt_32_blocks_172: cmpb $240,%r15b - jae .L_16_blocks_overflow_dcqChtdkakixsDa + jae .L_16_blocks_overflow_214 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_dcqChtdkakixsDa -.L_16_blocks_overflow_dcqChtdkakixsDa: + jmp .L_16_blocks_ok_214 +.L_16_blocks_overflow_214: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -30730,7 +30730,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_dcqChtdkakixsDa: +.L_16_blocks_ok_214: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -30906,13 +30906,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_sBqizodrGodaDod + jae .L_16_blocks_overflow_215 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_sBqizodrGodaDod -.L_16_blocks_overflow_sBqizodrGodaDod: + jmp .L_16_blocks_ok_215 +.L_16_blocks_overflow_215: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -30923,7 +30923,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_sBqizodrGodaDod: +.L_16_blocks_ok_215: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -31167,61 +31167,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_cnotAvDezoxjigs + je .L_last_num_blocks_is_0_216 cmpl $8,%r10d - je .L_last_num_blocks_is_8_cnotAvDezoxjigs - jb .L_last_num_blocks_is_7_1_cnotAvDezoxjigs + je .L_last_num_blocks_is_8_216 + jb .L_last_num_blocks_is_7_1_216 cmpl $12,%r10d - je .L_last_num_blocks_is_12_cnotAvDezoxjigs - jb .L_last_num_blocks_is_11_9_cnotAvDezoxjigs + je .L_last_num_blocks_is_12_216 + jb .L_last_num_blocks_is_11_9_216 cmpl $15,%r10d - je .L_last_num_blocks_is_15_cnotAvDezoxjigs - ja .L_last_num_blocks_is_16_cnotAvDezoxjigs + je .L_last_num_blocks_is_15_216 + ja .L_last_num_blocks_is_16_216 cmpl $14,%r10d - je .L_last_num_blocks_is_14_cnotAvDezoxjigs - jmp .L_last_num_blocks_is_13_cnotAvDezoxjigs + je .L_last_num_blocks_is_14_216 + jmp .L_last_num_blocks_is_13_216 -.L_last_num_blocks_is_11_9_cnotAvDezoxjigs: +.L_last_num_blocks_is_11_9_216: cmpl $10,%r10d - je .L_last_num_blocks_is_10_cnotAvDezoxjigs - ja .L_last_num_blocks_is_11_cnotAvDezoxjigs - jmp .L_last_num_blocks_is_9_cnotAvDezoxjigs + je .L_last_num_blocks_is_10_216 + ja .L_last_num_blocks_is_11_216 + jmp .L_last_num_blocks_is_9_216 -.L_last_num_blocks_is_7_1_cnotAvDezoxjigs: +.L_last_num_blocks_is_7_1_216: cmpl $4,%r10d - je .L_last_num_blocks_is_4_cnotAvDezoxjigs - jb .L_last_num_blocks_is_3_1_cnotAvDezoxjigs + je .L_last_num_blocks_is_4_216 + jb .L_last_num_blocks_is_3_1_216 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_cnotAvDezoxjigs - je .L_last_num_blocks_is_6_cnotAvDezoxjigs - jmp .L_last_num_blocks_is_5_cnotAvDezoxjigs + ja .L_last_num_blocks_is_7_216 + je .L_last_num_blocks_is_6_216 + jmp .L_last_num_blocks_is_5_216 -.L_last_num_blocks_is_3_1_cnotAvDezoxjigs: +.L_last_num_blocks_is_3_1_216: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_cnotAvDezoxjigs - je .L_last_num_blocks_is_2_cnotAvDezoxjigs -.L_last_num_blocks_is_1_cnotAvDezoxjigs: + ja .L_last_num_blocks_is_3_216 + je .L_last_num_blocks_is_2_216 +.L_last_num_blocks_is_1_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_htskiACAAaxxhqa + jae .L_16_blocks_overflow_217 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_htskiACAAaxxhqa + jmp .L_16_blocks_ok_217 -.L_16_blocks_overflow_htskiACAAaxxhqa: +.L_16_blocks_overflow_217: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_htskiACAAaxxhqa: +.L_16_blocks_ok_217: @@ -31309,7 +31309,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_Dzckelnvflzikhy + jl .L_small_initial_partial_block_218 @@ -31353,8 +31353,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_Dzckelnvflzikhy -.L_small_initial_partial_block_Dzckelnvflzikhy: + jmp .L_small_initial_compute_done_218 +.L_small_initial_partial_block_218: @@ -31406,24 +31406,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_Dzckelnvflzikhy -.L_small_initial_compute_done_Dzckelnvflzikhy: -.L_after_reduction_Dzckelnvflzikhy: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_2_cnotAvDezoxjigs: + jmp .L_after_reduction_218 +.L_small_initial_compute_done_218: +.L_after_reduction_218: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_2_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_zFdkvgFvpvEihoA + jae .L_16_blocks_overflow_219 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_zFdkvgFvpvEihoA + jmp .L_16_blocks_ok_219 -.L_16_blocks_overflow_zFdkvgFvpvEihoA: +.L_16_blocks_overflow_219: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_zFdkvgFvpvEihoA: +.L_16_blocks_ok_219: @@ -31512,7 +31512,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GCmvgEyliqDAEvt + jl .L_small_initial_partial_block_220 @@ -31556,8 +31556,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GCmvgEyliqDAEvt -.L_small_initial_partial_block_GCmvgEyliqDAEvt: + jmp .L_small_initial_compute_done_220 +.L_small_initial_partial_block_220: @@ -31604,27 +31604,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GCmvgEyliqDAEvt: +.L_small_initial_compute_done_220: orq %r8,%r8 - je .L_after_reduction_GCmvgEyliqDAEvt + je .L_after_reduction_220 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GCmvgEyliqDAEvt: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_3_cnotAvDezoxjigs: +.L_after_reduction_220: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_3_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_deDxkArrzuGpDzc + jae .L_16_blocks_overflow_221 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_deDxkArrzuGpDzc + jmp .L_16_blocks_ok_221 -.L_16_blocks_overflow_deDxkArrzuGpDzc: +.L_16_blocks_overflow_221: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_deDxkArrzuGpDzc: +.L_16_blocks_ok_221: @@ -31713,7 +31713,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kkimaDgwybfuryc + jl .L_small_initial_partial_block_222 @@ -31758,8 +31758,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kkimaDgwybfuryc -.L_small_initial_partial_block_kkimaDgwybfuryc: + jmp .L_small_initial_compute_done_222 +.L_small_initial_partial_block_222: @@ -31806,27 +31806,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kkimaDgwybfuryc: +.L_small_initial_compute_done_222: orq %r8,%r8 - je .L_after_reduction_kkimaDgwybfuryc + je .L_after_reduction_222 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kkimaDgwybfuryc: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_4_cnotAvDezoxjigs: +.L_after_reduction_222: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_4_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_wrqFbibnjnyxecw + jae .L_16_blocks_overflow_223 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_wrqFbibnjnyxecw + jmp .L_16_blocks_ok_223 -.L_16_blocks_overflow_wrqFbibnjnyxecw: +.L_16_blocks_overflow_223: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_wrqFbibnjnyxecw: +.L_16_blocks_ok_223: @@ -31915,7 +31915,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kEBfmknsibjblCs + jl .L_small_initial_partial_block_224 @@ -31960,8 +31960,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kEBfmknsibjblCs -.L_small_initial_partial_block_kEBfmknsibjblCs: + jmp .L_small_initial_compute_done_224 +.L_small_initial_partial_block_224: @@ -32009,32 +32009,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kEBfmknsibjblCs: +.L_small_initial_compute_done_224: orq %r8,%r8 - je .L_after_reduction_kEBfmknsibjblCs + je .L_after_reduction_224 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kEBfmknsibjblCs: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_5_cnotAvDezoxjigs: +.L_after_reduction_224: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_5_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_AwaEBfkistBhcBa + jae .L_16_blocks_overflow_225 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_AwaEBfkistBhcBa + jmp .L_16_blocks_ok_225 -.L_16_blocks_overflow_AwaEBfkistBhcBa: +.L_16_blocks_overflow_225: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_AwaEBfkistBhcBa: +.L_16_blocks_ok_225: @@ -32140,7 +32140,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hzrpribEeFjbrFs + jl .L_small_initial_partial_block_226 @@ -32191,8 +32191,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hzrpribEeFjbrFs -.L_small_initial_partial_block_hzrpribEeFjbrFs: + jmp .L_small_initial_compute_done_226 +.L_small_initial_partial_block_226: @@ -32240,32 +32240,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hzrpribEeFjbrFs: +.L_small_initial_compute_done_226: orq %r8,%r8 - je .L_after_reduction_hzrpribEeFjbrFs + je .L_after_reduction_226 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hzrpribEeFjbrFs: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_6_cnotAvDezoxjigs: +.L_after_reduction_226: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_6_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_GGxhnmBfyllGysD + jae .L_16_blocks_overflow_227 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_GGxhnmBfyllGysD + jmp .L_16_blocks_ok_227 -.L_16_blocks_overflow_GGxhnmBfyllGysD: +.L_16_blocks_overflow_227: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_GGxhnmBfyllGysD: +.L_16_blocks_ok_227: @@ -32371,7 +32371,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fpxwBxDypsmmjmC + jl .L_small_initial_partial_block_228 @@ -32422,8 +32422,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fpxwBxDypsmmjmC -.L_small_initial_partial_block_fpxwBxDypsmmjmC: + jmp .L_small_initial_compute_done_228 +.L_small_initial_partial_block_228: @@ -32477,32 +32477,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fpxwBxDypsmmjmC: +.L_small_initial_compute_done_228: orq %r8,%r8 - je .L_after_reduction_fpxwBxDypsmmjmC + je .L_after_reduction_228 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fpxwBxDypsmmjmC: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_7_cnotAvDezoxjigs: +.L_after_reduction_228: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_7_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_kmFvpfCqnmAhxnz + jae .L_16_blocks_overflow_229 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_kmFvpfCqnmAhxnz + jmp .L_16_blocks_ok_229 -.L_16_blocks_overflow_kmFvpfCqnmAhxnz: +.L_16_blocks_overflow_229: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_kmFvpfCqnmAhxnz: +.L_16_blocks_ok_229: @@ -32608,7 +32608,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mldfmCfiBCvsdyB + jl .L_small_initial_partial_block_230 @@ -32660,8 +32660,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mldfmCfiBCvsdyB -.L_small_initial_partial_block_mldfmCfiBCvsdyB: + jmp .L_small_initial_compute_done_230 +.L_small_initial_partial_block_230: @@ -32715,32 +32715,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mldfmCfiBCvsdyB: +.L_small_initial_compute_done_230: orq %r8,%r8 - je .L_after_reduction_mldfmCfiBCvsdyB + je .L_after_reduction_230 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mldfmCfiBCvsdyB: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_8_cnotAvDezoxjigs: +.L_after_reduction_230: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_8_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_puCqbsmGcjwovvm + jae .L_16_blocks_overflow_231 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_puCqbsmGcjwovvm + jmp .L_16_blocks_ok_231 -.L_16_blocks_overflow_puCqbsmGcjwovvm: +.L_16_blocks_overflow_231: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_puCqbsmGcjwovvm: +.L_16_blocks_ok_231: @@ -32846,7 +32846,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BuBhgbzeCxtvztl + jl .L_small_initial_partial_block_232 @@ -32900,8 +32900,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BuBhgbzeCxtvztl -.L_small_initial_partial_block_BuBhgbzeCxtvztl: + jmp .L_small_initial_compute_done_232 +.L_small_initial_partial_block_232: @@ -32956,26 +32956,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BuBhgbzeCxtvztl: +.L_small_initial_compute_done_232: orq %r8,%r8 - je .L_after_reduction_BuBhgbzeCxtvztl + je .L_after_reduction_232 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BuBhgbzeCxtvztl: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_9_cnotAvDezoxjigs: +.L_after_reduction_232: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_9_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_oBeszEykxAgipDm + jae .L_16_blocks_overflow_233 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_oBeszEykxAgipDm + jmp .L_16_blocks_ok_233 -.L_16_blocks_overflow_oBeszEykxAgipDm: +.L_16_blocks_overflow_233: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -32984,7 +32984,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_oBeszEykxAgipDm: +.L_16_blocks_ok_233: @@ -33107,7 +33107,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vCdsdzmsuvrgnEf + jl .L_small_initial_partial_block_234 @@ -33167,8 +33167,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vCdsdzmsuvrgnEf -.L_small_initial_partial_block_vCdsdzmsuvrgnEf: + jmp .L_small_initial_compute_done_234 +.L_small_initial_partial_block_234: @@ -33225,26 +33225,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vCdsdzmsuvrgnEf: +.L_small_initial_compute_done_234: orq %r8,%r8 - je .L_after_reduction_vCdsdzmsuvrgnEf + je .L_after_reduction_234 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vCdsdzmsuvrgnEf: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_10_cnotAvDezoxjigs: +.L_after_reduction_234: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_10_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_tghhfCfEptjzGeA + jae .L_16_blocks_overflow_235 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_tghhfCfEptjzGeA + jmp .L_16_blocks_ok_235 -.L_16_blocks_overflow_tghhfCfEptjzGeA: +.L_16_blocks_overflow_235: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -33253,7 +33253,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_tghhfCfEptjzGeA: +.L_16_blocks_ok_235: @@ -33376,7 +33376,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ulBByciknkGeDhm + jl .L_small_initial_partial_block_236 @@ -33436,8 +33436,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ulBByciknkGeDhm -.L_small_initial_partial_block_ulBByciknkGeDhm: + jmp .L_small_initial_compute_done_236 +.L_small_initial_partial_block_236: @@ -33500,26 +33500,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ulBByciknkGeDhm: +.L_small_initial_compute_done_236: orq %r8,%r8 - je .L_after_reduction_ulBByciknkGeDhm + je .L_after_reduction_236 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ulBByciknkGeDhm: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_11_cnotAvDezoxjigs: +.L_after_reduction_236: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_11_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_CnsBfalgAmfeqjo + jae .L_16_blocks_overflow_237 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_CnsBfalgAmfeqjo + jmp .L_16_blocks_ok_237 -.L_16_blocks_overflow_CnsBfalgAmfeqjo: +.L_16_blocks_overflow_237: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -33528,7 +33528,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_CnsBfalgAmfeqjo: +.L_16_blocks_ok_237: @@ -33651,7 +33651,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yFteDdorEApqaAw + jl .L_small_initial_partial_block_238 @@ -33712,8 +33712,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yFteDdorEApqaAw -.L_small_initial_partial_block_yFteDdorEApqaAw: + jmp .L_small_initial_compute_done_238 +.L_small_initial_partial_block_238: @@ -33776,26 +33776,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yFteDdorEApqaAw: +.L_small_initial_compute_done_238: orq %r8,%r8 - je .L_after_reduction_yFteDdorEApqaAw + je .L_after_reduction_238 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yFteDdorEApqaAw: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_12_cnotAvDezoxjigs: +.L_after_reduction_238: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_12_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_hmhBbgAoADzsvri + jae .L_16_blocks_overflow_239 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_hmhBbgAoADzsvri + jmp .L_16_blocks_ok_239 -.L_16_blocks_overflow_hmhBbgAoADzsvri: +.L_16_blocks_overflow_239: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -33804,7 +33804,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_hmhBbgAoADzsvri: +.L_16_blocks_ok_239: @@ -33927,7 +33927,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_bvmyoADytaCgboB + jl .L_small_initial_partial_block_240 @@ -33986,8 +33986,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_bvmyoADytaCgboB -.L_small_initial_partial_block_bvmyoADytaCgboB: + jmp .L_small_initial_compute_done_240 +.L_small_initial_partial_block_240: @@ -34051,27 +34051,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_bvmyoADytaCgboB: +.L_small_initial_compute_done_240: orq %r8,%r8 - je .L_after_reduction_bvmyoADytaCgboB + je .L_after_reduction_240 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_bvmyoADytaCgboB: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_13_cnotAvDezoxjigs: +.L_after_reduction_240: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_13_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_xsAbcofzmblltnA + jae .L_16_blocks_overflow_241 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_xsAbcofzmblltnA + jmp .L_16_blocks_ok_241 -.L_16_blocks_overflow_xsAbcofzmblltnA: +.L_16_blocks_overflow_241: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -34082,7 +34082,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_xsAbcofzmblltnA: +.L_16_blocks_ok_241: @@ -34222,7 +34222,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_etulFCuzhxwzsBG + jl .L_small_initial_partial_block_242 @@ -34287,8 +34287,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_etulFCuzhxwzsBG -.L_small_initial_partial_block_etulFCuzhxwzsBG: + jmp .L_small_initial_compute_done_242 +.L_small_initial_partial_block_242: @@ -34350,27 +34350,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_etulFCuzhxwzsBG: +.L_small_initial_compute_done_242: orq %r8,%r8 - je .L_after_reduction_etulFCuzhxwzsBG + je .L_after_reduction_242 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_etulFCuzhxwzsBG: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_14_cnotAvDezoxjigs: +.L_after_reduction_242: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_14_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_jyqbptEasFbiiwh + jae .L_16_blocks_overflow_243 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_jyqbptEasFbiiwh + jmp .L_16_blocks_ok_243 -.L_16_blocks_overflow_jyqbptEasFbiiwh: +.L_16_blocks_overflow_243: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -34381,7 +34381,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_jyqbptEasFbiiwh: +.L_16_blocks_ok_243: @@ -34521,7 +34521,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jrwceinDDafuscx + jl .L_small_initial_partial_block_244 @@ -34586,8 +34586,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jrwceinDDafuscx -.L_small_initial_partial_block_jrwceinDDafuscx: + jmp .L_small_initial_compute_done_244 +.L_small_initial_partial_block_244: @@ -34655,27 +34655,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jrwceinDDafuscx: +.L_small_initial_compute_done_244: orq %r8,%r8 - je .L_after_reduction_jrwceinDDafuscx + je .L_after_reduction_244 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jrwceinDDafuscx: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_15_cnotAvDezoxjigs: +.L_after_reduction_244: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_15_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_yvBkssgbquurjyn + jae .L_16_blocks_overflow_245 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_yvBkssgbquurjyn + jmp .L_16_blocks_ok_245 -.L_16_blocks_overflow_yvBkssgbquurjyn: +.L_16_blocks_overflow_245: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -34686,7 +34686,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_yvBkssgbquurjyn: +.L_16_blocks_ok_245: @@ -34826,7 +34826,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kmGwlvnpgjwwziv + jl .L_small_initial_partial_block_246 @@ -34892,8 +34892,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kmGwlvnpgjwwziv -.L_small_initial_partial_block_kmGwlvnpgjwwziv: + jmp .L_small_initial_compute_done_246 +.L_small_initial_partial_block_246: @@ -34961,27 +34961,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kmGwlvnpgjwwziv: +.L_small_initial_compute_done_246: orq %r8,%r8 - je .L_after_reduction_kmGwlvnpgjwwziv + je .L_after_reduction_246 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kmGwlvnpgjwwziv: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_16_cnotAvDezoxjigs: +.L_after_reduction_246: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_16_216: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_zxBrcnFjqfdsdBn + jae .L_16_blocks_overflow_247 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_zxBrcnFjqfdsdBn + jmp .L_16_blocks_ok_247 -.L_16_blocks_overflow_zxBrcnFjqfdsdBn: +.L_16_blocks_overflow_247: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -34992,7 +34992,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_zxBrcnFjqfdsdBn: +.L_16_blocks_ok_247: @@ -35129,7 +35129,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_kjgGssgycykwBfF: +.L_small_initial_partial_block_248: @@ -35198,11 +35198,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kjgGssgycykwBfF: +.L_small_initial_compute_done_248: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kjgGssgycykwBfF: - jmp .L_last_blocks_done_cnotAvDezoxjigs -.L_last_num_blocks_is_0_cnotAvDezoxjigs: +.L_after_reduction_248: + jmp .L_last_blocks_done_216 +.L_last_num_blocks_is_0_216: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -35264,18 +35264,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_cnotAvDezoxjigs: +.L_last_blocks_done_216: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_uygCycEksAzDBkF -.L_encrypt_16_blocks_uygCycEksAzDBkF: + jmp .L_ghash_done_172 +.L_encrypt_16_blocks_172: cmpb $240,%r15b - jae .L_16_blocks_overflow_DDfzEzluofbymmu + jae .L_16_blocks_overflow_249 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_DDfzEzluofbymmu -.L_16_blocks_overflow_DDfzEzluofbymmu: + jmp .L_16_blocks_ok_249 +.L_16_blocks_overflow_249: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -35286,7 +35286,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_DDfzEzluofbymmu: +.L_16_blocks_ok_249: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -35499,61 +35499,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_bgrAtBjonnloqvd + je .L_last_num_blocks_is_0_250 cmpl $8,%r10d - je .L_last_num_blocks_is_8_bgrAtBjonnloqvd - jb .L_last_num_blocks_is_7_1_bgrAtBjonnloqvd + je .L_last_num_blocks_is_8_250 + jb .L_last_num_blocks_is_7_1_250 cmpl $12,%r10d - je .L_last_num_blocks_is_12_bgrAtBjonnloqvd - jb .L_last_num_blocks_is_11_9_bgrAtBjonnloqvd + je .L_last_num_blocks_is_12_250 + jb .L_last_num_blocks_is_11_9_250 cmpl $15,%r10d - je .L_last_num_blocks_is_15_bgrAtBjonnloqvd - ja .L_last_num_blocks_is_16_bgrAtBjonnloqvd + je .L_last_num_blocks_is_15_250 + ja .L_last_num_blocks_is_16_250 cmpl $14,%r10d - je .L_last_num_blocks_is_14_bgrAtBjonnloqvd - jmp .L_last_num_blocks_is_13_bgrAtBjonnloqvd + je .L_last_num_blocks_is_14_250 + jmp .L_last_num_blocks_is_13_250 -.L_last_num_blocks_is_11_9_bgrAtBjonnloqvd: +.L_last_num_blocks_is_11_9_250: cmpl $10,%r10d - je .L_last_num_blocks_is_10_bgrAtBjonnloqvd - ja .L_last_num_blocks_is_11_bgrAtBjonnloqvd - jmp .L_last_num_blocks_is_9_bgrAtBjonnloqvd + je .L_last_num_blocks_is_10_250 + ja .L_last_num_blocks_is_11_250 + jmp .L_last_num_blocks_is_9_250 -.L_last_num_blocks_is_7_1_bgrAtBjonnloqvd: +.L_last_num_blocks_is_7_1_250: cmpl $4,%r10d - je .L_last_num_blocks_is_4_bgrAtBjonnloqvd - jb .L_last_num_blocks_is_3_1_bgrAtBjonnloqvd + je .L_last_num_blocks_is_4_250 + jb .L_last_num_blocks_is_3_1_250 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_bgrAtBjonnloqvd - je .L_last_num_blocks_is_6_bgrAtBjonnloqvd - jmp .L_last_num_blocks_is_5_bgrAtBjonnloqvd + ja .L_last_num_blocks_is_7_250 + je .L_last_num_blocks_is_6_250 + jmp .L_last_num_blocks_is_5_250 -.L_last_num_blocks_is_3_1_bgrAtBjonnloqvd: +.L_last_num_blocks_is_3_1_250: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_bgrAtBjonnloqvd - je .L_last_num_blocks_is_2_bgrAtBjonnloqvd -.L_last_num_blocks_is_1_bgrAtBjonnloqvd: + ja .L_last_num_blocks_is_3_250 + je .L_last_num_blocks_is_2_250 +.L_last_num_blocks_is_1_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_BpnEqnwfaujGcxw + jae .L_16_blocks_overflow_251 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_BpnEqnwfaujGcxw + jmp .L_16_blocks_ok_251 -.L_16_blocks_overflow_BpnEqnwfaujGcxw: +.L_16_blocks_overflow_251: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_BpnEqnwfaujGcxw: +.L_16_blocks_ok_251: @@ -35664,7 +35664,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_onApBxrihCpDyuv + jl .L_small_initial_partial_block_252 @@ -35706,8 +35706,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_onApBxrihCpDyuv -.L_small_initial_partial_block_onApBxrihCpDyuv: + jmp .L_small_initial_compute_done_252 +.L_small_initial_partial_block_252: @@ -35731,24 +35731,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_onApBxrihCpDyuv -.L_small_initial_compute_done_onApBxrihCpDyuv: -.L_after_reduction_onApBxrihCpDyuv: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_2_bgrAtBjonnloqvd: + jmp .L_after_reduction_252 +.L_small_initial_compute_done_252: +.L_after_reduction_252: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_2_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_yGzfqvCnxdtlkml + jae .L_16_blocks_overflow_253 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_yGzfqvCnxdtlkml + jmp .L_16_blocks_ok_253 -.L_16_blocks_overflow_yGzfqvCnxdtlkml: +.L_16_blocks_overflow_253: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_yGzfqvCnxdtlkml: +.L_16_blocks_ok_253: @@ -35860,7 +35860,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_laDvpatEibgvrif + jl .L_small_initial_partial_block_254 @@ -35902,8 +35902,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_laDvpatEibgvrif -.L_small_initial_partial_block_laDvpatEibgvrif: + jmp .L_small_initial_compute_done_254 +.L_small_initial_partial_block_254: @@ -35948,27 +35948,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_laDvpatEibgvrif: +.L_small_initial_compute_done_254: orq %r8,%r8 - je .L_after_reduction_laDvpatEibgvrif + je .L_after_reduction_254 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_laDvpatEibgvrif: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_3_bgrAtBjonnloqvd: +.L_after_reduction_254: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_3_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_zEmomnpkxghGxvv + jae .L_16_blocks_overflow_255 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_zEmomnpkxghGxvv + jmp .L_16_blocks_ok_255 -.L_16_blocks_overflow_zEmomnpkxghGxvv: +.L_16_blocks_overflow_255: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_zEmomnpkxghGxvv: +.L_16_blocks_ok_255: @@ -36080,7 +36080,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CxvnsjnikvCumBt + jl .L_small_initial_partial_block_256 @@ -36123,8 +36123,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CxvnsjnikvCumBt -.L_small_initial_partial_block_CxvnsjnikvCumBt: + jmp .L_small_initial_compute_done_256 +.L_small_initial_partial_block_256: @@ -36169,27 +36169,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CxvnsjnikvCumBt: +.L_small_initial_compute_done_256: orq %r8,%r8 - je .L_after_reduction_CxvnsjnikvCumBt + je .L_after_reduction_256 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CxvnsjnikvCumBt: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_4_bgrAtBjonnloqvd: +.L_after_reduction_256: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_4_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_lnwsAFekGAytyvl + jae .L_16_blocks_overflow_257 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_lnwsAFekGAytyvl + jmp .L_16_blocks_ok_257 -.L_16_blocks_overflow_lnwsAFekGAytyvl: +.L_16_blocks_overflow_257: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_lnwsAFekGAytyvl: +.L_16_blocks_ok_257: @@ -36301,7 +36301,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DuEowGxxDqfDchE + jl .L_small_initial_partial_block_258 @@ -36343,8 +36343,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DuEowGxxDqfDchE -.L_small_initial_partial_block_DuEowGxxDqfDchE: + jmp .L_small_initial_compute_done_258 +.L_small_initial_partial_block_258: @@ -36390,32 +36390,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DuEowGxxDqfDchE: +.L_small_initial_compute_done_258: orq %r8,%r8 - je .L_after_reduction_DuEowGxxDqfDchE + je .L_after_reduction_258 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DuEowGxxDqfDchE: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_5_bgrAtBjonnloqvd: +.L_after_reduction_258: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_5_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_mwEtErqidqvqpGF + jae .L_16_blocks_overflow_259 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_mwEtErqidqvqpGF + jmp .L_16_blocks_ok_259 -.L_16_blocks_overflow_mwEtErqidqvqpGF: +.L_16_blocks_overflow_259: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_mwEtErqidqvqpGF: +.L_16_blocks_ok_259: @@ -36544,7 +36544,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dBmpdFzlyhizqih + jl .L_small_initial_partial_block_260 @@ -36596,8 +36596,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dBmpdFzlyhizqih -.L_small_initial_partial_block_dBmpdFzlyhizqih: + jmp .L_small_initial_compute_done_260 +.L_small_initial_partial_block_260: @@ -36642,32 +36642,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dBmpdFzlyhizqih: +.L_small_initial_compute_done_260: orq %r8,%r8 - je .L_after_reduction_dBmpdFzlyhizqih + je .L_after_reduction_260 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dBmpdFzlyhizqih: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_6_bgrAtBjonnloqvd: +.L_after_reduction_260: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_6_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_mwxgbklgswkuqsa + jae .L_16_blocks_overflow_261 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_mwxgbklgswkuqsa + jmp .L_16_blocks_ok_261 -.L_16_blocks_overflow_mwxgbklgswkuqsa: +.L_16_blocks_overflow_261: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_mwxgbklgswkuqsa: +.L_16_blocks_ok_261: @@ -36796,7 +36796,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cDmmbofklwlFmfm + jl .L_small_initial_partial_block_262 @@ -36848,8 +36848,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cDmmbofklwlFmfm -.L_small_initial_partial_block_cDmmbofklwlFmfm: + jmp .L_small_initial_compute_done_262 +.L_small_initial_partial_block_262: @@ -36904,32 +36904,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cDmmbofklwlFmfm: +.L_small_initial_compute_done_262: orq %r8,%r8 - je .L_after_reduction_cDmmbofklwlFmfm + je .L_after_reduction_262 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cDmmbofklwlFmfm: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_7_bgrAtBjonnloqvd: +.L_after_reduction_262: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_7_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_apjydFuxojAaohg + jae .L_16_blocks_overflow_263 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_apjydFuxojAaohg + jmp .L_16_blocks_ok_263 -.L_16_blocks_overflow_apjydFuxojAaohg: +.L_16_blocks_overflow_263: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_apjydFuxojAaohg: +.L_16_blocks_ok_263: @@ -37058,7 +37058,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fACAycudcpGjduv + jl .L_small_initial_partial_block_264 @@ -37111,8 +37111,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fACAycudcpGjduv -.L_small_initial_partial_block_fACAycudcpGjduv: + jmp .L_small_initial_compute_done_264 +.L_small_initial_partial_block_264: @@ -37167,32 +37167,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fACAycudcpGjduv: +.L_small_initial_compute_done_264: orq %r8,%r8 - je .L_after_reduction_fACAycudcpGjduv + je .L_after_reduction_264 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fACAycudcpGjduv: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_8_bgrAtBjonnloqvd: +.L_after_reduction_264: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_8_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_FynazCysgzxlwbF + jae .L_16_blocks_overflow_265 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_FynazCysgzxlwbF + jmp .L_16_blocks_ok_265 -.L_16_blocks_overflow_FynazCysgzxlwbF: +.L_16_blocks_overflow_265: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_FynazCysgzxlwbF: +.L_16_blocks_ok_265: @@ -37321,7 +37321,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tiGlcfEtAplCkCh + jl .L_small_initial_partial_block_266 @@ -37372,8 +37372,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tiGlcfEtAplCkCh -.L_small_initial_partial_block_tiGlcfEtAplCkCh: + jmp .L_small_initial_compute_done_266 +.L_small_initial_partial_block_266: @@ -37429,26 +37429,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tiGlcfEtAplCkCh: +.L_small_initial_compute_done_266: orq %r8,%r8 - je .L_after_reduction_tiGlcfEtAplCkCh + je .L_after_reduction_266 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tiGlcfEtAplCkCh: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_9_bgrAtBjonnloqvd: +.L_after_reduction_266: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_9_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_DgfacAafzlforja + jae .L_16_blocks_overflow_267 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_DgfacAafzlforja + jmp .L_16_blocks_ok_267 -.L_16_blocks_overflow_DgfacAafzlforja: +.L_16_blocks_overflow_267: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -37457,7 +37457,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_DgfacAafzlforja: +.L_16_blocks_ok_267: @@ -37603,7 +37603,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qtAGbEhizluraBo + jl .L_small_initial_partial_block_268 @@ -37664,8 +37664,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qtAGbEhizluraBo -.L_small_initial_partial_block_qtAGbEhizluraBo: + jmp .L_small_initial_compute_done_268 +.L_small_initial_partial_block_268: @@ -37719,26 +37719,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qtAGbEhizluraBo: +.L_small_initial_compute_done_268: orq %r8,%r8 - je .L_after_reduction_qtAGbEhizluraBo + je .L_after_reduction_268 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qtAGbEhizluraBo: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_10_bgrAtBjonnloqvd: +.L_after_reduction_268: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_10_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_BxvrAsDbwlfAxeo + jae .L_16_blocks_overflow_269 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_BxvrAsDbwlfAxeo + jmp .L_16_blocks_ok_269 -.L_16_blocks_overflow_BxvrAsDbwlfAxeo: +.L_16_blocks_overflow_269: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -37747,7 +37747,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_BxvrAsDbwlfAxeo: +.L_16_blocks_ok_269: @@ -37893,7 +37893,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lnztwkChDbAhqFc + jl .L_small_initial_partial_block_270 @@ -37954,8 +37954,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lnztwkChDbAhqFc -.L_small_initial_partial_block_lnztwkChDbAhqFc: + jmp .L_small_initial_compute_done_270 +.L_small_initial_partial_block_270: @@ -38019,26 +38019,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lnztwkChDbAhqFc: +.L_small_initial_compute_done_270: orq %r8,%r8 - je .L_after_reduction_lnztwkChDbAhqFc + je .L_after_reduction_270 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lnztwkChDbAhqFc: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_11_bgrAtBjonnloqvd: +.L_after_reduction_270: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_11_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_utBEuotxgeclgru + jae .L_16_blocks_overflow_271 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_utBEuotxgeclgru + jmp .L_16_blocks_ok_271 -.L_16_blocks_overflow_utBEuotxgeclgru: +.L_16_blocks_overflow_271: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -38047,7 +38047,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_utBEuotxgeclgru: +.L_16_blocks_ok_271: @@ -38193,7 +38193,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oykrfAmonkmtkcy + jl .L_small_initial_partial_block_272 @@ -38255,8 +38255,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oykrfAmonkmtkcy -.L_small_initial_partial_block_oykrfAmonkmtkcy: + jmp .L_small_initial_compute_done_272 +.L_small_initial_partial_block_272: @@ -38320,26 +38320,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oykrfAmonkmtkcy: +.L_small_initial_compute_done_272: orq %r8,%r8 - je .L_after_reduction_oykrfAmonkmtkcy + je .L_after_reduction_272 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_oykrfAmonkmtkcy: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_12_bgrAtBjonnloqvd: +.L_after_reduction_272: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_12_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_vldCgkGqtkyyrmG + jae .L_16_blocks_overflow_273 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_vldCgkGqtkyyrmG + jmp .L_16_blocks_ok_273 -.L_16_blocks_overflow_vldCgkGqtkyyrmG: +.L_16_blocks_overflow_273: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -38348,7 +38348,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_vldCgkGqtkyyrmG: +.L_16_blocks_ok_273: @@ -38494,7 +38494,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rxlrcdudinyeczo + jl .L_small_initial_partial_block_274 @@ -38550,8 +38550,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rxlrcdudinyeczo -.L_small_initial_partial_block_rxlrcdudinyeczo: + jmp .L_small_initial_compute_done_274 +.L_small_initial_partial_block_274: @@ -38616,27 +38616,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rxlrcdudinyeczo: +.L_small_initial_compute_done_274: orq %r8,%r8 - je .L_after_reduction_rxlrcdudinyeczo + je .L_after_reduction_274 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rxlrcdudinyeczo: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_13_bgrAtBjonnloqvd: +.L_after_reduction_274: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_13_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_nhvdBGpupuEjtFD + jae .L_16_blocks_overflow_275 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_nhvdBGpupuEjtFD + jmp .L_16_blocks_ok_275 -.L_16_blocks_overflow_nhvdBGpupuEjtFD: +.L_16_blocks_overflow_275: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -38647,7 +38647,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_nhvdBGpupuEjtFD: +.L_16_blocks_ok_275: @@ -38810,7 +38810,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tugGfarEdfzmEnD + jl .L_small_initial_partial_block_276 @@ -38876,8 +38876,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tugGfarEdfzmEnD -.L_small_initial_partial_block_tugGfarEdfzmEnD: + jmp .L_small_initial_compute_done_276 +.L_small_initial_partial_block_276: @@ -38936,27 +38936,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tugGfarEdfzmEnD: +.L_small_initial_compute_done_276: orq %r8,%r8 - je .L_after_reduction_tugGfarEdfzmEnD + je .L_after_reduction_276 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tugGfarEdfzmEnD: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_14_bgrAtBjonnloqvd: +.L_after_reduction_276: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_14_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_otannEccCmkkwjx + jae .L_16_blocks_overflow_277 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_otannEccCmkkwjx + jmp .L_16_blocks_ok_277 -.L_16_blocks_overflow_otannEccCmkkwjx: +.L_16_blocks_overflow_277: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -38967,7 +38967,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_otannEccCmkkwjx: +.L_16_blocks_ok_277: @@ -39130,7 +39130,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xkcntsunsgvwybk + jl .L_small_initial_partial_block_278 @@ -39196,8 +39196,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xkcntsunsgvwybk -.L_small_initial_partial_block_xkcntsunsgvwybk: + jmp .L_small_initial_compute_done_278 +.L_small_initial_partial_block_278: @@ -39266,27 +39266,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xkcntsunsgvwybk: +.L_small_initial_compute_done_278: orq %r8,%r8 - je .L_after_reduction_xkcntsunsgvwybk + je .L_after_reduction_278 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xkcntsunsgvwybk: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_15_bgrAtBjonnloqvd: +.L_after_reduction_278: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_15_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_ktdFEnuklrCzyEA + jae .L_16_blocks_overflow_279 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ktdFEnuklrCzyEA + jmp .L_16_blocks_ok_279 -.L_16_blocks_overflow_ktdFEnuklrCzyEA: +.L_16_blocks_overflow_279: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -39297,7 +39297,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ktdFEnuklrCzyEA: +.L_16_blocks_ok_279: @@ -39460,7 +39460,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sfjEjsnidDtfBkg + jl .L_small_initial_partial_block_280 @@ -39527,8 +39527,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sfjEjsnidDtfBkg -.L_small_initial_partial_block_sfjEjsnidDtfBkg: + jmp .L_small_initial_compute_done_280 +.L_small_initial_partial_block_280: @@ -39597,27 +39597,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sfjEjsnidDtfBkg: +.L_small_initial_compute_done_280: orq %r8,%r8 - je .L_after_reduction_sfjEjsnidDtfBkg + je .L_after_reduction_280 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sfjEjsnidDtfBkg: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_16_bgrAtBjonnloqvd: +.L_after_reduction_280: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_16_250: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_poiBxjbqqxpCDtl + jae .L_16_blocks_overflow_281 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_poiBxjbqqxpCDtl + jmp .L_16_blocks_ok_281 -.L_16_blocks_overflow_poiBxjbqqxpCDtl: +.L_16_blocks_overflow_281: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -39628,7 +39628,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_poiBxjbqqxpCDtl: +.L_16_blocks_ok_281: @@ -39788,7 +39788,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_sgGijbccfGmjliF: +.L_small_initial_partial_block_282: @@ -39858,11 +39858,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sgGijbccfGmjliF: +.L_small_initial_compute_done_282: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sgGijbccfGmjliF: - jmp .L_last_blocks_done_bgrAtBjonnloqvd -.L_last_num_blocks_is_0_bgrAtBjonnloqvd: +.L_after_reduction_282: + jmp .L_last_blocks_done_250 +.L_last_num_blocks_is_0_250: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -39923,18 +39923,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_bgrAtBjonnloqvd: +.L_last_blocks_done_250: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_uygCycEksAzDBkF + jmp .L_ghash_done_172 -.L_message_below_32_blocks_uygCycEksAzDBkF: +.L_message_below_32_blocks_172: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_tfeFvpjBjvvGmzC + jnz .L_skip_hkeys_precomputation_283 vmovdqu64 640(%rsp),%zmm3 @@ -40062,7 +40062,7 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_tfeFvpjBjvvGmzC: +.L_skip_hkeys_precomputation_283: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -40070,61 +40070,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_aChEemefGGhwnFB + je .L_last_num_blocks_is_0_284 cmpl $8,%r10d - je .L_last_num_blocks_is_8_aChEemefGGhwnFB - jb .L_last_num_blocks_is_7_1_aChEemefGGhwnFB + je .L_last_num_blocks_is_8_284 + jb .L_last_num_blocks_is_7_1_284 cmpl $12,%r10d - je .L_last_num_blocks_is_12_aChEemefGGhwnFB - jb .L_last_num_blocks_is_11_9_aChEemefGGhwnFB + je .L_last_num_blocks_is_12_284 + jb .L_last_num_blocks_is_11_9_284 cmpl $15,%r10d - je .L_last_num_blocks_is_15_aChEemefGGhwnFB - ja .L_last_num_blocks_is_16_aChEemefGGhwnFB + je .L_last_num_blocks_is_15_284 + ja .L_last_num_blocks_is_16_284 cmpl $14,%r10d - je .L_last_num_blocks_is_14_aChEemefGGhwnFB - jmp .L_last_num_blocks_is_13_aChEemefGGhwnFB + je .L_last_num_blocks_is_14_284 + jmp .L_last_num_blocks_is_13_284 -.L_last_num_blocks_is_11_9_aChEemefGGhwnFB: +.L_last_num_blocks_is_11_9_284: cmpl $10,%r10d - je .L_last_num_blocks_is_10_aChEemefGGhwnFB - ja .L_last_num_blocks_is_11_aChEemefGGhwnFB - jmp .L_last_num_blocks_is_9_aChEemefGGhwnFB + je .L_last_num_blocks_is_10_284 + ja .L_last_num_blocks_is_11_284 + jmp .L_last_num_blocks_is_9_284 -.L_last_num_blocks_is_7_1_aChEemefGGhwnFB: +.L_last_num_blocks_is_7_1_284: cmpl $4,%r10d - je .L_last_num_blocks_is_4_aChEemefGGhwnFB - jb .L_last_num_blocks_is_3_1_aChEemefGGhwnFB + je .L_last_num_blocks_is_4_284 + jb .L_last_num_blocks_is_3_1_284 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_aChEemefGGhwnFB - je .L_last_num_blocks_is_6_aChEemefGGhwnFB - jmp .L_last_num_blocks_is_5_aChEemefGGhwnFB + ja .L_last_num_blocks_is_7_284 + je .L_last_num_blocks_is_6_284 + jmp .L_last_num_blocks_is_5_284 -.L_last_num_blocks_is_3_1_aChEemefGGhwnFB: +.L_last_num_blocks_is_3_1_284: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_aChEemefGGhwnFB - je .L_last_num_blocks_is_2_aChEemefGGhwnFB -.L_last_num_blocks_is_1_aChEemefGGhwnFB: + ja .L_last_num_blocks_is_3_284 + je .L_last_num_blocks_is_2_284 +.L_last_num_blocks_is_1_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_Eyxpwkuvqxnvfvr + jae .L_16_blocks_overflow_285 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_Eyxpwkuvqxnvfvr + jmp .L_16_blocks_ok_285 -.L_16_blocks_overflow_Eyxpwkuvqxnvfvr: +.L_16_blocks_overflow_285: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_Eyxpwkuvqxnvfvr: +.L_16_blocks_ok_285: @@ -40212,7 +40212,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GGgbnjurwngbFko + jl .L_small_initial_partial_block_286 @@ -40256,8 +40256,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GGgbnjurwngbFko -.L_small_initial_partial_block_GGgbnjurwngbFko: + jmp .L_small_initial_compute_done_286 +.L_small_initial_partial_block_286: @@ -40309,24 +40309,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_GGgbnjurwngbFko -.L_small_initial_compute_done_GGgbnjurwngbFko: -.L_after_reduction_GGgbnjurwngbFko: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_2_aChEemefGGhwnFB: + jmp .L_after_reduction_286 +.L_small_initial_compute_done_286: +.L_after_reduction_286: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_2_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_EusrqBquAteadEm + jae .L_16_blocks_overflow_287 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_EusrqBquAteadEm + jmp .L_16_blocks_ok_287 -.L_16_blocks_overflow_EusrqBquAteadEm: +.L_16_blocks_overflow_287: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_EusrqBquAteadEm: +.L_16_blocks_ok_287: @@ -40415,7 +40415,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hDrirwBnrvGDysx + jl .L_small_initial_partial_block_288 @@ -40459,8 +40459,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hDrirwBnrvGDysx -.L_small_initial_partial_block_hDrirwBnrvGDysx: + jmp .L_small_initial_compute_done_288 +.L_small_initial_partial_block_288: @@ -40507,27 +40507,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hDrirwBnrvGDysx: +.L_small_initial_compute_done_288: orq %r8,%r8 - je .L_after_reduction_hDrirwBnrvGDysx + je .L_after_reduction_288 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hDrirwBnrvGDysx: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_3_aChEemefGGhwnFB: +.L_after_reduction_288: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_3_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_guywFoFdfCezrwc + jae .L_16_blocks_overflow_289 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_guywFoFdfCezrwc + jmp .L_16_blocks_ok_289 -.L_16_blocks_overflow_guywFoFdfCezrwc: +.L_16_blocks_overflow_289: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_guywFoFdfCezrwc: +.L_16_blocks_ok_289: @@ -40616,7 +40616,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ffxzspaGDmEydrm + jl .L_small_initial_partial_block_290 @@ -40661,8 +40661,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ffxzspaGDmEydrm -.L_small_initial_partial_block_ffxzspaGDmEydrm: + jmp .L_small_initial_compute_done_290 +.L_small_initial_partial_block_290: @@ -40709,27 +40709,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ffxzspaGDmEydrm: +.L_small_initial_compute_done_290: orq %r8,%r8 - je .L_after_reduction_ffxzspaGDmEydrm + je .L_after_reduction_290 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ffxzspaGDmEydrm: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_4_aChEemefGGhwnFB: +.L_after_reduction_290: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_4_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_qElnjeuodkBCttv + jae .L_16_blocks_overflow_291 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_qElnjeuodkBCttv + jmp .L_16_blocks_ok_291 -.L_16_blocks_overflow_qElnjeuodkBCttv: +.L_16_blocks_overflow_291: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_qElnjeuodkBCttv: +.L_16_blocks_ok_291: @@ -40818,7 +40818,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_enzoBzByjGeevwt + jl .L_small_initial_partial_block_292 @@ -40863,8 +40863,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_enzoBzByjGeevwt -.L_small_initial_partial_block_enzoBzByjGeevwt: + jmp .L_small_initial_compute_done_292 +.L_small_initial_partial_block_292: @@ -40912,32 +40912,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_enzoBzByjGeevwt: +.L_small_initial_compute_done_292: orq %r8,%r8 - je .L_after_reduction_enzoBzByjGeevwt + je .L_after_reduction_292 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_enzoBzByjGeevwt: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_5_aChEemefGGhwnFB: +.L_after_reduction_292: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_5_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_wyjdlAqvFxphibG + jae .L_16_blocks_overflow_293 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_wyjdlAqvFxphibG + jmp .L_16_blocks_ok_293 -.L_16_blocks_overflow_wyjdlAqvFxphibG: +.L_16_blocks_overflow_293: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_wyjdlAqvFxphibG: +.L_16_blocks_ok_293: @@ -41043,7 +41043,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gumqDmoesupgjAe + jl .L_small_initial_partial_block_294 @@ -41094,8 +41094,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gumqDmoesupgjAe -.L_small_initial_partial_block_gumqDmoesupgjAe: + jmp .L_small_initial_compute_done_294 +.L_small_initial_partial_block_294: @@ -41143,32 +41143,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gumqDmoesupgjAe: +.L_small_initial_compute_done_294: orq %r8,%r8 - je .L_after_reduction_gumqDmoesupgjAe + je .L_after_reduction_294 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gumqDmoesupgjAe: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_6_aChEemefGGhwnFB: +.L_after_reduction_294: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_6_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_zkialEdmBzdbytD + jae .L_16_blocks_overflow_295 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_zkialEdmBzdbytD + jmp .L_16_blocks_ok_295 -.L_16_blocks_overflow_zkialEdmBzdbytD: +.L_16_blocks_overflow_295: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_zkialEdmBzdbytD: +.L_16_blocks_ok_295: @@ -41274,7 +41274,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_iyirevfEdBcuEnu + jl .L_small_initial_partial_block_296 @@ -41325,8 +41325,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_iyirevfEdBcuEnu -.L_small_initial_partial_block_iyirevfEdBcuEnu: + jmp .L_small_initial_compute_done_296 +.L_small_initial_partial_block_296: @@ -41380,32 +41380,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_iyirevfEdBcuEnu: +.L_small_initial_compute_done_296: orq %r8,%r8 - je .L_after_reduction_iyirevfEdBcuEnu + je .L_after_reduction_296 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_iyirevfEdBcuEnu: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_7_aChEemefGGhwnFB: +.L_after_reduction_296: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_7_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_uogkvfpffDvcwkj + jae .L_16_blocks_overflow_297 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_uogkvfpffDvcwkj + jmp .L_16_blocks_ok_297 -.L_16_blocks_overflow_uogkvfpffDvcwkj: +.L_16_blocks_overflow_297: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_uogkvfpffDvcwkj: +.L_16_blocks_ok_297: @@ -41511,7 +41511,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cxouotnlpalgxmB + jl .L_small_initial_partial_block_298 @@ -41563,8 +41563,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cxouotnlpalgxmB -.L_small_initial_partial_block_cxouotnlpalgxmB: + jmp .L_small_initial_compute_done_298 +.L_small_initial_partial_block_298: @@ -41618,32 +41618,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cxouotnlpalgxmB: +.L_small_initial_compute_done_298: orq %r8,%r8 - je .L_after_reduction_cxouotnlpalgxmB + je .L_after_reduction_298 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cxouotnlpalgxmB: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_8_aChEemefGGhwnFB: +.L_after_reduction_298: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_8_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_DvwlGgkmfBGEyGc + jae .L_16_blocks_overflow_299 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_DvwlGgkmfBGEyGc + jmp .L_16_blocks_ok_299 -.L_16_blocks_overflow_DvwlGgkmfBGEyGc: +.L_16_blocks_overflow_299: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_DvwlGgkmfBGEyGc: +.L_16_blocks_ok_299: @@ -41749,7 +41749,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EqsEaucdawdajlq + jl .L_small_initial_partial_block_300 @@ -41803,8 +41803,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EqsEaucdawdajlq -.L_small_initial_partial_block_EqsEaucdawdajlq: + jmp .L_small_initial_compute_done_300 +.L_small_initial_partial_block_300: @@ -41859,26 +41859,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EqsEaucdawdajlq: +.L_small_initial_compute_done_300: orq %r8,%r8 - je .L_after_reduction_EqsEaucdawdajlq + je .L_after_reduction_300 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EqsEaucdawdajlq: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_9_aChEemefGGhwnFB: +.L_after_reduction_300: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_9_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_msogFyEhEitGsdf + jae .L_16_blocks_overflow_301 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_msogFyEhEitGsdf + jmp .L_16_blocks_ok_301 -.L_16_blocks_overflow_msogFyEhEitGsdf: +.L_16_blocks_overflow_301: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -41887,7 +41887,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_msogFyEhEitGsdf: +.L_16_blocks_ok_301: @@ -42010,7 +42010,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sapjknpxtioDDAG + jl .L_small_initial_partial_block_302 @@ -42070,8 +42070,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sapjknpxtioDDAG -.L_small_initial_partial_block_sapjknpxtioDDAG: + jmp .L_small_initial_compute_done_302 +.L_small_initial_partial_block_302: @@ -42128,26 +42128,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sapjknpxtioDDAG: +.L_small_initial_compute_done_302: orq %r8,%r8 - je .L_after_reduction_sapjknpxtioDDAG + je .L_after_reduction_302 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sapjknpxtioDDAG: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_10_aChEemefGGhwnFB: +.L_after_reduction_302: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_10_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_BncDDCdFiFfirCh + jae .L_16_blocks_overflow_303 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_BncDDCdFiFfirCh + jmp .L_16_blocks_ok_303 -.L_16_blocks_overflow_BncDDCdFiFfirCh: +.L_16_blocks_overflow_303: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -42156,7 +42156,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_BncDDCdFiFfirCh: +.L_16_blocks_ok_303: @@ -42279,7 +42279,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gwCjqnwjusEyDGE + jl .L_small_initial_partial_block_304 @@ -42339,8 +42339,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gwCjqnwjusEyDGE -.L_small_initial_partial_block_gwCjqnwjusEyDGE: + jmp .L_small_initial_compute_done_304 +.L_small_initial_partial_block_304: @@ -42403,26 +42403,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gwCjqnwjusEyDGE: +.L_small_initial_compute_done_304: orq %r8,%r8 - je .L_after_reduction_gwCjqnwjusEyDGE + je .L_after_reduction_304 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gwCjqnwjusEyDGE: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_11_aChEemefGGhwnFB: +.L_after_reduction_304: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_11_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_eavDybzxFpBAoxE + jae .L_16_blocks_overflow_305 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_eavDybzxFpBAoxE + jmp .L_16_blocks_ok_305 -.L_16_blocks_overflow_eavDybzxFpBAoxE: +.L_16_blocks_overflow_305: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -42431,7 +42431,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_eavDybzxFpBAoxE: +.L_16_blocks_ok_305: @@ -42554,7 +42554,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zxCknzfsjGCqDxu + jl .L_small_initial_partial_block_306 @@ -42615,8 +42615,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zxCknzfsjGCqDxu -.L_small_initial_partial_block_zxCknzfsjGCqDxu: + jmp .L_small_initial_compute_done_306 +.L_small_initial_partial_block_306: @@ -42679,26 +42679,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zxCknzfsjGCqDxu: +.L_small_initial_compute_done_306: orq %r8,%r8 - je .L_after_reduction_zxCknzfsjGCqDxu + je .L_after_reduction_306 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zxCknzfsjGCqDxu: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_12_aChEemefGGhwnFB: +.L_after_reduction_306: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_12_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_jfAFEisxEvlqocA + jae .L_16_blocks_overflow_307 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_jfAFEisxEvlqocA + jmp .L_16_blocks_ok_307 -.L_16_blocks_overflow_jfAFEisxEvlqocA: +.L_16_blocks_overflow_307: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -42707,7 +42707,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_jfAFEisxEvlqocA: +.L_16_blocks_ok_307: @@ -42830,7 +42830,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fpcnnreFjEbphei + jl .L_small_initial_partial_block_308 @@ -42889,8 +42889,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fpcnnreFjEbphei -.L_small_initial_partial_block_fpcnnreFjEbphei: + jmp .L_small_initial_compute_done_308 +.L_small_initial_partial_block_308: @@ -42954,27 +42954,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fpcnnreFjEbphei: +.L_small_initial_compute_done_308: orq %r8,%r8 - je .L_after_reduction_fpcnnreFjEbphei + je .L_after_reduction_308 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fpcnnreFjEbphei: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_13_aChEemefGGhwnFB: +.L_after_reduction_308: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_13_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_cijuDFfpzqAxzar + jae .L_16_blocks_overflow_309 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_cijuDFfpzqAxzar + jmp .L_16_blocks_ok_309 -.L_16_blocks_overflow_cijuDFfpzqAxzar: +.L_16_blocks_overflow_309: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -42985,7 +42985,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_cijuDFfpzqAxzar: +.L_16_blocks_ok_309: @@ -43125,7 +43125,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BFkDdDDwljbGtGn + jl .L_small_initial_partial_block_310 @@ -43190,8 +43190,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BFkDdDDwljbGtGn -.L_small_initial_partial_block_BFkDdDDwljbGtGn: + jmp .L_small_initial_compute_done_310 +.L_small_initial_partial_block_310: @@ -43253,27 +43253,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BFkDdDDwljbGtGn: +.L_small_initial_compute_done_310: orq %r8,%r8 - je .L_after_reduction_BFkDdDDwljbGtGn + je .L_after_reduction_310 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BFkDdDDwljbGtGn: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_14_aChEemefGGhwnFB: +.L_after_reduction_310: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_14_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_khcwhnBjmqtzmcs + jae .L_16_blocks_overflow_311 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_khcwhnBjmqtzmcs + jmp .L_16_blocks_ok_311 -.L_16_blocks_overflow_khcwhnBjmqtzmcs: +.L_16_blocks_overflow_311: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -43284,7 +43284,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_khcwhnBjmqtzmcs: +.L_16_blocks_ok_311: @@ -43424,7 +43424,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vDdylefrsvsqjBq + jl .L_small_initial_partial_block_312 @@ -43489,8 +43489,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vDdylefrsvsqjBq -.L_small_initial_partial_block_vDdylefrsvsqjBq: + jmp .L_small_initial_compute_done_312 +.L_small_initial_partial_block_312: @@ -43558,27 +43558,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vDdylefrsvsqjBq: +.L_small_initial_compute_done_312: orq %r8,%r8 - je .L_after_reduction_vDdylefrsvsqjBq + je .L_after_reduction_312 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vDdylefrsvsqjBq: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_15_aChEemefGGhwnFB: +.L_after_reduction_312: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_15_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_exBgwvimxEqfqBv + jae .L_16_blocks_overflow_313 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_exBgwvimxEqfqBv + jmp .L_16_blocks_ok_313 -.L_16_blocks_overflow_exBgwvimxEqfqBv: +.L_16_blocks_overflow_313: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -43589,7 +43589,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_exBgwvimxEqfqBv: +.L_16_blocks_ok_313: @@ -43729,7 +43729,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_msDGmhxdmqnmvpn + jl .L_small_initial_partial_block_314 @@ -43795,8 +43795,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_msDGmhxdmqnmvpn -.L_small_initial_partial_block_msDGmhxdmqnmvpn: + jmp .L_small_initial_compute_done_314 +.L_small_initial_partial_block_314: @@ -43864,27 +43864,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_msDGmhxdmqnmvpn: +.L_small_initial_compute_done_314: orq %r8,%r8 - je .L_after_reduction_msDGmhxdmqnmvpn + je .L_after_reduction_314 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_msDGmhxdmqnmvpn: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_16_aChEemefGGhwnFB: +.L_after_reduction_314: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_16_284: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_eEfAkeacFCedvzl + jae .L_16_blocks_overflow_315 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_eEfAkeacFCedvzl + jmp .L_16_blocks_ok_315 -.L_16_blocks_overflow_eEfAkeacFCedvzl: +.L_16_blocks_overflow_315: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -43895,7 +43895,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_eEfAkeacFCedvzl: +.L_16_blocks_ok_315: @@ -44032,7 +44032,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_jgeuqhctmzuFheu: +.L_small_initial_partial_block_316: @@ -44101,11 +44101,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jgeuqhctmzuFheu: +.L_small_initial_compute_done_316: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jgeuqhctmzuFheu: - jmp .L_last_blocks_done_aChEemefGGhwnFB -.L_last_num_blocks_is_0_aChEemefGGhwnFB: +.L_after_reduction_316: + jmp .L_last_blocks_done_284 +.L_last_num_blocks_is_0_284: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -44167,65 +44167,65 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_aChEemefGGhwnFB: +.L_last_blocks_done_284: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_uygCycEksAzDBkF + jmp .L_ghash_done_172 -.L_message_below_equal_16_blocks_uygCycEksAzDBkF: +.L_message_below_equal_16_blocks_172: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_EvedxoaiihwrrcE - jl .L_small_initial_num_blocks_is_7_1_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_8_317 + jl .L_small_initial_num_blocks_is_7_1_317 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_EvedxoaiihwrrcE - jl .L_small_initial_num_blocks_is_11_9_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_12_317 + jl .L_small_initial_num_blocks_is_11_9_317 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_16_317 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_15_317 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_EvedxoaiihwrrcE - jmp .L_small_initial_num_blocks_is_13_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_14_317 + jmp .L_small_initial_num_blocks_is_13_317 -.L_small_initial_num_blocks_is_11_9_EvedxoaiihwrrcE: +.L_small_initial_num_blocks_is_11_9_317: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_11_317 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_EvedxoaiihwrrcE - jmp .L_small_initial_num_blocks_is_9_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_10_317 + jmp .L_small_initial_num_blocks_is_9_317 -.L_small_initial_num_blocks_is_7_1_EvedxoaiihwrrcE: +.L_small_initial_num_blocks_is_7_1_317: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_EvedxoaiihwrrcE - jl .L_small_initial_num_blocks_is_3_1_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_4_317 + jl .L_small_initial_num_blocks_is_3_1_317 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_7_317 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_EvedxoaiihwrrcE - jmp .L_small_initial_num_blocks_is_5_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_6_317 + jmp .L_small_initial_num_blocks_is_5_317 -.L_small_initial_num_blocks_is_3_1_EvedxoaiihwrrcE: +.L_small_initial_num_blocks_is_3_1_317: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_3_317 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_EvedxoaiihwrrcE + je .L_small_initial_num_blocks_is_2_317 -.L_small_initial_num_blocks_is_1_EvedxoaiihwrrcE: +.L_small_initial_num_blocks_is_1_317: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -44270,7 +44270,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ErCGEpxtitsmnky + jl .L_small_initial_partial_block_318 @@ -44312,8 +44312,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ErCGEpxtitsmnky -.L_small_initial_partial_block_ErCGEpxtitsmnky: + jmp .L_small_initial_compute_done_318 +.L_small_initial_partial_block_318: @@ -44337,11 +44337,11 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_ErCGEpxtitsmnky -.L_small_initial_compute_done_ErCGEpxtitsmnky: -.L_after_reduction_ErCGEpxtitsmnky: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_2_EvedxoaiihwrrcE: + jmp .L_after_reduction_318 +.L_small_initial_compute_done_318: +.L_after_reduction_318: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_2_317: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -44388,7 +44388,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uifmqfFatbcjlwb + jl .L_small_initial_partial_block_319 @@ -44430,8 +44430,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uifmqfFatbcjlwb -.L_small_initial_partial_block_uifmqfFatbcjlwb: + jmp .L_small_initial_compute_done_319 +.L_small_initial_partial_block_319: @@ -44476,14 +44476,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uifmqfFatbcjlwb: +.L_small_initial_compute_done_319: orq %r8,%r8 - je .L_after_reduction_uifmqfFatbcjlwb + je .L_after_reduction_319 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_uifmqfFatbcjlwb: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_3_EvedxoaiihwrrcE: +.L_after_reduction_319: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_3_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -44530,7 +44530,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qaklvgujdsvtCdD + jl .L_small_initial_partial_block_320 @@ -44573,8 +44573,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qaklvgujdsvtCdD -.L_small_initial_partial_block_qaklvgujdsvtCdD: + jmp .L_small_initial_compute_done_320 +.L_small_initial_partial_block_320: @@ -44619,14 +44619,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qaklvgujdsvtCdD: +.L_small_initial_compute_done_320: orq %r8,%r8 - je .L_after_reduction_qaklvgujdsvtCdD + je .L_after_reduction_320 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_qaklvgujdsvtCdD: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_4_EvedxoaiihwrrcE: +.L_after_reduction_320: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_4_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -44673,7 +44673,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FFmmcojDDcGGpaw + jl .L_small_initial_partial_block_321 @@ -44715,8 +44715,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FFmmcojDDcGGpaw -.L_small_initial_partial_block_FFmmcojDDcGGpaw: + jmp .L_small_initial_compute_done_321 +.L_small_initial_partial_block_321: @@ -44762,14 +44762,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FFmmcojDDcGGpaw: +.L_small_initial_compute_done_321: orq %r8,%r8 - je .L_after_reduction_FFmmcojDDcGGpaw + je .L_after_reduction_321 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_FFmmcojDDcGGpaw: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_5_EvedxoaiihwrrcE: +.L_after_reduction_321: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_5_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -44836,7 +44836,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vwmcucnqdDfhsuE + jl .L_small_initial_partial_block_322 @@ -44888,8 +44888,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vwmcucnqdDfhsuE -.L_small_initial_partial_block_vwmcucnqdDfhsuE: + jmp .L_small_initial_compute_done_322 +.L_small_initial_partial_block_322: @@ -44934,14 +44934,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vwmcucnqdDfhsuE: +.L_small_initial_compute_done_322: orq %r8,%r8 - je .L_after_reduction_vwmcucnqdDfhsuE + je .L_after_reduction_322 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_vwmcucnqdDfhsuE: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_6_EvedxoaiihwrrcE: +.L_after_reduction_322: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_6_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -45008,7 +45008,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cpaemktswxjwjnC + jl .L_small_initial_partial_block_323 @@ -45060,8 +45060,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cpaemktswxjwjnC -.L_small_initial_partial_block_cpaemktswxjwjnC: + jmp .L_small_initial_compute_done_323 +.L_small_initial_partial_block_323: @@ -45116,14 +45116,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cpaemktswxjwjnC: +.L_small_initial_compute_done_323: orq %r8,%r8 - je .L_after_reduction_cpaemktswxjwjnC + je .L_after_reduction_323 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_cpaemktswxjwjnC: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_7_EvedxoaiihwrrcE: +.L_after_reduction_323: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_7_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -45190,7 +45190,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wkpgstjroklpiwk + jl .L_small_initial_partial_block_324 @@ -45243,8 +45243,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wkpgstjroklpiwk -.L_small_initial_partial_block_wkpgstjroklpiwk: + jmp .L_small_initial_compute_done_324 +.L_small_initial_partial_block_324: @@ -45299,14 +45299,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wkpgstjroklpiwk: +.L_small_initial_compute_done_324: orq %r8,%r8 - je .L_after_reduction_wkpgstjroklpiwk + je .L_after_reduction_324 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_wkpgstjroklpiwk: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_8_EvedxoaiihwrrcE: +.L_after_reduction_324: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_8_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -45373,7 +45373,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qpsGkqfsjEAzvvp + jl .L_small_initial_partial_block_325 @@ -45424,8 +45424,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qpsGkqfsjEAzvvp -.L_small_initial_partial_block_qpsGkqfsjEAzvvp: + jmp .L_small_initial_compute_done_325 +.L_small_initial_partial_block_325: @@ -45481,14 +45481,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qpsGkqfsjEAzvvp: +.L_small_initial_compute_done_325: orq %r8,%r8 - je .L_after_reduction_qpsGkqfsjEAzvvp + je .L_after_reduction_325 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_qpsGkqfsjEAzvvp: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_9_EvedxoaiihwrrcE: +.L_after_reduction_325: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_9_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -45574,7 +45574,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cxdfBeqyydznCEu + jl .L_small_initial_partial_block_326 @@ -45635,8 +45635,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cxdfBeqyydznCEu -.L_small_initial_partial_block_cxdfBeqyydznCEu: + jmp .L_small_initial_compute_done_326 +.L_small_initial_partial_block_326: @@ -45690,14 +45690,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cxdfBeqyydznCEu: +.L_small_initial_compute_done_326: orq %r8,%r8 - je .L_after_reduction_cxdfBeqyydznCEu + je .L_after_reduction_326 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_cxdfBeqyydznCEu: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_10_EvedxoaiihwrrcE: +.L_after_reduction_326: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_10_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -45783,7 +45783,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AsiBxkDAnGixicy + jl .L_small_initial_partial_block_327 @@ -45844,8 +45844,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AsiBxkDAnGixicy -.L_small_initial_partial_block_AsiBxkDAnGixicy: + jmp .L_small_initial_compute_done_327 +.L_small_initial_partial_block_327: @@ -45909,14 +45909,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AsiBxkDAnGixicy: +.L_small_initial_compute_done_327: orq %r8,%r8 - je .L_after_reduction_AsiBxkDAnGixicy + je .L_after_reduction_327 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_AsiBxkDAnGixicy: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_11_EvedxoaiihwrrcE: +.L_after_reduction_327: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_11_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -46002,7 +46002,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AjytgsjyDjfroqq + jl .L_small_initial_partial_block_328 @@ -46064,8 +46064,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AjytgsjyDjfroqq -.L_small_initial_partial_block_AjytgsjyDjfroqq: + jmp .L_small_initial_compute_done_328 +.L_small_initial_partial_block_328: @@ -46129,14 +46129,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AjytgsjyDjfroqq: +.L_small_initial_compute_done_328: orq %r8,%r8 - je .L_after_reduction_AjytgsjyDjfroqq + je .L_after_reduction_328 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_AjytgsjyDjfroqq: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_12_EvedxoaiihwrrcE: +.L_after_reduction_328: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_12_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -46222,7 +46222,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DrBDwbilgutamCE + jl .L_small_initial_partial_block_329 @@ -46278,8 +46278,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DrBDwbilgutamCE -.L_small_initial_partial_block_DrBDwbilgutamCE: + jmp .L_small_initial_compute_done_329 +.L_small_initial_partial_block_329: @@ -46344,14 +46344,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DrBDwbilgutamCE: +.L_small_initial_compute_done_329: orq %r8,%r8 - je .L_after_reduction_DrBDwbilgutamCE + je .L_after_reduction_329 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_DrBDwbilgutamCE: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_13_EvedxoaiihwrrcE: +.L_after_reduction_329: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_13_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -46456,7 +46456,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_znDfwthApEtiyDq + jl .L_small_initial_partial_block_330 @@ -46522,8 +46522,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_znDfwthApEtiyDq -.L_small_initial_partial_block_znDfwthApEtiyDq: + jmp .L_small_initial_compute_done_330 +.L_small_initial_partial_block_330: @@ -46582,14 +46582,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_znDfwthApEtiyDq: +.L_small_initial_compute_done_330: orq %r8,%r8 - je .L_after_reduction_znDfwthApEtiyDq + je .L_after_reduction_330 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_znDfwthApEtiyDq: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_14_EvedxoaiihwrrcE: +.L_after_reduction_330: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_14_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -46694,7 +46694,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kqeuFxFeDxGkpoA + jl .L_small_initial_partial_block_331 @@ -46760,8 +46760,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kqeuFxFeDxGkpoA -.L_small_initial_partial_block_kqeuFxFeDxGkpoA: + jmp .L_small_initial_compute_done_331 +.L_small_initial_partial_block_331: @@ -46830,14 +46830,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kqeuFxFeDxGkpoA: +.L_small_initial_compute_done_331: orq %r8,%r8 - je .L_after_reduction_kqeuFxFeDxGkpoA + je .L_after_reduction_331 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_kqeuFxFeDxGkpoA: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_15_EvedxoaiihwrrcE: +.L_after_reduction_331: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_15_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -46942,7 +46942,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zovxxEfazoFbeex + jl .L_small_initial_partial_block_332 @@ -47009,8 +47009,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zovxxEfazoFbeex -.L_small_initial_partial_block_zovxxEfazoFbeex: + jmp .L_small_initial_compute_done_332 +.L_small_initial_partial_block_332: @@ -47079,14 +47079,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zovxxEfazoFbeex: +.L_small_initial_compute_done_332: orq %r8,%r8 - je .L_after_reduction_zovxxEfazoFbeex + je .L_after_reduction_332 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_zovxxEfazoFbeex: - jmp .L_small_initial_blocks_encrypted_EvedxoaiihwrrcE -.L_small_initial_num_blocks_is_16_EvedxoaiihwrrcE: +.L_after_reduction_332: + jmp .L_small_initial_blocks_encrypted_317 +.L_small_initial_num_blocks_is_16_317: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -47188,7 +47188,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_nDtiFpkergzzhGo: +.L_small_initial_partial_block_333: @@ -47258,25 +47258,25 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nDtiFpkergzzhGo: +.L_small_initial_compute_done_333: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_nDtiFpkergzzhGo: -.L_small_initial_blocks_encrypted_EvedxoaiihwrrcE: -.L_ghash_done_uygCycEksAzDBkF: +.L_after_reduction_333: +.L_small_initial_blocks_encrypted_317: +.L_ghash_done_172: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_uygCycEksAzDBkF: +.L_enc_dec_done_172: jmp .Lexit_gcm_encrypt .align 32 .Laes_gcm_encrypt_256_avx512: orq %r8,%r8 - je .L_enc_dec_done_iygyqoBzBDrEGDx + je .L_enc_dec_done_334 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_zqvgkDsEbegulfh + je .L_partial_block_done_335 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -47298,9 +47298,9 @@ ossl_aes_gcm_encrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_zqvgkDsEbegulfh + jge .L_no_extra_mask_335 subq %r13,%r12 -.L_no_extra_mask_zqvgkDsEbegulfh: +.L_no_extra_mask_335: @@ -47310,7 +47310,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 vpxorq %xmm3,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_zqvgkDsEbegulfh + jl .L_partial_incomplete_335 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -47345,13 +47345,13 @@ ossl_aes_gcm_encrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_zqvgkDsEbegulfh + jmp .L_enc_dec_done_335 -.L_partial_incomplete_zqvgkDsEbegulfh: +.L_partial_incomplete_335: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_zqvgkDsEbegulfh: +.L_enc_dec_done_335: leaq byte_len_to_mask_table(%rip),%r12 @@ -47362,12 +47362,12 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %xmm5,%xmm3,%xmm3 movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_zqvgkDsEbegulfh: +.L_partial_block_done_335: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_iygyqoBzBDrEGDx + je .L_enc_dec_done_334 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_iygyqoBzBDrEGDx + jbe .L_message_below_equal_16_blocks_334 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -47387,13 +47387,13 @@ ossl_aes_gcm_encrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_aBaodoDalGDlscs + jae .L_next_16_overflow_336 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_aBaodoDalGDlscs -.L_next_16_overflow_aBaodoDalGDlscs: + jmp .L_next_16_ok_336 +.L_next_16_overflow_336: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -47404,7 +47404,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_aBaodoDalGDlscs: +.L_next_16_ok_336: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -47512,7 +47512,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_nACbkenyBhACdaq + jnz .L_skip_hkeys_precomputation_337 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -47528,20 +47528,20 @@ ossl_aes_gcm_encrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_nACbkenyBhACdaq: +.L_skip_hkeys_precomputation_337: cmpq $512,%r8 - jb .L_message_below_32_blocks_iygyqoBzBDrEGDx + jb .L_message_below_32_blocks_334 cmpb $240,%r15b - jae .L_next_16_overflow_CamFmzClAsuGlCt + jae .L_next_16_overflow_338 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_CamFmzClAsuGlCt -.L_next_16_overflow_CamFmzClAsuGlCt: + jmp .L_next_16_ok_338 +.L_next_16_overflow_338: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -47552,7 +47552,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_CamFmzClAsuGlCt: +.L_next_16_ok_338: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -47660,7 +47660,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_BFugbEtChDDskcj + jnz .L_skip_hkeys_precomputation_339 vmovdqu64 640(%rsp),%zmm3 @@ -47908,22 +47908,22 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_BFugbEtChDDskcj: +.L_skip_hkeys_precomputation_339: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_iygyqoBzBDrEGDx -.L_encrypt_big_nblocks_iygyqoBzBDrEGDx: + jb .L_no_more_big_nblocks_334 +.L_encrypt_big_nblocks_334: cmpb $240,%r15b - jae .L_16_blocks_overflow_mgxaEdDpcutwwFl + jae .L_16_blocks_overflow_340 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_mgxaEdDpcutwwFl -.L_16_blocks_overflow_mgxaEdDpcutwwFl: + jmp .L_16_blocks_ok_340 +.L_16_blocks_overflow_340: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -47934,7 +47934,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_mgxaEdDpcutwwFl: +.L_16_blocks_ok_340: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -48122,13 +48122,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_uvCdiswBAmoeClq + jae .L_16_blocks_overflow_341 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_uvCdiswBAmoeClq -.L_16_blocks_overflow_uvCdiswBAmoeClq: + jmp .L_16_blocks_ok_341 +.L_16_blocks_overflow_341: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -48139,7 +48139,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_uvCdiswBAmoeClq: +.L_16_blocks_ok_341: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -48327,13 +48327,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_aGacoydrhrbkAcx + jae .L_16_blocks_overflow_342 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_aGacoydrhrbkAcx -.L_16_blocks_overflow_aGacoydrhrbkAcx: + jmp .L_16_blocks_ok_342 +.L_16_blocks_overflow_342: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -48344,7 +48344,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_aGacoydrhrbkAcx: +.L_16_blocks_ok_342: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -48562,16 +48562,16 @@ ossl_aes_gcm_encrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_iygyqoBzBDrEGDx + jae .L_encrypt_big_nblocks_334 -.L_no_more_big_nblocks_iygyqoBzBDrEGDx: +.L_no_more_big_nblocks_334: cmpq $512,%r8 - jae .L_encrypt_32_blocks_iygyqoBzBDrEGDx + jae .L_encrypt_32_blocks_334 cmpq $256,%r8 - jae .L_encrypt_16_blocks_iygyqoBzBDrEGDx -.L_encrypt_0_blocks_ghash_32_iygyqoBzBDrEGDx: + jae .L_encrypt_16_blocks_334 +.L_encrypt_0_blocks_ghash_32_334: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -48614,61 +48614,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_aCrznswshDckglE + je .L_last_num_blocks_is_0_343 cmpl $8,%r10d - je .L_last_num_blocks_is_8_aCrznswshDckglE - jb .L_last_num_blocks_is_7_1_aCrznswshDckglE + je .L_last_num_blocks_is_8_343 + jb .L_last_num_blocks_is_7_1_343 cmpl $12,%r10d - je .L_last_num_blocks_is_12_aCrznswshDckglE - jb .L_last_num_blocks_is_11_9_aCrznswshDckglE + je .L_last_num_blocks_is_12_343 + jb .L_last_num_blocks_is_11_9_343 cmpl $15,%r10d - je .L_last_num_blocks_is_15_aCrznswshDckglE - ja .L_last_num_blocks_is_16_aCrznswshDckglE + je .L_last_num_blocks_is_15_343 + ja .L_last_num_blocks_is_16_343 cmpl $14,%r10d - je .L_last_num_blocks_is_14_aCrznswshDckglE - jmp .L_last_num_blocks_is_13_aCrznswshDckglE + je .L_last_num_blocks_is_14_343 + jmp .L_last_num_blocks_is_13_343 -.L_last_num_blocks_is_11_9_aCrznswshDckglE: +.L_last_num_blocks_is_11_9_343: cmpl $10,%r10d - je .L_last_num_blocks_is_10_aCrznswshDckglE - ja .L_last_num_blocks_is_11_aCrznswshDckglE - jmp .L_last_num_blocks_is_9_aCrznswshDckglE + je .L_last_num_blocks_is_10_343 + ja .L_last_num_blocks_is_11_343 + jmp .L_last_num_blocks_is_9_343 -.L_last_num_blocks_is_7_1_aCrznswshDckglE: +.L_last_num_blocks_is_7_1_343: cmpl $4,%r10d - je .L_last_num_blocks_is_4_aCrznswshDckglE - jb .L_last_num_blocks_is_3_1_aCrznswshDckglE + je .L_last_num_blocks_is_4_343 + jb .L_last_num_blocks_is_3_1_343 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_aCrznswshDckglE - je .L_last_num_blocks_is_6_aCrznswshDckglE - jmp .L_last_num_blocks_is_5_aCrznswshDckglE + ja .L_last_num_blocks_is_7_343 + je .L_last_num_blocks_is_6_343 + jmp .L_last_num_blocks_is_5_343 -.L_last_num_blocks_is_3_1_aCrznswshDckglE: +.L_last_num_blocks_is_3_1_343: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_aCrznswshDckglE - je .L_last_num_blocks_is_2_aCrznswshDckglE -.L_last_num_blocks_is_1_aCrznswshDckglE: + ja .L_last_num_blocks_is_3_343 + je .L_last_num_blocks_is_2_343 +.L_last_num_blocks_is_1_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_imDloyfGzcwFyko + jae .L_16_blocks_overflow_344 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_imDloyfGzcwFyko + jmp .L_16_blocks_ok_344 -.L_16_blocks_overflow_imDloyfGzcwFyko: +.L_16_blocks_overflow_344: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_imDloyfGzcwFyko: +.L_16_blocks_ok_344: @@ -48760,7 +48760,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_anxblbdqmokbGEi + jl .L_small_initial_partial_block_345 @@ -48804,8 +48804,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_anxblbdqmokbGEi -.L_small_initial_partial_block_anxblbdqmokbGEi: + jmp .L_small_initial_compute_done_345 +.L_small_initial_partial_block_345: @@ -48857,24 +48857,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_anxblbdqmokbGEi -.L_small_initial_compute_done_anxblbdqmokbGEi: -.L_after_reduction_anxblbdqmokbGEi: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_2_aCrznswshDckglE: + jmp .L_after_reduction_345 +.L_small_initial_compute_done_345: +.L_after_reduction_345: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_2_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_ddwAjklcmGuEyvo + jae .L_16_blocks_overflow_346 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_ddwAjklcmGuEyvo + jmp .L_16_blocks_ok_346 -.L_16_blocks_overflow_ddwAjklcmGuEyvo: +.L_16_blocks_overflow_346: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_ddwAjklcmGuEyvo: +.L_16_blocks_ok_346: @@ -48967,7 +48967,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vaAdhFryBdFjhsf + jl .L_small_initial_partial_block_347 @@ -49011,8 +49011,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vaAdhFryBdFjhsf -.L_small_initial_partial_block_vaAdhFryBdFjhsf: + jmp .L_small_initial_compute_done_347 +.L_small_initial_partial_block_347: @@ -49059,27 +49059,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vaAdhFryBdFjhsf: +.L_small_initial_compute_done_347: orq %r8,%r8 - je .L_after_reduction_vaAdhFryBdFjhsf + je .L_after_reduction_347 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vaAdhFryBdFjhsf: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_3_aCrznswshDckglE: +.L_after_reduction_347: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_3_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_yrCpcDaqqfralaq + jae .L_16_blocks_overflow_348 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_yrCpcDaqqfralaq + jmp .L_16_blocks_ok_348 -.L_16_blocks_overflow_yrCpcDaqqfralaq: +.L_16_blocks_overflow_348: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_yrCpcDaqqfralaq: +.L_16_blocks_ok_348: @@ -49172,7 +49172,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CDsECFbohACFrrl + jl .L_small_initial_partial_block_349 @@ -49217,8 +49217,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CDsECFbohACFrrl -.L_small_initial_partial_block_CDsECFbohACFrrl: + jmp .L_small_initial_compute_done_349 +.L_small_initial_partial_block_349: @@ -49265,27 +49265,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CDsECFbohACFrrl: +.L_small_initial_compute_done_349: orq %r8,%r8 - je .L_after_reduction_CDsECFbohACFrrl + je .L_after_reduction_349 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CDsECFbohACFrrl: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_4_aCrznswshDckglE: +.L_after_reduction_349: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_4_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_sgiuliygzmneAFv + jae .L_16_blocks_overflow_350 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_sgiuliygzmneAFv + jmp .L_16_blocks_ok_350 -.L_16_blocks_overflow_sgiuliygzmneAFv: +.L_16_blocks_overflow_350: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_sgiuliygzmneAFv: +.L_16_blocks_ok_350: @@ -49378,7 +49378,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_utqasCzEFDDjwFr + jl .L_small_initial_partial_block_351 @@ -49423,8 +49423,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_utqasCzEFDDjwFr -.L_small_initial_partial_block_utqasCzEFDDjwFr: + jmp .L_small_initial_compute_done_351 +.L_small_initial_partial_block_351: @@ -49472,32 +49472,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_utqasCzEFDDjwFr: +.L_small_initial_compute_done_351: orq %r8,%r8 - je .L_after_reduction_utqasCzEFDDjwFr + je .L_after_reduction_351 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_utqasCzEFDDjwFr: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_5_aCrznswshDckglE: +.L_after_reduction_351: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_5_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_iFvhEAiemvnphyy + jae .L_16_blocks_overflow_352 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_iFvhEAiemvnphyy + jmp .L_16_blocks_ok_352 -.L_16_blocks_overflow_iFvhEAiemvnphyy: +.L_16_blocks_overflow_352: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_iFvhEAiemvnphyy: +.L_16_blocks_ok_352: @@ -49609,7 +49609,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_pGjiilmmfwDafnh + jl .L_small_initial_partial_block_353 @@ -49660,8 +49660,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_pGjiilmmfwDafnh -.L_small_initial_partial_block_pGjiilmmfwDafnh: + jmp .L_small_initial_compute_done_353 +.L_small_initial_partial_block_353: @@ -49709,32 +49709,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_pGjiilmmfwDafnh: +.L_small_initial_compute_done_353: orq %r8,%r8 - je .L_after_reduction_pGjiilmmfwDafnh + je .L_after_reduction_353 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_pGjiilmmfwDafnh: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_6_aCrznswshDckglE: +.L_after_reduction_353: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_6_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_hiCAnCAyuwhiEGn + jae .L_16_blocks_overflow_354 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_hiCAnCAyuwhiEGn + jmp .L_16_blocks_ok_354 -.L_16_blocks_overflow_hiCAnCAyuwhiEGn: +.L_16_blocks_overflow_354: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_hiCAnCAyuwhiEGn: +.L_16_blocks_ok_354: @@ -49846,7 +49846,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EfCfnarADotlzkj + jl .L_small_initial_partial_block_355 @@ -49897,8 +49897,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EfCfnarADotlzkj -.L_small_initial_partial_block_EfCfnarADotlzkj: + jmp .L_small_initial_compute_done_355 +.L_small_initial_partial_block_355: @@ -49952,32 +49952,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EfCfnarADotlzkj: +.L_small_initial_compute_done_355: orq %r8,%r8 - je .L_after_reduction_EfCfnarADotlzkj + je .L_after_reduction_355 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EfCfnarADotlzkj: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_7_aCrznswshDckglE: +.L_after_reduction_355: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_7_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_jdsrggiFgcaxDsd + jae .L_16_blocks_overflow_356 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_jdsrggiFgcaxDsd + jmp .L_16_blocks_ok_356 -.L_16_blocks_overflow_jdsrggiFgcaxDsd: +.L_16_blocks_overflow_356: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_jdsrggiFgcaxDsd: +.L_16_blocks_ok_356: @@ -50089,7 +50089,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ipbqzpCeGnbjBkq + jl .L_small_initial_partial_block_357 @@ -50141,8 +50141,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ipbqzpCeGnbjBkq -.L_small_initial_partial_block_ipbqzpCeGnbjBkq: + jmp .L_small_initial_compute_done_357 +.L_small_initial_partial_block_357: @@ -50196,32 +50196,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ipbqzpCeGnbjBkq: +.L_small_initial_compute_done_357: orq %r8,%r8 - je .L_after_reduction_ipbqzpCeGnbjBkq + je .L_after_reduction_357 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ipbqzpCeGnbjBkq: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_8_aCrznswshDckglE: +.L_after_reduction_357: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_8_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_zzpwuboDaryrADA + jae .L_16_blocks_overflow_358 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_zzpwuboDaryrADA + jmp .L_16_blocks_ok_358 -.L_16_blocks_overflow_zzpwuboDaryrADA: +.L_16_blocks_overflow_358: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_zzpwuboDaryrADA: +.L_16_blocks_ok_358: @@ -50333,7 +50333,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EBtpEDqEjbcdsju + jl .L_small_initial_partial_block_359 @@ -50387,8 +50387,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EBtpEDqEjbcdsju -.L_small_initial_partial_block_EBtpEDqEjbcdsju: + jmp .L_small_initial_compute_done_359 +.L_small_initial_partial_block_359: @@ -50443,26 +50443,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EBtpEDqEjbcdsju: +.L_small_initial_compute_done_359: orq %r8,%r8 - je .L_after_reduction_EBtpEDqEjbcdsju + je .L_after_reduction_359 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EBtpEDqEjbcdsju: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_9_aCrznswshDckglE: +.L_after_reduction_359: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_9_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_uAhsdrFiklzvFua + jae .L_16_blocks_overflow_360 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_uAhsdrFiklzvFua + jmp .L_16_blocks_ok_360 -.L_16_blocks_overflow_uAhsdrFiklzvFua: +.L_16_blocks_overflow_360: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -50471,7 +50471,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_uAhsdrFiklzvFua: +.L_16_blocks_ok_360: @@ -50602,7 +50602,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qimdfBypdFskivz + jl .L_small_initial_partial_block_361 @@ -50662,8 +50662,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qimdfBypdFskivz -.L_small_initial_partial_block_qimdfBypdFskivz: + jmp .L_small_initial_compute_done_361 +.L_small_initial_partial_block_361: @@ -50720,26 +50720,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qimdfBypdFskivz: +.L_small_initial_compute_done_361: orq %r8,%r8 - je .L_after_reduction_qimdfBypdFskivz + je .L_after_reduction_361 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qimdfBypdFskivz: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_10_aCrznswshDckglE: +.L_after_reduction_361: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_10_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_EwxbDxxxyrAaxlF + jae .L_16_blocks_overflow_362 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_EwxbDxxxyrAaxlF + jmp .L_16_blocks_ok_362 -.L_16_blocks_overflow_EwxbDxxxyrAaxlF: +.L_16_blocks_overflow_362: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -50748,7 +50748,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_EwxbDxxxyrAaxlF: +.L_16_blocks_ok_362: @@ -50879,7 +50879,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nkaelugyCjhfuyc + jl .L_small_initial_partial_block_363 @@ -50939,8 +50939,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nkaelugyCjhfuyc -.L_small_initial_partial_block_nkaelugyCjhfuyc: + jmp .L_small_initial_compute_done_363 +.L_small_initial_partial_block_363: @@ -51003,26 +51003,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nkaelugyCjhfuyc: +.L_small_initial_compute_done_363: orq %r8,%r8 - je .L_after_reduction_nkaelugyCjhfuyc + je .L_after_reduction_363 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nkaelugyCjhfuyc: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_11_aCrznswshDckglE: +.L_after_reduction_363: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_11_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_yjBGqlojalhBqya + jae .L_16_blocks_overflow_364 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_yjBGqlojalhBqya + jmp .L_16_blocks_ok_364 -.L_16_blocks_overflow_yjBGqlojalhBqya: +.L_16_blocks_overflow_364: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -51031,7 +51031,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_yjBGqlojalhBqya: +.L_16_blocks_ok_364: @@ -51162,7 +51162,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_upsvhpflcyjzqob + jl .L_small_initial_partial_block_365 @@ -51223,8 +51223,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_upsvhpflcyjzqob -.L_small_initial_partial_block_upsvhpflcyjzqob: + jmp .L_small_initial_compute_done_365 +.L_small_initial_partial_block_365: @@ -51287,26 +51287,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_upsvhpflcyjzqob: +.L_small_initial_compute_done_365: orq %r8,%r8 - je .L_after_reduction_upsvhpflcyjzqob + je .L_after_reduction_365 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_upsvhpflcyjzqob: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_12_aCrznswshDckglE: +.L_after_reduction_365: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_12_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_GBFtfyCisxaCDeo + jae .L_16_blocks_overflow_366 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_GBFtfyCisxaCDeo + jmp .L_16_blocks_ok_366 -.L_16_blocks_overflow_GBFtfyCisxaCDeo: +.L_16_blocks_overflow_366: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -51315,7 +51315,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_GBFtfyCisxaCDeo: +.L_16_blocks_ok_366: @@ -51446,7 +51446,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jxqolABemjDcGoa + jl .L_small_initial_partial_block_367 @@ -51505,8 +51505,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jxqolABemjDcGoa -.L_small_initial_partial_block_jxqolABemjDcGoa: + jmp .L_small_initial_compute_done_367 +.L_small_initial_partial_block_367: @@ -51570,27 +51570,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jxqolABemjDcGoa: +.L_small_initial_compute_done_367: orq %r8,%r8 - je .L_after_reduction_jxqolABemjDcGoa + je .L_after_reduction_367 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jxqolABemjDcGoa: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_13_aCrznswshDckglE: +.L_after_reduction_367: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_13_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_pmblFxwdwCDyeEp + jae .L_16_blocks_overflow_368 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_pmblFxwdwCDyeEp + jmp .L_16_blocks_ok_368 -.L_16_blocks_overflow_pmblFxwdwCDyeEp: +.L_16_blocks_overflow_368: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -51601,7 +51601,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_pmblFxwdwCDyeEp: +.L_16_blocks_ok_368: @@ -51751,7 +51751,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AlbyExeFEFqjDkc + jl .L_small_initial_partial_block_369 @@ -51816,8 +51816,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AlbyExeFEFqjDkc -.L_small_initial_partial_block_AlbyExeFEFqjDkc: + jmp .L_small_initial_compute_done_369 +.L_small_initial_partial_block_369: @@ -51879,27 +51879,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AlbyExeFEFqjDkc: +.L_small_initial_compute_done_369: orq %r8,%r8 - je .L_after_reduction_AlbyExeFEFqjDkc + je .L_after_reduction_369 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AlbyExeFEFqjDkc: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_14_aCrznswshDckglE: +.L_after_reduction_369: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_14_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_rbhrvgyqqDGtipE + jae .L_16_blocks_overflow_370 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_rbhrvgyqqDGtipE + jmp .L_16_blocks_ok_370 -.L_16_blocks_overflow_rbhrvgyqqDGtipE: +.L_16_blocks_overflow_370: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -51910,7 +51910,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_rbhrvgyqqDGtipE: +.L_16_blocks_ok_370: @@ -52060,7 +52060,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zrFyAGcGCExrFql + jl .L_small_initial_partial_block_371 @@ -52125,8 +52125,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zrFyAGcGCExrFql -.L_small_initial_partial_block_zrFyAGcGCExrFql: + jmp .L_small_initial_compute_done_371 +.L_small_initial_partial_block_371: @@ -52194,27 +52194,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zrFyAGcGCExrFql: +.L_small_initial_compute_done_371: orq %r8,%r8 - je .L_after_reduction_zrFyAGcGCExrFql + je .L_after_reduction_371 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zrFyAGcGCExrFql: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_15_aCrznswshDckglE: +.L_after_reduction_371: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_15_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_rFsEaCnGaplhzeu + jae .L_16_blocks_overflow_372 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_rFsEaCnGaplhzeu + jmp .L_16_blocks_ok_372 -.L_16_blocks_overflow_rFsEaCnGaplhzeu: +.L_16_blocks_overflow_372: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -52225,7 +52225,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_rFsEaCnGaplhzeu: +.L_16_blocks_ok_372: @@ -52375,7 +52375,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_embEaDBkjsBkfvo + jl .L_small_initial_partial_block_373 @@ -52441,8 +52441,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_embEaDBkjsBkfvo -.L_small_initial_partial_block_embEaDBkjsBkfvo: + jmp .L_small_initial_compute_done_373 +.L_small_initial_partial_block_373: @@ -52510,27 +52510,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_embEaDBkjsBkfvo: +.L_small_initial_compute_done_373: orq %r8,%r8 - je .L_after_reduction_embEaDBkjsBkfvo + je .L_after_reduction_373 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_embEaDBkjsBkfvo: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_16_aCrznswshDckglE: +.L_after_reduction_373: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_16_343: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_jlBCFmxmthqAqub + jae .L_16_blocks_overflow_374 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_jlBCFmxmthqAqub + jmp .L_16_blocks_ok_374 -.L_16_blocks_overflow_jlBCFmxmthqAqub: +.L_16_blocks_overflow_374: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -52541,7 +52541,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_jlBCFmxmthqAqub: +.L_16_blocks_ok_374: @@ -52688,7 +52688,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_odaisFyfxykzsub: +.L_small_initial_partial_block_375: @@ -52757,11 +52757,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_odaisFyfxykzsub: +.L_small_initial_compute_done_375: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_odaisFyfxykzsub: - jmp .L_last_blocks_done_aCrznswshDckglE -.L_last_num_blocks_is_0_aCrznswshDckglE: +.L_after_reduction_375: + jmp .L_last_blocks_done_343 +.L_last_num_blocks_is_0_343: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -52822,18 +52822,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_aCrznswshDckglE: +.L_last_blocks_done_343: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_iygyqoBzBDrEGDx -.L_encrypt_32_blocks_iygyqoBzBDrEGDx: + jmp .L_ghash_done_334 +.L_encrypt_32_blocks_334: cmpb $240,%r15b - jae .L_16_blocks_overflow_shbCqwuxatcarFk + jae .L_16_blocks_overflow_376 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_shbCqwuxatcarFk -.L_16_blocks_overflow_shbCqwuxatcarFk: + jmp .L_16_blocks_ok_376 +.L_16_blocks_overflow_376: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -52844,7 +52844,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_shbCqwuxatcarFk: +.L_16_blocks_ok_376: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -53032,13 +53032,13 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_qlsyayhgEdxuolb + jae .L_16_blocks_overflow_377 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_qlsyayhgEdxuolb -.L_16_blocks_overflow_qlsyayhgEdxuolb: + jmp .L_16_blocks_ok_377 +.L_16_blocks_overflow_377: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -53049,7 +53049,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_qlsyayhgEdxuolb: +.L_16_blocks_ok_377: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -53305,61 +53305,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_btoesFmiotqivzq + je .L_last_num_blocks_is_0_378 cmpl $8,%r10d - je .L_last_num_blocks_is_8_btoesFmiotqivzq - jb .L_last_num_blocks_is_7_1_btoesFmiotqivzq + je .L_last_num_blocks_is_8_378 + jb .L_last_num_blocks_is_7_1_378 cmpl $12,%r10d - je .L_last_num_blocks_is_12_btoesFmiotqivzq - jb .L_last_num_blocks_is_11_9_btoesFmiotqivzq + je .L_last_num_blocks_is_12_378 + jb .L_last_num_blocks_is_11_9_378 cmpl $15,%r10d - je .L_last_num_blocks_is_15_btoesFmiotqivzq - ja .L_last_num_blocks_is_16_btoesFmiotqivzq + je .L_last_num_blocks_is_15_378 + ja .L_last_num_blocks_is_16_378 cmpl $14,%r10d - je .L_last_num_blocks_is_14_btoesFmiotqivzq - jmp .L_last_num_blocks_is_13_btoesFmiotqivzq + je .L_last_num_blocks_is_14_378 + jmp .L_last_num_blocks_is_13_378 -.L_last_num_blocks_is_11_9_btoesFmiotqivzq: +.L_last_num_blocks_is_11_9_378: cmpl $10,%r10d - je .L_last_num_blocks_is_10_btoesFmiotqivzq - ja .L_last_num_blocks_is_11_btoesFmiotqivzq - jmp .L_last_num_blocks_is_9_btoesFmiotqivzq + je .L_last_num_blocks_is_10_378 + ja .L_last_num_blocks_is_11_378 + jmp .L_last_num_blocks_is_9_378 -.L_last_num_blocks_is_7_1_btoesFmiotqivzq: +.L_last_num_blocks_is_7_1_378: cmpl $4,%r10d - je .L_last_num_blocks_is_4_btoesFmiotqivzq - jb .L_last_num_blocks_is_3_1_btoesFmiotqivzq + je .L_last_num_blocks_is_4_378 + jb .L_last_num_blocks_is_3_1_378 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_btoesFmiotqivzq - je .L_last_num_blocks_is_6_btoesFmiotqivzq - jmp .L_last_num_blocks_is_5_btoesFmiotqivzq + ja .L_last_num_blocks_is_7_378 + je .L_last_num_blocks_is_6_378 + jmp .L_last_num_blocks_is_5_378 -.L_last_num_blocks_is_3_1_btoesFmiotqivzq: +.L_last_num_blocks_is_3_1_378: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_btoesFmiotqivzq - je .L_last_num_blocks_is_2_btoesFmiotqivzq -.L_last_num_blocks_is_1_btoesFmiotqivzq: + ja .L_last_num_blocks_is_3_378 + je .L_last_num_blocks_is_2_378 +.L_last_num_blocks_is_1_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_ykasuomdxjktbDA + jae .L_16_blocks_overflow_379 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_ykasuomdxjktbDA + jmp .L_16_blocks_ok_379 -.L_16_blocks_overflow_ykasuomdxjktbDA: +.L_16_blocks_overflow_379: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_ykasuomdxjktbDA: +.L_16_blocks_ok_379: @@ -53451,7 +53451,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tEnCdkciEyGxljp + jl .L_small_initial_partial_block_380 @@ -53495,8 +53495,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tEnCdkciEyGxljp -.L_small_initial_partial_block_tEnCdkciEyGxljp: + jmp .L_small_initial_compute_done_380 +.L_small_initial_partial_block_380: @@ -53548,24 +53548,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_tEnCdkciEyGxljp -.L_small_initial_compute_done_tEnCdkciEyGxljp: -.L_after_reduction_tEnCdkciEyGxljp: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_2_btoesFmiotqivzq: + jmp .L_after_reduction_380 +.L_small_initial_compute_done_380: +.L_after_reduction_380: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_2_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_jyAcdjBuaExcddm + jae .L_16_blocks_overflow_381 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_jyAcdjBuaExcddm + jmp .L_16_blocks_ok_381 -.L_16_blocks_overflow_jyAcdjBuaExcddm: +.L_16_blocks_overflow_381: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_jyAcdjBuaExcddm: +.L_16_blocks_ok_381: @@ -53658,7 +53658,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kqoatuztgkstEbz + jl .L_small_initial_partial_block_382 @@ -53702,8 +53702,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kqoatuztgkstEbz -.L_small_initial_partial_block_kqoatuztgkstEbz: + jmp .L_small_initial_compute_done_382 +.L_small_initial_partial_block_382: @@ -53750,27 +53750,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kqoatuztgkstEbz: +.L_small_initial_compute_done_382: orq %r8,%r8 - je .L_after_reduction_kqoatuztgkstEbz + je .L_after_reduction_382 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kqoatuztgkstEbz: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_3_btoesFmiotqivzq: +.L_after_reduction_382: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_3_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_feEEqqeniDfFxCa + jae .L_16_blocks_overflow_383 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_feEEqqeniDfFxCa + jmp .L_16_blocks_ok_383 -.L_16_blocks_overflow_feEEqqeniDfFxCa: +.L_16_blocks_overflow_383: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_feEEqqeniDfFxCa: +.L_16_blocks_ok_383: @@ -53863,7 +53863,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DhDbgbdyGGbqwsv + jl .L_small_initial_partial_block_384 @@ -53908,8 +53908,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DhDbgbdyGGbqwsv -.L_small_initial_partial_block_DhDbgbdyGGbqwsv: + jmp .L_small_initial_compute_done_384 +.L_small_initial_partial_block_384: @@ -53956,27 +53956,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DhDbgbdyGGbqwsv: +.L_small_initial_compute_done_384: orq %r8,%r8 - je .L_after_reduction_DhDbgbdyGGbqwsv + je .L_after_reduction_384 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DhDbgbdyGGbqwsv: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_4_btoesFmiotqivzq: +.L_after_reduction_384: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_4_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_FpowsheAtkFuuam + jae .L_16_blocks_overflow_385 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_FpowsheAtkFuuam + jmp .L_16_blocks_ok_385 -.L_16_blocks_overflow_FpowsheAtkFuuam: +.L_16_blocks_overflow_385: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_FpowsheAtkFuuam: +.L_16_blocks_ok_385: @@ -54069,7 +54069,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gxjGhujutnupuuA + jl .L_small_initial_partial_block_386 @@ -54114,8 +54114,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gxjGhujutnupuuA -.L_small_initial_partial_block_gxjGhujutnupuuA: + jmp .L_small_initial_compute_done_386 +.L_small_initial_partial_block_386: @@ -54163,32 +54163,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gxjGhujutnupuuA: +.L_small_initial_compute_done_386: orq %r8,%r8 - je .L_after_reduction_gxjGhujutnupuuA + je .L_after_reduction_386 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gxjGhujutnupuuA: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_5_btoesFmiotqivzq: +.L_after_reduction_386: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_5_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_fxBvbhdGdeqfxpE + jae .L_16_blocks_overflow_387 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_fxBvbhdGdeqfxpE + jmp .L_16_blocks_ok_387 -.L_16_blocks_overflow_fxBvbhdGdeqfxpE: +.L_16_blocks_overflow_387: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_fxBvbhdGdeqfxpE: +.L_16_blocks_ok_387: @@ -54300,7 +54300,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_corxBoDpzcxzjCp + jl .L_small_initial_partial_block_388 @@ -54351,8 +54351,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_corxBoDpzcxzjCp -.L_small_initial_partial_block_corxBoDpzcxzjCp: + jmp .L_small_initial_compute_done_388 +.L_small_initial_partial_block_388: @@ -54400,32 +54400,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_corxBoDpzcxzjCp: +.L_small_initial_compute_done_388: orq %r8,%r8 - je .L_after_reduction_corxBoDpzcxzjCp + je .L_after_reduction_388 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_corxBoDpzcxzjCp: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_6_btoesFmiotqivzq: +.L_after_reduction_388: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_6_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_eqqnvywtcBwBxFh + jae .L_16_blocks_overflow_389 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_eqqnvywtcBwBxFh + jmp .L_16_blocks_ok_389 -.L_16_blocks_overflow_eqqnvywtcBwBxFh: +.L_16_blocks_overflow_389: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_eqqnvywtcBwBxFh: +.L_16_blocks_ok_389: @@ -54537,7 +54537,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ytuelzAGbgtGtfr + jl .L_small_initial_partial_block_390 @@ -54588,8 +54588,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ytuelzAGbgtGtfr -.L_small_initial_partial_block_ytuelzAGbgtGtfr: + jmp .L_small_initial_compute_done_390 +.L_small_initial_partial_block_390: @@ -54643,32 +54643,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ytuelzAGbgtGtfr: +.L_small_initial_compute_done_390: orq %r8,%r8 - je .L_after_reduction_ytuelzAGbgtGtfr + je .L_after_reduction_390 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ytuelzAGbgtGtfr: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_7_btoesFmiotqivzq: +.L_after_reduction_390: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_7_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_lfismiegtoxsceG + jae .L_16_blocks_overflow_391 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_lfismiegtoxsceG + jmp .L_16_blocks_ok_391 -.L_16_blocks_overflow_lfismiegtoxsceG: +.L_16_blocks_overflow_391: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_lfismiegtoxsceG: +.L_16_blocks_ok_391: @@ -54780,7 +54780,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sBDghnoyhrCmBop + jl .L_small_initial_partial_block_392 @@ -54832,8 +54832,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sBDghnoyhrCmBop -.L_small_initial_partial_block_sBDghnoyhrCmBop: + jmp .L_small_initial_compute_done_392 +.L_small_initial_partial_block_392: @@ -54887,32 +54887,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sBDghnoyhrCmBop: +.L_small_initial_compute_done_392: orq %r8,%r8 - je .L_after_reduction_sBDghnoyhrCmBop + je .L_after_reduction_392 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sBDghnoyhrCmBop: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_8_btoesFmiotqivzq: +.L_after_reduction_392: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_8_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_cnxmjyrrxxDwctk + jae .L_16_blocks_overflow_393 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_cnxmjyrrxxDwctk + jmp .L_16_blocks_ok_393 -.L_16_blocks_overflow_cnxmjyrrxxDwctk: +.L_16_blocks_overflow_393: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_cnxmjyrrxxDwctk: +.L_16_blocks_ok_393: @@ -55024,7 +55024,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zerxvifmubnFiAw + jl .L_small_initial_partial_block_394 @@ -55078,8 +55078,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zerxvifmubnFiAw -.L_small_initial_partial_block_zerxvifmubnFiAw: + jmp .L_small_initial_compute_done_394 +.L_small_initial_partial_block_394: @@ -55134,26 +55134,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zerxvifmubnFiAw: +.L_small_initial_compute_done_394: orq %r8,%r8 - je .L_after_reduction_zerxvifmubnFiAw + je .L_after_reduction_394 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zerxvifmubnFiAw: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_9_btoesFmiotqivzq: +.L_after_reduction_394: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_9_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_CysekAcEqrdoehB + jae .L_16_blocks_overflow_395 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_CysekAcEqrdoehB + jmp .L_16_blocks_ok_395 -.L_16_blocks_overflow_CysekAcEqrdoehB: +.L_16_blocks_overflow_395: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -55162,7 +55162,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_CysekAcEqrdoehB: +.L_16_blocks_ok_395: @@ -55293,7 +55293,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CDCwcunhttfkhem + jl .L_small_initial_partial_block_396 @@ -55353,8 +55353,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CDCwcunhttfkhem -.L_small_initial_partial_block_CDCwcunhttfkhem: + jmp .L_small_initial_compute_done_396 +.L_small_initial_partial_block_396: @@ -55411,26 +55411,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CDCwcunhttfkhem: +.L_small_initial_compute_done_396: orq %r8,%r8 - je .L_after_reduction_CDCwcunhttfkhem + je .L_after_reduction_396 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CDCwcunhttfkhem: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_10_btoesFmiotqivzq: +.L_after_reduction_396: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_10_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_kjxnlEGsxyvlyCg + jae .L_16_blocks_overflow_397 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_kjxnlEGsxyvlyCg + jmp .L_16_blocks_ok_397 -.L_16_blocks_overflow_kjxnlEGsxyvlyCg: +.L_16_blocks_overflow_397: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -55439,7 +55439,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_kjxnlEGsxyvlyCg: +.L_16_blocks_ok_397: @@ -55570,7 +55570,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yznAwzrGchmzhzn + jl .L_small_initial_partial_block_398 @@ -55630,8 +55630,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yznAwzrGchmzhzn -.L_small_initial_partial_block_yznAwzrGchmzhzn: + jmp .L_small_initial_compute_done_398 +.L_small_initial_partial_block_398: @@ -55694,26 +55694,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yznAwzrGchmzhzn: +.L_small_initial_compute_done_398: orq %r8,%r8 - je .L_after_reduction_yznAwzrGchmzhzn + je .L_after_reduction_398 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yznAwzrGchmzhzn: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_11_btoesFmiotqivzq: +.L_after_reduction_398: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_11_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_AoDlsApAqnltpeA + jae .L_16_blocks_overflow_399 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_AoDlsApAqnltpeA + jmp .L_16_blocks_ok_399 -.L_16_blocks_overflow_AoDlsApAqnltpeA: +.L_16_blocks_overflow_399: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -55722,7 +55722,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_AoDlsApAqnltpeA: +.L_16_blocks_ok_399: @@ -55853,7 +55853,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sChkrDDpcBryCfz + jl .L_small_initial_partial_block_400 @@ -55914,8 +55914,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sChkrDDpcBryCfz -.L_small_initial_partial_block_sChkrDDpcBryCfz: + jmp .L_small_initial_compute_done_400 +.L_small_initial_partial_block_400: @@ -55978,26 +55978,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sChkrDDpcBryCfz: +.L_small_initial_compute_done_400: orq %r8,%r8 - je .L_after_reduction_sChkrDDpcBryCfz + je .L_after_reduction_400 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sChkrDDpcBryCfz: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_12_btoesFmiotqivzq: +.L_after_reduction_400: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_12_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_abBkyynBvCApgjh + jae .L_16_blocks_overflow_401 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_abBkyynBvCApgjh + jmp .L_16_blocks_ok_401 -.L_16_blocks_overflow_abBkyynBvCApgjh: +.L_16_blocks_overflow_401: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -56006,7 +56006,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_abBkyynBvCApgjh: +.L_16_blocks_ok_401: @@ -56137,7 +56137,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_teskjqpCqhfBhkd + jl .L_small_initial_partial_block_402 @@ -56196,8 +56196,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_teskjqpCqhfBhkd -.L_small_initial_partial_block_teskjqpCqhfBhkd: + jmp .L_small_initial_compute_done_402 +.L_small_initial_partial_block_402: @@ -56261,27 +56261,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_teskjqpCqhfBhkd: +.L_small_initial_compute_done_402: orq %r8,%r8 - je .L_after_reduction_teskjqpCqhfBhkd + je .L_after_reduction_402 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_teskjqpCqhfBhkd: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_13_btoesFmiotqivzq: +.L_after_reduction_402: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_13_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_mjfDhrmwFmameEq + jae .L_16_blocks_overflow_403 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_mjfDhrmwFmameEq + jmp .L_16_blocks_ok_403 -.L_16_blocks_overflow_mjfDhrmwFmameEq: +.L_16_blocks_overflow_403: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -56292,7 +56292,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_mjfDhrmwFmameEq: +.L_16_blocks_ok_403: @@ -56442,7 +56442,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CGlsuplczpgiEem + jl .L_small_initial_partial_block_404 @@ -56507,8 +56507,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CGlsuplczpgiEem -.L_small_initial_partial_block_CGlsuplczpgiEem: + jmp .L_small_initial_compute_done_404 +.L_small_initial_partial_block_404: @@ -56570,27 +56570,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CGlsuplczpgiEem: +.L_small_initial_compute_done_404: orq %r8,%r8 - je .L_after_reduction_CGlsuplczpgiEem + je .L_after_reduction_404 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CGlsuplczpgiEem: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_14_btoesFmiotqivzq: +.L_after_reduction_404: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_14_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_GBBmxzADzdkkvjA + jae .L_16_blocks_overflow_405 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_GBBmxzADzdkkvjA + jmp .L_16_blocks_ok_405 -.L_16_blocks_overflow_GBBmxzADzdkkvjA: +.L_16_blocks_overflow_405: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -56601,7 +56601,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_GBBmxzADzdkkvjA: +.L_16_blocks_ok_405: @@ -56751,7 +56751,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cejDpngiqcgmylk + jl .L_small_initial_partial_block_406 @@ -56816,8 +56816,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cejDpngiqcgmylk -.L_small_initial_partial_block_cejDpngiqcgmylk: + jmp .L_small_initial_compute_done_406 +.L_small_initial_partial_block_406: @@ -56885,27 +56885,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cejDpngiqcgmylk: +.L_small_initial_compute_done_406: orq %r8,%r8 - je .L_after_reduction_cejDpngiqcgmylk + je .L_after_reduction_406 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cejDpngiqcgmylk: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_15_btoesFmiotqivzq: +.L_after_reduction_406: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_15_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_svAlCCqgkuvlAtx + jae .L_16_blocks_overflow_407 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_svAlCCqgkuvlAtx + jmp .L_16_blocks_ok_407 -.L_16_blocks_overflow_svAlCCqgkuvlAtx: +.L_16_blocks_overflow_407: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -56916,7 +56916,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_svAlCCqgkuvlAtx: +.L_16_blocks_ok_407: @@ -57066,7 +57066,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tygzbBzlhxjrdln + jl .L_small_initial_partial_block_408 @@ -57132,8 +57132,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tygzbBzlhxjrdln -.L_small_initial_partial_block_tygzbBzlhxjrdln: + jmp .L_small_initial_compute_done_408 +.L_small_initial_partial_block_408: @@ -57201,27 +57201,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tygzbBzlhxjrdln: +.L_small_initial_compute_done_408: orq %r8,%r8 - je .L_after_reduction_tygzbBzlhxjrdln + je .L_after_reduction_408 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tygzbBzlhxjrdln: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_16_btoesFmiotqivzq: +.L_after_reduction_408: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_16_378: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_aplGcBfDtrsdmlD + jae .L_16_blocks_overflow_409 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_aplGcBfDtrsdmlD + jmp .L_16_blocks_ok_409 -.L_16_blocks_overflow_aplGcBfDtrsdmlD: +.L_16_blocks_overflow_409: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -57232,7 +57232,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_aplGcBfDtrsdmlD: +.L_16_blocks_ok_409: @@ -57379,7 +57379,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_DFdzftBikbwdkrq: +.L_small_initial_partial_block_410: @@ -57448,11 +57448,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DFdzftBikbwdkrq: +.L_small_initial_compute_done_410: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DFdzftBikbwdkrq: - jmp .L_last_blocks_done_btoesFmiotqivzq -.L_last_num_blocks_is_0_btoesFmiotqivzq: +.L_after_reduction_410: + jmp .L_last_blocks_done_378 +.L_last_num_blocks_is_0_378: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -57514,18 +57514,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_btoesFmiotqivzq: +.L_last_blocks_done_378: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_iygyqoBzBDrEGDx -.L_encrypt_16_blocks_iygyqoBzBDrEGDx: + jmp .L_ghash_done_334 +.L_encrypt_16_blocks_334: cmpb $240,%r15b - jae .L_16_blocks_overflow_ErfrlhztcphytGy + jae .L_16_blocks_overflow_411 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ErfrlhztcphytGy -.L_16_blocks_overflow_ErfrlhztcphytGy: + jmp .L_16_blocks_ok_411 +.L_16_blocks_overflow_411: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -57536,7 +57536,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ErfrlhztcphytGy: +.L_16_blocks_ok_411: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -57761,61 +57761,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_Gnubivtecsvvxsn + je .L_last_num_blocks_is_0_412 cmpl $8,%r10d - je .L_last_num_blocks_is_8_Gnubivtecsvvxsn - jb .L_last_num_blocks_is_7_1_Gnubivtecsvvxsn + je .L_last_num_blocks_is_8_412 + jb .L_last_num_blocks_is_7_1_412 cmpl $12,%r10d - je .L_last_num_blocks_is_12_Gnubivtecsvvxsn - jb .L_last_num_blocks_is_11_9_Gnubivtecsvvxsn + je .L_last_num_blocks_is_12_412 + jb .L_last_num_blocks_is_11_9_412 cmpl $15,%r10d - je .L_last_num_blocks_is_15_Gnubivtecsvvxsn - ja .L_last_num_blocks_is_16_Gnubivtecsvvxsn + je .L_last_num_blocks_is_15_412 + ja .L_last_num_blocks_is_16_412 cmpl $14,%r10d - je .L_last_num_blocks_is_14_Gnubivtecsvvxsn - jmp .L_last_num_blocks_is_13_Gnubivtecsvvxsn + je .L_last_num_blocks_is_14_412 + jmp .L_last_num_blocks_is_13_412 -.L_last_num_blocks_is_11_9_Gnubivtecsvvxsn: +.L_last_num_blocks_is_11_9_412: cmpl $10,%r10d - je .L_last_num_blocks_is_10_Gnubivtecsvvxsn - ja .L_last_num_blocks_is_11_Gnubivtecsvvxsn - jmp .L_last_num_blocks_is_9_Gnubivtecsvvxsn + je .L_last_num_blocks_is_10_412 + ja .L_last_num_blocks_is_11_412 + jmp .L_last_num_blocks_is_9_412 -.L_last_num_blocks_is_7_1_Gnubivtecsvvxsn: +.L_last_num_blocks_is_7_1_412: cmpl $4,%r10d - je .L_last_num_blocks_is_4_Gnubivtecsvvxsn - jb .L_last_num_blocks_is_3_1_Gnubivtecsvvxsn + je .L_last_num_blocks_is_4_412 + jb .L_last_num_blocks_is_3_1_412 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_Gnubivtecsvvxsn - je .L_last_num_blocks_is_6_Gnubivtecsvvxsn - jmp .L_last_num_blocks_is_5_Gnubivtecsvvxsn + ja .L_last_num_blocks_is_7_412 + je .L_last_num_blocks_is_6_412 + jmp .L_last_num_blocks_is_5_412 -.L_last_num_blocks_is_3_1_Gnubivtecsvvxsn: +.L_last_num_blocks_is_3_1_412: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_Gnubivtecsvvxsn - je .L_last_num_blocks_is_2_Gnubivtecsvvxsn -.L_last_num_blocks_is_1_Gnubivtecsvvxsn: + ja .L_last_num_blocks_is_3_412 + je .L_last_num_blocks_is_2_412 +.L_last_num_blocks_is_1_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_qAnlyyDDrCharyc + jae .L_16_blocks_overflow_413 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_qAnlyyDDrCharyc + jmp .L_16_blocks_ok_413 -.L_16_blocks_overflow_qAnlyyDDrCharyc: +.L_16_blocks_overflow_413: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_qAnlyyDDrCharyc: +.L_16_blocks_ok_413: @@ -57930,7 +57930,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fvxDhsaGzfnrkca + jl .L_small_initial_partial_block_414 @@ -57972,8 +57972,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fvxDhsaGzfnrkca -.L_small_initial_partial_block_fvxDhsaGzfnrkca: + jmp .L_small_initial_compute_done_414 +.L_small_initial_partial_block_414: @@ -57997,24 +57997,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_fvxDhsaGzfnrkca -.L_small_initial_compute_done_fvxDhsaGzfnrkca: -.L_after_reduction_fvxDhsaGzfnrkca: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_2_Gnubivtecsvvxsn: + jmp .L_after_reduction_414 +.L_small_initial_compute_done_414: +.L_after_reduction_414: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_2_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_gEFEqxgkDqDlBrp + jae .L_16_blocks_overflow_415 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_gEFEqxgkDqDlBrp + jmp .L_16_blocks_ok_415 -.L_16_blocks_overflow_gEFEqxgkDqDlBrp: +.L_16_blocks_overflow_415: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_gEFEqxgkDqDlBrp: +.L_16_blocks_ok_415: @@ -58130,7 +58130,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GbbFDiEfauixjjg + jl .L_small_initial_partial_block_416 @@ -58172,8 +58172,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GbbFDiEfauixjjg -.L_small_initial_partial_block_GbbFDiEfauixjjg: + jmp .L_small_initial_compute_done_416 +.L_small_initial_partial_block_416: @@ -58218,27 +58218,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GbbFDiEfauixjjg: +.L_small_initial_compute_done_416: orq %r8,%r8 - je .L_after_reduction_GbbFDiEfauixjjg + je .L_after_reduction_416 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GbbFDiEfauixjjg: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_3_Gnubivtecsvvxsn: +.L_after_reduction_416: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_3_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_slmtggkbzGwheut + jae .L_16_blocks_overflow_417 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_slmtggkbzGwheut + jmp .L_16_blocks_ok_417 -.L_16_blocks_overflow_slmtggkbzGwheut: +.L_16_blocks_overflow_417: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_slmtggkbzGwheut: +.L_16_blocks_ok_417: @@ -58354,7 +58354,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ptEdonDntFBeGqk + jl .L_small_initial_partial_block_418 @@ -58397,8 +58397,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ptEdonDntFBeGqk -.L_small_initial_partial_block_ptEdonDntFBeGqk: + jmp .L_small_initial_compute_done_418 +.L_small_initial_partial_block_418: @@ -58443,27 +58443,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ptEdonDntFBeGqk: +.L_small_initial_compute_done_418: orq %r8,%r8 - je .L_after_reduction_ptEdonDntFBeGqk + je .L_after_reduction_418 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ptEdonDntFBeGqk: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_4_Gnubivtecsvvxsn: +.L_after_reduction_418: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_4_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_pyrnqjwtunwCifj + jae .L_16_blocks_overflow_419 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_pyrnqjwtunwCifj + jmp .L_16_blocks_ok_419 -.L_16_blocks_overflow_pyrnqjwtunwCifj: +.L_16_blocks_overflow_419: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_pyrnqjwtunwCifj: +.L_16_blocks_ok_419: @@ -58579,7 +58579,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EFnzvxanclnChAl + jl .L_small_initial_partial_block_420 @@ -58621,8 +58621,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EFnzvxanclnChAl -.L_small_initial_partial_block_EFnzvxanclnChAl: + jmp .L_small_initial_compute_done_420 +.L_small_initial_partial_block_420: @@ -58668,32 +58668,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EFnzvxanclnChAl: +.L_small_initial_compute_done_420: orq %r8,%r8 - je .L_after_reduction_EFnzvxanclnChAl + je .L_after_reduction_420 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EFnzvxanclnChAl: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_5_Gnubivtecsvvxsn: +.L_after_reduction_420: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_5_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_fwAnzFjtnADuhAc + jae .L_16_blocks_overflow_421 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_fwAnzFjtnADuhAc + jmp .L_16_blocks_ok_421 -.L_16_blocks_overflow_fwAnzFjtnADuhAc: +.L_16_blocks_overflow_421: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_fwAnzFjtnADuhAc: +.L_16_blocks_ok_421: @@ -58828,7 +58828,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zDFmpGnvmcwcpcF + jl .L_small_initial_partial_block_422 @@ -58880,8 +58880,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zDFmpGnvmcwcpcF -.L_small_initial_partial_block_zDFmpGnvmcwcpcF: + jmp .L_small_initial_compute_done_422 +.L_small_initial_partial_block_422: @@ -58926,32 +58926,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zDFmpGnvmcwcpcF: +.L_small_initial_compute_done_422: orq %r8,%r8 - je .L_after_reduction_zDFmpGnvmcwcpcF + je .L_after_reduction_422 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zDFmpGnvmcwcpcF: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_6_Gnubivtecsvvxsn: +.L_after_reduction_422: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_6_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_oxGpzauifbxypuo + jae .L_16_blocks_overflow_423 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_oxGpzauifbxypuo + jmp .L_16_blocks_ok_423 -.L_16_blocks_overflow_oxGpzauifbxypuo: +.L_16_blocks_overflow_423: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_oxGpzauifbxypuo: +.L_16_blocks_ok_423: @@ -59086,7 +59086,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BfEymsnFikrbmiG + jl .L_small_initial_partial_block_424 @@ -59138,8 +59138,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BfEymsnFikrbmiG -.L_small_initial_partial_block_BfEymsnFikrbmiG: + jmp .L_small_initial_compute_done_424 +.L_small_initial_partial_block_424: @@ -59194,32 +59194,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BfEymsnFikrbmiG: +.L_small_initial_compute_done_424: orq %r8,%r8 - je .L_after_reduction_BfEymsnFikrbmiG + je .L_after_reduction_424 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BfEymsnFikrbmiG: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_7_Gnubivtecsvvxsn: +.L_after_reduction_424: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_7_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_AebyqcFDoyhohAm + jae .L_16_blocks_overflow_425 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_AebyqcFDoyhohAm + jmp .L_16_blocks_ok_425 -.L_16_blocks_overflow_AebyqcFDoyhohAm: +.L_16_blocks_overflow_425: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_AebyqcFDoyhohAm: +.L_16_blocks_ok_425: @@ -59354,7 +59354,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yGtdkquBpFrzGxA + jl .L_small_initial_partial_block_426 @@ -59407,8 +59407,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yGtdkquBpFrzGxA -.L_small_initial_partial_block_yGtdkquBpFrzGxA: + jmp .L_small_initial_compute_done_426 +.L_small_initial_partial_block_426: @@ -59463,32 +59463,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yGtdkquBpFrzGxA: +.L_small_initial_compute_done_426: orq %r8,%r8 - je .L_after_reduction_yGtdkquBpFrzGxA + je .L_after_reduction_426 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yGtdkquBpFrzGxA: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_8_Gnubivtecsvvxsn: +.L_after_reduction_426: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_8_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_oCxiagplknoApvk + jae .L_16_blocks_overflow_427 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_oCxiagplknoApvk + jmp .L_16_blocks_ok_427 -.L_16_blocks_overflow_oCxiagplknoApvk: +.L_16_blocks_overflow_427: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_oCxiagplknoApvk: +.L_16_blocks_ok_427: @@ -59623,7 +59623,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hniungngbtdmzdr + jl .L_small_initial_partial_block_428 @@ -59674,8 +59674,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hniungngbtdmzdr -.L_small_initial_partial_block_hniungngbtdmzdr: + jmp .L_small_initial_compute_done_428 +.L_small_initial_partial_block_428: @@ -59731,26 +59731,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hniungngbtdmzdr: +.L_small_initial_compute_done_428: orq %r8,%r8 - je .L_after_reduction_hniungngbtdmzdr + je .L_after_reduction_428 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hniungngbtdmzdr: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_9_Gnubivtecsvvxsn: +.L_after_reduction_428: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_9_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_FCElafjzFDfavhs + jae .L_16_blocks_overflow_429 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_FCElafjzFDfavhs + jmp .L_16_blocks_ok_429 -.L_16_blocks_overflow_FCElafjzFDfavhs: +.L_16_blocks_overflow_429: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -59759,7 +59759,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_FCElafjzFDfavhs: +.L_16_blocks_ok_429: @@ -59913,7 +59913,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mvCGduogqzcBglb + jl .L_small_initial_partial_block_430 @@ -59974,8 +59974,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mvCGduogqzcBglb -.L_small_initial_partial_block_mvCGduogqzcBglb: + jmp .L_small_initial_compute_done_430 +.L_small_initial_partial_block_430: @@ -60029,26 +60029,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mvCGduogqzcBglb: +.L_small_initial_compute_done_430: orq %r8,%r8 - je .L_after_reduction_mvCGduogqzcBglb + je .L_after_reduction_430 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mvCGduogqzcBglb: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_10_Gnubivtecsvvxsn: +.L_after_reduction_430: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_10_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_zjpEuudbihqhbzF + jae .L_16_blocks_overflow_431 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_zjpEuudbihqhbzF + jmp .L_16_blocks_ok_431 -.L_16_blocks_overflow_zjpEuudbihqhbzF: +.L_16_blocks_overflow_431: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -60057,7 +60057,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_zjpEuudbihqhbzF: +.L_16_blocks_ok_431: @@ -60211,7 +60211,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rBzbuDmawutlBue + jl .L_small_initial_partial_block_432 @@ -60272,8 +60272,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rBzbuDmawutlBue -.L_small_initial_partial_block_rBzbuDmawutlBue: + jmp .L_small_initial_compute_done_432 +.L_small_initial_partial_block_432: @@ -60337,26 +60337,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rBzbuDmawutlBue: +.L_small_initial_compute_done_432: orq %r8,%r8 - je .L_after_reduction_rBzbuDmawutlBue + je .L_after_reduction_432 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rBzbuDmawutlBue: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_11_Gnubivtecsvvxsn: +.L_after_reduction_432: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_11_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_mBfswwiFwAiopFm + jae .L_16_blocks_overflow_433 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_mBfswwiFwAiopFm + jmp .L_16_blocks_ok_433 -.L_16_blocks_overflow_mBfswwiFwAiopFm: +.L_16_blocks_overflow_433: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -60365,7 +60365,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_mBfswwiFwAiopFm: +.L_16_blocks_ok_433: @@ -60519,7 +60519,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ovzvvxganxCwprx + jl .L_small_initial_partial_block_434 @@ -60581,8 +60581,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ovzvvxganxCwprx -.L_small_initial_partial_block_ovzvvxganxCwprx: + jmp .L_small_initial_compute_done_434 +.L_small_initial_partial_block_434: @@ -60646,26 +60646,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ovzvvxganxCwprx: +.L_small_initial_compute_done_434: orq %r8,%r8 - je .L_after_reduction_ovzvvxganxCwprx + je .L_after_reduction_434 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ovzvvxganxCwprx: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_12_Gnubivtecsvvxsn: +.L_after_reduction_434: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_12_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_CzFuleccpdzkGbv + jae .L_16_blocks_overflow_435 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_CzFuleccpdzkGbv + jmp .L_16_blocks_ok_435 -.L_16_blocks_overflow_CzFuleccpdzkGbv: +.L_16_blocks_overflow_435: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -60674,7 +60674,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_CzFuleccpdzkGbv: +.L_16_blocks_ok_435: @@ -60828,7 +60828,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xFyFnkBxGhsnghi + jl .L_small_initial_partial_block_436 @@ -60884,8 +60884,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xFyFnkBxGhsnghi -.L_small_initial_partial_block_xFyFnkBxGhsnghi: + jmp .L_small_initial_compute_done_436 +.L_small_initial_partial_block_436: @@ -60950,27 +60950,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xFyFnkBxGhsnghi: +.L_small_initial_compute_done_436: orq %r8,%r8 - je .L_after_reduction_xFyFnkBxGhsnghi + je .L_after_reduction_436 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xFyFnkBxGhsnghi: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_13_Gnubivtecsvvxsn: +.L_after_reduction_436: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_13_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_uhDBaxzddCojahr + jae .L_16_blocks_overflow_437 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_uhDBaxzddCojahr + jmp .L_16_blocks_ok_437 -.L_16_blocks_overflow_uhDBaxzddCojahr: +.L_16_blocks_overflow_437: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -60981,7 +60981,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_uhDBaxzddCojahr: +.L_16_blocks_ok_437: @@ -61154,7 +61154,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xEqfwFDfExxAlne + jl .L_small_initial_partial_block_438 @@ -61220,8 +61220,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xEqfwFDfExxAlne -.L_small_initial_partial_block_xEqfwFDfExxAlne: + jmp .L_small_initial_compute_done_438 +.L_small_initial_partial_block_438: @@ -61280,27 +61280,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xEqfwFDfExxAlne: +.L_small_initial_compute_done_438: orq %r8,%r8 - je .L_after_reduction_xEqfwFDfExxAlne + je .L_after_reduction_438 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xEqfwFDfExxAlne: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_14_Gnubivtecsvvxsn: +.L_after_reduction_438: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_14_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_GkvhilqBilxepey + jae .L_16_blocks_overflow_439 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_GkvhilqBilxepey + jmp .L_16_blocks_ok_439 -.L_16_blocks_overflow_GkvhilqBilxepey: +.L_16_blocks_overflow_439: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -61311,7 +61311,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_GkvhilqBilxepey: +.L_16_blocks_ok_439: @@ -61484,7 +61484,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lkgemhztDfdaxdt + jl .L_small_initial_partial_block_440 @@ -61550,8 +61550,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lkgemhztDfdaxdt -.L_small_initial_partial_block_lkgemhztDfdaxdt: + jmp .L_small_initial_compute_done_440 +.L_small_initial_partial_block_440: @@ -61620,27 +61620,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lkgemhztDfdaxdt: +.L_small_initial_compute_done_440: orq %r8,%r8 - je .L_after_reduction_lkgemhztDfdaxdt + je .L_after_reduction_440 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lkgemhztDfdaxdt: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_15_Gnubivtecsvvxsn: +.L_after_reduction_440: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_15_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_jCoymdtsFabmjta + jae .L_16_blocks_overflow_441 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_jCoymdtsFabmjta + jmp .L_16_blocks_ok_441 -.L_16_blocks_overflow_jCoymdtsFabmjta: +.L_16_blocks_overflow_441: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -61651,7 +61651,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_jCoymdtsFabmjta: +.L_16_blocks_ok_441: @@ -61824,7 +61824,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ptwuadxGeakCwBu + jl .L_small_initial_partial_block_442 @@ -61891,8 +61891,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ptwuadxGeakCwBu -.L_small_initial_partial_block_ptwuadxGeakCwBu: + jmp .L_small_initial_compute_done_442 +.L_small_initial_partial_block_442: @@ -61961,27 +61961,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ptwuadxGeakCwBu: +.L_small_initial_compute_done_442: orq %r8,%r8 - je .L_after_reduction_ptwuadxGeakCwBu + je .L_after_reduction_442 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ptwuadxGeakCwBu: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_16_Gnubivtecsvvxsn: +.L_after_reduction_442: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_16_412: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_eChADgkmpAxhbGf + jae .L_16_blocks_overflow_443 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_eChADgkmpAxhbGf + jmp .L_16_blocks_ok_443 -.L_16_blocks_overflow_eChADgkmpAxhbGf: +.L_16_blocks_overflow_443: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -61992,7 +61992,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_eChADgkmpAxhbGf: +.L_16_blocks_ok_443: @@ -62162,7 +62162,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_yqaymaBzAyEGkvr: +.L_small_initial_partial_block_444: @@ -62232,11 +62232,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yqaymaBzAyEGkvr: +.L_small_initial_compute_done_444: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yqaymaBzAyEGkvr: - jmp .L_last_blocks_done_Gnubivtecsvvxsn -.L_last_num_blocks_is_0_Gnubivtecsvvxsn: +.L_after_reduction_444: + jmp .L_last_blocks_done_412 +.L_last_num_blocks_is_0_412: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -62297,18 +62297,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_Gnubivtecsvvxsn: +.L_last_blocks_done_412: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_iygyqoBzBDrEGDx + jmp .L_ghash_done_334 -.L_message_below_32_blocks_iygyqoBzBDrEGDx: +.L_message_below_32_blocks_334: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_azDuvFwdmjnExka + jnz .L_skip_hkeys_precomputation_445 vmovdqu64 640(%rsp),%zmm3 @@ -62436,7 +62436,7 @@ ossl_aes_gcm_encrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_azDuvFwdmjnExka: +.L_skip_hkeys_precomputation_445: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -62444,61 +62444,61 @@ ossl_aes_gcm_encrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_gzwxEzzolteBiAA + je .L_last_num_blocks_is_0_446 cmpl $8,%r10d - je .L_last_num_blocks_is_8_gzwxEzzolteBiAA - jb .L_last_num_blocks_is_7_1_gzwxEzzolteBiAA + je .L_last_num_blocks_is_8_446 + jb .L_last_num_blocks_is_7_1_446 cmpl $12,%r10d - je .L_last_num_blocks_is_12_gzwxEzzolteBiAA - jb .L_last_num_blocks_is_11_9_gzwxEzzolteBiAA + je .L_last_num_blocks_is_12_446 + jb .L_last_num_blocks_is_11_9_446 cmpl $15,%r10d - je .L_last_num_blocks_is_15_gzwxEzzolteBiAA - ja .L_last_num_blocks_is_16_gzwxEzzolteBiAA + je .L_last_num_blocks_is_15_446 + ja .L_last_num_blocks_is_16_446 cmpl $14,%r10d - je .L_last_num_blocks_is_14_gzwxEzzolteBiAA - jmp .L_last_num_blocks_is_13_gzwxEzzolteBiAA + je .L_last_num_blocks_is_14_446 + jmp .L_last_num_blocks_is_13_446 -.L_last_num_blocks_is_11_9_gzwxEzzolteBiAA: +.L_last_num_blocks_is_11_9_446: cmpl $10,%r10d - je .L_last_num_blocks_is_10_gzwxEzzolteBiAA - ja .L_last_num_blocks_is_11_gzwxEzzolteBiAA - jmp .L_last_num_blocks_is_9_gzwxEzzolteBiAA + je .L_last_num_blocks_is_10_446 + ja .L_last_num_blocks_is_11_446 + jmp .L_last_num_blocks_is_9_446 -.L_last_num_blocks_is_7_1_gzwxEzzolteBiAA: +.L_last_num_blocks_is_7_1_446: cmpl $4,%r10d - je .L_last_num_blocks_is_4_gzwxEzzolteBiAA - jb .L_last_num_blocks_is_3_1_gzwxEzzolteBiAA + je .L_last_num_blocks_is_4_446 + jb .L_last_num_blocks_is_3_1_446 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_gzwxEzzolteBiAA - je .L_last_num_blocks_is_6_gzwxEzzolteBiAA - jmp .L_last_num_blocks_is_5_gzwxEzzolteBiAA + ja .L_last_num_blocks_is_7_446 + je .L_last_num_blocks_is_6_446 + jmp .L_last_num_blocks_is_5_446 -.L_last_num_blocks_is_3_1_gzwxEzzolteBiAA: +.L_last_num_blocks_is_3_1_446: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_gzwxEzzolteBiAA - je .L_last_num_blocks_is_2_gzwxEzzolteBiAA -.L_last_num_blocks_is_1_gzwxEzzolteBiAA: + ja .L_last_num_blocks_is_3_446 + je .L_last_num_blocks_is_2_446 +.L_last_num_blocks_is_1_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_tcAeDEdjbkxBBvs + jae .L_16_blocks_overflow_447 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_tcAeDEdjbkxBBvs + jmp .L_16_blocks_ok_447 -.L_16_blocks_overflow_tcAeDEdjbkxBBvs: +.L_16_blocks_overflow_447: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_tcAeDEdjbkxBBvs: +.L_16_blocks_ok_447: @@ -62590,7 +62590,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xeFdigcGzfeaBDt + jl .L_small_initial_partial_block_448 @@ -62634,8 +62634,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xeFdigcGzfeaBDt -.L_small_initial_partial_block_xeFdigcGzfeaBDt: + jmp .L_small_initial_compute_done_448 +.L_small_initial_partial_block_448: @@ -62687,24 +62687,24 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_xeFdigcGzfeaBDt -.L_small_initial_compute_done_xeFdigcGzfeaBDt: -.L_after_reduction_xeFdigcGzfeaBDt: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_2_gzwxEzzolteBiAA: + jmp .L_after_reduction_448 +.L_small_initial_compute_done_448: +.L_after_reduction_448: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_2_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_dAineCpcothilCk + jae .L_16_blocks_overflow_449 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_dAineCpcothilCk + jmp .L_16_blocks_ok_449 -.L_16_blocks_overflow_dAineCpcothilCk: +.L_16_blocks_overflow_449: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_dAineCpcothilCk: +.L_16_blocks_ok_449: @@ -62797,7 +62797,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ofjtfahGoqegcbx + jl .L_small_initial_partial_block_450 @@ -62841,8 +62841,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ofjtfahGoqegcbx -.L_small_initial_partial_block_ofjtfahGoqegcbx: + jmp .L_small_initial_compute_done_450 +.L_small_initial_partial_block_450: @@ -62889,27 +62889,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ofjtfahGoqegcbx: +.L_small_initial_compute_done_450: orq %r8,%r8 - je .L_after_reduction_ofjtfahGoqegcbx + je .L_after_reduction_450 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ofjtfahGoqegcbx: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_3_gzwxEzzolteBiAA: +.L_after_reduction_450: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_3_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_eAcurBaqahuEvqx + jae .L_16_blocks_overflow_451 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_eAcurBaqahuEvqx + jmp .L_16_blocks_ok_451 -.L_16_blocks_overflow_eAcurBaqahuEvqx: +.L_16_blocks_overflow_451: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_eAcurBaqahuEvqx: +.L_16_blocks_ok_451: @@ -63002,7 +63002,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mqkDffwwghfDgFe + jl .L_small_initial_partial_block_452 @@ -63047,8 +63047,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mqkDffwwghfDgFe -.L_small_initial_partial_block_mqkDffwwghfDgFe: + jmp .L_small_initial_compute_done_452 +.L_small_initial_partial_block_452: @@ -63095,27 +63095,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mqkDffwwghfDgFe: +.L_small_initial_compute_done_452: orq %r8,%r8 - je .L_after_reduction_mqkDffwwghfDgFe + je .L_after_reduction_452 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mqkDffwwghfDgFe: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_4_gzwxEzzolteBiAA: +.L_after_reduction_452: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_4_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_kEnpDEaykmkmueD + jae .L_16_blocks_overflow_453 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_kEnpDEaykmkmueD + jmp .L_16_blocks_ok_453 -.L_16_blocks_overflow_kEnpDEaykmkmueD: +.L_16_blocks_overflow_453: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_kEnpDEaykmkmueD: +.L_16_blocks_ok_453: @@ -63208,7 +63208,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vcdtlcyhhcslpim + jl .L_small_initial_partial_block_454 @@ -63253,8 +63253,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vcdtlcyhhcslpim -.L_small_initial_partial_block_vcdtlcyhhcslpim: + jmp .L_small_initial_compute_done_454 +.L_small_initial_partial_block_454: @@ -63302,32 +63302,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vcdtlcyhhcslpim: +.L_small_initial_compute_done_454: orq %r8,%r8 - je .L_after_reduction_vcdtlcyhhcslpim + je .L_after_reduction_454 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vcdtlcyhhcslpim: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_5_gzwxEzzolteBiAA: +.L_after_reduction_454: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_5_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_epyzBzlcwuAirjx + jae .L_16_blocks_overflow_455 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_epyzBzlcwuAirjx + jmp .L_16_blocks_ok_455 -.L_16_blocks_overflow_epyzBzlcwuAirjx: +.L_16_blocks_overflow_455: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_epyzBzlcwuAirjx: +.L_16_blocks_ok_455: @@ -63439,7 +63439,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ewwaipyhlqonAgv + jl .L_small_initial_partial_block_456 @@ -63490,8 +63490,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ewwaipyhlqonAgv -.L_small_initial_partial_block_ewwaipyhlqonAgv: + jmp .L_small_initial_compute_done_456 +.L_small_initial_partial_block_456: @@ -63539,32 +63539,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ewwaipyhlqonAgv: +.L_small_initial_compute_done_456: orq %r8,%r8 - je .L_after_reduction_ewwaipyhlqonAgv + je .L_after_reduction_456 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ewwaipyhlqonAgv: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_6_gzwxEzzolteBiAA: +.L_after_reduction_456: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_6_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_hfzqDewGwcdnnFt + jae .L_16_blocks_overflow_457 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_hfzqDewGwcdnnFt + jmp .L_16_blocks_ok_457 -.L_16_blocks_overflow_hfzqDewGwcdnnFt: +.L_16_blocks_overflow_457: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_hfzqDewGwcdnnFt: +.L_16_blocks_ok_457: @@ -63676,7 +63676,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rfhgErpgCjmnfvn + jl .L_small_initial_partial_block_458 @@ -63727,8 +63727,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rfhgErpgCjmnfvn -.L_small_initial_partial_block_rfhgErpgCjmnfvn: + jmp .L_small_initial_compute_done_458 +.L_small_initial_partial_block_458: @@ -63782,32 +63782,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rfhgErpgCjmnfvn: +.L_small_initial_compute_done_458: orq %r8,%r8 - je .L_after_reduction_rfhgErpgCjmnfvn + je .L_after_reduction_458 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rfhgErpgCjmnfvn: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_7_gzwxEzzolteBiAA: +.L_after_reduction_458: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_7_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_quhdBifmvgvjvmD + jae .L_16_blocks_overflow_459 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_quhdBifmvgvjvmD + jmp .L_16_blocks_ok_459 -.L_16_blocks_overflow_quhdBifmvgvjvmD: +.L_16_blocks_overflow_459: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_quhdBifmvgvjvmD: +.L_16_blocks_ok_459: @@ -63919,7 +63919,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BFzjGFbnGgEEFao + jl .L_small_initial_partial_block_460 @@ -63971,8 +63971,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BFzjGFbnGgEEFao -.L_small_initial_partial_block_BFzjGFbnGgEEFao: + jmp .L_small_initial_compute_done_460 +.L_small_initial_partial_block_460: @@ -64026,32 +64026,32 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BFzjGFbnGgEEFao: +.L_small_initial_compute_done_460: orq %r8,%r8 - je .L_after_reduction_BFzjGFbnGgEEFao + je .L_after_reduction_460 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BFzjGFbnGgEEFao: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_8_gzwxEzzolteBiAA: +.L_after_reduction_460: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_8_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_gyktrCtEnzizCBy + jae .L_16_blocks_overflow_461 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_gyktrCtEnzizCBy + jmp .L_16_blocks_ok_461 -.L_16_blocks_overflow_gyktrCtEnzizCBy: +.L_16_blocks_overflow_461: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_gyktrCtEnzizCBy: +.L_16_blocks_ok_461: @@ -64163,7 +64163,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ayCAbzwEahEemyi + jl .L_small_initial_partial_block_462 @@ -64217,8 +64217,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ayCAbzwEahEemyi -.L_small_initial_partial_block_ayCAbzwEahEemyi: + jmp .L_small_initial_compute_done_462 +.L_small_initial_partial_block_462: @@ -64273,26 +64273,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ayCAbzwEahEemyi: +.L_small_initial_compute_done_462: orq %r8,%r8 - je .L_after_reduction_ayCAbzwEahEemyi + je .L_after_reduction_462 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ayCAbzwEahEemyi: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_9_gzwxEzzolteBiAA: +.L_after_reduction_462: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_9_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_wzjqGnDrxpicBig + jae .L_16_blocks_overflow_463 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_wzjqGnDrxpicBig + jmp .L_16_blocks_ok_463 -.L_16_blocks_overflow_wzjqGnDrxpicBig: +.L_16_blocks_overflow_463: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -64301,7 +64301,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_wzjqGnDrxpicBig: +.L_16_blocks_ok_463: @@ -64432,7 +64432,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ftkjfEfnyyBmcdc + jl .L_small_initial_partial_block_464 @@ -64492,8 +64492,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ftkjfEfnyyBmcdc -.L_small_initial_partial_block_ftkjfEfnyyBmcdc: + jmp .L_small_initial_compute_done_464 +.L_small_initial_partial_block_464: @@ -64550,26 +64550,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ftkjfEfnyyBmcdc: +.L_small_initial_compute_done_464: orq %r8,%r8 - je .L_after_reduction_ftkjfEfnyyBmcdc + je .L_after_reduction_464 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ftkjfEfnyyBmcdc: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_10_gzwxEzzolteBiAA: +.L_after_reduction_464: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_10_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_obhoAlGGxdmtiFr + jae .L_16_blocks_overflow_465 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_obhoAlGGxdmtiFr + jmp .L_16_blocks_ok_465 -.L_16_blocks_overflow_obhoAlGGxdmtiFr: +.L_16_blocks_overflow_465: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -64578,7 +64578,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_obhoAlGGxdmtiFr: +.L_16_blocks_ok_465: @@ -64709,7 +64709,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_swwkphiridauobp + jl .L_small_initial_partial_block_466 @@ -64769,8 +64769,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_swwkphiridauobp -.L_small_initial_partial_block_swwkphiridauobp: + jmp .L_small_initial_compute_done_466 +.L_small_initial_partial_block_466: @@ -64833,26 +64833,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_swwkphiridauobp: +.L_small_initial_compute_done_466: orq %r8,%r8 - je .L_after_reduction_swwkphiridauobp + je .L_after_reduction_466 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_swwkphiridauobp: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_11_gzwxEzzolteBiAA: +.L_after_reduction_466: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_11_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_pfabBBAcckzFwtp + jae .L_16_blocks_overflow_467 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_pfabBBAcckzFwtp + jmp .L_16_blocks_ok_467 -.L_16_blocks_overflow_pfabBBAcckzFwtp: +.L_16_blocks_overflow_467: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -64861,7 +64861,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_pfabBBAcckzFwtp: +.L_16_blocks_ok_467: @@ -64992,7 +64992,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sEDmGoxjAfppati + jl .L_small_initial_partial_block_468 @@ -65053,8 +65053,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sEDmGoxjAfppati -.L_small_initial_partial_block_sEDmGoxjAfppati: + jmp .L_small_initial_compute_done_468 +.L_small_initial_partial_block_468: @@ -65117,26 +65117,26 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sEDmGoxjAfppati: +.L_small_initial_compute_done_468: orq %r8,%r8 - je .L_after_reduction_sEDmGoxjAfppati + je .L_after_reduction_468 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sEDmGoxjAfppati: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_12_gzwxEzzolteBiAA: +.L_after_reduction_468: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_12_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_EoqzDusxkBytzvg + jae .L_16_blocks_overflow_469 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_EoqzDusxkBytzvg + jmp .L_16_blocks_ok_469 -.L_16_blocks_overflow_EoqzDusxkBytzvg: +.L_16_blocks_overflow_469: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -65145,7 +65145,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_EoqzDusxkBytzvg: +.L_16_blocks_ok_469: @@ -65276,7 +65276,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zCBwarExqmDnwjF + jl .L_small_initial_partial_block_470 @@ -65335,8 +65335,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zCBwarExqmDnwjF -.L_small_initial_partial_block_zCBwarExqmDnwjF: + jmp .L_small_initial_compute_done_470 +.L_small_initial_partial_block_470: @@ -65400,27 +65400,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zCBwarExqmDnwjF: +.L_small_initial_compute_done_470: orq %r8,%r8 - je .L_after_reduction_zCBwarExqmDnwjF + je .L_after_reduction_470 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zCBwarExqmDnwjF: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_13_gzwxEzzolteBiAA: +.L_after_reduction_470: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_13_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_rBcDgiadkybFwbh + jae .L_16_blocks_overflow_471 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_rBcDgiadkybFwbh + jmp .L_16_blocks_ok_471 -.L_16_blocks_overflow_rBcDgiadkybFwbh: +.L_16_blocks_overflow_471: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -65431,7 +65431,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_rBcDgiadkybFwbh: +.L_16_blocks_ok_471: @@ -65581,7 +65581,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ydylEAhcuohxern + jl .L_small_initial_partial_block_472 @@ -65646,8 +65646,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ydylEAhcuohxern -.L_small_initial_partial_block_ydylEAhcuohxern: + jmp .L_small_initial_compute_done_472 +.L_small_initial_partial_block_472: @@ -65709,27 +65709,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ydylEAhcuohxern: +.L_small_initial_compute_done_472: orq %r8,%r8 - je .L_after_reduction_ydylEAhcuohxern + je .L_after_reduction_472 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ydylEAhcuohxern: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_14_gzwxEzzolteBiAA: +.L_after_reduction_472: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_14_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_DBissuDpEtBDdDq + jae .L_16_blocks_overflow_473 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_DBissuDpEtBDdDq + jmp .L_16_blocks_ok_473 -.L_16_blocks_overflow_DBissuDpEtBDdDq: +.L_16_blocks_overflow_473: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -65740,7 +65740,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_DBissuDpEtBDdDq: +.L_16_blocks_ok_473: @@ -65890,7 +65890,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_weAdFlpFlgBGvvF + jl .L_small_initial_partial_block_474 @@ -65955,8 +65955,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_weAdFlpFlgBGvvF -.L_small_initial_partial_block_weAdFlpFlgBGvvF: + jmp .L_small_initial_compute_done_474 +.L_small_initial_partial_block_474: @@ -66024,27 +66024,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_weAdFlpFlgBGvvF: +.L_small_initial_compute_done_474: orq %r8,%r8 - je .L_after_reduction_weAdFlpFlgBGvvF + je .L_after_reduction_474 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_weAdFlpFlgBGvvF: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_15_gzwxEzzolteBiAA: +.L_after_reduction_474: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_15_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_kAohyzDDrpCdCbB + jae .L_16_blocks_overflow_475 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_kAohyzDDrpCdCbB + jmp .L_16_blocks_ok_475 -.L_16_blocks_overflow_kAohyzDDrpCdCbB: +.L_16_blocks_overflow_475: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -66055,7 +66055,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_kAohyzDDrpCdCbB: +.L_16_blocks_ok_475: @@ -66205,7 +66205,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wzGGqcpiEhzftDp + jl .L_small_initial_partial_block_476 @@ -66271,8 +66271,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wzGGqcpiEhzftDp -.L_small_initial_partial_block_wzGGqcpiEhzftDp: + jmp .L_small_initial_compute_done_476 +.L_small_initial_partial_block_476: @@ -66340,27 +66340,27 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wzGGqcpiEhzftDp: +.L_small_initial_compute_done_476: orq %r8,%r8 - je .L_after_reduction_wzGGqcpiEhzftDp + je .L_after_reduction_476 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wzGGqcpiEhzftDp: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_16_gzwxEzzolteBiAA: +.L_after_reduction_476: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_16_446: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_nEnxAgcqwpiizwh + jae .L_16_blocks_overflow_477 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_nEnxAgcqwpiizwh + jmp .L_16_blocks_ok_477 -.L_16_blocks_overflow_nEnxAgcqwpiizwh: +.L_16_blocks_overflow_477: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -66371,7 +66371,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_nEnxAgcqwpiizwh: +.L_16_blocks_ok_477: @@ -66518,7 +66518,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_pysGjAasElzftre: +.L_small_initial_partial_block_478: @@ -66587,11 +66587,11 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_pysGjAasElzftre: +.L_small_initial_compute_done_478: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_pysGjAasElzftre: - jmp .L_last_blocks_done_gzwxEzzolteBiAA -.L_last_num_blocks_is_0_gzwxEzzolteBiAA: +.L_after_reduction_478: + jmp .L_last_blocks_done_446 +.L_last_num_blocks_is_0_446: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -66653,65 +66653,65 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_gzwxEzzolteBiAA: +.L_last_blocks_done_446: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_iygyqoBzBDrEGDx + jmp .L_ghash_done_334 -.L_message_below_equal_16_blocks_iygyqoBzBDrEGDx: +.L_message_below_equal_16_blocks_334: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_fjkhbFvywuClvDi - jl .L_small_initial_num_blocks_is_7_1_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_8_479 + jl .L_small_initial_num_blocks_is_7_1_479 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_fjkhbFvywuClvDi - jl .L_small_initial_num_blocks_is_11_9_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_12_479 + jl .L_small_initial_num_blocks_is_11_9_479 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_16_479 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_15_479 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_fjkhbFvywuClvDi - jmp .L_small_initial_num_blocks_is_13_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_14_479 + jmp .L_small_initial_num_blocks_is_13_479 -.L_small_initial_num_blocks_is_11_9_fjkhbFvywuClvDi: +.L_small_initial_num_blocks_is_11_9_479: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_11_479 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_fjkhbFvywuClvDi - jmp .L_small_initial_num_blocks_is_9_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_10_479 + jmp .L_small_initial_num_blocks_is_9_479 -.L_small_initial_num_blocks_is_7_1_fjkhbFvywuClvDi: +.L_small_initial_num_blocks_is_7_1_479: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_fjkhbFvywuClvDi - jl .L_small_initial_num_blocks_is_3_1_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_4_479 + jl .L_small_initial_num_blocks_is_3_1_479 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_7_479 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_fjkhbFvywuClvDi - jmp .L_small_initial_num_blocks_is_5_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_6_479 + jmp .L_small_initial_num_blocks_is_5_479 -.L_small_initial_num_blocks_is_3_1_fjkhbFvywuClvDi: +.L_small_initial_num_blocks_is_3_1_479: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_3_479 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_fjkhbFvywuClvDi + je .L_small_initial_num_blocks_is_2_479 -.L_small_initial_num_blocks_is_1_fjkhbFvywuClvDi: +.L_small_initial_num_blocks_is_1_479: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -66760,7 +66760,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tqqgaGflmBqowhn + jl .L_small_initial_partial_block_480 @@ -66802,8 +66802,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tqqgaGflmBqowhn -.L_small_initial_partial_block_tqqgaGflmBqowhn: + jmp .L_small_initial_compute_done_480 +.L_small_initial_partial_block_480: @@ -66827,11 +66827,11 @@ ossl_aes_gcm_encrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_tqqgaGflmBqowhn -.L_small_initial_compute_done_tqqgaGflmBqowhn: -.L_after_reduction_tqqgaGflmBqowhn: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_2_fjkhbFvywuClvDi: + jmp .L_after_reduction_480 +.L_small_initial_compute_done_480: +.L_after_reduction_480: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_2_479: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -66882,7 +66882,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jaewgcmucxndegx + jl .L_small_initial_partial_block_481 @@ -66924,8 +66924,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jaewgcmucxndegx -.L_small_initial_partial_block_jaewgcmucxndegx: + jmp .L_small_initial_compute_done_481 +.L_small_initial_partial_block_481: @@ -66970,14 +66970,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jaewgcmucxndegx: +.L_small_initial_compute_done_481: orq %r8,%r8 - je .L_after_reduction_jaewgcmucxndegx + je .L_after_reduction_481 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_jaewgcmucxndegx: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_3_fjkhbFvywuClvDi: +.L_after_reduction_481: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_3_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67028,7 +67028,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AueghshnrfcFmfw + jl .L_small_initial_partial_block_482 @@ -67071,8 +67071,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AueghshnrfcFmfw -.L_small_initial_partial_block_AueghshnrfcFmfw: + jmp .L_small_initial_compute_done_482 +.L_small_initial_partial_block_482: @@ -67117,14 +67117,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AueghshnrfcFmfw: +.L_small_initial_compute_done_482: orq %r8,%r8 - je .L_after_reduction_AueghshnrfcFmfw + je .L_after_reduction_482 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_AueghshnrfcFmfw: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_4_fjkhbFvywuClvDi: +.L_after_reduction_482: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_4_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67175,7 +67175,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lrnwoafpFsiCueF + jl .L_small_initial_partial_block_483 @@ -67217,8 +67217,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lrnwoafpFsiCueF -.L_small_initial_partial_block_lrnwoafpFsiCueF: + jmp .L_small_initial_compute_done_483 +.L_small_initial_partial_block_483: @@ -67264,14 +67264,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lrnwoafpFsiCueF: +.L_small_initial_compute_done_483: orq %r8,%r8 - je .L_after_reduction_lrnwoafpFsiCueF + je .L_after_reduction_483 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_lrnwoafpFsiCueF: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_5_fjkhbFvywuClvDi: +.L_after_reduction_483: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_5_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67344,7 +67344,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zfmzgwhDvmGdAnD + jl .L_small_initial_partial_block_484 @@ -67396,8 +67396,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zfmzgwhDvmGdAnD -.L_small_initial_partial_block_zfmzgwhDvmGdAnD: + jmp .L_small_initial_compute_done_484 +.L_small_initial_partial_block_484: @@ -67442,14 +67442,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zfmzgwhDvmGdAnD: +.L_small_initial_compute_done_484: orq %r8,%r8 - je .L_after_reduction_zfmzgwhDvmGdAnD + je .L_after_reduction_484 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_zfmzgwhDvmGdAnD: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_6_fjkhbFvywuClvDi: +.L_after_reduction_484: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_6_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67522,7 +67522,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_emcBAFyAwubDAvm + jl .L_small_initial_partial_block_485 @@ -67574,8 +67574,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_emcBAFyAwubDAvm -.L_small_initial_partial_block_emcBAFyAwubDAvm: + jmp .L_small_initial_compute_done_485 +.L_small_initial_partial_block_485: @@ -67630,14 +67630,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_emcBAFyAwubDAvm: +.L_small_initial_compute_done_485: orq %r8,%r8 - je .L_after_reduction_emcBAFyAwubDAvm + je .L_after_reduction_485 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_emcBAFyAwubDAvm: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_7_fjkhbFvywuClvDi: +.L_after_reduction_485: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_7_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67710,7 +67710,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lFpqvebAgebnlul + jl .L_small_initial_partial_block_486 @@ -67763,8 +67763,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lFpqvebAgebnlul -.L_small_initial_partial_block_lFpqvebAgebnlul: + jmp .L_small_initial_compute_done_486 +.L_small_initial_partial_block_486: @@ -67819,14 +67819,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lFpqvebAgebnlul: +.L_small_initial_compute_done_486: orq %r8,%r8 - je .L_after_reduction_lFpqvebAgebnlul + je .L_after_reduction_486 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_lFpqvebAgebnlul: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_8_fjkhbFvywuClvDi: +.L_after_reduction_486: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_8_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -67899,7 +67899,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rqhAzAClokAbGve + jl .L_small_initial_partial_block_487 @@ -67950,8 +67950,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rqhAzAClokAbGve -.L_small_initial_partial_block_rqhAzAClokAbGve: + jmp .L_small_initial_compute_done_487 +.L_small_initial_partial_block_487: @@ -68007,14 +68007,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rqhAzAClokAbGve: +.L_small_initial_compute_done_487: orq %r8,%r8 - je .L_after_reduction_rqhAzAClokAbGve + je .L_after_reduction_487 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_rqhAzAClokAbGve: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_9_fjkhbFvywuClvDi: +.L_after_reduction_487: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_9_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -68108,7 +68108,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cuwvipptyzcGaqy + jl .L_small_initial_partial_block_488 @@ -68169,8 +68169,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cuwvipptyzcGaqy -.L_small_initial_partial_block_cuwvipptyzcGaqy: + jmp .L_small_initial_compute_done_488 +.L_small_initial_partial_block_488: @@ -68224,14 +68224,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cuwvipptyzcGaqy: +.L_small_initial_compute_done_488: orq %r8,%r8 - je .L_after_reduction_cuwvipptyzcGaqy + je .L_after_reduction_488 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_cuwvipptyzcGaqy: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_10_fjkhbFvywuClvDi: +.L_after_reduction_488: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_10_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -68325,7 +68325,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ooyjhummfFduyai + jl .L_small_initial_partial_block_489 @@ -68386,8 +68386,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ooyjhummfFduyai -.L_small_initial_partial_block_ooyjhummfFduyai: + jmp .L_small_initial_compute_done_489 +.L_small_initial_partial_block_489: @@ -68451,14 +68451,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ooyjhummfFduyai: +.L_small_initial_compute_done_489: orq %r8,%r8 - je .L_after_reduction_ooyjhummfFduyai + je .L_after_reduction_489 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ooyjhummfFduyai: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_11_fjkhbFvywuClvDi: +.L_after_reduction_489: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_11_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -68552,7 +68552,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xsddqtyfukjktdn + jl .L_small_initial_partial_block_490 @@ -68614,8 +68614,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xsddqtyfukjktdn -.L_small_initial_partial_block_xsddqtyfukjktdn: + jmp .L_small_initial_compute_done_490 +.L_small_initial_partial_block_490: @@ -68679,14 +68679,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xsddqtyfukjktdn: +.L_small_initial_compute_done_490: orq %r8,%r8 - je .L_after_reduction_xsddqtyfukjktdn + je .L_after_reduction_490 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_xsddqtyfukjktdn: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_12_fjkhbFvywuClvDi: +.L_after_reduction_490: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_12_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -68780,7 +68780,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jgFhnerFhcnkGrE + jl .L_small_initial_partial_block_491 @@ -68836,8 +68836,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jgFhnerFhcnkGrE -.L_small_initial_partial_block_jgFhnerFhcnkGrE: + jmp .L_small_initial_compute_done_491 +.L_small_initial_partial_block_491: @@ -68902,14 +68902,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jgFhnerFhcnkGrE: +.L_small_initial_compute_done_491: orq %r8,%r8 - je .L_after_reduction_jgFhnerFhcnkGrE + je .L_after_reduction_491 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_jgFhnerFhcnkGrE: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_13_fjkhbFvywuClvDi: +.L_after_reduction_491: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_13_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -69024,7 +69024,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BDqmwyidnAqtBwp + jl .L_small_initial_partial_block_492 @@ -69090,8 +69090,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BDqmwyidnAqtBwp -.L_small_initial_partial_block_BDqmwyidnAqtBwp: + jmp .L_small_initial_compute_done_492 +.L_small_initial_partial_block_492: @@ -69150,14 +69150,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BDqmwyidnAqtBwp: +.L_small_initial_compute_done_492: orq %r8,%r8 - je .L_after_reduction_BDqmwyidnAqtBwp + je .L_after_reduction_492 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_BDqmwyidnAqtBwp: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_14_fjkhbFvywuClvDi: +.L_after_reduction_492: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_14_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -69272,7 +69272,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GwxcghxuEqoynDe + jl .L_small_initial_partial_block_493 @@ -69338,8 +69338,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GwxcghxuEqoynDe -.L_small_initial_partial_block_GwxcghxuEqoynDe: + jmp .L_small_initial_compute_done_493 +.L_small_initial_partial_block_493: @@ -69408,14 +69408,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GwxcghxuEqoynDe: +.L_small_initial_compute_done_493: orq %r8,%r8 - je .L_after_reduction_GwxcghxuEqoynDe + je .L_after_reduction_493 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_GwxcghxuEqoynDe: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_15_fjkhbFvywuClvDi: +.L_after_reduction_493: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_15_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -69530,7 +69530,7 @@ ossl_aes_gcm_encrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nEunfqrwpbdCwtA + jl .L_small_initial_partial_block_494 @@ -69597,8 +69597,8 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nEunfqrwpbdCwtA -.L_small_initial_partial_block_nEunfqrwpbdCwtA: + jmp .L_small_initial_compute_done_494 +.L_small_initial_partial_block_494: @@ -69667,14 +69667,14 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nEunfqrwpbdCwtA: +.L_small_initial_compute_done_494: orq %r8,%r8 - je .L_after_reduction_nEunfqrwpbdCwtA + je .L_after_reduction_494 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_nEunfqrwpbdCwtA: - jmp .L_small_initial_blocks_encrypted_fjkhbFvywuClvDi -.L_small_initial_num_blocks_is_16_fjkhbFvywuClvDi: +.L_after_reduction_494: + jmp .L_small_initial_blocks_encrypted_479 +.L_small_initial_num_blocks_is_16_479: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -69786,7 +69786,7 @@ ossl_aes_gcm_encrypt_avx512: vpshufb %zmm29,%zmm5,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_afkDoqpaFxxhmvw: +.L_small_initial_partial_block_495: @@ -69856,18 +69856,18 @@ ossl_aes_gcm_encrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_afkDoqpaFxxhmvw: +.L_small_initial_compute_done_495: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_afkDoqpaFxxhmvw: -.L_small_initial_blocks_encrypted_fjkhbFvywuClvDi: -.L_ghash_done_iygyqoBzBDrEGDx: +.L_after_reduction_495: +.L_small_initial_blocks_encrypted_479: +.L_ghash_done_334: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_iygyqoBzBDrEGDx: +.L_enc_dec_done_334: jmp .Lexit_gcm_encrypt .Lexit_gcm_encrypt: cmpq $256,%r8 - jbe .Lskip_hkeys_cleanup_nAzenDskcnmrwEb + jbe .Lskip_hkeys_cleanup_496 vpxor %xmm0,%xmm0,%xmm0 vmovdqa64 %zmm0,0(%rsp) vmovdqa64 %zmm0,64(%rsp) @@ -69881,7 +69881,7 @@ ossl_aes_gcm_encrypt_avx512: vmovdqa64 %zmm0,576(%rsp) vmovdqa64 %zmm0,640(%rsp) vmovdqa64 %zmm0,704(%rsp) -.Lskip_hkeys_cleanup_nAzenDskcnmrwEb: +.Lskip_hkeys_cleanup_496: vzeroupper leaq (%rbp),%rsp .cfi_def_cfa_register %rsp @@ -69969,13 +69969,13 @@ ossl_aes_gcm_decrypt_avx512: .align 32 .Laes_gcm_decrypt_128_avx512: orq %r8,%r8 - je .L_enc_dec_done_kpzgFwDvlzADzny + je .L_enc_dec_done_497 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_jAEgtiodweiEsqa + je .L_partial_block_done_498 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -69999,9 +69999,9 @@ ossl_aes_gcm_decrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_jAEgtiodweiEsqa + jge .L_no_extra_mask_498 subq %r13,%r12 -.L_no_extra_mask_jAEgtiodweiEsqa: +.L_no_extra_mask_498: @@ -70012,7 +70012,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %xmm5,%xmm6,%xmm6 vpxorq %xmm6,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_jAEgtiodweiEsqa + jl .L_partial_incomplete_498 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -70047,13 +70047,13 @@ ossl_aes_gcm_decrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_jAEgtiodweiEsqa + jmp .L_enc_dec_done_498 -.L_partial_incomplete_jAEgtiodweiEsqa: +.L_partial_incomplete_498: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_jAEgtiodweiEsqa: +.L_enc_dec_done_498: leaq byte_len_to_mask_table(%rip),%r12 @@ -70061,12 +70061,12 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 %xmm14,64(%rsi) movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_jAEgtiodweiEsqa: +.L_partial_block_done_498: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_kpzgFwDvlzADzny + je .L_enc_dec_done_497 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_kpzgFwDvlzADzny + jbe .L_message_below_equal_16_blocks_497 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -70086,13 +70086,13 @@ ossl_aes_gcm_decrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_dBeAgDgfbzxElcb + jae .L_next_16_overflow_499 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_dBeAgDgfbzxElcb -.L_next_16_overflow_dBeAgDgfbzxElcb: + jmp .L_next_16_ok_499 +.L_next_16_overflow_499: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -70103,7 +70103,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_dBeAgDgfbzxElcb: +.L_next_16_ok_499: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -70191,7 +70191,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_itkoyyqvjiztGGp + jnz .L_skip_hkeys_precomputation_500 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -70207,20 +70207,20 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_itkoyyqvjiztGGp: +.L_skip_hkeys_precomputation_500: cmpq $512,%r8 - jb .L_message_below_32_blocks_kpzgFwDvlzADzny + jb .L_message_below_32_blocks_497 cmpb $240,%r15b - jae .L_next_16_overflow_cDClwfcyajGjzdu + jae .L_next_16_overflow_501 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_cDClwfcyajGjzdu -.L_next_16_overflow_cDClwfcyajGjzdu: + jmp .L_next_16_ok_501 +.L_next_16_overflow_501: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -70231,7 +70231,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_cDClwfcyajGjzdu: +.L_next_16_ok_501: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -70319,7 +70319,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_kDBGpbFpykhbaBz + jnz .L_skip_hkeys_precomputation_502 vmovdqu64 640(%rsp),%zmm3 @@ -70567,22 +70567,22 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_kDBGpbFpykhbaBz: +.L_skip_hkeys_precomputation_502: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_kpzgFwDvlzADzny -.L_encrypt_big_nblocks_kpzgFwDvlzADzny: + jb .L_no_more_big_nblocks_497 +.L_encrypt_big_nblocks_497: cmpb $240,%r15b - jae .L_16_blocks_overflow_deetwmnmqriqGnl + jae .L_16_blocks_overflow_503 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_deetwmnmqriqGnl -.L_16_blocks_overflow_deetwmnmqriqGnl: + jmp .L_16_blocks_ok_503 +.L_16_blocks_overflow_503: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -70593,7 +70593,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_deetwmnmqriqGnl: +.L_16_blocks_ok_503: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -70758,13 +70758,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_imECwClsCdbxwmD + jae .L_16_blocks_overflow_504 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_imECwClsCdbxwmD -.L_16_blocks_overflow_imECwClsCdbxwmD: + jmp .L_16_blocks_ok_504 +.L_16_blocks_overflow_504: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -70775,7 +70775,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_imECwClsCdbxwmD: +.L_16_blocks_ok_504: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -70940,13 +70940,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_vcBkrdEmphAtbBl + jae .L_16_blocks_overflow_505 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_vcBkrdEmphAtbBl -.L_16_blocks_overflow_vcBkrdEmphAtbBl: + jmp .L_16_blocks_ok_505 +.L_16_blocks_overflow_505: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -70957,7 +70957,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_vcBkrdEmphAtbBl: +.L_16_blocks_ok_505: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -71152,16 +71152,16 @@ ossl_aes_gcm_decrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_kpzgFwDvlzADzny + jae .L_encrypt_big_nblocks_497 -.L_no_more_big_nblocks_kpzgFwDvlzADzny: +.L_no_more_big_nblocks_497: cmpq $512,%r8 - jae .L_encrypt_32_blocks_kpzgFwDvlzADzny + jae .L_encrypt_32_blocks_497 cmpq $256,%r8 - jae .L_encrypt_16_blocks_kpzgFwDvlzADzny -.L_encrypt_0_blocks_ghash_32_kpzgFwDvlzADzny: + jae .L_encrypt_16_blocks_497 +.L_encrypt_0_blocks_ghash_32_497: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -71204,61 +71204,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_eetGtppdondlGqv + je .L_last_num_blocks_is_0_506 cmpl $8,%r10d - je .L_last_num_blocks_is_8_eetGtppdondlGqv - jb .L_last_num_blocks_is_7_1_eetGtppdondlGqv + je .L_last_num_blocks_is_8_506 + jb .L_last_num_blocks_is_7_1_506 cmpl $12,%r10d - je .L_last_num_blocks_is_12_eetGtppdondlGqv - jb .L_last_num_blocks_is_11_9_eetGtppdondlGqv + je .L_last_num_blocks_is_12_506 + jb .L_last_num_blocks_is_11_9_506 cmpl $15,%r10d - je .L_last_num_blocks_is_15_eetGtppdondlGqv - ja .L_last_num_blocks_is_16_eetGtppdondlGqv + je .L_last_num_blocks_is_15_506 + ja .L_last_num_blocks_is_16_506 cmpl $14,%r10d - je .L_last_num_blocks_is_14_eetGtppdondlGqv - jmp .L_last_num_blocks_is_13_eetGtppdondlGqv + je .L_last_num_blocks_is_14_506 + jmp .L_last_num_blocks_is_13_506 -.L_last_num_blocks_is_11_9_eetGtppdondlGqv: +.L_last_num_blocks_is_11_9_506: cmpl $10,%r10d - je .L_last_num_blocks_is_10_eetGtppdondlGqv - ja .L_last_num_blocks_is_11_eetGtppdondlGqv - jmp .L_last_num_blocks_is_9_eetGtppdondlGqv + je .L_last_num_blocks_is_10_506 + ja .L_last_num_blocks_is_11_506 + jmp .L_last_num_blocks_is_9_506 -.L_last_num_blocks_is_7_1_eetGtppdondlGqv: +.L_last_num_blocks_is_7_1_506: cmpl $4,%r10d - je .L_last_num_blocks_is_4_eetGtppdondlGqv - jb .L_last_num_blocks_is_3_1_eetGtppdondlGqv + je .L_last_num_blocks_is_4_506 + jb .L_last_num_blocks_is_3_1_506 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_eetGtppdondlGqv - je .L_last_num_blocks_is_6_eetGtppdondlGqv - jmp .L_last_num_blocks_is_5_eetGtppdondlGqv + ja .L_last_num_blocks_is_7_506 + je .L_last_num_blocks_is_6_506 + jmp .L_last_num_blocks_is_5_506 -.L_last_num_blocks_is_3_1_eetGtppdondlGqv: +.L_last_num_blocks_is_3_1_506: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_eetGtppdondlGqv - je .L_last_num_blocks_is_2_eetGtppdondlGqv -.L_last_num_blocks_is_1_eetGtppdondlGqv: + ja .L_last_num_blocks_is_3_506 + je .L_last_num_blocks_is_2_506 +.L_last_num_blocks_is_1_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_gfjvCdibyncsraa + jae .L_16_blocks_overflow_507 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_gfjvCdibyncsraa + jmp .L_16_blocks_ok_507 -.L_16_blocks_overflow_gfjvCdibyncsraa: +.L_16_blocks_overflow_507: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_gfjvCdibyncsraa: +.L_16_blocks_ok_507: @@ -71342,7 +71342,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hbrfdwDhzcAtwls + jl .L_small_initial_partial_block_508 @@ -71386,8 +71386,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hbrfdwDhzcAtwls -.L_small_initial_partial_block_hbrfdwDhzcAtwls: + jmp .L_small_initial_compute_done_508 +.L_small_initial_partial_block_508: @@ -71439,24 +71439,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_hbrfdwDhzcAtwls -.L_small_initial_compute_done_hbrfdwDhzcAtwls: -.L_after_reduction_hbrfdwDhzcAtwls: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_2_eetGtppdondlGqv: + jmp .L_after_reduction_508 +.L_small_initial_compute_done_508: +.L_after_reduction_508: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_2_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_zmdmmyjEvqbznbA + jae .L_16_blocks_overflow_509 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_zmdmmyjEvqbznbA + jmp .L_16_blocks_ok_509 -.L_16_blocks_overflow_zmdmmyjEvqbznbA: +.L_16_blocks_overflow_509: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_zmdmmyjEvqbznbA: +.L_16_blocks_ok_509: @@ -71541,7 +71541,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cxdDliEcuurqbjq + jl .L_small_initial_partial_block_510 @@ -71585,8 +71585,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cxdDliEcuurqbjq -.L_small_initial_partial_block_cxdDliEcuurqbjq: + jmp .L_small_initial_compute_done_510 +.L_small_initial_partial_block_510: @@ -71633,27 +71633,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cxdDliEcuurqbjq: +.L_small_initial_compute_done_510: orq %r8,%r8 - je .L_after_reduction_cxdDliEcuurqbjq + je .L_after_reduction_510 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cxdDliEcuurqbjq: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_3_eetGtppdondlGqv: +.L_after_reduction_510: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_3_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_fhpDcEkfvbphmqF + jae .L_16_blocks_overflow_511 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_fhpDcEkfvbphmqF + jmp .L_16_blocks_ok_511 -.L_16_blocks_overflow_fhpDcEkfvbphmqF: +.L_16_blocks_overflow_511: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_fhpDcEkfvbphmqF: +.L_16_blocks_ok_511: @@ -71738,7 +71738,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hqqbsqetGCAvupc + jl .L_small_initial_partial_block_512 @@ -71783,8 +71783,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hqqbsqetGCAvupc -.L_small_initial_partial_block_hqqbsqetGCAvupc: + jmp .L_small_initial_compute_done_512 +.L_small_initial_partial_block_512: @@ -71831,27 +71831,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hqqbsqetGCAvupc: +.L_small_initial_compute_done_512: orq %r8,%r8 - je .L_after_reduction_hqqbsqetGCAvupc + je .L_after_reduction_512 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hqqbsqetGCAvupc: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_4_eetGtppdondlGqv: +.L_after_reduction_512: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_4_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_ibBbgCccGjgpvDh + jae .L_16_blocks_overflow_513 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_ibBbgCccGjgpvDh + jmp .L_16_blocks_ok_513 -.L_16_blocks_overflow_ibBbgCccGjgpvDh: +.L_16_blocks_overflow_513: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_ibBbgCccGjgpvDh: +.L_16_blocks_ok_513: @@ -71936,7 +71936,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mkdzdutAvqxDjfn + jl .L_small_initial_partial_block_514 @@ -71981,8 +71981,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mkdzdutAvqxDjfn -.L_small_initial_partial_block_mkdzdutAvqxDjfn: + jmp .L_small_initial_compute_done_514 +.L_small_initial_partial_block_514: @@ -72030,32 +72030,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mkdzdutAvqxDjfn: +.L_small_initial_compute_done_514: orq %r8,%r8 - je .L_after_reduction_mkdzdutAvqxDjfn + je .L_after_reduction_514 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mkdzdutAvqxDjfn: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_5_eetGtppdondlGqv: +.L_after_reduction_514: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_5_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_EFEnlhckpgCFbdm + jae .L_16_blocks_overflow_515 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_EFEnlhckpgCFbdm + jmp .L_16_blocks_ok_515 -.L_16_blocks_overflow_EFEnlhckpgCFbdm: +.L_16_blocks_overflow_515: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_EFEnlhckpgCFbdm: +.L_16_blocks_ok_515: @@ -72155,7 +72155,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wbCqsrblzsrfFid + jl .L_small_initial_partial_block_516 @@ -72206,8 +72206,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wbCqsrblzsrfFid -.L_small_initial_partial_block_wbCqsrblzsrfFid: + jmp .L_small_initial_compute_done_516 +.L_small_initial_partial_block_516: @@ -72255,32 +72255,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wbCqsrblzsrfFid: +.L_small_initial_compute_done_516: orq %r8,%r8 - je .L_after_reduction_wbCqsrblzsrfFid + je .L_after_reduction_516 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wbCqsrblzsrfFid: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_6_eetGtppdondlGqv: +.L_after_reduction_516: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_6_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_ofmxlpECjwwAkgo + jae .L_16_blocks_overflow_517 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_ofmxlpECjwwAkgo + jmp .L_16_blocks_ok_517 -.L_16_blocks_overflow_ofmxlpECjwwAkgo: +.L_16_blocks_overflow_517: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_ofmxlpECjwwAkgo: +.L_16_blocks_ok_517: @@ -72380,7 +72380,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wwbqxuzhtAlfqta + jl .L_small_initial_partial_block_518 @@ -72431,8 +72431,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wwbqxuzhtAlfqta -.L_small_initial_partial_block_wwbqxuzhtAlfqta: + jmp .L_small_initial_compute_done_518 +.L_small_initial_partial_block_518: @@ -72486,32 +72486,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wwbqxuzhtAlfqta: +.L_small_initial_compute_done_518: orq %r8,%r8 - je .L_after_reduction_wwbqxuzhtAlfqta + je .L_after_reduction_518 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wwbqxuzhtAlfqta: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_7_eetGtppdondlGqv: +.L_after_reduction_518: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_7_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_bqdqbesqojlslco + jae .L_16_blocks_overflow_519 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_bqdqbesqojlslco + jmp .L_16_blocks_ok_519 -.L_16_blocks_overflow_bqdqbesqojlslco: +.L_16_blocks_overflow_519: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_bqdqbesqojlslco: +.L_16_blocks_ok_519: @@ -72611,7 +72611,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_bAxjwxmixvpFnqD + jl .L_small_initial_partial_block_520 @@ -72663,8 +72663,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_bAxjwxmixvpFnqD -.L_small_initial_partial_block_bAxjwxmixvpFnqD: + jmp .L_small_initial_compute_done_520 +.L_small_initial_partial_block_520: @@ -72718,32 +72718,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_bAxjwxmixvpFnqD: +.L_small_initial_compute_done_520: orq %r8,%r8 - je .L_after_reduction_bAxjwxmixvpFnqD + je .L_after_reduction_520 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_bAxjwxmixvpFnqD: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_8_eetGtppdondlGqv: +.L_after_reduction_520: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_8_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_pBytEyeqaDrikcE + jae .L_16_blocks_overflow_521 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_pBytEyeqaDrikcE + jmp .L_16_blocks_ok_521 -.L_16_blocks_overflow_pBytEyeqaDrikcE: +.L_16_blocks_overflow_521: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_pBytEyeqaDrikcE: +.L_16_blocks_ok_521: @@ -72843,7 +72843,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mdBakavzFGwGxqB + jl .L_small_initial_partial_block_522 @@ -72897,8 +72897,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mdBakavzFGwGxqB -.L_small_initial_partial_block_mdBakavzFGwGxqB: + jmp .L_small_initial_compute_done_522 +.L_small_initial_partial_block_522: @@ -72953,26 +72953,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mdBakavzFGwGxqB: +.L_small_initial_compute_done_522: orq %r8,%r8 - je .L_after_reduction_mdBakavzFGwGxqB + je .L_after_reduction_522 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mdBakavzFGwGxqB: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_9_eetGtppdondlGqv: +.L_after_reduction_522: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_9_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_hmojuwGlwprmzBx + jae .L_16_blocks_overflow_523 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_hmojuwGlwprmzBx + jmp .L_16_blocks_ok_523 -.L_16_blocks_overflow_hmojuwGlwprmzBx: +.L_16_blocks_overflow_523: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -72981,7 +72981,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_hmojuwGlwprmzBx: +.L_16_blocks_ok_523: @@ -73096,7 +73096,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yCzpGsDmAEfywvj + jl .L_small_initial_partial_block_524 @@ -73156,8 +73156,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yCzpGsDmAEfywvj -.L_small_initial_partial_block_yCzpGsDmAEfywvj: + jmp .L_small_initial_compute_done_524 +.L_small_initial_partial_block_524: @@ -73214,26 +73214,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yCzpGsDmAEfywvj: +.L_small_initial_compute_done_524: orq %r8,%r8 - je .L_after_reduction_yCzpGsDmAEfywvj + je .L_after_reduction_524 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yCzpGsDmAEfywvj: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_10_eetGtppdondlGqv: +.L_after_reduction_524: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_10_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_yECjfywmbFnxacs + jae .L_16_blocks_overflow_525 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_yECjfywmbFnxacs + jmp .L_16_blocks_ok_525 -.L_16_blocks_overflow_yECjfywmbFnxacs: +.L_16_blocks_overflow_525: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -73242,7 +73242,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_yECjfywmbFnxacs: +.L_16_blocks_ok_525: @@ -73357,7 +73357,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jaFAxycEEajiDjd + jl .L_small_initial_partial_block_526 @@ -73417,8 +73417,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jaFAxycEEajiDjd -.L_small_initial_partial_block_jaFAxycEEajiDjd: + jmp .L_small_initial_compute_done_526 +.L_small_initial_partial_block_526: @@ -73481,26 +73481,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jaFAxycEEajiDjd: +.L_small_initial_compute_done_526: orq %r8,%r8 - je .L_after_reduction_jaFAxycEEajiDjd + je .L_after_reduction_526 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jaFAxycEEajiDjd: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_11_eetGtppdondlGqv: +.L_after_reduction_526: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_11_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_DzGftfvrohzEhyD + jae .L_16_blocks_overflow_527 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_DzGftfvrohzEhyD + jmp .L_16_blocks_ok_527 -.L_16_blocks_overflow_DzGftfvrohzEhyD: +.L_16_blocks_overflow_527: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -73509,7 +73509,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_DzGftfvrohzEhyD: +.L_16_blocks_ok_527: @@ -73624,7 +73624,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_odtqaBajmorEoen + jl .L_small_initial_partial_block_528 @@ -73685,8 +73685,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_odtqaBajmorEoen -.L_small_initial_partial_block_odtqaBajmorEoen: + jmp .L_small_initial_compute_done_528 +.L_small_initial_partial_block_528: @@ -73749,26 +73749,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_odtqaBajmorEoen: +.L_small_initial_compute_done_528: orq %r8,%r8 - je .L_after_reduction_odtqaBajmorEoen + je .L_after_reduction_528 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_odtqaBajmorEoen: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_12_eetGtppdondlGqv: +.L_after_reduction_528: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_12_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_riyhqpywrEoeomv + jae .L_16_blocks_overflow_529 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_riyhqpywrEoeomv + jmp .L_16_blocks_ok_529 -.L_16_blocks_overflow_riyhqpywrEoeomv: +.L_16_blocks_overflow_529: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -73777,7 +73777,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_riyhqpywrEoeomv: +.L_16_blocks_ok_529: @@ -73892,7 +73892,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vlCDEfDvrfvBGyx + jl .L_small_initial_partial_block_530 @@ -73951,8 +73951,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vlCDEfDvrfvBGyx -.L_small_initial_partial_block_vlCDEfDvrfvBGyx: + jmp .L_small_initial_compute_done_530 +.L_small_initial_partial_block_530: @@ -74016,27 +74016,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vlCDEfDvrfvBGyx: +.L_small_initial_compute_done_530: orq %r8,%r8 - je .L_after_reduction_vlCDEfDvrfvBGyx + je .L_after_reduction_530 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vlCDEfDvrfvBGyx: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_13_eetGtppdondlGqv: +.L_after_reduction_530: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_13_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_EqDCyFGsCaxyrow + jae .L_16_blocks_overflow_531 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_EqDCyFGsCaxyrow + jmp .L_16_blocks_ok_531 -.L_16_blocks_overflow_EqDCyFGsCaxyrow: +.L_16_blocks_overflow_531: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -74047,7 +74047,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_EqDCyFGsCaxyrow: +.L_16_blocks_ok_531: @@ -74177,7 +74177,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mbzeFuuElnsbsig + jl .L_small_initial_partial_block_532 @@ -74242,8 +74242,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mbzeFuuElnsbsig -.L_small_initial_partial_block_mbzeFuuElnsbsig: + jmp .L_small_initial_compute_done_532 +.L_small_initial_partial_block_532: @@ -74305,27 +74305,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mbzeFuuElnsbsig: +.L_small_initial_compute_done_532: orq %r8,%r8 - je .L_after_reduction_mbzeFuuElnsbsig + je .L_after_reduction_532 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mbzeFuuElnsbsig: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_14_eetGtppdondlGqv: +.L_after_reduction_532: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_14_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_DCshtwrrnawpAxD + jae .L_16_blocks_overflow_533 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_DCshtwrrnawpAxD + jmp .L_16_blocks_ok_533 -.L_16_blocks_overflow_DCshtwrrnawpAxD: +.L_16_blocks_overflow_533: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -74336,7 +74336,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_DCshtwrrnawpAxD: +.L_16_blocks_ok_533: @@ -74466,7 +74466,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tkcxpjEmpqwbvej + jl .L_small_initial_partial_block_534 @@ -74531,8 +74531,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tkcxpjEmpqwbvej -.L_small_initial_partial_block_tkcxpjEmpqwbvej: + jmp .L_small_initial_compute_done_534 +.L_small_initial_partial_block_534: @@ -74600,27 +74600,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tkcxpjEmpqwbvej: +.L_small_initial_compute_done_534: orq %r8,%r8 - je .L_after_reduction_tkcxpjEmpqwbvej + je .L_after_reduction_534 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tkcxpjEmpqwbvej: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_15_eetGtppdondlGqv: +.L_after_reduction_534: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_15_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_tcsnnmGfovEcooE + jae .L_16_blocks_overflow_535 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_tcsnnmGfovEcooE + jmp .L_16_blocks_ok_535 -.L_16_blocks_overflow_tcsnnmGfovEcooE: +.L_16_blocks_overflow_535: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -74631,7 +74631,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_tcsnnmGfovEcooE: +.L_16_blocks_ok_535: @@ -74761,7 +74761,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oAusysBjjifDnDf + jl .L_small_initial_partial_block_536 @@ -74827,8 +74827,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oAusysBjjifDnDf -.L_small_initial_partial_block_oAusysBjjifDnDf: + jmp .L_small_initial_compute_done_536 +.L_small_initial_partial_block_536: @@ -74896,27 +74896,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oAusysBjjifDnDf: +.L_small_initial_compute_done_536: orq %r8,%r8 - je .L_after_reduction_oAusysBjjifDnDf + je .L_after_reduction_536 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_oAusysBjjifDnDf: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_16_eetGtppdondlGqv: +.L_after_reduction_536: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_16_506: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_ctsDzhEDzaqcpuo + jae .L_16_blocks_overflow_537 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ctsDzhEDzaqcpuo + jmp .L_16_blocks_ok_537 -.L_16_blocks_overflow_ctsDzhEDzaqcpuo: +.L_16_blocks_overflow_537: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -74927,7 +74927,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ctsDzhEDzaqcpuo: +.L_16_blocks_ok_537: @@ -75054,7 +75054,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_FjCifaBakmzlfFC: +.L_small_initial_partial_block_538: @@ -75123,11 +75123,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FjCifaBakmzlfFC: +.L_small_initial_compute_done_538: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FjCifaBakmzlfFC: - jmp .L_last_blocks_done_eetGtppdondlGqv -.L_last_num_blocks_is_0_eetGtppdondlGqv: +.L_after_reduction_538: + jmp .L_last_blocks_done_506 +.L_last_num_blocks_is_0_506: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -75188,18 +75188,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_eetGtppdondlGqv: +.L_last_blocks_done_506: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_kpzgFwDvlzADzny -.L_encrypt_32_blocks_kpzgFwDvlzADzny: + jmp .L_ghash_done_497 +.L_encrypt_32_blocks_497: cmpb $240,%r15b - jae .L_16_blocks_overflow_zopmdpdnBxlEnBB + jae .L_16_blocks_overflow_539 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_zopmdpdnBxlEnBB -.L_16_blocks_overflow_zopmdpdnBxlEnBB: + jmp .L_16_blocks_ok_539 +.L_16_blocks_overflow_539: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -75210,7 +75210,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_zopmdpdnBxlEnBB: +.L_16_blocks_ok_539: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -75375,13 +75375,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_ptlkwckkbgnbseE + jae .L_16_blocks_overflow_540 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ptlkwckkbgnbseE -.L_16_blocks_overflow_ptlkwckkbgnbseE: + jmp .L_16_blocks_ok_540 +.L_16_blocks_overflow_540: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -75392,7 +75392,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ptlkwckkbgnbseE: +.L_16_blocks_ok_540: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -75625,61 +75625,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_naArnppmugyrAeq + je .L_last_num_blocks_is_0_541 cmpl $8,%r10d - je .L_last_num_blocks_is_8_naArnppmugyrAeq - jb .L_last_num_blocks_is_7_1_naArnppmugyrAeq + je .L_last_num_blocks_is_8_541 + jb .L_last_num_blocks_is_7_1_541 cmpl $12,%r10d - je .L_last_num_blocks_is_12_naArnppmugyrAeq - jb .L_last_num_blocks_is_11_9_naArnppmugyrAeq + je .L_last_num_blocks_is_12_541 + jb .L_last_num_blocks_is_11_9_541 cmpl $15,%r10d - je .L_last_num_blocks_is_15_naArnppmugyrAeq - ja .L_last_num_blocks_is_16_naArnppmugyrAeq + je .L_last_num_blocks_is_15_541 + ja .L_last_num_blocks_is_16_541 cmpl $14,%r10d - je .L_last_num_blocks_is_14_naArnppmugyrAeq - jmp .L_last_num_blocks_is_13_naArnppmugyrAeq + je .L_last_num_blocks_is_14_541 + jmp .L_last_num_blocks_is_13_541 -.L_last_num_blocks_is_11_9_naArnppmugyrAeq: +.L_last_num_blocks_is_11_9_541: cmpl $10,%r10d - je .L_last_num_blocks_is_10_naArnppmugyrAeq - ja .L_last_num_blocks_is_11_naArnppmugyrAeq - jmp .L_last_num_blocks_is_9_naArnppmugyrAeq + je .L_last_num_blocks_is_10_541 + ja .L_last_num_blocks_is_11_541 + jmp .L_last_num_blocks_is_9_541 -.L_last_num_blocks_is_7_1_naArnppmugyrAeq: +.L_last_num_blocks_is_7_1_541: cmpl $4,%r10d - je .L_last_num_blocks_is_4_naArnppmugyrAeq - jb .L_last_num_blocks_is_3_1_naArnppmugyrAeq + je .L_last_num_blocks_is_4_541 + jb .L_last_num_blocks_is_3_1_541 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_naArnppmugyrAeq - je .L_last_num_blocks_is_6_naArnppmugyrAeq - jmp .L_last_num_blocks_is_5_naArnppmugyrAeq + ja .L_last_num_blocks_is_7_541 + je .L_last_num_blocks_is_6_541 + jmp .L_last_num_blocks_is_5_541 -.L_last_num_blocks_is_3_1_naArnppmugyrAeq: +.L_last_num_blocks_is_3_1_541: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_naArnppmugyrAeq - je .L_last_num_blocks_is_2_naArnppmugyrAeq -.L_last_num_blocks_is_1_naArnppmugyrAeq: + ja .L_last_num_blocks_is_3_541 + je .L_last_num_blocks_is_2_541 +.L_last_num_blocks_is_1_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_foblolbfaretoCA + jae .L_16_blocks_overflow_542 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_foblolbfaretoCA + jmp .L_16_blocks_ok_542 -.L_16_blocks_overflow_foblolbfaretoCA: +.L_16_blocks_overflow_542: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_foblolbfaretoCA: +.L_16_blocks_ok_542: @@ -75763,7 +75763,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fdGrcsACsFoknkk + jl .L_small_initial_partial_block_543 @@ -75807,8 +75807,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fdGrcsACsFoknkk -.L_small_initial_partial_block_fdGrcsACsFoknkk: + jmp .L_small_initial_compute_done_543 +.L_small_initial_partial_block_543: @@ -75860,24 +75860,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_fdGrcsACsFoknkk -.L_small_initial_compute_done_fdGrcsACsFoknkk: -.L_after_reduction_fdGrcsACsFoknkk: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_2_naArnppmugyrAeq: + jmp .L_after_reduction_543 +.L_small_initial_compute_done_543: +.L_after_reduction_543: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_2_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_ijzjnzDDhfeACza + jae .L_16_blocks_overflow_544 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_ijzjnzDDhfeACza + jmp .L_16_blocks_ok_544 -.L_16_blocks_overflow_ijzjnzDDhfeACza: +.L_16_blocks_overflow_544: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_ijzjnzDDhfeACza: +.L_16_blocks_ok_544: @@ -75962,7 +75962,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mmiucroxtrconnu + jl .L_small_initial_partial_block_545 @@ -76006,8 +76006,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mmiucroxtrconnu -.L_small_initial_partial_block_mmiucroxtrconnu: + jmp .L_small_initial_compute_done_545 +.L_small_initial_partial_block_545: @@ -76054,27 +76054,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mmiucroxtrconnu: +.L_small_initial_compute_done_545: orq %r8,%r8 - je .L_after_reduction_mmiucroxtrconnu + je .L_after_reduction_545 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mmiucroxtrconnu: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_3_naArnppmugyrAeq: +.L_after_reduction_545: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_3_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_rgCqaEsvhyvbioD + jae .L_16_blocks_overflow_546 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_rgCqaEsvhyvbioD + jmp .L_16_blocks_ok_546 -.L_16_blocks_overflow_rgCqaEsvhyvbioD: +.L_16_blocks_overflow_546: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_rgCqaEsvhyvbioD: +.L_16_blocks_ok_546: @@ -76159,7 +76159,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xEmCGjixeBviAzq + jl .L_small_initial_partial_block_547 @@ -76204,8 +76204,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xEmCGjixeBviAzq -.L_small_initial_partial_block_xEmCGjixeBviAzq: + jmp .L_small_initial_compute_done_547 +.L_small_initial_partial_block_547: @@ -76252,27 +76252,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xEmCGjixeBviAzq: +.L_small_initial_compute_done_547: orq %r8,%r8 - je .L_after_reduction_xEmCGjixeBviAzq + je .L_after_reduction_547 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xEmCGjixeBviAzq: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_4_naArnppmugyrAeq: +.L_after_reduction_547: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_4_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_uucaiDcpdfEeCpk + jae .L_16_blocks_overflow_548 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_uucaiDcpdfEeCpk + jmp .L_16_blocks_ok_548 -.L_16_blocks_overflow_uucaiDcpdfEeCpk: +.L_16_blocks_overflow_548: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_uucaiDcpdfEeCpk: +.L_16_blocks_ok_548: @@ -76357,7 +76357,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uvepkEtuBtmvyiC + jl .L_small_initial_partial_block_549 @@ -76402,8 +76402,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uvepkEtuBtmvyiC -.L_small_initial_partial_block_uvepkEtuBtmvyiC: + jmp .L_small_initial_compute_done_549 +.L_small_initial_partial_block_549: @@ -76451,32 +76451,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_uvepkEtuBtmvyiC: +.L_small_initial_compute_done_549: orq %r8,%r8 - je .L_after_reduction_uvepkEtuBtmvyiC + je .L_after_reduction_549 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_uvepkEtuBtmvyiC: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_5_naArnppmugyrAeq: +.L_after_reduction_549: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_5_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_upsbDwhvjvdhcjA + jae .L_16_blocks_overflow_550 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_upsbDwhvjvdhcjA + jmp .L_16_blocks_ok_550 -.L_16_blocks_overflow_upsbDwhvjvdhcjA: +.L_16_blocks_overflow_550: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_upsbDwhvjvdhcjA: +.L_16_blocks_ok_550: @@ -76576,7 +76576,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xpGEpmBAectsEsk + jl .L_small_initial_partial_block_551 @@ -76627,8 +76627,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xpGEpmBAectsEsk -.L_small_initial_partial_block_xpGEpmBAectsEsk: + jmp .L_small_initial_compute_done_551 +.L_small_initial_partial_block_551: @@ -76676,32 +76676,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xpGEpmBAectsEsk: +.L_small_initial_compute_done_551: orq %r8,%r8 - je .L_after_reduction_xpGEpmBAectsEsk + je .L_after_reduction_551 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xpGEpmBAectsEsk: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_6_naArnppmugyrAeq: +.L_after_reduction_551: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_6_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_GFaCgmrvDluBwsh + jae .L_16_blocks_overflow_552 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_GFaCgmrvDluBwsh + jmp .L_16_blocks_ok_552 -.L_16_blocks_overflow_GFaCgmrvDluBwsh: +.L_16_blocks_overflow_552: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_GFaCgmrvDluBwsh: +.L_16_blocks_ok_552: @@ -76801,7 +76801,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xcvdqzFgCijgcjn + jl .L_small_initial_partial_block_553 @@ -76852,8 +76852,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xcvdqzFgCijgcjn -.L_small_initial_partial_block_xcvdqzFgCijgcjn: + jmp .L_small_initial_compute_done_553 +.L_small_initial_partial_block_553: @@ -76907,32 +76907,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xcvdqzFgCijgcjn: +.L_small_initial_compute_done_553: orq %r8,%r8 - je .L_after_reduction_xcvdqzFgCijgcjn + je .L_after_reduction_553 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xcvdqzFgCijgcjn: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_7_naArnppmugyrAeq: +.L_after_reduction_553: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_7_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_bBhtfqngfAjwCgn + jae .L_16_blocks_overflow_554 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_bBhtfqngfAjwCgn + jmp .L_16_blocks_ok_554 -.L_16_blocks_overflow_bBhtfqngfAjwCgn: +.L_16_blocks_overflow_554: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_bBhtfqngfAjwCgn: +.L_16_blocks_ok_554: @@ -77032,7 +77032,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rBzsfipgFbprhya + jl .L_small_initial_partial_block_555 @@ -77084,8 +77084,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rBzsfipgFbprhya -.L_small_initial_partial_block_rBzsfipgFbprhya: + jmp .L_small_initial_compute_done_555 +.L_small_initial_partial_block_555: @@ -77139,32 +77139,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rBzsfipgFbprhya: +.L_small_initial_compute_done_555: orq %r8,%r8 - je .L_after_reduction_rBzsfipgFbprhya + je .L_after_reduction_555 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rBzsfipgFbprhya: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_8_naArnppmugyrAeq: +.L_after_reduction_555: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_8_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_baCralbqexwqmuj + jae .L_16_blocks_overflow_556 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_baCralbqexwqmuj + jmp .L_16_blocks_ok_556 -.L_16_blocks_overflow_baCralbqexwqmuj: +.L_16_blocks_overflow_556: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_baCralbqexwqmuj: +.L_16_blocks_ok_556: @@ -77264,7 +77264,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ypowpGsCzuEbmDd + jl .L_small_initial_partial_block_557 @@ -77318,8 +77318,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ypowpGsCzuEbmDd -.L_small_initial_partial_block_ypowpGsCzuEbmDd: + jmp .L_small_initial_compute_done_557 +.L_small_initial_partial_block_557: @@ -77374,26 +77374,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ypowpGsCzuEbmDd: +.L_small_initial_compute_done_557: orq %r8,%r8 - je .L_after_reduction_ypowpGsCzuEbmDd + je .L_after_reduction_557 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ypowpGsCzuEbmDd: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_9_naArnppmugyrAeq: +.L_after_reduction_557: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_9_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_nEgupijfbolfeuy + jae .L_16_blocks_overflow_558 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_nEgupijfbolfeuy + jmp .L_16_blocks_ok_558 -.L_16_blocks_overflow_nEgupijfbolfeuy: +.L_16_blocks_overflow_558: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -77402,7 +77402,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_nEgupijfbolfeuy: +.L_16_blocks_ok_558: @@ -77517,7 +77517,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nFxABjFvvpGyick + jl .L_small_initial_partial_block_559 @@ -77577,8 +77577,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nFxABjFvvpGyick -.L_small_initial_partial_block_nFxABjFvvpGyick: + jmp .L_small_initial_compute_done_559 +.L_small_initial_partial_block_559: @@ -77635,26 +77635,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nFxABjFvvpGyick: +.L_small_initial_compute_done_559: orq %r8,%r8 - je .L_after_reduction_nFxABjFvvpGyick + je .L_after_reduction_559 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nFxABjFvvpGyick: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_10_naArnppmugyrAeq: +.L_after_reduction_559: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_10_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_fCpiAfrGwulgzmh + jae .L_16_blocks_overflow_560 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_fCpiAfrGwulgzmh + jmp .L_16_blocks_ok_560 -.L_16_blocks_overflow_fCpiAfrGwulgzmh: +.L_16_blocks_overflow_560: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -77663,7 +77663,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_fCpiAfrGwulgzmh: +.L_16_blocks_ok_560: @@ -77778,7 +77778,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rsaqoFfCupqCdCF + jl .L_small_initial_partial_block_561 @@ -77838,8 +77838,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rsaqoFfCupqCdCF -.L_small_initial_partial_block_rsaqoFfCupqCdCF: + jmp .L_small_initial_compute_done_561 +.L_small_initial_partial_block_561: @@ -77902,26 +77902,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rsaqoFfCupqCdCF: +.L_small_initial_compute_done_561: orq %r8,%r8 - je .L_after_reduction_rsaqoFfCupqCdCF + je .L_after_reduction_561 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rsaqoFfCupqCdCF: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_11_naArnppmugyrAeq: +.L_after_reduction_561: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_11_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_favjaueCtrberEb + jae .L_16_blocks_overflow_562 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_favjaueCtrberEb + jmp .L_16_blocks_ok_562 -.L_16_blocks_overflow_favjaueCtrberEb: +.L_16_blocks_overflow_562: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -77930,7 +77930,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_favjaueCtrberEb: +.L_16_blocks_ok_562: @@ -78045,7 +78045,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_loEkooaDsnEadhb + jl .L_small_initial_partial_block_563 @@ -78106,8 +78106,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_loEkooaDsnEadhb -.L_small_initial_partial_block_loEkooaDsnEadhb: + jmp .L_small_initial_compute_done_563 +.L_small_initial_partial_block_563: @@ -78170,26 +78170,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_loEkooaDsnEadhb: +.L_small_initial_compute_done_563: orq %r8,%r8 - je .L_after_reduction_loEkooaDsnEadhb + je .L_after_reduction_563 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_loEkooaDsnEadhb: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_12_naArnppmugyrAeq: +.L_after_reduction_563: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_12_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_sceEntmnnqAnAiv + jae .L_16_blocks_overflow_564 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_sceEntmnnqAnAiv + jmp .L_16_blocks_ok_564 -.L_16_blocks_overflow_sceEntmnnqAnAiv: +.L_16_blocks_overflow_564: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -78198,7 +78198,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_sceEntmnnqAnAiv: +.L_16_blocks_ok_564: @@ -78313,7 +78313,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AGdzDAjfhmywmvu + jl .L_small_initial_partial_block_565 @@ -78372,8 +78372,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AGdzDAjfhmywmvu -.L_small_initial_partial_block_AGdzDAjfhmywmvu: + jmp .L_small_initial_compute_done_565 +.L_small_initial_partial_block_565: @@ -78437,27 +78437,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AGdzDAjfhmywmvu: +.L_small_initial_compute_done_565: orq %r8,%r8 - je .L_after_reduction_AGdzDAjfhmywmvu + je .L_after_reduction_565 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AGdzDAjfhmywmvu: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_13_naArnppmugyrAeq: +.L_after_reduction_565: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_13_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_GsdFdttmDswlCqr + jae .L_16_blocks_overflow_566 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_GsdFdttmDswlCqr + jmp .L_16_blocks_ok_566 -.L_16_blocks_overflow_GsdFdttmDswlCqr: +.L_16_blocks_overflow_566: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -78468,7 +78468,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_GsdFdttmDswlCqr: +.L_16_blocks_ok_566: @@ -78598,7 +78598,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FzAhftrFnkdufxA + jl .L_small_initial_partial_block_567 @@ -78663,8 +78663,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FzAhftrFnkdufxA -.L_small_initial_partial_block_FzAhftrFnkdufxA: + jmp .L_small_initial_compute_done_567 +.L_small_initial_partial_block_567: @@ -78726,27 +78726,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FzAhftrFnkdufxA: +.L_small_initial_compute_done_567: orq %r8,%r8 - je .L_after_reduction_FzAhftrFnkdufxA + je .L_after_reduction_567 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FzAhftrFnkdufxA: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_14_naArnppmugyrAeq: +.L_after_reduction_567: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_14_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_GtoGCodajCEAuoA + jae .L_16_blocks_overflow_568 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_GtoGCodajCEAuoA + jmp .L_16_blocks_ok_568 -.L_16_blocks_overflow_GtoGCodajCEAuoA: +.L_16_blocks_overflow_568: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -78757,7 +78757,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_GtoGCodajCEAuoA: +.L_16_blocks_ok_568: @@ -78887,7 +78887,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sFaacyvufBxDbkq + jl .L_small_initial_partial_block_569 @@ -78952,8 +78952,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sFaacyvufBxDbkq -.L_small_initial_partial_block_sFaacyvufBxDbkq: + jmp .L_small_initial_compute_done_569 +.L_small_initial_partial_block_569: @@ -79021,27 +79021,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sFaacyvufBxDbkq: +.L_small_initial_compute_done_569: orq %r8,%r8 - je .L_after_reduction_sFaacyvufBxDbkq + je .L_after_reduction_569 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sFaacyvufBxDbkq: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_15_naArnppmugyrAeq: +.L_after_reduction_569: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_15_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_srmwDxytmnnuhan + jae .L_16_blocks_overflow_570 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_srmwDxytmnnuhan + jmp .L_16_blocks_ok_570 -.L_16_blocks_overflow_srmwDxytmnnuhan: +.L_16_blocks_overflow_570: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -79052,7 +79052,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_srmwDxytmnnuhan: +.L_16_blocks_ok_570: @@ -79182,7 +79182,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_okrkbyBaDkApexq + jl .L_small_initial_partial_block_571 @@ -79248,8 +79248,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_okrkbyBaDkApexq -.L_small_initial_partial_block_okrkbyBaDkApexq: + jmp .L_small_initial_compute_done_571 +.L_small_initial_partial_block_571: @@ -79317,27 +79317,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_okrkbyBaDkApexq: +.L_small_initial_compute_done_571: orq %r8,%r8 - je .L_after_reduction_okrkbyBaDkApexq + je .L_after_reduction_571 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_okrkbyBaDkApexq: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_16_naArnppmugyrAeq: +.L_after_reduction_571: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_16_541: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_AEzurkudrvgDcss + jae .L_16_blocks_overflow_572 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_AEzurkudrvgDcss + jmp .L_16_blocks_ok_572 -.L_16_blocks_overflow_AEzurkudrvgDcss: +.L_16_blocks_overflow_572: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -79348,7 +79348,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_AEzurkudrvgDcss: +.L_16_blocks_ok_572: @@ -79475,7 +79475,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_dawyAebroEvqgat: +.L_small_initial_partial_block_573: @@ -79544,11 +79544,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dawyAebroEvqgat: +.L_small_initial_compute_done_573: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dawyAebroEvqgat: - jmp .L_last_blocks_done_naArnppmugyrAeq -.L_last_num_blocks_is_0_naArnppmugyrAeq: +.L_after_reduction_573: + jmp .L_last_blocks_done_541 +.L_last_num_blocks_is_0_541: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -79610,18 +79610,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_naArnppmugyrAeq: +.L_last_blocks_done_541: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_kpzgFwDvlzADzny -.L_encrypt_16_blocks_kpzgFwDvlzADzny: + jmp .L_ghash_done_497 +.L_encrypt_16_blocks_497: cmpb $240,%r15b - jae .L_16_blocks_overflow_qczevpkanlelayb + jae .L_16_blocks_overflow_574 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_qczevpkanlelayb -.L_16_blocks_overflow_qczevpkanlelayb: + jmp .L_16_blocks_ok_574 +.L_16_blocks_overflow_574: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -79632,7 +79632,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_qczevpkanlelayb: +.L_16_blocks_ok_574: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -79834,61 +79834,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_0_575 cmpl $8,%r10d - je .L_last_num_blocks_is_8_oxxaFudqqjGjCEq - jb .L_last_num_blocks_is_7_1_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_8_575 + jb .L_last_num_blocks_is_7_1_575 cmpl $12,%r10d - je .L_last_num_blocks_is_12_oxxaFudqqjGjCEq - jb .L_last_num_blocks_is_11_9_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_12_575 + jb .L_last_num_blocks_is_11_9_575 cmpl $15,%r10d - je .L_last_num_blocks_is_15_oxxaFudqqjGjCEq - ja .L_last_num_blocks_is_16_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_15_575 + ja .L_last_num_blocks_is_16_575 cmpl $14,%r10d - je .L_last_num_blocks_is_14_oxxaFudqqjGjCEq - jmp .L_last_num_blocks_is_13_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_14_575 + jmp .L_last_num_blocks_is_13_575 -.L_last_num_blocks_is_11_9_oxxaFudqqjGjCEq: +.L_last_num_blocks_is_11_9_575: cmpl $10,%r10d - je .L_last_num_blocks_is_10_oxxaFudqqjGjCEq - ja .L_last_num_blocks_is_11_oxxaFudqqjGjCEq - jmp .L_last_num_blocks_is_9_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_10_575 + ja .L_last_num_blocks_is_11_575 + jmp .L_last_num_blocks_is_9_575 -.L_last_num_blocks_is_7_1_oxxaFudqqjGjCEq: +.L_last_num_blocks_is_7_1_575: cmpl $4,%r10d - je .L_last_num_blocks_is_4_oxxaFudqqjGjCEq - jb .L_last_num_blocks_is_3_1_oxxaFudqqjGjCEq + je .L_last_num_blocks_is_4_575 + jb .L_last_num_blocks_is_3_1_575 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_oxxaFudqqjGjCEq - je .L_last_num_blocks_is_6_oxxaFudqqjGjCEq - jmp .L_last_num_blocks_is_5_oxxaFudqqjGjCEq + ja .L_last_num_blocks_is_7_575 + je .L_last_num_blocks_is_6_575 + jmp .L_last_num_blocks_is_5_575 -.L_last_num_blocks_is_3_1_oxxaFudqqjGjCEq: +.L_last_num_blocks_is_3_1_575: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_oxxaFudqqjGjCEq - je .L_last_num_blocks_is_2_oxxaFudqqjGjCEq -.L_last_num_blocks_is_1_oxxaFudqqjGjCEq: + ja .L_last_num_blocks_is_3_575 + je .L_last_num_blocks_is_2_575 +.L_last_num_blocks_is_1_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_qixjldmiysyrDqi + jae .L_16_blocks_overflow_576 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_qixjldmiysyrDqi + jmp .L_16_blocks_ok_576 -.L_16_blocks_overflow_qixjldmiysyrDqi: +.L_16_blocks_overflow_576: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_qixjldmiysyrDqi: +.L_16_blocks_ok_576: @@ -79995,7 +79995,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_uqruCboBusDamjG + jl .L_small_initial_partial_block_577 @@ -80037,8 +80037,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_uqruCboBusDamjG -.L_small_initial_partial_block_uqruCboBusDamjG: + jmp .L_small_initial_compute_done_577 +.L_small_initial_partial_block_577: @@ -80062,24 +80062,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_uqruCboBusDamjG -.L_small_initial_compute_done_uqruCboBusDamjG: -.L_after_reduction_uqruCboBusDamjG: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_2_oxxaFudqqjGjCEq: + jmp .L_after_reduction_577 +.L_small_initial_compute_done_577: +.L_after_reduction_577: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_2_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_vbGCsziijqGyGaB + jae .L_16_blocks_overflow_578 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_vbGCsziijqGyGaB + jmp .L_16_blocks_ok_578 -.L_16_blocks_overflow_vbGCsziijqGyGaB: +.L_16_blocks_overflow_578: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_vbGCsziijqGyGaB: +.L_16_blocks_ok_578: @@ -80187,7 +80187,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GrgkadgCnprowys + jl .L_small_initial_partial_block_579 @@ -80229,8 +80229,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GrgkadgCnprowys -.L_small_initial_partial_block_GrgkadgCnprowys: + jmp .L_small_initial_compute_done_579 +.L_small_initial_partial_block_579: @@ -80275,27 +80275,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GrgkadgCnprowys: +.L_small_initial_compute_done_579: orq %r8,%r8 - je .L_after_reduction_GrgkadgCnprowys + je .L_after_reduction_579 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GrgkadgCnprowys: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_3_oxxaFudqqjGjCEq: +.L_after_reduction_579: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_3_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_kDbFrbEdpuoFvds + jae .L_16_blocks_overflow_580 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_kDbFrbEdpuoFvds + jmp .L_16_blocks_ok_580 -.L_16_blocks_overflow_kDbFrbEdpuoFvds: +.L_16_blocks_overflow_580: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_kDbFrbEdpuoFvds: +.L_16_blocks_ok_580: @@ -80403,7 +80403,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AwCkAenocFafyyF + jl .L_small_initial_partial_block_581 @@ -80446,8 +80446,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AwCkAenocFafyyF -.L_small_initial_partial_block_AwCkAenocFafyyF: + jmp .L_small_initial_compute_done_581 +.L_small_initial_partial_block_581: @@ -80492,27 +80492,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AwCkAenocFafyyF: +.L_small_initial_compute_done_581: orq %r8,%r8 - je .L_after_reduction_AwCkAenocFafyyF + je .L_after_reduction_581 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AwCkAenocFafyyF: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_4_oxxaFudqqjGjCEq: +.L_after_reduction_581: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_4_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_fvBkmbicqdjvzif + jae .L_16_blocks_overflow_582 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_fvBkmbicqdjvzif + jmp .L_16_blocks_ok_582 -.L_16_blocks_overflow_fvBkmbicqdjvzif: +.L_16_blocks_overflow_582: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_fvBkmbicqdjvzif: +.L_16_blocks_ok_582: @@ -80620,7 +80620,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fxficfshrBuyzef + jl .L_small_initial_partial_block_583 @@ -80662,8 +80662,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fxficfshrBuyzef -.L_small_initial_partial_block_fxficfshrBuyzef: + jmp .L_small_initial_compute_done_583 +.L_small_initial_partial_block_583: @@ -80709,32 +80709,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fxficfshrBuyzef: +.L_small_initial_compute_done_583: orq %r8,%r8 - je .L_after_reduction_fxficfshrBuyzef + je .L_after_reduction_583 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fxficfshrBuyzef: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_5_oxxaFudqqjGjCEq: +.L_after_reduction_583: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_5_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_gpnAxFvilmBtqrp + jae .L_16_blocks_overflow_584 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_gpnAxFvilmBtqrp + jmp .L_16_blocks_ok_584 -.L_16_blocks_overflow_gpnAxFvilmBtqrp: +.L_16_blocks_overflow_584: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_gpnAxFvilmBtqrp: +.L_16_blocks_ok_584: @@ -80857,7 +80857,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EiyajignneBvejo + jl .L_small_initial_partial_block_585 @@ -80909,8 +80909,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EiyajignneBvejo -.L_small_initial_partial_block_EiyajignneBvejo: + jmp .L_small_initial_compute_done_585 +.L_small_initial_partial_block_585: @@ -80955,32 +80955,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EiyajignneBvejo: +.L_small_initial_compute_done_585: orq %r8,%r8 - je .L_after_reduction_EiyajignneBvejo + je .L_after_reduction_585 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EiyajignneBvejo: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_6_oxxaFudqqjGjCEq: +.L_after_reduction_585: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_6_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_CfDevglEqphrvEc + jae .L_16_blocks_overflow_586 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_CfDevglEqphrvEc + jmp .L_16_blocks_ok_586 -.L_16_blocks_overflow_CfDevglEqphrvEc: +.L_16_blocks_overflow_586: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_CfDevglEqphrvEc: +.L_16_blocks_ok_586: @@ -81103,7 +81103,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lsnusklsBhzbghA + jl .L_small_initial_partial_block_587 @@ -81155,8 +81155,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lsnusklsBhzbghA -.L_small_initial_partial_block_lsnusklsBhzbghA: + jmp .L_small_initial_compute_done_587 +.L_small_initial_partial_block_587: @@ -81211,32 +81211,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lsnusklsBhzbghA: +.L_small_initial_compute_done_587: orq %r8,%r8 - je .L_after_reduction_lsnusklsBhzbghA + je .L_after_reduction_587 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_lsnusklsBhzbghA: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_7_oxxaFudqqjGjCEq: +.L_after_reduction_587: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_7_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_CiiqygszsbnEsdA + jae .L_16_blocks_overflow_588 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_CiiqygszsbnEsdA + jmp .L_16_blocks_ok_588 -.L_16_blocks_overflow_CiiqygszsbnEsdA: +.L_16_blocks_overflow_588: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_CiiqygszsbnEsdA: +.L_16_blocks_ok_588: @@ -81359,7 +81359,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BhaiezgEmcAqGcA + jl .L_small_initial_partial_block_589 @@ -81412,8 +81412,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BhaiezgEmcAqGcA -.L_small_initial_partial_block_BhaiezgEmcAqGcA: + jmp .L_small_initial_compute_done_589 +.L_small_initial_partial_block_589: @@ -81468,32 +81468,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BhaiezgEmcAqGcA: +.L_small_initial_compute_done_589: orq %r8,%r8 - je .L_after_reduction_BhaiezgEmcAqGcA + je .L_after_reduction_589 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BhaiezgEmcAqGcA: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_8_oxxaFudqqjGjCEq: +.L_after_reduction_589: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_8_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_ECttuspxBEesibq + jae .L_16_blocks_overflow_590 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_ECttuspxBEesibq + jmp .L_16_blocks_ok_590 -.L_16_blocks_overflow_ECttuspxBEesibq: +.L_16_blocks_overflow_590: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_ECttuspxBEesibq: +.L_16_blocks_ok_590: @@ -81616,7 +81616,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ABBqtiyFesxzjAi + jl .L_small_initial_partial_block_591 @@ -81667,8 +81667,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ABBqtiyFesxzjAi -.L_small_initial_partial_block_ABBqtiyFesxzjAi: + jmp .L_small_initial_compute_done_591 +.L_small_initial_partial_block_591: @@ -81724,26 +81724,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ABBqtiyFesxzjAi: +.L_small_initial_compute_done_591: orq %r8,%r8 - je .L_after_reduction_ABBqtiyFesxzjAi + je .L_after_reduction_591 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ABBqtiyFesxzjAi: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_9_oxxaFudqqjGjCEq: +.L_after_reduction_591: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_9_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_aBsthnaDGwsjEnF + jae .L_16_blocks_overflow_592 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_aBsthnaDGwsjEnF + jmp .L_16_blocks_ok_592 -.L_16_blocks_overflow_aBsthnaDGwsjEnF: +.L_16_blocks_overflow_592: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -81752,7 +81752,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_aBsthnaDGwsjEnF: +.L_16_blocks_ok_592: @@ -81890,7 +81890,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xuuGkuwxohgdfpz + jl .L_small_initial_partial_block_593 @@ -81951,8 +81951,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xuuGkuwxohgdfpz -.L_small_initial_partial_block_xuuGkuwxohgdfpz: + jmp .L_small_initial_compute_done_593 +.L_small_initial_partial_block_593: @@ -82006,26 +82006,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xuuGkuwxohgdfpz: +.L_small_initial_compute_done_593: orq %r8,%r8 - je .L_after_reduction_xuuGkuwxohgdfpz + je .L_after_reduction_593 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xuuGkuwxohgdfpz: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_10_oxxaFudqqjGjCEq: +.L_after_reduction_593: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_10_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_aCifCeeoodaspGd + jae .L_16_blocks_overflow_594 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_aCifCeeoodaspGd + jmp .L_16_blocks_ok_594 -.L_16_blocks_overflow_aCifCeeoodaspGd: +.L_16_blocks_overflow_594: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -82034,7 +82034,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_aCifCeeoodaspGd: +.L_16_blocks_ok_594: @@ -82172,7 +82172,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_analjDbjemkyfAz + jl .L_small_initial_partial_block_595 @@ -82233,8 +82233,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_analjDbjemkyfAz -.L_small_initial_partial_block_analjDbjemkyfAz: + jmp .L_small_initial_compute_done_595 +.L_small_initial_partial_block_595: @@ -82298,26 +82298,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_analjDbjemkyfAz: +.L_small_initial_compute_done_595: orq %r8,%r8 - je .L_after_reduction_analjDbjemkyfAz + je .L_after_reduction_595 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_analjDbjemkyfAz: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_11_oxxaFudqqjGjCEq: +.L_after_reduction_595: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_11_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_Guvlcwwhauohknj + jae .L_16_blocks_overflow_596 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_Guvlcwwhauohknj + jmp .L_16_blocks_ok_596 -.L_16_blocks_overflow_Guvlcwwhauohknj: +.L_16_blocks_overflow_596: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -82326,7 +82326,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_Guvlcwwhauohknj: +.L_16_blocks_ok_596: @@ -82464,7 +82464,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mpDyvAvybrCdFex + jl .L_small_initial_partial_block_597 @@ -82526,8 +82526,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mpDyvAvybrCdFex -.L_small_initial_partial_block_mpDyvAvybrCdFex: + jmp .L_small_initial_compute_done_597 +.L_small_initial_partial_block_597: @@ -82591,26 +82591,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mpDyvAvybrCdFex: +.L_small_initial_compute_done_597: orq %r8,%r8 - je .L_after_reduction_mpDyvAvybrCdFex + je .L_after_reduction_597 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mpDyvAvybrCdFex: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_12_oxxaFudqqjGjCEq: +.L_after_reduction_597: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_12_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_okuxgcbwameopgh + jae .L_16_blocks_overflow_598 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_okuxgcbwameopgh + jmp .L_16_blocks_ok_598 -.L_16_blocks_overflow_okuxgcbwameopgh: +.L_16_blocks_overflow_598: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -82619,7 +82619,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_okuxgcbwameopgh: +.L_16_blocks_ok_598: @@ -82757,7 +82757,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nyfdovlmjBsoCFG + jl .L_small_initial_partial_block_599 @@ -82813,8 +82813,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nyfdovlmjBsoCFG -.L_small_initial_partial_block_nyfdovlmjBsoCFG: + jmp .L_small_initial_compute_done_599 +.L_small_initial_partial_block_599: @@ -82879,27 +82879,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nyfdovlmjBsoCFG: +.L_small_initial_compute_done_599: orq %r8,%r8 - je .L_after_reduction_nyfdovlmjBsoCFG + je .L_after_reduction_599 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nyfdovlmjBsoCFG: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_13_oxxaFudqqjGjCEq: +.L_after_reduction_599: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_13_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_asCmgxodFhyjlzC + jae .L_16_blocks_overflow_600 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_asCmgxodFhyjlzC + jmp .L_16_blocks_ok_600 -.L_16_blocks_overflow_asCmgxodFhyjlzC: +.L_16_blocks_overflow_600: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -82910,7 +82910,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_asCmgxodFhyjlzC: +.L_16_blocks_ok_600: @@ -83063,7 +83063,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aobAzixdovidzCn + jl .L_small_initial_partial_block_601 @@ -83129,8 +83129,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aobAzixdovidzCn -.L_small_initial_partial_block_aobAzixdovidzCn: + jmp .L_small_initial_compute_done_601 +.L_small_initial_partial_block_601: @@ -83189,27 +83189,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aobAzixdovidzCn: +.L_small_initial_compute_done_601: orq %r8,%r8 - je .L_after_reduction_aobAzixdovidzCn + je .L_after_reduction_601 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aobAzixdovidzCn: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_14_oxxaFudqqjGjCEq: +.L_after_reduction_601: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_14_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_lxvxnhxjFbwblrh + jae .L_16_blocks_overflow_602 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_lxvxnhxjFbwblrh + jmp .L_16_blocks_ok_602 -.L_16_blocks_overflow_lxvxnhxjFbwblrh: +.L_16_blocks_overflow_602: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -83220,7 +83220,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_lxvxnhxjFbwblrh: +.L_16_blocks_ok_602: @@ -83373,7 +83373,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_okBnusrliheyGAB + jl .L_small_initial_partial_block_603 @@ -83439,8 +83439,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_okBnusrliheyGAB -.L_small_initial_partial_block_okBnusrliheyGAB: + jmp .L_small_initial_compute_done_603 +.L_small_initial_partial_block_603: @@ -83509,27 +83509,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_okBnusrliheyGAB: +.L_small_initial_compute_done_603: orq %r8,%r8 - je .L_after_reduction_okBnusrliheyGAB + je .L_after_reduction_603 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_okBnusrliheyGAB: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_15_oxxaFudqqjGjCEq: +.L_after_reduction_603: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_15_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_GtxcAocbabflsuf + jae .L_16_blocks_overflow_604 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_GtxcAocbabflsuf + jmp .L_16_blocks_ok_604 -.L_16_blocks_overflow_GtxcAocbabflsuf: +.L_16_blocks_overflow_604: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -83540,7 +83540,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_GtxcAocbabflsuf: +.L_16_blocks_ok_604: @@ -83693,7 +83693,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_smEGzbmjxgfmarg + jl .L_small_initial_partial_block_605 @@ -83760,8 +83760,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_smEGzbmjxgfmarg -.L_small_initial_partial_block_smEGzbmjxgfmarg: + jmp .L_small_initial_compute_done_605 +.L_small_initial_partial_block_605: @@ -83830,27 +83830,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_smEGzbmjxgfmarg: +.L_small_initial_compute_done_605: orq %r8,%r8 - je .L_after_reduction_smEGzbmjxgfmarg + je .L_after_reduction_605 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_smEGzbmjxgfmarg: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_16_oxxaFudqqjGjCEq: +.L_after_reduction_605: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_16_575: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_AxywvnwCEkqkFya + jae .L_16_blocks_overflow_606 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_AxywvnwCEkqkFya + jmp .L_16_blocks_ok_606 -.L_16_blocks_overflow_AxywvnwCEkqkFya: +.L_16_blocks_overflow_606: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -83861,7 +83861,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_AxywvnwCEkqkFya: +.L_16_blocks_ok_606: @@ -84011,7 +84011,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_eBdDvoCDcfrmcwk: +.L_small_initial_partial_block_607: @@ -84081,11 +84081,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_eBdDvoCDcfrmcwk: +.L_small_initial_compute_done_607: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_eBdDvoCDcfrmcwk: - jmp .L_last_blocks_done_oxxaFudqqjGjCEq -.L_last_num_blocks_is_0_oxxaFudqqjGjCEq: +.L_after_reduction_607: + jmp .L_last_blocks_done_575 +.L_last_num_blocks_is_0_575: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -84146,18 +84146,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_oxxaFudqqjGjCEq: +.L_last_blocks_done_575: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_kpzgFwDvlzADzny + jmp .L_ghash_done_497 -.L_message_below_32_blocks_kpzgFwDvlzADzny: +.L_message_below_32_blocks_497: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_cdviEffqdkykzzz + jnz .L_skip_hkeys_precomputation_608 vmovdqu64 640(%rsp),%zmm3 @@ -84285,7 +84285,7 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_cdviEffqdkykzzz: +.L_skip_hkeys_precomputation_608: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -84293,61 +84293,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_DlcGrswzomffbed + je .L_last_num_blocks_is_0_609 cmpl $8,%r10d - je .L_last_num_blocks_is_8_DlcGrswzomffbed - jb .L_last_num_blocks_is_7_1_DlcGrswzomffbed + je .L_last_num_blocks_is_8_609 + jb .L_last_num_blocks_is_7_1_609 cmpl $12,%r10d - je .L_last_num_blocks_is_12_DlcGrswzomffbed - jb .L_last_num_blocks_is_11_9_DlcGrswzomffbed + je .L_last_num_blocks_is_12_609 + jb .L_last_num_blocks_is_11_9_609 cmpl $15,%r10d - je .L_last_num_blocks_is_15_DlcGrswzomffbed - ja .L_last_num_blocks_is_16_DlcGrswzomffbed + je .L_last_num_blocks_is_15_609 + ja .L_last_num_blocks_is_16_609 cmpl $14,%r10d - je .L_last_num_blocks_is_14_DlcGrswzomffbed - jmp .L_last_num_blocks_is_13_DlcGrswzomffbed + je .L_last_num_blocks_is_14_609 + jmp .L_last_num_blocks_is_13_609 -.L_last_num_blocks_is_11_9_DlcGrswzomffbed: +.L_last_num_blocks_is_11_9_609: cmpl $10,%r10d - je .L_last_num_blocks_is_10_DlcGrswzomffbed - ja .L_last_num_blocks_is_11_DlcGrswzomffbed - jmp .L_last_num_blocks_is_9_DlcGrswzomffbed + je .L_last_num_blocks_is_10_609 + ja .L_last_num_blocks_is_11_609 + jmp .L_last_num_blocks_is_9_609 -.L_last_num_blocks_is_7_1_DlcGrswzomffbed: +.L_last_num_blocks_is_7_1_609: cmpl $4,%r10d - je .L_last_num_blocks_is_4_DlcGrswzomffbed - jb .L_last_num_blocks_is_3_1_DlcGrswzomffbed + je .L_last_num_blocks_is_4_609 + jb .L_last_num_blocks_is_3_1_609 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_DlcGrswzomffbed - je .L_last_num_blocks_is_6_DlcGrswzomffbed - jmp .L_last_num_blocks_is_5_DlcGrswzomffbed + ja .L_last_num_blocks_is_7_609 + je .L_last_num_blocks_is_6_609 + jmp .L_last_num_blocks_is_5_609 -.L_last_num_blocks_is_3_1_DlcGrswzomffbed: +.L_last_num_blocks_is_3_1_609: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_DlcGrswzomffbed - je .L_last_num_blocks_is_2_DlcGrswzomffbed -.L_last_num_blocks_is_1_DlcGrswzomffbed: + ja .L_last_num_blocks_is_3_609 + je .L_last_num_blocks_is_2_609 +.L_last_num_blocks_is_1_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_nkvsbijsrvuuazc + jae .L_16_blocks_overflow_610 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_nkvsbijsrvuuazc + jmp .L_16_blocks_ok_610 -.L_16_blocks_overflow_nkvsbijsrvuuazc: +.L_16_blocks_overflow_610: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_nkvsbijsrvuuazc: +.L_16_blocks_ok_610: @@ -84431,7 +84431,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DFgCElBtBCAajyG + jl .L_small_initial_partial_block_611 @@ -84475,8 +84475,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DFgCElBtBCAajyG -.L_small_initial_partial_block_DFgCElBtBCAajyG: + jmp .L_small_initial_compute_done_611 +.L_small_initial_partial_block_611: @@ -84528,24 +84528,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_DFgCElBtBCAajyG -.L_small_initial_compute_done_DFgCElBtBCAajyG: -.L_after_reduction_DFgCElBtBCAajyG: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_2_DlcGrswzomffbed: + jmp .L_after_reduction_611 +.L_small_initial_compute_done_611: +.L_after_reduction_611: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_2_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_FfdvjpwlmxjCbaw + jae .L_16_blocks_overflow_612 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_FfdvjpwlmxjCbaw + jmp .L_16_blocks_ok_612 -.L_16_blocks_overflow_FfdvjpwlmxjCbaw: +.L_16_blocks_overflow_612: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_FfdvjpwlmxjCbaw: +.L_16_blocks_ok_612: @@ -84630,7 +84630,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vEdccjugxcmBinp + jl .L_small_initial_partial_block_613 @@ -84674,8 +84674,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vEdccjugxcmBinp -.L_small_initial_partial_block_vEdccjugxcmBinp: + jmp .L_small_initial_compute_done_613 +.L_small_initial_partial_block_613: @@ -84722,27 +84722,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vEdccjugxcmBinp: +.L_small_initial_compute_done_613: orq %r8,%r8 - je .L_after_reduction_vEdccjugxcmBinp + je .L_after_reduction_613 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vEdccjugxcmBinp: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_3_DlcGrswzomffbed: +.L_after_reduction_613: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_3_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_qpAblpGlbiicBgF + jae .L_16_blocks_overflow_614 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_qpAblpGlbiicBgF + jmp .L_16_blocks_ok_614 -.L_16_blocks_overflow_qpAblpGlbiicBgF: +.L_16_blocks_overflow_614: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_qpAblpGlbiicBgF: +.L_16_blocks_ok_614: @@ -84827,7 +84827,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xnjvGhamaAbyDis + jl .L_small_initial_partial_block_615 @@ -84872,8 +84872,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xnjvGhamaAbyDis -.L_small_initial_partial_block_xnjvGhamaAbyDis: + jmp .L_small_initial_compute_done_615 +.L_small_initial_partial_block_615: @@ -84920,27 +84920,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xnjvGhamaAbyDis: +.L_small_initial_compute_done_615: orq %r8,%r8 - je .L_after_reduction_xnjvGhamaAbyDis + je .L_after_reduction_615 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xnjvGhamaAbyDis: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_4_DlcGrswzomffbed: +.L_after_reduction_615: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_4_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_eyvumBoDfDnzble + jae .L_16_blocks_overflow_616 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_eyvumBoDfDnzble + jmp .L_16_blocks_ok_616 -.L_16_blocks_overflow_eyvumBoDfDnzble: +.L_16_blocks_overflow_616: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_eyvumBoDfDnzble: +.L_16_blocks_ok_616: @@ -85025,7 +85025,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aknGmwFcqEcwruD + jl .L_small_initial_partial_block_617 @@ -85070,8 +85070,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aknGmwFcqEcwruD -.L_small_initial_partial_block_aknGmwFcqEcwruD: + jmp .L_small_initial_compute_done_617 +.L_small_initial_partial_block_617: @@ -85119,32 +85119,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aknGmwFcqEcwruD: +.L_small_initial_compute_done_617: orq %r8,%r8 - je .L_after_reduction_aknGmwFcqEcwruD + je .L_after_reduction_617 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aknGmwFcqEcwruD: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_5_DlcGrswzomffbed: +.L_after_reduction_617: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_5_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_bxwhvgtauaBysej + jae .L_16_blocks_overflow_618 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_bxwhvgtauaBysej + jmp .L_16_blocks_ok_618 -.L_16_blocks_overflow_bxwhvgtauaBysej: +.L_16_blocks_overflow_618: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_bxwhvgtauaBysej: +.L_16_blocks_ok_618: @@ -85244,7 +85244,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_beumqymbcolzarz + jl .L_small_initial_partial_block_619 @@ -85295,8 +85295,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_beumqymbcolzarz -.L_small_initial_partial_block_beumqymbcolzarz: + jmp .L_small_initial_compute_done_619 +.L_small_initial_partial_block_619: @@ -85344,32 +85344,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_beumqymbcolzarz: +.L_small_initial_compute_done_619: orq %r8,%r8 - je .L_after_reduction_beumqymbcolzarz + je .L_after_reduction_619 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_beumqymbcolzarz: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_6_DlcGrswzomffbed: +.L_after_reduction_619: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_6_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_csECbxsBfheikpF + jae .L_16_blocks_overflow_620 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_csECbxsBfheikpF + jmp .L_16_blocks_ok_620 -.L_16_blocks_overflow_csECbxsBfheikpF: +.L_16_blocks_overflow_620: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_csECbxsBfheikpF: +.L_16_blocks_ok_620: @@ -85469,7 +85469,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FazcyvEiEytgdsl + jl .L_small_initial_partial_block_621 @@ -85520,8 +85520,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FazcyvEiEytgdsl -.L_small_initial_partial_block_FazcyvEiEytgdsl: + jmp .L_small_initial_compute_done_621 +.L_small_initial_partial_block_621: @@ -85575,32 +85575,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FazcyvEiEytgdsl: +.L_small_initial_compute_done_621: orq %r8,%r8 - je .L_after_reduction_FazcyvEiEytgdsl + je .L_after_reduction_621 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FazcyvEiEytgdsl: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_7_DlcGrswzomffbed: +.L_after_reduction_621: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_7_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_emqmlalEkxwndqk + jae .L_16_blocks_overflow_622 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_emqmlalEkxwndqk + jmp .L_16_blocks_ok_622 -.L_16_blocks_overflow_emqmlalEkxwndqk: +.L_16_blocks_overflow_622: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_emqmlalEkxwndqk: +.L_16_blocks_ok_622: @@ -85700,7 +85700,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_luwbasgbGlrGgzG + jl .L_small_initial_partial_block_623 @@ -85752,8 +85752,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_luwbasgbGlrGgzG -.L_small_initial_partial_block_luwbasgbGlrGgzG: + jmp .L_small_initial_compute_done_623 +.L_small_initial_partial_block_623: @@ -85807,32 +85807,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_luwbasgbGlrGgzG: +.L_small_initial_compute_done_623: orq %r8,%r8 - je .L_after_reduction_luwbasgbGlrGgzG + je .L_after_reduction_623 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_luwbasgbGlrGgzG: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_8_DlcGrswzomffbed: +.L_after_reduction_623: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_8_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_fzDzproroGdpurF + jae .L_16_blocks_overflow_624 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_fzDzproroGdpurF + jmp .L_16_blocks_ok_624 -.L_16_blocks_overflow_fzDzproroGdpurF: +.L_16_blocks_overflow_624: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_fzDzproroGdpurF: +.L_16_blocks_ok_624: @@ -85932,7 +85932,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gtDlyrvAzGvEjsb + jl .L_small_initial_partial_block_625 @@ -85986,8 +85986,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gtDlyrvAzGvEjsb -.L_small_initial_partial_block_gtDlyrvAzGvEjsb: + jmp .L_small_initial_compute_done_625 +.L_small_initial_partial_block_625: @@ -86042,26 +86042,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gtDlyrvAzGvEjsb: +.L_small_initial_compute_done_625: orq %r8,%r8 - je .L_after_reduction_gtDlyrvAzGvEjsb + je .L_after_reduction_625 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gtDlyrvAzGvEjsb: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_9_DlcGrswzomffbed: +.L_after_reduction_625: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_9_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_doFEkAzqDqixqAv + jae .L_16_blocks_overflow_626 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_doFEkAzqDqixqAv + jmp .L_16_blocks_ok_626 -.L_16_blocks_overflow_doFEkAzqDqixqAv: +.L_16_blocks_overflow_626: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -86070,7 +86070,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_doFEkAzqDqixqAv: +.L_16_blocks_ok_626: @@ -86185,7 +86185,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_eynixwBFmnGdDlF + jl .L_small_initial_partial_block_627 @@ -86245,8 +86245,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_eynixwBFmnGdDlF -.L_small_initial_partial_block_eynixwBFmnGdDlF: + jmp .L_small_initial_compute_done_627 +.L_small_initial_partial_block_627: @@ -86303,26 +86303,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_eynixwBFmnGdDlF: +.L_small_initial_compute_done_627: orq %r8,%r8 - je .L_after_reduction_eynixwBFmnGdDlF + je .L_after_reduction_627 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_eynixwBFmnGdDlF: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_10_DlcGrswzomffbed: +.L_after_reduction_627: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_10_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_FbdyBbfbuqjdFes + jae .L_16_blocks_overflow_628 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_FbdyBbfbuqjdFes + jmp .L_16_blocks_ok_628 -.L_16_blocks_overflow_FbdyBbfbuqjdFes: +.L_16_blocks_overflow_628: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -86331,7 +86331,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_FbdyBbfbuqjdFes: +.L_16_blocks_ok_628: @@ -86446,7 +86446,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_edcdfnijlltdcoq + jl .L_small_initial_partial_block_629 @@ -86506,8 +86506,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_edcdfnijlltdcoq -.L_small_initial_partial_block_edcdfnijlltdcoq: + jmp .L_small_initial_compute_done_629 +.L_small_initial_partial_block_629: @@ -86570,26 +86570,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_edcdfnijlltdcoq: +.L_small_initial_compute_done_629: orq %r8,%r8 - je .L_after_reduction_edcdfnijlltdcoq + je .L_after_reduction_629 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_edcdfnijlltdcoq: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_11_DlcGrswzomffbed: +.L_after_reduction_629: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_11_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_zDtgsabrsdBzhpn + jae .L_16_blocks_overflow_630 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_zDtgsabrsdBzhpn + jmp .L_16_blocks_ok_630 -.L_16_blocks_overflow_zDtgsabrsdBzhpn: +.L_16_blocks_overflow_630: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -86598,7 +86598,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_zDtgsabrsdBzhpn: +.L_16_blocks_ok_630: @@ -86713,7 +86713,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_waFDedemeEwFaqe + jl .L_small_initial_partial_block_631 @@ -86774,8 +86774,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_waFDedemeEwFaqe -.L_small_initial_partial_block_waFDedemeEwFaqe: + jmp .L_small_initial_compute_done_631 +.L_small_initial_partial_block_631: @@ -86838,26 +86838,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_waFDedemeEwFaqe: +.L_small_initial_compute_done_631: orq %r8,%r8 - je .L_after_reduction_waFDedemeEwFaqe + je .L_after_reduction_631 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_waFDedemeEwFaqe: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_12_DlcGrswzomffbed: +.L_after_reduction_631: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_12_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_oExqautfwkwokEB + jae .L_16_blocks_overflow_632 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_oExqautfwkwokEB + jmp .L_16_blocks_ok_632 -.L_16_blocks_overflow_oExqautfwkwokEB: +.L_16_blocks_overflow_632: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -86866,7 +86866,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_oExqautfwkwokEB: +.L_16_blocks_ok_632: @@ -86981,7 +86981,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DGBGrfFtbtDGuea + jl .L_small_initial_partial_block_633 @@ -87040,8 +87040,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DGBGrfFtbtDGuea -.L_small_initial_partial_block_DGBGrfFtbtDGuea: + jmp .L_small_initial_compute_done_633 +.L_small_initial_partial_block_633: @@ -87105,27 +87105,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DGBGrfFtbtDGuea: +.L_small_initial_compute_done_633: orq %r8,%r8 - je .L_after_reduction_DGBGrfFtbtDGuea + je .L_after_reduction_633 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DGBGrfFtbtDGuea: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_13_DlcGrswzomffbed: +.L_after_reduction_633: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_13_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_ohwtArFrtkbhrfh + jae .L_16_blocks_overflow_634 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_ohwtArFrtkbhrfh + jmp .L_16_blocks_ok_634 -.L_16_blocks_overflow_ohwtArFrtkbhrfh: +.L_16_blocks_overflow_634: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -87136,7 +87136,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_ohwtArFrtkbhrfh: +.L_16_blocks_ok_634: @@ -87266,7 +87266,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gciAjgCyCslvyxD + jl .L_small_initial_partial_block_635 @@ -87331,8 +87331,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gciAjgCyCslvyxD -.L_small_initial_partial_block_gciAjgCyCslvyxD: + jmp .L_small_initial_compute_done_635 +.L_small_initial_partial_block_635: @@ -87394,27 +87394,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gciAjgCyCslvyxD: +.L_small_initial_compute_done_635: orq %r8,%r8 - je .L_after_reduction_gciAjgCyCslvyxD + je .L_after_reduction_635 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gciAjgCyCslvyxD: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_14_DlcGrswzomffbed: +.L_after_reduction_635: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_14_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_tzqtBkzxjBrlBag + jae .L_16_blocks_overflow_636 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_tzqtBkzxjBrlBag + jmp .L_16_blocks_ok_636 -.L_16_blocks_overflow_tzqtBkzxjBrlBag: +.L_16_blocks_overflow_636: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -87425,7 +87425,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_tzqtBkzxjBrlBag: +.L_16_blocks_ok_636: @@ -87555,7 +87555,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ryvqbkroifBFpls + jl .L_small_initial_partial_block_637 @@ -87620,8 +87620,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ryvqbkroifBFpls -.L_small_initial_partial_block_ryvqbkroifBFpls: + jmp .L_small_initial_compute_done_637 +.L_small_initial_partial_block_637: @@ -87689,27 +87689,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ryvqbkroifBFpls: +.L_small_initial_compute_done_637: orq %r8,%r8 - je .L_after_reduction_ryvqbkroifBFpls + je .L_after_reduction_637 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ryvqbkroifBFpls: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_15_DlcGrswzomffbed: +.L_after_reduction_637: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_15_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_trczcgzdorhDGwA + jae .L_16_blocks_overflow_638 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_trczcgzdorhDGwA + jmp .L_16_blocks_ok_638 -.L_16_blocks_overflow_trczcgzdorhDGwA: +.L_16_blocks_overflow_638: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -87720,7 +87720,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_trczcgzdorhDGwA: +.L_16_blocks_ok_638: @@ -87850,7 +87850,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_shkqfGqkgxgsnos + jl .L_small_initial_partial_block_639 @@ -87916,8 +87916,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_shkqfGqkgxgsnos -.L_small_initial_partial_block_shkqfGqkgxgsnos: + jmp .L_small_initial_compute_done_639 +.L_small_initial_partial_block_639: @@ -87985,27 +87985,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_shkqfGqkgxgsnos: +.L_small_initial_compute_done_639: orq %r8,%r8 - je .L_after_reduction_shkqfGqkgxgsnos + je .L_after_reduction_639 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_shkqfGqkgxgsnos: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_16_DlcGrswzomffbed: +.L_after_reduction_639: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_16_609: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_BBvnirsFbDcgesl + jae .L_16_blocks_overflow_640 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_BBvnirsFbDcgesl + jmp .L_16_blocks_ok_640 -.L_16_blocks_overflow_BBvnirsFbDcgesl: +.L_16_blocks_overflow_640: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -88016,7 +88016,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_BBvnirsFbDcgesl: +.L_16_blocks_ok_640: @@ -88143,7 +88143,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_fuyrBhBkcpprxbE: +.L_small_initial_partial_block_641: @@ -88212,11 +88212,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fuyrBhBkcpprxbE: +.L_small_initial_compute_done_641: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fuyrBhBkcpprxbE: - jmp .L_last_blocks_done_DlcGrswzomffbed -.L_last_num_blocks_is_0_DlcGrswzomffbed: +.L_after_reduction_641: + jmp .L_last_blocks_done_609 +.L_last_num_blocks_is_0_609: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -88278,65 +88278,65 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_DlcGrswzomffbed: +.L_last_blocks_done_609: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_kpzgFwDvlzADzny + jmp .L_ghash_done_497 -.L_message_below_equal_16_blocks_kpzgFwDvlzADzny: +.L_message_below_equal_16_blocks_497: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_DsqEjAaljoEdzpu - jl .L_small_initial_num_blocks_is_7_1_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_8_642 + jl .L_small_initial_num_blocks_is_7_1_642 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_DsqEjAaljoEdzpu - jl .L_small_initial_num_blocks_is_11_9_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_12_642 + jl .L_small_initial_num_blocks_is_11_9_642 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_16_642 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_15_642 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_DsqEjAaljoEdzpu - jmp .L_small_initial_num_blocks_is_13_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_14_642 + jmp .L_small_initial_num_blocks_is_13_642 -.L_small_initial_num_blocks_is_11_9_DsqEjAaljoEdzpu: +.L_small_initial_num_blocks_is_11_9_642: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_11_642 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_DsqEjAaljoEdzpu - jmp .L_small_initial_num_blocks_is_9_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_10_642 + jmp .L_small_initial_num_blocks_is_9_642 -.L_small_initial_num_blocks_is_7_1_DsqEjAaljoEdzpu: +.L_small_initial_num_blocks_is_7_1_642: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_DsqEjAaljoEdzpu - jl .L_small_initial_num_blocks_is_3_1_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_4_642 + jl .L_small_initial_num_blocks_is_3_1_642 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_7_642 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_DsqEjAaljoEdzpu - jmp .L_small_initial_num_blocks_is_5_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_6_642 + jmp .L_small_initial_num_blocks_is_5_642 -.L_small_initial_num_blocks_is_3_1_DsqEjAaljoEdzpu: +.L_small_initial_num_blocks_is_3_1_642: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_3_642 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_DsqEjAaljoEdzpu + je .L_small_initial_num_blocks_is_2_642 -.L_small_initial_num_blocks_is_1_DsqEjAaljoEdzpu: +.L_small_initial_num_blocks_is_1_642: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -88377,7 +88377,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wDrffiCttqvFnAB + jl .L_small_initial_partial_block_643 @@ -88419,8 +88419,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wDrffiCttqvFnAB -.L_small_initial_partial_block_wDrffiCttqvFnAB: + jmp .L_small_initial_compute_done_643 +.L_small_initial_partial_block_643: @@ -88444,11 +88444,11 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_wDrffiCttqvFnAB -.L_small_initial_compute_done_wDrffiCttqvFnAB: -.L_after_reduction_wDrffiCttqvFnAB: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_2_DsqEjAaljoEdzpu: + jmp .L_after_reduction_643 +.L_small_initial_compute_done_643: +.L_after_reduction_643: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_2_642: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -88491,7 +88491,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dppFolobGnhooBf + jl .L_small_initial_partial_block_644 @@ -88533,8 +88533,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dppFolobGnhooBf -.L_small_initial_partial_block_dppFolobGnhooBf: + jmp .L_small_initial_compute_done_644 +.L_small_initial_partial_block_644: @@ -88579,14 +88579,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dppFolobGnhooBf: +.L_small_initial_compute_done_644: orq %r8,%r8 - je .L_after_reduction_dppFolobGnhooBf + je .L_after_reduction_644 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_dppFolobGnhooBf: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_3_DsqEjAaljoEdzpu: +.L_after_reduction_644: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_3_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -88629,7 +88629,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ifzFszGohGoqoyt + jl .L_small_initial_partial_block_645 @@ -88672,8 +88672,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ifzFszGohGoqoyt -.L_small_initial_partial_block_ifzFszGohGoqoyt: + jmp .L_small_initial_compute_done_645 +.L_small_initial_partial_block_645: @@ -88718,14 +88718,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ifzFszGohGoqoyt: +.L_small_initial_compute_done_645: orq %r8,%r8 - je .L_after_reduction_ifzFszGohGoqoyt + je .L_after_reduction_645 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ifzFszGohGoqoyt: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_4_DsqEjAaljoEdzpu: +.L_after_reduction_645: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_4_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -88768,7 +88768,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gfnktBbhlaqcEDw + jl .L_small_initial_partial_block_646 @@ -88810,8 +88810,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gfnktBbhlaqcEDw -.L_small_initial_partial_block_gfnktBbhlaqcEDw: + jmp .L_small_initial_compute_done_646 +.L_small_initial_partial_block_646: @@ -88857,14 +88857,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gfnktBbhlaqcEDw: +.L_small_initial_compute_done_646: orq %r8,%r8 - je .L_after_reduction_gfnktBbhlaqcEDw + je .L_after_reduction_646 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_gfnktBbhlaqcEDw: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_5_DsqEjAaljoEdzpu: +.L_after_reduction_646: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_5_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -88925,7 +88925,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CfvjfCGbmkmmhsD + jl .L_small_initial_partial_block_647 @@ -88977,8 +88977,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CfvjfCGbmkmmhsD -.L_small_initial_partial_block_CfvjfCGbmkmmhsD: + jmp .L_small_initial_compute_done_647 +.L_small_initial_partial_block_647: @@ -89023,14 +89023,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CfvjfCGbmkmmhsD: +.L_small_initial_compute_done_647: orq %r8,%r8 - je .L_after_reduction_CfvjfCGbmkmmhsD + je .L_after_reduction_647 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_CfvjfCGbmkmmhsD: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_6_DsqEjAaljoEdzpu: +.L_after_reduction_647: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_6_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -89091,7 +89091,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gjvGlFuqAzhBFgv + jl .L_small_initial_partial_block_648 @@ -89143,8 +89143,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gjvGlFuqAzhBFgv -.L_small_initial_partial_block_gjvGlFuqAzhBFgv: + jmp .L_small_initial_compute_done_648 +.L_small_initial_partial_block_648: @@ -89199,14 +89199,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gjvGlFuqAzhBFgv: +.L_small_initial_compute_done_648: orq %r8,%r8 - je .L_after_reduction_gjvGlFuqAzhBFgv + je .L_after_reduction_648 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_gjvGlFuqAzhBFgv: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_7_DsqEjAaljoEdzpu: +.L_after_reduction_648: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_7_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -89267,7 +89267,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oCkFBafhgBayqmr + jl .L_small_initial_partial_block_649 @@ -89320,8 +89320,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oCkFBafhgBayqmr -.L_small_initial_partial_block_oCkFBafhgBayqmr: + jmp .L_small_initial_compute_done_649 +.L_small_initial_partial_block_649: @@ -89376,14 +89376,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oCkFBafhgBayqmr: +.L_small_initial_compute_done_649: orq %r8,%r8 - je .L_after_reduction_oCkFBafhgBayqmr + je .L_after_reduction_649 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_oCkFBafhgBayqmr: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_8_DsqEjAaljoEdzpu: +.L_after_reduction_649: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_8_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -89444,7 +89444,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ppddyowubrBfAuj + jl .L_small_initial_partial_block_650 @@ -89495,8 +89495,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ppddyowubrBfAuj -.L_small_initial_partial_block_ppddyowubrBfAuj: + jmp .L_small_initial_compute_done_650 +.L_small_initial_partial_block_650: @@ -89552,14 +89552,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ppddyowubrBfAuj: +.L_small_initial_compute_done_650: orq %r8,%r8 - je .L_after_reduction_ppddyowubrBfAuj + je .L_after_reduction_650 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ppddyowubrBfAuj: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_9_DsqEjAaljoEdzpu: +.L_after_reduction_650: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_9_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -89637,7 +89637,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AgxkjfmFaBsllFt + jl .L_small_initial_partial_block_651 @@ -89698,8 +89698,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AgxkjfmFaBsllFt -.L_small_initial_partial_block_AgxkjfmFaBsllFt: + jmp .L_small_initial_compute_done_651 +.L_small_initial_partial_block_651: @@ -89753,14 +89753,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AgxkjfmFaBsllFt: +.L_small_initial_compute_done_651: orq %r8,%r8 - je .L_after_reduction_AgxkjfmFaBsllFt + je .L_after_reduction_651 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_AgxkjfmFaBsllFt: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_10_DsqEjAaljoEdzpu: +.L_after_reduction_651: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_10_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -89838,7 +89838,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_imFdEjbAhqFjrdh + jl .L_small_initial_partial_block_652 @@ -89899,8 +89899,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_imFdEjbAhqFjrdh -.L_small_initial_partial_block_imFdEjbAhqFjrdh: + jmp .L_small_initial_compute_done_652 +.L_small_initial_partial_block_652: @@ -89964,14 +89964,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_imFdEjbAhqFjrdh: +.L_small_initial_compute_done_652: orq %r8,%r8 - je .L_after_reduction_imFdEjbAhqFjrdh + je .L_after_reduction_652 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_imFdEjbAhqFjrdh: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_11_DsqEjAaljoEdzpu: +.L_after_reduction_652: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_11_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -90049,7 +90049,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fEEAbqEerxwBqBD + jl .L_small_initial_partial_block_653 @@ -90111,8 +90111,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fEEAbqEerxwBqBD -.L_small_initial_partial_block_fEEAbqEerxwBqBD: + jmp .L_small_initial_compute_done_653 +.L_small_initial_partial_block_653: @@ -90176,14 +90176,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fEEAbqEerxwBqBD: +.L_small_initial_compute_done_653: orq %r8,%r8 - je .L_after_reduction_fEEAbqEerxwBqBD + je .L_after_reduction_653 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_fEEAbqEerxwBqBD: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_12_DsqEjAaljoEdzpu: +.L_after_reduction_653: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_12_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -90261,7 +90261,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xkgdevyggkCptEq + jl .L_small_initial_partial_block_654 @@ -90317,8 +90317,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xkgdevyggkCptEq -.L_small_initial_partial_block_xkgdevyggkCptEq: + jmp .L_small_initial_compute_done_654 +.L_small_initial_partial_block_654: @@ -90383,14 +90383,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xkgdevyggkCptEq: +.L_small_initial_compute_done_654: orq %r8,%r8 - je .L_after_reduction_xkgdevyggkCptEq + je .L_after_reduction_654 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_xkgdevyggkCptEq: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_13_DsqEjAaljoEdzpu: +.L_after_reduction_654: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_13_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -90485,7 +90485,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dzvbuuCqsqFAjxi + jl .L_small_initial_partial_block_655 @@ -90551,8 +90551,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dzvbuuCqsqFAjxi -.L_small_initial_partial_block_dzvbuuCqsqFAjxi: + jmp .L_small_initial_compute_done_655 +.L_small_initial_partial_block_655: @@ -90611,14 +90611,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dzvbuuCqsqFAjxi: +.L_small_initial_compute_done_655: orq %r8,%r8 - je .L_after_reduction_dzvbuuCqsqFAjxi + je .L_after_reduction_655 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_dzvbuuCqsqFAjxi: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_14_DsqEjAaljoEdzpu: +.L_after_reduction_655: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_14_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -90713,7 +90713,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hhtqnAhdhxjjDnc + jl .L_small_initial_partial_block_656 @@ -90779,8 +90779,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hhtqnAhdhxjjDnc -.L_small_initial_partial_block_hhtqnAhdhxjjDnc: + jmp .L_small_initial_compute_done_656 +.L_small_initial_partial_block_656: @@ -90849,14 +90849,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hhtqnAhdhxjjDnc: +.L_small_initial_compute_done_656: orq %r8,%r8 - je .L_after_reduction_hhtqnAhdhxjjDnc + je .L_after_reduction_656 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_hhtqnAhdhxjjDnc: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_15_DsqEjAaljoEdzpu: +.L_after_reduction_656: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_15_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -90951,7 +90951,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GagurgckAhoCdcw + jl .L_small_initial_partial_block_657 @@ -91018,8 +91018,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GagurgckAhoCdcw -.L_small_initial_partial_block_GagurgckAhoCdcw: + jmp .L_small_initial_compute_done_657 +.L_small_initial_partial_block_657: @@ -91088,14 +91088,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GagurgckAhoCdcw: +.L_small_initial_compute_done_657: orq %r8,%r8 - je .L_after_reduction_GagurgckAhoCdcw + je .L_after_reduction_657 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_GagurgckAhoCdcw: - jmp .L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu -.L_small_initial_num_blocks_is_16_DsqEjAaljoEdzpu: +.L_after_reduction_657: + jmp .L_small_initial_blocks_encrypted_642 +.L_small_initial_num_blocks_is_16_642: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -91187,7 +91187,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm11,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_msiFyqpegCpyxxg: +.L_small_initial_partial_block_658: @@ -91257,25 +91257,25 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_msiFyqpegCpyxxg: +.L_small_initial_compute_done_658: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_msiFyqpegCpyxxg: -.L_small_initial_blocks_encrypted_DsqEjAaljoEdzpu: -.L_ghash_done_kpzgFwDvlzADzny: +.L_after_reduction_658: +.L_small_initial_blocks_encrypted_642: +.L_ghash_done_497: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_kpzgFwDvlzADzny: +.L_enc_dec_done_497: jmp .Lexit_gcm_decrypt .align 32 .Laes_gcm_decrypt_192_avx512: orq %r8,%r8 - je .L_enc_dec_done_EzeEqCiibleghsn + je .L_enc_dec_done_659 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_pocxztyqAyxmwtm + je .L_partial_block_done_660 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -91299,9 +91299,9 @@ ossl_aes_gcm_decrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_pocxztyqAyxmwtm + jge .L_no_extra_mask_660 subq %r13,%r12 -.L_no_extra_mask_pocxztyqAyxmwtm: +.L_no_extra_mask_660: @@ -91312,7 +91312,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %xmm5,%xmm6,%xmm6 vpxorq %xmm6,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_pocxztyqAyxmwtm + jl .L_partial_incomplete_660 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -91347,13 +91347,13 @@ ossl_aes_gcm_decrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_pocxztyqAyxmwtm + jmp .L_enc_dec_done_660 -.L_partial_incomplete_pocxztyqAyxmwtm: +.L_partial_incomplete_660: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_pocxztyqAyxmwtm: +.L_enc_dec_done_660: leaq byte_len_to_mask_table(%rip),%r12 @@ -91361,12 +91361,12 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 %xmm14,64(%rsi) movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_pocxztyqAyxmwtm: +.L_partial_block_done_660: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_EzeEqCiibleghsn + je .L_enc_dec_done_659 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_EzeEqCiibleghsn + jbe .L_message_below_equal_16_blocks_659 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -91386,13 +91386,13 @@ ossl_aes_gcm_decrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_ieDmAmkljrpjbff + jae .L_next_16_overflow_661 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_ieDmAmkljrpjbff -.L_next_16_overflow_ieDmAmkljrpjbff: + jmp .L_next_16_ok_661 +.L_next_16_overflow_661: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -91403,7 +91403,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_ieDmAmkljrpjbff: +.L_next_16_ok_661: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -91501,7 +91501,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_BGpcsxikchdBGhx + jnz .L_skip_hkeys_precomputation_662 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -91517,20 +91517,20 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_BGpcsxikchdBGhx: +.L_skip_hkeys_precomputation_662: cmpq $512,%r8 - jb .L_message_below_32_blocks_EzeEqCiibleghsn + jb .L_message_below_32_blocks_659 cmpb $240,%r15b - jae .L_next_16_overflow_spxfotGswBArhxl + jae .L_next_16_overflow_663 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_spxfotGswBArhxl -.L_next_16_overflow_spxfotGswBArhxl: + jmp .L_next_16_ok_663 +.L_next_16_overflow_663: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -91541,7 +91541,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_spxfotGswBArhxl: +.L_next_16_ok_663: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -91639,7 +91639,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_DjDdtxEBzmsFEoE + jnz .L_skip_hkeys_precomputation_664 vmovdqu64 640(%rsp),%zmm3 @@ -91887,22 +91887,22 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_DjDdtxEBzmsFEoE: +.L_skip_hkeys_precomputation_664: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_EzeEqCiibleghsn -.L_encrypt_big_nblocks_EzeEqCiibleghsn: + jb .L_no_more_big_nblocks_659 +.L_encrypt_big_nblocks_659: cmpb $240,%r15b - jae .L_16_blocks_overflow_uxeoxcoFtrFyBxG + jae .L_16_blocks_overflow_665 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_uxeoxcoFtrFyBxG -.L_16_blocks_overflow_uxeoxcoFtrFyBxG: + jmp .L_16_blocks_ok_665 +.L_16_blocks_overflow_665: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -91913,7 +91913,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_uxeoxcoFtrFyBxG: +.L_16_blocks_ok_665: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -92089,13 +92089,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_nbmbogBBzeFBgAi + jae .L_16_blocks_overflow_666 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_nbmbogBBzeFBgAi -.L_16_blocks_overflow_nbmbogBBzeFBgAi: + jmp .L_16_blocks_ok_666 +.L_16_blocks_overflow_666: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -92106,7 +92106,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_nbmbogBBzeFBgAi: +.L_16_blocks_ok_666: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -92282,13 +92282,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_alEoAwdFvzkfsuG + jae .L_16_blocks_overflow_667 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_alEoAwdFvzkfsuG -.L_16_blocks_overflow_alEoAwdFvzkfsuG: + jmp .L_16_blocks_ok_667 +.L_16_blocks_overflow_667: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -92299,7 +92299,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_alEoAwdFvzkfsuG: +.L_16_blocks_ok_667: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -92505,16 +92505,16 @@ ossl_aes_gcm_decrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_EzeEqCiibleghsn + jae .L_encrypt_big_nblocks_659 -.L_no_more_big_nblocks_EzeEqCiibleghsn: +.L_no_more_big_nblocks_659: cmpq $512,%r8 - jae .L_encrypt_32_blocks_EzeEqCiibleghsn + jae .L_encrypt_32_blocks_659 cmpq $256,%r8 - jae .L_encrypt_16_blocks_EzeEqCiibleghsn -.L_encrypt_0_blocks_ghash_32_EzeEqCiibleghsn: + jae .L_encrypt_16_blocks_659 +.L_encrypt_0_blocks_ghash_32_659: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -92557,61 +92557,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_0_668 cmpl $8,%r10d - je .L_last_num_blocks_is_8_EtDGBzcxfwaqvwq - jb .L_last_num_blocks_is_7_1_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_8_668 + jb .L_last_num_blocks_is_7_1_668 cmpl $12,%r10d - je .L_last_num_blocks_is_12_EtDGBzcxfwaqvwq - jb .L_last_num_blocks_is_11_9_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_12_668 + jb .L_last_num_blocks_is_11_9_668 cmpl $15,%r10d - je .L_last_num_blocks_is_15_EtDGBzcxfwaqvwq - ja .L_last_num_blocks_is_16_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_15_668 + ja .L_last_num_blocks_is_16_668 cmpl $14,%r10d - je .L_last_num_blocks_is_14_EtDGBzcxfwaqvwq - jmp .L_last_num_blocks_is_13_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_14_668 + jmp .L_last_num_blocks_is_13_668 -.L_last_num_blocks_is_11_9_EtDGBzcxfwaqvwq: +.L_last_num_blocks_is_11_9_668: cmpl $10,%r10d - je .L_last_num_blocks_is_10_EtDGBzcxfwaqvwq - ja .L_last_num_blocks_is_11_EtDGBzcxfwaqvwq - jmp .L_last_num_blocks_is_9_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_10_668 + ja .L_last_num_blocks_is_11_668 + jmp .L_last_num_blocks_is_9_668 -.L_last_num_blocks_is_7_1_EtDGBzcxfwaqvwq: +.L_last_num_blocks_is_7_1_668: cmpl $4,%r10d - je .L_last_num_blocks_is_4_EtDGBzcxfwaqvwq - jb .L_last_num_blocks_is_3_1_EtDGBzcxfwaqvwq + je .L_last_num_blocks_is_4_668 + jb .L_last_num_blocks_is_3_1_668 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_EtDGBzcxfwaqvwq - je .L_last_num_blocks_is_6_EtDGBzcxfwaqvwq - jmp .L_last_num_blocks_is_5_EtDGBzcxfwaqvwq + ja .L_last_num_blocks_is_7_668 + je .L_last_num_blocks_is_6_668 + jmp .L_last_num_blocks_is_5_668 -.L_last_num_blocks_is_3_1_EtDGBzcxfwaqvwq: +.L_last_num_blocks_is_3_1_668: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_EtDGBzcxfwaqvwq - je .L_last_num_blocks_is_2_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_1_EtDGBzcxfwaqvwq: + ja .L_last_num_blocks_is_3_668 + je .L_last_num_blocks_is_2_668 +.L_last_num_blocks_is_1_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_emtfasfkmFpqGwC + jae .L_16_blocks_overflow_669 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_emtfasfkmFpqGwC + jmp .L_16_blocks_ok_669 -.L_16_blocks_overflow_emtfasfkmFpqGwC: +.L_16_blocks_overflow_669: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_emtfasfkmFpqGwC: +.L_16_blocks_ok_669: @@ -92699,7 +92699,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DzzcmycigpAuawj + jl .L_small_initial_partial_block_670 @@ -92743,8 +92743,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DzzcmycigpAuawj -.L_small_initial_partial_block_DzzcmycigpAuawj: + jmp .L_small_initial_compute_done_670 +.L_small_initial_partial_block_670: @@ -92796,24 +92796,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_DzzcmycigpAuawj -.L_small_initial_compute_done_DzzcmycigpAuawj: -.L_after_reduction_DzzcmycigpAuawj: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_2_EtDGBzcxfwaqvwq: + jmp .L_after_reduction_670 +.L_small_initial_compute_done_670: +.L_after_reduction_670: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_2_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_gEssdDoywAFyakk + jae .L_16_blocks_overflow_671 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_gEssdDoywAFyakk + jmp .L_16_blocks_ok_671 -.L_16_blocks_overflow_gEssdDoywAFyakk: +.L_16_blocks_overflow_671: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_gEssdDoywAFyakk: +.L_16_blocks_ok_671: @@ -92902,7 +92902,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DbplxubvBmAwufj + jl .L_small_initial_partial_block_672 @@ -92946,8 +92946,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DbplxubvBmAwufj -.L_small_initial_partial_block_DbplxubvBmAwufj: + jmp .L_small_initial_compute_done_672 +.L_small_initial_partial_block_672: @@ -92994,27 +92994,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DbplxubvBmAwufj: +.L_small_initial_compute_done_672: orq %r8,%r8 - je .L_after_reduction_DbplxubvBmAwufj + je .L_after_reduction_672 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DbplxubvBmAwufj: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_3_EtDGBzcxfwaqvwq: +.L_after_reduction_672: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_3_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_uabrGaohoEDrpqh + jae .L_16_blocks_overflow_673 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_uabrGaohoEDrpqh + jmp .L_16_blocks_ok_673 -.L_16_blocks_overflow_uabrGaohoEDrpqh: +.L_16_blocks_overflow_673: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_uabrGaohoEDrpqh: +.L_16_blocks_ok_673: @@ -93103,7 +93103,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vhAmsAgAuuuguvl + jl .L_small_initial_partial_block_674 @@ -93148,8 +93148,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vhAmsAgAuuuguvl -.L_small_initial_partial_block_vhAmsAgAuuuguvl: + jmp .L_small_initial_compute_done_674 +.L_small_initial_partial_block_674: @@ -93196,27 +93196,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vhAmsAgAuuuguvl: +.L_small_initial_compute_done_674: orq %r8,%r8 - je .L_after_reduction_vhAmsAgAuuuguvl + je .L_after_reduction_674 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vhAmsAgAuuuguvl: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_4_EtDGBzcxfwaqvwq: +.L_after_reduction_674: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_4_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_FycAihaCDpEefhy + jae .L_16_blocks_overflow_675 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_FycAihaCDpEefhy + jmp .L_16_blocks_ok_675 -.L_16_blocks_overflow_FycAihaCDpEefhy: +.L_16_blocks_overflow_675: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_FycAihaCDpEefhy: +.L_16_blocks_ok_675: @@ -93305,7 +93305,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BDpnskmakFrmdmj + jl .L_small_initial_partial_block_676 @@ -93350,8 +93350,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BDpnskmakFrmdmj -.L_small_initial_partial_block_BDpnskmakFrmdmj: + jmp .L_small_initial_compute_done_676 +.L_small_initial_partial_block_676: @@ -93399,32 +93399,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BDpnskmakFrmdmj: +.L_small_initial_compute_done_676: orq %r8,%r8 - je .L_after_reduction_BDpnskmakFrmdmj + je .L_after_reduction_676 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BDpnskmakFrmdmj: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_5_EtDGBzcxfwaqvwq: +.L_after_reduction_676: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_5_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_nCmmkacdueAtaoF + jae .L_16_blocks_overflow_677 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_nCmmkacdueAtaoF + jmp .L_16_blocks_ok_677 -.L_16_blocks_overflow_nCmmkacdueAtaoF: +.L_16_blocks_overflow_677: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_nCmmkacdueAtaoF: +.L_16_blocks_ok_677: @@ -93530,7 +93530,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oDgGkzrGfgvGdwk + jl .L_small_initial_partial_block_678 @@ -93581,8 +93581,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oDgGkzrGfgvGdwk -.L_small_initial_partial_block_oDgGkzrGfgvGdwk: + jmp .L_small_initial_compute_done_678 +.L_small_initial_partial_block_678: @@ -93630,32 +93630,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oDgGkzrGfgvGdwk: +.L_small_initial_compute_done_678: orq %r8,%r8 - je .L_after_reduction_oDgGkzrGfgvGdwk + je .L_after_reduction_678 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_oDgGkzrGfgvGdwk: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_6_EtDGBzcxfwaqvwq: +.L_after_reduction_678: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_6_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_palkiliGxbhbFAC + jae .L_16_blocks_overflow_679 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_palkiliGxbhbFAC + jmp .L_16_blocks_ok_679 -.L_16_blocks_overflow_palkiliGxbhbFAC: +.L_16_blocks_overflow_679: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_palkiliGxbhbFAC: +.L_16_blocks_ok_679: @@ -93761,7 +93761,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_umCjlCCFasAvtzn + jl .L_small_initial_partial_block_680 @@ -93812,8 +93812,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_umCjlCCFasAvtzn -.L_small_initial_partial_block_umCjlCCFasAvtzn: + jmp .L_small_initial_compute_done_680 +.L_small_initial_partial_block_680: @@ -93867,32 +93867,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_umCjlCCFasAvtzn: +.L_small_initial_compute_done_680: orq %r8,%r8 - je .L_after_reduction_umCjlCCFasAvtzn + je .L_after_reduction_680 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_umCjlCCFasAvtzn: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_7_EtDGBzcxfwaqvwq: +.L_after_reduction_680: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_7_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_tnGCjqdzshaDAbm + jae .L_16_blocks_overflow_681 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_tnGCjqdzshaDAbm + jmp .L_16_blocks_ok_681 -.L_16_blocks_overflow_tnGCjqdzshaDAbm: +.L_16_blocks_overflow_681: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_tnGCjqdzshaDAbm: +.L_16_blocks_ok_681: @@ -93998,7 +93998,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yCGvvmGrsrmcfjx + jl .L_small_initial_partial_block_682 @@ -94050,8 +94050,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yCGvvmGrsrmcfjx -.L_small_initial_partial_block_yCGvvmGrsrmcfjx: + jmp .L_small_initial_compute_done_682 +.L_small_initial_partial_block_682: @@ -94105,32 +94105,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yCGvvmGrsrmcfjx: +.L_small_initial_compute_done_682: orq %r8,%r8 - je .L_after_reduction_yCGvvmGrsrmcfjx + je .L_after_reduction_682 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yCGvvmGrsrmcfjx: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_8_EtDGBzcxfwaqvwq: +.L_after_reduction_682: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_8_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_vnEbhBvuovesEqt + jae .L_16_blocks_overflow_683 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_vnEbhBvuovesEqt + jmp .L_16_blocks_ok_683 -.L_16_blocks_overflow_vnEbhBvuovesEqt: +.L_16_blocks_overflow_683: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_vnEbhBvuovesEqt: +.L_16_blocks_ok_683: @@ -94236,7 +94236,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hgobxynnyhyvFEu + jl .L_small_initial_partial_block_684 @@ -94290,8 +94290,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hgobxynnyhyvFEu -.L_small_initial_partial_block_hgobxynnyhyvFEu: + jmp .L_small_initial_compute_done_684 +.L_small_initial_partial_block_684: @@ -94346,26 +94346,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hgobxynnyhyvFEu: +.L_small_initial_compute_done_684: orq %r8,%r8 - je .L_after_reduction_hgobxynnyhyvFEu + je .L_after_reduction_684 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hgobxynnyhyvFEu: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_9_EtDGBzcxfwaqvwq: +.L_after_reduction_684: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_9_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_vbfizqxwtwrzByC + jae .L_16_blocks_overflow_685 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_vbfizqxwtwrzByC + jmp .L_16_blocks_ok_685 -.L_16_blocks_overflow_vbfizqxwtwrzByC: +.L_16_blocks_overflow_685: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -94374,7 +94374,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_vbfizqxwtwrzByC: +.L_16_blocks_ok_685: @@ -94497,7 +94497,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_pwxrwgquughvsdb + jl .L_small_initial_partial_block_686 @@ -94557,8 +94557,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_pwxrwgquughvsdb -.L_small_initial_partial_block_pwxrwgquughvsdb: + jmp .L_small_initial_compute_done_686 +.L_small_initial_partial_block_686: @@ -94615,26 +94615,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_pwxrwgquughvsdb: +.L_small_initial_compute_done_686: orq %r8,%r8 - je .L_after_reduction_pwxrwgquughvsdb + je .L_after_reduction_686 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_pwxrwgquughvsdb: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_10_EtDGBzcxfwaqvwq: +.L_after_reduction_686: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_10_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_buoEAkakxdqjsuk + jae .L_16_blocks_overflow_687 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_buoEAkakxdqjsuk + jmp .L_16_blocks_ok_687 -.L_16_blocks_overflow_buoEAkakxdqjsuk: +.L_16_blocks_overflow_687: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -94643,7 +94643,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_buoEAkakxdqjsuk: +.L_16_blocks_ok_687: @@ -94766,7 +94766,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ibbqcmezxDorlzw + jl .L_small_initial_partial_block_688 @@ -94826,8 +94826,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ibbqcmezxDorlzw -.L_small_initial_partial_block_ibbqcmezxDorlzw: + jmp .L_small_initial_compute_done_688 +.L_small_initial_partial_block_688: @@ -94890,26 +94890,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ibbqcmezxDorlzw: +.L_small_initial_compute_done_688: orq %r8,%r8 - je .L_after_reduction_ibbqcmezxDorlzw + je .L_after_reduction_688 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ibbqcmezxDorlzw: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_11_EtDGBzcxfwaqvwq: +.L_after_reduction_688: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_11_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_EGvivBgfdydbuzD + jae .L_16_blocks_overflow_689 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_EGvivBgfdydbuzD + jmp .L_16_blocks_ok_689 -.L_16_blocks_overflow_EGvivBgfdydbuzD: +.L_16_blocks_overflow_689: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -94918,7 +94918,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_EGvivBgfdydbuzD: +.L_16_blocks_ok_689: @@ -95041,7 +95041,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dhoriADdDwBlxCB + jl .L_small_initial_partial_block_690 @@ -95102,8 +95102,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dhoriADdDwBlxCB -.L_small_initial_partial_block_dhoriADdDwBlxCB: + jmp .L_small_initial_compute_done_690 +.L_small_initial_partial_block_690: @@ -95166,26 +95166,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dhoriADdDwBlxCB: +.L_small_initial_compute_done_690: orq %r8,%r8 - je .L_after_reduction_dhoriADdDwBlxCB + je .L_after_reduction_690 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dhoriADdDwBlxCB: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_12_EtDGBzcxfwaqvwq: +.L_after_reduction_690: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_12_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_gyobuGFejkEsifA + jae .L_16_blocks_overflow_691 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_gyobuGFejkEsifA + jmp .L_16_blocks_ok_691 -.L_16_blocks_overflow_gyobuGFejkEsifA: +.L_16_blocks_overflow_691: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -95194,7 +95194,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_gyobuGFejkEsifA: +.L_16_blocks_ok_691: @@ -95317,7 +95317,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aCtmxmnypmbdnlG + jl .L_small_initial_partial_block_692 @@ -95376,8 +95376,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aCtmxmnypmbdnlG -.L_small_initial_partial_block_aCtmxmnypmbdnlG: + jmp .L_small_initial_compute_done_692 +.L_small_initial_partial_block_692: @@ -95441,27 +95441,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aCtmxmnypmbdnlG: +.L_small_initial_compute_done_692: orq %r8,%r8 - je .L_after_reduction_aCtmxmnypmbdnlG + je .L_after_reduction_692 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aCtmxmnypmbdnlG: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_13_EtDGBzcxfwaqvwq: +.L_after_reduction_692: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_13_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_taFnwxshgpAGqGv + jae .L_16_blocks_overflow_693 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_taFnwxshgpAGqGv + jmp .L_16_blocks_ok_693 -.L_16_blocks_overflow_taFnwxshgpAGqGv: +.L_16_blocks_overflow_693: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -95472,7 +95472,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_taFnwxshgpAGqGv: +.L_16_blocks_ok_693: @@ -95612,7 +95612,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_snqyptpnCrnsjCe + jl .L_small_initial_partial_block_694 @@ -95677,8 +95677,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_snqyptpnCrnsjCe -.L_small_initial_partial_block_snqyptpnCrnsjCe: + jmp .L_small_initial_compute_done_694 +.L_small_initial_partial_block_694: @@ -95740,27 +95740,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_snqyptpnCrnsjCe: +.L_small_initial_compute_done_694: orq %r8,%r8 - je .L_after_reduction_snqyptpnCrnsjCe + je .L_after_reduction_694 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_snqyptpnCrnsjCe: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_14_EtDGBzcxfwaqvwq: +.L_after_reduction_694: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_14_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_oglwgnsskgyfFsh + jae .L_16_blocks_overflow_695 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_oglwgnsskgyfFsh + jmp .L_16_blocks_ok_695 -.L_16_blocks_overflow_oglwgnsskgyfFsh: +.L_16_blocks_overflow_695: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -95771,7 +95771,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_oglwgnsskgyfFsh: +.L_16_blocks_ok_695: @@ -95911,7 +95911,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wftlFGlgwbgBqlw + jl .L_small_initial_partial_block_696 @@ -95976,8 +95976,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wftlFGlgwbgBqlw -.L_small_initial_partial_block_wftlFGlgwbgBqlw: + jmp .L_small_initial_compute_done_696 +.L_small_initial_partial_block_696: @@ -96045,27 +96045,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wftlFGlgwbgBqlw: +.L_small_initial_compute_done_696: orq %r8,%r8 - je .L_after_reduction_wftlFGlgwbgBqlw + je .L_after_reduction_696 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wftlFGlgwbgBqlw: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_15_EtDGBzcxfwaqvwq: +.L_after_reduction_696: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_15_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_AAAoijaFeouxBhg + jae .L_16_blocks_overflow_697 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_AAAoijaFeouxBhg + jmp .L_16_blocks_ok_697 -.L_16_blocks_overflow_AAAoijaFeouxBhg: +.L_16_blocks_overflow_697: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -96076,7 +96076,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_AAAoijaFeouxBhg: +.L_16_blocks_ok_697: @@ -96216,7 +96216,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EACeBkmeriiasmr + jl .L_small_initial_partial_block_698 @@ -96282,8 +96282,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EACeBkmeriiasmr -.L_small_initial_partial_block_EACeBkmeriiasmr: + jmp .L_small_initial_compute_done_698 +.L_small_initial_partial_block_698: @@ -96351,27 +96351,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EACeBkmeriiasmr: +.L_small_initial_compute_done_698: orq %r8,%r8 - je .L_after_reduction_EACeBkmeriiasmr + je .L_after_reduction_698 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EACeBkmeriiasmr: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_16_EtDGBzcxfwaqvwq: +.L_after_reduction_698: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_16_668: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_juadzxekinxtnGm + jae .L_16_blocks_overflow_699 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_juadzxekinxtnGm + jmp .L_16_blocks_ok_699 -.L_16_blocks_overflow_juadzxekinxtnGm: +.L_16_blocks_overflow_699: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -96382,7 +96382,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_juadzxekinxtnGm: +.L_16_blocks_ok_699: @@ -96519,7 +96519,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_qiEozgpltoFunBi: +.L_small_initial_partial_block_700: @@ -96588,11 +96588,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qiEozgpltoFunBi: +.L_small_initial_compute_done_700: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qiEozgpltoFunBi: - jmp .L_last_blocks_done_EtDGBzcxfwaqvwq -.L_last_num_blocks_is_0_EtDGBzcxfwaqvwq: +.L_after_reduction_700: + jmp .L_last_blocks_done_668 +.L_last_num_blocks_is_0_668: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -96653,18 +96653,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_EtDGBzcxfwaqvwq: +.L_last_blocks_done_668: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_EzeEqCiibleghsn -.L_encrypt_32_blocks_EzeEqCiibleghsn: + jmp .L_ghash_done_659 +.L_encrypt_32_blocks_659: cmpb $240,%r15b - jae .L_16_blocks_overflow_umgxFkoonxsadya + jae .L_16_blocks_overflow_701 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_umgxFkoonxsadya -.L_16_blocks_overflow_umgxFkoonxsadya: + jmp .L_16_blocks_ok_701 +.L_16_blocks_overflow_701: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -96675,7 +96675,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_umgxFkoonxsadya: +.L_16_blocks_ok_701: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -96851,13 +96851,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_tfmnhiGDkehnasm + jae .L_16_blocks_overflow_702 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_tfmnhiGDkehnasm -.L_16_blocks_overflow_tfmnhiGDkehnasm: + jmp .L_16_blocks_ok_702 +.L_16_blocks_overflow_702: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -96868,7 +96868,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_tfmnhiGDkehnasm: +.L_16_blocks_ok_702: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -97112,61 +97112,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_eFaDobhDcadAiew + je .L_last_num_blocks_is_0_703 cmpl $8,%r10d - je .L_last_num_blocks_is_8_eFaDobhDcadAiew - jb .L_last_num_blocks_is_7_1_eFaDobhDcadAiew + je .L_last_num_blocks_is_8_703 + jb .L_last_num_blocks_is_7_1_703 cmpl $12,%r10d - je .L_last_num_blocks_is_12_eFaDobhDcadAiew - jb .L_last_num_blocks_is_11_9_eFaDobhDcadAiew + je .L_last_num_blocks_is_12_703 + jb .L_last_num_blocks_is_11_9_703 cmpl $15,%r10d - je .L_last_num_blocks_is_15_eFaDobhDcadAiew - ja .L_last_num_blocks_is_16_eFaDobhDcadAiew + je .L_last_num_blocks_is_15_703 + ja .L_last_num_blocks_is_16_703 cmpl $14,%r10d - je .L_last_num_blocks_is_14_eFaDobhDcadAiew - jmp .L_last_num_blocks_is_13_eFaDobhDcadAiew + je .L_last_num_blocks_is_14_703 + jmp .L_last_num_blocks_is_13_703 -.L_last_num_blocks_is_11_9_eFaDobhDcadAiew: +.L_last_num_blocks_is_11_9_703: cmpl $10,%r10d - je .L_last_num_blocks_is_10_eFaDobhDcadAiew - ja .L_last_num_blocks_is_11_eFaDobhDcadAiew - jmp .L_last_num_blocks_is_9_eFaDobhDcadAiew + je .L_last_num_blocks_is_10_703 + ja .L_last_num_blocks_is_11_703 + jmp .L_last_num_blocks_is_9_703 -.L_last_num_blocks_is_7_1_eFaDobhDcadAiew: +.L_last_num_blocks_is_7_1_703: cmpl $4,%r10d - je .L_last_num_blocks_is_4_eFaDobhDcadAiew - jb .L_last_num_blocks_is_3_1_eFaDobhDcadAiew + je .L_last_num_blocks_is_4_703 + jb .L_last_num_blocks_is_3_1_703 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_eFaDobhDcadAiew - je .L_last_num_blocks_is_6_eFaDobhDcadAiew - jmp .L_last_num_blocks_is_5_eFaDobhDcadAiew + ja .L_last_num_blocks_is_7_703 + je .L_last_num_blocks_is_6_703 + jmp .L_last_num_blocks_is_5_703 -.L_last_num_blocks_is_3_1_eFaDobhDcadAiew: +.L_last_num_blocks_is_3_1_703: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_eFaDobhDcadAiew - je .L_last_num_blocks_is_2_eFaDobhDcadAiew -.L_last_num_blocks_is_1_eFaDobhDcadAiew: + ja .L_last_num_blocks_is_3_703 + je .L_last_num_blocks_is_2_703 +.L_last_num_blocks_is_1_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_jAmvpArrgcBDchj + jae .L_16_blocks_overflow_704 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_jAmvpArrgcBDchj + jmp .L_16_blocks_ok_704 -.L_16_blocks_overflow_jAmvpArrgcBDchj: +.L_16_blocks_overflow_704: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_jAmvpArrgcBDchj: +.L_16_blocks_ok_704: @@ -97254,7 +97254,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kmhBhcmgnbwiyhq + jl .L_small_initial_partial_block_705 @@ -97298,8 +97298,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kmhBhcmgnbwiyhq -.L_small_initial_partial_block_kmhBhcmgnbwiyhq: + jmp .L_small_initial_compute_done_705 +.L_small_initial_partial_block_705: @@ -97351,24 +97351,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_kmhBhcmgnbwiyhq -.L_small_initial_compute_done_kmhBhcmgnbwiyhq: -.L_after_reduction_kmhBhcmgnbwiyhq: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_2_eFaDobhDcadAiew: + jmp .L_after_reduction_705 +.L_small_initial_compute_done_705: +.L_after_reduction_705: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_2_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_qrrktncehlzzmhc + jae .L_16_blocks_overflow_706 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_qrrktncehlzzmhc + jmp .L_16_blocks_ok_706 -.L_16_blocks_overflow_qrrktncehlzzmhc: +.L_16_blocks_overflow_706: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_qrrktncehlzzmhc: +.L_16_blocks_ok_706: @@ -97457,7 +97457,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CjbFEfcksDuGtzc + jl .L_small_initial_partial_block_707 @@ -97501,8 +97501,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CjbFEfcksDuGtzc -.L_small_initial_partial_block_CjbFEfcksDuGtzc: + jmp .L_small_initial_compute_done_707 +.L_small_initial_partial_block_707: @@ -97549,27 +97549,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CjbFEfcksDuGtzc: +.L_small_initial_compute_done_707: orq %r8,%r8 - je .L_after_reduction_CjbFEfcksDuGtzc + je .L_after_reduction_707 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CjbFEfcksDuGtzc: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_3_eFaDobhDcadAiew: +.L_after_reduction_707: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_3_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_ajAowpxEqljEBmp + jae .L_16_blocks_overflow_708 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_ajAowpxEqljEBmp + jmp .L_16_blocks_ok_708 -.L_16_blocks_overflow_ajAowpxEqljEBmp: +.L_16_blocks_overflow_708: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_ajAowpxEqljEBmp: +.L_16_blocks_ok_708: @@ -97658,7 +97658,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_duchEjElhyEebmG + jl .L_small_initial_partial_block_709 @@ -97703,8 +97703,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_duchEjElhyEebmG -.L_small_initial_partial_block_duchEjElhyEebmG: + jmp .L_small_initial_compute_done_709 +.L_small_initial_partial_block_709: @@ -97751,27 +97751,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_duchEjElhyEebmG: +.L_small_initial_compute_done_709: orq %r8,%r8 - je .L_after_reduction_duchEjElhyEebmG + je .L_after_reduction_709 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_duchEjElhyEebmG: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_4_eFaDobhDcadAiew: +.L_after_reduction_709: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_4_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_jzeBqbkAzdfywvg + jae .L_16_blocks_overflow_710 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_jzeBqbkAzdfywvg + jmp .L_16_blocks_ok_710 -.L_16_blocks_overflow_jzeBqbkAzdfywvg: +.L_16_blocks_overflow_710: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_jzeBqbkAzdfywvg: +.L_16_blocks_ok_710: @@ -97860,7 +97860,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CudjcBuhoGulDFa + jl .L_small_initial_partial_block_711 @@ -97905,8 +97905,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CudjcBuhoGulDFa -.L_small_initial_partial_block_CudjcBuhoGulDFa: + jmp .L_small_initial_compute_done_711 +.L_small_initial_partial_block_711: @@ -97954,32 +97954,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CudjcBuhoGulDFa: +.L_small_initial_compute_done_711: orq %r8,%r8 - je .L_after_reduction_CudjcBuhoGulDFa + je .L_after_reduction_711 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CudjcBuhoGulDFa: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_5_eFaDobhDcadAiew: +.L_after_reduction_711: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_5_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_ojzaExBznEnewaC + jae .L_16_blocks_overflow_712 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_ojzaExBznEnewaC + jmp .L_16_blocks_ok_712 -.L_16_blocks_overflow_ojzaExBznEnewaC: +.L_16_blocks_overflow_712: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_ojzaExBznEnewaC: +.L_16_blocks_ok_712: @@ -98085,7 +98085,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qvszBimGsckkGyu + jl .L_small_initial_partial_block_713 @@ -98136,8 +98136,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qvszBimGsckkGyu -.L_small_initial_partial_block_qvszBimGsckkGyu: + jmp .L_small_initial_compute_done_713 +.L_small_initial_partial_block_713: @@ -98185,32 +98185,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qvszBimGsckkGyu: +.L_small_initial_compute_done_713: orq %r8,%r8 - je .L_after_reduction_qvszBimGsckkGyu + je .L_after_reduction_713 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qvszBimGsckkGyu: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_6_eFaDobhDcadAiew: +.L_after_reduction_713: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_6_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_apDaAGbgiFxffdq + jae .L_16_blocks_overflow_714 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_apDaAGbgiFxffdq + jmp .L_16_blocks_ok_714 -.L_16_blocks_overflow_apDaAGbgiFxffdq: +.L_16_blocks_overflow_714: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_apDaAGbgiFxffdq: +.L_16_blocks_ok_714: @@ -98316,7 +98316,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xegeCthCandioit + jl .L_small_initial_partial_block_715 @@ -98367,8 +98367,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xegeCthCandioit -.L_small_initial_partial_block_xegeCthCandioit: + jmp .L_small_initial_compute_done_715 +.L_small_initial_partial_block_715: @@ -98422,32 +98422,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xegeCthCandioit: +.L_small_initial_compute_done_715: orq %r8,%r8 - je .L_after_reduction_xegeCthCandioit + je .L_after_reduction_715 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xegeCthCandioit: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_7_eFaDobhDcadAiew: +.L_after_reduction_715: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_7_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_pzrtiFljlwyuEdt + jae .L_16_blocks_overflow_716 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_pzrtiFljlwyuEdt + jmp .L_16_blocks_ok_716 -.L_16_blocks_overflow_pzrtiFljlwyuEdt: +.L_16_blocks_overflow_716: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_pzrtiFljlwyuEdt: +.L_16_blocks_ok_716: @@ -98553,7 +98553,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CxxyFnmdqCDsirp + jl .L_small_initial_partial_block_717 @@ -98605,8 +98605,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CxxyFnmdqCDsirp -.L_small_initial_partial_block_CxxyFnmdqCDsirp: + jmp .L_small_initial_compute_done_717 +.L_small_initial_partial_block_717: @@ -98660,32 +98660,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CxxyFnmdqCDsirp: +.L_small_initial_compute_done_717: orq %r8,%r8 - je .L_after_reduction_CxxyFnmdqCDsirp + je .L_after_reduction_717 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_CxxyFnmdqCDsirp: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_8_eFaDobhDcadAiew: +.L_after_reduction_717: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_8_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_inyvFGkdcjfgxsd + jae .L_16_blocks_overflow_718 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_inyvFGkdcjfgxsd + jmp .L_16_blocks_ok_718 -.L_16_blocks_overflow_inyvFGkdcjfgxsd: +.L_16_blocks_overflow_718: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_inyvFGkdcjfgxsd: +.L_16_blocks_ok_718: @@ -98791,7 +98791,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_syzmcEAsnpBbzab + jl .L_small_initial_partial_block_719 @@ -98845,8 +98845,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_syzmcEAsnpBbzab -.L_small_initial_partial_block_syzmcEAsnpBbzab: + jmp .L_small_initial_compute_done_719 +.L_small_initial_partial_block_719: @@ -98901,26 +98901,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_syzmcEAsnpBbzab: +.L_small_initial_compute_done_719: orq %r8,%r8 - je .L_after_reduction_syzmcEAsnpBbzab + je .L_after_reduction_719 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_syzmcEAsnpBbzab: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_9_eFaDobhDcadAiew: +.L_after_reduction_719: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_9_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_fjDrcchaiBakAAF + jae .L_16_blocks_overflow_720 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_fjDrcchaiBakAAF + jmp .L_16_blocks_ok_720 -.L_16_blocks_overflow_fjDrcchaiBakAAF: +.L_16_blocks_overflow_720: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -98929,7 +98929,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_fjDrcchaiBakAAF: +.L_16_blocks_ok_720: @@ -99052,7 +99052,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fBmmvCByqAnbllk + jl .L_small_initial_partial_block_721 @@ -99112,8 +99112,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fBmmvCByqAnbllk -.L_small_initial_partial_block_fBmmvCByqAnbllk: + jmp .L_small_initial_compute_done_721 +.L_small_initial_partial_block_721: @@ -99170,26 +99170,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fBmmvCByqAnbllk: +.L_small_initial_compute_done_721: orq %r8,%r8 - je .L_after_reduction_fBmmvCByqAnbllk + je .L_after_reduction_721 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fBmmvCByqAnbllk: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_10_eFaDobhDcadAiew: +.L_after_reduction_721: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_10_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_sGBgmBdhxxaBuyG + jae .L_16_blocks_overflow_722 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_sGBgmBdhxxaBuyG + jmp .L_16_blocks_ok_722 -.L_16_blocks_overflow_sGBgmBdhxxaBuyG: +.L_16_blocks_overflow_722: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -99198,7 +99198,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_sGBgmBdhxxaBuyG: +.L_16_blocks_ok_722: @@ -99321,7 +99321,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kGoywspckFGlFlm + jl .L_small_initial_partial_block_723 @@ -99381,8 +99381,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kGoywspckFGlFlm -.L_small_initial_partial_block_kGoywspckFGlFlm: + jmp .L_small_initial_compute_done_723 +.L_small_initial_partial_block_723: @@ -99445,26 +99445,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kGoywspckFGlFlm: +.L_small_initial_compute_done_723: orq %r8,%r8 - je .L_after_reduction_kGoywspckFGlFlm + je .L_after_reduction_723 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kGoywspckFGlFlm: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_11_eFaDobhDcadAiew: +.L_after_reduction_723: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_11_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_jpnxiiwAmlwyGlm + jae .L_16_blocks_overflow_724 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_jpnxiiwAmlwyGlm + jmp .L_16_blocks_ok_724 -.L_16_blocks_overflow_jpnxiiwAmlwyGlm: +.L_16_blocks_overflow_724: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -99473,7 +99473,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_jpnxiiwAmlwyGlm: +.L_16_blocks_ok_724: @@ -99596,7 +99596,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hAFivtCFrjhrutC + jl .L_small_initial_partial_block_725 @@ -99657,8 +99657,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hAFivtCFrjhrutC -.L_small_initial_partial_block_hAFivtCFrjhrutC: + jmp .L_small_initial_compute_done_725 +.L_small_initial_partial_block_725: @@ -99721,26 +99721,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hAFivtCFrjhrutC: +.L_small_initial_compute_done_725: orq %r8,%r8 - je .L_after_reduction_hAFivtCFrjhrutC + je .L_after_reduction_725 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hAFivtCFrjhrutC: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_12_eFaDobhDcadAiew: +.L_after_reduction_725: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_12_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_owekkBumCcpvlbo + jae .L_16_blocks_overflow_726 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_owekkBumCcpvlbo + jmp .L_16_blocks_ok_726 -.L_16_blocks_overflow_owekkBumCcpvlbo: +.L_16_blocks_overflow_726: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -99749,7 +99749,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_owekkBumCcpvlbo: +.L_16_blocks_ok_726: @@ -99872,7 +99872,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FwoAGhlEfmfanez + jl .L_small_initial_partial_block_727 @@ -99931,8 +99931,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FwoAGhlEfmfanez -.L_small_initial_partial_block_FwoAGhlEfmfanez: + jmp .L_small_initial_compute_done_727 +.L_small_initial_partial_block_727: @@ -99996,27 +99996,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FwoAGhlEfmfanez: +.L_small_initial_compute_done_727: orq %r8,%r8 - je .L_after_reduction_FwoAGhlEfmfanez + je .L_after_reduction_727 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FwoAGhlEfmfanez: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_13_eFaDobhDcadAiew: +.L_after_reduction_727: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_13_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_etnEggBiycuvyzx + jae .L_16_blocks_overflow_728 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_etnEggBiycuvyzx + jmp .L_16_blocks_ok_728 -.L_16_blocks_overflow_etnEggBiycuvyzx: +.L_16_blocks_overflow_728: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -100027,7 +100027,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_etnEggBiycuvyzx: +.L_16_blocks_ok_728: @@ -100167,7 +100167,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rCdlcescGhEnawl + jl .L_small_initial_partial_block_729 @@ -100232,8 +100232,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rCdlcescGhEnawl -.L_small_initial_partial_block_rCdlcescGhEnawl: + jmp .L_small_initial_compute_done_729 +.L_small_initial_partial_block_729: @@ -100295,27 +100295,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rCdlcescGhEnawl: +.L_small_initial_compute_done_729: orq %r8,%r8 - je .L_after_reduction_rCdlcescGhEnawl + je .L_after_reduction_729 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rCdlcescGhEnawl: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_14_eFaDobhDcadAiew: +.L_after_reduction_729: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_14_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_sjiAcpDCgjcudFy + jae .L_16_blocks_overflow_730 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_sjiAcpDCgjcudFy + jmp .L_16_blocks_ok_730 -.L_16_blocks_overflow_sjiAcpDCgjcudFy: +.L_16_blocks_overflow_730: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -100326,7 +100326,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_sjiAcpDCgjcudFy: +.L_16_blocks_ok_730: @@ -100466,7 +100466,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sAkdufvaxEErlbv + jl .L_small_initial_partial_block_731 @@ -100531,8 +100531,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sAkdufvaxEErlbv -.L_small_initial_partial_block_sAkdufvaxEErlbv: + jmp .L_small_initial_compute_done_731 +.L_small_initial_partial_block_731: @@ -100600,27 +100600,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sAkdufvaxEErlbv: +.L_small_initial_compute_done_731: orq %r8,%r8 - je .L_after_reduction_sAkdufvaxEErlbv + je .L_after_reduction_731 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sAkdufvaxEErlbv: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_15_eFaDobhDcadAiew: +.L_after_reduction_731: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_15_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_EgBemkwFGrAmmql + jae .L_16_blocks_overflow_732 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_EgBemkwFGrAmmql + jmp .L_16_blocks_ok_732 -.L_16_blocks_overflow_EgBemkwFGrAmmql: +.L_16_blocks_overflow_732: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -100631,7 +100631,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_EgBemkwFGrAmmql: +.L_16_blocks_ok_732: @@ -100771,7 +100771,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BesuiwjpdsGkEvd + jl .L_small_initial_partial_block_733 @@ -100837,8 +100837,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BesuiwjpdsGkEvd -.L_small_initial_partial_block_BesuiwjpdsGkEvd: + jmp .L_small_initial_compute_done_733 +.L_small_initial_partial_block_733: @@ -100906,27 +100906,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BesuiwjpdsGkEvd: +.L_small_initial_compute_done_733: orq %r8,%r8 - je .L_after_reduction_BesuiwjpdsGkEvd + je .L_after_reduction_733 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BesuiwjpdsGkEvd: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_16_eFaDobhDcadAiew: +.L_after_reduction_733: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_16_703: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_icczkgxjcnsrGDl + jae .L_16_blocks_overflow_734 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_icczkgxjcnsrGDl + jmp .L_16_blocks_ok_734 -.L_16_blocks_overflow_icczkgxjcnsrGDl: +.L_16_blocks_overflow_734: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -100937,7 +100937,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_icczkgxjcnsrGDl: +.L_16_blocks_ok_734: @@ -101074,7 +101074,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_gsGgrBxtsonlyFd: +.L_small_initial_partial_block_735: @@ -101143,11 +101143,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gsGgrBxtsonlyFd: +.L_small_initial_compute_done_735: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gsGgrBxtsonlyFd: - jmp .L_last_blocks_done_eFaDobhDcadAiew -.L_last_num_blocks_is_0_eFaDobhDcadAiew: +.L_after_reduction_735: + jmp .L_last_blocks_done_703 +.L_last_num_blocks_is_0_703: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -101209,18 +101209,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_eFaDobhDcadAiew: +.L_last_blocks_done_703: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_EzeEqCiibleghsn -.L_encrypt_16_blocks_EzeEqCiibleghsn: + jmp .L_ghash_done_659 +.L_encrypt_16_blocks_659: cmpb $240,%r15b - jae .L_16_blocks_overflow_zhzpdDwgFryjdGp + jae .L_16_blocks_overflow_736 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_zhzpdDwgFryjdGp -.L_16_blocks_overflow_zhzpdDwgFryjdGp: + jmp .L_16_blocks_ok_736 +.L_16_blocks_overflow_736: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -101231,7 +101231,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_zhzpdDwgFryjdGp: +.L_16_blocks_ok_736: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -101444,61 +101444,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_bwqbqEyzFmathAc + je .L_last_num_blocks_is_0_737 cmpl $8,%r10d - je .L_last_num_blocks_is_8_bwqbqEyzFmathAc - jb .L_last_num_blocks_is_7_1_bwqbqEyzFmathAc + je .L_last_num_blocks_is_8_737 + jb .L_last_num_blocks_is_7_1_737 cmpl $12,%r10d - je .L_last_num_blocks_is_12_bwqbqEyzFmathAc - jb .L_last_num_blocks_is_11_9_bwqbqEyzFmathAc + je .L_last_num_blocks_is_12_737 + jb .L_last_num_blocks_is_11_9_737 cmpl $15,%r10d - je .L_last_num_blocks_is_15_bwqbqEyzFmathAc - ja .L_last_num_blocks_is_16_bwqbqEyzFmathAc + je .L_last_num_blocks_is_15_737 + ja .L_last_num_blocks_is_16_737 cmpl $14,%r10d - je .L_last_num_blocks_is_14_bwqbqEyzFmathAc - jmp .L_last_num_blocks_is_13_bwqbqEyzFmathAc + je .L_last_num_blocks_is_14_737 + jmp .L_last_num_blocks_is_13_737 -.L_last_num_blocks_is_11_9_bwqbqEyzFmathAc: +.L_last_num_blocks_is_11_9_737: cmpl $10,%r10d - je .L_last_num_blocks_is_10_bwqbqEyzFmathAc - ja .L_last_num_blocks_is_11_bwqbqEyzFmathAc - jmp .L_last_num_blocks_is_9_bwqbqEyzFmathAc + je .L_last_num_blocks_is_10_737 + ja .L_last_num_blocks_is_11_737 + jmp .L_last_num_blocks_is_9_737 -.L_last_num_blocks_is_7_1_bwqbqEyzFmathAc: +.L_last_num_blocks_is_7_1_737: cmpl $4,%r10d - je .L_last_num_blocks_is_4_bwqbqEyzFmathAc - jb .L_last_num_blocks_is_3_1_bwqbqEyzFmathAc + je .L_last_num_blocks_is_4_737 + jb .L_last_num_blocks_is_3_1_737 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_bwqbqEyzFmathAc - je .L_last_num_blocks_is_6_bwqbqEyzFmathAc - jmp .L_last_num_blocks_is_5_bwqbqEyzFmathAc + ja .L_last_num_blocks_is_7_737 + je .L_last_num_blocks_is_6_737 + jmp .L_last_num_blocks_is_5_737 -.L_last_num_blocks_is_3_1_bwqbqEyzFmathAc: +.L_last_num_blocks_is_3_1_737: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_bwqbqEyzFmathAc - je .L_last_num_blocks_is_2_bwqbqEyzFmathAc -.L_last_num_blocks_is_1_bwqbqEyzFmathAc: + ja .L_last_num_blocks_is_3_737 + je .L_last_num_blocks_is_2_737 +.L_last_num_blocks_is_1_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_noBcCsBAsqmejBq + jae .L_16_blocks_overflow_738 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_noBcCsBAsqmejBq + jmp .L_16_blocks_ok_738 -.L_16_blocks_overflow_noBcCsBAsqmejBq: +.L_16_blocks_overflow_738: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_noBcCsBAsqmejBq: +.L_16_blocks_ok_738: @@ -101609,7 +101609,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jFhlaidzulpDGCd + jl .L_small_initial_partial_block_739 @@ -101651,8 +101651,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jFhlaidzulpDGCd -.L_small_initial_partial_block_jFhlaidzulpDGCd: + jmp .L_small_initial_compute_done_739 +.L_small_initial_partial_block_739: @@ -101676,24 +101676,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_jFhlaidzulpDGCd -.L_small_initial_compute_done_jFhlaidzulpDGCd: -.L_after_reduction_jFhlaidzulpDGCd: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_2_bwqbqEyzFmathAc: + jmp .L_after_reduction_739 +.L_small_initial_compute_done_739: +.L_after_reduction_739: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_2_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_iEpseqdunDqjwuD + jae .L_16_blocks_overflow_740 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_iEpseqdunDqjwuD + jmp .L_16_blocks_ok_740 -.L_16_blocks_overflow_iEpseqdunDqjwuD: +.L_16_blocks_overflow_740: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_iEpseqdunDqjwuD: +.L_16_blocks_ok_740: @@ -101805,7 +101805,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nGbBoglibCAmdGh + jl .L_small_initial_partial_block_741 @@ -101847,8 +101847,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nGbBoglibCAmdGh -.L_small_initial_partial_block_nGbBoglibCAmdGh: + jmp .L_small_initial_compute_done_741 +.L_small_initial_partial_block_741: @@ -101893,27 +101893,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nGbBoglibCAmdGh: +.L_small_initial_compute_done_741: orq %r8,%r8 - je .L_after_reduction_nGbBoglibCAmdGh + je .L_after_reduction_741 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nGbBoglibCAmdGh: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_3_bwqbqEyzFmathAc: +.L_after_reduction_741: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_3_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_EGvjniuajyeqctm + jae .L_16_blocks_overflow_742 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_EGvjniuajyeqctm + jmp .L_16_blocks_ok_742 -.L_16_blocks_overflow_EGvjniuajyeqctm: +.L_16_blocks_overflow_742: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_EGvjniuajyeqctm: +.L_16_blocks_ok_742: @@ -102025,7 +102025,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xchbrvFuemGBuyh + jl .L_small_initial_partial_block_743 @@ -102068,8 +102068,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xchbrvFuemGBuyh -.L_small_initial_partial_block_xchbrvFuemGBuyh: + jmp .L_small_initial_compute_done_743 +.L_small_initial_partial_block_743: @@ -102114,27 +102114,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xchbrvFuemGBuyh: +.L_small_initial_compute_done_743: orq %r8,%r8 - je .L_after_reduction_xchbrvFuemGBuyh + je .L_after_reduction_743 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_xchbrvFuemGBuyh: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_4_bwqbqEyzFmathAc: +.L_after_reduction_743: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_4_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_cmglGrwhwemdEFx + jae .L_16_blocks_overflow_744 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_cmglGrwhwemdEFx + jmp .L_16_blocks_ok_744 -.L_16_blocks_overflow_cmglGrwhwemdEFx: +.L_16_blocks_overflow_744: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_cmglGrwhwemdEFx: +.L_16_blocks_ok_744: @@ -102246,7 +102246,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wedqGjdukEgkrmc + jl .L_small_initial_partial_block_745 @@ -102288,8 +102288,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wedqGjdukEgkrmc -.L_small_initial_partial_block_wedqGjdukEgkrmc: + jmp .L_small_initial_compute_done_745 +.L_small_initial_partial_block_745: @@ -102335,32 +102335,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wedqGjdukEgkrmc: +.L_small_initial_compute_done_745: orq %r8,%r8 - je .L_after_reduction_wedqGjdukEgkrmc + je .L_after_reduction_745 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wedqGjdukEgkrmc: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_5_bwqbqEyzFmathAc: +.L_after_reduction_745: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_5_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_yjzxGqovvuoamgo + jae .L_16_blocks_overflow_746 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_yjzxGqovvuoamgo + jmp .L_16_blocks_ok_746 -.L_16_blocks_overflow_yjzxGqovvuoamgo: +.L_16_blocks_overflow_746: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_yjzxGqovvuoamgo: +.L_16_blocks_ok_746: @@ -102489,7 +102489,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ArigDhBhjlkpiio + jl .L_small_initial_partial_block_747 @@ -102541,8 +102541,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ArigDhBhjlkpiio -.L_small_initial_partial_block_ArigDhBhjlkpiio: + jmp .L_small_initial_compute_done_747 +.L_small_initial_partial_block_747: @@ -102587,32 +102587,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ArigDhBhjlkpiio: +.L_small_initial_compute_done_747: orq %r8,%r8 - je .L_after_reduction_ArigDhBhjlkpiio + je .L_after_reduction_747 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ArigDhBhjlkpiio: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_6_bwqbqEyzFmathAc: +.L_after_reduction_747: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_6_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_cevAbulmkyCqrGr + jae .L_16_blocks_overflow_748 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_cevAbulmkyCqrGr + jmp .L_16_blocks_ok_748 -.L_16_blocks_overflow_cevAbulmkyCqrGr: +.L_16_blocks_overflow_748: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_cevAbulmkyCqrGr: +.L_16_blocks_ok_748: @@ -102741,7 +102741,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_cllzGbwvqfDeqnA + jl .L_small_initial_partial_block_749 @@ -102793,8 +102793,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_cllzGbwvqfDeqnA -.L_small_initial_partial_block_cllzGbwvqfDeqnA: + jmp .L_small_initial_compute_done_749 +.L_small_initial_partial_block_749: @@ -102849,32 +102849,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cllzGbwvqfDeqnA: +.L_small_initial_compute_done_749: orq %r8,%r8 - je .L_after_reduction_cllzGbwvqfDeqnA + je .L_after_reduction_749 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cllzGbwvqfDeqnA: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_7_bwqbqEyzFmathAc: +.L_after_reduction_749: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_7_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_xcdBmyyjeBtljpq + jae .L_16_blocks_overflow_750 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_xcdBmyyjeBtljpq + jmp .L_16_blocks_ok_750 -.L_16_blocks_overflow_xcdBmyyjeBtljpq: +.L_16_blocks_overflow_750: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_xcdBmyyjeBtljpq: +.L_16_blocks_ok_750: @@ -103003,7 +103003,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_feBjctGjsioyvuu + jl .L_small_initial_partial_block_751 @@ -103056,8 +103056,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_feBjctGjsioyvuu -.L_small_initial_partial_block_feBjctGjsioyvuu: + jmp .L_small_initial_compute_done_751 +.L_small_initial_partial_block_751: @@ -103112,32 +103112,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_feBjctGjsioyvuu: +.L_small_initial_compute_done_751: orq %r8,%r8 - je .L_after_reduction_feBjctGjsioyvuu + je .L_after_reduction_751 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_feBjctGjsioyvuu: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_8_bwqbqEyzFmathAc: +.L_after_reduction_751: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_8_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_qxiGphGbulsiedD + jae .L_16_blocks_overflow_752 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_qxiGphGbulsiedD + jmp .L_16_blocks_ok_752 -.L_16_blocks_overflow_qxiGphGbulsiedD: +.L_16_blocks_overflow_752: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_qxiGphGbulsiedD: +.L_16_blocks_ok_752: @@ -103266,7 +103266,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_htvGBouGqqzDlBb + jl .L_small_initial_partial_block_753 @@ -103317,8 +103317,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_htvGBouGqqzDlBb -.L_small_initial_partial_block_htvGBouGqqzDlBb: + jmp .L_small_initial_compute_done_753 +.L_small_initial_partial_block_753: @@ -103374,26 +103374,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_htvGBouGqqzDlBb: +.L_small_initial_compute_done_753: orq %r8,%r8 - je .L_after_reduction_htvGBouGqqzDlBb + je .L_after_reduction_753 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_htvGBouGqqzDlBb: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_9_bwqbqEyzFmathAc: +.L_after_reduction_753: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_9_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_ktotEBtjyxoohrx + jae .L_16_blocks_overflow_754 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_ktotEBtjyxoohrx + jmp .L_16_blocks_ok_754 -.L_16_blocks_overflow_ktotEBtjyxoohrx: +.L_16_blocks_overflow_754: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -103402,7 +103402,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_ktotEBtjyxoohrx: +.L_16_blocks_ok_754: @@ -103548,7 +103548,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hqzgjgjowmukfzv + jl .L_small_initial_partial_block_755 @@ -103609,8 +103609,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hqzgjgjowmukfzv -.L_small_initial_partial_block_hqzgjgjowmukfzv: + jmp .L_small_initial_compute_done_755 +.L_small_initial_partial_block_755: @@ -103664,26 +103664,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hqzgjgjowmukfzv: +.L_small_initial_compute_done_755: orq %r8,%r8 - je .L_after_reduction_hqzgjgjowmukfzv + je .L_after_reduction_755 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hqzgjgjowmukfzv: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_10_bwqbqEyzFmathAc: +.L_after_reduction_755: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_10_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_drbjgopABaEbFAr + jae .L_16_blocks_overflow_756 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_drbjgopABaEbFAr + jmp .L_16_blocks_ok_756 -.L_16_blocks_overflow_drbjgopABaEbFAr: +.L_16_blocks_overflow_756: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -103692,7 +103692,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_drbjgopABaEbFAr: +.L_16_blocks_ok_756: @@ -103838,7 +103838,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wzkyiuDzrsjncvj + jl .L_small_initial_partial_block_757 @@ -103899,8 +103899,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wzkyiuDzrsjncvj -.L_small_initial_partial_block_wzkyiuDzrsjncvj: + jmp .L_small_initial_compute_done_757 +.L_small_initial_partial_block_757: @@ -103964,26 +103964,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wzkyiuDzrsjncvj: +.L_small_initial_compute_done_757: orq %r8,%r8 - je .L_after_reduction_wzkyiuDzrsjncvj + je .L_after_reduction_757 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_wzkyiuDzrsjncvj: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_11_bwqbqEyzFmathAc: +.L_after_reduction_757: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_11_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_kftbmbxwoCkdapz + jae .L_16_blocks_overflow_758 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_kftbmbxwoCkdapz + jmp .L_16_blocks_ok_758 -.L_16_blocks_overflow_kftbmbxwoCkdapz: +.L_16_blocks_overflow_758: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -103992,7 +103992,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_kftbmbxwoCkdapz: +.L_16_blocks_ok_758: @@ -104138,7 +104138,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aqqvCravpvthbdg + jl .L_small_initial_partial_block_759 @@ -104200,8 +104200,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aqqvCravpvthbdg -.L_small_initial_partial_block_aqqvCravpvthbdg: + jmp .L_small_initial_compute_done_759 +.L_small_initial_partial_block_759: @@ -104265,26 +104265,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aqqvCravpvthbdg: +.L_small_initial_compute_done_759: orq %r8,%r8 - je .L_after_reduction_aqqvCravpvthbdg + je .L_after_reduction_759 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aqqvCravpvthbdg: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_12_bwqbqEyzFmathAc: +.L_after_reduction_759: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_12_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_fpkdjwiDFqbDpBv + jae .L_16_blocks_overflow_760 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_fpkdjwiDFqbDpBv + jmp .L_16_blocks_ok_760 -.L_16_blocks_overflow_fpkdjwiDFqbDpBv: +.L_16_blocks_overflow_760: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -104293,7 +104293,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_fpkdjwiDFqbDpBv: +.L_16_blocks_ok_760: @@ -104439,7 +104439,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_pdqcGCjmglydxBD + jl .L_small_initial_partial_block_761 @@ -104495,8 +104495,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_pdqcGCjmglydxBD -.L_small_initial_partial_block_pdqcGCjmglydxBD: + jmp .L_small_initial_compute_done_761 +.L_small_initial_partial_block_761: @@ -104561,27 +104561,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_pdqcGCjmglydxBD: +.L_small_initial_compute_done_761: orq %r8,%r8 - je .L_after_reduction_pdqcGCjmglydxBD + je .L_after_reduction_761 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_pdqcGCjmglydxBD: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_13_bwqbqEyzFmathAc: +.L_after_reduction_761: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_13_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_lGvnecyekofwDpb + jae .L_16_blocks_overflow_762 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_lGvnecyekofwDpb + jmp .L_16_blocks_ok_762 -.L_16_blocks_overflow_lGvnecyekofwDpb: +.L_16_blocks_overflow_762: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -104592,7 +104592,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_lGvnecyekofwDpb: +.L_16_blocks_ok_762: @@ -104755,7 +104755,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zgbmiyFCtlbureD + jl .L_small_initial_partial_block_763 @@ -104821,8 +104821,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zgbmiyFCtlbureD -.L_small_initial_partial_block_zgbmiyFCtlbureD: + jmp .L_small_initial_compute_done_763 +.L_small_initial_partial_block_763: @@ -104881,27 +104881,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zgbmiyFCtlbureD: +.L_small_initial_compute_done_763: orq %r8,%r8 - je .L_after_reduction_zgbmiyFCtlbureD + je .L_after_reduction_763 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zgbmiyFCtlbureD: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_14_bwqbqEyzFmathAc: +.L_after_reduction_763: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_14_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_byEdAxiimBnthvk + jae .L_16_blocks_overflow_764 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_byEdAxiimBnthvk + jmp .L_16_blocks_ok_764 -.L_16_blocks_overflow_byEdAxiimBnthvk: +.L_16_blocks_overflow_764: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -104912,7 +104912,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_byEdAxiimBnthvk: +.L_16_blocks_ok_764: @@ -105075,7 +105075,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qEpDnApAfqpDjdq + jl .L_small_initial_partial_block_765 @@ -105141,8 +105141,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qEpDnApAfqpDjdq -.L_small_initial_partial_block_qEpDnApAfqpDjdq: + jmp .L_small_initial_compute_done_765 +.L_small_initial_partial_block_765: @@ -105211,27 +105211,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qEpDnApAfqpDjdq: +.L_small_initial_compute_done_765: orq %r8,%r8 - je .L_after_reduction_qEpDnApAfqpDjdq + je .L_after_reduction_765 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qEpDnApAfqpDjdq: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_15_bwqbqEyzFmathAc: +.L_after_reduction_765: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_15_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_FmgpviBGEycEFEA + jae .L_16_blocks_overflow_766 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_FmgpviBGEycEFEA + jmp .L_16_blocks_ok_766 -.L_16_blocks_overflow_FmgpviBGEycEFEA: +.L_16_blocks_overflow_766: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -105242,7 +105242,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_FmgpviBGEycEFEA: +.L_16_blocks_ok_766: @@ -105405,7 +105405,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fyxgFpaDexAibhj + jl .L_small_initial_partial_block_767 @@ -105472,8 +105472,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fyxgFpaDexAibhj -.L_small_initial_partial_block_fyxgFpaDexAibhj: + jmp .L_small_initial_compute_done_767 +.L_small_initial_partial_block_767: @@ -105542,27 +105542,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fyxgFpaDexAibhj: +.L_small_initial_compute_done_767: orq %r8,%r8 - je .L_after_reduction_fyxgFpaDexAibhj + je .L_after_reduction_767 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fyxgFpaDexAibhj: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_16_bwqbqEyzFmathAc: +.L_after_reduction_767: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_16_737: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_xCirgbdmwFadphq + jae .L_16_blocks_overflow_768 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_xCirgbdmwFadphq + jmp .L_16_blocks_ok_768 -.L_16_blocks_overflow_xCirgbdmwFadphq: +.L_16_blocks_overflow_768: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -105573,7 +105573,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_xCirgbdmwFadphq: +.L_16_blocks_ok_768: @@ -105733,7 +105733,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_AFdzygrAdvxioki: +.L_small_initial_partial_block_769: @@ -105803,11 +105803,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AFdzygrAdvxioki: +.L_small_initial_compute_done_769: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AFdzygrAdvxioki: - jmp .L_last_blocks_done_bwqbqEyzFmathAc -.L_last_num_blocks_is_0_bwqbqEyzFmathAc: +.L_after_reduction_769: + jmp .L_last_blocks_done_737 +.L_last_num_blocks_is_0_737: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -105868,18 +105868,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_bwqbqEyzFmathAc: +.L_last_blocks_done_737: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_EzeEqCiibleghsn + jmp .L_ghash_done_659 -.L_message_below_32_blocks_EzeEqCiibleghsn: +.L_message_below_32_blocks_659: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_AtroafBEsdEFCdm + jnz .L_skip_hkeys_precomputation_770 vmovdqu64 640(%rsp),%zmm3 @@ -106007,7 +106007,7 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_AtroafBEsdEFCdm: +.L_skip_hkeys_precomputation_770: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -106015,61 +106015,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_0_771 cmpl $8,%r10d - je .L_last_num_blocks_is_8_zGdCBEiybwnDAAi - jb .L_last_num_blocks_is_7_1_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_8_771 + jb .L_last_num_blocks_is_7_1_771 cmpl $12,%r10d - je .L_last_num_blocks_is_12_zGdCBEiybwnDAAi - jb .L_last_num_blocks_is_11_9_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_12_771 + jb .L_last_num_blocks_is_11_9_771 cmpl $15,%r10d - je .L_last_num_blocks_is_15_zGdCBEiybwnDAAi - ja .L_last_num_blocks_is_16_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_15_771 + ja .L_last_num_blocks_is_16_771 cmpl $14,%r10d - je .L_last_num_blocks_is_14_zGdCBEiybwnDAAi - jmp .L_last_num_blocks_is_13_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_14_771 + jmp .L_last_num_blocks_is_13_771 -.L_last_num_blocks_is_11_9_zGdCBEiybwnDAAi: +.L_last_num_blocks_is_11_9_771: cmpl $10,%r10d - je .L_last_num_blocks_is_10_zGdCBEiybwnDAAi - ja .L_last_num_blocks_is_11_zGdCBEiybwnDAAi - jmp .L_last_num_blocks_is_9_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_10_771 + ja .L_last_num_blocks_is_11_771 + jmp .L_last_num_blocks_is_9_771 -.L_last_num_blocks_is_7_1_zGdCBEiybwnDAAi: +.L_last_num_blocks_is_7_1_771: cmpl $4,%r10d - je .L_last_num_blocks_is_4_zGdCBEiybwnDAAi - jb .L_last_num_blocks_is_3_1_zGdCBEiybwnDAAi + je .L_last_num_blocks_is_4_771 + jb .L_last_num_blocks_is_3_1_771 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_zGdCBEiybwnDAAi - je .L_last_num_blocks_is_6_zGdCBEiybwnDAAi - jmp .L_last_num_blocks_is_5_zGdCBEiybwnDAAi + ja .L_last_num_blocks_is_7_771 + je .L_last_num_blocks_is_6_771 + jmp .L_last_num_blocks_is_5_771 -.L_last_num_blocks_is_3_1_zGdCBEiybwnDAAi: +.L_last_num_blocks_is_3_1_771: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_zGdCBEiybwnDAAi - je .L_last_num_blocks_is_2_zGdCBEiybwnDAAi -.L_last_num_blocks_is_1_zGdCBEiybwnDAAi: + ja .L_last_num_blocks_is_3_771 + je .L_last_num_blocks_is_2_771 +.L_last_num_blocks_is_1_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_FxEDroEsbrnkdut + jae .L_16_blocks_overflow_772 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_FxEDroEsbrnkdut + jmp .L_16_blocks_ok_772 -.L_16_blocks_overflow_FxEDroEsbrnkdut: +.L_16_blocks_overflow_772: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_FxEDroEsbrnkdut: +.L_16_blocks_ok_772: @@ -106157,7 +106157,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_palkagzprgooilA + jl .L_small_initial_partial_block_773 @@ -106201,8 +106201,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_palkagzprgooilA -.L_small_initial_partial_block_palkagzprgooilA: + jmp .L_small_initial_compute_done_773 +.L_small_initial_partial_block_773: @@ -106254,24 +106254,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_palkagzprgooilA -.L_small_initial_compute_done_palkagzprgooilA: -.L_after_reduction_palkagzprgooilA: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_2_zGdCBEiybwnDAAi: + jmp .L_after_reduction_773 +.L_small_initial_compute_done_773: +.L_after_reduction_773: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_2_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_fDgGAqoaaCbaAwa + jae .L_16_blocks_overflow_774 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_fDgGAqoaaCbaAwa + jmp .L_16_blocks_ok_774 -.L_16_blocks_overflow_fDgGAqoaaCbaAwa: +.L_16_blocks_overflow_774: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_fDgGAqoaaCbaAwa: +.L_16_blocks_ok_774: @@ -106360,7 +106360,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EoCmzsFcvzjdcie + jl .L_small_initial_partial_block_775 @@ -106404,8 +106404,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EoCmzsFcvzjdcie -.L_small_initial_partial_block_EoCmzsFcvzjdcie: + jmp .L_small_initial_compute_done_775 +.L_small_initial_partial_block_775: @@ -106452,27 +106452,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EoCmzsFcvzjdcie: +.L_small_initial_compute_done_775: orq %r8,%r8 - je .L_after_reduction_EoCmzsFcvzjdcie + je .L_after_reduction_775 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EoCmzsFcvzjdcie: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_3_zGdCBEiybwnDAAi: +.L_after_reduction_775: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_3_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_xoDrrDymqemfidA + jae .L_16_blocks_overflow_776 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_xoDrrDymqemfidA + jmp .L_16_blocks_ok_776 -.L_16_blocks_overflow_xoDrrDymqemfidA: +.L_16_blocks_overflow_776: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_xoDrrDymqemfidA: +.L_16_blocks_ok_776: @@ -106561,7 +106561,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nkkigkEpFfvxyif + jl .L_small_initial_partial_block_777 @@ -106606,8 +106606,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nkkigkEpFfvxyif -.L_small_initial_partial_block_nkkigkEpFfvxyif: + jmp .L_small_initial_compute_done_777 +.L_small_initial_partial_block_777: @@ -106654,27 +106654,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nkkigkEpFfvxyif: +.L_small_initial_compute_done_777: orq %r8,%r8 - je .L_after_reduction_nkkigkEpFfvxyif + je .L_after_reduction_777 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nkkigkEpFfvxyif: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_4_zGdCBEiybwnDAAi: +.L_after_reduction_777: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_4_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_EnoxEoGzqplnFab + jae .L_16_blocks_overflow_778 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_EnoxEoGzqplnFab + jmp .L_16_blocks_ok_778 -.L_16_blocks_overflow_EnoxEoGzqplnFab: +.L_16_blocks_overflow_778: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_EnoxEoGzqplnFab: +.L_16_blocks_ok_778: @@ -106763,7 +106763,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kzcejezBzAcfpqE + jl .L_small_initial_partial_block_779 @@ -106808,8 +106808,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kzcejezBzAcfpqE -.L_small_initial_partial_block_kzcejezBzAcfpqE: + jmp .L_small_initial_compute_done_779 +.L_small_initial_partial_block_779: @@ -106857,32 +106857,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kzcejezBzAcfpqE: +.L_small_initial_compute_done_779: orq %r8,%r8 - je .L_after_reduction_kzcejezBzAcfpqE + je .L_after_reduction_779 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kzcejezBzAcfpqE: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_5_zGdCBEiybwnDAAi: +.L_after_reduction_779: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_5_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_rEkrwgvFnDbtylf + jae .L_16_blocks_overflow_780 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_rEkrwgvFnDbtylf + jmp .L_16_blocks_ok_780 -.L_16_blocks_overflow_rEkrwgvFnDbtylf: +.L_16_blocks_overflow_780: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_rEkrwgvFnDbtylf: +.L_16_blocks_ok_780: @@ -106988,7 +106988,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_smfinaaqEdcwblk + jl .L_small_initial_partial_block_781 @@ -107039,8 +107039,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_smfinaaqEdcwblk -.L_small_initial_partial_block_smfinaaqEdcwblk: + jmp .L_small_initial_compute_done_781 +.L_small_initial_partial_block_781: @@ -107088,32 +107088,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_smfinaaqEdcwblk: +.L_small_initial_compute_done_781: orq %r8,%r8 - je .L_after_reduction_smfinaaqEdcwblk + je .L_after_reduction_781 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_smfinaaqEdcwblk: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_6_zGdCBEiybwnDAAi: +.L_after_reduction_781: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_6_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_CrdzmtEcpFvFqBv + jae .L_16_blocks_overflow_782 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_CrdzmtEcpFvFqBv + jmp .L_16_blocks_ok_782 -.L_16_blocks_overflow_CrdzmtEcpFvFqBv: +.L_16_blocks_overflow_782: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_CrdzmtEcpFvFqBv: +.L_16_blocks_ok_782: @@ -107219,7 +107219,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gFdgvdpwnBsABEj + jl .L_small_initial_partial_block_783 @@ -107270,8 +107270,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gFdgvdpwnBsABEj -.L_small_initial_partial_block_gFdgvdpwnBsABEj: + jmp .L_small_initial_compute_done_783 +.L_small_initial_partial_block_783: @@ -107325,32 +107325,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gFdgvdpwnBsABEj: +.L_small_initial_compute_done_783: orq %r8,%r8 - je .L_after_reduction_gFdgvdpwnBsABEj + je .L_after_reduction_783 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gFdgvdpwnBsABEj: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_7_zGdCBEiybwnDAAi: +.L_after_reduction_783: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_7_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_yuqvqtDduqymroe + jae .L_16_blocks_overflow_784 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_yuqvqtDduqymroe + jmp .L_16_blocks_ok_784 -.L_16_blocks_overflow_yuqvqtDduqymroe: +.L_16_blocks_overflow_784: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_yuqvqtDduqymroe: +.L_16_blocks_ok_784: @@ -107456,7 +107456,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_rGwpfyGGtjkjFzB + jl .L_small_initial_partial_block_785 @@ -107508,8 +107508,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_rGwpfyGGtjkjFzB -.L_small_initial_partial_block_rGwpfyGGtjkjFzB: + jmp .L_small_initial_compute_done_785 +.L_small_initial_partial_block_785: @@ -107563,32 +107563,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_rGwpfyGGtjkjFzB: +.L_small_initial_compute_done_785: orq %r8,%r8 - je .L_after_reduction_rGwpfyGGtjkjFzB + je .L_after_reduction_785 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_rGwpfyGGtjkjFzB: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_8_zGdCBEiybwnDAAi: +.L_after_reduction_785: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_8_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_lGaCtfFwxiurgAm + jae .L_16_blocks_overflow_786 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_lGaCtfFwxiurgAm + jmp .L_16_blocks_ok_786 -.L_16_blocks_overflow_lGaCtfFwxiurgAm: +.L_16_blocks_overflow_786: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_lGaCtfFwxiurgAm: +.L_16_blocks_ok_786: @@ -107694,7 +107694,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qFhucfqqplyubxA + jl .L_small_initial_partial_block_787 @@ -107748,8 +107748,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qFhucfqqplyubxA -.L_small_initial_partial_block_qFhucfqqplyubxA: + jmp .L_small_initial_compute_done_787 +.L_small_initial_partial_block_787: @@ -107804,26 +107804,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qFhucfqqplyubxA: +.L_small_initial_compute_done_787: orq %r8,%r8 - je .L_after_reduction_qFhucfqqplyubxA + je .L_after_reduction_787 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qFhucfqqplyubxA: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_9_zGdCBEiybwnDAAi: +.L_after_reduction_787: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_9_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_mvfnjafesEvrtuw + jae .L_16_blocks_overflow_788 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_mvfnjafesEvrtuw + jmp .L_16_blocks_ok_788 -.L_16_blocks_overflow_mvfnjafesEvrtuw: +.L_16_blocks_overflow_788: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -107832,7 +107832,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_mvfnjafesEvrtuw: +.L_16_blocks_ok_788: @@ -107955,7 +107955,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ujidCgdvCmrxtpa + jl .L_small_initial_partial_block_789 @@ -108015,8 +108015,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ujidCgdvCmrxtpa -.L_small_initial_partial_block_ujidCgdvCmrxtpa: + jmp .L_small_initial_compute_done_789 +.L_small_initial_partial_block_789: @@ -108073,26 +108073,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ujidCgdvCmrxtpa: +.L_small_initial_compute_done_789: orq %r8,%r8 - je .L_after_reduction_ujidCgdvCmrxtpa + je .L_after_reduction_789 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ujidCgdvCmrxtpa: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_10_zGdCBEiybwnDAAi: +.L_after_reduction_789: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_10_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_sijCiuycdzDtGqi + jae .L_16_blocks_overflow_790 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_sijCiuycdzDtGqi + jmp .L_16_blocks_ok_790 -.L_16_blocks_overflow_sijCiuycdzDtGqi: +.L_16_blocks_overflow_790: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -108101,7 +108101,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_sijCiuycdzDtGqi: +.L_16_blocks_ok_790: @@ -108224,7 +108224,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nooiDGzikEfhFfe + jl .L_small_initial_partial_block_791 @@ -108284,8 +108284,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nooiDGzikEfhFfe -.L_small_initial_partial_block_nooiDGzikEfhFfe: + jmp .L_small_initial_compute_done_791 +.L_small_initial_partial_block_791: @@ -108348,26 +108348,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nooiDGzikEfhFfe: +.L_small_initial_compute_done_791: orq %r8,%r8 - je .L_after_reduction_nooiDGzikEfhFfe + je .L_after_reduction_791 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nooiDGzikEfhFfe: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_11_zGdCBEiybwnDAAi: +.L_after_reduction_791: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_11_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_hamipvoftkFkjot + jae .L_16_blocks_overflow_792 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_hamipvoftkFkjot + jmp .L_16_blocks_ok_792 -.L_16_blocks_overflow_hamipvoftkFkjot: +.L_16_blocks_overflow_792: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -108376,7 +108376,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_hamipvoftkFkjot: +.L_16_blocks_ok_792: @@ -108499,7 +108499,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_exmwiyddrbifrsk + jl .L_small_initial_partial_block_793 @@ -108560,8 +108560,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_exmwiyddrbifrsk -.L_small_initial_partial_block_exmwiyddrbifrsk: + jmp .L_small_initial_compute_done_793 +.L_small_initial_partial_block_793: @@ -108624,26 +108624,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_exmwiyddrbifrsk: +.L_small_initial_compute_done_793: orq %r8,%r8 - je .L_after_reduction_exmwiyddrbifrsk + je .L_after_reduction_793 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_exmwiyddrbifrsk: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_12_zGdCBEiybwnDAAi: +.L_after_reduction_793: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_12_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_parbDFFrzfqvBtt + jae .L_16_blocks_overflow_794 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_parbDFFrzfqvBtt + jmp .L_16_blocks_ok_794 -.L_16_blocks_overflow_parbDFFrzfqvBtt: +.L_16_blocks_overflow_794: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -108652,7 +108652,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_parbDFFrzfqvBtt: +.L_16_blocks_ok_794: @@ -108775,7 +108775,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nxnitznegvbvbhh + jl .L_small_initial_partial_block_795 @@ -108834,8 +108834,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nxnitznegvbvbhh -.L_small_initial_partial_block_nxnitznegvbvbhh: + jmp .L_small_initial_compute_done_795 +.L_small_initial_partial_block_795: @@ -108899,27 +108899,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nxnitznegvbvbhh: +.L_small_initial_compute_done_795: orq %r8,%r8 - je .L_after_reduction_nxnitznegvbvbhh + je .L_after_reduction_795 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nxnitznegvbvbhh: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_13_zGdCBEiybwnDAAi: +.L_after_reduction_795: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_13_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_FzmhbidkDCCseqs + jae .L_16_blocks_overflow_796 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_FzmhbidkDCCseqs + jmp .L_16_blocks_ok_796 -.L_16_blocks_overflow_FzmhbidkDCCseqs: +.L_16_blocks_overflow_796: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -108930,7 +108930,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_FzmhbidkDCCseqs: +.L_16_blocks_ok_796: @@ -109070,7 +109070,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_svqhisjwzDCCnBD + jl .L_small_initial_partial_block_797 @@ -109135,8 +109135,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_svqhisjwzDCCnBD -.L_small_initial_partial_block_svqhisjwzDCCnBD: + jmp .L_small_initial_compute_done_797 +.L_small_initial_partial_block_797: @@ -109198,27 +109198,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_svqhisjwzDCCnBD: +.L_small_initial_compute_done_797: orq %r8,%r8 - je .L_after_reduction_svqhisjwzDCCnBD + je .L_after_reduction_797 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_svqhisjwzDCCnBD: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_14_zGdCBEiybwnDAAi: +.L_after_reduction_797: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_14_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_qbhvnxrnqEaGcrC + jae .L_16_blocks_overflow_798 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_qbhvnxrnqEaGcrC + jmp .L_16_blocks_ok_798 -.L_16_blocks_overflow_qbhvnxrnqEaGcrC: +.L_16_blocks_overflow_798: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -109229,7 +109229,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_qbhvnxrnqEaGcrC: +.L_16_blocks_ok_798: @@ -109369,7 +109369,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GlkerxBnwFqnhbB + jl .L_small_initial_partial_block_799 @@ -109434,8 +109434,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GlkerxBnwFqnhbB -.L_small_initial_partial_block_GlkerxBnwFqnhbB: + jmp .L_small_initial_compute_done_799 +.L_small_initial_partial_block_799: @@ -109503,27 +109503,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GlkerxBnwFqnhbB: +.L_small_initial_compute_done_799: orq %r8,%r8 - je .L_after_reduction_GlkerxBnwFqnhbB + je .L_after_reduction_799 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GlkerxBnwFqnhbB: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_15_zGdCBEiybwnDAAi: +.L_after_reduction_799: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_15_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_kEncwwyhDatAzmA + jae .L_16_blocks_overflow_800 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_kEncwwyhDatAzmA + jmp .L_16_blocks_ok_800 -.L_16_blocks_overflow_kEncwwyhDatAzmA: +.L_16_blocks_overflow_800: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -109534,7 +109534,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_kEncwwyhDatAzmA: +.L_16_blocks_ok_800: @@ -109674,7 +109674,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jaspjkwCfstGEqE + jl .L_small_initial_partial_block_801 @@ -109740,8 +109740,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jaspjkwCfstGEqE -.L_small_initial_partial_block_jaspjkwCfstGEqE: + jmp .L_small_initial_compute_done_801 +.L_small_initial_partial_block_801: @@ -109809,27 +109809,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jaspjkwCfstGEqE: +.L_small_initial_compute_done_801: orq %r8,%r8 - je .L_after_reduction_jaspjkwCfstGEqE + je .L_after_reduction_801 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jaspjkwCfstGEqE: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_16_zGdCBEiybwnDAAi: +.L_after_reduction_801: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_16_771: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_nqsBrjBbEdouqvv + jae .L_16_blocks_overflow_802 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_nqsBrjBbEdouqvv + jmp .L_16_blocks_ok_802 -.L_16_blocks_overflow_nqsBrjBbEdouqvv: +.L_16_blocks_overflow_802: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -109840,7 +109840,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_nqsBrjBbEdouqvv: +.L_16_blocks_ok_802: @@ -109977,7 +109977,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_vxEhEpzckFefkEh: +.L_small_initial_partial_block_803: @@ -110046,11 +110046,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vxEhEpzckFefkEh: +.L_small_initial_compute_done_803: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vxEhEpzckFefkEh: - jmp .L_last_blocks_done_zGdCBEiybwnDAAi -.L_last_num_blocks_is_0_zGdCBEiybwnDAAi: +.L_after_reduction_803: + jmp .L_last_blocks_done_771 +.L_last_num_blocks_is_0_771: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -110112,65 +110112,65 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_zGdCBEiybwnDAAi: +.L_last_blocks_done_771: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_EzeEqCiibleghsn + jmp .L_ghash_done_659 -.L_message_below_equal_16_blocks_EzeEqCiibleghsn: +.L_message_below_equal_16_blocks_659: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_uguocdcokEpnmjy - jl .L_small_initial_num_blocks_is_7_1_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_8_804 + jl .L_small_initial_num_blocks_is_7_1_804 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_uguocdcokEpnmjy - jl .L_small_initial_num_blocks_is_11_9_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_12_804 + jl .L_small_initial_num_blocks_is_11_9_804 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_16_804 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_15_804 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_uguocdcokEpnmjy - jmp .L_small_initial_num_blocks_is_13_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_14_804 + jmp .L_small_initial_num_blocks_is_13_804 -.L_small_initial_num_blocks_is_11_9_uguocdcokEpnmjy: +.L_small_initial_num_blocks_is_11_9_804: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_11_804 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_uguocdcokEpnmjy - jmp .L_small_initial_num_blocks_is_9_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_10_804 + jmp .L_small_initial_num_blocks_is_9_804 -.L_small_initial_num_blocks_is_7_1_uguocdcokEpnmjy: +.L_small_initial_num_blocks_is_7_1_804: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_uguocdcokEpnmjy - jl .L_small_initial_num_blocks_is_3_1_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_4_804 + jl .L_small_initial_num_blocks_is_3_1_804 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_7_804 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_uguocdcokEpnmjy - jmp .L_small_initial_num_blocks_is_5_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_6_804 + jmp .L_small_initial_num_blocks_is_5_804 -.L_small_initial_num_blocks_is_3_1_uguocdcokEpnmjy: +.L_small_initial_num_blocks_is_3_1_804: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_3_804 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_uguocdcokEpnmjy + je .L_small_initial_num_blocks_is_2_804 -.L_small_initial_num_blocks_is_1_uguocdcokEpnmjy: +.L_small_initial_num_blocks_is_1_804: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -110215,7 +110215,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DeaEuaqwxwliFud + jl .L_small_initial_partial_block_805 @@ -110257,8 +110257,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DeaEuaqwxwliFud -.L_small_initial_partial_block_DeaEuaqwxwliFud: + jmp .L_small_initial_compute_done_805 +.L_small_initial_partial_block_805: @@ -110282,11 +110282,11 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_DeaEuaqwxwliFud -.L_small_initial_compute_done_DeaEuaqwxwliFud: -.L_after_reduction_DeaEuaqwxwliFud: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_2_uguocdcokEpnmjy: + jmp .L_after_reduction_805 +.L_small_initial_compute_done_805: +.L_after_reduction_805: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_2_804: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -110333,7 +110333,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zeEGbjlDfqoEeAh + jl .L_small_initial_partial_block_806 @@ -110375,8 +110375,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zeEGbjlDfqoEeAh -.L_small_initial_partial_block_zeEGbjlDfqoEeAh: + jmp .L_small_initial_compute_done_806 +.L_small_initial_partial_block_806: @@ -110421,14 +110421,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zeEGbjlDfqoEeAh: +.L_small_initial_compute_done_806: orq %r8,%r8 - je .L_after_reduction_zeEGbjlDfqoEeAh + je .L_after_reduction_806 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_zeEGbjlDfqoEeAh: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_3_uguocdcokEpnmjy: +.L_after_reduction_806: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_3_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -110475,7 +110475,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kjmgdlDyFwCbEAu + jl .L_small_initial_partial_block_807 @@ -110518,8 +110518,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kjmgdlDyFwCbEAu -.L_small_initial_partial_block_kjmgdlDyFwCbEAu: + jmp .L_small_initial_compute_done_807 +.L_small_initial_partial_block_807: @@ -110564,14 +110564,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kjmgdlDyFwCbEAu: +.L_small_initial_compute_done_807: orq %r8,%r8 - je .L_after_reduction_kjmgdlDyFwCbEAu + je .L_after_reduction_807 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_kjmgdlDyFwCbEAu: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_4_uguocdcokEpnmjy: +.L_after_reduction_807: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_4_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -110618,7 +110618,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ybdoAnBdcpmDocn + jl .L_small_initial_partial_block_808 @@ -110660,8 +110660,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ybdoAnBdcpmDocn -.L_small_initial_partial_block_ybdoAnBdcpmDocn: + jmp .L_small_initial_compute_done_808 +.L_small_initial_partial_block_808: @@ -110707,14 +110707,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ybdoAnBdcpmDocn: +.L_small_initial_compute_done_808: orq %r8,%r8 - je .L_after_reduction_ybdoAnBdcpmDocn + je .L_after_reduction_808 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_ybdoAnBdcpmDocn: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_5_uguocdcokEpnmjy: +.L_after_reduction_808: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_5_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -110781,7 +110781,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CsqvrAcxlBrwGxv + jl .L_small_initial_partial_block_809 @@ -110833,8 +110833,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CsqvrAcxlBrwGxv -.L_small_initial_partial_block_CsqvrAcxlBrwGxv: + jmp .L_small_initial_compute_done_809 +.L_small_initial_partial_block_809: @@ -110879,14 +110879,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CsqvrAcxlBrwGxv: +.L_small_initial_compute_done_809: orq %r8,%r8 - je .L_after_reduction_CsqvrAcxlBrwGxv + je .L_after_reduction_809 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_CsqvrAcxlBrwGxv: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_6_uguocdcokEpnmjy: +.L_after_reduction_809: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_6_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -110953,7 +110953,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_icixbolBvgdkdCa + jl .L_small_initial_partial_block_810 @@ -111005,8 +111005,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_icixbolBvgdkdCa -.L_small_initial_partial_block_icixbolBvgdkdCa: + jmp .L_small_initial_compute_done_810 +.L_small_initial_partial_block_810: @@ -111061,14 +111061,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_icixbolBvgdkdCa: +.L_small_initial_compute_done_810: orq %r8,%r8 - je .L_after_reduction_icixbolBvgdkdCa + je .L_after_reduction_810 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_icixbolBvgdkdCa: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_7_uguocdcokEpnmjy: +.L_after_reduction_810: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_7_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -111135,7 +111135,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tolGblpuEEldpux + jl .L_small_initial_partial_block_811 @@ -111188,8 +111188,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tolGblpuEEldpux -.L_small_initial_partial_block_tolGblpuEEldpux: + jmp .L_small_initial_compute_done_811 +.L_small_initial_partial_block_811: @@ -111244,14 +111244,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tolGblpuEEldpux: +.L_small_initial_compute_done_811: orq %r8,%r8 - je .L_after_reduction_tolGblpuEEldpux + je .L_after_reduction_811 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_tolGblpuEEldpux: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_8_uguocdcokEpnmjy: +.L_after_reduction_811: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_8_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -111318,7 +111318,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fitvEFDkloczDFj + jl .L_small_initial_partial_block_812 @@ -111369,8 +111369,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fitvEFDkloczDFj -.L_small_initial_partial_block_fitvEFDkloczDFj: + jmp .L_small_initial_compute_done_812 +.L_small_initial_partial_block_812: @@ -111426,14 +111426,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fitvEFDkloczDFj: +.L_small_initial_compute_done_812: orq %r8,%r8 - je .L_after_reduction_fitvEFDkloczDFj + je .L_after_reduction_812 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_fitvEFDkloczDFj: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_9_uguocdcokEpnmjy: +.L_after_reduction_812: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_9_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -111519,7 +111519,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xehjqAqfvmmecxy + jl .L_small_initial_partial_block_813 @@ -111580,8 +111580,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xehjqAqfvmmecxy -.L_small_initial_partial_block_xehjqAqfvmmecxy: + jmp .L_small_initial_compute_done_813 +.L_small_initial_partial_block_813: @@ -111635,14 +111635,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_xehjqAqfvmmecxy: +.L_small_initial_compute_done_813: orq %r8,%r8 - je .L_after_reduction_xehjqAqfvmmecxy + je .L_after_reduction_813 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_xehjqAqfvmmecxy: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_10_uguocdcokEpnmjy: +.L_after_reduction_813: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_10_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -111728,7 +111728,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_CjfugwxsApdsbuj + jl .L_small_initial_partial_block_814 @@ -111789,8 +111789,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_CjfugwxsApdsbuj -.L_small_initial_partial_block_CjfugwxsApdsbuj: + jmp .L_small_initial_compute_done_814 +.L_small_initial_partial_block_814: @@ -111854,14 +111854,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_CjfugwxsApdsbuj: +.L_small_initial_compute_done_814: orq %r8,%r8 - je .L_after_reduction_CjfugwxsApdsbuj + je .L_after_reduction_814 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_CjfugwxsApdsbuj: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_11_uguocdcokEpnmjy: +.L_after_reduction_814: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_11_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -111947,7 +111947,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hBmdnqrsjgblCED + jl .L_small_initial_partial_block_815 @@ -112009,8 +112009,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hBmdnqrsjgblCED -.L_small_initial_partial_block_hBmdnqrsjgblCED: + jmp .L_small_initial_compute_done_815 +.L_small_initial_partial_block_815: @@ -112074,14 +112074,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hBmdnqrsjgblCED: +.L_small_initial_compute_done_815: orq %r8,%r8 - je .L_after_reduction_hBmdnqrsjgblCED + je .L_after_reduction_815 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_hBmdnqrsjgblCED: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_12_uguocdcokEpnmjy: +.L_after_reduction_815: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_12_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -112167,7 +112167,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AqeGbibuyaosGju + jl .L_small_initial_partial_block_816 @@ -112223,8 +112223,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AqeGbibuyaosGju -.L_small_initial_partial_block_AqeGbibuyaosGju: + jmp .L_small_initial_compute_done_816 +.L_small_initial_partial_block_816: @@ -112289,14 +112289,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AqeGbibuyaosGju: +.L_small_initial_compute_done_816: orq %r8,%r8 - je .L_after_reduction_AqeGbibuyaosGju + je .L_after_reduction_816 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_AqeGbibuyaosGju: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_13_uguocdcokEpnmjy: +.L_after_reduction_816: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_13_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -112401,7 +112401,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DejowidehECliyC + jl .L_small_initial_partial_block_817 @@ -112467,8 +112467,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DejowidehECliyC -.L_small_initial_partial_block_DejowidehECliyC: + jmp .L_small_initial_compute_done_817 +.L_small_initial_partial_block_817: @@ -112527,14 +112527,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DejowidehECliyC: +.L_small_initial_compute_done_817: orq %r8,%r8 - je .L_after_reduction_DejowidehECliyC + je .L_after_reduction_817 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_DejowidehECliyC: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_14_uguocdcokEpnmjy: +.L_after_reduction_817: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_14_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -112639,7 +112639,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qxftApipErlhoBp + jl .L_small_initial_partial_block_818 @@ -112705,8 +112705,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qxftApipErlhoBp -.L_small_initial_partial_block_qxftApipErlhoBp: + jmp .L_small_initial_compute_done_818 +.L_small_initial_partial_block_818: @@ -112775,14 +112775,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qxftApipErlhoBp: +.L_small_initial_compute_done_818: orq %r8,%r8 - je .L_after_reduction_qxftApipErlhoBp + je .L_after_reduction_818 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_qxftApipErlhoBp: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_15_uguocdcokEpnmjy: +.L_after_reduction_818: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_15_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -112887,7 +112887,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FDxdndErhhsmFuD + jl .L_small_initial_partial_block_819 @@ -112954,8 +112954,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FDxdndErhhsmFuD -.L_small_initial_partial_block_FDxdndErhhsmFuD: + jmp .L_small_initial_compute_done_819 +.L_small_initial_partial_block_819: @@ -113024,14 +113024,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FDxdndErhhsmFuD: +.L_small_initial_compute_done_819: orq %r8,%r8 - je .L_after_reduction_FDxdndErhhsmFuD + je .L_after_reduction_819 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_FDxdndErhhsmFuD: - jmp .L_small_initial_blocks_encrypted_uguocdcokEpnmjy -.L_small_initial_num_blocks_is_16_uguocdcokEpnmjy: +.L_after_reduction_819: + jmp .L_small_initial_blocks_encrypted_804 +.L_small_initial_num_blocks_is_16_804: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -113133,7 +113133,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm11,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_drBwqslxDntwvlz: +.L_small_initial_partial_block_820: @@ -113203,25 +113203,25 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_drBwqslxDntwvlz: +.L_small_initial_compute_done_820: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_drBwqslxDntwvlz: -.L_small_initial_blocks_encrypted_uguocdcokEpnmjy: -.L_ghash_done_EzeEqCiibleghsn: +.L_after_reduction_820: +.L_small_initial_blocks_encrypted_804: +.L_ghash_done_659: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_EzeEqCiibleghsn: +.L_enc_dec_done_659: jmp .Lexit_gcm_decrypt .align 32 .Laes_gcm_decrypt_256_avx512: orq %r8,%r8 - je .L_enc_dec_done_BgFfAgFalCBiqtf + je .L_enc_dec_done_821 xorq %r14,%r14 vmovdqu64 64(%rsi),%xmm14 movq (%rdx),%r11 orq %r11,%r11 - je .L_partial_block_done_ietExhhcgDljsFr + je .L_partial_block_done_822 movl $16,%r10d leaq byte_len_to_mask_table(%rip),%r12 cmpq %r10,%r8 @@ -113245,9 +113245,9 @@ ossl_aes_gcm_decrypt_avx512: leaq (%r8,%r11,1),%r13 subq $16,%r13 - jge .L_no_extra_mask_ietExhhcgDljsFr + jge .L_no_extra_mask_822 subq %r13,%r12 -.L_no_extra_mask_ietExhhcgDljsFr: +.L_no_extra_mask_822: @@ -113258,7 +113258,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %xmm5,%xmm6,%xmm6 vpxorq %xmm6,%xmm14,%xmm14 cmpq $0,%r13 - jl .L_partial_incomplete_ietExhhcgDljsFr + jl .L_partial_incomplete_822 vpclmulqdq $0x11,%xmm4,%xmm14,%xmm7 vpclmulqdq $0x00,%xmm4,%xmm14,%xmm10 @@ -113293,13 +113293,13 @@ ossl_aes_gcm_decrypt_avx512: movq %r11,%r12 movq $16,%r11 subq %r12,%r11 - jmp .L_enc_dec_done_ietExhhcgDljsFr + jmp .L_enc_dec_done_822 -.L_partial_incomplete_ietExhhcgDljsFr: +.L_partial_incomplete_822: addq %r8,(%rdx) movq %r8,%r11 -.L_enc_dec_done_ietExhhcgDljsFr: +.L_enc_dec_done_822: leaq byte_len_to_mask_table(%rip),%r12 @@ -113307,12 +113307,12 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 %xmm14,64(%rsi) movq %r9,%r12 vmovdqu8 %xmm3,(%r12){%k1} -.L_partial_block_done_ietExhhcgDljsFr: +.L_partial_block_done_822: vmovdqu64 0(%rsi),%xmm2 subq %r11,%r8 - je .L_enc_dec_done_BgFfAgFalCBiqtf + je .L_enc_dec_done_821 cmpq $256,%r8 - jbe .L_message_below_equal_16_blocks_BgFfAgFalCBiqtf + jbe .L_message_below_equal_16_blocks_821 vmovdqa64 SHUF_MASK(%rip),%zmm29 vmovdqa64 ddq_addbe_4444(%rip),%zmm27 @@ -113332,13 +113332,13 @@ ossl_aes_gcm_decrypt_avx512: cmpb $240,%r15b - jae .L_next_16_overflow_lmvpiqbBrlurcnA + jae .L_next_16_overflow_823 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_lmvpiqbBrlurcnA -.L_next_16_overflow_lmvpiqbBrlurcnA: + jmp .L_next_16_ok_823 +.L_next_16_overflow_823: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -113349,7 +113349,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_lmvpiqbBrlurcnA: +.L_next_16_ok_823: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -113457,7 +113457,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,896(%rsp) vmovdqa64 %zmm12,960(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_kzephFbcxwFaFnk + jnz .L_skip_hkeys_precomputation_824 vmovdqu64 288(%rsi),%zmm0 vmovdqu64 %zmm0,704(%rsp) @@ -113473,20 +113473,20 @@ ossl_aes_gcm_decrypt_avx512: vmovdqu64 96(%rsi),%zmm5 vmovdqu64 %zmm5,512(%rsp) -.L_skip_hkeys_precomputation_kzephFbcxwFaFnk: +.L_skip_hkeys_precomputation_824: cmpq $512,%r8 - jb .L_message_below_32_blocks_BgFfAgFalCBiqtf + jb .L_message_below_32_blocks_821 cmpb $240,%r15b - jae .L_next_16_overflow_FEGbovkkcgjGrGw + jae .L_next_16_overflow_825 vpaddd %zmm28,%zmm2,%zmm7 vpaddd %zmm27,%zmm7,%zmm10 vpaddd %zmm27,%zmm10,%zmm11 vpaddd %zmm27,%zmm11,%zmm12 - jmp .L_next_16_ok_FEGbovkkcgjGrGw -.L_next_16_overflow_FEGbovkkcgjGrGw: + jmp .L_next_16_ok_825 +.L_next_16_overflow_825: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm12 vpaddd ddq_add_1234(%rip),%zmm2,%zmm7 @@ -113497,7 +113497,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm10,%zmm10 vpshufb %zmm29,%zmm11,%zmm11 vpshufb %zmm29,%zmm12,%zmm12 -.L_next_16_ok_FEGbovkkcgjGrGw: +.L_next_16_ok_825: vshufi64x2 $255,%zmm12,%zmm12,%zmm2 addb $16,%r15b @@ -113605,7 +113605,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm11,1152(%rsp) vmovdqa64 %zmm12,1216(%rsp) testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_GbbBjkinxxqFykE + jnz .L_skip_hkeys_precomputation_826 vmovdqu64 640(%rsp),%zmm3 @@ -113853,22 +113853,22 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,0(%rsp) -.L_skip_hkeys_precomputation_GbbBjkinxxqFykE: +.L_skip_hkeys_precomputation_826: movq $1,%r14 addq $512,%r11 subq $512,%r8 cmpq $768,%r8 - jb .L_no_more_big_nblocks_BgFfAgFalCBiqtf -.L_encrypt_big_nblocks_BgFfAgFalCBiqtf: + jb .L_no_more_big_nblocks_821 +.L_encrypt_big_nblocks_821: cmpb $240,%r15b - jae .L_16_blocks_overflow_GjhrlamdEjDqito + jae .L_16_blocks_overflow_827 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_GjhrlamdEjDqito -.L_16_blocks_overflow_GjhrlamdEjDqito: + jmp .L_16_blocks_ok_827 +.L_16_blocks_overflow_827: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -113879,7 +113879,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_GjhrlamdEjDqito: +.L_16_blocks_ok_827: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -114067,13 +114067,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_bhgtflwnesEFDEG + jae .L_16_blocks_overflow_828 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_bhgtflwnesEFDEG -.L_16_blocks_overflow_bhgtflwnesEFDEG: + jmp .L_16_blocks_ok_828 +.L_16_blocks_overflow_828: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -114084,7 +114084,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_bhgtflwnesEFDEG: +.L_16_blocks_ok_828: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -114272,13 +114272,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,896(%rsp) vmovdqa64 %zmm5,960(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_nckpabxFgacrijF + jae .L_16_blocks_overflow_829 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_nckpabxFgacrijF -.L_16_blocks_overflow_nckpabxFgacrijF: + jmp .L_16_blocks_ok_829 +.L_16_blocks_overflow_829: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -114289,7 +114289,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_nckpabxFgacrijF: +.L_16_blocks_ok_829: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1280(%rsp),%zmm8 vmovdqu64 512(%rsp),%zmm1 @@ -114507,16 +114507,16 @@ ossl_aes_gcm_decrypt_avx512: addq $768,%r11 subq $768,%r8 cmpq $768,%r8 - jae .L_encrypt_big_nblocks_BgFfAgFalCBiqtf + jae .L_encrypt_big_nblocks_821 -.L_no_more_big_nblocks_BgFfAgFalCBiqtf: +.L_no_more_big_nblocks_821: cmpq $512,%r8 - jae .L_encrypt_32_blocks_BgFfAgFalCBiqtf + jae .L_encrypt_32_blocks_821 cmpq $256,%r8 - jae .L_encrypt_16_blocks_BgFfAgFalCBiqtf -.L_encrypt_0_blocks_ghash_32_BgFfAgFalCBiqtf: + jae .L_encrypt_16_blocks_821 +.L_encrypt_0_blocks_ghash_32_821: movl %r8d,%r10d andl $~15,%r10d movl $256,%ebx @@ -114559,61 +114559,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_obndhAGbhpDwcwD + je .L_last_num_blocks_is_0_830 cmpl $8,%r10d - je .L_last_num_blocks_is_8_obndhAGbhpDwcwD - jb .L_last_num_blocks_is_7_1_obndhAGbhpDwcwD + je .L_last_num_blocks_is_8_830 + jb .L_last_num_blocks_is_7_1_830 cmpl $12,%r10d - je .L_last_num_blocks_is_12_obndhAGbhpDwcwD - jb .L_last_num_blocks_is_11_9_obndhAGbhpDwcwD + je .L_last_num_blocks_is_12_830 + jb .L_last_num_blocks_is_11_9_830 cmpl $15,%r10d - je .L_last_num_blocks_is_15_obndhAGbhpDwcwD - ja .L_last_num_blocks_is_16_obndhAGbhpDwcwD + je .L_last_num_blocks_is_15_830 + ja .L_last_num_blocks_is_16_830 cmpl $14,%r10d - je .L_last_num_blocks_is_14_obndhAGbhpDwcwD - jmp .L_last_num_blocks_is_13_obndhAGbhpDwcwD + je .L_last_num_blocks_is_14_830 + jmp .L_last_num_blocks_is_13_830 -.L_last_num_blocks_is_11_9_obndhAGbhpDwcwD: +.L_last_num_blocks_is_11_9_830: cmpl $10,%r10d - je .L_last_num_blocks_is_10_obndhAGbhpDwcwD - ja .L_last_num_blocks_is_11_obndhAGbhpDwcwD - jmp .L_last_num_blocks_is_9_obndhAGbhpDwcwD + je .L_last_num_blocks_is_10_830 + ja .L_last_num_blocks_is_11_830 + jmp .L_last_num_blocks_is_9_830 -.L_last_num_blocks_is_7_1_obndhAGbhpDwcwD: +.L_last_num_blocks_is_7_1_830: cmpl $4,%r10d - je .L_last_num_blocks_is_4_obndhAGbhpDwcwD - jb .L_last_num_blocks_is_3_1_obndhAGbhpDwcwD + je .L_last_num_blocks_is_4_830 + jb .L_last_num_blocks_is_3_1_830 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_obndhAGbhpDwcwD - je .L_last_num_blocks_is_6_obndhAGbhpDwcwD - jmp .L_last_num_blocks_is_5_obndhAGbhpDwcwD + ja .L_last_num_blocks_is_7_830 + je .L_last_num_blocks_is_6_830 + jmp .L_last_num_blocks_is_5_830 -.L_last_num_blocks_is_3_1_obndhAGbhpDwcwD: +.L_last_num_blocks_is_3_1_830: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_obndhAGbhpDwcwD - je .L_last_num_blocks_is_2_obndhAGbhpDwcwD -.L_last_num_blocks_is_1_obndhAGbhpDwcwD: + ja .L_last_num_blocks_is_3_830 + je .L_last_num_blocks_is_2_830 +.L_last_num_blocks_is_1_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_epjDmoeulFAzEai + jae .L_16_blocks_overflow_831 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_epjDmoeulFAzEai + jmp .L_16_blocks_ok_831 -.L_16_blocks_overflow_epjDmoeulFAzEai: +.L_16_blocks_overflow_831: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_epjDmoeulFAzEai: +.L_16_blocks_ok_831: @@ -114705,7 +114705,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xEqamgGjbbwccpa + jl .L_small_initial_partial_block_832 @@ -114749,8 +114749,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xEqamgGjbbwccpa -.L_small_initial_partial_block_xEqamgGjbbwccpa: + jmp .L_small_initial_compute_done_832 +.L_small_initial_partial_block_832: @@ -114802,24 +114802,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_xEqamgGjbbwccpa -.L_small_initial_compute_done_xEqamgGjbbwccpa: -.L_after_reduction_xEqamgGjbbwccpa: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_2_obndhAGbhpDwcwD: + jmp .L_after_reduction_832 +.L_small_initial_compute_done_832: +.L_after_reduction_832: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_2_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_alAtdtziqAhxxcG + jae .L_16_blocks_overflow_833 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_alAtdtziqAhxxcG + jmp .L_16_blocks_ok_833 -.L_16_blocks_overflow_alAtdtziqAhxxcG: +.L_16_blocks_overflow_833: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_alAtdtziqAhxxcG: +.L_16_blocks_ok_833: @@ -114912,7 +114912,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gzbvnvddzhtadwC + jl .L_small_initial_partial_block_834 @@ -114956,8 +114956,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gzbvnvddzhtadwC -.L_small_initial_partial_block_gzbvnvddzhtadwC: + jmp .L_small_initial_compute_done_834 +.L_small_initial_partial_block_834: @@ -115004,27 +115004,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gzbvnvddzhtadwC: +.L_small_initial_compute_done_834: orq %r8,%r8 - je .L_after_reduction_gzbvnvddzhtadwC + je .L_after_reduction_834 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gzbvnvddzhtadwC: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_3_obndhAGbhpDwcwD: +.L_after_reduction_834: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_3_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_aFomtgvepzvzxiq + jae .L_16_blocks_overflow_835 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_aFomtgvepzvzxiq + jmp .L_16_blocks_ok_835 -.L_16_blocks_overflow_aFomtgvepzvzxiq: +.L_16_blocks_overflow_835: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_aFomtgvepzvzxiq: +.L_16_blocks_ok_835: @@ -115117,7 +115117,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_DcACBlvyEkxyepf + jl .L_small_initial_partial_block_836 @@ -115162,8 +115162,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_DcACBlvyEkxyepf -.L_small_initial_partial_block_DcACBlvyEkxyepf: + jmp .L_small_initial_compute_done_836 +.L_small_initial_partial_block_836: @@ -115210,27 +115210,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DcACBlvyEkxyepf: +.L_small_initial_compute_done_836: orq %r8,%r8 - je .L_after_reduction_DcACBlvyEkxyepf + je .L_after_reduction_836 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DcACBlvyEkxyepf: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_4_obndhAGbhpDwcwD: +.L_after_reduction_836: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_4_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_rbFvoGniysnxbfq + jae .L_16_blocks_overflow_837 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_rbFvoGniysnxbfq + jmp .L_16_blocks_ok_837 -.L_16_blocks_overflow_rbFvoGniysnxbfq: +.L_16_blocks_overflow_837: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_rbFvoGniysnxbfq: +.L_16_blocks_ok_837: @@ -115323,7 +115323,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_FCFuahmbwioAgwe + jl .L_small_initial_partial_block_838 @@ -115368,8 +115368,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_FCFuahmbwioAgwe -.L_small_initial_partial_block_FCFuahmbwioAgwe: + jmp .L_small_initial_compute_done_838 +.L_small_initial_partial_block_838: @@ -115417,32 +115417,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_FCFuahmbwioAgwe: +.L_small_initial_compute_done_838: orq %r8,%r8 - je .L_after_reduction_FCFuahmbwioAgwe + je .L_after_reduction_838 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_FCFuahmbwioAgwe: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_5_obndhAGbhpDwcwD: +.L_after_reduction_838: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_5_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_mCnedkbcelkfhgd + jae .L_16_blocks_overflow_839 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_mCnedkbcelkfhgd + jmp .L_16_blocks_ok_839 -.L_16_blocks_overflow_mCnedkbcelkfhgd: +.L_16_blocks_overflow_839: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_mCnedkbcelkfhgd: +.L_16_blocks_ok_839: @@ -115554,7 +115554,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dhhhEzBrhyefkpb + jl .L_small_initial_partial_block_840 @@ -115605,8 +115605,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dhhhEzBrhyefkpb -.L_small_initial_partial_block_dhhhEzBrhyefkpb: + jmp .L_small_initial_compute_done_840 +.L_small_initial_partial_block_840: @@ -115654,32 +115654,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dhhhEzBrhyefkpb: +.L_small_initial_compute_done_840: orq %r8,%r8 - je .L_after_reduction_dhhhEzBrhyefkpb + je .L_after_reduction_840 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_dhhhEzBrhyefkpb: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_6_obndhAGbhpDwcwD: +.L_after_reduction_840: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_6_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_DCGjrdfzAwhcjay + jae .L_16_blocks_overflow_841 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_DCGjrdfzAwhcjay + jmp .L_16_blocks_ok_841 -.L_16_blocks_overflow_DCGjrdfzAwhcjay: +.L_16_blocks_overflow_841: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_DCGjrdfzAwhcjay: +.L_16_blocks_ok_841: @@ -115791,7 +115791,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GozpeluEtznBemc + jl .L_small_initial_partial_block_842 @@ -115842,8 +115842,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GozpeluEtznBemc -.L_small_initial_partial_block_GozpeluEtznBemc: + jmp .L_small_initial_compute_done_842 +.L_small_initial_partial_block_842: @@ -115897,32 +115897,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GozpeluEtznBemc: +.L_small_initial_compute_done_842: orq %r8,%r8 - je .L_after_reduction_GozpeluEtznBemc + je .L_after_reduction_842 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GozpeluEtznBemc: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_7_obndhAGbhpDwcwD: +.L_after_reduction_842: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_7_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_gyjpEtAobldqEEj + jae .L_16_blocks_overflow_843 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_gyjpEtAobldqEEj + jmp .L_16_blocks_ok_843 -.L_16_blocks_overflow_gyjpEtAobldqEEj: +.L_16_blocks_overflow_843: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_gyjpEtAobldqEEj: +.L_16_blocks_ok_843: @@ -116034,7 +116034,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ipnpdhiCmBAwahp + jl .L_small_initial_partial_block_844 @@ -116086,8 +116086,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ipnpdhiCmBAwahp -.L_small_initial_partial_block_ipnpdhiCmBAwahp: + jmp .L_small_initial_compute_done_844 +.L_small_initial_partial_block_844: @@ -116141,32 +116141,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ipnpdhiCmBAwahp: +.L_small_initial_compute_done_844: orq %r8,%r8 - je .L_after_reduction_ipnpdhiCmBAwahp + je .L_after_reduction_844 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ipnpdhiCmBAwahp: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_8_obndhAGbhpDwcwD: +.L_after_reduction_844: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_8_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_rvBgqcrdGAdFhrz + jae .L_16_blocks_overflow_845 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_rvBgqcrdGAdFhrz + jmp .L_16_blocks_ok_845 -.L_16_blocks_overflow_rvBgqcrdGAdFhrz: +.L_16_blocks_overflow_845: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_rvBgqcrdGAdFhrz: +.L_16_blocks_ok_845: @@ -116278,7 +116278,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_odzdxgnGExAlkDw + jl .L_small_initial_partial_block_846 @@ -116332,8 +116332,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_odzdxgnGExAlkDw -.L_small_initial_partial_block_odzdxgnGExAlkDw: + jmp .L_small_initial_compute_done_846 +.L_small_initial_partial_block_846: @@ -116388,26 +116388,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_odzdxgnGExAlkDw: +.L_small_initial_compute_done_846: orq %r8,%r8 - je .L_after_reduction_odzdxgnGExAlkDw + je .L_after_reduction_846 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_odzdxgnGExAlkDw: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_9_obndhAGbhpDwcwD: +.L_after_reduction_846: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_9_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_kcFAmzBbrxgdibi + jae .L_16_blocks_overflow_847 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_kcFAmzBbrxgdibi + jmp .L_16_blocks_ok_847 -.L_16_blocks_overflow_kcFAmzBbrxgdibi: +.L_16_blocks_overflow_847: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -116416,7 +116416,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_kcFAmzBbrxgdibi: +.L_16_blocks_ok_847: @@ -116547,7 +116547,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gwxGvCfzwlanoxm + jl .L_small_initial_partial_block_848 @@ -116607,8 +116607,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gwxGvCfzwlanoxm -.L_small_initial_partial_block_gwxGvCfzwlanoxm: + jmp .L_small_initial_compute_done_848 +.L_small_initial_partial_block_848: @@ -116665,26 +116665,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gwxGvCfzwlanoxm: +.L_small_initial_compute_done_848: orq %r8,%r8 - je .L_after_reduction_gwxGvCfzwlanoxm + je .L_after_reduction_848 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_gwxGvCfzwlanoxm: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_10_obndhAGbhpDwcwD: +.L_after_reduction_848: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_10_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_iFinvhmymrAnrEB + jae .L_16_blocks_overflow_849 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_iFinvhmymrAnrEB + jmp .L_16_blocks_ok_849 -.L_16_blocks_overflow_iFinvhmymrAnrEB: +.L_16_blocks_overflow_849: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -116693,7 +116693,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_iFinvhmymrAnrEB: +.L_16_blocks_ok_849: @@ -116824,7 +116824,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vvxcGqdEzEGCcqF + jl .L_small_initial_partial_block_850 @@ -116884,8 +116884,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vvxcGqdEzEGCcqF -.L_small_initial_partial_block_vvxcGqdEzEGCcqF: + jmp .L_small_initial_compute_done_850 +.L_small_initial_partial_block_850: @@ -116948,26 +116948,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vvxcGqdEzEGCcqF: +.L_small_initial_compute_done_850: orq %r8,%r8 - je .L_after_reduction_vvxcGqdEzEGCcqF + je .L_after_reduction_850 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vvxcGqdEzEGCcqF: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_11_obndhAGbhpDwcwD: +.L_after_reduction_850: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_11_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_hpgBbEgzweaErAA + jae .L_16_blocks_overflow_851 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_hpgBbEgzweaErAA + jmp .L_16_blocks_ok_851 -.L_16_blocks_overflow_hpgBbEgzweaErAA: +.L_16_blocks_overflow_851: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -116976,7 +116976,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_hpgBbEgzweaErAA: +.L_16_blocks_ok_851: @@ -117107,7 +117107,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_sdjrqwBwbppdvDD + jl .L_small_initial_partial_block_852 @@ -117168,8 +117168,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_sdjrqwBwbppdvDD -.L_small_initial_partial_block_sdjrqwBwbppdvDD: + jmp .L_small_initial_compute_done_852 +.L_small_initial_partial_block_852: @@ -117232,26 +117232,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_sdjrqwBwbppdvDD: +.L_small_initial_compute_done_852: orq %r8,%r8 - je .L_after_reduction_sdjrqwBwbppdvDD + je .L_after_reduction_852 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_sdjrqwBwbppdvDD: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_12_obndhAGbhpDwcwD: +.L_after_reduction_852: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_12_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_lmCAymmsEgbAyzq + jae .L_16_blocks_overflow_853 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_lmCAymmsEgbAyzq + jmp .L_16_blocks_ok_853 -.L_16_blocks_overflow_lmCAymmsEgbAyzq: +.L_16_blocks_overflow_853: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -117260,7 +117260,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_lmCAymmsEgbAyzq: +.L_16_blocks_ok_853: @@ -117391,7 +117391,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_eqoFDwfrricghto + jl .L_small_initial_partial_block_854 @@ -117450,8 +117450,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_eqoFDwfrricghto -.L_small_initial_partial_block_eqoFDwfrricghto: + jmp .L_small_initial_compute_done_854 +.L_small_initial_partial_block_854: @@ -117515,27 +117515,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_eqoFDwfrricghto: +.L_small_initial_compute_done_854: orq %r8,%r8 - je .L_after_reduction_eqoFDwfrricghto + je .L_after_reduction_854 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_eqoFDwfrricghto: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_13_obndhAGbhpDwcwD: +.L_after_reduction_854: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_13_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_kqxretCfxjCFlaF + jae .L_16_blocks_overflow_855 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_kqxretCfxjCFlaF + jmp .L_16_blocks_ok_855 -.L_16_blocks_overflow_kqxretCfxjCFlaF: +.L_16_blocks_overflow_855: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -117546,7 +117546,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_kqxretCfxjCFlaF: +.L_16_blocks_ok_855: @@ -117696,7 +117696,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mDhAFfCiursnmgi + jl .L_small_initial_partial_block_856 @@ -117761,8 +117761,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mDhAFfCiursnmgi -.L_small_initial_partial_block_mDhAFfCiursnmgi: + jmp .L_small_initial_compute_done_856 +.L_small_initial_partial_block_856: @@ -117824,27 +117824,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mDhAFfCiursnmgi: +.L_small_initial_compute_done_856: orq %r8,%r8 - je .L_after_reduction_mDhAFfCiursnmgi + je .L_after_reduction_856 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mDhAFfCiursnmgi: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_14_obndhAGbhpDwcwD: +.L_after_reduction_856: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_14_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_qqntgyscqBoyCzt + jae .L_16_blocks_overflow_857 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_qqntgyscqBoyCzt + jmp .L_16_blocks_ok_857 -.L_16_blocks_overflow_qqntgyscqBoyCzt: +.L_16_blocks_overflow_857: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -117855,7 +117855,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_qqntgyscqBoyCzt: +.L_16_blocks_ok_857: @@ -118005,7 +118005,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mAeEwEBnFkievuA + jl .L_small_initial_partial_block_858 @@ -118070,8 +118070,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mAeEwEBnFkievuA -.L_small_initial_partial_block_mAeEwEBnFkievuA: + jmp .L_small_initial_compute_done_858 +.L_small_initial_partial_block_858: @@ -118139,27 +118139,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mAeEwEBnFkievuA: +.L_small_initial_compute_done_858: orq %r8,%r8 - je .L_after_reduction_mAeEwEBnFkievuA + je .L_after_reduction_858 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mAeEwEBnFkievuA: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_15_obndhAGbhpDwcwD: +.L_after_reduction_858: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_15_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_krpjvpsuBeCykEy + jae .L_16_blocks_overflow_859 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_krpjvpsuBeCykEy + jmp .L_16_blocks_ok_859 -.L_16_blocks_overflow_krpjvpsuBeCykEy: +.L_16_blocks_overflow_859: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -118170,7 +118170,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_krpjvpsuBeCykEy: +.L_16_blocks_ok_859: @@ -118320,7 +118320,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ClFCmglpDmcEEuf + jl .L_small_initial_partial_block_860 @@ -118386,8 +118386,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ClFCmglpDmcEEuf -.L_small_initial_partial_block_ClFCmglpDmcEEuf: + jmp .L_small_initial_compute_done_860 +.L_small_initial_partial_block_860: @@ -118455,27 +118455,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ClFCmglpDmcEEuf: +.L_small_initial_compute_done_860: orq %r8,%r8 - je .L_after_reduction_ClFCmglpDmcEEuf + je .L_after_reduction_860 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ClFCmglpDmcEEuf: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_16_obndhAGbhpDwcwD: +.L_after_reduction_860: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_16_830: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_ECDfjlodgjrampA + jae .L_16_blocks_overflow_861 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ECDfjlodgjrampA + jmp .L_16_blocks_ok_861 -.L_16_blocks_overflow_ECDfjlodgjrampA: +.L_16_blocks_overflow_861: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -118486,7 +118486,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ECDfjlodgjrampA: +.L_16_blocks_ok_861: @@ -118633,7 +118633,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_DponctGCxbolodr: +.L_small_initial_partial_block_862: @@ -118702,11 +118702,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_DponctGCxbolodr: +.L_small_initial_compute_done_862: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_DponctGCxbolodr: - jmp .L_last_blocks_done_obndhAGbhpDwcwD -.L_last_num_blocks_is_0_obndhAGbhpDwcwD: +.L_after_reduction_862: + jmp .L_last_blocks_done_830 +.L_last_num_blocks_is_0_830: vmovdqa64 1024(%rsp),%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -118767,18 +118767,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_obndhAGbhpDwcwD: +.L_last_blocks_done_830: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_BgFfAgFalCBiqtf -.L_encrypt_32_blocks_BgFfAgFalCBiqtf: + jmp .L_ghash_done_821 +.L_encrypt_32_blocks_821: cmpb $240,%r15b - jae .L_16_blocks_overflow_wjnebcsacfhthiC + jae .L_16_blocks_overflow_863 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_wjnebcsacfhthiC -.L_16_blocks_overflow_wjnebcsacfhthiC: + jmp .L_16_blocks_ok_863 +.L_16_blocks_overflow_863: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -118789,7 +118789,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_wjnebcsacfhthiC: +.L_16_blocks_ok_863: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -118977,13 +118977,13 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm4,1408(%rsp) vmovdqa64 %zmm5,1472(%rsp) cmpb $240,%r15b - jae .L_16_blocks_overflow_sxplopcerpBCxFh + jae .L_16_blocks_overflow_864 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_sxplopcerpBCxFh -.L_16_blocks_overflow_sxplopcerpBCxFh: + jmp .L_16_blocks_ok_864 +.L_16_blocks_overflow_864: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -118994,7 +118994,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_sxplopcerpBCxFh: +.L_16_blocks_ok_864: vbroadcastf64x2 0(%rdi),%zmm30 vmovdqa64 1024(%rsp),%zmm8 vmovdqu64 256(%rsp),%zmm1 @@ -119250,61 +119250,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_0_865 cmpl $8,%r10d - je .L_last_num_blocks_is_8_qqnkGjkvxcoBuuo - jb .L_last_num_blocks_is_7_1_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_8_865 + jb .L_last_num_blocks_is_7_1_865 cmpl $12,%r10d - je .L_last_num_blocks_is_12_qqnkGjkvxcoBuuo - jb .L_last_num_blocks_is_11_9_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_12_865 + jb .L_last_num_blocks_is_11_9_865 cmpl $15,%r10d - je .L_last_num_blocks_is_15_qqnkGjkvxcoBuuo - ja .L_last_num_blocks_is_16_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_15_865 + ja .L_last_num_blocks_is_16_865 cmpl $14,%r10d - je .L_last_num_blocks_is_14_qqnkGjkvxcoBuuo - jmp .L_last_num_blocks_is_13_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_14_865 + jmp .L_last_num_blocks_is_13_865 -.L_last_num_blocks_is_11_9_qqnkGjkvxcoBuuo: +.L_last_num_blocks_is_11_9_865: cmpl $10,%r10d - je .L_last_num_blocks_is_10_qqnkGjkvxcoBuuo - ja .L_last_num_blocks_is_11_qqnkGjkvxcoBuuo - jmp .L_last_num_blocks_is_9_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_10_865 + ja .L_last_num_blocks_is_11_865 + jmp .L_last_num_blocks_is_9_865 -.L_last_num_blocks_is_7_1_qqnkGjkvxcoBuuo: +.L_last_num_blocks_is_7_1_865: cmpl $4,%r10d - je .L_last_num_blocks_is_4_qqnkGjkvxcoBuuo - jb .L_last_num_blocks_is_3_1_qqnkGjkvxcoBuuo + je .L_last_num_blocks_is_4_865 + jb .L_last_num_blocks_is_3_1_865 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_qqnkGjkvxcoBuuo - je .L_last_num_blocks_is_6_qqnkGjkvxcoBuuo - jmp .L_last_num_blocks_is_5_qqnkGjkvxcoBuuo + ja .L_last_num_blocks_is_7_865 + je .L_last_num_blocks_is_6_865 + jmp .L_last_num_blocks_is_5_865 -.L_last_num_blocks_is_3_1_qqnkGjkvxcoBuuo: +.L_last_num_blocks_is_3_1_865: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_qqnkGjkvxcoBuuo - je .L_last_num_blocks_is_2_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_1_qqnkGjkvxcoBuuo: + ja .L_last_num_blocks_is_3_865 + je .L_last_num_blocks_is_2_865 +.L_last_num_blocks_is_1_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_CqbEeivFDehuczk + jae .L_16_blocks_overflow_866 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_CqbEeivFDehuczk + jmp .L_16_blocks_ok_866 -.L_16_blocks_overflow_CqbEeivFDehuczk: +.L_16_blocks_overflow_866: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_CqbEeivFDehuczk: +.L_16_blocks_ok_866: @@ -119396,7 +119396,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ovvcrpptyxpdEsi + jl .L_small_initial_partial_block_867 @@ -119440,8 +119440,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ovvcrpptyxpdEsi -.L_small_initial_partial_block_ovvcrpptyxpdEsi: + jmp .L_small_initial_compute_done_867 +.L_small_initial_partial_block_867: @@ -119493,24 +119493,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_ovvcrpptyxpdEsi -.L_small_initial_compute_done_ovvcrpptyxpdEsi: -.L_after_reduction_ovvcrpptyxpdEsi: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_2_qqnkGjkvxcoBuuo: + jmp .L_after_reduction_867 +.L_small_initial_compute_done_867: +.L_after_reduction_867: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_2_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_lyEGefDEjqtrjnk + jae .L_16_blocks_overflow_868 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_lyEGefDEjqtrjnk + jmp .L_16_blocks_ok_868 -.L_16_blocks_overflow_lyEGefDEjqtrjnk: +.L_16_blocks_overflow_868: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_lyEGefDEjqtrjnk: +.L_16_blocks_ok_868: @@ -119603,7 +119603,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jwCvcbksDlsktFg + jl .L_small_initial_partial_block_869 @@ -119647,8 +119647,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jwCvcbksDlsktFg -.L_small_initial_partial_block_jwCvcbksDlsktFg: + jmp .L_small_initial_compute_done_869 +.L_small_initial_partial_block_869: @@ -119695,27 +119695,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jwCvcbksDlsktFg: +.L_small_initial_compute_done_869: orq %r8,%r8 - je .L_after_reduction_jwCvcbksDlsktFg + je .L_after_reduction_869 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jwCvcbksDlsktFg: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_3_qqnkGjkvxcoBuuo: +.L_after_reduction_869: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_3_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_FDwabmGcchsEryf + jae .L_16_blocks_overflow_870 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_FDwabmGcchsEryf + jmp .L_16_blocks_ok_870 -.L_16_blocks_overflow_FDwabmGcchsEryf: +.L_16_blocks_overflow_870: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_FDwabmGcchsEryf: +.L_16_blocks_ok_870: @@ -119808,7 +119808,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_oezfjaeCotimFCc + jl .L_small_initial_partial_block_871 @@ -119853,8 +119853,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_oezfjaeCotimFCc -.L_small_initial_partial_block_oezfjaeCotimFCc: + jmp .L_small_initial_compute_done_871 +.L_small_initial_partial_block_871: @@ -119901,27 +119901,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_oezfjaeCotimFCc: +.L_small_initial_compute_done_871: orq %r8,%r8 - je .L_after_reduction_oezfjaeCotimFCc + je .L_after_reduction_871 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_oezfjaeCotimFCc: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_4_qqnkGjkvxcoBuuo: +.L_after_reduction_871: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_4_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_GdjDnwnfgiqsdaw + jae .L_16_blocks_overflow_872 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_GdjDnwnfgiqsdaw + jmp .L_16_blocks_ok_872 -.L_16_blocks_overflow_GdjDnwnfgiqsdaw: +.L_16_blocks_overflow_872: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_GdjDnwnfgiqsdaw: +.L_16_blocks_ok_872: @@ -120014,7 +120014,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ukCgwvlDoBwGkvz + jl .L_small_initial_partial_block_873 @@ -120059,8 +120059,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ukCgwvlDoBwGkvz -.L_small_initial_partial_block_ukCgwvlDoBwGkvz: + jmp .L_small_initial_compute_done_873 +.L_small_initial_partial_block_873: @@ -120108,32 +120108,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ukCgwvlDoBwGkvz: +.L_small_initial_compute_done_873: orq %r8,%r8 - je .L_after_reduction_ukCgwvlDoBwGkvz + je .L_after_reduction_873 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ukCgwvlDoBwGkvz: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_5_qqnkGjkvxcoBuuo: +.L_after_reduction_873: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_5_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_nqhlhgxEGgzrkif + jae .L_16_blocks_overflow_874 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_nqhlhgxEGgzrkif + jmp .L_16_blocks_ok_874 -.L_16_blocks_overflow_nqhlhgxEGgzrkif: +.L_16_blocks_overflow_874: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_nqhlhgxEGgzrkif: +.L_16_blocks_ok_874: @@ -120245,7 +120245,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_duxrFblrgGhstzC + jl .L_small_initial_partial_block_875 @@ -120296,8 +120296,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_duxrFblrgGhstzC -.L_small_initial_partial_block_duxrFblrgGhstzC: + jmp .L_small_initial_compute_done_875 +.L_small_initial_partial_block_875: @@ -120345,32 +120345,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_duxrFblrgGhstzC: +.L_small_initial_compute_done_875: orq %r8,%r8 - je .L_after_reduction_duxrFblrgGhstzC + je .L_after_reduction_875 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_duxrFblrgGhstzC: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_6_qqnkGjkvxcoBuuo: +.L_after_reduction_875: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_6_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_EdyCnseyshzrwih + jae .L_16_blocks_overflow_876 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_EdyCnseyshzrwih + jmp .L_16_blocks_ok_876 -.L_16_blocks_overflow_EdyCnseyshzrwih: +.L_16_blocks_overflow_876: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_EdyCnseyshzrwih: +.L_16_blocks_ok_876: @@ -120482,7 +120482,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_BqbnserxoazdhFF + jl .L_small_initial_partial_block_877 @@ -120533,8 +120533,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_BqbnserxoazdhFF -.L_small_initial_partial_block_BqbnserxoazdhFF: + jmp .L_small_initial_compute_done_877 +.L_small_initial_partial_block_877: @@ -120588,32 +120588,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_BqbnserxoazdhFF: +.L_small_initial_compute_done_877: orq %r8,%r8 - je .L_after_reduction_BqbnserxoazdhFF + je .L_after_reduction_877 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_BqbnserxoazdhFF: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_7_qqnkGjkvxcoBuuo: +.L_after_reduction_877: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_7_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_lgtCCEbGyjrusov + jae .L_16_blocks_overflow_878 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_lgtCCEbGyjrusov + jmp .L_16_blocks_ok_878 -.L_16_blocks_overflow_lgtCCEbGyjrusov: +.L_16_blocks_overflow_878: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_lgtCCEbGyjrusov: +.L_16_blocks_ok_878: @@ -120725,7 +120725,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_Bowrjocufyajgdk + jl .L_small_initial_partial_block_879 @@ -120777,8 +120777,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_Bowrjocufyajgdk -.L_small_initial_partial_block_Bowrjocufyajgdk: + jmp .L_small_initial_compute_done_879 +.L_small_initial_partial_block_879: @@ -120832,32 +120832,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_Bowrjocufyajgdk: +.L_small_initial_compute_done_879: orq %r8,%r8 - je .L_after_reduction_Bowrjocufyajgdk + je .L_after_reduction_879 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_Bowrjocufyajgdk: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_8_qqnkGjkvxcoBuuo: +.L_after_reduction_879: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_8_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_heoanoulcmlywmy + jae .L_16_blocks_overflow_880 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_heoanoulcmlywmy + jmp .L_16_blocks_ok_880 -.L_16_blocks_overflow_heoanoulcmlywmy: +.L_16_blocks_overflow_880: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_heoanoulcmlywmy: +.L_16_blocks_ok_880: @@ -120969,7 +120969,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fGlGlyfbcbFljuz + jl .L_small_initial_partial_block_881 @@ -121023,8 +121023,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fGlGlyfbcbFljuz -.L_small_initial_partial_block_fGlGlyfbcbFljuz: + jmp .L_small_initial_compute_done_881 +.L_small_initial_partial_block_881: @@ -121079,26 +121079,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fGlGlyfbcbFljuz: +.L_small_initial_compute_done_881: orq %r8,%r8 - je .L_after_reduction_fGlGlyfbcbFljuz + je .L_after_reduction_881 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fGlGlyfbcbFljuz: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_9_qqnkGjkvxcoBuuo: +.L_after_reduction_881: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_9_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_xcejihsCfFBCguz + jae .L_16_blocks_overflow_882 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_xcejihsCfFBCguz + jmp .L_16_blocks_ok_882 -.L_16_blocks_overflow_xcejihsCfFBCguz: +.L_16_blocks_overflow_882: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -121107,7 +121107,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_xcejihsCfFBCguz: +.L_16_blocks_ok_882: @@ -121238,7 +121238,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_poykjChppCBGnwc + jl .L_small_initial_partial_block_883 @@ -121298,8 +121298,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_poykjChppCBGnwc -.L_small_initial_partial_block_poykjChppCBGnwc: + jmp .L_small_initial_compute_done_883 +.L_small_initial_partial_block_883: @@ -121356,26 +121356,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_poykjChppCBGnwc: +.L_small_initial_compute_done_883: orq %r8,%r8 - je .L_after_reduction_poykjChppCBGnwc + je .L_after_reduction_883 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_poykjChppCBGnwc: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_10_qqnkGjkvxcoBuuo: +.L_after_reduction_883: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_10_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_oehzythuvqAuqBv + jae .L_16_blocks_overflow_884 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_oehzythuvqAuqBv + jmp .L_16_blocks_ok_884 -.L_16_blocks_overflow_oehzythuvqAuqBv: +.L_16_blocks_overflow_884: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -121384,7 +121384,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_oehzythuvqAuqBv: +.L_16_blocks_ok_884: @@ -121515,7 +121515,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mviDFpolCcEqyiv + jl .L_small_initial_partial_block_885 @@ -121575,8 +121575,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mviDFpolCcEqyiv -.L_small_initial_partial_block_mviDFpolCcEqyiv: + jmp .L_small_initial_compute_done_885 +.L_small_initial_partial_block_885: @@ -121639,26 +121639,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mviDFpolCcEqyiv: +.L_small_initial_compute_done_885: orq %r8,%r8 - je .L_after_reduction_mviDFpolCcEqyiv + je .L_after_reduction_885 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mviDFpolCcEqyiv: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_11_qqnkGjkvxcoBuuo: +.L_after_reduction_885: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_11_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_mBmunjifwhveAaw + jae .L_16_blocks_overflow_886 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_mBmunjifwhveAaw + jmp .L_16_blocks_ok_886 -.L_16_blocks_overflow_mBmunjifwhveAaw: +.L_16_blocks_overflow_886: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -121667,7 +121667,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_mBmunjifwhveAaw: +.L_16_blocks_ok_886: @@ -121798,7 +121798,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vjtyfFDhBkEljof + jl .L_small_initial_partial_block_887 @@ -121859,8 +121859,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vjtyfFDhBkEljof -.L_small_initial_partial_block_vjtyfFDhBkEljof: + jmp .L_small_initial_compute_done_887 +.L_small_initial_partial_block_887: @@ -121923,26 +121923,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vjtyfFDhBkEljof: +.L_small_initial_compute_done_887: orq %r8,%r8 - je .L_after_reduction_vjtyfFDhBkEljof + je .L_after_reduction_887 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vjtyfFDhBkEljof: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_12_qqnkGjkvxcoBuuo: +.L_after_reduction_887: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_12_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_eAgndieweEemknm + jae .L_16_blocks_overflow_888 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_eAgndieweEemknm + jmp .L_16_blocks_ok_888 -.L_16_blocks_overflow_eAgndieweEemknm: +.L_16_blocks_overflow_888: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -121951,7 +121951,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_eAgndieweEemknm: +.L_16_blocks_ok_888: @@ -122082,7 +122082,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_mFybdBtGDhGsnhi + jl .L_small_initial_partial_block_889 @@ -122141,8 +122141,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_mFybdBtGDhGsnhi -.L_small_initial_partial_block_mFybdBtGDhGsnhi: + jmp .L_small_initial_compute_done_889 +.L_small_initial_partial_block_889: @@ -122206,27 +122206,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_mFybdBtGDhGsnhi: +.L_small_initial_compute_done_889: orq %r8,%r8 - je .L_after_reduction_mFybdBtGDhGsnhi + je .L_after_reduction_889 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_mFybdBtGDhGsnhi: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_13_qqnkGjkvxcoBuuo: +.L_after_reduction_889: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_13_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_jllxzssyhpuoxEg + jae .L_16_blocks_overflow_890 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_jllxzssyhpuoxEg + jmp .L_16_blocks_ok_890 -.L_16_blocks_overflow_jllxzssyhpuoxEg: +.L_16_blocks_overflow_890: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -122237,7 +122237,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_jllxzssyhpuoxEg: +.L_16_blocks_ok_890: @@ -122387,7 +122387,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GADbjiefrEfBbkv + jl .L_small_initial_partial_block_891 @@ -122452,8 +122452,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GADbjiefrEfBbkv -.L_small_initial_partial_block_GADbjiefrEfBbkv: + jmp .L_small_initial_compute_done_891 +.L_small_initial_partial_block_891: @@ -122515,27 +122515,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GADbjiefrEfBbkv: +.L_small_initial_compute_done_891: orq %r8,%r8 - je .L_after_reduction_GADbjiefrEfBbkv + je .L_after_reduction_891 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_GADbjiefrEfBbkv: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_14_qqnkGjkvxcoBuuo: +.L_after_reduction_891: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_14_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_cyxhszCytFixiqC + jae .L_16_blocks_overflow_892 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_cyxhszCytFixiqC + jmp .L_16_blocks_ok_892 -.L_16_blocks_overflow_cyxhszCytFixiqC: +.L_16_blocks_overflow_892: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -122546,7 +122546,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_cyxhszCytFixiqC: +.L_16_blocks_ok_892: @@ -122696,7 +122696,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_viyqdahlbpvrqaj + jl .L_small_initial_partial_block_893 @@ -122761,8 +122761,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_viyqdahlbpvrqaj -.L_small_initial_partial_block_viyqdahlbpvrqaj: + jmp .L_small_initial_compute_done_893 +.L_small_initial_partial_block_893: @@ -122830,27 +122830,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_viyqdahlbpvrqaj: +.L_small_initial_compute_done_893: orq %r8,%r8 - je .L_after_reduction_viyqdahlbpvrqaj + je .L_after_reduction_893 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_viyqdahlbpvrqaj: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_15_qqnkGjkvxcoBuuo: +.L_after_reduction_893: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_15_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_vzamjyBkjfFvdud + jae .L_16_blocks_overflow_894 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_vzamjyBkjfFvdud + jmp .L_16_blocks_ok_894 -.L_16_blocks_overflow_vzamjyBkjfFvdud: +.L_16_blocks_overflow_894: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -122861,7 +122861,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_vzamjyBkjfFvdud: +.L_16_blocks_ok_894: @@ -123011,7 +123011,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vsdGzscuaFpqgaG + jl .L_small_initial_partial_block_895 @@ -123077,8 +123077,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vsdGzscuaFpqgaG -.L_small_initial_partial_block_vsdGzscuaFpqgaG: + jmp .L_small_initial_compute_done_895 +.L_small_initial_partial_block_895: @@ -123146,27 +123146,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vsdGzscuaFpqgaG: +.L_small_initial_compute_done_895: orq %r8,%r8 - je .L_after_reduction_vsdGzscuaFpqgaG + je .L_after_reduction_895 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vsdGzscuaFpqgaG: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_16_qqnkGjkvxcoBuuo: +.L_after_reduction_895: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_16_865: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_jqbtuccBdCnDcvB + jae .L_16_blocks_overflow_896 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_jqbtuccBdCnDcvB + jmp .L_16_blocks_ok_896 -.L_16_blocks_overflow_jqbtuccBdCnDcvB: +.L_16_blocks_overflow_896: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -123177,7 +123177,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_jqbtuccBdCnDcvB: +.L_16_blocks_ok_896: @@ -123324,7 +123324,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_hxtqwfsDpatqBqd: +.L_small_initial_partial_block_897: @@ -123393,11 +123393,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hxtqwfsDpatqBqd: +.L_small_initial_compute_done_897: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hxtqwfsDpatqBqd: - jmp .L_last_blocks_done_qqnkGjkvxcoBuuo -.L_last_num_blocks_is_0_qqnkGjkvxcoBuuo: +.L_after_reduction_897: + jmp .L_last_blocks_done_865 +.L_last_num_blocks_is_0_865: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -123459,18 +123459,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_qqnkGjkvxcoBuuo: +.L_last_blocks_done_865: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_BgFfAgFalCBiqtf -.L_encrypt_16_blocks_BgFfAgFalCBiqtf: + jmp .L_ghash_done_821 +.L_encrypt_16_blocks_821: cmpb $240,%r15b - jae .L_16_blocks_overflow_xsuBFhiDiBdExbA + jae .L_16_blocks_overflow_898 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_xsuBFhiDiBdExbA -.L_16_blocks_overflow_xsuBFhiDiBdExbA: + jmp .L_16_blocks_ok_898 +.L_16_blocks_overflow_898: vpshufb %zmm29,%zmm2,%zmm2 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -123481,7 +123481,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_xsuBFhiDiBdExbA: +.L_16_blocks_ok_898: vbroadcastf64x2 0(%rdi),%zmm30 vpxorq 768(%rsp),%zmm14,%zmm8 vmovdqu64 0(%rsp),%zmm1 @@ -123706,61 +123706,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_0_899 cmpl $8,%r10d - je .L_last_num_blocks_is_8_bmmCnCClAGkAgFj - jb .L_last_num_blocks_is_7_1_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_8_899 + jb .L_last_num_blocks_is_7_1_899 cmpl $12,%r10d - je .L_last_num_blocks_is_12_bmmCnCClAGkAgFj - jb .L_last_num_blocks_is_11_9_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_12_899 + jb .L_last_num_blocks_is_11_9_899 cmpl $15,%r10d - je .L_last_num_blocks_is_15_bmmCnCClAGkAgFj - ja .L_last_num_blocks_is_16_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_15_899 + ja .L_last_num_blocks_is_16_899 cmpl $14,%r10d - je .L_last_num_blocks_is_14_bmmCnCClAGkAgFj - jmp .L_last_num_blocks_is_13_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_14_899 + jmp .L_last_num_blocks_is_13_899 -.L_last_num_blocks_is_11_9_bmmCnCClAGkAgFj: +.L_last_num_blocks_is_11_9_899: cmpl $10,%r10d - je .L_last_num_blocks_is_10_bmmCnCClAGkAgFj - ja .L_last_num_blocks_is_11_bmmCnCClAGkAgFj - jmp .L_last_num_blocks_is_9_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_10_899 + ja .L_last_num_blocks_is_11_899 + jmp .L_last_num_blocks_is_9_899 -.L_last_num_blocks_is_7_1_bmmCnCClAGkAgFj: +.L_last_num_blocks_is_7_1_899: cmpl $4,%r10d - je .L_last_num_blocks_is_4_bmmCnCClAGkAgFj - jb .L_last_num_blocks_is_3_1_bmmCnCClAGkAgFj + je .L_last_num_blocks_is_4_899 + jb .L_last_num_blocks_is_3_1_899 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_bmmCnCClAGkAgFj - je .L_last_num_blocks_is_6_bmmCnCClAGkAgFj - jmp .L_last_num_blocks_is_5_bmmCnCClAGkAgFj + ja .L_last_num_blocks_is_7_899 + je .L_last_num_blocks_is_6_899 + jmp .L_last_num_blocks_is_5_899 -.L_last_num_blocks_is_3_1_bmmCnCClAGkAgFj: +.L_last_num_blocks_is_3_1_899: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_bmmCnCClAGkAgFj - je .L_last_num_blocks_is_2_bmmCnCClAGkAgFj -.L_last_num_blocks_is_1_bmmCnCClAGkAgFj: + ja .L_last_num_blocks_is_3_899 + je .L_last_num_blocks_is_2_899 +.L_last_num_blocks_is_1_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_hGgwkkmdjbqwjDp + jae .L_16_blocks_overflow_900 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_hGgwkkmdjbqwjDp + jmp .L_16_blocks_ok_900 -.L_16_blocks_overflow_hGgwkkmdjbqwjDp: +.L_16_blocks_overflow_900: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_hGgwkkmdjbqwjDp: +.L_16_blocks_ok_900: @@ -123875,7 +123875,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ofcgydBjFqroECm + jl .L_small_initial_partial_block_901 @@ -123917,8 +123917,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ofcgydBjFqroECm -.L_small_initial_partial_block_ofcgydBjFqroECm: + jmp .L_small_initial_compute_done_901 +.L_small_initial_partial_block_901: @@ -123942,24 +123942,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_ofcgydBjFqroECm -.L_small_initial_compute_done_ofcgydBjFqroECm: -.L_after_reduction_ofcgydBjFqroECm: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_2_bmmCnCClAGkAgFj: + jmp .L_after_reduction_901 +.L_small_initial_compute_done_901: +.L_after_reduction_901: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_2_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_pawopGfayscdgvw + jae .L_16_blocks_overflow_902 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_pawopGfayscdgvw + jmp .L_16_blocks_ok_902 -.L_16_blocks_overflow_pawopGfayscdgvw: +.L_16_blocks_overflow_902: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_pawopGfayscdgvw: +.L_16_blocks_ok_902: @@ -124075,7 +124075,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kuGedDpafeFAzAj + jl .L_small_initial_partial_block_903 @@ -124117,8 +124117,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kuGedDpafeFAzAj -.L_small_initial_partial_block_kuGedDpafeFAzAj: + jmp .L_small_initial_compute_done_903 +.L_small_initial_partial_block_903: @@ -124163,27 +124163,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kuGedDpafeFAzAj: +.L_small_initial_compute_done_903: orq %r8,%r8 - je .L_after_reduction_kuGedDpafeFAzAj + je .L_after_reduction_903 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kuGedDpafeFAzAj: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_3_bmmCnCClAGkAgFj: +.L_after_reduction_903: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_3_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_FwEFvgquiDiDCmw + jae .L_16_blocks_overflow_904 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_FwEFvgquiDiDCmw + jmp .L_16_blocks_ok_904 -.L_16_blocks_overflow_FwEFvgquiDiDCmw: +.L_16_blocks_overflow_904: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_FwEFvgquiDiDCmw: +.L_16_blocks_ok_904: @@ -124299,7 +124299,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vkiEvcBfqmiFBqt + jl .L_small_initial_partial_block_905 @@ -124342,8 +124342,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vkiEvcBfqmiFBqt -.L_small_initial_partial_block_vkiEvcBfqmiFBqt: + jmp .L_small_initial_compute_done_905 +.L_small_initial_partial_block_905: @@ -124388,27 +124388,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vkiEvcBfqmiFBqt: +.L_small_initial_compute_done_905: orq %r8,%r8 - je .L_after_reduction_vkiEvcBfqmiFBqt + je .L_after_reduction_905 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_vkiEvcBfqmiFBqt: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_4_bmmCnCClAGkAgFj: +.L_after_reduction_905: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_4_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_jxjBkgBpDcdcffm + jae .L_16_blocks_overflow_906 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_jxjBkgBpDcdcffm + jmp .L_16_blocks_ok_906 -.L_16_blocks_overflow_jxjBkgBpDcdcffm: +.L_16_blocks_overflow_906: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_jxjBkgBpDcdcffm: +.L_16_blocks_ok_906: @@ -124524,7 +124524,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qecodegreduBirC + jl .L_small_initial_partial_block_907 @@ -124566,8 +124566,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qecodegreduBirC -.L_small_initial_partial_block_qecodegreduBirC: + jmp .L_small_initial_compute_done_907 +.L_small_initial_partial_block_907: @@ -124613,32 +124613,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qecodegreduBirC: +.L_small_initial_compute_done_907: orq %r8,%r8 - je .L_after_reduction_qecodegreduBirC + je .L_after_reduction_907 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_qecodegreduBirC: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_5_bmmCnCClAGkAgFj: +.L_after_reduction_907: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_5_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_xrbDdkkfxkForcf + jae .L_16_blocks_overflow_908 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_xrbDdkkfxkForcf + jmp .L_16_blocks_ok_908 -.L_16_blocks_overflow_xrbDdkkfxkForcf: +.L_16_blocks_overflow_908: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_xrbDdkkfxkForcf: +.L_16_blocks_ok_908: @@ -124773,7 +124773,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ipkrpGonrvDdlul + jl .L_small_initial_partial_block_909 @@ -124825,8 +124825,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ipkrpGonrvDdlul -.L_small_initial_partial_block_ipkrpGonrvDdlul: + jmp .L_small_initial_compute_done_909 +.L_small_initial_partial_block_909: @@ -124871,32 +124871,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ipkrpGonrvDdlul: +.L_small_initial_compute_done_909: orq %r8,%r8 - je .L_after_reduction_ipkrpGonrvDdlul + je .L_after_reduction_909 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ipkrpGonrvDdlul: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_6_bmmCnCClAGkAgFj: +.L_after_reduction_909: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_6_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_CtwuEdGsnajdAbF + jae .L_16_blocks_overflow_910 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_CtwuEdGsnajdAbF + jmp .L_16_blocks_ok_910 -.L_16_blocks_overflow_CtwuEdGsnajdAbF: +.L_16_blocks_overflow_910: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_CtwuEdGsnajdAbF: +.L_16_blocks_ok_910: @@ -125031,7 +125031,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_irvmxinkoauBnnn + jl .L_small_initial_partial_block_911 @@ -125083,8 +125083,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_irvmxinkoauBnnn -.L_small_initial_partial_block_irvmxinkoauBnnn: + jmp .L_small_initial_compute_done_911 +.L_small_initial_partial_block_911: @@ -125139,32 +125139,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_irvmxinkoauBnnn: +.L_small_initial_compute_done_911: orq %r8,%r8 - je .L_after_reduction_irvmxinkoauBnnn + je .L_after_reduction_911 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_irvmxinkoauBnnn: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_7_bmmCnCClAGkAgFj: +.L_after_reduction_911: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_7_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_EeAvozbiewjvgFD + jae .L_16_blocks_overflow_912 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_EeAvozbiewjvgFD + jmp .L_16_blocks_ok_912 -.L_16_blocks_overflow_EeAvozbiewjvgFD: +.L_16_blocks_overflow_912: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_EeAvozbiewjvgFD: +.L_16_blocks_ok_912: @@ -125299,7 +125299,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_zglGxGAzpFcFiGB + jl .L_small_initial_partial_block_913 @@ -125352,8 +125352,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_zglGxGAzpFcFiGB -.L_small_initial_partial_block_zglGxGAzpFcFiGB: + jmp .L_small_initial_compute_done_913 +.L_small_initial_partial_block_913: @@ -125408,32 +125408,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_zglGxGAzpFcFiGB: +.L_small_initial_compute_done_913: orq %r8,%r8 - je .L_after_reduction_zglGxGAzpFcFiGB + je .L_after_reduction_913 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_zglGxGAzpFcFiGB: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_8_bmmCnCClAGkAgFj: +.L_after_reduction_913: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_8_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_zaEkzmpqyunpECD + jae .L_16_blocks_overflow_914 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_zaEkzmpqyunpECD + jmp .L_16_blocks_ok_914 -.L_16_blocks_overflow_zaEkzmpqyunpECD: +.L_16_blocks_overflow_914: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_zaEkzmpqyunpECD: +.L_16_blocks_ok_914: @@ -125568,7 +125568,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nutzgwpyocmmbbl + jl .L_small_initial_partial_block_915 @@ -125619,8 +125619,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nutzgwpyocmmbbl -.L_small_initial_partial_block_nutzgwpyocmmbbl: + jmp .L_small_initial_compute_done_915 +.L_small_initial_partial_block_915: @@ -125676,26 +125676,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nutzgwpyocmmbbl: +.L_small_initial_compute_done_915: orq %r8,%r8 - je .L_after_reduction_nutzgwpyocmmbbl + je .L_after_reduction_915 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nutzgwpyocmmbbl: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_9_bmmCnCClAGkAgFj: +.L_after_reduction_915: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_9_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_ijaxBzyhokmrwhB + jae .L_16_blocks_overflow_916 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_ijaxBzyhokmrwhB + jmp .L_16_blocks_ok_916 -.L_16_blocks_overflow_ijaxBzyhokmrwhB: +.L_16_blocks_overflow_916: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -125704,7 +125704,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_ijaxBzyhokmrwhB: +.L_16_blocks_ok_916: @@ -125858,7 +125858,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_kgFmECqeDtpBDkx + jl .L_small_initial_partial_block_917 @@ -125919,8 +125919,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_kgFmECqeDtpBDkx -.L_small_initial_partial_block_kgFmECqeDtpBDkx: + jmp .L_small_initial_compute_done_917 +.L_small_initial_partial_block_917: @@ -125974,26 +125974,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_kgFmECqeDtpBDkx: +.L_small_initial_compute_done_917: orq %r8,%r8 - je .L_after_reduction_kgFmECqeDtpBDkx + je .L_after_reduction_917 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_kgFmECqeDtpBDkx: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_10_bmmCnCClAGkAgFj: +.L_after_reduction_917: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_10_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_GzdExkqDxAbkvEo + jae .L_16_blocks_overflow_918 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_GzdExkqDxAbkvEo + jmp .L_16_blocks_ok_918 -.L_16_blocks_overflow_GzdExkqDxAbkvEo: +.L_16_blocks_overflow_918: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -126002,7 +126002,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_GzdExkqDxAbkvEo: +.L_16_blocks_ok_918: @@ -126156,7 +126156,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AAiCDrFrytDuCDn + jl .L_small_initial_partial_block_919 @@ -126217,8 +126217,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AAiCDrFrytDuCDn -.L_small_initial_partial_block_AAiCDrFrytDuCDn: + jmp .L_small_initial_compute_done_919 +.L_small_initial_partial_block_919: @@ -126282,26 +126282,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AAiCDrFrytDuCDn: +.L_small_initial_compute_done_919: orq %r8,%r8 - je .L_after_reduction_AAiCDrFrytDuCDn + je .L_after_reduction_919 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AAiCDrFrytDuCDn: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_11_bmmCnCClAGkAgFj: +.L_after_reduction_919: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_11_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_yltlCswbDrnGDok + jae .L_16_blocks_overflow_920 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_yltlCswbDrnGDok + jmp .L_16_blocks_ok_920 -.L_16_blocks_overflow_yltlCswbDrnGDok: +.L_16_blocks_overflow_920: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -126310,7 +126310,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_yltlCswbDrnGDok: +.L_16_blocks_ok_920: @@ -126464,7 +126464,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_tDngsvCGbzkAsuh + jl .L_small_initial_partial_block_921 @@ -126526,8 +126526,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_tDngsvCGbzkAsuh -.L_small_initial_partial_block_tDngsvCGbzkAsuh: + jmp .L_small_initial_compute_done_921 +.L_small_initial_partial_block_921: @@ -126591,26 +126591,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_tDngsvCGbzkAsuh: +.L_small_initial_compute_done_921: orq %r8,%r8 - je .L_after_reduction_tDngsvCGbzkAsuh + je .L_after_reduction_921 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_tDngsvCGbzkAsuh: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_12_bmmCnCClAGkAgFj: +.L_after_reduction_921: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_12_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_GalprwEtyEjbdqq + jae .L_16_blocks_overflow_922 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_GalprwEtyEjbdqq + jmp .L_16_blocks_ok_922 -.L_16_blocks_overflow_GalprwEtyEjbdqq: +.L_16_blocks_overflow_922: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -126619,7 +126619,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_GalprwEtyEjbdqq: +.L_16_blocks_ok_922: @@ -126773,7 +126773,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EcsrurdgazbByqj + jl .L_small_initial_partial_block_923 @@ -126829,8 +126829,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EcsrurdgazbByqj -.L_small_initial_partial_block_EcsrurdgazbByqj: + jmp .L_small_initial_compute_done_923 +.L_small_initial_partial_block_923: @@ -126895,27 +126895,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EcsrurdgazbByqj: +.L_small_initial_compute_done_923: orq %r8,%r8 - je .L_after_reduction_EcsrurdgazbByqj + je .L_after_reduction_923 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EcsrurdgazbByqj: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_13_bmmCnCClAGkAgFj: +.L_after_reduction_923: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_13_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_ihAecDstcbcoicc + jae .L_16_blocks_overflow_924 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_ihAecDstcbcoicc + jmp .L_16_blocks_ok_924 -.L_16_blocks_overflow_ihAecDstcbcoicc: +.L_16_blocks_overflow_924: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -126926,7 +126926,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_ihAecDstcbcoicc: +.L_16_blocks_ok_924: @@ -127099,7 +127099,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_roqkaFiszosAqgz + jl .L_small_initial_partial_block_925 @@ -127165,8 +127165,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_roqkaFiszosAqgz -.L_small_initial_partial_block_roqkaFiszosAqgz: + jmp .L_small_initial_compute_done_925 +.L_small_initial_partial_block_925: @@ -127225,27 +127225,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_roqkaFiszosAqgz: +.L_small_initial_compute_done_925: orq %r8,%r8 - je .L_after_reduction_roqkaFiszosAqgz + je .L_after_reduction_925 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_roqkaFiszosAqgz: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_14_bmmCnCClAGkAgFj: +.L_after_reduction_925: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_14_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_qasAxEunzlsgDip + jae .L_16_blocks_overflow_926 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_qasAxEunzlsgDip + jmp .L_16_blocks_ok_926 -.L_16_blocks_overflow_qasAxEunzlsgDip: +.L_16_blocks_overflow_926: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -127256,7 +127256,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_qasAxEunzlsgDip: +.L_16_blocks_ok_926: @@ -127429,7 +127429,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_hcbivhienxrdbiF + jl .L_small_initial_partial_block_927 @@ -127495,8 +127495,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_hcbivhienxrdbiF -.L_small_initial_partial_block_hcbivhienxrdbiF: + jmp .L_small_initial_compute_done_927 +.L_small_initial_partial_block_927: @@ -127565,27 +127565,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_hcbivhienxrdbiF: +.L_small_initial_compute_done_927: orq %r8,%r8 - je .L_after_reduction_hcbivhienxrdbiF + je .L_after_reduction_927 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_hcbivhienxrdbiF: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_15_bmmCnCClAGkAgFj: +.L_after_reduction_927: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_15_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_ahaqtuobjhjiqnG + jae .L_16_blocks_overflow_928 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ahaqtuobjhjiqnG + jmp .L_16_blocks_ok_928 -.L_16_blocks_overflow_ahaqtuobjhjiqnG: +.L_16_blocks_overflow_928: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -127596,7 +127596,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ahaqtuobjhjiqnG: +.L_16_blocks_ok_928: @@ -127769,7 +127769,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_nfuiydADpehainf + jl .L_small_initial_partial_block_929 @@ -127836,8 +127836,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_nfuiydADpehainf -.L_small_initial_partial_block_nfuiydADpehainf: + jmp .L_small_initial_compute_done_929 +.L_small_initial_partial_block_929: @@ -127906,27 +127906,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_nfuiydADpehainf: +.L_small_initial_compute_done_929: orq %r8,%r8 - je .L_after_reduction_nfuiydADpehainf + je .L_after_reduction_929 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_nfuiydADpehainf: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_16_bmmCnCClAGkAgFj: +.L_after_reduction_929: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_16_899: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_uidgFuqCojcnwky + jae .L_16_blocks_overflow_930 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_uidgFuqCojcnwky + jmp .L_16_blocks_ok_930 -.L_16_blocks_overflow_uidgFuqCojcnwky: +.L_16_blocks_overflow_930: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -127937,7 +127937,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_uidgFuqCojcnwky: +.L_16_blocks_ok_930: @@ -128107,7 +128107,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_cjqsridulpjfbmx: +.L_small_initial_partial_block_931: @@ -128177,11 +128177,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cjqsridulpjfbmx: +.L_small_initial_compute_done_931: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cjqsridulpjfbmx: - jmp .L_last_blocks_done_bmmCnCClAGkAgFj -.L_last_num_blocks_is_0_bmmCnCClAGkAgFj: +.L_after_reduction_931: + jmp .L_last_blocks_done_899 +.L_last_num_blocks_is_0_899: vmovdqa64 1280(%rsp),%zmm13 vmovdqu64 512(%rsp),%zmm12 vpclmulqdq $0x11,%zmm12,%zmm13,%zmm0 @@ -128242,18 +128242,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_bmmCnCClAGkAgFj: +.L_last_blocks_done_899: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_BgFfAgFalCBiqtf + jmp .L_ghash_done_821 -.L_message_below_32_blocks_BgFfAgFalCBiqtf: +.L_message_below_32_blocks_821: subq $256,%r8 addq $256,%r11 movl %r8d,%r10d testq %r14,%r14 - jnz .L_skip_hkeys_precomputation_Earvmapwfbnrowd + jnz .L_skip_hkeys_precomputation_932 vmovdqu64 640(%rsp),%zmm3 @@ -128381,7 +128381,7 @@ ossl_aes_gcm_decrypt_avx512: vpternlogq $0x96,%zmm7,%zmm6,%zmm5 vmovdqu64 %zmm5,256(%rsp) -.L_skip_hkeys_precomputation_Earvmapwfbnrowd: +.L_skip_hkeys_precomputation_932: movq $1,%r14 andl $~15,%r10d movl $512,%ebx @@ -128389,61 +128389,61 @@ ossl_aes_gcm_decrypt_avx512: movl %r8d,%r10d addl $15,%r10d shrl $4,%r10d - je .L_last_num_blocks_is_0_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_0_933 cmpl $8,%r10d - je .L_last_num_blocks_is_8_dfkhivqAFxzwiGe - jb .L_last_num_blocks_is_7_1_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_8_933 + jb .L_last_num_blocks_is_7_1_933 cmpl $12,%r10d - je .L_last_num_blocks_is_12_dfkhivqAFxzwiGe - jb .L_last_num_blocks_is_11_9_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_12_933 + jb .L_last_num_blocks_is_11_9_933 cmpl $15,%r10d - je .L_last_num_blocks_is_15_dfkhivqAFxzwiGe - ja .L_last_num_blocks_is_16_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_15_933 + ja .L_last_num_blocks_is_16_933 cmpl $14,%r10d - je .L_last_num_blocks_is_14_dfkhivqAFxzwiGe - jmp .L_last_num_blocks_is_13_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_14_933 + jmp .L_last_num_blocks_is_13_933 -.L_last_num_blocks_is_11_9_dfkhivqAFxzwiGe: +.L_last_num_blocks_is_11_9_933: cmpl $10,%r10d - je .L_last_num_blocks_is_10_dfkhivqAFxzwiGe - ja .L_last_num_blocks_is_11_dfkhivqAFxzwiGe - jmp .L_last_num_blocks_is_9_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_10_933 + ja .L_last_num_blocks_is_11_933 + jmp .L_last_num_blocks_is_9_933 -.L_last_num_blocks_is_7_1_dfkhivqAFxzwiGe: +.L_last_num_blocks_is_7_1_933: cmpl $4,%r10d - je .L_last_num_blocks_is_4_dfkhivqAFxzwiGe - jb .L_last_num_blocks_is_3_1_dfkhivqAFxzwiGe + je .L_last_num_blocks_is_4_933 + jb .L_last_num_blocks_is_3_1_933 cmpl $6,%r10d - ja .L_last_num_blocks_is_7_dfkhivqAFxzwiGe - je .L_last_num_blocks_is_6_dfkhivqAFxzwiGe - jmp .L_last_num_blocks_is_5_dfkhivqAFxzwiGe + ja .L_last_num_blocks_is_7_933 + je .L_last_num_blocks_is_6_933 + jmp .L_last_num_blocks_is_5_933 -.L_last_num_blocks_is_3_1_dfkhivqAFxzwiGe: +.L_last_num_blocks_is_3_1_933: cmpl $2,%r10d - ja .L_last_num_blocks_is_3_dfkhivqAFxzwiGe - je .L_last_num_blocks_is_2_dfkhivqAFxzwiGe -.L_last_num_blocks_is_1_dfkhivqAFxzwiGe: + ja .L_last_num_blocks_is_3_933 + je .L_last_num_blocks_is_2_933 +.L_last_num_blocks_is_1_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $255,%r15d - jae .L_16_blocks_overflow_qfBhoGFEfAudmsB + jae .L_16_blocks_overflow_934 vpaddd %xmm28,%xmm2,%xmm0 - jmp .L_16_blocks_ok_qfBhoGFEfAudmsB + jmp .L_16_blocks_ok_934 -.L_16_blocks_overflow_qfBhoGFEfAudmsB: +.L_16_blocks_overflow_934: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %xmm29,%xmm0,%xmm0 -.L_16_blocks_ok_qfBhoGFEfAudmsB: +.L_16_blocks_ok_934: @@ -128535,7 +128535,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_laBstqfnvmDyubg + jl .L_small_initial_partial_block_935 @@ -128579,8 +128579,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_laBstqfnvmDyubg -.L_small_initial_partial_block_laBstqfnvmDyubg: + jmp .L_small_initial_compute_done_935 +.L_small_initial_partial_block_935: @@ -128632,24 +128632,24 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm7,%xmm14,%xmm14 - jmp .L_after_reduction_laBstqfnvmDyubg -.L_small_initial_compute_done_laBstqfnvmDyubg: -.L_after_reduction_laBstqfnvmDyubg: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_2_dfkhivqAFxzwiGe: + jmp .L_after_reduction_935 +.L_small_initial_compute_done_935: +.L_after_reduction_935: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_2_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $254,%r15d - jae .L_16_blocks_overflow_DBDfdezDtfzgqyB + jae .L_16_blocks_overflow_936 vpaddd %ymm28,%ymm2,%ymm0 - jmp .L_16_blocks_ok_DBDfdezDtfzgqyB + jmp .L_16_blocks_ok_936 -.L_16_blocks_overflow_DBDfdezDtfzgqyB: +.L_16_blocks_overflow_936: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %ymm29,%ymm0,%ymm0 -.L_16_blocks_ok_DBDfdezDtfzgqyB: +.L_16_blocks_ok_936: @@ -128742,7 +128742,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_fzxzoyAmsdzqvlm + jl .L_small_initial_partial_block_937 @@ -128786,8 +128786,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_fzxzoyAmsdzqvlm -.L_small_initial_partial_block_fzxzoyAmsdzqvlm: + jmp .L_small_initial_compute_done_937 +.L_small_initial_partial_block_937: @@ -128834,27 +128834,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_fzxzoyAmsdzqvlm: +.L_small_initial_compute_done_937: orq %r8,%r8 - je .L_after_reduction_fzxzoyAmsdzqvlm + je .L_after_reduction_937 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_fzxzoyAmsdzqvlm: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_3_dfkhivqAFxzwiGe: +.L_after_reduction_937: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_3_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $253,%r15d - jae .L_16_blocks_overflow_zeAorDfehCBauCb + jae .L_16_blocks_overflow_938 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_zeAorDfehCBauCb + jmp .L_16_blocks_ok_938 -.L_16_blocks_overflow_zeAorDfehCBauCb: +.L_16_blocks_overflow_938: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_zeAorDfehCBauCb: +.L_16_blocks_ok_938: @@ -128947,7 +128947,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yvixmuEoyhuBlyB + jl .L_small_initial_partial_block_939 @@ -128992,8 +128992,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yvixmuEoyhuBlyB -.L_small_initial_partial_block_yvixmuEoyhuBlyB: + jmp .L_small_initial_compute_done_939 +.L_small_initial_partial_block_939: @@ -129040,27 +129040,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yvixmuEoyhuBlyB: +.L_small_initial_compute_done_939: orq %r8,%r8 - je .L_after_reduction_yvixmuEoyhuBlyB + je .L_after_reduction_939 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yvixmuEoyhuBlyB: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_4_dfkhivqAFxzwiGe: +.L_after_reduction_939: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_4_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax kmovq (%r10,%rax,8),%k1 cmpl $252,%r15d - jae .L_16_blocks_overflow_zmdtbcEbrfioqbi + jae .L_16_blocks_overflow_940 vpaddd %zmm28,%zmm2,%zmm0 - jmp .L_16_blocks_ok_zmdtbcEbrfioqbi + jmp .L_16_blocks_ok_940 -.L_16_blocks_overflow_zmdtbcEbrfioqbi: +.L_16_blocks_overflow_940: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vpshufb %zmm29,%zmm0,%zmm0 -.L_16_blocks_ok_zmdtbcEbrfioqbi: +.L_16_blocks_ok_940: @@ -129153,7 +129153,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_AkzFciirDhAcErk + jl .L_small_initial_partial_block_941 @@ -129198,8 +129198,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_AkzFciirDhAcErk -.L_small_initial_partial_block_AkzFciirDhAcErk: + jmp .L_small_initial_compute_done_941 +.L_small_initial_partial_block_941: @@ -129247,32 +129247,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_AkzFciirDhAcErk: +.L_small_initial_compute_done_941: orq %r8,%r8 - je .L_after_reduction_AkzFciirDhAcErk + je .L_after_reduction_941 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_AkzFciirDhAcErk: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_5_dfkhivqAFxzwiGe: +.L_after_reduction_941: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_5_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $251,%r15d - jae .L_16_blocks_overflow_CbaulglAsvBBDeC + jae .L_16_blocks_overflow_942 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %xmm27,%xmm0,%xmm3 - jmp .L_16_blocks_ok_CbaulglAsvBBDeC + jmp .L_16_blocks_ok_942 -.L_16_blocks_overflow_CbaulglAsvBBDeC: +.L_16_blocks_overflow_942: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %xmm29,%xmm3,%xmm3 -.L_16_blocks_ok_CbaulglAsvBBDeC: +.L_16_blocks_ok_942: @@ -129384,7 +129384,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_obwCfxsnnxinEEG + jl .L_small_initial_partial_block_943 @@ -129435,8 +129435,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_obwCfxsnnxinEEG -.L_small_initial_partial_block_obwCfxsnnxinEEG: + jmp .L_small_initial_compute_done_943 +.L_small_initial_partial_block_943: @@ -129484,32 +129484,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_obwCfxsnnxinEEG: +.L_small_initial_compute_done_943: orq %r8,%r8 - je .L_after_reduction_obwCfxsnnxinEEG + je .L_after_reduction_943 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_obwCfxsnnxinEEG: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_6_dfkhivqAFxzwiGe: +.L_after_reduction_943: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_6_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $250,%r15d - jae .L_16_blocks_overflow_dElkfrzqgrzGFkB + jae .L_16_blocks_overflow_944 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %ymm27,%ymm0,%ymm3 - jmp .L_16_blocks_ok_dElkfrzqgrzGFkB + jmp .L_16_blocks_ok_944 -.L_16_blocks_overflow_dElkfrzqgrzGFkB: +.L_16_blocks_overflow_944: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %ymm29,%ymm3,%ymm3 -.L_16_blocks_ok_dElkfrzqgrzGFkB: +.L_16_blocks_ok_944: @@ -129621,7 +129621,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ueqDgpDlyfrDEzb + jl .L_small_initial_partial_block_945 @@ -129672,8 +129672,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ueqDgpDlyfrDEzb -.L_small_initial_partial_block_ueqDgpDlyfrDEzb: + jmp .L_small_initial_compute_done_945 +.L_small_initial_partial_block_945: @@ -129727,32 +129727,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ueqDgpDlyfrDEzb: +.L_small_initial_compute_done_945: orq %r8,%r8 - je .L_after_reduction_ueqDgpDlyfrDEzb + je .L_after_reduction_945 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ueqDgpDlyfrDEzb: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_7_dfkhivqAFxzwiGe: +.L_after_reduction_945: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_7_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $249,%r15d - jae .L_16_blocks_overflow_mcCecmAtpnADcho + jae .L_16_blocks_overflow_946 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_mcCecmAtpnADcho + jmp .L_16_blocks_ok_946 -.L_16_blocks_overflow_mcCecmAtpnADcho: +.L_16_blocks_overflow_946: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_mcCecmAtpnADcho: +.L_16_blocks_ok_946: @@ -129864,7 +129864,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_ussziGFsDahzgCA + jl .L_small_initial_partial_block_947 @@ -129916,8 +129916,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_ussziGFsDahzgCA -.L_small_initial_partial_block_ussziGFsDahzgCA: + jmp .L_small_initial_compute_done_947 +.L_small_initial_partial_block_947: @@ -129971,32 +129971,32 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_ussziGFsDahzgCA: +.L_small_initial_compute_done_947: orq %r8,%r8 - je .L_after_reduction_ussziGFsDahzgCA + je .L_after_reduction_947 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_ussziGFsDahzgCA: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_8_dfkhivqAFxzwiGe: +.L_after_reduction_947: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_8_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $64,%rax kmovq (%r10,%rax,8),%k1 cmpl $248,%r15d - jae .L_16_blocks_overflow_qyFkdltbnbywinD + jae .L_16_blocks_overflow_948 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 - jmp .L_16_blocks_ok_qyFkdltbnbywinD + jmp .L_16_blocks_ok_948 -.L_16_blocks_overflow_qyFkdltbnbywinD: +.L_16_blocks_overflow_948: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 vpaddd %zmm5,%zmm0,%zmm3 vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 -.L_16_blocks_ok_qyFkdltbnbywinD: +.L_16_blocks_ok_948: @@ -130108,7 +130108,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_aFlFBFhvxwqbGFF + jl .L_small_initial_partial_block_949 @@ -130162,8 +130162,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_aFlFBFhvxwqbGFF -.L_small_initial_partial_block_aFlFBFhvxwqbGFF: + jmp .L_small_initial_compute_done_949 +.L_small_initial_partial_block_949: @@ -130218,26 +130218,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_aFlFBFhvxwqbGFF: +.L_small_initial_compute_done_949: orq %r8,%r8 - je .L_after_reduction_aFlFBFhvxwqbGFF + je .L_after_reduction_949 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_aFlFBFhvxwqbGFF: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_9_dfkhivqAFxzwiGe: +.L_after_reduction_949: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_9_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $247,%r15d - jae .L_16_blocks_overflow_jaAfqGlviFGpfab + jae .L_16_blocks_overflow_950 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %xmm27,%xmm3,%xmm4 - jmp .L_16_blocks_ok_jaAfqGlviFGpfab + jmp .L_16_blocks_ok_950 -.L_16_blocks_overflow_jaAfqGlviFGpfab: +.L_16_blocks_overflow_950: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -130246,7 +130246,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %xmm29,%xmm4,%xmm4 -.L_16_blocks_ok_jaAfqGlviFGpfab: +.L_16_blocks_ok_950: @@ -130377,7 +130377,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_jxchlGjDidlqCCy + jl .L_small_initial_partial_block_951 @@ -130437,8 +130437,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_jxchlGjDidlqCCy -.L_small_initial_partial_block_jxchlGjDidlqCCy: + jmp .L_small_initial_compute_done_951 +.L_small_initial_partial_block_951: @@ -130495,26 +130495,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_jxchlGjDidlqCCy: +.L_small_initial_compute_done_951: orq %r8,%r8 - je .L_after_reduction_jxchlGjDidlqCCy + je .L_after_reduction_951 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_jxchlGjDidlqCCy: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_10_dfkhivqAFxzwiGe: +.L_after_reduction_951: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_10_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $246,%r15d - jae .L_16_blocks_overflow_ifxfunzGkahmzhG + jae .L_16_blocks_overflow_952 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %ymm27,%ymm3,%ymm4 - jmp .L_16_blocks_ok_ifxfunzGkahmzhG + jmp .L_16_blocks_ok_952 -.L_16_blocks_overflow_ifxfunzGkahmzhG: +.L_16_blocks_overflow_952: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -130523,7 +130523,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %ymm29,%ymm4,%ymm4 -.L_16_blocks_ok_ifxfunzGkahmzhG: +.L_16_blocks_ok_952: @@ -130654,7 +130654,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_iksxtDvwxlrniDa + jl .L_small_initial_partial_block_953 @@ -130714,8 +130714,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_iksxtDvwxlrniDa -.L_small_initial_partial_block_iksxtDvwxlrniDa: + jmp .L_small_initial_compute_done_953 +.L_small_initial_partial_block_953: @@ -130778,26 +130778,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_iksxtDvwxlrniDa: +.L_small_initial_compute_done_953: orq %r8,%r8 - je .L_after_reduction_iksxtDvwxlrniDa + je .L_after_reduction_953 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_iksxtDvwxlrniDa: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_11_dfkhivqAFxzwiGe: +.L_after_reduction_953: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_11_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $245,%r15d - jae .L_16_blocks_overflow_egrmrylcwtttayy + jae .L_16_blocks_overflow_954 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_egrmrylcwtttayy + jmp .L_16_blocks_ok_954 -.L_16_blocks_overflow_egrmrylcwtttayy: +.L_16_blocks_overflow_954: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -130806,7 +130806,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_egrmrylcwtttayy: +.L_16_blocks_ok_954: @@ -130937,7 +130937,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_axjaDvuzGlCcwmm + jl .L_small_initial_partial_block_955 @@ -130998,8 +130998,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_axjaDvuzGlCcwmm -.L_small_initial_partial_block_axjaDvuzGlCcwmm: + jmp .L_small_initial_compute_done_955 +.L_small_initial_partial_block_955: @@ -131062,26 +131062,26 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_axjaDvuzGlCcwmm: +.L_small_initial_compute_done_955: orq %r8,%r8 - je .L_after_reduction_axjaDvuzGlCcwmm + je .L_after_reduction_955 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_axjaDvuzGlCcwmm: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_12_dfkhivqAFxzwiGe: +.L_after_reduction_955: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_12_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $128,%rax kmovq (%r10,%rax,8),%k1 cmpl $244,%r15d - jae .L_16_blocks_overflow_zwssxCnymfxljrk + jae .L_16_blocks_overflow_956 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 - jmp .L_16_blocks_ok_zwssxCnymfxljrk + jmp .L_16_blocks_ok_956 -.L_16_blocks_overflow_zwssxCnymfxljrk: +.L_16_blocks_overflow_956: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -131090,7 +131090,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm0,%zmm0 vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 -.L_16_blocks_ok_zwssxCnymfxljrk: +.L_16_blocks_ok_956: @@ -131221,7 +131221,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_EvfsABAshgacfke + jl .L_small_initial_partial_block_957 @@ -131280,8 +131280,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_EvfsABAshgacfke -.L_small_initial_partial_block_EvfsABAshgacfke: + jmp .L_small_initial_compute_done_957 +.L_small_initial_partial_block_957: @@ -131345,27 +131345,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_EvfsABAshgacfke: +.L_small_initial_compute_done_957: orq %r8,%r8 - je .L_after_reduction_EvfsABAshgacfke + je .L_after_reduction_957 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_EvfsABAshgacfke: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_13_dfkhivqAFxzwiGe: +.L_after_reduction_957: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_13_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $243,%r15d - jae .L_16_blocks_overflow_vsvrsCrquqxomml + jae .L_16_blocks_overflow_958 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %xmm27,%xmm4,%xmm5 - jmp .L_16_blocks_ok_vsvrsCrquqxomml + jmp .L_16_blocks_ok_958 -.L_16_blocks_overflow_vsvrsCrquqxomml: +.L_16_blocks_overflow_958: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -131376,7 +131376,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %xmm29,%xmm5,%xmm5 -.L_16_blocks_ok_vsvrsCrquqxomml: +.L_16_blocks_ok_958: @@ -131526,7 +131526,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_adjxckAomkBzbjw + jl .L_small_initial_partial_block_959 @@ -131591,8 +131591,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_adjxckAomkBzbjw -.L_small_initial_partial_block_adjxckAomkBzbjw: + jmp .L_small_initial_compute_done_959 +.L_small_initial_partial_block_959: @@ -131654,27 +131654,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_adjxckAomkBzbjw: +.L_small_initial_compute_done_959: orq %r8,%r8 - je .L_after_reduction_adjxckAomkBzbjw + je .L_after_reduction_959 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_adjxckAomkBzbjw: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_14_dfkhivqAFxzwiGe: +.L_after_reduction_959: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_14_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $242,%r15d - jae .L_16_blocks_overflow_hmvAkrCzrvDuoEr + jae .L_16_blocks_overflow_960 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %ymm27,%ymm4,%ymm5 - jmp .L_16_blocks_ok_hmvAkrCzrvDuoEr + jmp .L_16_blocks_ok_960 -.L_16_blocks_overflow_hmvAkrCzrvDuoEr: +.L_16_blocks_overflow_960: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -131685,7 +131685,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %ymm29,%ymm5,%ymm5 -.L_16_blocks_ok_hmvAkrCzrvDuoEr: +.L_16_blocks_ok_960: @@ -131835,7 +131835,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_spDCszqGjFtddFj + jl .L_small_initial_partial_block_961 @@ -131900,8 +131900,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_spDCszqGjFtddFj -.L_small_initial_partial_block_spDCszqGjFtddFj: + jmp .L_small_initial_compute_done_961 +.L_small_initial_partial_block_961: @@ -131969,27 +131969,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_spDCszqGjFtddFj: +.L_small_initial_compute_done_961: orq %r8,%r8 - je .L_after_reduction_spDCszqGjFtddFj + je .L_after_reduction_961 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_spDCszqGjFtddFj: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_15_dfkhivqAFxzwiGe: +.L_after_reduction_961: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_15_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $241,%r15d - jae .L_16_blocks_overflow_ADsszwCrGfcvGFi + jae .L_16_blocks_overflow_962 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_ADsszwCrGfcvGFi + jmp .L_16_blocks_ok_962 -.L_16_blocks_overflow_ADsszwCrGfcvGFi: +.L_16_blocks_overflow_962: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -132000,7 +132000,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_ADsszwCrGfcvGFi: +.L_16_blocks_ok_962: @@ -132150,7 +132150,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yyncnqrfuDoFFfc + jl .L_small_initial_partial_block_963 @@ -132216,8 +132216,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yyncnqrfuDoFFfc -.L_small_initial_partial_block_yyncnqrfuDoFFfc: + jmp .L_small_initial_compute_done_963 +.L_small_initial_partial_block_963: @@ -132285,27 +132285,27 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yyncnqrfuDoFFfc: +.L_small_initial_compute_done_963: orq %r8,%r8 - je .L_after_reduction_yyncnqrfuDoFFfc + je .L_after_reduction_963 vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_yyncnqrfuDoFFfc: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_16_dfkhivqAFxzwiGe: +.L_after_reduction_963: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_16_933: leaq byte64_len_to_mask_table(%rip),%r10 movq %r8,%rax subq $192,%rax kmovq (%r10,%rax,8),%k1 cmpl $240,%r15d - jae .L_16_blocks_overflow_kxFpEbqmfGrayjB + jae .L_16_blocks_overflow_964 vpaddd %zmm28,%zmm2,%zmm0 vpaddd %zmm27,%zmm0,%zmm3 vpaddd %zmm27,%zmm3,%zmm4 vpaddd %zmm27,%zmm4,%zmm5 - jmp .L_16_blocks_ok_kxFpEbqmfGrayjB + jmp .L_16_blocks_ok_964 -.L_16_blocks_overflow_kxFpEbqmfGrayjB: +.L_16_blocks_overflow_964: vpshufb %zmm29,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 vmovdqa64 ddq_add_4444(%rip),%zmm5 @@ -132316,7 +132316,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm3,%zmm3 vpshufb %zmm29,%zmm4,%zmm4 vpshufb %zmm29,%zmm5,%zmm5 -.L_16_blocks_ok_kxFpEbqmfGrayjB: +.L_16_blocks_ok_964: @@ -132463,7 +132463,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm21,%zmm21 vextracti32x4 $3,%zmm21,%xmm7 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_cCmuyFygpFpuyFD: +.L_small_initial_partial_block_965: @@ -132532,11 +132532,11 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_cCmuyFygpFpuyFD: +.L_small_initial_compute_done_965: vpxorq %xmm7,%xmm14,%xmm14 -.L_after_reduction_cCmuyFygpFpuyFD: - jmp .L_last_blocks_done_dfkhivqAFxzwiGe -.L_last_num_blocks_is_0_dfkhivqAFxzwiGe: +.L_after_reduction_965: + jmp .L_last_blocks_done_933 +.L_last_num_blocks_is_0_933: vmovdqa64 768(%rsp),%zmm13 vpxorq %zmm14,%zmm13,%zmm13 vmovdqu64 0(%rsp,%rbx,1),%zmm12 @@ -132598,65 +132598,65 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm24,%xmm3,%xmm14 -.L_last_blocks_done_dfkhivqAFxzwiGe: +.L_last_blocks_done_933: vpshufb %xmm29,%xmm2,%xmm2 - jmp .L_ghash_done_BgFfAgFalCBiqtf + jmp .L_ghash_done_821 -.L_message_below_equal_16_blocks_BgFfAgFalCBiqtf: +.L_message_below_equal_16_blocks_821: movl %r8d,%r12d addl $15,%r12d shrl $4,%r12d cmpq $8,%r12 - je .L_small_initial_num_blocks_is_8_BFvobdvksttGkes - jl .L_small_initial_num_blocks_is_7_1_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_8_966 + jl .L_small_initial_num_blocks_is_7_1_966 cmpq $12,%r12 - je .L_small_initial_num_blocks_is_12_BFvobdvksttGkes - jl .L_small_initial_num_blocks_is_11_9_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_12_966 + jl .L_small_initial_num_blocks_is_11_9_966 cmpq $16,%r12 - je .L_small_initial_num_blocks_is_16_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_16_966 cmpq $15,%r12 - je .L_small_initial_num_blocks_is_15_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_15_966 cmpq $14,%r12 - je .L_small_initial_num_blocks_is_14_BFvobdvksttGkes - jmp .L_small_initial_num_blocks_is_13_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_14_966 + jmp .L_small_initial_num_blocks_is_13_966 -.L_small_initial_num_blocks_is_11_9_BFvobdvksttGkes: +.L_small_initial_num_blocks_is_11_9_966: cmpq $11,%r12 - je .L_small_initial_num_blocks_is_11_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_11_966 cmpq $10,%r12 - je .L_small_initial_num_blocks_is_10_BFvobdvksttGkes - jmp .L_small_initial_num_blocks_is_9_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_10_966 + jmp .L_small_initial_num_blocks_is_9_966 -.L_small_initial_num_blocks_is_7_1_BFvobdvksttGkes: +.L_small_initial_num_blocks_is_7_1_966: cmpq $4,%r12 - je .L_small_initial_num_blocks_is_4_BFvobdvksttGkes - jl .L_small_initial_num_blocks_is_3_1_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_4_966 + jl .L_small_initial_num_blocks_is_3_1_966 cmpq $7,%r12 - je .L_small_initial_num_blocks_is_7_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_7_966 cmpq $6,%r12 - je .L_small_initial_num_blocks_is_6_BFvobdvksttGkes - jmp .L_small_initial_num_blocks_is_5_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_6_966 + jmp .L_small_initial_num_blocks_is_5_966 -.L_small_initial_num_blocks_is_3_1_BFvobdvksttGkes: +.L_small_initial_num_blocks_is_3_1_966: cmpq $3,%r12 - je .L_small_initial_num_blocks_is_3_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_3_966 cmpq $2,%r12 - je .L_small_initial_num_blocks_is_2_BFvobdvksttGkes + je .L_small_initial_num_blocks_is_2_966 -.L_small_initial_num_blocks_is_1_BFvobdvksttGkes: +.L_small_initial_num_blocks_is_1_966: vmovdqa64 SHUF_MASK(%rip),%xmm29 vpaddd ONE(%rip),%xmm2,%xmm0 leaq byte64_len_to_mask_table(%rip),%r10 @@ -132705,7 +132705,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_xwoqffAokxjdyfe + jl .L_small_initial_partial_block_967 @@ -132747,8 +132747,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_xwoqffAokxjdyfe -.L_small_initial_partial_block_xwoqffAokxjdyfe: + jmp .L_small_initial_compute_done_967 +.L_small_initial_partial_block_967: @@ -132772,11 +132772,11 @@ ossl_aes_gcm_decrypt_avx512: vpxorq %xmm13,%xmm14,%xmm14 - jmp .L_after_reduction_xwoqffAokxjdyfe -.L_small_initial_compute_done_xwoqffAokxjdyfe: -.L_after_reduction_xwoqffAokxjdyfe: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_2_BFvobdvksttGkes: + jmp .L_after_reduction_967 +.L_small_initial_compute_done_967: +.L_after_reduction_967: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_2_966: vmovdqa64 SHUF_MASK(%rip),%ymm29 vshufi64x2 $0,%ymm2,%ymm2,%ymm0 vpaddd ddq_add_1234(%rip),%ymm0,%ymm0 @@ -132827,7 +132827,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_docblAAffyjncil + jl .L_small_initial_partial_block_968 @@ -132869,8 +132869,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_docblAAffyjncil -.L_small_initial_partial_block_docblAAffyjncil: + jmp .L_small_initial_compute_done_968 +.L_small_initial_partial_block_968: @@ -132915,14 +132915,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_docblAAffyjncil: +.L_small_initial_compute_done_968: orq %r8,%r8 - je .L_after_reduction_docblAAffyjncil + je .L_after_reduction_968 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_docblAAffyjncil: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_3_BFvobdvksttGkes: +.L_after_reduction_968: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_3_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -132973,7 +132973,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_qwjngbegozfGvCf + jl .L_small_initial_partial_block_969 @@ -133016,8 +133016,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_qwjngbegozfGvCf -.L_small_initial_partial_block_qwjngbegozfGvCf: + jmp .L_small_initial_compute_done_969 +.L_small_initial_partial_block_969: @@ -133062,14 +133062,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_qwjngbegozfGvCf: +.L_small_initial_compute_done_969: orq %r8,%r8 - je .L_after_reduction_qwjngbegozfGvCf + je .L_after_reduction_969 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_qwjngbegozfGvCf: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_4_BFvobdvksttGkes: +.L_after_reduction_969: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_4_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -133120,7 +133120,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lykpwlhBrquzBjq + jl .L_small_initial_partial_block_970 @@ -133162,8 +133162,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lykpwlhBrquzBjq -.L_small_initial_partial_block_lykpwlhBrquzBjq: + jmp .L_small_initial_compute_done_970 +.L_small_initial_partial_block_970: @@ -133209,14 +133209,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lykpwlhBrquzBjq: +.L_small_initial_compute_done_970: orq %r8,%r8 - je .L_after_reduction_lykpwlhBrquzBjq + je .L_after_reduction_970 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_lykpwlhBrquzBjq: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_5_BFvobdvksttGkes: +.L_after_reduction_970: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_5_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -133289,7 +133289,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_wEBEjcxteoEEbdv + jl .L_small_initial_partial_block_971 @@ -133341,8 +133341,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_wEBEjcxteoEEbdv -.L_small_initial_partial_block_wEBEjcxteoEEbdv: + jmp .L_small_initial_compute_done_971 +.L_small_initial_partial_block_971: @@ -133387,14 +133387,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_wEBEjcxteoEEbdv: +.L_small_initial_compute_done_971: orq %r8,%r8 - je .L_after_reduction_wEBEjcxteoEEbdv + je .L_after_reduction_971 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_wEBEjcxteoEEbdv: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_6_BFvobdvksttGkes: +.L_after_reduction_971: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_6_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -133467,7 +133467,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GeGuFrqjgnGatCq + jl .L_small_initial_partial_block_972 @@ -133519,8 +133519,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GeGuFrqjgnGatCq -.L_small_initial_partial_block_GeGuFrqjgnGatCq: + jmp .L_small_initial_compute_done_972 +.L_small_initial_partial_block_972: @@ -133575,14 +133575,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GeGuFrqjgnGatCq: +.L_small_initial_compute_done_972: orq %r8,%r8 - je .L_after_reduction_GeGuFrqjgnGatCq + je .L_after_reduction_972 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_GeGuFrqjgnGatCq: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_7_BFvobdvksttGkes: +.L_after_reduction_972: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_7_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -133655,7 +133655,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_dnuemxcuxqiahko + jl .L_small_initial_partial_block_973 @@ -133708,8 +133708,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_dnuemxcuxqiahko -.L_small_initial_partial_block_dnuemxcuxqiahko: + jmp .L_small_initial_compute_done_973 +.L_small_initial_partial_block_973: @@ -133764,14 +133764,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_dnuemxcuxqiahko: +.L_small_initial_compute_done_973: orq %r8,%r8 - je .L_after_reduction_dnuemxcuxqiahko + je .L_after_reduction_973 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_dnuemxcuxqiahko: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_8_BFvobdvksttGkes: +.L_after_reduction_973: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_8_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -133844,7 +133844,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lqkatnvbmenDGmu + jl .L_small_initial_partial_block_974 @@ -133895,8 +133895,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lqkatnvbmenDGmu -.L_small_initial_partial_block_lqkatnvbmenDGmu: + jmp .L_small_initial_compute_done_974 +.L_small_initial_partial_block_974: @@ -133952,14 +133952,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lqkatnvbmenDGmu: +.L_small_initial_compute_done_974: orq %r8,%r8 - je .L_after_reduction_lqkatnvbmenDGmu + je .L_after_reduction_974 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_lqkatnvbmenDGmu: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_9_BFvobdvksttGkes: +.L_after_reduction_974: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_9_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -134053,7 +134053,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_akbdAxxFivazzvn + jl .L_small_initial_partial_block_975 @@ -134114,8 +134114,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_akbdAxxFivazzvn -.L_small_initial_partial_block_akbdAxxFivazzvn: + jmp .L_small_initial_compute_done_975 +.L_small_initial_partial_block_975: @@ -134169,14 +134169,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_akbdAxxFivazzvn: +.L_small_initial_compute_done_975: orq %r8,%r8 - je .L_after_reduction_akbdAxxFivazzvn + je .L_after_reduction_975 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_akbdAxxFivazzvn: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_10_BFvobdvksttGkes: +.L_after_reduction_975: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_10_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -134270,7 +134270,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_gtCBivDqyilstnw + jl .L_small_initial_partial_block_976 @@ -134331,8 +134331,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_gtCBivDqyilstnw -.L_small_initial_partial_block_gtCBivDqyilstnw: + jmp .L_small_initial_compute_done_976 +.L_small_initial_partial_block_976: @@ -134396,14 +134396,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_gtCBivDqyilstnw: +.L_small_initial_compute_done_976: orq %r8,%r8 - je .L_after_reduction_gtCBivDqyilstnw + je .L_after_reduction_976 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_gtCBivDqyilstnw: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_11_BFvobdvksttGkes: +.L_after_reduction_976: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_11_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -134497,7 +134497,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yCajAbdipitxdfG + jl .L_small_initial_partial_block_977 @@ -134559,8 +134559,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yCajAbdipitxdfG -.L_small_initial_partial_block_yCajAbdipitxdfG: + jmp .L_small_initial_compute_done_977 +.L_small_initial_partial_block_977: @@ -134624,14 +134624,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yCajAbdipitxdfG: +.L_small_initial_compute_done_977: orq %r8,%r8 - je .L_after_reduction_yCajAbdipitxdfG + je .L_after_reduction_977 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_yCajAbdipitxdfG: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_12_BFvobdvksttGkes: +.L_after_reduction_977: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_12_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -134725,7 +134725,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_GrGfiAqrrtbgoFj + jl .L_small_initial_partial_block_978 @@ -134781,8 +134781,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_GrGfiAqrrtbgoFj -.L_small_initial_partial_block_GrGfiAqrrtbgoFj: + jmp .L_small_initial_compute_done_978 +.L_small_initial_partial_block_978: @@ -134847,14 +134847,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_GrGfiAqrrtbgoFj: +.L_small_initial_compute_done_978: orq %r8,%r8 - je .L_after_reduction_GrGfiAqrrtbgoFj + je .L_after_reduction_978 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_GrGfiAqrrtbgoFj: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_13_BFvobdvksttGkes: +.L_after_reduction_978: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_13_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -134969,7 +134969,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_vxgEbbwrzCsbngh + jl .L_small_initial_partial_block_979 @@ -135035,8 +135035,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_vxgEbbwrzCsbngh -.L_small_initial_partial_block_vxgEbbwrzCsbngh: + jmp .L_small_initial_compute_done_979 +.L_small_initial_partial_block_979: @@ -135095,14 +135095,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_vxgEbbwrzCsbngh: +.L_small_initial_compute_done_979: orq %r8,%r8 - je .L_after_reduction_vxgEbbwrzCsbngh + je .L_after_reduction_979 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_vxgEbbwrzCsbngh: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_14_BFvobdvksttGkes: +.L_after_reduction_979: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_14_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -135217,7 +135217,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_lCAefFCethapCBx + jl .L_small_initial_partial_block_980 @@ -135283,8 +135283,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_lCAefFCethapCBx -.L_small_initial_partial_block_lCAefFCethapCBx: + jmp .L_small_initial_compute_done_980 +.L_small_initial_partial_block_980: @@ -135353,14 +135353,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_lCAefFCethapCBx: +.L_small_initial_compute_done_980: orq %r8,%r8 - je .L_after_reduction_lCAefFCethapCBx + je .L_after_reduction_980 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_lCAefFCethapCBx: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_15_BFvobdvksttGkes: +.L_after_reduction_980: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_15_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -135475,7 +135475,7 @@ ossl_aes_gcm_decrypt_avx512: cmpq $16,%r8 - jl .L_small_initial_partial_block_yAmanilitAqeGch + jl .L_small_initial_partial_block_981 @@ -135542,8 +135542,8 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 - jmp .L_small_initial_compute_done_yAmanilitAqeGch -.L_small_initial_partial_block_yAmanilitAqeGch: + jmp .L_small_initial_compute_done_981 +.L_small_initial_partial_block_981: @@ -135612,14 +135612,14 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_yAmanilitAqeGch: +.L_small_initial_compute_done_981: orq %r8,%r8 - je .L_after_reduction_yAmanilitAqeGch + je .L_after_reduction_981 vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_yAmanilitAqeGch: - jmp .L_small_initial_blocks_encrypted_BFvobdvksttGkes -.L_small_initial_num_blocks_is_16_BFvobdvksttGkes: +.L_after_reduction_981: + jmp .L_small_initial_blocks_encrypted_966 +.L_small_initial_num_blocks_is_16_966: vmovdqa64 SHUF_MASK(%rip),%zmm29 vshufi64x2 $0,%zmm2,%zmm2,%zmm2 vpaddd ddq_add_1234(%rip),%zmm2,%zmm0 @@ -135731,7 +135731,7 @@ ossl_aes_gcm_decrypt_avx512: vpshufb %zmm29,%zmm11,%zmm11 vextracti32x4 $3,%zmm11,%xmm13 subq $16 * (16 - 1),%r8 -.L_small_initial_partial_block_adFtlCftbzzmqiy: +.L_small_initial_partial_block_982: @@ -135801,18 +135801,18 @@ ossl_aes_gcm_decrypt_avx512: vpslldq $4,%xmm14,%xmm14 vpternlogq $0x96,%xmm0,%xmm5,%xmm14 -.L_small_initial_compute_done_adFtlCftbzzmqiy: +.L_small_initial_compute_done_982: vpxorq %xmm13,%xmm14,%xmm14 -.L_after_reduction_adFtlCftbzzmqiy: -.L_small_initial_blocks_encrypted_BFvobdvksttGkes: -.L_ghash_done_BgFfAgFalCBiqtf: +.L_after_reduction_982: +.L_small_initial_blocks_encrypted_966: +.L_ghash_done_821: vmovdqu64 %xmm2,0(%rsi) vmovdqu64 %xmm14,64(%rsi) -.L_enc_dec_done_BgFfAgFalCBiqtf: +.L_enc_dec_done_821: jmp .Lexit_gcm_decrypt .Lexit_gcm_decrypt: cmpq $256,%r8 - jbe .Lskip_hkeys_cleanup_bDoEcnfhdqoqhlk + jbe .Lskip_hkeys_cleanup_983 vpxor %xmm0,%xmm0,%xmm0 vmovdqa64 %zmm0,0(%rsp) vmovdqa64 %zmm0,64(%rsp) @@ -135826,7 +135826,7 @@ ossl_aes_gcm_decrypt_avx512: vmovdqa64 %zmm0,576(%rsp) vmovdqa64 %zmm0,640(%rsp) vmovdqa64 %zmm0,704(%rsp) -.Lskip_hkeys_cleanup_bDoEcnfhdqoqhlk: +.Lskip_hkeys_cleanup_983: vzeroupper leaq (%rbp),%rsp .cfi_def_cfa_register %rsp @@ -135864,7 +135864,7 @@ ossl_aes_gcm_finalize_avx512: cmpq $0,%rsi - je .L_partial_done_FqapxBplxvFlEbc + je .L_partial_done_984 vpclmulqdq $0x11,%xmm2,%xmm4,%xmm0 vpclmulqdq $0x00,%xmm2,%xmm4,%xmm16 @@ -135894,7 +135894,7 @@ ossl_aes_gcm_finalize_avx512: vpternlogq $0x96,%xmm16,%xmm0,%xmm4 -.L_partial_done_FqapxBplxvFlEbc: +.L_partial_done_984: vmovq 56(%rdi),%xmm5 vpinsrq $1,48(%rdi),%xmm5,%xmm5 vpsllq $3,%xmm5,%xmm5 @@ -135932,7 +135932,7 @@ ossl_aes_gcm_finalize_avx512: vpshufb SHUF_MASK(%rip),%xmm4,%xmm4 vpxor %xmm4,%xmm3,%xmm3 -.L_return_T_FqapxBplxvFlEbc: +.L_return_T_984: vmovdqu %xmm3,64(%rdi) .Labort_finalize: .byte 0xf3,0xc3 diff --git a/crypto/modes/asm/aes-gcm-avx512.pl b/crypto/modes/asm/aes-gcm-avx512.pl index 9d83abf4da..9f9124373b 100644 --- a/crypto/modes/asm/aes-gcm-avx512.pl +++ b/crypto/modes/asm/aes-gcm-avx512.pl @@ -155,6 +155,9 @@ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; my ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9, $arg10, $arg11); +# ; Counter used for assembly label generation +my $label_count = 0; + # ; This implementation follows the convention: for non-leaf functions (they # ; must call PROLOG) %rbp is used as a frame pointer, and has fixed offset from # ; the function entry: $GP_STORAGE + [8 bytes alignment (Windows only)]. This @@ -200,15 +203,6 @@ # ;;; Helper functions # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -# ; Generates "random" local labels -sub random_string() { - my @chars = ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '_'); - my $length = 15; - my $str; - map { $str .= $chars[rand(33)] } 1 .. $length; - return $str; -} - sub BYTE { my ($reg) = @_; if ($reg =~ /%r[abcd]x/i) { @@ -417,7 +411,7 @@ sub PROLOG { sub EPILOG { my ($hkeys_storage_on_stack, $payload_len) = @_; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; if ($hkeys_storage_on_stack && $CLEAR_HKEYS_STORAGE_ON_EXIT) { @@ -425,13 +419,13 @@ sub EPILOG { # ; were stored in the local frame storage $code .= <<___; cmpq \$`16*16`,$payload_len - jbe .Lskip_hkeys_cleanup_${rndsuffix} + jbe .Lskip_hkeys_cleanup_${label_suffix} vpxor %xmm0,%xmm0,%xmm0 ___ for (my $i = 0; $i < int($HKEYS_STORAGE / 64); $i++) { $code .= "vmovdqa64 %zmm0,`$STACK_HKEYS_OFFSET + 64*$i`(%rsp)\n"; } - $code .= ".Lskip_hkeys_cleanup_${rndsuffix}:\n"; + $code .= ".Lskip_hkeys_cleanup_${label_suffix}:\n"; } if ($CLEAR_SCRATCH_REGISTERS) { @@ -537,11 +531,11 @@ sub precompute_hkeys_on_stack { && $HKEYS_RANGE ne "first32" && $HKEYS_RANGE ne "last32"); - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; test $HKEYS_READY,$HKEYS_READY - jnz .L_skip_hkeys_precomputation_${rndsuffix} + jnz .L_skip_hkeys_precomputation_${label_suffix} ___ if ($HKEYS_RANGE eq "first16" || $HKEYS_RANGE eq "first32" || $HKEYS_RANGE eq "all") { @@ -615,7 +609,7 @@ sub precompute_hkeys_on_stack { } } - $code .= ".L_skip_hkeys_precomputation_${rndsuffix}:\n"; + $code .= ".L_skip_hkeys_precomputation_${label_suffix}:\n"; } # ;; ============================================================================= @@ -1234,7 +1228,7 @@ sub GHASH_1_TO_16 { # ;; To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input # ;; GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. # ;; -# ;; Refer to [3] for more detals. +# ;; Refer to [3] for more details. # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; sub GHASH_MUL { my $GH = $_[0]; #; [in/out] xmm/ymm/zmm with multiply operand(s) (128-bits) @@ -1418,20 +1412,20 @@ sub CALC_AAD_HASH { my $SHFMSK = $ZT13; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; mov $A_IN,$T1 # ; T1 = AAD mov $A_LEN,$T2 # ; T2 = aadLen or $T2,$T2 - jz .L_CALC_AAD_done_${rndsuffix} + jz .L_CALC_AAD_done_${label_suffix} xor $HKEYS_READY,$HKEYS_READY vmovdqa64 SHUF_MASK(%rip),$SHFMSK -.L_get_AAD_loop48x16_${rndsuffix}: +.L_get_AAD_loop48x16_${label_suffix}: cmp \$`(48*16)`,$T2 - jl .L_exit_AAD_loop48x16_${rndsuffix} + jl .L_exit_AAD_loop48x16_${label_suffix} ___ $code .= <<___; @@ -1499,15 +1493,15 @@ sub CALC_AAD_HASH { $code .= <<___; sub \$`(48*16)`,$T2 - je .L_CALC_AAD_done_${rndsuffix} + je .L_CALC_AAD_done_${label_suffix} add \$`(48*16)`,$T1 - jmp .L_get_AAD_loop48x16_${rndsuffix} + jmp .L_get_AAD_loop48x16_${label_suffix} -.L_exit_AAD_loop48x16_${rndsuffix}: +.L_exit_AAD_loop48x16_${label_suffix}: # ; Less than 48x16 bytes remaining cmp \$`(32*16)`,$T2 - jl .L_less_than_32x16_${rndsuffix} + jl .L_less_than_32x16_${label_suffix} ___ $code .= <<___; @@ -1556,14 +1550,14 @@ sub CALC_AAD_HASH { $code .= <<___; sub \$`(32*16)`,$T2 - je .L_CALC_AAD_done_${rndsuffix} + je .L_CALC_AAD_done_${label_suffix} add \$`(32*16)`,$T1 - jmp .L_less_than_16x16_${rndsuffix} + jmp .L_less_than_16x16_${label_suffix} -.L_less_than_32x16_${rndsuffix}: +.L_less_than_32x16_${label_suffix}: cmp \$`(16*16)`,$T2 - jl .L_less_than_16x16_${rndsuffix} + jl .L_less_than_16x16_${label_suffix} # ; Get next 16 blocks vmovdqu64 `64*0`($T1),$ZT1 vmovdqu64 `64*1`($T1),$ZT2 @@ -1588,11 +1582,11 @@ sub CALC_AAD_HASH { $code .= <<___; sub \$`(16*16)`,$T2 - je .L_CALC_AAD_done_${rndsuffix} + je .L_CALC_AAD_done_${label_suffix} add \$`(16*16)`,$T1 # ; Less than 16x16 bytes remaining -.L_less_than_16x16_${rndsuffix}: +.L_less_than_16x16_${label_suffix}: # ;; prep mask source address lea byte64_len_to_mask_table(%rip),$T3 lea ($T3,$T2,8),$T3 @@ -1601,28 +1595,28 @@ sub CALC_AAD_HASH { add \$15,@{[DWORD($T2)]} shr \$4,@{[DWORD($T2)]} cmp \$2,@{[DWORD($T2)]} - jb .L_AAD_blocks_1_${rndsuffix} - je .L_AAD_blocks_2_${rndsuffix} + jb .L_AAD_blocks_1_${label_suffix} + je .L_AAD_blocks_2_${label_suffix} cmp \$4,@{[DWORD($T2)]} - jb .L_AAD_blocks_3_${rndsuffix} - je .L_AAD_blocks_4_${rndsuffix} + jb .L_AAD_blocks_3_${label_suffix} + je .L_AAD_blocks_4_${label_suffix} cmp \$6,@{[DWORD($T2)]} - jb .L_AAD_blocks_5_${rndsuffix} - je .L_AAD_blocks_6_${rndsuffix} + jb .L_AAD_blocks_5_${label_suffix} + je .L_AAD_blocks_6_${label_suffix} cmp \$8,@{[DWORD($T2)]} - jb .L_AAD_blocks_7_${rndsuffix} - je .L_AAD_blocks_8_${rndsuffix} + jb .L_AAD_blocks_7_${label_suffix} + je .L_AAD_blocks_8_${label_suffix} cmp \$10,@{[DWORD($T2)]} - jb .L_AAD_blocks_9_${rndsuffix} - je .L_AAD_blocks_10_${rndsuffix} + jb .L_AAD_blocks_9_${label_suffix} + je .L_AAD_blocks_10_${label_suffix} cmp \$12,@{[DWORD($T2)]} - jb .L_AAD_blocks_11_${rndsuffix} - je .L_AAD_blocks_12_${rndsuffix} + jb .L_AAD_blocks_11_${label_suffix} + je .L_AAD_blocks_12_${label_suffix} cmp \$14,@{[DWORD($T2)]} - jb .L_AAD_blocks_13_${rndsuffix} - je .L_AAD_blocks_14_${rndsuffix} + jb .L_AAD_blocks_13_${label_suffix} + je .L_AAD_blocks_14_${label_suffix} cmp \$15,@{[DWORD($T2)]} - je .L_AAD_blocks_15_${rndsuffix} + je .L_AAD_blocks_15_${label_suffix} ___ # ;; fall through for 16 blocks @@ -1635,7 +1629,7 @@ sub CALC_AAD_HASH { # ;; - jump to reduction code for (my $aad_blocks = 16; $aad_blocks > 0; $aad_blocks--) { - $code .= ".L_AAD_blocks_${aad_blocks}_${rndsuffix}:\n"; + $code .= ".L_AAD_blocks_${aad_blocks}_${label_suffix}:\n"; if ($aad_blocks > 12) { $code .= "sub \$`12*16*8`, $T3\n"; } elsif ($aad_blocks > 8) { @@ -1656,11 +1650,11 @@ sub CALC_AAD_HASH { if ($aad_blocks > 1) { # ;; fall through to CALC_AAD_done in 1 block case - $code .= "jmp .L_CALC_AAD_done_${rndsuffix}\n"; + $code .= "jmp .L_CALC_AAD_done_${label_suffix}\n"; } } - $code .= ".L_CALC_AAD_done_${rndsuffix}:\n"; + $code .= ".L_CALC_AAD_done_${label_suffix}:\n"; # ;; result in AAD_HASH } @@ -1710,13 +1704,13 @@ sub PARTIAL_BLOCK { my $IA1 = $GPTMP2; my $IA2 = $GPTMP0; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; # ;; if no partial block present then LENGTH/DATA_OFFSET will be set to zero mov ($PBLOCK_LEN),$LENGTH or $LENGTH,$LENGTH - je .L_partial_block_done_${rndsuffix} # ;Leave Macro if no partial blocks + je .L_partial_block_done_${label_suffix} # ;Leave Macro if no partial blocks ___ &READ_SMALL_DATA_INPUT($XTMP0, $PLAIN_CIPH_IN, $PLAIN_CIPH_LEN, $IA0, $IA2, $MASKREG); @@ -1755,9 +1749,9 @@ sub PARTIAL_BLOCK { } $code .= <<___; sub \$16,$IA1 - jge .L_no_extra_mask_${rndsuffix} + jge .L_no_extra_mask_${label_suffix} sub $IA1,$IA0 -.L_no_extra_mask_${rndsuffix}: +.L_no_extra_mask_${label_suffix}: # ;; get the appropriate mask to mask out bottom $LENGTH bytes of $XTMP1 # ;; - mask out bottom $LENGTH bytes of $XTMP1 # ;; sizeof(SHIFT_MASK) == 16 bytes @@ -1781,7 +1775,7 @@ sub PARTIAL_BLOCK { } $code .= <<___; cmp \$0,$IA1 - jl .L_partial_incomplete_${rndsuffix} + jl .L_partial_incomplete_${label_suffix} ___ # ;; GHASH computation for the last <16 Byte block @@ -1793,9 +1787,9 @@ sub PARTIAL_BLOCK { mov $LENGTH,$IA0 mov \$16,$LENGTH sub $IA0,$LENGTH - jmp .L_enc_dec_done_${rndsuffix} + jmp .L_enc_dec_done_${label_suffix} -.L_partial_incomplete_${rndsuffix}: +.L_partial_incomplete_${label_suffix}: ___ if ($win64) { $code .= <<___; @@ -1808,7 +1802,7 @@ sub PARTIAL_BLOCK { $code .= <<___; mov $PLAIN_CIPH_LEN,$LENGTH -.L_enc_dec_done_${rndsuffix}: +.L_enc_dec_done_${label_suffix}: # ;; output encrypted Bytes lea byte_len_to_mask_table(%rip),$IA0 @@ -1826,7 +1820,7 @@ sub PARTIAL_BLOCK { $code .= <<___; mov $CIPH_PLAIN_OUT,$IA0 vmovdqu8 $XTMP1,($IA0){$MASKREG} -.L_partial_block_done_${rndsuffix}: +.L_partial_block_done_${label_suffix}: ___ } @@ -2016,7 +2010,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { my $GM = $_[23]; # [in] ZMM with mid prodcut part my $GL = $_[24]; # [in] ZMM with lo product part - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;;; - Hash all but the last partial block of data @@ -2034,7 +2028,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { # ;; NOTE: the 'jl' is always taken for num_initial_blocks = 16. # ;; This is run in the context of GCM_ENC_DEC_SMALL for length < 256. cmp \$16,$LENGTH - jl .L_small_initial_partial_block_${rndsuffix} + jl .L_small_initial_partial_block_${label_suffix} # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;;; Handle a full length final block - encrypt and hash all blocks @@ -2056,11 +2050,11 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { &GHASH_1_TO_16($GCM128_CTX, $HASH_IN_OUT, $ZT0, $ZT1, $ZT2, $ZT3, $ZT4, $ZT5, $ZT6, $ZT7, $ZT8, &ZWORD($HASH_IN_OUT), $DAT0, $DAT1, $DAT2, $DAT3, $NUM_BLOCKS, $GH, $GM, $GL); } - $code .= "jmp .L_small_initial_compute_done_${rndsuffix}\n"; + $code .= "jmp .L_small_initial_compute_done_${label_suffix}\n"; } $code .= <<___; -.L_small_initial_partial_block_${rndsuffix}: +.L_small_initial_partial_block_${label_suffix}: # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;;; Handle ghash for a <16B final block @@ -2125,7 +2119,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { # ;; a partial block of data, so xor that into the hash. vpxorq $LAST_GHASH_BLK,$HASH_IN_OUT,$HASH_IN_OUT # ;; The result is in $HASH_IN_OUT - jmp .L_after_reduction_${rndsuffix} + jmp .L_after_reduction_${label_suffix} ___ } @@ -2133,7 +2127,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { # ;;; After GHASH reduction # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - $code .= ".L_small_initial_compute_done_${rndsuffix}:\n"; + $code .= ".L_small_initial_compute_done_${label_suffix}:\n"; # ;; If using init/update/finalize, we need to xor any partial block data # ;; into the hash. @@ -2144,13 +2138,13 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH { $code .= <<___; # ;; NOTE: for $NUM_BLOCKS = 16, $LENGTH, stored in [PBlockLen] is never zero or $LENGTH,$LENGTH - je .L_after_reduction_${rndsuffix} + je .L_after_reduction_${label_suffix} ___ } $code .= "vpxorq $LAST_GHASH_BLK,$HASH_IN_OUT,$HASH_IN_OUT\n"; } - $code .= ".L_after_reduction_${rndsuffix}:\n"; + $code .= ".L_after_reduction_${label_suffix}:\n"; # ;; Final hash is now in HASH_IN_OUT } @@ -2266,7 +2260,7 @@ sub GHASH_16_ENCRYPT_N_GHASH_N { die "GHASH_16_ENCRYPT_N_GHASH_N: num_blocks is out of bounds = $NUM_BLOCKS\n" if ($NUM_BLOCKS > 16 || $NUM_BLOCKS < 0); - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; my $GH1H = $HASH_IN_OUT; @@ -2326,16 +2320,16 @@ sub GHASH_16_ENCRYPT_N_GHASH_N { $code .= <<___; cmp \$`(256 - $NUM_BLOCKS)`,@{[DWORD($CTR_CHECK)]} - jae .L_16_blocks_overflow_${rndsuffix} + jae .L_16_blocks_overflow_${label_suffix} ___ &ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16( $NUM_BLOCKS, "vpaddd", $B00_03, $B04_07, $B08_11, $B12_15, $CTR_BE, $B00_03, $B04_07, $B08_11, $ADDBE_1234, $ADDBE_4x4, $ADDBE_4x4, $ADDBE_4x4); $code .= <<___; - jmp .L_16_blocks_ok_${rndsuffix} + jmp .L_16_blocks_ok_${label_suffix} -.L_16_blocks_overflow_${rndsuffix}: +.L_16_blocks_overflow_${label_suffix}: vpshufb $SHFMSK,$CTR_BE,$CTR_BE vpaddd ddq_add_1234(%rip),$CTR_BE,$B00_03 ___ @@ -2355,7 +2349,7 @@ sub GHASH_16_ENCRYPT_N_GHASH_N { $NUM_BLOCKS, "vpshufb", $B00_03, $B04_07, $B08_11, $B12_15, $B00_03, $B04_07, $B08_11, $B12_15, $SHFMSK, $SHFMSK, $SHFMSK, $SHFMSK); $code .= <<___; -.L_16_blocks_ok_${rndsuffix}: +.L_16_blocks_ok_${label_suffix}: # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;; - pre-load constants @@ -2805,53 +2799,53 @@ sub GCM_ENC_DEC_LAST { my $MASKREG = $_[44]; # [clobbered] mask register my $PBLOCK_LEN = $_[45]; # [in] partial block length - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; mov @{[DWORD($LENGTH)]},@{[DWORD($IA0)]} add \$15,@{[DWORD($IA0)]} shr \$4,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_0_${rndsuffix} + je .L_last_num_blocks_is_0_${label_suffix} cmp \$8,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_8_${rndsuffix} - jb .L_last_num_blocks_is_7_1_${rndsuffix} + je .L_last_num_blocks_is_8_${label_suffix} + jb .L_last_num_blocks_is_7_1_${label_suffix} cmp \$12,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_12_${rndsuffix} - jb .L_last_num_blocks_is_11_9_${rndsuffix} + je .L_last_num_blocks_is_12_${label_suffix} + jb .L_last_num_blocks_is_11_9_${label_suffix} # ;; 16, 15, 14 or 13 cmp \$15,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_15_${rndsuffix} - ja .L_last_num_blocks_is_16_${rndsuffix} + je .L_last_num_blocks_is_15_${label_suffix} + ja .L_last_num_blocks_is_16_${label_suffix} cmp \$14,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_14_${rndsuffix} - jmp .L_last_num_blocks_is_13_${rndsuffix} + je .L_last_num_blocks_is_14_${label_suffix} + jmp .L_last_num_blocks_is_13_${label_suffix} -.L_last_num_blocks_is_11_9_${rndsuffix}: +.L_last_num_blocks_is_11_9_${label_suffix}: # ;; 11, 10 or 9 cmp \$10,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_10_${rndsuffix} - ja .L_last_num_blocks_is_11_${rndsuffix} - jmp .L_last_num_blocks_is_9_${rndsuffix} + je .L_last_num_blocks_is_10_${label_suffix} + ja .L_last_num_blocks_is_11_${label_suffix} + jmp .L_last_num_blocks_is_9_${label_suffix} -.L_last_num_blocks_is_7_1_${rndsuffix}: +.L_last_num_blocks_is_7_1_${label_suffix}: cmp \$4,@{[DWORD($IA0)]} - je .L_last_num_blocks_is_4_${rndsuffix} - jb .L_last_num_blocks_is_3_1_${rndsuffix} + je .L_last_num_blocks_is_4_${label_suffix} + jb .L_last_num_blocks_is_3_1_${label_suffix} # ;; 7, 6 or 5 cmp \$6,@{[DWORD($IA0)]} - ja .L_last_num_blocks_is_7_${rndsuffix} - je .L_last_num_blocks_is_6_${rndsuffix} - jmp .L_last_num_blocks_is_5_${rndsuffix} + ja .L_last_num_blocks_is_7_${label_suffix} + je .L_last_num_blocks_is_6_${label_suffix} + jmp .L_last_num_blocks_is_5_${label_suffix} -.L_last_num_blocks_is_3_1_${rndsuffix}: +.L_last_num_blocks_is_3_1_${label_suffix}: # ;; 3, 2 or 1 cmp \$2,@{[DWORD($IA0)]} - ja .L_last_num_blocks_is_3_${rndsuffix} - je .L_last_num_blocks_is_2_${rndsuffix} + ja .L_last_num_blocks_is_3_${label_suffix} + je .L_last_num_blocks_is_2_${label_suffix} ___ # ;; fall through for `jmp .L_last_num_blocks_is_1` @@ -2859,7 +2853,7 @@ sub GCM_ENC_DEC_LAST { # ;; Use rep to generate different block size variants # ;; - one block size has to be the first one for my $num_blocks (1 .. 16) { - $code .= ".L_last_num_blocks_is_${num_blocks}_${rndsuffix}:\n"; + $code .= ".L_last_num_blocks_is_${num_blocks}_${label_suffix}:\n"; &GHASH_16_ENCRYPT_N_GHASH_N( $AES_KEYS, $GCM128_CTX, $CIPH_PLAIN_OUT, $PLAIN_CIPH_IN, $DATA_OFFSET, $LENGTH, $CTR_BE, $CTR_CHECK, $HASHKEY_OFFSET, $GHASHIN_BLK_OFFSET, @@ -2872,10 +2866,10 @@ sub GCM_ENC_DEC_LAST { $ENC_DEC, $HASH_IN_OUT, $IA0, $IA1, $MASKREG, $num_blocks, $PBLOCK_LEN); - $code .= "jmp .L_last_blocks_done_${rndsuffix}\n"; + $code .= "jmp .L_last_blocks_done_${label_suffix}\n"; } - $code .= ".L_last_num_blocks_is_0_${rndsuffix}:\n"; + $code .= ".L_last_num_blocks_is_0_${label_suffix}:\n"; # ;; if there is 0 blocks to cipher then there are only 16 blocks for ghash and reduction # ;; - convert mid into end_reduce @@ -2891,7 +2885,7 @@ sub GCM_ENC_DEC_LAST { $GHASHIN_BLK_OFFSET, 0, "%rsp", $HASHKEY_OFFSET, 0, $HASH_IN_OUT, $ZT00, $ZT01, $ZT02, $ZT03, $ZT04, $ZT05, $ZT06, $ZT07, $ZT08, $ZT09); - $code .= ".L_last_blocks_done_${rndsuffix}:\n"; + $code .= ".L_last_blocks_done_${label_suffix}:\n"; } # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2985,20 +2979,20 @@ sub GHASH_16_ENCRYPT_16_PARALLEL { my $GHDAT1 = $ZT21; my $GHDAT2 = $ZT22; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ;; prepare counter blocks $code .= <<___; cmpb \$`(256 - 16)`,@{[BYTE($CTR_CHECK)]} - jae .L_16_blocks_overflow_${rndsuffix} + jae .L_16_blocks_overflow_${label_suffix} vpaddd $ADDBE_1234,$CTR_BE,$B00_03 vpaddd $ADDBE_4x4,$B00_03,$B04_07 vpaddd $ADDBE_4x4,$B04_07,$B08_11 vpaddd $ADDBE_4x4,$B08_11,$B12_15 - jmp .L_16_blocks_ok_${rndsuffix} -.L_16_blocks_overflow_${rndsuffix}: + jmp .L_16_blocks_ok_${label_suffix} +.L_16_blocks_overflow_${label_suffix}: vpshufb $SHFMSK,$CTR_BE,$CTR_BE vmovdqa64 ddq_add_4444(%rip),$B12_15 vpaddd ddq_add_1234(%rip),$CTR_BE,$B00_03 @@ -3009,7 +3003,7 @@ sub GHASH_16_ENCRYPT_16_PARALLEL { vpshufb $SHFMSK,$B04_07,$B04_07 vpshufb $SHFMSK,$B08_11,$B08_11 vpshufb $SHFMSK,$B12_15,$B12_15 -.L_16_blocks_ok_${rndsuffix}: +.L_16_blocks_ok_${label_suffix}: ___ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3338,25 +3332,25 @@ sub ENCRYPT_SINGLE_BLOCK { my $XMM0 = $_[1]; # ; [in/out] my $GPR1 = $_[2]; # ; [clobbered] - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; # ; load number of rounds from AES_KEY structure (offset in bytes is # ; size of the |rd_key| buffer) mov `4*15*4`($AES_KEY),@{[DWORD($GPR1)]} cmp \$9,@{[DWORD($GPR1)]} - je .Laes_128_${rndsuffix} + je .Laes_128_${label_suffix} cmp \$11,@{[DWORD($GPR1)]} - je .Laes_192_${rndsuffix} + je .Laes_192_${label_suffix} cmp \$13,@{[DWORD($GPR1)]} - je .Laes_256_${rndsuffix} - jmp .Lexit_aes_${rndsuffix} + je .Laes_256_${label_suffix} + jmp .Lexit_aes_${label_suffix} ___ for my $keylen (sort keys %aes_rounds) { my $nr = $aes_rounds{$keylen}; $code .= <<___; .align 32 -.Laes_${keylen}_${rndsuffix}: +.Laes_${keylen}_${label_suffix}: ___ $code .= "vpxorq `16*0`($AES_KEY),$XMM0, $XMM0\n\n"; for (my $i = 1; $i <= $nr; $i++) { @@ -3364,10 +3358,10 @@ sub ENCRYPT_SINGLE_BLOCK { } $code .= <<___; vaesenclast `16*($nr+1)`($AES_KEY),$XMM0,$XMM0 - jmp .Lexit_aes_${rndsuffix} + jmp .Lexit_aes_${label_suffix} ___ } - $code .= ".Lexit_aes_${rndsuffix}:\n\n"; + $code .= ".Lexit_aes_${label_suffix}:\n\n"; } sub CALC_J0 { @@ -3562,52 +3556,52 @@ sub GCM_ENC_DEC_SMALL { my $SHUFMASK = $_[29]; # [in] ZMM with BE/LE shuffle mask my $PBLOCK_LEN = $_[30]; # [in] partial block length - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; cmp \$8,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_8_${rndsuffix} - jl .L_small_initial_num_blocks_is_7_1_${rndsuffix} + je .L_small_initial_num_blocks_is_8_${label_suffix} + jl .L_small_initial_num_blocks_is_7_1_${label_suffix} cmp \$12,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_12_${rndsuffix} - jl .L_small_initial_num_blocks_is_11_9_${rndsuffix} + je .L_small_initial_num_blocks_is_12_${label_suffix} + jl .L_small_initial_num_blocks_is_11_9_${label_suffix} # ;; 16, 15, 14 or 13 cmp \$16,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_16_${rndsuffix} + je .L_small_initial_num_blocks_is_16_${label_suffix} cmp \$15,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_15_${rndsuffix} + je .L_small_initial_num_blocks_is_15_${label_suffix} cmp \$14,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_14_${rndsuffix} - jmp .L_small_initial_num_blocks_is_13_${rndsuffix} + je .L_small_initial_num_blocks_is_14_${label_suffix} + jmp .L_small_initial_num_blocks_is_13_${label_suffix} -.L_small_initial_num_blocks_is_11_9_${rndsuffix}: +.L_small_initial_num_blocks_is_11_9_${label_suffix}: # ;; 11, 10 or 9 cmp \$11,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_11_${rndsuffix} + je .L_small_initial_num_blocks_is_11_${label_suffix} cmp \$10,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_10_${rndsuffix} - jmp .L_small_initial_num_blocks_is_9_${rndsuffix} + je .L_small_initial_num_blocks_is_10_${label_suffix} + jmp .L_small_initial_num_blocks_is_9_${label_suffix} -.L_small_initial_num_blocks_is_7_1_${rndsuffix}: +.L_small_initial_num_blocks_is_7_1_${label_suffix}: cmp \$4,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_4_${rndsuffix} - jl .L_small_initial_num_blocks_is_3_1_${rndsuffix} + je .L_small_initial_num_blocks_is_4_${label_suffix} + jl .L_small_initial_num_blocks_is_3_1_${label_suffix} # ;; 7, 6 or 5 cmp \$7,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_7_${rndsuffix} + je .L_small_initial_num_blocks_is_7_${label_suffix} cmp \$6,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_6_${rndsuffix} - jmp .L_small_initial_num_blocks_is_5_${rndsuffix} + je .L_small_initial_num_blocks_is_6_${label_suffix} + jmp .L_small_initial_num_blocks_is_5_${label_suffix} -.L_small_initial_num_blocks_is_3_1_${rndsuffix}: +.L_small_initial_num_blocks_is_3_1_${label_suffix}: # ;; 3, 2 or 1 cmp \$3,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_3_${rndsuffix} + je .L_small_initial_num_blocks_is_3_${label_suffix} cmp \$2,$NUM_BLOCKS - je .L_small_initial_num_blocks_is_2_${rndsuffix} + je .L_small_initial_num_blocks_is_2_${label_suffix} # ;; for $NUM_BLOCKS == 1, just fall through and no 'jmp' needed @@ -3616,7 +3610,7 @@ sub GCM_ENC_DEC_SMALL { ___ for (my $num_blocks = 1; $num_blocks <= 16; $num_blocks++) { - $code .= ".L_small_initial_num_blocks_is_${num_blocks}_${rndsuffix}:\n"; + $code .= ".L_small_initial_num_blocks_is_${num_blocks}_${label_suffix}:\n"; &INITIAL_BLOCKS_PARTIAL( $AES_KEYS, $GCM128_CTX, $CIPH_PLAIN_OUT, $PLAIN_CIPH_IN, $LENGTH, $DATA_OFFSET, $num_blocks, $CTR, $HASH_IN_OUT, $ENC_DEC, $ZTMP0, $ZTMP1, @@ -3625,11 +3619,11 @@ sub GCM_ENC_DEC_SMALL { $ZTMP14, $IA0, $IA1, $MASKREG, $SHUFMASK, $PBLOCK_LEN); if ($num_blocks != 16) { - $code .= "jmp .L_small_initial_blocks_encrypted_${rndsuffix}\n"; + $code .= "jmp .L_small_initial_blocks_encrypted_${label_suffix}\n"; } } - $code .= ".L_small_initial_blocks_encrypted_${rndsuffix}:\n"; + $code .= ".L_small_initial_blocks_encrypted_${label_suffix}:\n"; } # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3710,7 +3704,7 @@ sub GCM_ENC_DEC { my $MASKREG = "%k1"; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; # ;; reduction every 48 blocks, depth 32 blocks # ;; @note 48 blocks is the maximum capacity of the stack frame @@ -3751,7 +3745,7 @@ sub GCM_ENC_DEC { } else { $code .= "or $PLAIN_CIPH_LEN,$PLAIN_CIPH_LEN\n"; } - $code .= "je .L_enc_dec_done_${rndsuffix}\n"; + $code .= "je .L_enc_dec_done_${label_suffix}\n"; # Length value from context $CTX_OFFSET_InLen`($GCM128_CTX) is updated in # 'providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc' @@ -3778,12 +3772,12 @@ sub GCM_ENC_DEC { # ;; There may be no more data if it was consumed in the partial block. $code .= <<___; sub $DATA_OFFSET,$LENGTH - je .L_enc_dec_done_${rndsuffix} + je .L_enc_dec_done_${label_suffix} ___ $code .= <<___; cmp \$`(16 * 16)`,$LENGTH - jbe .L_message_below_equal_16_blocks_${rndsuffix} + jbe .L_message_below_equal_16_blocks_${label_suffix} vmovdqa64 SHUF_MASK(%rip),$SHUF_MASK vmovdqa64 ddq_addbe_4444(%rip),$ADDBE_4x4 @@ -3815,7 +3809,7 @@ sub GCM_ENC_DEC { $code .= <<___; cmp \$`(32 * 16)`,$LENGTH - jb .L_message_below_32_blocks_${rndsuffix} + jb .L_message_below_32_blocks_${label_suffix} ___ # ;; ==== AES-CTR - next 16 blocks @@ -3836,13 +3830,13 @@ sub GCM_ENC_DEC { sub \$`(32 * 16)`,$LENGTH cmp \$`($big_loop_nblocks * 16)`,$LENGTH - jb .L_no_more_big_nblocks_${rndsuffix} + jb .L_no_more_big_nblocks_${label_suffix} ___ # ;; ==== # ;; ==== AES-CTR + GHASH - 48 blocks loop # ;; ==== - $code .= ".L_encrypt_big_nblocks_${rndsuffix}:\n"; + $code .= ".L_encrypt_big_nblocks_${label_suffix}:\n"; # ;; ==== AES-CTR + GHASH - 16 blocks, start $aesout_offset = ($STACK_LOCAL_OFFSET + (32 * 16)); @@ -3893,15 +3887,15 @@ sub GCM_ENC_DEC { add \$`($big_loop_nblocks * 16)`,$DATA_OFFSET sub \$`($big_loop_nblocks * 16)`,$LENGTH cmp \$`($big_loop_nblocks * 16)`,$LENGTH - jae .L_encrypt_big_nblocks_${rndsuffix} + jae .L_encrypt_big_nblocks_${label_suffix} -.L_no_more_big_nblocks_${rndsuffix}: +.L_no_more_big_nblocks_${label_suffix}: cmp \$`(32 * 16)`,$LENGTH - jae .L_encrypt_32_blocks_${rndsuffix} + jae .L_encrypt_32_blocks_${label_suffix} cmp \$`(16 * 16)`,$LENGTH - jae .L_encrypt_16_blocks_${rndsuffix} + jae .L_encrypt_16_blocks_${label_suffix} ___ # ;; ===================================================== @@ -3909,7 +3903,7 @@ sub GCM_ENC_DEC { # ;; ==== GHASH 1 x 16 blocks # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks # ;; ==== then GHASH N blocks - $code .= ".L_encrypt_0_blocks_ghash_32_${rndsuffix}:\n"; + $code .= ".L_encrypt_0_blocks_ghash_32_${label_suffix}:\n"; # ;; calculate offset to the right hash key $code .= <<___; @@ -3937,7 +3931,7 @@ sub GCM_ENC_DEC { $IA0, $IA5, $MASKREG, $PBLOCK_LEN); $code .= "vpshufb @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n"; - $code .= "jmp .L_ghash_done_${rndsuffix}\n"; + $code .= "jmp .L_ghash_done_${label_suffix}\n"; # ;; ===================================================== # ;; ===================================================== @@ -3946,7 +3940,7 @@ sub GCM_ENC_DEC { # ;; ==== GHASH 1 x 16 blocks (reduction) # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks # ;; ==== then GHASH N blocks - $code .= ".L_encrypt_32_blocks_${rndsuffix}:\n"; + $code .= ".L_encrypt_32_blocks_${label_suffix}:\n"; # ;; ==== AES-CTR + GHASH - 16 blocks, start $aesout_offset = ($STACK_LOCAL_OFFSET + (32 * 16)); @@ -4007,7 +4001,7 @@ sub GCM_ENC_DEC { $IA0, $IA5, $MASKREG, $PBLOCK_LEN); $code .= "vpshufb @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n"; - $code .= "jmp .L_ghash_done_${rndsuffix}\n"; + $code .= "jmp .L_ghash_done_${label_suffix}\n"; # ;; ===================================================== # ;; ===================================================== @@ -4015,7 +4009,7 @@ sub GCM_ENC_DEC { # ;; ==== GHASH 1 x 16 blocks # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks # ;; ==== then GHASH N blocks - $code .= ".L_encrypt_16_blocks_${rndsuffix}:\n"; + $code .= ".L_encrypt_16_blocks_${label_suffix}:\n"; # ;; ==== AES-CTR + GHASH - 16 blocks, start $aesout_offset = ($STACK_LOCAL_OFFSET + (32 * 16)); @@ -4059,9 +4053,9 @@ sub GCM_ENC_DEC { $code .= "vpshufb @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n"; $code .= <<___; - jmp .L_ghash_done_${rndsuffix} + jmp .L_ghash_done_${label_suffix} -.L_message_below_32_blocks_${rndsuffix}: +.L_message_below_32_blocks_${label_suffix}: # ;; 32 > number of blocks > 16 sub \$`(16 * 16)`,$LENGTH @@ -4094,9 +4088,9 @@ sub GCM_ENC_DEC { $code .= "vpshufb @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n"; $code .= <<___; - jmp .L_ghash_done_${rndsuffix} + jmp .L_ghash_done_${label_suffix} -.L_message_below_equal_16_blocks_${rndsuffix}: +.L_message_below_equal_16_blocks_${label_suffix}: # ;; Determine how many blocks to process # ;; - process one additional block if there is a partial block mov @{[DWORD($LENGTH)]},@{[DWORD($IA1)]} @@ -4113,13 +4107,13 @@ sub GCM_ENC_DEC { # ;; fall through to exit - $code .= ".L_ghash_done_${rndsuffix}:\n"; + $code .= ".L_ghash_done_${label_suffix}:\n"; # ;; save the last counter block $code .= "vmovdqu64 $CTR_BLOCKx,`$CTX_OFFSET_CurCount`($GCM128_CTX)\n"; $code .= <<___; vmovdqu64 $AAD_HASHx,`$CTX_OFFSET_AadHash`($GCM128_CTX) -.L_enc_dec_done_${rndsuffix}: +.L_enc_dec_done_${label_suffix}: ___ } @@ -4155,7 +4149,7 @@ sub INITIAL_BLOCKS_16 { my $B08_11 = $T7; my $B12_15 = $T8; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; my $stack_offset = $BLK_OFFSET; $code .= <<___; @@ -4163,13 +4157,13 @@ sub INITIAL_BLOCKS_16 { # ;; prepare counter blocks cmpb \$`(256 - 16)`,@{[BYTE($CTR_CHECK)]} - jae .L_next_16_overflow_${rndsuffix} + jae .L_next_16_overflow_${label_suffix} vpaddd $ADDBE_1234,$CTR,$B00_03 vpaddd $ADDBE_4x4,$B00_03,$B04_07 vpaddd $ADDBE_4x4,$B04_07,$B08_11 vpaddd $ADDBE_4x4,$B08_11,$B12_15 - jmp .L_next_16_ok_${rndsuffix} -.L_next_16_overflow_${rndsuffix}: + jmp .L_next_16_ok_${label_suffix} +.L_next_16_overflow_${label_suffix}: vpshufb $SHUF_MASK,$CTR,$CTR vmovdqa64 ddq_add_4444(%rip),$B12_15 vpaddd ddq_add_1234(%rip),$CTR,$B00_03 @@ -4180,7 +4174,7 @@ sub INITIAL_BLOCKS_16 { vpshufb $SHUF_MASK,$B04_07,$B04_07 vpshufb $SHUF_MASK,$B08_11,$B08_11 vpshufb $SHUF_MASK,$B12_15,$B12_15 -.L_next_16_ok_${rndsuffix}: +.L_next_16_ok_${label_suffix}: vshufi64x2 \$0b11111111,$B12_15,$B12_15,$CTR addb \$16,@{[BYTE($CTR_CHECK)]} # ;; === load 16 blocks of data @@ -4264,7 +4258,7 @@ sub GCM_COMPLETE { my $GCM128_CTX = $_[0]; my $PBLOCK_LEN = $_[1]; - my $rndsuffix = &random_string(); + my $label_suffix = $label_count++; $code .= <<___; vmovdqu @{[HashKeyByIdx(1,$GCM128_CTX)]},%xmm2 @@ -4276,14 +4270,14 @@ sub GCM_COMPLETE { # ;; Process the final partial block. cmp \$0,$PBLOCK_LEN - je .L_partial_done_${rndsuffix} + je .L_partial_done_${label_suffix} ___ # ;GHASH computation for the last <16 Byte block &GHASH_MUL("%xmm4", "%xmm2", "%xmm0", "%xmm16", "%xmm17"); $code .= <<___; -.L_partial_done_${rndsuffix}: +.L_partial_done_${label_suffix}: vmovq `$CTX_OFFSET_InLen`($GCM128_CTX), %xmm5 vpinsrq \$1, `$CTX_OFFSET_AadLen`($GCM128_CTX), %xmm5, %xmm5 # ; xmm5 = len(A)||len(C) vpsllq \$3, %xmm5, %xmm5 # ; convert bytes into bits @@ -4297,7 +4291,7 @@ sub GCM_COMPLETE { vpshufb SHUF_MASK(%rip),%xmm4,%xmm4 # ; perform a 16Byte swap vpxor %xmm4,%xmm3,%xmm3 -.L_return_T_${rndsuffix}: +.L_return_T_${label_suffix}: vmovdqu %xmm3,`$CTX_OFFSET_AadHash`($GCM128_CTX) ___ } diff --git a/crypto/modes/asm/ghash-riscv64.pl b/crypto/modes/asm/ghash-riscv64.pl index 6f2a1384de..ee97ff0dd3 100644 --- a/crypto/modes/asm/ghash-riscv64.pl +++ b/crypto/modes/asm/ghash-riscv64.pl @@ -1,298 +1,428 @@ #! /usr/bin/env perl -# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +# This file is dual-licensed, meaning that you can use it under your +# choice of either of the following two licenses: # -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at +# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You can obtain +# a copy in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html +# +# or +# +# Copyright (c) 2023, Christoph Müllner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; + +use FindBin qw($Bin); +use lib "$Bin"; +use lib "$Bin/../../perlasm"; +use riscv; # $output is the last argument if it looks like a file (it has an extension) # $flavour is the first argument if it doesn't look like a file -$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; -$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; +my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; $output and open STDOUT,">$output"; -my @regs = map("x$_",(0..31)); -my @regaliases = ('zero','ra','sp','gp','tp','t0','t1','t2','s0','s1', - map("a$_",(0..7)), - map("s$_",(2..11)), - map("t$_",(3..6)) -); - -my %reglookup; -@reglookup{@regs} = @regs; -@reglookup{@regaliases} = @regs; - -# Takes a register name, possibly an alias, and converts it to a register index -# from 0 to 31 -sub read_reg { - my $reg = lc shift; - if (!exists($reglookup{$reg})) { - die("Unknown register ".$reg); - } - my $regstr = $reglookup{$reg}; - if (!($regstr =~ /^x([0-9]+)$/)) { - die("Could not process register ".$reg); - } - return $1; -} - -sub rv64_rev8 { - # Encoding for rev8 rd, rs instruction on RV64 - # XXXXXXXXXXXXX_ rs _XXX_ rd _XXXXXXX - my $template = 0b011010111000_00000_101_00000_0010011; - my $rd = read_reg shift; - my $rs = read_reg shift; +my $code=<<___; +.text +___ - return ".word ".($template | ($rs << 15) | ($rd << 7)); -} +################################################################################ +# void gcm_init_rv64i_zbc(u128 Htable[16], const u64 H[2]); +# void gcm_init_rv64i_zbc__zbb(u128 Htable[16], const u64 H[2]); +# void gcm_init_rv64i_zbc__zbkb(u128 Htable[16], const u64 H[2]); +# +# input: H: 128-bit H - secret parameter E(K, 0^128) +# output: Htable: Preprocessed key data for gcm_gmult_rv64i_zbc* and +# gcm_ghash_rv64i_zbc* +# +# All callers of this function revert the byte-order unconditionally +# on little-endian machines. So we need to revert the byte-order back. +# Additionally we reverse the bits of each byte. -sub rv64_clmul { - # Encoding for clmul rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0000101_00000_00000_001_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; +{ +my ($Htable,$H,$VAL0,$VAL1,$TMP0,$TMP1,$TMP2) = ("a0","a1","a2","a3","t0","t1","t2"); - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +$code .= <<___; +.p2align 3 +.globl gcm_init_rv64i_zbc +.type gcm_init_rv64i_zbc,\@function +gcm_init_rv64i_zbc: + ld $VAL0,0($H) + ld $VAL1,8($H) + @{[brev8_rv64i $VAL0, $TMP0, $TMP1, $TMP2]} + @{[brev8_rv64i $VAL1, $TMP0, $TMP1, $TMP2]} + @{[sd_rev8_rv64i $VAL0, $Htable, 0, $TMP0]} + @{[sd_rev8_rv64i $VAL1, $Htable, 8, $TMP0]} + ret +.size gcm_init_rv64i_zbc,.-gcm_init_rv64i_zbc +___ } -sub rv64_clmulh { - # Encoding for clmulh rd, rs1, rs2 instruction on RV64 - # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX - my $template = 0b0000101_00000_00000_011_00000_0110011; - my $rd = read_reg shift; - my $rs1 = read_reg shift; - my $rs2 = read_reg shift; +{ +my ($Htable,$H,$VAL0,$VAL1,$TMP0,$TMP1,$TMP2) = ("a0","a1","a2","a3","t0","t1","t2"); - return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +$code .= <<___; +.p2align 3 +.globl gcm_init_rv64i_zbc__zbb +.type gcm_init_rv64i_zbc__zbb,\@function +gcm_init_rv64i_zbc__zbb: + ld $VAL0,0($H) + ld $VAL1,8($H) + @{[brev8_rv64i $VAL0, $TMP0, $TMP1, $TMP2]} + @{[brev8_rv64i $VAL1, $TMP0, $TMP1, $TMP2]} + @{[rev8 $VAL0, $VAL0]} + @{[rev8 $VAL1, $VAL1]} + sd $VAL0,0($Htable) + sd $VAL1,8($Htable) + ret +.size gcm_init_rv64i_zbc__zbb,.-gcm_init_rv64i_zbc__zbb +___ } -################################################################################ -# gcm_init_clmul_rv64i_zbb_zbc(u128 Htable[16], const u64 Xi[2]) -# Initialization function for clmul-based implementation of GMULT -# This function is used in tandem with gcm_gmult_clmul_rv64i_zbb_zbc -################################################################################ { -my ($Haddr,$Xi,$TEMP) = ("a0","a1","a2"); +my ($Htable,$H,$TMP0,$TMP1) = ("a0","a1","t0","t1"); $code .= <<___; -.text -.balign 16 -.globl gcm_init_clmul_rv64i_zbb_zbc -.type gcm_init_clmul_rv64i_zbb_zbc,\@function -# Initialize clmul-based implementation of galois field multiplication routine. -# gcm_init_clmul_rv64i_zbb_zbc(ctx->Htable, ctx->H.u) -gcm_init_clmul_rv64i_zbb_zbc: - # argument 0 = ctx->Htable (store H here) - # argument 1 = H.u[] (2x 64-bit words) [H_high64, H_low64] - - # Simply store [H_high64, H_low64] for later - ld $TEMP,0($Xi) - sd $TEMP,0($Haddr) - ld $TEMP,8($Xi) - sd $TEMP,8($Haddr) - +.p2align 3 +.globl gcm_init_rv64i_zbc__zbkb +.type gcm_init_rv64i_zbc__zbkb,\@function +gcm_init_rv64i_zbc__zbkb: + ld $TMP0,0($H) + ld $TMP1,8($H) + @{[brev8 $TMP0, $TMP0]} + @{[brev8 $TMP1, $TMP1]} + @{[rev8 $TMP0, $TMP0]} + @{[rev8 $TMP1, $TMP1]} + sd $TMP0,0($Htable) + sd $TMP1,8($Htable) ret - +.size gcm_init_rv64i_zbc__zbkb,.-gcm_init_rv64i_zbc__zbkb ___ - } ################################################################################ -# gcm_gmult_clmul_rv64i_zbb_zbc(u64 Xi[2], const u128 Htable[16]) -# Compute GMULT (X*H mod f) using the Zbc (clmul) and Zbb (basic bit manip) -# extensions, and the Modified Barrett Reduction technique -################################################################################ +# void gcm_gmult_rv64i_zbc(u64 Xi[2], const u128 Htable[16]); +# void gcm_gmult_rv64i_zbc__zbkb(u64 Xi[2], const u128 Htable[16]); +# +# input: Xi: current hash value +# Htable: copy of H +# output: Xi: next hash value Xi +# +# Compute GMULT (Xi*H mod f) using the Zbc (clmul) and Zbb (basic bit manip) +# extensions. Using the no-Karatsuba approach and clmul for the final reduction. +# This results in an implementation with minimized number of instructions. +# HW with clmul latencies higher than 2 cycles might observe a performance +# improvement with Karatsuba. HW with clmul latencies higher than 6 cycles +# might observe a performance improvement with additionally converting the +# reduction to shift&xor. For a full discussion of this estimates see +# https://github.com/riscv/riscv-crypto/blob/master/doc/supp/gcm-mode-cmul.adoc { -my ($Xi,$Haddr,$A1,$A0,$B1,$B0,$C1,$C0,$D1,$D0,$E1,$E0,$TEMP,$TEMP2,$qp_low) = - ("a0","a1","a2","a3","a4","a5","a6","a7","t0","t1","t2","t3","t4","t5","t6"); +my ($Xi,$Htable,$x0,$x1,$y0,$y1) = ("a0","a1","a4","a5","a6","a7"); +my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); $code .= <<___; -.text -.balign 16 -.globl gcm_gmult_clmul_rv64i_zbb_zbc -.type gcm_gmult_clmul_rv64i_zbb_zbc,\@function -# static void gcm_gmult_clmul_rv64i_zbb_zbc(u64 Xi[2], const u128 Htable[16]) -# Computes product of X*H mod f -gcm_gmult_clmul_rv64i_zbb_zbc: - - # Load X and H (H is saved previously in gcm_init_clmul_rv64i_zbb_zbc) - ld $A1,0($Xi) - ld $A0,8($Xi) - - ld $B1,0($Haddr) - ld $B0,8($Haddr) - - li $qp_low,0xe100000000000000 - - # Perform Katratsuba Multiplication to generate a 255-bit intermediate - # A = [A1:A0] - # B = [B1:B0] - # Let: - # [C1:C0] = A1*B1 - # [D1:D0] = A0*B0 - # [E1:E0] = (A0+A1)*(B0+B1) - # Then: - # A*B = [C1:C0+C1+D1+E1:D1+C0+D0+E0:D0] - - @{[rv64_rev8 $A1, $A1]} - @{[rv64_clmul $C0,$A1,$B1]} - @{[rv64_clmulh $C1,$A1,$B1]} - - @{[rv64_rev8 $A0,$A0]} - @{[rv64_clmul $D0,$A0,$B0]} - @{[rv64_clmulh $D1,$A0,$B0]} - - xor $TEMP,$A0,$A1 - xor $TEMP2,$B0,$B1 - - @{[rv64_clmul $E0,$TEMP,$TEMP2]} - @{[rv64_clmulh $E1,$TEMP,$TEMP2]} - - # 0th term is just C1 - - # Construct term 1 in E1 (E1 only appears in dword 1) - xor $E1,$E1,$D1 - xor $E1,$E1,$C1 - xor $E1,$E1,$C0 - - # Term 1 is E1 - - # Construct term 2 in E0 (E0 only appears in dword 2) - xor $E0,$E0,$D0 - xor $E0,$E0,$C0 - xor $E0,$E0,$D1 - - # Term 2 is E0 - - # final term is just D0 - - # X*H is now stored in [C1,E1,E0,D0] - - # Left-justify - slli $C1,$C1,1 - # Or in the high bit of E1 - srli $TEMP,$E1,63 - or $C1,$C1,$TEMP - - slli $E1,$E1,1 - # Or in the high bit of E0 - srli $TEMP2,$E0,63 - or $E1,$E1,$TEMP2 - - slli $E0,$E0,1 - # Or in the high bit of D0 - srli $TEMP,$D0,63 - or $E0,$E0,$TEMP - - slli $D0,$D0,1 - - # Barrett Reduction - # c = [E0, D0] - # We want the top 128 bits of the result of c*f - # We'll get this by computing the low-half (most significant 128 bits in - # the reflected domain) of clmul(c,fs)<<1 first, then - # xor in c to complete the calculation - - # AA = [AA1:AA0] = [E0,D0] = c - # BB = [BB1:BB0] = [qp_low,0] - # [CC1:CC0] = AA1*BB1 - # [DD1:DD0] = AA0*BB0 - # [EE1:EE0] = (AA0+AA1)*(BB0+BB1) - # Then: - # AA*BB = [CC1:CC0+CC1+DD1+EE1:DD1+CC0+DD0+EE0:DD0] - # We only need CC0,DD1,DD0,EE0 to compute the low 128 bits of c * qp_low +.p2align 3 +.globl gcm_gmult_rv64i_zbc +.type gcm_gmult_rv64i_zbc,\@function +gcm_gmult_rv64i_zbc: + # Load Xi and bit-reverse it + ld $x0, 0($Xi) + ld $x1, 8($Xi) + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + + # Load the key (already bit-reversed) + ld $y0, 0($Htable) + ld $y1, 8($Htable) + + # Load the reduction constant + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + + # Multiplication (without Karatsuba) + @{[clmulh $z3, $x1, $y1]} + @{[clmul $z2, $x1, $y1]} + @{[clmulh $t1, $x0, $y1]} + @{[clmul $z1, $x0, $y1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $y0]} + @{[clmul $t0, $x1, $y0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $y0]} + @{[clmul $z0, $x0, $y0]} + xor $z1, $z1, $t1 + + # Reduction with clmul + @{[clmulh $t1, $z3, $polymod]} + @{[clmul $t0, $z3, $polymod]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $polymod]} + @{[clmul $t0, $z2, $polymod]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + # Bit-reverse Xi back and store it + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + sd $x0, 0($Xi) + sd $x1, 8($Xi) + ret +.size gcm_gmult_rv64i_zbc,.-gcm_gmult_rv64i_zbc ___ +} -my ($CC0,$EE0,$AA1,$AA0,$BB1) = ($A0,$B1,$E0,$D0,$qp_low); +{ +my ($Xi,$Htable,$x0,$x1,$y0,$y1) = ("a0","a1","a4","a5","a6","a7"); +my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); $code .= <<___; - - @{[rv64_clmul $CC0,$AA1,$BB1]} - #clmul DD0,AA0,BB0 # BB0 is 0, so DD0 = 0 - #clmulh DD1,AA0,BB0 # BB0 is 0, so DD1 = 0 - xor $TEMP,$AA0,$AA1 - #xor TEMP2,BB0,BB1 # TEMP2 = BB1 = qp_low - @{[rv64_clmul $EE0,$TEMP,$BB1]} - - # Result is [N/A:N/A:DD1+CC0+DD0+EE0:DD0] - # Simplifying: [CC0+EE0:0] - xor $TEMP2,$CC0,$EE0 - # Shift left by 1 to correct for bit reflection - slli $TEMP2,$TEMP2,1 - - # xor into c = [E0,D0] - # Note that only E0 is affected - xor $E0,$E0,$TEMP2 - - # Now, q = [E0,D0] - - # The final step is to compute clmul(q,[qp_low:0])<<1 - # The leftmost 128 bits are the reduced result. - # Once again, we use Karatsuba multiplication, but many of the terms - # simplify or cancel out. - # AA = [AA1:AA0] = [E0,D0] = c - # BB = [BB1:BB0] = [qp_low,0] - # [CC1:CC0] = AA1*BB1 - # [DD1:DD0] = AA0*BB0 - # [EE1:EE0] = (AA0+AA1)*(BB0+BB1) - # Then: - # AA*BB = [CC1:CC0+CC1+DD1+EE1:DD1+CC0+DD0+EE0:DD0] - # We need CC1,CC0,DD0,DD1,EE1,EE0 to compute the leftmost 128 bits of AA*BB - +.p2align 3 +.globl gcm_gmult_rv64i_zbc__zbkb +.type gcm_gmult_rv64i_zbc__zbkb,\@function +gcm_gmult_rv64i_zbc__zbkb: + # Load Xi and bit-reverse it + ld $x0, 0($Xi) + ld $x1, 8($Xi) + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + + # Load the key (already bit-reversed) + ld $y0, 0($Htable) + ld $y1, 8($Htable) + + # Load the reduction constant + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + + # Multiplication (without Karatsuba) + @{[clmulh $z3, $x1, $y1]} + @{[clmul $z2, $x1, $y1]} + @{[clmulh $t1, $x0, $y1]} + @{[clmul $z1, $x0, $y1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $y0]} + @{[clmul $t0, $x1, $y0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $y0]} + @{[clmul $z0, $x0, $y0]} + xor $z1, $z1, $t1 + + # Reduction with clmul + @{[clmulh $t1, $z3, $polymod]} + @{[clmul $t0, $z3, $polymod]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $polymod]} + @{[clmul $t0, $z2, $polymod]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + # Bit-reverse Xi back and store it + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + sd $x0, 0($Xi) + sd $x1, 8($Xi) + ret +.size gcm_gmult_rv64i_zbc__zbkb,.-gcm_gmult_rv64i_zbc__zbkb ___ +} -my ($AA1,$AA0,$BB1,$CC1,$CC0,$EE1,$EE0) = ($E0,$D0,$qp_low,$A0,$A1,$C0,$B0); +################################################################################ +# void gcm_ghash_rv64i_zbc(u64 Xi[2], const u128 Htable[16], +# const u8 *inp, size_t len); +# void gcm_ghash_rv64i_zbc__zbkb(u64 Xi[2], const u128 Htable[16], +# const u8 *inp, size_t len); +# +# input: Xi: current hash value +# Htable: copy of H +# inp: pointer to input data +# len: length of input data in bytes (multiple of block size) +# output: Xi: Xi+1 (next hash value Xi) +{ +my ($Xi,$Htable,$inp,$len,$x0,$x1,$y0,$y1) = ("a0","a1","a2","a3","a4","a5","a6","a7"); +my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); $code .= <<___; +.p2align 3 +.globl gcm_ghash_rv64i_zbc +.type gcm_ghash_rv64i_zbc,\@function +gcm_ghash_rv64i_zbc: + # Load Xi and bit-reverse it + ld $x0, 0($Xi) + ld $x1, 8($Xi) + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + + # Load the key (already bit-reversed) + ld $y0, 0($Htable) + ld $y1, 8($Htable) + + # Load the reduction constant + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + +Lstep: + # Load the input data, bit-reverse them, and XOR them with Xi + ld $t0, 0($inp) + ld $t1, 8($inp) + add $inp, $inp, 16 + add $len, $len, -16 + @{[brev8_rv64i $t0, $z0, $z1, $z2]} + @{[brev8_rv64i $t1, $z0, $z1, $z2]} + xor $x0, $x0, $t0 + xor $x1, $x1, $t1 + + # Multiplication (without Karatsuba) + @{[clmulh $z3, $x1, $y1]} + @{[clmul $z2, $x1, $y1]} + @{[clmulh $t1, $x0, $y1]} + @{[clmul $z1, $x0, $y1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $y0]} + @{[clmul $t0, $x1, $y0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $y0]} + @{[clmul $z0, $x0, $y0]} + xor $z1, $z1, $t1 + + # Reduction with clmul + @{[clmulh $t1, $z3, $polymod]} + @{[clmul $t0, $z3, $polymod]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $polymod]} + @{[clmul $t0, $z2, $polymod]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + # Iterate over all blocks + bnez $len, Lstep + + # Bit-reverse final Xi back and store it + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + sd $x0, 0($Xi) + sd $x1, 8($Xi) + ret +.size gcm_ghash_rv64i_zbc,.-gcm_ghash_rv64i_zbc +___ +} - @{[rv64_clmul $CC0,$AA1,$BB1]} - @{[rv64_clmulh $CC1,$AA1,$BB1]} - - #clmul DD0,AA0,BB0 # BB0 = 0 so DD0 = 0 - #clmulh DD1,AA0,BB0 # BB0 = 0 so DD1 = 0 - - xor $TEMP,$AA0,$AA1 - #xor TEMP2,BB0,BB1 # BB0 = 0 to TEMP2 == BB1 == qp_low - - @{[rv64_clmul $EE0,$TEMP,$BB1]} - @{[rv64_clmulh $EE1,$TEMP,$BB1]} - - # Need the DD1+CC0+DD0+EE0 term to shift its leftmost bit into the - # intermediate result. - # This is just CC0+EE0, store it in TEMP - xor $TEMP,$CC0,$EE0 - - # Result is [CC1:CC0+CC1+EE1:(a single bit)]<<1 - # Combine into [CC1:CC0] - xor $CC0,$CC0,$CC1 - xor $CC0,$CC0,$EE1 - - # Shift 128-bit quantity, xor in [C1,E1] and store - slli $CC1,$CC1,1 - srli $TEMP2,$CC0,63 - or $CC1,$CC1,$TEMP2 - # xor in C1 - xor $CC1,$CC1,$C1 - @{[rv64_rev8 $CC1,$CC1]} - - slli $CC0,$CC0,1 - srli $TEMP,$TEMP,63 - or $CC0,$CC0,$TEMP - # xor in E1 - xor $CC0,$CC0,$E1 - @{[rv64_rev8 $CC0,$CC0]} - sd $CC1,0(a0) - sd $CC0,8(a0) +{ +my ($Xi,$Htable,$inp,$len,$x0,$x1,$y0,$y1) = ("a0","a1","a2","a3","a4","a5","a6","a7"); +my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); +$code .= <<___; +.p2align 3 +.globl gcm_ghash_rv64i_zbc__zbkb +.type gcm_ghash_rv64i_zbc__zbkb,\@function +gcm_ghash_rv64i_zbc__zbkb: + # Load Xi and bit-reverse it + ld $x0, 0($Xi) + ld $x1, 8($Xi) + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + + # Load the key (already bit-reversed) + ld $y0, 0($Htable) + ld $y1, 8($Htable) + + # Load the reduction constant + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + +Lstep_zkbk: + # Load the input data, bit-reverse them, and XOR them with Xi + ld $t0, 0($inp) + ld $t1, 8($inp) + add $inp, $inp, 16 + add $len, $len, -16 + @{[brev8 $t0, $t0]} + @{[brev8 $t1, $t1]} + xor $x0, $x0, $t0 + xor $x1, $x1, $t1 + + # Multiplication (without Karatsuba) + @{[clmulh $z3, $x1, $y1]} + @{[clmul $z2, $x1, $y1]} + @{[clmulh $t1, $x0, $y1]} + @{[clmul $z1, $x0, $y1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $y0]} + @{[clmul $t0, $x1, $y0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $y0]} + @{[clmul $z0, $x0, $y0]} + xor $z1, $z1, $t1 + + # Reduction with clmul + @{[clmulh $t1, $z3, $polymod]} + @{[clmul $t0, $z3, $polymod]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $polymod]} + @{[clmul $t0, $z2, $polymod]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + # Iterate over all blocks + bnez $len, Lstep_zkbk + + # Bit-reverse final Xi back and store it + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + sd $x0, 0($Xi) + sd $x1, 8($Xi) ret +.size gcm_ghash_rv64i_zbc__zbkb,.-gcm_ghash_rv64i_zbc__zbkb ___ - } +$code .= <<___; +.p2align 3 +Lbrev8_const: + .dword 0xAAAAAAAAAAAAAAAA + .dword 0xCCCCCCCCCCCCCCCC + .dword 0xF0F0F0F0F0F0F0F0 +.size Lbrev8_const,.-Lbrev8_const + +Lpolymod: + .byte 0x87 +.size Lpolymod,.-Lpolymod +___ + print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/modes/asm/ghash-s390x.pl b/crypto/modes/asm/ghash-s390x.pl index 9e746d55ac..0ae6adbf61 100644 --- a/crypto/modes/asm/ghash-s390x.pl +++ b/crypto/modes/asm/ghash-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/build.info b/crypto/modes/build.info index d46e424c2b..c79f75c5c4 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -55,7 +55,7 @@ IF[{- !$disabled{asm} -}] ENDIF $COMMON=cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c xts128.c \ - wrap128.c $MODESASM + wrap128.c xts128gb.c $MODESASM SOURCE[../../libcrypto]=$COMMON \ cts128.c ocb128.c siv128.c SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c index 39994eeb95..77ff5dd06b 100644 --- a/crypto/modes/gcm128.c +++ b/crypto/modes/gcm128.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,9 +27,10 @@ typedef size_t size_t_aX; # define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) #endif -/* RISC-V uses C implementation of gmult as a fallback. */ +/* RISC-V uses C implementation as a fallback. */ #if defined(__riscv) # define INCLUDE_C_GMULT_4BIT +# define INCLUDE_C_GHASH_4BIT #endif #define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) @@ -48,7 +49,7 @@ typedef size_t size_t_aX; /*- * - * NOTE: TABLE_BITS and all non-4bit implmentations have been removed in 3.1. + * NOTE: TABLE_BITS and all non-4bit implementations have been removed in 3.1. * * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should * never be set to 8. 8 is effectively reserved for testing purposes. @@ -232,7 +233,7 @@ static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) # endif -# if !defined(GHASH_ASM) +# if !defined(GHASH_ASM) || defined(INCLUDE_C_GHASH_4BIT) # if !defined(OPENSSL_SMALL_FOOTPRINT) /* * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for @@ -311,7 +312,11 @@ static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], Xi[0] = Z.hi; Xi[1] = Z.lo; } - } while (inp += 16, len -= 16); + + inp += 16; + /* Block size is 128 bits so len is a multiple of 16 */ + len -= 16; + } while (len > 0); } # endif # else @@ -364,7 +369,7 @@ void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); # endif -# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) +# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(_M_ARM64) # include "arm_arch.h" # if __ARM_MAX_ARCH__>=7 # define GHASH_ASM_ARM @@ -397,10 +402,17 @@ void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); # elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64 # include "crypto/riscv_arch.h" -# define GHASH_ASM_RISCV -# undef GHASH -void gcm_init_clmul_rv64i_zbb_zbc(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_clmul_rv64i_zbb_zbc(u64 Xi[2], const u128 Htable[16]); +# define GHASH_ASM_RV64I +/* Zbc/Zbkc (scalar crypto with clmul) based routines. */ +void gcm_init_rv64i_zbc(u128 Htable[16], const u64 Xi[2]); +void gcm_init_rv64i_zbc__zbb(u128 Htable[16], const u64 Xi[2]); +void gcm_init_rv64i_zbc__zbkb(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_rv64i_zbc(u64 Xi[2], const u128 Htable[16]); +void gcm_gmult_rv64i_zbc__zbkb(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_rv64i_zbc(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len); +void gcm_ghash_rv64i_zbc__zbkb(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len); # endif #endif @@ -408,7 +420,7 @@ static void gcm_get_funcs(struct gcm_funcs_st *ctx) { /* set defaults -- overridden below as needed */ ctx->ginit = gcm_init_4bit; -#if !defined(GHASH_ASM) || defined(INCLUDE_C_GMULT_4BIT) +#if !defined(GHASH_ASM) ctx->gmult = gcm_gmult_4bit; #else ctx->gmult = NULL; @@ -495,12 +507,25 @@ static void gcm_get_funcs(struct gcm_funcs_st *ctx) ctx->ghash = gcm_ghash_p8; } return; -#elif defined(GHASH_ASM_RISCV) && __riscv_xlen == 64 - /* RISCV defaults; gmult already set above */ - ctx->ghash = NULL; - if (RISCV_HAS_ZBB() && RISCV_HAS_ZBC()) { - ctx->ginit = gcm_init_clmul_rv64i_zbb_zbc; - ctx->gmult = gcm_gmult_clmul_rv64i_zbb_zbc; +#elif defined(GHASH_ASM_RV64I) + /* RISCV defaults */ + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; + + if (RISCV_HAS_ZBC()) { + if (RISCV_HAS_ZBKB()) { + ctx->ginit = gcm_init_rv64i_zbc__zbkb; + ctx->gmult = gcm_gmult_rv64i_zbc__zbkb; + ctx->ghash = gcm_ghash_rv64i_zbc__zbkb; + } else if (RISCV_HAS_ZBB()) { + ctx->ginit = gcm_init_rv64i_zbc__zbb; + ctx->gmult = gcm_gmult_rv64i_zbc; + ctx->ghash = gcm_ghash_rv64i_zbc; + } else { + ctx->ginit = gcm_init_rv64i_zbc; + ctx->gmult = gcm_gmult_rv64i_zbc; + ctx->ghash = gcm_ghash_rv64i_zbc; + } } return; #elif defined(GHASH_ASM) @@ -511,6 +536,43 @@ static void gcm_get_funcs(struct gcm_funcs_st *ctx) #endif } +void ossl_gcm_init_4bit(u128 Htable[16], const u64 H[2]) +{ + struct gcm_funcs_st funcs; + + gcm_get_funcs(&funcs); + funcs.ginit(Htable, H); +} + +void ossl_gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) +{ + struct gcm_funcs_st funcs; + + gcm_get_funcs(&funcs); + funcs.gmult(Xi, Htable); +} + +void ossl_gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) +{ + struct gcm_funcs_st funcs; + u64 tmp[2]; + size_t i; + + gcm_get_funcs(&funcs); + if (funcs.ghash != NULL) { + funcs.ghash(Xi, Htable, inp, len); + } else { + /* Emulate ghash if needed */ + for (i = 0; i < len; i += 16) { + memcpy(tmp, &inp[i], sizeof(tmp)); + Xi[0] ^= tmp[0]; + Xi[1] ^= tmp[1]; + funcs.gmult(Xi, Htable); + } + } +} + void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) { DECLARE_IS_ENDIAN; diff --git a/crypto/modes/ocb128.c b/crypto/modes/ocb128.c index b5202ba5bd..1ae807c100 100644 --- a/crypto/modes/ocb128.c +++ b/crypto/modes/ocb128.c @@ -155,10 +155,8 @@ int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, memset(ctx, 0, sizeof(*ctx)); ctx->l_index = 0; ctx->max_l_index = 5; - if ((ctx->l = OPENSSL_malloc(ctx->max_l_index * 16)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((ctx->l = OPENSSL_malloc(ctx->max_l_index * 16)) == NULL) return 0; - } /* * We set both the encryption and decryption key schedules - decryption @@ -202,10 +200,8 @@ int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, if (keydec) dest->keydec = keydec; if (src->l) { - if ((dest->l = OPENSSL_malloc(src->max_l_index * 16)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((dest->l = OPENSSL_malloc(src->max_l_index * 16)) == NULL) return 0; - } memcpy(dest->l, src->l, (src->l_index + 1) * 16); } return 1; diff --git a/crypto/modes/xts128gb.c b/crypto/modes/xts128gb.c new file mode 100644 index 0000000000..021c0597e4 --- /dev/null +++ b/crypto/modes/xts128gb.c @@ -0,0 +1,199 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/endian.h" +#include "crypto/modes.h" + +#ifndef STRICT_ALIGNMENT +# ifdef __GNUC__ +typedef u64 u64_a1 __attribute((__aligned__(1))); +# else +typedef u64 u64_a1; +# endif +#endif + +int ossl_crypto_xts128gb_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc) +{ + DECLARE_IS_ENDIAN; + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + } tweak, scratch; + unsigned int i; + + if (len < 16) + return -1; + + memcpy(tweak.c, iv, 16); + + (*ctx->block2) (tweak.c, tweak.c, ctx->key2); + + if (!enc && (len % 16)) + len -= 16; + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; +#else + scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64_a1 *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((u64_a1 *)out)[1] = scratch.u[1] ^= tweak.u[1]; +#endif + inp += 16; + out += 16; + len -= 16; + + if (len == 0) + return 0; + + if (IS_LITTLE_ENDIAN) { + u8 res; + u64 hi, lo; +#ifdef BSWAP8 + hi = BSWAP8(tweak.u[0]); + lo = BSWAP8(tweak.u[1]); +#else + u8 *p = tweak.c; + + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + res = (u8)lo & 1; + tweak.u[0] = (lo >> 1) | (hi << 63); + tweak.u[1] = hi >> 1; + if (res) + tweak.c[15] ^= 0xe1; +#ifdef BSWAP8 + hi = BSWAP8(tweak.u[0]); + lo = BSWAP8(tweak.u[1]); +#else + p = tweak.c; + + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + tweak.u[0] = lo; + tweak.u[1] = hi; + } else { + u8 carry, res; + carry = 0; + for (i = 0; i < 16; ++i) { + res = (tweak.c[i] << 7) & 0x80; + tweak.c[i] = ((tweak.c[i] >> 1) + carry) & 0xff; + carry = res; + } + if (res) + tweak.c[0] ^= 0xe1; + } + } + if (enc) { + for (i = 0; i < len; ++i) { + u8 c = inp[i]; + out[i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out - 16, scratch.c, 16); + } else { + union { + u64 u[2]; + u8 c[16]; + } tweak1; + + if (IS_LITTLE_ENDIAN) { + u8 res; + u64 hi, lo; +#ifdef BSWAP8 + hi = BSWAP8(tweak.u[0]); + lo = BSWAP8(tweak.u[1]); +#else + u8 *p = tweak.c; + + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + res = (u8)lo & 1; + tweak1.u[0] = (lo >> 1) | (hi << 63); + tweak1.u[1] = hi >> 1; + if (res) + tweak1.c[15] ^= 0xe1; +#ifdef BSWAP8 + hi = BSWAP8(tweak1.u[0]); + lo = BSWAP8(tweak1.u[1]); +#else + p = tweak1.c; + + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + tweak1.u[0] = lo; + tweak1.u[1] = hi; + } else { + u8 carry, res; + carry = 0; + for (i = 0; i < 16; ++i) { + res = (tweak.c[i] << 7) & 0x80; + tweak1.c[i] = ((tweak.c[i] >> 1) + carry) & 0xff; + carry = res; + } + if (res) + tweak1.c[0] ^= 0xe1; + } +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; +#else + scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak1.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; + + for (i = 0; i < len; ++i) { + u8 c = inp[16 + i]; + out[16 + i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64_a1 *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((u64_a1 *)out)[1] = scratch.u[1] ^ tweak.u[1]; +#endif + } + + return 0; +} diff --git a/crypto/o_fopen.c b/crypto/o_fopen.c index 337985c62f..09c28e0bf7 100644 --- a/crypto/o_fopen.c +++ b/crypto/o_fopen.c @@ -87,10 +87,8 @@ FILE *openssl_fopen(const char *filename, const char *mode) char *iterator; char lastchar; - if ((newname = OPENSSL_malloc(strlen(filename) + 1)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((newname = OPENSSL_malloc(strlen(filename) + 1)) == NULL) return NULL; - } for (iterator = newname, lastchar = '\0'; *filename; filename++, iterator++) { diff --git a/crypto/o_str.c b/crypto/o_str.c index 3354ce0927..f1aacda5e3 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -56,10 +56,8 @@ void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) return NULL; ret = CRYPTO_malloc(siz, file, line); - if (ret == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } return memcpy(ret, data, siz); } @@ -196,10 +194,8 @@ unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen, return NULL; } buf_n /= 2; - if ((buf = OPENSSL_malloc(buf_n)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(buf_n)) == NULL) return NULL; - } if (buflen != NULL) *buflen = 0; @@ -272,10 +268,8 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) return OPENSSL_zalloc(1); tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2; - if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) return NULL; - } if (buf2hexstr_sep(tmp, tmp_n, NULL, buf, buflen, sep)) return tmp; @@ -285,13 +279,13 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) /* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) + * Given a buffer of length 'buflen' return a OPENSSL_malloc'ed string with + * its hex representation @@@ (Contents of buffer are always kept in ASCII, + * also on EBCDIC machines) */ char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) { - return ossl_buf2hexstr_sep(buf, buflen, ':'); + return ossl_buf2hexstr_sep(buf, buflen, DEFAULT_SEPARATOR); } int openssl_strerror_r(int errnum, char *buf, size_t buflen) diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c index 1efa0345fb..5a468bba3a 100644 --- a/crypto/objects/o_names.c +++ b/crypto/objects/o_names.c @@ -89,7 +89,6 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { name_funcs = OPENSSL_zalloc(sizeof(*name_funcs)); if (name_funcs == NULL) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); ret = 0; goto out; } @@ -98,7 +97,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); if (!push) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_CRYPTO_LIB); OPENSSL_free(name_funcs); ret = 0; goto out; diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index ec78962d7b..b0e1032ec2 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -20,17 +20,9 @@ #include "crypto/asn1.h" #include "obj_local.h" -/* obj_dat.h is generated from objects.h by obj_dat.pl */ +/* obj_dat.h is generated from objects.txt and obj_mac.{num,h} by obj_dat.pl */ #include "obj_dat.h" -/* - * If we don't have suitable TSAN support, we'll use a lock for generation of - * new NIDs. This will be slower of course. - */ -#ifndef tsan_ld_acq -# define OBJ_USE_LOCK_FOR_NEW_NID -#endif - DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); @@ -47,7 +39,7 @@ struct added_obj_st { static LHASH_OF(ADDED_OBJ) *added = NULL; static CRYPTO_RWLOCK *ossl_obj_lock = NULL; -#ifdef OBJ_USE_LOCK_FOR_NEW_NID +#ifdef TSAN_REQUIRES_LOCKING static CRYPTO_RWLOCK *ossl_obj_nid_lock = NULL; #endif @@ -57,7 +49,7 @@ static ossl_inline void objs_free_locks(void) { CRYPTO_THREAD_lock_free(ossl_obj_lock); ossl_obj_lock = NULL; -#ifdef OBJ_USE_LOCK_FOR_NEW_NID +#ifdef TSAN_REQUIRES_LOCKING CRYPTO_THREAD_lock_free(ossl_obj_nid_lock); ossl_obj_nid_lock = NULL; #endif @@ -69,7 +61,7 @@ DEFINE_RUN_ONCE_STATIC(obj_lock_initialise) if (ossl_obj_lock == NULL) return 0; -#ifdef OBJ_USE_LOCK_FOR_NEW_NID +#ifdef TSAN_REQUIRES_LOCKING ossl_obj_nid_lock = CRYPTO_THREAD_lock_new(); if (ossl_obj_nid_lock == NULL) { objs_free_locks(); @@ -235,8 +227,8 @@ void ossl_obj_cleanup_int(void) */ static int obj_new_nid_unlocked(int num) { -#ifdef OBJ_USE_LOCK_FOR_NEW_NID - static int new_nid = NUM_NID; + static TSAN_QUALIFIER int new_nid = NUM_NID; +#ifdef TSAN_REQUIRES_LOCKING int i; i = new_nid; @@ -244,8 +236,6 @@ static int obj_new_nid_unlocked(int num) return i; #else - static TSAN_QUALIFIER int new_nid = NUM_NID; - return tsan_add(&new_nid, num); #endif } @@ -285,10 +275,8 @@ static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock) || (o->sn != NULL && (ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL) || (o->ln != NULL - && (ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); + && (ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)) goto err2; - } if (!ossl_obj_write_lock(lock)) { ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK); @@ -297,7 +285,7 @@ static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock) if (added == NULL) { added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp); if (added == NULL) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OBJ, ERR_R_CRYPTO_LIB); goto err; } } @@ -430,8 +418,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) int i, j; if (!no_name) { - if ((nid = OBJ_sn2nid(s)) != NID_undef || - (nid = OBJ_ln2nid(s)) != NID_undef) { + if ((nid = OBJ_sn2nid(s)) != NID_undef + || (nid = OBJ_ln2nid(s)) != NID_undef) { return OBJ_nid2obj(nid); } if (!ossl_isdigit(*s)) { @@ -450,10 +438,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) if (j < 0) return NULL; - if ((buf = OPENSSL_malloc(j)) == NULL) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(j)) == NULL) return NULL; - } p = buf; /* Write out tag+length */ @@ -524,17 +510,19 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) use_bn = 0; for (;;) { unsigned char c = *p++; + len--; - if ((len == 0) && (c & 0x80)) + if (len == 0 && (c & 0x80) != 0) goto err; if (use_bn) { if (!BN_add_word(bl, c & 0x7f)) goto err; - } else + } else { l |= c & 0x7f; - if (!(c & 0x80)) + } + if ((c & 0x80) == 0) break; - if (!use_bn && (l > (ULONG_MAX >> 7L))) { + if (!use_bn && l > (ULONG_MAX >> 7L)) { if (bl == NULL && (bl = BN_new()) == NULL) goto err; if (!BN_set_word(bl, l)) @@ -544,8 +532,9 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) if (use_bn) { if (!BN_lshift(bl, bl, 7)) goto err; - } else + } else { l <<= 7L; + } } if (first) { @@ -555,13 +544,14 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) if (use_bn) { if (!BN_sub_word(bl, 80)) goto err; - } else + } else { l -= 80; + } } else { i = (int)(l / 40); l -= (long)(i * 40); } - if (buf && (buf_len > 1)) { + if (buf != NULL && buf_len > 1) { *buf++ = i + '0'; *buf = '\0'; buf_len--; @@ -575,7 +565,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) if (!bndec) goto err; i = strlen(bndec); - if (buf) { + if (buf != NULL) { if (buf_len > 1) { *buf++ = '.'; *buf = '\0'; @@ -596,7 +586,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) } else { BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); i = strlen(tbuf); - if (buf && (buf_len > 0)) { + if (buf && buf_len > 0) { OPENSSL_strlcpy(buf, tbuf, buf_len); if (i > buf_len) { buf += buf_len; @@ -779,6 +769,12 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) ASN1_OBJECT *tmpoid = NULL; int ok = 0; + /* With no arguments at all, nothing can be done */ + if (oid == NULL && sn == NULL && ln == NULL) { + ERR_raise(ERR_LIB_OBJ, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + /* Check to see if short or long name already present */ if ((sn != NULL && OBJ_sn2nid(sn) != NID_undef) || (ln != NULL && OBJ_ln2nid(ln) != NID_undef)) { @@ -786,10 +782,15 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) return 0; } - /* Convert numerical OID string to an ASN1_OBJECT structure */ - tmpoid = OBJ_txt2obj(oid, 1); - if (tmpoid == NULL) - return 0; + if (oid != NULL) { + /* Convert numerical OID string to an ASN1_OBJECT structure */ + tmpoid = OBJ_txt2obj(oid, 1); + if (tmpoid == NULL) + return 0; + } else { + /* Create a no-OID ASN1_OBJECT */ + tmpoid = ASN1_OBJECT_new(); + } if (!ossl_obj_write_lock(1)) { ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK); @@ -798,7 +799,8 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) } /* If NID is not NID_undef then object already exists */ - if (ossl_obj_obj2nid(tmpoid, 0) != NID_undef) { + if (oid != NULL + && ossl_obj_obj2nid(tmpoid, 0) != NID_undef) { ERR_raise(ERR_LIB_OBJ, OBJ_R_OID_EXISTS); goto err; } diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 59d156117a..5292db3f07 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/obj_dat.pl * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[8076] = { +static const unsigned char so[8476] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1115,9 +1115,76 @@ static const unsigned char so[8076] = { 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0D, /* [ 8045] OBJ_rpkiNotify */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x2F, /* [ 8053] OBJ_id_ct_geofeedCSVwithCRLF */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x30, /* [ 8064] OBJ_id_ct_signedChecklist */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x08, /* [ 8075] OBJ_sm4_gcm */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x09, /* [ 8083] OBJ_sm4_ccm */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x31, /* [ 8091] OBJ_id_ct_ASPA */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x32, /* [ 8102] OBJ_id_mod_cmp2000_02 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x63, /* [ 8110] OBJ_id_mod_cmp2021_88 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x64, /* [ 8118] OBJ_id_mod_cmp2021_02 */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x14, /* [ 8126] OBJ_id_it_rootCaCert */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x15, /* [ 8134] OBJ_id_it_certProfile */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x16, /* [ 8142] OBJ_id_it_crlStatusList */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x17, /* [ 8150] OBJ_id_it_crls */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x07, /* [ 8158] OBJ_id_regCtrl_altCertTemplate */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x0B, /* [ 8167] OBJ_id_regCtrl_algId */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x0C, /* [ 8176] OBJ_id_regCtrl_rsaKeyLen */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2C, /* [ 8185] OBJ_id_aa_ets_attrCertificateRefs */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2D, /* [ 8196] OBJ_id_aa_ets_attrRevocationRefs */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x34, /* [ 8207] OBJ_id_aa_CMSAlgorithmProtection */ + 0x04, /* [ 8216] OBJ_itu_t_identified_organization */ + 0x04,0x00, /* [ 8217] OBJ_etsi */ + 0x04,0x00,0x8D,0x45, /* [ 8219] OBJ_electronic_signature_standard */ + 0x04,0x00,0x8D,0x45,0x02, /* [ 8223] OBJ_ess_attributes */ + 0x04,0x00,0x8D,0x45,0x02,0x01, /* [ 8228] OBJ_id_aa_ets_mimeType */ + 0x04,0x00,0x8D,0x45,0x02,0x02, /* [ 8234] OBJ_id_aa_ets_longTermValidation */ + 0x04,0x00,0x8D,0x45,0x02,0x03, /* [ 8240] OBJ_id_aa_ets_SignaturePolicyDocument */ + 0x04,0x00,0x8D,0x45,0x02,0x04, /* [ 8246] OBJ_id_aa_ets_archiveTimestampV3 */ + 0x04,0x00,0x8D,0x45,0x02,0x05, /* [ 8252] OBJ_id_aa_ATSHashIndex */ + 0x04,0x00,0x81,0x95,0x32, /* [ 8258] OBJ_cades */ + 0x04,0x00,0x81,0x95,0x32,0x01, /* [ 8263] OBJ_cades_attributes */ + 0x04,0x00,0x81,0x95,0x32,0x01,0x01, /* [ 8269] OBJ_id_aa_ets_signerAttrV2 */ + 0x04,0x00,0x81,0x95,0x32,0x01,0x03, /* [ 8276] OBJ_id_aa_ets_sigPolicyStore */ + 0x04,0x00,0x81,0x95,0x32,0x01,0x04, /* [ 8283] OBJ_id_aa_ATSHashIndex_v2 */ + 0x04,0x00,0x81,0x95,0x32,0x01,0x05, /* [ 8290] OBJ_id_aa_ATSHashIndex_v3 */ + 0x04,0x00,0x81,0x95,0x32,0x01,0x06, /* [ 8297] OBJ_signedAssertion */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x30, /* [ 8304] OBJ_id_aa_ets_archiveTimestampV2 */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,0x03,0x01, /* [ 8315] OBJ_hmacWithSM3 */ + 0x60,0x86,0x48,0x01,0x86,0xF9,0x66, /* [ 8325] OBJ_oracle */ + 0x60,0x86,0x48,0x01,0x86,0xF9,0x66,0xAD,0xCA,0x7B,0x01,0x01, /* [ 8332] OBJ_oracle_jdk_trustedkeyusage */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x32, /* [ 8344] OBJ_id_ct_signedTAL */ + 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x0A, /* [ 8355] OBJ_sm4_xts */ + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x19,0x02,0x01, /* [ 8363] OBJ_ms_ntds_obj_sid */ + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x19,0x02, /* [ 8373] OBJ_ms_ntds_sec_ext */ + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x15,0x07, /* [ 8382] OBJ_ms_cert_templ */ + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x15,0x0A, /* [ 8391] OBJ_ms_app_policies */ + 0x55,0x1D,0x26, /* [ 8400] OBJ_authority_attribute_identifier */ + 0x55,0x1D,0x27, /* [ 8403] OBJ_role_spec_cert_identifier */ + 0x55,0x1D,0x29, /* [ 8406] OBJ_basic_att_constraints */ + 0x55,0x1D,0x2A, /* [ 8409] OBJ_delegated_name_constraints */ + 0x55,0x1D,0x2B, /* [ 8412] OBJ_time_specification */ + 0x55,0x1D,0x30, /* [ 8415] OBJ_attribute_descriptor */ + 0x55,0x1D,0x31, /* [ 8418] OBJ_user_notice */ + 0x55,0x1D,0x32, /* [ 8421] OBJ_soa_identifier */ + 0x55,0x1D,0x34, /* [ 8424] OBJ_acceptable_cert_policies */ + 0x55,0x1D,0x39, /* [ 8427] OBJ_acceptable_privilege_policies */ + 0x55,0x1D,0x3D, /* [ 8430] OBJ_indirect_issuer */ + 0x55,0x1D,0x3E, /* [ 8433] OBJ_no_assertion */ + 0x55,0x1D,0x3F, /* [ 8436] OBJ_id_aa_issuing_distribution_point */ + 0x55,0x1D,0x40, /* [ 8439] OBJ_issued_on_behalf_of */ + 0x55,0x1D,0x41, /* [ 8442] OBJ_single_use */ + 0x55,0x1D,0x42, /* [ 8445] OBJ_group_ac */ + 0x55,0x1D,0x43, /* [ 8448] OBJ_allowed_attribute_assignments */ + 0x55,0x1D,0x44, /* [ 8451] OBJ_attribute_mappings */ + 0x55,0x1D,0x45, /* [ 8454] OBJ_holder_name_constraints */ + 0x55,0x1D,0x46, /* [ 8457] OBJ_authorization_validation */ + 0x55,0x1D,0x47, /* [ 8460] OBJ_prot_restrict */ + 0x55,0x1D,0x48, /* [ 8463] OBJ_subject_alt_public_key_info */ + 0x55,0x1D,0x49, /* [ 8466] OBJ_alt_signature_algorithm */ + 0x55,0x1D,0x4A, /* [ 8469] OBJ_alt_signature_value */ + 0x55,0x1D,0x4B, /* [ 8472] OBJ_associated_information */ }; -#define NUM_NID 1248 +#define NUM_NID 1320 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2367,9 +2434,81 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"rpkiNotify", "RPKI Notify", NID_rpkiNotify, 8, &so[8045]}, {"id-ct-geofeedCSVwithCRLF", "id-ct-geofeedCSVwithCRLF", NID_id_ct_geofeedCSVwithCRLF, 11, &so[8053]}, {"id-ct-signedChecklist", "id-ct-signedChecklist", NID_id_ct_signedChecklist, 11, &so[8064]}, + {"SM4-GCM", "sm4-gcm", NID_sm4_gcm, 8, &so[8075]}, + {"SM4-CCM", "sm4-ccm", NID_sm4_ccm, 8, &so[8083]}, + {"id-ct-ASPA", "id-ct-ASPA", NID_id_ct_ASPA, 11, &so[8091]}, + {"id-mod-cmp2000-02", "id-mod-cmp2000-02", NID_id_mod_cmp2000_02, 8, &so[8102]}, + {"id-mod-cmp2021-88", "id-mod-cmp2021-88", NID_id_mod_cmp2021_88, 8, &so[8110]}, + {"id-mod-cmp2021-02", "id-mod-cmp2021-02", NID_id_mod_cmp2021_02, 8, &so[8118]}, + {"id-it-rootCaCert", "id-it-rootCaCert", NID_id_it_rootCaCert, 8, &so[8126]}, + {"id-it-certProfile", "id-it-certProfile", NID_id_it_certProfile, 8, &so[8134]}, + {"id-it-crlStatusList", "id-it-crlStatusList", NID_id_it_crlStatusList, 8, &so[8142]}, + {"id-it-crls", "id-it-crls", NID_id_it_crls, 8, &so[8150]}, + {"id-regCtrl-altCertTemplate", "id-regCtrl-altCertTemplate", NID_id_regCtrl_altCertTemplate, 9, &so[8158]}, + {"id-regCtrl-algId", "id-regCtrl-algId", NID_id_regCtrl_algId, 9, &so[8167]}, + {"id-regCtrl-rsaKeyLen", "id-regCtrl-rsaKeyLen", NID_id_regCtrl_rsaKeyLen, 9, &so[8176]}, + {"id-aa-ets-attrCertificateRefs", "id-aa-ets-attrCertificateRefs", NID_id_aa_ets_attrCertificateRefs, 11, &so[8185]}, + {"id-aa-ets-attrRevocationRefs", "id-aa-ets-attrRevocationRefs", NID_id_aa_ets_attrRevocationRefs, 11, &so[8196]}, + {"id-aa-CMSAlgorithmProtection", "id-aa-CMSAlgorithmProtection", NID_id_aa_CMSAlgorithmProtection, 9, &so[8207]}, + {"itu-t-identified-organization", "itu-t-identified-organization", NID_itu_t_identified_organization, 1, &so[8216]}, + {"etsi", "etsi", NID_etsi, 2, &so[8217]}, + {"electronic-signature-standard", "electronic-signature-standard", NID_electronic_signature_standard, 4, &so[8219]}, + {"ess-attributes", "ess-attributes", NID_ess_attributes, 5, &so[8223]}, + {"id-aa-ets-mimeType", "id-aa-ets-mimeType", NID_id_aa_ets_mimeType, 6, &so[8228]}, + {"id-aa-ets-longTermValidation", "id-aa-ets-longTermValidation", NID_id_aa_ets_longTermValidation, 6, &so[8234]}, + {"id-aa-ets-SignaturePolicyDocument", "id-aa-ets-SignaturePolicyDocument", NID_id_aa_ets_SignaturePolicyDocument, 6, &so[8240]}, + {"id-aa-ets-archiveTimestampV3", "id-aa-ets-archiveTimestampV3", NID_id_aa_ets_archiveTimestampV3, 6, &so[8246]}, + {"id-aa-ATSHashIndex", "id-aa-ATSHashIndex", NID_id_aa_ATSHashIndex, 6, &so[8252]}, + {"cades", "cades", NID_cades, 5, &so[8258]}, + {"cades-attributes", "cades-attributes", NID_cades_attributes, 6, &so[8263]}, + {"id-aa-ets-signerAttrV2", "id-aa-ets-signerAttrV2", NID_id_aa_ets_signerAttrV2, 7, &so[8269]}, + {"id-aa-ets-sigPolicyStore", "id-aa-ets-sigPolicyStore", NID_id_aa_ets_sigPolicyStore, 7, &so[8276]}, + {"id-aa-ATSHashIndex-v2", "id-aa-ATSHashIndex-v2", NID_id_aa_ATSHashIndex_v2, 7, &so[8283]}, + {"id-aa-ATSHashIndex-v3", "id-aa-ATSHashIndex-v3", NID_id_aa_ATSHashIndex_v3, 7, &so[8290]}, + {"signedAssertion", "signedAssertion", NID_signedAssertion, 7, &so[8297]}, + {"id-aa-ets-archiveTimestampV2", "id-aa-ets-archiveTimestampV2", NID_id_aa_ets_archiveTimestampV2, 11, &so[8304]}, + {"hmacWithSM3", "hmacWithSM3", NID_hmacWithSM3, 10, &so[8315]}, + {"oracle-organization", "Oracle organization", NID_oracle, 7, &so[8325]}, + {"oracle-jdk-trustedkeyusage", "Trusted key usage (Oracle)", NID_oracle_jdk_trustedkeyusage, 12, &so[8332]}, + {"id-ct-signedTAL", "id-ct-signedTAL", NID_id_ct_signedTAL, 11, &so[8344]}, + {"brainpoolP256r1tls13", "brainpoolP256r1tls13", NID_brainpoolP256r1tls13}, + {"brainpoolP384r1tls13", "brainpoolP384r1tls13", NID_brainpoolP384r1tls13}, + {"brainpoolP512r1tls13", "brainpoolP512r1tls13", NID_brainpoolP512r1tls13}, + {"brotli", "Brotli compression", NID_brotli}, + {"zstd", "Zstandard compression", NID_zstd}, + {"SM4-XTS", "sm4-xts", NID_sm4_xts, 8, &so[8355]}, + {"ms-ntds-obj-sid", "Microsoft NTDS AD objectSid", NID_ms_ntds_obj_sid, 10, &so[8363]}, + {"ms-ntds-sec-ext", "Microsoft NTDS CA Extension", NID_ms_ntds_sec_ext, 9, &so[8373]}, + {"ms-cert-templ", "Microsoft certificate template", NID_ms_cert_templ, 9, &so[8382]}, + {"ms-app-policies", "Microsoft Application Policies Extension", NID_ms_app_policies, 9, &so[8391]}, + {"authorityAttributeIdentifier", "X509v3 Authority Attribute Identifier", NID_authority_attribute_identifier, 3, &so[8400]}, + {"roleSpecCertIdentifier", "X509v3 Role Specification Certificate Identifier", NID_role_spec_cert_identifier, 3, &so[8403]}, + {"basicAttConstraints", "X509v3 Basic Attribute Certificate Constraints", NID_basic_att_constraints, 3, &so[8406]}, + {"delegatedNameConstraints", "X509v3 Delegated Name Constraints", NID_delegated_name_constraints, 3, &so[8409]}, + {"timeSpecification", "X509v3 Time Specification", NID_time_specification, 3, &so[8412]}, + {"attributeDescriptor", "X509v3 Attribute Descriptor", NID_attribute_descriptor, 3, &so[8415]}, + {"userNotice", "X509v3 User Notice", NID_user_notice, 3, &so[8418]}, + {"sOAIdentifier", "X509v3 Source of Authority Identifier", NID_soa_identifier, 3, &so[8421]}, + {"acceptableCertPolicies", "X509v3 Acceptable Certification Policies", NID_acceptable_cert_policies, 3, &so[8424]}, + {"acceptablePrivPolicies", "X509v3 Acceptable Privilege Policies", NID_acceptable_privilege_policies, 3, &so[8427]}, + {"indirectIssuer", "X509v3 Indirect Issuer", NID_indirect_issuer, 3, &so[8430]}, + {"noAssertion", "X509v3 No Assertion", NID_no_assertion, 3, &so[8433]}, + {"aAissuingDistributionPoint", "X509v3 Attribute Authority Issuing Distribution Point", NID_id_aa_issuing_distribution_point, 3, &so[8436]}, + {"issuedOnBehalfOf", "X509v3 Issued On Behalf Of", NID_issued_on_behalf_of, 3, &so[8439]}, + {"singleUse", "X509v3 Single Use", NID_single_use, 3, &so[8442]}, + {"groupAC", "X509v3 Group Attribute Certificate", NID_group_ac, 3, &so[8445]}, + {"allowedAttributeAssignments", "X509v3 Allowed Attribute Assignments", NID_allowed_attribute_assignments, 3, &so[8448]}, + {"attributeMappings", "X509v3 Attribute Mappings", NID_attribute_mappings, 3, &so[8451]}, + {"holderNameConstraints", "X509v3 Holder Name Constraints", NID_holder_name_constraints, 3, &so[8454]}, + {"authorizationValidation", "X509v3 Authorization Validation", NID_authorization_validation, 3, &so[8457]}, + {"protRestrict", "X509v3 Protocol Restriction", NID_prot_restrict, 3, &so[8460]}, + {"subjectAltPublicKeyInfo", "X509v3 Subject Alternative Public Key Info", NID_subject_alt_public_key_info, 3, &so[8463]}, + {"altSignatureAlgorithm", "X509v3 Alternative Signature Algorithm", NID_alt_signature_algorithm, 3, &so[8466]}, + {"altSignatureValue", "X509v3 Alternative Signature Value", NID_alt_signature_value, 3, &so[8469]}, + {"associatedInformation", "X509v3 Associated Information", NID_associated_information, 3, &so[8472]}, }; -#define NUM_SN 1239 +#define NUM_SN 1311 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2648,12 +2787,15 @@ static const unsigned int sn_objs[NUM_SN] = { 1204, /* "SM2-SM3" */ 1143, /* "SM3" */ 1134, /* "SM4-CBC" */ + 1249, /* "SM4-CCM" */ 1137, /* "SM4-CFB" */ 1136, /* "SM4-CFB1" */ 1138, /* "SM4-CFB8" */ 1139, /* "SM4-CTR" */ 1133, /* "SM4-ECB" */ + 1248, /* "SM4-GCM" */ 1135, /* "SM4-OFB" */ + 1290, /* "SM4-XTS" */ 188, /* "SMIME" */ 167, /* "SMIME-CAPS" */ 100, /* "SN" */ @@ -2676,25 +2818,37 @@ static const unsigned int sn_objs[NUM_SN] = { 1206, /* "X963KDF" */ 185, /* "X9cm" */ 125, /* "ZLIB" */ + 1307, /* "aAissuingDistributionPoint" */ 478, /* "aRecord" */ 289, /* "aaControls" */ 287, /* "ac-auditEntity" */ 397, /* "ac-proxying" */ 288, /* "ac-targeting" */ + 1303, /* "acceptableCertPolicies" */ + 1304, /* "acceptablePrivPolicies" */ 368, /* "acceptableResponses" */ 446, /* "account" */ 363, /* "ad_timestamping" */ 376, /* "algorithm" */ + 1311, /* "allowedAttributeAssignments" */ + 1317, /* "altSignatureAlgorithm" */ + 1318, /* "altSignatureValue" */ 405, /* "ansi-X9-62" */ 910, /* "anyExtendedKeyUsage" */ 746, /* "anyPolicy" */ 370, /* "archiveCutoff" */ 484, /* "associatedDomain" */ + 1319, /* "associatedInformation" */ 485, /* "associatedName" */ + 1300, /* "attributeDescriptor" */ + 1312, /* "attributeMappings" */ 501, /* "audio" */ + 1295, /* "authorityAttributeIdentifier" */ 177, /* "authorityInfoAccess" */ 90, /* "authorityKeyIdentifier" */ 882, /* "authorityRevocationList" */ + 1314, /* "authorizationValidation" */ + 1297, /* "basicAttConstraints" */ 87, /* "basicConstraints" */ 365, /* "basicOCSPResponse" */ 285, /* "biometricInfo" */ @@ -2705,13 +2859,17 @@ static const unsigned int sn_objs[NUM_SN] = { 925, /* "brainpoolP224r1" */ 926, /* "brainpoolP224t1" */ 927, /* "brainpoolP256r1" */ + 1285, /* "brainpoolP256r1tls13" */ 928, /* "brainpoolP256t1" */ 929, /* "brainpoolP320r1" */ 930, /* "brainpoolP320t1" */ 931, /* "brainpoolP384r1" */ + 1286, /* "brainpoolP384r1tls13" */ 932, /* "brainpoolP384t1" */ 933, /* "brainpoolP512r1" */ + 1287, /* "brainpoolP512r1tls13" */ 934, /* "brainpoolP512t1" */ + 1288, /* "brotli" */ 494, /* "buildingName" */ 860, /* "businessCategory" */ 691, /* "c2onb191v4" */ @@ -2739,6 +2897,8 @@ static const unsigned int sn_objs[NUM_SN] = { 483, /* "cNAMERecord" */ 179, /* "caIssuers" */ 785, /* "caRepository" */ + 1273, /* "cades" */ + 1274, /* "cades-attributes" */ 1023, /* "capwapAC" */ 1024, /* "capwapWTP" */ 443, /* "caseIgnoreIA5StringSyntax" */ @@ -2780,6 +2940,7 @@ static const unsigned int sn_objs[NUM_SN] = { 495, /* "dSAQuality" */ 434, /* "data" */ 390, /* "dcobject" */ + 1298, /* "delegatedNameConstraints" */ 140, /* "deltaCRL" */ 891, /* "deltaRevocationList" */ 107, /* "description" */ @@ -2829,10 +2990,13 @@ static const unsigned int sn_objs[NUM_SN] = { 795, /* "ecdsa-with-SHA384" */ 796, /* "ecdsa-with-SHA512" */ 792, /* "ecdsa-with-Specified" */ + 1266, /* "electronic-signature-standard" */ 48, /* "emailAddress" */ 132, /* "emailProtection" */ 885, /* "enhancedSearchGuide" */ 389, /* "enterprises" */ + 1267, /* "ess-attributes" */ + 1265, /* "etsi" */ 384, /* "experimental" */ 172, /* "extReq" */ 56, /* "extendedCertificateAttributes" */ @@ -2864,6 +3028,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1010, /* "gost89-ecb" */ 812, /* "gost94" */ 850, /* "gost94cc" */ + 1310, /* "groupAC" */ 1156, /* "hmacWithDstu34311" */ 797, /* "hmacWithMD5" */ 163, /* "hmacWithSHA1" */ @@ -2873,10 +3038,12 @@ static const unsigned int sn_objs[NUM_SN] = { 801, /* "hmacWithSHA512" */ 1193, /* "hmacWithSHA512-224" */ 1194, /* "hmacWithSHA512-256" */ + 1281, /* "hmacWithSM3" */ 432, /* "holdInstructionCallIssuer" */ 430, /* "holdInstructionCode" */ 431, /* "holdInstructionNone" */ 433, /* "holdInstructionReject" */ + 1313, /* "holderNameConstraints" */ 486, /* "homePostalAddress" */ 473, /* "homeTelephoneNumber" */ 466, /* "host" */ @@ -2923,6 +3090,19 @@ static const unsigned int sn_objs[NUM_SN] = { 852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ 810, /* "id-HMACGostR3411-94" */ 782, /* "id-PasswordBasedMAC" */ + 1272, /* "id-aa-ATSHashIndex" */ + 1277, /* "id-aa-ATSHashIndex-v2" */ + 1278, /* "id-aa-ATSHashIndex-v3" */ + 1263, /* "id-aa-CMSAlgorithmProtection" */ + 1270, /* "id-aa-ets-SignaturePolicyDocument" */ + 1280, /* "id-aa-ets-archiveTimestampV2" */ + 1271, /* "id-aa-ets-archiveTimestampV3" */ + 1261, /* "id-aa-ets-attrCertificateRefs" */ + 1262, /* "id-aa-ets-attrRevocationRefs" */ + 1269, /* "id-aa-ets-longTermValidation" */ + 1268, /* "id-aa-ets-mimeType" */ + 1276, /* "id-aa-ets-sigPolicyStore" */ + 1275, /* "id-aa-ets-signerAttrV2" */ 266, /* "id-aca" */ 355, /* "id-aca-accessIdentity" */ 354, /* "id-aca-authenticationInfo" */ @@ -2980,6 +3160,7 @@ static const unsigned int sn_objs[NUM_SN] = { 327, /* "id-cmc-statusInfo" */ 331, /* "id-cmc-transactionId" */ 1238, /* "id-cp" */ + 1250, /* "id-ct-ASPA" */ 787, /* "id-ct-asciiTextWithCRLF" */ 1246, /* "id-ct-geofeedCSVwithCRLF" */ 1237, /* "id-ct-resourceTaggedAttest" */ @@ -2987,6 +3168,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1236, /* "id-ct-rpkiGhostbusters" */ 1235, /* "id-ct-rpkiManifest" */ 1247, /* "id-ct-signedChecklist" */ + 1284, /* "id-ct-signedTAL" */ 1060, /* "id-ct-xml" */ 1108, /* "id-dsa-with-sha3-224" */ 1109, /* "id-dsa-with-sha3-256" */ @@ -3009,8 +3191,11 @@ static const unsigned int sn_objs[NUM_SN] = { 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1255, /* "id-it-certProfile" */ 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ + 1256, /* "id-it-crlStatusList" */ + 1257, /* "id-it-crls" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ 310, /* "id-it-implicitConfirm" */ @@ -3019,6 +3204,7 @@ static const unsigned int sn_objs[NUM_SN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1254, /* "id-it-rootCaCert" */ 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ @@ -3032,6 +3218,9 @@ static const unsigned int sn_objs[NUM_SN] = { 274, /* "id-mod-cmc" */ 277, /* "id-mod-cmp" */ 284, /* "id-mod-cmp2000" */ + 1251, /* "id-mod-cmp2000-02" */ + 1253, /* "id-mod-cmp2021-02" */ + 1252, /* "id-mod-cmp2021-88" */ 273, /* "id-mod-crmf" */ 283, /* "id-mod-dvcs" */ 275, /* "id-mod-kea-profile-88" */ @@ -3071,12 +3260,15 @@ static const unsigned int sn_objs[NUM_SN] = { 164, /* "id-qt-cps" */ 165, /* "id-qt-unotice" */ 313, /* "id-regCtrl" */ + 1259, /* "id-regCtrl-algId" */ + 1258, /* "id-regCtrl-altCertTemplate" */ 316, /* "id-regCtrl-authenticator" */ 319, /* "id-regCtrl-oldCertID" */ 318, /* "id-regCtrl-pkiArchiveOptions" */ 317, /* "id-regCtrl-pkiPublicationInfo" */ 320, /* "id-regCtrl-protocolEncrKey" */ 315, /* "id-regCtrl-regToken" */ + 1260, /* "id-regCtrl-rsaKeyLen" */ 314, /* "id-regInfo" */ 322, /* "id-regInfo-certReq" */ 321, /* "id-regInfo-utf8Pairs" */ @@ -3196,6 +3388,7 @@ static const unsigned int sn_objs[NUM_SN] = { 676, /* "identified-organization" */ 1170, /* "ieee" */ 1171, /* "ieee-siswg" */ + 1305, /* "indirectIssuer" */ 461, /* "info" */ 748, /* "inhibitAnyPolicy" */ 101, /* "initials" */ @@ -3208,9 +3401,11 @@ static const unsigned int sn_objs[NUM_SN] = { 1022, /* "ipsecIKE" */ 295, /* "ipsecTunnel" */ 296, /* "ipsecUser" */ + 1308, /* "issuedOnBehalfOf" */ 86, /* "issuerAltName" */ 1008, /* "issuerSignTool" */ 770, /* "issuingDistributionPoint" */ + 1264, /* "itu-t-identified-organization" */ 492, /* "janetMailbox" */ 957, /* "jurisdictionC" */ 955, /* "jurisdictionL" */ @@ -3259,6 +3454,10 @@ static const unsigned int sn_objs[NUM_SN] = { 1215, /* "modp_4096" */ 1216, /* "modp_6144" */ 1217, /* "modp_8192" */ + 1294, /* "ms-app-policies" */ + 1293, /* "ms-cert-templ" */ + 1291, /* "ms-ntds-obj-sid" */ + 1292, /* "ms-ntds-sec-ext" */ 136, /* "msCTLSign" */ 135, /* "msCodeCom" */ 134, /* "msCodeInd" */ @@ -3271,6 +3470,7 @@ static const unsigned int sn_objs[NUM_SN] = { 481, /* "nSRecord" */ 173, /* "name" */ 666, /* "nameConstraints" */ + 1306, /* "noAssertion" */ 369, /* "noCheck" */ 403, /* "noRevAvail" */ 72, /* "nsBaseUrl" */ @@ -3286,6 +3486,8 @@ static const unsigned int sn_objs[NUM_SN] = { 139, /* "nsSGC" */ 77, /* "nsSslServerName" */ 681, /* "onBasis" */ + 1283, /* "oracle-jdk-trustedkeyusage" */ + 1282, /* "oracle-organization" */ 1089, /* "organizationIdentifier" */ 491, /* "organizationalStatus" */ 1141, /* "oscca" */ @@ -3342,6 +3544,7 @@ static const unsigned int sn_objs[NUM_SN] = { 415, /* "prime256v1" */ 385, /* "private" */ 84, /* "privateKeyUsagePeriod" */ + 1315, /* "protRestrict" */ 886, /* "protocolInformation" */ 663, /* "proxyCertInfo" */ 510, /* "pseudonym" */ @@ -3352,6 +3555,7 @@ static const unsigned int sn_objs[NUM_SN] = { 870, /* "registeredAddress" */ 400, /* "role" */ 877, /* "roleOccupant" */ + 1296, /* "roleSpecCertIdentifier" */ 448, /* "room" */ 463, /* "roomNumber" */ 1243, /* "rpkiManifest" */ @@ -3360,6 +3564,7 @@ static const unsigned int sn_objs[NUM_SN] = { 644, /* "rsaOAEPEncryptionSET" */ 377, /* "rsaSignature" */ 1, /* "rsadsi" */ + 1302, /* "sOAIdentifier" */ 482, /* "sOARecord" */ 155, /* "safeContentsBag" */ 291, /* "sbgp-autonomousSysNum" */ @@ -3544,14 +3749,17 @@ static const unsigned int sn_objs[NUM_SN] = { 604, /* "setext-pinAny" */ 603, /* "setext-pinSecure" */ 605, /* "setext-track2" */ + 1279, /* "signedAssertion" */ 1244, /* "signedObject" */ 52, /* "signingTime" */ 454, /* "simpleSecurityObject" */ 496, /* "singleLevelQuality" */ + 1309, /* "singleUse" */ 1142, /* "sm-scheme" */ 387, /* "snmpv2" */ 660, /* "street" */ 85, /* "subjectAltName" */ + 1316, /* "subjectAltPublicKeyInfo" */ 769, /* "subjectDirectoryAttributes" */ 398, /* "subjectInfoAccess" */ 82, /* "subjectKeyIdentifier" */ @@ -3566,6 +3774,7 @@ static const unsigned int sn_objs[NUM_SN] = { 865, /* "telexNumber" */ 459, /* "textEncodedORAddress" */ 293, /* "textNotice" */ + 1299, /* "timeSpecification" */ 133, /* "timeStamping" */ 106, /* "title" */ 1020, /* "tlsfeature" */ @@ -3589,6 +3798,7 @@ static const unsigned int sn_objs[NUM_SN] = { 49, /* "unstructuredName" */ 880, /* "userCertificate" */ 465, /* "userClass" */ + 1301, /* "userNotice" */ 879, /* "userPassword" */ 373, /* "valid" */ 678, /* "wap" */ @@ -3610,9 +3820,10 @@ static const unsigned int sn_objs[NUM_SN] = { 158, /* "x509Certificate" */ 160, /* "x509Crl" */ 1093, /* "x509ExtAdmission" */ + 1289, /* "zstd" */ }; -#define NUM_LN 1239 +#define NUM_LN 1311 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3624,6 +3835,7 @@ static const unsigned int ln_objs[NUM_LN] = { 365, /* "Basic OCSP Response" */ 285, /* "Biometric Info" */ 1221, /* "Brand Indicator for Message Identification" */ + 1288, /* "Brotli compression" */ 179, /* "CA Issuers" */ 785, /* "CA Repository" */ 1219, /* "CMC Archive Server" */ @@ -3727,16 +3939,20 @@ static const unsigned int ln_objs[NUM_LN] = { 504, /* "MIME MHS" */ 388, /* "Mail" */ 383, /* "Management" */ + 1294, /* "Microsoft Application Policies Extension" */ 417, /* "Microsoft CSP Name" */ 135, /* "Microsoft Commercial Code Signing" */ 138, /* "Microsoft Encrypted File System" */ 171, /* "Microsoft Extension Request" */ 134, /* "Microsoft Individual Code Signing" */ 856, /* "Microsoft Local Key set" */ + 1291, /* "Microsoft NTDS AD objectSid" */ + 1292, /* "Microsoft NTDS CA Extension" */ 137, /* "Microsoft Server Gated Crypto" */ 648, /* "Microsoft Smartcard Login" */ 136, /* "Microsoft Trust List Signing" */ 649, /* "Microsoft User Principal Name" */ + 1293, /* "Microsoft certificate template" */ 1211, /* "NAIRealm" */ 393, /* "NULL" */ 404, /* "NULL" */ @@ -3762,6 +3978,7 @@ static const unsigned int ln_objs[NUM_LN] = { 180, /* "OCSP Signing" */ 1005, /* "OGRN" */ 1226, /* "OGRNIP" */ + 1282, /* "Oracle organization" */ 161, /* "PBES2" */ 69, /* "PBKDF2" */ 162, /* "PBMAC1" */ @@ -3808,37 +4025,64 @@ static const unsigned int ln_objs[NUM_LN] = { 129, /* "TLS Web Server Authentication" */ 133, /* "Time Stamping" */ 375, /* "Trust Root" */ + 1283, /* "Trusted key usage (Oracle)" */ 1034, /* "X25519" */ 1035, /* "X448" */ 12, /* "X509" */ 402, /* "X509v3 AC Targeting" */ + 1303, /* "X509v3 Acceptable Certification Policies" */ + 1304, /* "X509v3 Acceptable Privilege Policies" */ + 1311, /* "X509v3 Allowed Attribute Assignments" */ + 1317, /* "X509v3 Alternative Signature Algorithm" */ + 1318, /* "X509v3 Alternative Signature Value" */ 746, /* "X509v3 Any Policy" */ + 1319, /* "X509v3 Associated Information" */ + 1307, /* "X509v3 Attribute Authority Issuing Distribution Point" */ + 1300, /* "X509v3 Attribute Descriptor" */ + 1312, /* "X509v3 Attribute Mappings" */ + 1295, /* "X509v3 Authority Attribute Identifier" */ 90, /* "X509v3 Authority Key Identifier" */ + 1314, /* "X509v3 Authorization Validation" */ + 1297, /* "X509v3 Basic Attribute Certificate Constraints" */ 87, /* "X509v3 Basic Constraints" */ 103, /* "X509v3 CRL Distribution Points" */ 88, /* "X509v3 CRL Number" */ 141, /* "X509v3 CRL Reason Code" */ 771, /* "X509v3 Certificate Issuer" */ 89, /* "X509v3 Certificate Policies" */ + 1298, /* "X509v3 Delegated Name Constraints" */ 140, /* "X509v3 Delta CRL Indicator" */ 126, /* "X509v3 Extended Key Usage" */ 857, /* "X509v3 Freshest CRL" */ + 1310, /* "X509v3 Group Attribute Certificate" */ + 1313, /* "X509v3 Holder Name Constraints" */ + 1305, /* "X509v3 Indirect Issuer" */ 748, /* "X509v3 Inhibit Any Policy" */ + 1308, /* "X509v3 Issued On Behalf Of" */ 86, /* "X509v3 Issuer Alternative Name" */ 770, /* "X509v3 Issuing Distribution Point" */ 83, /* "X509v3 Key Usage" */ 666, /* "X509v3 Name Constraints" */ + 1306, /* "X509v3 No Assertion" */ 403, /* "X509v3 No Revocation Available" */ 401, /* "X509v3 Policy Constraints" */ 747, /* "X509v3 Policy Mappings" */ 84, /* "X509v3 Private Key Usage Period" */ + 1315, /* "X509v3 Protocol Restriction" */ + 1296, /* "X509v3 Role Specification Certificate Identifier" */ + 1309, /* "X509v3 Single Use" */ + 1302, /* "X509v3 Source of Authority Identifier" */ 85, /* "X509v3 Subject Alternative Name" */ + 1316, /* "X509v3 Subject Alternative Public Key Info" */ 769, /* "X509v3 Subject Directory Attributes" */ 82, /* "X509v3 Subject Key Identifier" */ + 1299, /* "X509v3 Time Specification" */ + 1301, /* "X509v3 User Notice" */ 920, /* "X9.42 DH" */ 184, /* "X9.57" */ 185, /* "X9.57 CM ?" */ 1209, /* "XmppAddr" */ + 1289, /* "Zstandard compression" */ 478, /* "aRecord" */ 289, /* "aaControls" */ 287, /* "ac-auditEntity" */ @@ -3944,12 +4188,15 @@ static const unsigned int ln_objs[NUM_LN] = { 925, /* "brainpoolP224r1" */ 926, /* "brainpoolP224t1" */ 927, /* "brainpoolP256r1" */ + 1285, /* "brainpoolP256r1tls13" */ 928, /* "brainpoolP256t1" */ 929, /* "brainpoolP320r1" */ 930, /* "brainpoolP320t1" */ 931, /* "brainpoolP384r1" */ + 1286, /* "brainpoolP384r1tls13" */ 932, /* "brainpoolP384t1" */ 933, /* "brainpoolP512r1" */ + 1287, /* "brainpoolP512r1tls13" */ 934, /* "brainpoolP512t1" */ 494, /* "buildingName" */ 860, /* "businessCategory" */ @@ -3975,6 +4222,8 @@ static const unsigned int ln_objs[NUM_LN] = { 703, /* "c2tnb431r1" */ 881, /* "cACertificate" */ 483, /* "cNAMERecord" */ + 1273, /* "cades" */ + 1274, /* "cades-attributes" */ 751, /* "camellia-128-cbc" */ 962, /* "camellia-128-ccm" */ 757, /* "camellia-128-cfb" */ @@ -4113,9 +4362,12 @@ static const unsigned int ln_objs[NUM_LN] = { 1113, /* "ecdsa_with_SHA3-256" */ 1114, /* "ecdsa_with_SHA3-384" */ 1115, /* "ecdsa_with_SHA3-512" */ + 1266, /* "electronic-signature-standard" */ 48, /* "emailAddress" */ 632, /* "encrypted track 2" */ 885, /* "enhancedSearchGuide" */ + 1267, /* "ess-attributes" */ + 1265, /* "etsi" */ 56, /* "extendedCertificateAttributes" */ 867, /* "facsimileTelephoneNumber" */ 462, /* "favouriteDrink" */ @@ -4154,6 +4406,7 @@ static const unsigned int ln_objs[NUM_LN] = { 801, /* "hmacWithSHA512" */ 1193, /* "hmacWithSHA512-224" */ 1194, /* "hmacWithSHA512-256" */ + 1281, /* "hmacWithSM3" */ 486, /* "homePostalAddress" */ 473, /* "homeTelephoneNumber" */ 466, /* "host" */ @@ -4190,6 +4443,19 @@ static const unsigned int ln_objs[NUM_LN] = { 848, /* "id-GostR3410-94-bBis" */ 822, /* "id-GostR3411-94-CryptoProParamSet" */ 821, /* "id-GostR3411-94-TestParamSet" */ + 1272, /* "id-aa-ATSHashIndex" */ + 1277, /* "id-aa-ATSHashIndex-v2" */ + 1278, /* "id-aa-ATSHashIndex-v3" */ + 1263, /* "id-aa-CMSAlgorithmProtection" */ + 1270, /* "id-aa-ets-SignaturePolicyDocument" */ + 1280, /* "id-aa-ets-archiveTimestampV2" */ + 1271, /* "id-aa-ets-archiveTimestampV3" */ + 1261, /* "id-aa-ets-attrCertificateRefs" */ + 1262, /* "id-aa-ets-attrRevocationRefs" */ + 1269, /* "id-aa-ets-longTermValidation" */ + 1268, /* "id-aa-ets-mimeType" */ + 1276, /* "id-aa-ets-sigPolicyStore" */ + 1275, /* "id-aa-ets-signerAttrV2" */ 266, /* "id-aca" */ 355, /* "id-aca-accessIdentity" */ 354, /* "id-aca-authenticationInfo" */ @@ -4241,6 +4507,7 @@ static const unsigned int ln_objs[NUM_LN] = { 327, /* "id-cmc-statusInfo" */ 331, /* "id-cmc-transactionId" */ 1238, /* "id-cp" */ + 1250, /* "id-ct-ASPA" */ 787, /* "id-ct-asciiTextWithCRLF" */ 1246, /* "id-ct-geofeedCSVwithCRLF" */ 1237, /* "id-ct-resourceTaggedAttest" */ @@ -4248,6 +4515,7 @@ static const unsigned int ln_objs[NUM_LN] = { 1236, /* "id-ct-rpkiGhostbusters" */ 1235, /* "id-ct-rpkiManifest" */ 1247, /* "id-ct-signedChecklist" */ + 1284, /* "id-ct-signedTAL" */ 1060, /* "id-ct-xml" */ 408, /* "id-ecPublicKey" */ 508, /* "id-hex-multipart-message" */ @@ -4256,8 +4524,11 @@ static const unsigned int ln_objs[NUM_LN] = { 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1255, /* "id-it-certProfile" */ 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ + 1256, /* "id-it-crlStatusList" */ + 1257, /* "id-it-crls" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ 310, /* "id-it-implicitConfirm" */ @@ -4266,6 +4537,7 @@ static const unsigned int ln_objs[NUM_LN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1254, /* "id-it-rootCaCert" */ 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ @@ -4277,6 +4549,9 @@ static const unsigned int ln_objs[NUM_LN] = { 274, /* "id-mod-cmc" */ 277, /* "id-mod-cmp" */ 284, /* "id-mod-cmp2000" */ + 1251, /* "id-mod-cmp2000-02" */ + 1253, /* "id-mod-cmp2021-02" */ + 1252, /* "id-mod-cmp2021-88" */ 273, /* "id-mod-crmf" */ 283, /* "id-mod-dvcs" */ 275, /* "id-mod-kea-profile-88" */ @@ -4306,12 +4581,15 @@ static const unsigned int ln_objs[NUM_LN] = { 359, /* "id-qcs-pkixQCSyntax-v1" */ 259, /* "id-qt" */ 313, /* "id-regCtrl" */ + 1259, /* "id-regCtrl-algId" */ + 1258, /* "id-regCtrl-altCertTemplate" */ 316, /* "id-regCtrl-authenticator" */ 319, /* "id-regCtrl-oldCertID" */ 318, /* "id-regCtrl-pkiArchiveOptions" */ 317, /* "id-regCtrl-pkiPublicationInfo" */ 320, /* "id-regCtrl-protocolEncrKey" */ 315, /* "id-regCtrl-regToken" */ + 1260, /* "id-regCtrl-rsaKeyLen" */ 314, /* "id-regInfo" */ 322, /* "id-regInfo-certReq" */ 321, /* "id-regInfo-utf8Pairs" */ @@ -4426,6 +4704,7 @@ static const unsigned int ln_objs[NUM_LN] = { 181, /* "iso" */ 623, /* "issuer capabilities" */ 645, /* "itu-t" */ + 1264, /* "itu-t-identified-organization" */ 492, /* "janetMailbox" */ 646, /* "joint-iso-itu-t" */ 957, /* "jurisdictionCountryName" */ @@ -4788,6 +5067,7 @@ static const unsigned int ln_objs[NUM_LN] = { 42, /* "shaWithRSAEncryption" */ 1100, /* "shake128" */ 1101, /* "shake256" */ + 1279, /* "signedAssertion" */ 52, /* "signingTime" */ 454, /* "simpleSecurityObject" */ 496, /* "singleLevelQuality" */ @@ -4797,12 +5077,15 @@ static const unsigned int ln_objs[NUM_LN] = { 1143, /* "sm3" */ 1144, /* "sm3WithRSAEncryption" */ 1134, /* "sm4-cbc" */ + 1249, /* "sm4-ccm" */ 1137, /* "sm4-cfb" */ 1136, /* "sm4-cfb1" */ 1138, /* "sm4-cfb8" */ 1139, /* "sm4-ctr" */ 1133, /* "sm4-ecb" */ + 1248, /* "sm4-gcm" */ 1135, /* "sm4-ofb" */ + 1290, /* "sm4-xts" */ 1203, /* "sshkdf" */ 1205, /* "sskdf" */ 16, /* "stateOrProvinceName" */ @@ -4855,7 +5138,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1110 +#define NUM_OBJ 1177 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -4863,12 +5146,14 @@ static const unsigned int obj_objs[NUM_OBJ] = { 404, /* OBJ_ccitt OBJ_itu_t */ 645, /* OBJ_itu_t 0 */ 646, /* OBJ_joint_iso_itu_t 2 */ + 1264, /* OBJ_itu_t_identified_organization 0 4 */ 434, /* OBJ_data 0 9 */ 182, /* OBJ_member_body 1 2 */ 379, /* OBJ_org 1 3 */ 676, /* OBJ_identified_organization 1 3 */ 11, /* OBJ_X500 2 5 */ 647, /* OBJ_international_organizations 2 23 */ + 1265, /* OBJ_etsi 0 4 0 */ 380, /* OBJ_dod 1 3 6 */ 1170, /* OBJ_ieee 1 3 111 */ 12, /* OBJ_X509 2 5 4 */ @@ -4966,10 +5251,35 @@ static const unsigned int obj_objs[NUM_OBJ] = { 90, /* OBJ_authority_key_identifier 2 5 29 35 */ 401, /* OBJ_policy_constraints 2 5 29 36 */ 126, /* OBJ_ext_key_usage 2 5 29 37 */ + 1295, /* OBJ_authority_attribute_identifier 2 5 29 38 */ + 1296, /* OBJ_role_spec_cert_identifier 2 5 29 39 */ + 1297, /* OBJ_basic_att_constraints 2 5 29 41 */ + 1298, /* OBJ_delegated_name_constraints 2 5 29 42 */ + 1299, /* OBJ_time_specification 2 5 29 43 */ 857, /* OBJ_freshest_crl 2 5 29 46 */ + 1300, /* OBJ_attribute_descriptor 2 5 29 48 */ + 1301, /* OBJ_user_notice 2 5 29 49 */ + 1302, /* OBJ_soa_identifier 2 5 29 50 */ + 1303, /* OBJ_acceptable_cert_policies 2 5 29 52 */ 748, /* OBJ_inhibit_any_policy 2 5 29 54 */ 402, /* OBJ_target_information 2 5 29 55 */ 403, /* OBJ_no_rev_avail 2 5 29 56 */ + 1304, /* OBJ_acceptable_privilege_policies 2 5 29 57 */ + 1305, /* OBJ_indirect_issuer 2 5 29 61 */ + 1306, /* OBJ_no_assertion 2 5 29 62 */ + 1307, /* OBJ_id_aa_issuing_distribution_point 2 5 29 63 */ + 1308, /* OBJ_issued_on_behalf_of 2 5 29 64 */ + 1309, /* OBJ_single_use 2 5 29 65 */ + 1310, /* OBJ_group_ac 2 5 29 66 */ + 1311, /* OBJ_allowed_attribute_assignments 2 5 29 67 */ + 1312, /* OBJ_attribute_mappings 2 5 29 68 */ + 1313, /* OBJ_holder_name_constraints 2 5 29 69 */ + 1314, /* OBJ_authorization_validation 2 5 29 70 */ + 1315, /* OBJ_prot_restrict 2 5 29 71 */ + 1316, /* OBJ_subject_alt_public_key_info 2 5 29 72 */ + 1317, /* OBJ_alt_signature_algorithm 2 5 29 73 */ + 1318, /* OBJ_alt_signature_value 2 5 29 74 */ + 1319, /* OBJ_associated_information 2 5 29 75 */ 513, /* OBJ_set_ctype 2 23 42 0 */ 514, /* OBJ_set_msgExt 2 23 42 1 */ 515, /* OBJ_set_attr 2 23 42 3 */ @@ -4977,6 +5287,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 517, /* OBJ_set_certExt 2 23 42 7 */ 518, /* OBJ_set_brand 2 23 42 8 */ 679, /* OBJ_wap_wsg 2 23 43 1 */ + 1266, /* OBJ_electronic_signature_standard 0 4 0 1733 */ 382, /* OBJ_Directory 1 3 6 1 1 */ 383, /* OBJ_Management 1 3 6 1 2 */ 384, /* OBJ_Experimental 1 3 6 1 3 */ @@ -5102,6 +5413,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ 638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ 639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ + 1273, /* OBJ_cades 0 4 0 19122 */ + 1267, /* OBJ_ess_attributes 0 4 0 1733 2 */ 1195, /* OBJ_gmac 1 0 9797 3 4 */ 1141, /* OBJ_oscca 1 2 156 10197 */ 805, /* OBJ_cryptopro 1 2 643 2 2 */ @@ -5185,6 +5498,12 @@ static const unsigned int obj_objs[NUM_OBJ] = { 743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ 744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ 745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ + 1274, /* OBJ_cades_attributes 0 4 0 19122 1 */ + 1268, /* OBJ_id_aa_ets_mimeType 0 4 0 1733 2 1 */ + 1269, /* OBJ_id_aa_ets_longTermValidation 0 4 0 1733 2 2 */ + 1270, /* OBJ_id_aa_ets_SignaturePolicyDocument 0 4 0 1733 2 3 */ + 1271, /* OBJ_id_aa_ets_archiveTimestampV3 0 4 0 1733 2 4 */ + 1272, /* OBJ_id_aa_ATSHashIndex 0 4 0 1733 2 5 */ 804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ 1142, /* OBJ_sm_scheme 1 2 156 10197 1 */ 773, /* OBJ_kisa 1 2 410 200004 */ @@ -5227,6 +5546,11 @@ static const unsigned int obj_objs[NUM_OBJ] = { 633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ 634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ 635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ + 1275, /* OBJ_id_aa_ets_signerAttrV2 0 4 0 19122 1 1 */ + 1276, /* OBJ_id_aa_ets_sigPolicyStore 0 4 0 19122 1 3 */ + 1277, /* OBJ_id_aa_ATSHashIndex_v2 0 4 0 19122 1 4 */ + 1278, /* OBJ_id_aa_ATSHashIndex_v3 0 4 0 19122 1 5 */ + 1279, /* OBJ_signedAssertion 0 4 0 19122 1 6 */ 436, /* OBJ_ucl 0 9 2342 19200300 */ 820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ 819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ @@ -5303,6 +5627,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ 508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ 57, /* OBJ_netscape 2 16 840 1 113730 */ + 1282, /* OBJ_oracle 2 16 840 1 113894 */ 754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ 766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ 757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ @@ -5332,6 +5657,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1136, /* OBJ_sm4_cfb1 1 2 156 10197 1 104 5 */ 1138, /* OBJ_sm4_cfb8 1 2 156 10197 1 104 6 */ 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ + 1248, /* OBJ_sm4_gcm 1 2 156 10197 1 104 8 */ + 1249, /* OBJ_sm4_ccm 1 2 156 10197 1 104 9 */ + 1290, /* OBJ_sm4_xts 1 2 156 10197 1 104 10 */ 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ 1204, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ @@ -5433,6 +5761,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ 283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ 284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ + 1251, /* OBJ_id_mod_cmp2000_02 1 3 6 1 5 5 7 0 50 */ + 1252, /* OBJ_id_mod_cmp2021_88 1 3 6 1 5 5 7 0 99 */ + 1253, /* OBJ_id_mod_cmp2021_02 1 3 6 1 5 5 7 0 100 */ 177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ 285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ 286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ @@ -5495,6 +5826,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1223, /* OBJ_id_it_caCerts 1 3 6 1 5 5 7 4 17 */ 1224, /* OBJ_id_it_rootCaKeyUpdate 1 3 6 1 5 5 7 4 18 */ 1225, /* OBJ_id_it_certReqTemplate 1 3 6 1 5 5 7 4 19 */ + 1254, /* OBJ_id_it_rootCaCert 1 3 6 1 5 5 7 4 20 */ + 1255, /* OBJ_id_it_certProfile 1 3 6 1 5 5 7 4 21 */ + 1256, /* OBJ_id_it_crlStatusList 1 3 6 1 5 5 7 4 22 */ + 1257, /* OBJ_id_it_crls 1 3 6 1 5 5 7 4 23 */ 313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ 314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ 323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ @@ -5651,11 +5986,15 @@ static const unsigned int obj_objs[NUM_OBJ] = { 188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ 156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ 157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ + 1263, /* OBJ_id_aa_CMSAlgorithmProtection 1 2 840 113549 1 9 52 */ 681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ 682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ 683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ 417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ 856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ + 1293, /* OBJ_ms_cert_templ 1 3 6 1 4 1 311 21 7 */ + 1294, /* OBJ_ms_app_policies 1 3 6 1 4 1 311 21 10 */ + 1292, /* OBJ_ms_ntds_sec_ext 1 3 6 1 4 1 311 25 2 */ 390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ 91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ 973, /* OBJ_id_scrypt 1 3 6 1 4 1 11591 4 11 */ @@ -5665,6 +6004,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ 319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ 320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ + 1258, /* OBJ_id_regCtrl_altCertTemplate 1 3 6 1 5 5 7 5 1 7 */ + 1259, /* OBJ_id_regCtrl_algId 1 3 6 1 5 5 7 5 1 11 */ + 1260, /* OBJ_id_regCtrl_rsaKeyLen 1 3 6 1 5 5 7 5 1 12 */ 321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ 322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ 365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ @@ -5826,6 +6168,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ 456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ 457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ + 1281, /* OBJ_hmacWithSM3 1 2 156 10197 1 401 3 1 */ 1152, /* OBJ_dstu28147 1 2 804 2 1 1 1 1 1 1 */ 1156, /* OBJ_hmacWithDstu34311 1 2 804 2 1 1 1 1 1 2 */ 1157, /* OBJ_dstu34311 1 2 804 2 1 1 1 1 2 1 */ @@ -5853,6 +6196,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ 648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ 649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ + 1291, /* OBJ_ms_ntds_obj_sid 1 3 6 1 4 1 311 25 2 1 */ 1201, /* OBJ_blake2bmac 1 3 6 1 4 1 1722 12 2 1 */ 1202, /* OBJ_blake2smac 1 3 6 1 4 1 1722 12 2 2 */ 951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ @@ -5896,6 +6240,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1237, /* OBJ_id_ct_resourceTaggedAttest 1 2 840 113549 1 9 16 1 36 */ 1246, /* OBJ_id_ct_geofeedCSVwithCRLF 1 2 840 113549 1 9 16 1 47 */ 1247, /* OBJ_id_ct_signedChecklist 1 2 840 113549 1 9 16 1 48 */ + 1250, /* OBJ_id_ct_ASPA 1 2 840 113549 1 9 16 1 49 */ + 1284, /* OBJ_id_ct_signedTAL 1 2 840 113549 1 9 16 1 50 */ 212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ 213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ 214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ @@ -5925,7 +6271,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ 239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ 240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ + 1261, /* OBJ_id_aa_ets_attrCertificateRefs 1 2 840 113549 1 9 16 2 44 */ + 1262, /* OBJ_id_aa_ets_attrRevocationRefs 1 2 840 113549 1 9 16 2 45 */ 1086, /* OBJ_id_smime_aa_signingCertificateV2 1 2 840 113549 1 9 16 2 47 */ + 1280, /* OBJ_id_aa_ets_archiveTimestampV2 1 2 840 113549 1 9 16 2 48 */ 241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ 242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ 243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ @@ -5956,6 +6305,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ 1056, /* OBJ_blake2b512 1 3 6 1 4 1 1722 12 2 1 16 */ 1057, /* OBJ_blake2s256 1 3 6 1 4 1 1722 12 2 2 8 */ + 1283, /* OBJ_oracle_jdk_trustedkeyusage 2 16 840 1 113894 746875 1 1 */ 1159, /* OBJ_dstu4145be 1 2 804 2 1 1 1 1 3 1 1 1 1 */ 1160, /* OBJ_uacurve0 1 2 804 2 1 1 1 1 3 1 1 2 0 */ 1161, /* OBJ_uacurve1 1 2 804 2 1 1 1 1 3 1 1 2 1 */ diff --git a/crypto/objects/obj_lib.c b/crypto/objects/obj_lib.c index 72c0c2c81d..6cdc1d7e74 100644 --- a/crypto/objects/obj_lib.c +++ b/crypto/objects/obj_lib.c @@ -50,7 +50,6 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) return r; err: ASN1_OBJECT_free(r); - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/objects/obj_local.h b/crypto/objects/obj_local.h index 68dcd8d240..73848a6fbf 100644 --- a/crypto/objects/obj_local.h +++ b/crypto/objects/obj_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index c626558ad5..9deaf2a5a9 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1245,3 +1245,75 @@ signedObject 1244 rpkiNotify 1245 id_ct_geofeedCSVwithCRLF 1246 id_ct_signedChecklist 1247 +sm4_gcm 1248 +sm4_ccm 1249 +id_ct_ASPA 1250 +id_mod_cmp2000_02 1251 +id_mod_cmp2021_88 1252 +id_mod_cmp2021_02 1253 +id_it_rootCaCert 1254 +id_it_certProfile 1255 +id_it_crlStatusList 1256 +id_it_crls 1257 +id_regCtrl_altCertTemplate 1258 +id_regCtrl_algId 1259 +id_regCtrl_rsaKeyLen 1260 +id_aa_ets_attrCertificateRefs 1261 +id_aa_ets_attrRevocationRefs 1262 +id_aa_CMSAlgorithmProtection 1263 +itu_t_identified_organization 1264 +etsi 1265 +electronic_signature_standard 1266 +ess_attributes 1267 +id_aa_ets_mimeType 1268 +id_aa_ets_longTermValidation 1269 +id_aa_ets_SignaturePolicyDocument 1270 +id_aa_ets_archiveTimestampV3 1271 +id_aa_ATSHashIndex 1272 +cades 1273 +cades_attributes 1274 +id_aa_ets_signerAttrV2 1275 +id_aa_ets_sigPolicyStore 1276 +id_aa_ATSHashIndex_v2 1277 +id_aa_ATSHashIndex_v3 1278 +signedAssertion 1279 +id_aa_ets_archiveTimestampV2 1280 +hmacWithSM3 1281 +oracle 1282 +oracle_jdk_trustedkeyusage 1283 +id_ct_signedTAL 1284 +brainpoolP256r1tls13 1285 +brainpoolP384r1tls13 1286 +brainpoolP512r1tls13 1287 +brotli 1288 +zstd 1289 +sm4_xts 1290 +ms_ntds_obj_sid 1291 +ms_ntds_sec_ext 1292 +ms_cert_templ 1293 +ms_app_policies 1294 +authority_attribute_identifier 1295 +role_spec_cert_identifier 1296 +basic_att_constraints 1297 +delegated_name_constraints 1298 +time_specification 1299 +attribute_descriptor 1300 +user_notice 1301 +soa_identifier 1302 +acceptable_cert_policies 1303 +acceptable_privilege_policies 1304 +indirect_issuer 1305 +no_assertion 1306 +id_aa_issuing_distribution_point 1307 +issued_on_behalf_of 1308 +single_use 1309 +group_ac 1310 +allowed_attribute_assignments 1311 +attribute_mappings 1312 +holder_name_constraints 1313 +authorization_validation 1314 +prot_restrict 1315 +subject_alt_public_key_info 1316 +alt_signature_algorithm 1317 +alt_signature_value 1318 +associated_information 1319 diff --git a/crypto/objects/obj_xref.c b/crypto/objects/obj_xref.c index 8660de2004..2eb757cb77 100644 --- a/crypto/objects/obj_xref.c +++ b/crypto/objects/obj_xref.c @@ -155,10 +155,8 @@ int OBJ_add_sigid(int signid, int dig_id, int pkey_id) if (!obj_sig_init()) return 0; - if ((ntr = OPENSSL_malloc(sizeof(*ntr))) == NULL) { - ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); + if ((ntr = OPENSSL_malloc(sizeof(*ntr))) == NULL) return 0; - } ntr->sign_id = signid; ntr->hash_id = dig_id; ntr->pkey_id = pkey_id; diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h index 21a193ee98..913606f175 100644 --- a/crypto/objects/obj_xref.h +++ b/crypto/objects/obj_xref.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by objxref.pl * - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -75,6 +75,10 @@ static const nid_triple sigoid_srt[] = { NID_id_GostR3410_2012_512}, {NID_ED25519, NID_undef, NID_ED25519}, {NID_ED448, NID_undef, NID_ED448}, + {NID_ecdsa_with_SHA3_224, NID_sha3_224, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA3_256, NID_sha3_256, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA3_384, NID_sha3_384, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA3_512, NID_sha3_512, NID_X9_62_id_ecPublicKey}, {NID_RSA_SHA3_224, NID_sha3_224, NID_rsaEncryption}, {NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption}, {NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption}, @@ -122,9 +126,13 @@ static const nid_triple *const sigoid_srt_xref[] = { &sigoid_srt[28], &sigoid_srt[40], &sigoid_srt[41], + &sigoid_srt[48], &sigoid_srt[44], + &sigoid_srt[49], &sigoid_srt[45], + &sigoid_srt[50], &sigoid_srt[46], + &sigoid_srt[51], &sigoid_srt[47], - &sigoid_srt[48], + &sigoid_srt[52], }; diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt index 2a61d4db59..31c6eb9928 100644 --- a/crypto/objects/obj_xref.txt +++ b/crypto/objects/obj_xref.txt @@ -42,6 +42,10 @@ ecdsa_with_SHA384 sha384 X9_62_id_ecPublicKey ecdsa_with_SHA512 sha512 X9_62_id_ecPublicKey ecdsa_with_Recommended undef X9_62_id_ecPublicKey ecdsa_with_Specified undef X9_62_id_ecPublicKey +ecdsa_with_SHA3_224 sha3_224 X9_62_id_ecPublicKey +ecdsa_with_SHA3_256 sha3_256 X9_62_id_ecPublicKey +ecdsa_with_SHA3_384 sha3_384 X9_62_id_ecPublicKey +ecdsa_with_SHA3_512 sha3_512 X9_62_id_ecPublicKey dsa_with_SHA224 sha224 dsa dsa_with_SHA256 sha256 dsa diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 51dba7dcf3..305b89c016 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -282,6 +282,8 @@ id-smime-ct 35 : id-ct-rpkiGhostbusters id-smime-ct 36 : id-ct-resourceTaggedAttest id-smime-ct 47 : id-ct-geofeedCSVwithCRLF id-smime-ct 48 : id-ct-signedChecklist +id-smime-ct 49 : id-ct-ASPA +id-smime-ct 50 : id-ct-signedTAL # S/MIME Attributes id-smime-aa 1 : id-smime-aa-receiptRequest @@ -315,7 +317,10 @@ id-smime-aa 26 : id-smime-aa-ets-certCRLTimestamp id-smime-aa 27 : id-smime-aa-ets-archiveTimeStamp id-smime-aa 28 : id-smime-aa-signatureType id-smime-aa 29 : id-smime-aa-dvcs-dvc +id-smime-aa 44 : id-aa-ets-attrCertificateRefs +id-smime-aa 45 : id-aa-ets-attrRevocationRefs id-smime-aa 47 : id-smime-aa-signingCertificateV2 +id-smime-aa 48 : id-aa-ets-archiveTimestampV2 # S/MIME Algorithm Identifiers # obsolete @@ -348,15 +353,18 @@ id-smime-cti 6 : id-smime-cti-ets-proofOfCreation pkcs9 20 : : friendlyName pkcs9 21 : : localKeyID +!Alias ms-corp 1 3 6 1 4 1 311 !Cname ms-csp-name -1 3 6 1 4 1 311 17 1 : CSPName : Microsoft CSP Name -1 3 6 1 4 1 311 17 2 : LocalKeySet : Microsoft Local Key set +ms-corp 17 1 : CSPName : Microsoft CSP Name +ms-corp 17 2 : LocalKeySet : Microsoft Local Key set !Alias certTypes pkcs9 22 certTypes 1 : : x509Certificate certTypes 2 : : sdsiCertificate !Alias crlTypes pkcs9 23 crlTypes 1 : : x509Crl +pkcs9 52 : id-aa-CMSAlgorithmProtection + !Alias pkcs12 pkcs 12 !Alias pkcs12-pbeids pkcs12 1 @@ -396,6 +404,9 @@ sm-scheme 504 : RSA-SM3 : sm3WithRSAEncryption sm-scheme 501 : SM2-SM3 : SM2-with-SM3 +# From GM/T 0091-2020 +sm3 3 1 : : hmacWithSM3 + # From RFC4231 rsadsi 2 8 : : hmacWithSHA224 rsadsi 2 9 : : hmacWithSHA256 @@ -425,21 +436,26 @@ rsadsi 3 8 : RC5-CBC : rc5-cbc : RC5-OFB : rc5-ofb !Cname ms-ext-req -1 3 6 1 4 1 311 2 1 14 : msExtReq : Microsoft Extension Request +ms-corp 2 1 14 : msExtReq : Microsoft Extension Request !Cname ms-code-ind -1 3 6 1 4 1 311 2 1 21 : msCodeInd : Microsoft Individual Code Signing +ms-corp 2 1 21 : msCodeInd : Microsoft Individual Code Signing !Cname ms-code-com -1 3 6 1 4 1 311 2 1 22 : msCodeCom : Microsoft Commercial Code Signing +ms-corp 2 1 22 : msCodeCom : Microsoft Commercial Code Signing !Cname ms-ctl-sign -1 3 6 1 4 1 311 10 3 1 : msCTLSign : Microsoft Trust List Signing +ms-corp 10 3 1 : msCTLSign : Microsoft Trust List Signing !Cname ms-sgc -1 3 6 1 4 1 311 10 3 3 : msSGC : Microsoft Server Gated Crypto +ms-corp 10 3 3 : msSGC : Microsoft Server Gated Crypto !Cname ms-efs -1 3 6 1 4 1 311 10 3 4 : msEFS : Microsoft Encrypted File System +ms-corp 10 3 4 : msEFS : Microsoft Encrypted File System !Cname ms-smartcard-login -1 3 6 1 4 1 311 20 2 2 : msSmartcardLogin : Microsoft Smartcard Login +ms-corp 20 2 2 : msSmartcardLogin : Microsoft Smartcard Login !Cname ms-upn -1 3 6 1 4 1 311 20 2 3 : msUPN : Microsoft User Principal Name +ms-corp 20 2 3 : msUPN : Microsoft User Principal Name + +ms-corp 25 2 : ms-ntds-sec-ext : Microsoft NTDS CA Extension +ms-corp 25 2 1 : ms-ntds-obj-sid : Microsoft NTDS AD objectSid +ms-corp 21 7 : ms-cert-templ : Microsoft certificate template +ms-corp 21 10 : ms-app-policies : Microsoft Application Policies Extension 1 3 6 1 4 1 188 7 1 1 2 : IDEA-CBC : idea-cbc : IDEA-ECB : idea-ecb @@ -493,6 +509,9 @@ id-pkix-mod 13 : id-mod-timestamp-protocol id-pkix-mod 14 : id-mod-ocsp id-pkix-mod 15 : id-mod-dvcs id-pkix-mod 16 : id-mod-cmp2000 +id-pkix-mod 50 : id-mod-cmp2000-02 +id-pkix-mod 99 : id-mod-cmp2021-88 +id-pkix-mod 100 : id-mod-cmp2021-02 # PKIX Private Extensions !Cname info-access @@ -565,9 +584,9 @@ id-it 4 : id-it-preferredSymmAlg id-it 5 : id-it-caKeyUpdateInfo id-it 6 : id-it-currentCRL id-it 7 : id-it-unsupportedOIDs -# obsolete +# [Reserved and Obsolete]: id-it 8 : id-it-subscriptionRequest -# obsolete +# [Reserved and Obsolete]: id-it 9 : id-it-subscriptionResponse id-it 10 : id-it-keyPairParamReq id-it 11 : id-it-keyPairParamRep @@ -579,6 +598,10 @@ id-it 16 : id-it-suppLangTags id-it 17 : id-it-caCerts id-it 18 : id-it-rootCaKeyUpdate id-it 19 : id-it-certReqTemplate +id-it 20 : id-it-rootCaCert +id-it 21 : id-it-certProfile +id-it 22 : id-it-crlStatusList +id-it 23 : id-it-crls # CRMF registration id-pkip 1 : id-regCtrl @@ -591,6 +614,12 @@ id-regCtrl 3 : id-regCtrl-pkiPublicationInfo id-regCtrl 4 : id-regCtrl-pkiArchiveOptions id-regCtrl 5 : id-regCtrl-oldCertID id-regCtrl 6 : id-regCtrl-protocolEncrKey +id-regCtrl 7 : id-regCtrl-altCertTemplate +# id-regCtrl 8 : id-regCtrl-wtlsTemplate [Reserved and Obsolete] +# id-regCtrl 9 : id-regCtrl-regTokenUTF8 [Reserved and Obsolete] +# id-regCtrl 10 : id-regCtrl-authenticatorUTF8 [Reserved and Obsolete] +id-regCtrl 11 : id-regCtrl-algId +id-regCtrl 12 : id-regCtrl-rsaKeyLen # CRMF registration information id-regInfo 1 : id-regInfo-utf8Pairs @@ -850,14 +879,64 @@ id-ce 35 : authorityKeyIdentifier : X509v3 Authority Key Identifier id-ce 36 : policyConstraints : X509v3 Policy Constraints !Cname ext-key-usage id-ce 37 : extendedKeyUsage : X509v3 Extended Key Usage +!Cname authority-attribute-identifier +id-ce 38 : authorityAttributeIdentifier : X509v3 Authority Attribute Identifier +!Cname role-spec-cert-identifier +id-ce 39 : roleSpecCertIdentifier : X509v3 Role Specification Certificate Identifier +!Cname basic-att-constraints +id-ce 41 : basicAttConstraints : X509v3 Basic Attribute Certificate Constraints +!Cname delegated-name-constraints +id-ce 42 : delegatedNameConstraints : X509v3 Delegated Name Constraints +!Cname time-specification +id-ce 43 : timeSpecification : X509v3 Time Specification !Cname freshest-crl id-ce 46 : freshestCRL : X509v3 Freshest CRL +!Cname attribute-descriptor +id-ce 48 : attributeDescriptor : X509v3 Attribute Descriptor +!Cname user-notice +id-ce 49 : userNotice : X509v3 User Notice +!Cname soa-identifier +id-ce 50 : sOAIdentifier : X509v3 Source of Authority Identifier +!Cname acceptable-cert-policies +id-ce 52 : acceptableCertPolicies : X509v3 Acceptable Certification Policies !Cname inhibit-any-policy id-ce 54 : inhibitAnyPolicy : X509v3 Inhibit Any Policy !Cname target-information id-ce 55 : targetInformation : X509v3 AC Targeting !Cname no-rev-avail id-ce 56 : noRevAvail : X509v3 No Revocation Available +!Cname acceptable-privilege-policies +id-ce 57 : acceptablePrivPolicies : X509v3 Acceptable Privilege Policies +!Cname indirect-issuer +id-ce 61 : indirectIssuer : X509v3 Indirect Issuer +!Cname no-assertion +id-ce 62 : noAssertion : X509v3 No Assertion +!Cname id-aa-issuing-distribution-point +id-ce 63 : aAissuingDistributionPoint : X509v3 Attribute Authority Issuing Distribution Point +!Cname issued-on-behalf-of +id-ce 64 : issuedOnBehalfOf : X509v3 Issued On Behalf Of +!Cname single-use +id-ce 65 : singleUse : X509v3 Single Use +!Cname group-ac +id-ce 66 : groupAC : X509v3 Group Attribute Certificate +!Cname allowed-attribute-assignments +id-ce 67 : allowedAttributeAssignments : X509v3 Allowed Attribute Assignments +!Cname attribute-mappings +id-ce 68 : attributeMappings : X509v3 Attribute Mappings +!Cname holder-name-constraints +id-ce 69 : holderNameConstraints : X509v3 Holder Name Constraints +!Cname authorization-validation +id-ce 70 : authorizationValidation : X509v3 Authorization Validation +!Cname prot-restrict +id-ce 71 : protRestrict : X509v3 Protocol Restriction +!Cname subject-alt-public-key-info +id-ce 72 : subjectAltPublicKeyInfo : X509v3 Subject Alternative Public Key Info +!Cname alt-signature-algorithm +id-ce 73 : altSignatureAlgorithm : X509v3 Alternative Signature Algorithm +!Cname alt-signature-value +id-ce 74 : altSignatureValue : X509v3 Alternative Signature Value +!Cname associated-information +id-ce 75 : associatedInformation : X509v3 Associated Information # From RFC5280 ext-key-usage 0 : anyExtendedKeyUsage : Any Extended Key Usage @@ -1050,6 +1129,27 @@ holdInstruction 3 : holdInstructionReject : Hold Instruction Reject # OID's from ITU-T. Most of this is defined in RFC 1274. A couple of # them are also mentioned in RFC 2247 +# OIDs specific to Electronic Signature Standard/CAdES are as specified in +# ETSI EN 319 122-1 V1.2.1 (2021-10): +# Electronic Signatures and Infrastructures (ESI); CAdES digital signatures; +# Part 1: Building blocks and CAdES baseline signatures +itu-t 4 : itu-t-identified-organization +itu-t-identified-organization 0: etsi +etsi 1733 : electronic-signature-standard +electronic-signature-standard 2: ess-attributes +ess-attributes 1 : id-aa-ets-mimeType +ess-attributes 2 : id-aa-ets-longTermValidation +ess-attributes 3 : id-aa-ets-SignaturePolicyDocument +ess-attributes 4 : id-aa-ets-archiveTimestampV3 +ess-attributes 5 : id-aa-ATSHashIndex +etsi 19122 : cades +cades 1 : cades-attributes +cades-attributes 1 : id-aa-ets-signerAttrV2 +cades-attributes 3 : id-aa-ets-sigPolicyStore +cades-attributes 4 : id-aa-ATSHashIndex-v2 +cades-attributes 5 : id-aa-ATSHashIndex-v3 +cades-attributes 6 : signedAssertion + itu-t 9 : data data 2342 : pss pss 19200300 : ucl @@ -1565,6 +1665,9 @@ sm-scheme 104 4 : SM4-CFB : sm4-cfb sm-scheme 104 5 : SM4-CFB1 : sm4-cfb1 sm-scheme 104 6 : SM4-CFB8 : sm4-cfb8 sm-scheme 104 7 : SM4-CTR : sm4-ctr +sm-scheme 104 8 : SM4-GCM : sm4-gcm +sm-scheme 104 9 : SM4-CCM : sm4-ccm +sm-scheme 104 10 : SM4-XTS : sm4-xts # There is no OID that just denotes "HMAC" oddly enough... @@ -1597,12 +1700,18 @@ ISO-US 10046 2 1 : dhpublicnumber : X9.42 DH 1 3 36 3 3 2 8 1 1 5 : brainpoolP224r1 1 3 36 3 3 2 8 1 1 6 : brainpoolP224t1 1 3 36 3 3 2 8 1 1 7 : brainpoolP256r1 +# Alternate NID to represent the TLSv1.3 brainpoolP256r1 group + : brainpoolP256r1tls13 1 3 36 3 3 2 8 1 1 8 : brainpoolP256t1 1 3 36 3 3 2 8 1 1 9 : brainpoolP320r1 1 3 36 3 3 2 8 1 1 10 : brainpoolP320t1 1 3 36 3 3 2 8 1 1 11 : brainpoolP384r1 +# Alternate NID to represent the TLSv1.3 brainpoolP384r1 group + : brainpoolP384r1tls13 1 3 36 3 3 2 8 1 1 12 : brainpoolP384t1 1 3 36 3 3 2 8 1 1 13 : brainpoolP512r1 +# Alternate NID to represent the TLSv1.3 brainpoolP512r1 group + : brainpoolP512r1tls13 1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1 # ECDH schemes from RFC5753 @@ -1633,9 +1742,9 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme # CABForum EV SSL Certificate Guidelines # (see https://cabforum.org/extended-validation/) # OIDs for Subject Jurisdiction of Incorporation or Registration -1 3 6 1 4 1 311 60 2 1 1 : jurisdictionL : jurisdictionLocalityName -1 3 6 1 4 1 311 60 2 1 2 : jurisdictionST : jurisdictionStateOrProvinceName -1 3 6 1 4 1 311 60 2 1 3 : jurisdictionC : jurisdictionCountryName +ms-corp 60 2 1 1 : jurisdictionL : jurisdictionLocalityName +ms-corp 60 2 1 2 : jurisdictionST : jurisdictionStateOrProvinceName +ms-corp 60 2 1 3 : jurisdictionC : jurisdictionCountryName # SCRYPT algorithm !Cname id-scrypt @@ -1744,3 +1853,13 @@ dstu4145le 2 9 : uacurve9 : DSTU curve 9 : AES-128-SIV : aes-128-siv : AES-192-SIV : aes-192-siv : AES-256-SIV : aes-256-siv + + +!Cname oracle +joint-iso-itu-t 16 840 1 113894 : oracle-organization : Oracle organization +# Jdk trustedKeyUsage attribute +oracle 746875 1 1 : oracle-jdk-trustedkeyusage : Trusted key usage (Oracle) + +# NID for compression + : brotli : Brotli compression + : zstd : Zstandard compression diff --git a/crypto/ocsp/ocsp_prn.c b/crypto/ocsp/ocsp_prn.c index 654ddbc7ff..6fe65b6c0d 100644 --- a/crypto/ocsp/ocsp_prn.c +++ b/crypto/ocsp/ocsp_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -79,7 +79,9 @@ const char *OCSP_crl_reason_str(long s) {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, - {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} + {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"}, + {OCSP_REVOKED_STATUS_PRIVILEGEWITHDRAWN, "privilegeWithdrawn"}, + {OCSP_REVOKED_STATUS_AACOMPROMISE, "aACompromise"} }; return table2string(s, reason_tbl); } diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index fa07539d7e..b0827e9a22 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -36,7 +36,7 @@ static int ocsp_verify_signer(X509 *signer, int response, int ret = -1; if (ctx == NULL) { - ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB); goto end; } if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) { @@ -154,7 +154,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, } end: - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); sk_X509_free(untrusted); return ret; } diff --git a/crypto/ocsp/v3_ocsp.c b/crypto/ocsp/v3_ocsp.c index 2250208a15..4f54b7ceab 100644 --- a/crypto/ocsp/v3_ocsp.c +++ b/crypto/ocsp/v3_ocsp.c @@ -203,7 +203,7 @@ static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) err: if ((pos == NULL) || (*pos != os)) ASN1_OCTET_STRING_free(os); - ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OCSP, ERR_R_ASN1_LIB); return NULL; } diff --git a/crypto/packet.c b/crypto/packet.c index 927bb3f80f..6a43b35655 100644 --- a/crypto/packet.c +++ b/crypto/packet.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,6 +9,9 @@ #include "internal/cryptlib.h" #include "internal/packet.h" +#if !defined OPENSSL_NO_QUIC && !defined FIPS_MODULE +# include "internal/packet_quic.h" +#endif #include #define DEFAULT_BUF_SIZE 256 @@ -104,10 +107,8 @@ static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) pkt->curr = 0; pkt->written = 0; - if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) return 0; - } if (lenbytes == 0) return 1; @@ -225,6 +226,20 @@ static int put_value(unsigned char *data, uint64_t value, size_t len) return 1; } +#if !defined OPENSSL_NO_QUIC && !defined FIPS_MODULE +static int put_quic_value(unsigned char *data, size_t value, size_t len) +{ + if (data == NULL) + return 1; + + /* Value too large for field. */ + if (ossl_quic_vlint_encode_len(value) > len) + return 0; + + ossl_quic_vlint_encode_n(data, value, len); + return 1; +} +#endif /* * Internal helper function used by WPACKET_close(), WPACKET_finish() and @@ -261,10 +276,20 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) if (sub->lenbytes > 0) { unsigned char *buf = GETBUF(pkt); - if (buf != NULL - && !put_value(&buf[sub->packet_len], packlen, - sub->lenbytes)) - return 0; + if (buf != NULL) { +#if !defined OPENSSL_NO_QUIC && !defined FIPS_MODULE + if ((sub->flags & WPACKET_FLAGS_QUIC_VLINT) == 0) { + if (!put_value(&buf[sub->packet_len], packlen, sub->lenbytes)) + return 0; + } else { + if (!put_quic_value(&buf[sub->packet_len], packlen, sub->lenbytes)) + return 0; + } +#else + if (!put_value(&buf[sub->packet_len], packlen, sub->lenbytes)) + return 0; +#endif + } } else if (pkt->endfirst && sub->parent != NULL && (packlen != 0 || (sub->flags @@ -351,10 +376,8 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) if (lenbytes > 0 && pkt->endfirst) return 0; - if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) return 0; - } sub->parent = pkt->subs; pkt->subs = sub; @@ -510,3 +533,58 @@ void WPACKET_cleanup(WPACKET *pkt) } pkt->subs = NULL; } + +#if !defined OPENSSL_NO_QUIC && !defined FIPS_MODULE + +int WPACKET_start_quic_sub_packet_bound(WPACKET *pkt, size_t max_len) +{ + size_t enclen = ossl_quic_vlint_encode_len(max_len); + + if (enclen == 0) + return 0; + + if (WPACKET_start_sub_packet_len__(pkt, enclen) == 0) + return 0; + + pkt->subs->flags |= WPACKET_FLAGS_QUIC_VLINT; + return 1; +} + +int WPACKET_start_quic_sub_packet(WPACKET *pkt) +{ + /* + * Assume no (sub)packet will exceed 4GiB, thus the 8-byte encoding need not + * be used. + */ + return WPACKET_start_quic_sub_packet_bound(pkt, OSSL_QUIC_VLINT_4B_MIN); +} + +int WPACKET_quic_sub_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) +{ + if (!WPACKET_start_quic_sub_packet_bound(pkt, len) + || !WPACKET_allocate_bytes(pkt, len, allocbytes) + || !WPACKET_close(pkt)) + return 0; + + return 1; +} + +/* + * Write a QUIC variable-length integer to the packet. + */ +int WPACKET_quic_write_vlint(WPACKET *pkt, uint64_t v) +{ + unsigned char *b = NULL; + size_t enclen = ossl_quic_vlint_encode_len(v); + + if (enclen == 0) + return 0; + + if (WPACKET_allocate_bytes(pkt, enclen, &b) == 0) + return 0; + + ossl_quic_vlint_encode(b, v); + return 1; +} + +#endif diff --git a/crypto/param_build.c b/crypto/param_build.c index 4fc6c0319f..2392e5909c 100644 --- a/crypto/param_build.c +++ b/crypto/param_build.c @@ -32,7 +32,7 @@ typedef struct { union { /* * These fields are never directly addressed, but their sizes are - * imporant so that all native types can be copied here without overrun. + * important so that all native types can be copied here without overrun. */ ossl_intmax_t i; ossl_uintmax_t u; @@ -54,10 +54,8 @@ static OSSL_PARAM_BLD_DEF *param_push(OSSL_PARAM_BLD *bld, const char *key, { OSSL_PARAM_BLD_DEF *pd = OPENSSL_zalloc(sizeof(*pd)); - if (pd == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (pd == NULL) return NULL; - } pd->key = key; pd->type = type; pd->size = size; @@ -192,23 +190,20 @@ int OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD *bld, const char *key, return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL); } -int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key, - const BIGNUM *bn) -{ - return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, - bn == NULL ? 0 : BN_num_bytes(bn)); -} - -int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key, - const BIGNUM *bn, size_t sz) +static int push_BN(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn, size_t sz, int type) { int n, secure = 0; OSSL_PARAM_BLD_DEF *pd; + if (!ossl_assert(type == OSSL_PARAM_UNSIGNED_INTEGER + || type == OSSL_PARAM_INTEGER)) + return 0; + if (bn != NULL) { - if (BN_is_negative(bn)) { + if (type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative(bn)) { ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED, - "Negative big numbers are unsupported for OSSL_PARAM"); + "Negative big numbers are unsupported for OSSL_PARAM_UNSIGNED_INTEGER"); return 0; } @@ -228,13 +223,32 @@ int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key, if (sz == 0) sz++; } - pd = param_push(bld, key, sz, sz, OSSL_PARAM_UNSIGNED_INTEGER, secure); + pd = param_push(bld, key, sz, sz, type, secure); if (pd == NULL) return 0; pd->bn = bn; return 1; } +int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn) +{ + if (bn != NULL && BN_is_negative(bn)) + return push_BN(bld, key, bn, BN_num_bytes(bn) + 1, + OSSL_PARAM_INTEGER); + return push_BN(bld, key, bn, bn == NULL ? 0 : BN_num_bytes(bn), + OSSL_PARAM_UNSIGNED_INTEGER); +} + +int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key, + const BIGNUM *bn, size_t sz) +{ + if (bn != NULL && BN_is_negative(bn)) + return push_BN(bld, key, bn, BN_num_bytes(bn), + OSSL_PARAM_INTEGER); + return push_BN(bld, key, bn, sz, OSSL_PARAM_UNSIGNED_INTEGER); +} + int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, const char *buf, size_t bsize) { @@ -332,7 +346,10 @@ static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param, param[i].data = p; if (pd->bn != NULL) { /* BIGNUM */ - BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size); + if (pd->type == OSSL_PARAM_UNSIGNED_INTEGER) + BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size); + else + BN_signed_bn2native(pd->bn, (unsigned char *)p, pd->size); } else if (pd->type == OSSL_PARAM_OCTET_PTR || pd->type == OSSL_PARAM_UTF8_PTR) { /* PTR */ @@ -375,7 +392,6 @@ OSSL_PARAM *OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld) } params = OPENSSL_malloc(total); if (params == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_secure_free(s); return NULL; } diff --git a/crypto/params.c b/crypto/params.c index aa24ff941c..f2582b0927 100644 --- a/crypto/params.c +++ b/crypto/params.c @@ -14,6 +14,8 @@ #include "internal/thread_once.h" #include "internal/numbers.h" #include "internal/endian.h" +#include "internal/params.h" +#include "internal/packet.h" /* Shortcuts for raising errors that are widely used */ #define err_unsigned_negative \ @@ -1036,24 +1038,32 @@ OSSL_PARAM OSSL_PARAM_construct_time_t(const char *key, time_t *buf) int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val) { - BIGNUM *b; + BIGNUM *b = NULL; if (val == NULL || p == NULL) { err_null_argument; return 0; } - if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) { + + switch (p->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + b = BN_native2bn(p->data, (int)p->data_size, *val); + break; + case OSSL_PARAM_INTEGER: + b = BN_signed_native2bn(p->data, (int)p->data_size, *val); + break; + default: err_bad_type; - return 0; + break; } - b = BN_native2bn(p->data, (int)p->data_size, *val); - if (b != NULL) { - *val = b; - return 1; + if (b == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_BN_LIB); + return 0; } - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); - return 0; + + *val = b; + return 1; } int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) @@ -1069,18 +1079,15 @@ int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) err_null_argument; return 0; } - if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER) { + if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative(val)) { err_bad_type; return 0; } - /* For the moment, only positive values are permitted */ - if (BN_is_negative(val)) { - err_unsigned_negative; - return 0; - } - bytes = (size_t)BN_num_bytes(val); + /* We add 1 byte for signed numbers, to make space for a sign extension */ + if (p->data_type == OSSL_PARAM_INTEGER) + bytes++; /* We make sure that at least one byte is used, so zero is properly set */ if (bytes == 0) bytes++; @@ -1090,9 +1097,22 @@ int OSSL_PARAM_set_BN(OSSL_PARAM *p, const BIGNUM *val) return 1; if (p->data_size >= bytes) { p->return_size = p->data_size; - if (BN_bn2nativepad(val, p->data, p->data_size) >= 0) - return 1; - ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW); + + switch (p->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + if (BN_bn2nativepad(val, p->data, p->data_size) >= 0) + return 1; + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW); + break; + case OSSL_PARAM_INTEGER: + if (BN_signed_bn2native(val, p->data, p->data_size) >= 0) + return 1; + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW); + break; + default: + err_bad_type; + break; + } return 0; } err_too_small; @@ -1289,10 +1309,8 @@ static int get_string_internal(const OSSL_PARAM *p, void **val, if (*val == NULL) { char *const q = OPENSSL_malloc(alloc_sz); - if (q == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (q == NULL) return 0; - } *val = q; *max_len = alloc_sz; } @@ -1485,6 +1503,111 @@ OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf, return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, bsize); } +/* + * Extract the parameter into an allocated buffer. + * Any existing allocation in *out is cleared and freed. + * + * Returns 1 on success, 0 on failure and -1 if there are no matching params. + * + * *out and *out_len are guaranteed to be untouched if this function + * doesn't return success. + */ +int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name, + unsigned char **out, size_t *out_len) +{ + const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name); + void *buf = NULL; + size_t len = 0; + + if (p == NULL) + return -1; + + if (p->data != NULL + && p->data_size > 0 + && !OSSL_PARAM_get_octet_string(p, &buf, 0, &len)) + return 0; + + OPENSSL_clear_free(*out, *out_len); + *out = buf; + *out_len = len; + return 1; +} + +static int setbuf_fromparams(const OSSL_PARAM *p, const char *name, + unsigned char *out, size_t *outlen) +{ + int ret = 0; + WPACKET pkt; + + if (out == NULL) { + if (!WPACKET_init_null(&pkt, 0)) + return 0; + } else { + if (!WPACKET_init_static_len(&pkt, out, *outlen, 0)) + return 0; + } + + for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, name)) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) + goto err; + if (p->data != NULL + && p->data_size != 0 + && !WPACKET_memcpy(&pkt, p->data, p->data_size)) + goto err; + } + if (!WPACKET_get_total_written(&pkt, outlen) + || !WPACKET_finish(&pkt)) + goto err; + ret = 1; +err: + WPACKET_cleanup(&pkt); + return ret; +} + +int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name, + unsigned char **out, + size_t *out_len, size_t maxsize) +{ + const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name); + unsigned char *res; + size_t sz = 0; + + if (p == NULL) + return -1; + + /* Calculate the total size */ + if (!setbuf_fromparams(p, name, NULL, &sz)) + return 0; + + /* Check that it's not oversized */ + if (maxsize > 0 && sz > maxsize) + return 0; + + /* Special case zero length */ + if (sz == 0) { + if ((res = OPENSSL_zalloc(1)) == NULL) + return 0; + goto fin; + } + + /* Allocate the buffer */ + res = OPENSSL_malloc(sz); + if (res == NULL) + return 0; + + /* Concat one or more OSSL_KDF_PARAM_INFO fields */ + if (!setbuf_fromparams(p, name, res, &sz)) { + OPENSSL_clear_free(res, sz); + return 0; + } + + fin: + OPENSSL_clear_free(*out, *out_len); + *out = res; + *out_len = sz; + return 1; +} + OSSL_PARAM OSSL_PARAM_construct_end(void) { OSSL_PARAM end = OSSL_PARAM_END; diff --git a/crypto/params_dup.c b/crypto/params_dup.c index fd4764a7cd..769629bbf3 100644 --- a/crypto/params_dup.c +++ b/crypto/params_dup.c @@ -37,11 +37,8 @@ static int ossl_param_buf_alloc(OSSL_PARAM_BUF *out, size_t extra_blocks, size_t sz = OSSL_PARAM_ALIGN_SIZE * (extra_blocks + out->blocks); out->alloc = is_secure ? OPENSSL_secure_zalloc(sz) : OPENSSL_zalloc(sz); - if (out->alloc == NULL) { - ERR_raise(ERR_LIB_CRYPTO, is_secure ? CRYPTO_R_SECURE_MALLOC_FAILURE - : ERR_R_MALLOC_FAILURE); + if (out->alloc == NULL) return 0; - } out->alloc_sz = sz; out->cur = out->alloc + extra_blocks; return 1; @@ -185,10 +182,8 @@ OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *p1, const OSSL_PARAM *p2) /* Allocate enough space to store the merged parameters */ params = OPENSSL_zalloc((list1_sz + list2_sz + 1) * sizeof(*p1)); - if (params == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (params == NULL) return NULL; - } dst = params; p1cur = list1; p2cur = list2; diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c index 360f8933e1..38e0927195 100644 --- a/crypto/params_from_text.c +++ b/crypto/params_from_text.c @@ -8,7 +8,7 @@ * https://www.openssl.org/source/license.html */ -#include +#include "internal/common.h" /* for HAS_PREFIX */ #include #include #include @@ -35,10 +35,7 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key, * ishex is used to translate legacy style string controls in hex format * to octet string parameters. */ - *ishex = strncmp(key, "hex", 3) == 0; - - if (*ishex) - key += 3; + *ishex = CHECK_AND_SKIP_PREFIX(key, "hex"); p = *paramdef = OSSL_PARAM_locate_const(paramdefs, key); if (found != NULL) @@ -213,10 +210,8 @@ int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, ¶mdef, &ishex, &buf_n, &tmpbn, found)) goto err; - if ((buf = OPENSSL_zalloc(buf_n > 0 ? buf_n : 1)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_zalloc(buf_n > 0 ? buf_n : 1)) == NULL) goto err; - } ok = construct_from_text(to, paramdef, value, value_n, ishex, buf, buf_n, tmpbn); diff --git a/crypto/params_idx.c b/crypto/params_idx.c new file mode 100644 index 0000000000..e7c611e083 --- /dev/null +++ b/crypto/params_idx.c @@ -0,0 +1,2710 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from crypto/params_idx.c.in + * + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + + +#include "internal/e_os.h" +#include "internal/param_names.h" +#include + +/* Machine generated TRIE -- generated by util/perl/OpenSSL/paramnames.pm */ +int ossl_param_find_pidx(const char *s) +{ + switch(s[0]) { + default: + break; + case 'a': + switch(s[1]) { + default: + break; + case 'c': + if (strcmp("vp-info", s + 2) == 0) + return PIDX_KDF_PARAM_X942_ACVPINFO; + break; + case 'd': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_KDF_PARAM_ARGON2_AD; + } + break; + case 'e': + if (strcmp("ad", s + 2) == 0) + return PIDX_CIPHER_PARAM_AEAD; + break; + case 'l': + switch(s[2]) { + default: + break; + case 'g': + switch(s[3]) { + default: + break; + case '_': + if (strcmp("id_param", s + 4) == 0) + return PIDX_CIPHER_PARAM_ALGORITHM_ID_PARAMS; + break; + case 'i': + if (strcmp("d-absent", s + 4) == 0) + return PIDX_DIGEST_PARAM_ALGID_ABSENT; + break; + case 'o': + if (strcmp("rithm-id", s + 4) == 0) + return PIDX_SIGNATURE_PARAM_ALGORITHM_ID; + } + break; + case 'i': + if (strcmp("as", s + 3) == 0) + return PIDX_STORE_PARAM_ALIAS; + } + break; + case '\0': + return PIDX_PKEY_PARAM_EC_A; + } + break; + case 'b': + switch(s[1]) { + default: + break; + case 'a': + if (strcmp("sis-type", s + 2) == 0) + return PIDX_PKEY_PARAM_EC_CHAR2_TYPE; + break; + case 'i': + if (strcmp("ts", s + 2) == 0) + return PIDX_PKEY_PARAM_BITS; + break; + case 'l': + switch(s[2]) { + default: + break; + case 'o': + switch(s[3]) { + default: + break; + case 'c': + switch(s[4]) { + default: + break; + case 'k': + switch(s[5]) { + default: + break; + case '-': + if (strcmp("size", s + 6) == 0) + return PIDX_MAC_PARAM_BLOCK_SIZE; + break; + case '_': + if (strcmp("padding", s + 6) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_BLOCK_PADDING; + break; + case 's': + if (strcmp("ize", s + 6) == 0) + return PIDX_CIPHER_PARAM_BLOCK_SIZE; + } + } + } + } + break; + case 'u': + if (strcmp("ildinfo", s + 2) == 0) + return PIDX_PROV_PARAM_BUILDINFO; + break; + case '\0': + return PIDX_PKEY_PARAM_EC_B; + } + break; + case 'c': + switch(s[1]) { + default: + break; + case '-': + if (strcmp("rounds", s + 2) == 0) + return PIDX_MAC_PARAM_C_ROUNDS; + break; + case 'e': + if (strcmp("kalg", s + 2) == 0) + return PIDX_KDF_PARAM_CEK_ALG; + break; + case 'i': + if (strcmp("pher", s + 2) == 0) + return PIDX_ALG_PARAM_CIPHER; + break; + case 'o': + switch(s[2]) { + default: + break; + case 'f': + if (strcmp("actor", s + 3) == 0) + return PIDX_PKEY_PARAM_EC_COFACTOR; + break; + case 'n': + switch(s[3]) { + default: + break; + case 's': + if (strcmp("tant", s + 4) == 0) + return PIDX_KDF_PARAM_CONSTANT; + break; + case 't': + if (strcmp("ext-string", s + 4) == 0) + return PIDX_SIGNATURE_PARAM_CONTEXT_STRING; + } + } + break; + case 't': + switch(s[2]) { + default: + break; + case 's': + switch(s[3]) { + default: + break; + case '_': + if (strcmp("mode", s + 4) == 0) + return PIDX_CIPHER_PARAM_CTS_MODE; + break; + case '\0': + return PIDX_CIPHER_PARAM_CTS; + } + } + break; + case 'u': + switch(s[2]) { + default: + break; + case 's': + switch(s[3]) { + default: + break; + case 't': + switch(s[4]) { + default: + break; + case 'o': + switch(s[5]) { + default: + break; + case 'm': + switch(s[6]) { + default: + break; + case '-': + if (strcmp("iv", s + 7) == 0) + return PIDX_CIPHER_PARAM_CUSTOM_IV; + break; + case '\0': + return PIDX_MAC_PARAM_CUSTOM; + } + } + } + } + } + } + break; + case 'd': + switch(s[1]) { + default: + break; + case '-': + if (strcmp("rounds", s + 2) == 0) + return PIDX_MAC_PARAM_D_ROUNDS; + break; + case 'a': + switch(s[2]) { + default: + break; + case 't': + switch(s[3]) { + default: + break; + case 'a': + switch(s[4]) { + default: + break; + case '-': + switch(s[5]) { + default: + break; + case 's': + if (strcmp("tructure", s + 6) == 0) + return PIDX_OBJECT_PARAM_DATA_STRUCTURE; + break; + case 't': + if (strcmp("ype", s + 6) == 0) + return PIDX_OBJECT_PARAM_DATA_TYPE; + } + break; + case '\0': + return PIDX_KDF_PARAM_DATA; + } + } + } + break; + case 'e': + switch(s[2]) { + default: + break; + case 'c': + if (strcmp("oded-from-explicit", s + 3) == 0) + return PIDX_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS; + break; + case 'f': + if (strcmp("ault-digest", s + 3) == 0) + return PIDX_PKEY_PARAM_DEFAULT_DIGEST; + break; + case 's': + if (strcmp("c", s + 3) == 0) + return PIDX_OBJECT_PARAM_DESC; + } + break; + case 'h': + if (strcmp("kem-ikm", s + 2) == 0) + return PIDX_PKEY_PARAM_DHKEM_IKM; + break; + case 'i': + switch(s[2]) { + default: + break; + case 'g': + switch(s[3]) { + default: + break; + case 'e': + switch(s[4]) { + default: + break; + case 's': + switch(s[5]) { + default: + break; + case 't': + switch(s[6]) { + default: + break; + case '-': + switch(s[7]) { + default: + break; + case 'n': + if (strcmp("oinit", s + 8) == 0) + return PIDX_MAC_PARAM_DIGEST_NOINIT; + break; + case 'o': + if (strcmp("neshot", s + 8) == 0) + return PIDX_MAC_PARAM_DIGEST_ONESHOT; + break; + case 'p': + if (strcmp("rops", s + 8) == 0) + return PIDX_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS; + break; + case 's': + if (strcmp("ize", s + 8) == 0) + return PIDX_PKEY_PARAM_DIGEST_SIZE; + } + break; + case '\0': + return PIDX_STORE_PARAM_DIGEST; + } + } + } + } + break; + case 's': + if (strcmp("tid", s + 3) == 0) + return PIDX_PKEY_PARAM_DIST_ID; + } + break; + case 'r': + if (strcmp("bg-no-trunc-md", s + 2) == 0) + return PIDX_PROV_PARAM_DRBG_TRUNC_DIGEST; + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_D; + } + break; + case 'e': + switch(s[1]) { + default: + break; + case 'a': + if (strcmp("rly_clean", s + 2) == 0) + return PIDX_KDF_PARAM_EARLY_CLEAN; + break; + case 'c': + if (strcmp("dh-cofactor-mode", s + 2) == 0) + return PIDX_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE; + break; + case 'n': + switch(s[2]) { + default: + break; + case 'c': + switch(s[3]) { + default: + break; + case 'o': + switch(s[4]) { + default: + break; + case 'd': + switch(s[5]) { + default: + break; + case 'e': + if (strcmp("d-pub-key", s + 6) == 0) + return PIDX_PKEY_PARAM_ENCODED_PUBLIC_KEY; + break; + case 'i': + if (strcmp("ng", s + 6) == 0) + return PIDX_PKEY_PARAM_EC_ENCODING; + } + } + break; + case 'r': + if (strcmp("ypt-level", s + 4) == 0) + return PIDX_ENCODER_PARAM_ENCRYPT_LEVEL; + } + break; + case 'g': + if (strcmp("ine", s + 3) == 0) + return PIDX_ALG_PARAM_ENGINE; + break; + case 't': + switch(s[3]) { + default: + break; + case 'r': + switch(s[4]) { + default: + break; + case 'o': + switch(s[5]) { + default: + break; + case 'p': + switch(s[6]) { + default: + break; + case 'y': + switch(s[7]) { + default: + break; + case '_': + if (strcmp("required", s + 8) == 0) + return PIDX_DRBG_PARAM_ENTROPY_REQUIRED; + break; + case '\0': + return PIDX_KDF_PARAM_HMACDRBG_ENTROPY; + } + } + } + } + } + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_E; + break; + case 'x': + if (strcmp("pect", s + 2) == 0) + return PIDX_STORE_PARAM_EXPECT; + } + break; + case 'f': + switch(s[1]) { + default: + break; + case 'i': + switch(s[2]) { + default: + break; + case 'e': + if (strcmp("ld-type", s + 3) == 0) + return PIDX_PKEY_PARAM_EC_FIELD_TYPE; + break; + case 'n': + if (strcmp("gerprint", s + 3) == 0) + return PIDX_STORE_PARAM_FINGERPRINT; + } + } + break; + case 'g': + switch(s[1]) { + default: + break; + case 'e': + switch(s[2]) { + default: + break; + case 'n': + switch(s[3]) { + default: + break; + case 'e': + switch(s[4]) { + default: + break; + case 'r': + switch(s[5]) { + default: + break; + case 'a': + switch(s[6]) { + default: + break; + case 't': + switch(s[7]) { + default: + break; + case 'e': + switch(s[8]) { + default: + break; + case '\0': + return PIDX_RAND_PARAM_GENERATE; + } + break; + case 'o': + if (strcmp("r", s + 8) == 0) + return PIDX_PKEY_PARAM_EC_GENERATOR; + } + } + } + } + } + } + break; + case 'i': + if (strcmp("ndex", s + 2) == 0) + return PIDX_PKEY_PARAM_FFC_GINDEX; + break; + case 'r': + switch(s[2]) { + default: + break; + case 'o': + switch(s[3]) { + default: + break; + case 'u': + switch(s[4]) { + default: + break; + case 'p': + switch(s[5]) { + default: + break; + case '-': + if (strcmp("check", s + 6) == 0) + return PIDX_PKEY_PARAM_EC_GROUP_CHECK_TYPE; + break; + case '\0': + return PIDX_PKEY_PARAM_GROUP_NAME; + } + } + } + } + break; + case '\0': + return PIDX_PKEY_PARAM_FFC_G; + } + break; + case 'h': + switch(s[1]) { + default: + break; + case 'a': + if (strcmp("s-randkey", s + 2) == 0) + return PIDX_CIPHER_PARAM_HAS_RAND_KEY; + break; + case 'i': + if (strcmp("ndex", s + 2) == 0) + return PIDX_PKEY_PARAM_FFC_H; + } + break; + case 'i': + switch(s[1]) { + default: + break; + case 'd': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_KDF_PARAM_PKCS12_ID; + } + break; + case 'k': + if (strcmp("me", s + 2) == 0) + return PIDX_KEM_PARAM_IKME; + break; + case 'm': + if (strcmp("plicit-rejection", s + 2) == 0) + return PIDX_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION; + break; + case 'n': + switch(s[2]) { + default: + break; + case 'c': + if (strcmp("lude-public", s + 3) == 0) + return PIDX_PKEY_PARAM_EC_INCLUDE_PUBLIC; + break; + case 'f': + if (strcmp("o", s + 3) == 0) + return PIDX_KDF_PARAM_INFO; + break; + case 'p': + if (strcmp("ut-type", s + 3) == 0) + return PIDX_STORE_PARAM_INPUT_TYPE; + break; + case 's': + if (strcmp("tance", s + 3) == 0) + return PIDX_SIGNATURE_PARAM_INSTANCE; + } + break; + case 't': + switch(s[2]) { + default: + break; + case 'e': + switch(s[3]) { + default: + break; + case 'r': + switch(s[4]) { + default: + break; + case 'a': + if (strcmp("tion", s + 5) == 0) + return PIDX_GEN_PARAM_ITERATION; + break; + case '\0': + return PIDX_KDF_PARAM_ITER; + } + } + } + break; + case 'v': + switch(s[2]) { + default: + break; + case 'l': + if (strcmp("en", s + 3) == 0) + return PIDX_CIPHER_PARAM_IVLEN; + break; + case '\0': + return PIDX_MAC_PARAM_IV; + } + } + break; + case 'j': + switch(s[1]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_FFC_COFACTOR; + } + break; + case 'k': + switch(s[1]) { + default: + break; + case '1': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_CHAR2_PP_K1; + } + break; + case '2': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_CHAR2_PP_K2; + } + break; + case '3': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_CHAR2_PP_K3; + } + break; + case 'a': + if (strcmp("t", s + 2) == 0) + return PIDX_SIGNATURE_PARAM_KAT; + break; + case 'd': + switch(s[2]) { + default: + break; + case 'f': + switch(s[3]) { + default: + break; + case '-': + switch(s[4]) { + default: + break; + case 'd': + switch(s[5]) { + default: + break; + case 'i': + switch(s[6]) { + default: + break; + case 'g': + switch(s[7]) { + default: + break; + case 'e': + switch(s[8]) { + default: + break; + case 's': + switch(s[9]) { + default: + break; + case 't': + switch(s[10]) { + default: + break; + case '-': + if (strcmp("props", s + 11) == 0) + return PIDX_EXCHANGE_PARAM_KDF_DIGEST_PROPS; + break; + case '\0': + return PIDX_EXCHANGE_PARAM_KDF_DIGEST; + } + } + } + } + } + } + break; + case 'o': + if (strcmp("utlen", s + 5) == 0) + return PIDX_EXCHANGE_PARAM_KDF_OUTLEN; + break; + case 't': + if (strcmp("ype", s + 5) == 0) + return PIDX_EXCHANGE_PARAM_KDF_TYPE; + break; + case 'u': + if (strcmp("km", s + 5) == 0) + return PIDX_EXCHANGE_PARAM_KDF_UKM; + } + } + } + break; + case 'e': + switch(s[2]) { + default: + break; + case 'y': + switch(s[3]) { + default: + break; + case 'b': + if (strcmp("its", s + 4) == 0) + return PIDX_CIPHER_PARAM_RC2_KEYBITS; + break; + case 'l': + if (strcmp("en", s + 4) == 0) + return PIDX_CIPHER_PARAM_KEYLEN; + break; + case '\0': + return PIDX_MAC_PARAM_KEY; + } + } + } + break; + case 'l': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'b': + if (strcmp("el", s + 3) == 0) + return PIDX_KDF_PARAM_LABEL; + break; + case 'n': + if (strcmp("es", s + 3) == 0) + return PIDX_KDF_PARAM_ARGON2_LANES; + } + } + break; + case 'm': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'c': + switch(s[3]) { + default: + break; + case 'k': + if (strcmp("ey", s + 4) == 0) + return PIDX_CIPHER_PARAM_AEAD_MAC_KEY; + break; + case 'l': + if (strcmp("en", s + 4) == 0) + return PIDX_KDF_PARAM_MAC_SIZE; + break; + case '\0': + return PIDX_ALG_PARAM_MAC; + } + break; + case 'n': + if (strcmp("datory-digest", s + 3) == 0) + return PIDX_PKEY_PARAM_MANDATORY_DIGEST; + break; + case 'x': + switch(s[3]) { + default: + break; + case '-': + if (strcmp("size", s + 4) == 0) + return PIDX_PKEY_PARAM_MAX_SIZE; + break; + case '_': + switch(s[4]) { + default: + break; + case 'a': + if (strcmp("dinlen", s + 5) == 0) + return PIDX_DRBG_PARAM_MAX_ADINLEN; + break; + case 'e': + switch(s[5]) { + default: + break; + case 'a': + if (strcmp("rly_data", s + 6) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_MAX_EARLY_DATA; + break; + case 'n': + if (strcmp("tropylen", s + 6) == 0) + return PIDX_DRBG_PARAM_MAX_ENTROPYLEN; + } + break; + case 'f': + if (strcmp("rag_len", s + 5) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN; + break; + case 'n': + if (strcmp("oncelen", s + 5) == 0) + return PIDX_DRBG_PARAM_MAX_NONCELEN; + break; + case 'p': + if (strcmp("erslen", s + 5) == 0) + return PIDX_DRBG_PARAM_MAX_PERSLEN; + break; + case 'r': + if (strcmp("equest", s + 5) == 0) + return PIDX_RAND_PARAM_MAX_REQUEST; + } + break; + case 'i': + if (strcmp("um_length", s + 4) == 0) + return PIDX_DRBG_PARAM_MAX_LENGTH; + break; + case 'm': + if (strcmp("em_bytes", s + 4) == 0) + return PIDX_KDF_PARAM_SCRYPT_MAXMEM; + } + } + break; + case 'e': + if (strcmp("mcost", s + 2) == 0) + return PIDX_KDF_PARAM_ARGON2_MEMCOST; + break; + case 'g': + switch(s[2]) { + default: + break; + case 'f': + switch(s[3]) { + default: + break; + case '1': + switch(s[4]) { + default: + break; + case '-': + switch(s[5]) { + default: + break; + case 'd': + if (strcmp("igest", s + 6) == 0) + return PIDX_PKEY_PARAM_MGF1_DIGEST; + break; + case 'p': + if (strcmp("roperties", s + 6) == 0) + return PIDX_PKEY_PARAM_MGF1_PROPERTIES; + } + } + break; + case '\0': + return PIDX_PKEY_PARAM_MASKGENFUNC; + } + } + break; + case 'i': + switch(s[2]) { + default: + break; + case 'c': + if (strcmp("alg", s + 3) == 0) + return PIDX_DIGEST_PARAM_MICALG; + break; + case 'n': + switch(s[3]) { + default: + break; + case '_': + switch(s[4]) { + default: + break; + case 'e': + if (strcmp("ntropylen", s + 5) == 0) + return PIDX_DRBG_PARAM_MIN_ENTROPYLEN; + break; + case 'n': + if (strcmp("oncelen", s + 5) == 0) + return PIDX_DRBG_PARAM_MIN_NONCELEN; + } + break; + case 'i': + if (strcmp("um_length", s + 4) == 0) + return PIDX_DRBG_PARAM_MIN_LENGTH; + } + } + break; + case 'o': + switch(s[2]) { + default: + break; + case 'd': + switch(s[3]) { + default: + break; + case 'e': + switch(s[4]) { + default: + break; + case '\0': + return PIDX_CIPHER_PARAM_MODE; + } + break; + case 'u': + if (strcmp("le-filename", s + 4) == 0) + return PIDX_PROV_PARAM_CORE_MODULE_FILENAME; + } + } + break; + case '\0': + return PIDX_PKEY_PARAM_EC_CHAR2_M; + } + break; + case 'n': + switch(s[1]) { + default: + break; + case 'a': + if (strcmp("me", s + 2) == 0) + return PIDX_STORE_PARAM_ISSUER; + break; + case 'o': + switch(s[2]) { + default: + break; + case 'n': + switch(s[3]) { + default: + break; + case 'c': + switch(s[4]) { + default: + break; + case 'e': + switch(s[5]) { + default: + break; + case '-': + if (strcmp("type", s + 6) == 0) + return PIDX_SIGNATURE_PARAM_NONCE_TYPE; + break; + case '\0': + return PIDX_KDF_PARAM_HMACDRBG_NONCE; + } + } + } + } + break; + case 'u': + if (strcmp("m", s + 2) == 0) + return PIDX_CIPHER_PARAM_NUM; + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_N; + } + break; + case 'o': + switch(s[1]) { + default: + break; + case 'a': + if (strcmp("ep-label", s + 2) == 0) + return PIDX_ASYM_CIPHER_PARAM_OAEP_LABEL; + break; + case 'p': + switch(s[2]) { + default: + break; + case 'e': + switch(s[3]) { + default: + break; + case 'n': + if (strcmp("ssl-version", s + 4) == 0) + return PIDX_PROV_PARAM_CORE_VERSION; + break; + case 'r': + if (strcmp("ation", s + 4) == 0) + return PIDX_KEM_PARAM_OPERATION; + } + break; + case 't': + if (strcmp("ions", s + 3) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_OPTIONS; + } + break; + case 'r': + if (strcmp("der", s + 2) == 0) + return PIDX_PKEY_PARAM_EC_ORDER; + } + break; + case 'p': + switch(s[1]) { + default: + break; + case '1': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_P1; + } + break; + case '2': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_P2; + } + break; + case 'a': + switch(s[2]) { + default: + break; + case 'd': + switch(s[3]) { + default: + break; + case '-': + switch(s[4]) { + default: + break; + case 'm': + if (strcmp("ode", s + 5) == 0) + return PIDX_PKEY_PARAM_PAD_MODE; + break; + case 't': + if (strcmp("ype", s + 5) == 0) + return PIDX_DIGEST_PARAM_PAD_TYPE; + } + break; + case 'd': + if (strcmp("ing", s + 4) == 0) + return PIDX_CIPHER_PARAM_PADDING; + break; + case '\0': + return PIDX_EXCHANGE_PARAM_PAD; + } + break; + case 'r': + switch(s[3]) { + default: + break; + case 't': + switch(s[4]) { + default: + break; + case 'y': + switch(s[5]) { + default: + break; + case 'u': + if (strcmp("-info", s + 6) == 0) + return PIDX_KDF_PARAM_X942_PARTYUINFO; + break; + case 'v': + if (strcmp("-info", s + 6) == 0) + return PIDX_KDF_PARAM_X942_PARTYVINFO; + } + } + } + break; + case 's': + if (strcmp("s", s + 3) == 0) + return PIDX_KDF_PARAM_PASSWORD; + } + break; + case 'b': + if (strcmp("its", s + 2) == 0) + return PIDX_PKEY_PARAM_FFC_PBITS; + break; + case 'c': + if (strcmp("ounter", s + 2) == 0) + return PIDX_PKEY_PARAM_FFC_PCOUNTER; + break; + case 'k': + if (strcmp("cs5", s + 2) == 0) + return PIDX_KDF_PARAM_PKCS5; + break; + case 'o': + switch(s[2]) { + default: + break; + case 'i': + if (strcmp("nt-format", s + 3) == 0) + return PIDX_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT; + break; + case 't': + if (strcmp("ential", s + 3) == 0) + return PIDX_GEN_PARAM_POTENTIAL; + } + break; + case 'r': + switch(s[2]) { + default: + break; + case 'e': + switch(s[3]) { + default: + break; + case 'd': + if (strcmp("iction_resistance", s + 4) == 0) + return PIDX_DRBG_PARAM_PREDICTION_RESISTANCE; + break; + case 'f': + if (strcmp("ix", s + 4) == 0) + return PIDX_KDF_PARAM_PREFIX; + } + break; + case 'i': + switch(s[3]) { + default: + break; + case 'm': + if (strcmp("es", s + 4) == 0) + return PIDX_PKEY_PARAM_RSA_PRIMES; + break; + case 'v': + switch(s[4]) { + default: + break; + case '_': + if (strcmp("len", s + 5) == 0) + return PIDX_PKEY_PARAM_DH_PRIV_LEN; + break; + case '\0': + return PIDX_PKEY_PARAM_PRIV_KEY; + } + } + break; + case 'o': + switch(s[3]) { + default: + break; + case 'p': + if (strcmp("erties", s + 4) == 0) + return PIDX_STORE_PARAM_PROPERTIES; + break; + case 'v': + if (strcmp("ider-name", s + 4) == 0) + return PIDX_PROV_PARAM_CORE_PROV_NAME; + } + } + break; + case 'u': + if (strcmp("b", s + 2) == 0) + return PIDX_PKEY_PARAM_PUB_KEY; + break; + case '\0': + return PIDX_PKEY_PARAM_FFC_P; + } + break; + case 'q': + switch(s[1]) { + default: + break; + case '1': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_Q1; + } + break; + case '2': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_Q2; + } + break; + case 'b': + if (strcmp("its", s + 2) == 0) + return PIDX_PKEY_PARAM_FFC_QBITS; + break; + case '\0': + return PIDX_PKEY_PARAM_FFC_Q; + break; + case 'x': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_PUB_X; + } + break; + case 'y': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_PUB_Y; + } + } + break; + case 'r': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'n': + switch(s[3]) { + default: + break; + case 'd': + switch(s[4]) { + default: + break; + case 'k': + if (strcmp("ey", s + 5) == 0) + return PIDX_CIPHER_PARAM_RANDOM_KEY; + break; + case 'o': + if (strcmp("m_data", s + 5) == 0) + return PIDX_DRBG_PARAM_RANDOM_DATA; + } + } + } + break; + case 'e': + switch(s[2]) { + default: + break; + case 'a': + switch(s[3]) { + default: + break; + case 'd': + switch(s[4]) { + default: + break; + case '_': + switch(s[5]) { + default: + break; + case 'a': + if (strcmp("head", s + 6) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD; + break; + case 'b': + if (strcmp("uffer_len", s + 6) == 0) + return PIDX_LIBSSL_RECORD_LAYER_READ_BUFFER_LEN; + } + } + } + break; + case 'f': + if (strcmp("erence", s + 3) == 0) + return PIDX_OBJECT_PARAM_REFERENCE; + break; + case 's': + switch(s[3]) { + default: + break; + case 'e': + switch(s[4]) { + default: + break; + case 'e': + switch(s[5]) { + default: + break; + case 'd': + switch(s[6]) { + default: + break; + case '_': + switch(s[7]) { + default: + break; + case 'c': + if (strcmp("ounter", s + 8) == 0) + return PIDX_DRBG_PARAM_RESEED_COUNTER; + break; + case 'r': + if (strcmp("equests", s + 8) == 0) + return PIDX_DRBG_PARAM_RESEED_REQUESTS; + break; + case 't': + switch(s[8]) { + default: + break; + case 'i': + switch(s[9]) { + default: + break; + case 'm': + switch(s[10]) { + default: + break; + case 'e': + switch(s[11]) { + default: + break; + case '_': + if (strcmp("interval", s + 12) == 0) + return PIDX_DRBG_PARAM_RESEED_TIME_INTERVAL; + break; + case '\0': + return PIDX_DRBG_PARAM_RESEED_TIME; + } + } + } + } + } + } + } + } + } + } + break; + case 'o': + if (strcmp("unds", s + 2) == 0) + return PIDX_CIPHER_PARAM_ROUNDS; + break; + case 's': + switch(s[2]) { + default: + break; + case 'a': + switch(s[3]) { + default: + break; + case '-': + switch(s[4]) { + default: + break; + case 'c': + switch(s[5]) { + default: + break; + case 'o': + switch(s[6]) { + default: + break; + case 'e': + switch(s[7]) { + default: + break; + case 'f': + switch(s[8]) { + default: + break; + case 'f': + switch(s[9]) { + default: + break; + case 'i': + switch(s[10]) { + default: + break; + case 'c': + switch(s[11]) { + default: + break; + case 'i': + switch(s[12]) { + default: + break; + case 'e': + switch(s[13]) { + default: + break; + case 'n': + switch(s[14]) { + default: + break; + case 't': + switch(s[15]) { + default: + break; + case '1': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT1; + } + break; + case '2': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT2; + } + break; + case '3': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT3; + } + break; + case '4': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT4; + } + break; + case '5': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT5; + } + break; + case '6': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT6; + } + break; + case '7': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT7; + } + break; + case '8': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT8; + } + break; + case '9': + switch(s[16]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT9; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_COEFFICIENT; + } + } + } + } + } + } + } + } + } + } + } + break; + case 'e': + switch(s[5]) { + default: + break; + case 'x': + switch(s[6]) { + default: + break; + case 'p': + switch(s[7]) { + default: + break; + case 'o': + switch(s[8]) { + default: + break; + case 'n': + switch(s[9]) { + default: + break; + case 'e': + switch(s[10]) { + default: + break; + case 'n': + switch(s[11]) { + default: + break; + case 't': + switch(s[12]) { + default: + break; + case '1': + switch(s[13]) { + default: + break; + case '0': + switch(s[14]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT10; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT1; + } + break; + case '2': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT2; + } + break; + case '3': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT3; + } + break; + case '4': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT4; + } + break; + case '5': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT5; + } + break; + case '6': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT6; + } + break; + case '7': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT7; + } + break; + case '8': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT8; + } + break; + case '9': + switch(s[13]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT9; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_EXPONENT; + } + } + } + } + } + } + } + } + break; + case 'f': + switch(s[5]) { + default: + break; + case 'a': + switch(s[6]) { + default: + break; + case 'c': + switch(s[7]) { + default: + break; + case 't': + switch(s[8]) { + default: + break; + case 'o': + switch(s[9]) { + default: + break; + case 'r': + switch(s[10]) { + default: + break; + case '1': + switch(s[11]) { + default: + break; + case '0': + switch(s[12]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR10; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR1; + } + break; + case '2': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR2; + } + break; + case '3': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR3; + } + break; + case '4': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR4; + } + break; + case '5': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR5; + } + break; + case '6': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR6; + } + break; + case '7': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR7; + } + break; + case '8': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR8; + } + break; + case '9': + switch(s[11]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR9; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_FACTOR; + } + } + } + } + } + } + } + } + } + break; + case '\0': + return PIDX_KDF_PARAM_KBKDF_R; + } + break; + case 's': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'f': + if (strcmp("eprime-generator", s + 3) == 0) + return PIDX_PKEY_PARAM_DH_GENERATOR; + break; + case 'l': + switch(s[3]) { + default: + break; + case 't': + switch(s[4]) { + default: + break; + case 'l': + if (strcmp("en", s + 5) == 0) + return PIDX_SIGNATURE_PARAM_PSS_SALTLEN; + break; + case '\0': + return PIDX_KDF_PARAM_SALT; + } + } + break; + case 'v': + if (strcmp("e-parameters", s + 3) == 0) + return PIDX_ENCODER_PARAM_SAVE_PARAMETERS; + } + break; + case 'e': + switch(s[2]) { + default: + break; + case 'c': + switch(s[3]) { + default: + break; + case 'r': + if (strcmp("et", s + 4) == 0) + return PIDX_KDF_PARAM_SECRET; + break; + case 'u': + switch(s[4]) { + default: + break; + case 'r': + switch(s[5]) { + default: + break; + case 'i': + switch(s[6]) { + default: + break; + case 't': + switch(s[7]) { + default: + break; + case 'y': + switch(s[8]) { + default: + break; + case '-': + switch(s[9]) { + default: + break; + case 'b': + if (strcmp("its", s + 10) == 0) + return PIDX_PKEY_PARAM_SECURITY_BITS; + break; + case 'c': + if (strcmp("hecks", s + 10) == 0) + return PIDX_PROV_PARAM_SECURITY_CHECKS; + } + } + } + } + } + } + } + break; + case 'e': + if (strcmp("d", s + 3) == 0) + return PIDX_PKEY_PARAM_FFC_SEED; + break; + case 'r': + if (strcmp("ial", s + 3) == 0) + return PIDX_STORE_PARAM_SERIAL; + break; + case 's': + if (strcmp("sion_id", s + 3) == 0) + return PIDX_KDF_PARAM_SSHKDF_SESSION_ID; + } + break; + case 'i': + if (strcmp("ze", s + 2) == 0) + return PIDX_MAC_PARAM_SIZE; + break; + case 'p': + if (strcmp("eed", s + 2) == 0) + return PIDX_CIPHER_PARAM_SPEED; + break; + case 's': + if (strcmp("l3-ms", s + 2) == 0) + return PIDX_DIGEST_PARAM_SSL3_MS; + break; + case 't': + switch(s[2]) { + default: + break; + case '-': + switch(s[3]) { + default: + break; + case 'd': + if (strcmp("esc", s + 4) == 0) + return PIDX_PROV_PARAM_SELF_TEST_DESC; + break; + case 'p': + if (strcmp("hase", s + 4) == 0) + return PIDX_PROV_PARAM_SELF_TEST_PHASE; + break; + case 't': + if (strcmp("ype", s + 4) == 0) + return PIDX_PROV_PARAM_SELF_TEST_TYPE; + } + break; + case 'a': + switch(s[3]) { + default: + break; + case 't': + switch(s[4]) { + default: + break; + case 'e': + switch(s[5]) { + default: + break; + case '\0': + return PIDX_RAND_PARAM_STATE; + } + break; + case 'u': + if (strcmp("s", s + 5) == 0) + return PIDX_PROV_PARAM_STATUS; + } + } + break; + case 'r': + switch(s[3]) { + default: + break; + case 'e': + switch(s[4]) { + default: + break; + case 'a': + if (strcmp("m_mac", s + 5) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_STREAM_MAC; + break; + case 'n': + if (strcmp("gth", s + 5) == 0) + return PIDX_RAND_PARAM_STRENGTH; + } + } + } + break; + case 'u': + switch(s[2]) { + default: + break; + case 'b': + if (strcmp("ject", s + 3) == 0) + return PIDX_STORE_PARAM_SUBJECT; + break; + case 'p': + switch(s[3]) { + default: + break; + case 'p': + switch(s[4]) { + default: + break; + case '-': + switch(s[5]) { + default: + break; + case 'p': + switch(s[6]) { + default: + break; + case 'r': + if (strcmp("ivinfo", s + 7) == 0) + return PIDX_KDF_PARAM_X942_SUPP_PRIVINFO; + break; + case 'u': + if (strcmp("binfo", s + 7) == 0) + return PIDX_KDF_PARAM_X942_SUPP_PUBINFO; + } + } + } + } + } + } + break; + case 't': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'g': + switch(s[3]) { + default: + break; + case 'l': + if (strcmp("en", s + 4) == 0) + return PIDX_CIPHER_PARAM_AEAD_TAGLEN; + break; + case '\0': + return PIDX_CIPHER_PARAM_AEAD_TAG; + } + } + break; + case 'e': + switch(s[2]) { + default: + break; + case 's': + switch(s[3]) { + default: + break; + case 't': + switch(s[4]) { + default: + break; + case '_': + switch(s[5]) { + default: + break; + case 'e': + if (strcmp("ntropy", s + 6) == 0) + return PIDX_RAND_PARAM_TEST_ENTROPY; + break; + case 'n': + if (strcmp("once", s + 6) == 0) + return PIDX_RAND_PARAM_TEST_NONCE; + } + } + } + } + break; + case 'h': + if (strcmp("reads", s + 2) == 0) + return PIDX_KDF_PARAM_THREADS; + break; + case 'l': + switch(s[2]) { + default: + break; + case 's': + switch(s[3]) { + default: + break; + case '-': + switch(s[4]) { + default: + break; + case 'c': + if (strcmp("lient-version", s + 5) == 0) + return PIDX_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION; + break; + case 'd': + if (strcmp("ata-size", s + 5) == 0) + return PIDX_MAC_PARAM_TLS_DATA_SIZE; + break; + case 'g': + switch(s[5]) { + default: + break; + case 'r': + switch(s[6]) { + default: + break; + case 'o': + switch(s[7]) { + default: + break; + case 'u': + switch(s[8]) { + default: + break; + case 'p': + switch(s[9]) { + default: + break; + case '-': + switch(s[10]) { + default: + break; + case 'a': + if (strcmp("lg", s + 11) == 0) + return PIDX_CAPABILITY_TLS_GROUP_ALG; + break; + case 'i': + switch(s[11]) { + default: + break; + case 'd': + switch(s[12]) { + default: + break; + case '\0': + return PIDX_CAPABILITY_TLS_GROUP_ID; + } + break; + case 's': + if (strcmp("-kem", s + 12) == 0) + return PIDX_CAPABILITY_TLS_GROUP_IS_KEM; + } + break; + case 'n': + switch(s[11]) { + default: + break; + case 'a': + switch(s[12]) { + default: + break; + case 'm': + switch(s[13]) { + default: + break; + case 'e': + switch(s[14]) { + default: + break; + case '-': + if (strcmp("internal", s + 15) == 0) + return PIDX_CAPABILITY_TLS_GROUP_NAME_INTERNAL; + break; + case '\0': + return PIDX_CAPABILITY_TLS_GROUP_NAME; + } + } + } + } + break; + case 's': + if (strcmp("ec-bits", s + 11) == 0) + return PIDX_CAPABILITY_TLS_GROUP_SECURITY_BITS; + } + } + } + } + } + } + break; + case 'm': + switch(s[5]) { + default: + break; + case 'a': + switch(s[6]) { + default: + break; + case 'c': + switch(s[7]) { + default: + break; + case '-': + if (strcmp("size", s + 8) == 0) + return PIDX_CIPHER_PARAM_TLS_MAC_SIZE; + break; + case '\0': + return PIDX_CIPHER_PARAM_TLS_MAC; + } + break; + case 'x': + switch(s[7]) { + default: + break; + case '-': + switch(s[8]) { + default: + break; + case 'd': + if (strcmp("tls", s + 9) == 0) + return PIDX_CAPABILITY_TLS_GROUP_MAX_DTLS; + break; + case 't': + if (strcmp("ls", s + 9) == 0) + return PIDX_CAPABILITY_TLS_GROUP_MAX_TLS; + } + } + } + break; + case 'i': + switch(s[6]) { + default: + break; + case 'n': + switch(s[7]) { + default: + break; + case '-': + switch(s[8]) { + default: + break; + case 'd': + if (strcmp("tls", s + 9) == 0) + return PIDX_CAPABILITY_TLS_GROUP_MIN_DTLS; + break; + case 't': + if (strcmp("ls", s + 9) == 0) + return PIDX_CAPABILITY_TLS_GROUP_MIN_TLS; + } + } + } + break; + case 'u': + if (strcmp("lti", s + 6) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK; + } + break; + case 'n': + if (strcmp("egotiated-version", s + 5) == 0) + return PIDX_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION; + break; + case 's': + switch(s[5]) { + default: + break; + case 'i': + switch(s[6]) { + default: + break; + case 'g': + switch(s[7]) { + default: + break; + case 'a': + switch(s[8]) { + default: + break; + case 'l': + switch(s[9]) { + default: + break; + case 'g': + switch(s[10]) { + default: + break; + case '-': + switch(s[11]) { + default: + break; + case 'c': + if (strcmp("ode-point", s + 12) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_CODE_POINT; + break; + case 'h': + switch(s[12]) { + default: + break; + case 'a': + switch(s[13]) { + default: + break; + case 's': + switch(s[14]) { + default: + break; + case 'h': + switch(s[15]) { + default: + break; + case '-': + switch(s[16]) { + default: + break; + case 'n': + if (strcmp("ame", s + 17) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_HASH_NAME; + break; + case 'o': + if (strcmp("id", s + 17) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_HASH_OID; + } + } + } + } + } + break; + case 'i': + if (strcmp("ana-name", s + 12) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_IANA_NAME; + break; + case 'k': + switch(s[12]) { + default: + break; + case 'e': + switch(s[13]) { + default: + break; + case 'y': + switch(s[14]) { + default: + break; + case 't': + switch(s[15]) { + default: + break; + case 'y': + switch(s[16]) { + default: + break; + case 'p': + switch(s[17]) { + default: + break; + case 'e': + switch(s[18]) { + default: + break; + case '-': + if (strcmp("oid", s + 19) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_KEYTYPE_OID; + break; + case '\0': + return PIDX_CAPABILITY_TLS_SIGALG_KEYTYPE; + } + } + } + } + } + } + } + break; + case 'n': + if (strcmp("ame", s + 12) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_NAME; + break; + case 'o': + if (strcmp("id", s + 12) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_OID; + break; + case 's': + switch(s[12]) { + default: + break; + case 'e': + if (strcmp("c-bits", s + 13) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_SECURITY_BITS; + break; + case 'i': + switch(s[13]) { + default: + break; + case 'g': + switch(s[14]) { + default: + break; + case '-': + switch(s[15]) { + default: + break; + case 'n': + if (strcmp("ame", s + 16) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_SIG_NAME; + break; + case 'o': + if (strcmp("id", s + 16) == 0) + return PIDX_CAPABILITY_TLS_SIGALG_SIG_OID; + } + } + } + } + } + } + } + } + } + } + } + break; + case 'v': + if (strcmp("ersion", s + 5) == 0) + return PIDX_CIPHER_PARAM_TLS_VERSION; + } + break; + case '1': + switch(s[4]) { + default: + break; + case '-': + if (strcmp("prf-ems-check", s + 5) == 0) + return PIDX_PROV_PARAM_TLS1_PRF_EMS_CHECK; + break; + case 'm': + switch(s[5]) { + default: + break; + case 'u': + switch(s[6]) { + default: + break; + case 'l': + switch(s[7]) { + default: + break; + case 't': + switch(s[8]) { + default: + break; + case 'i': + switch(s[9]) { + default: + break; + case '_': + switch(s[10]) { + default: + break; + case 'a': + switch(s[11]) { + default: + break; + case 'a': + switch(s[12]) { + default: + break; + case 'd': + switch(s[13]) { + default: + break; + case 'p': + if (strcmp("acklen", s + 14) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN; + break; + case '\0': + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD; + } + } + } + break; + case 'e': + switch(s[11]) { + default: + break; + case 'n': + switch(s[12]) { + default: + break; + case 'c': + switch(s[13]) { + default: + break; + case 'i': + if (strcmp("n", s + 14) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN; + break; + case 'l': + if (strcmp("en", s + 14) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN; + break; + case '\0': + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC; + } + } + } + break; + case 'i': + if (strcmp("nterleave", s + 11) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE; + break; + case 'm': + switch(s[11]) { + default: + break; + case 'a': + switch(s[12]) { + default: + break; + case 'x': + switch(s[13]) { + default: + break; + case 'b': + if (strcmp("ufsz", s + 14) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE; + break; + case 's': + if (strcmp("ndfrag", s + 14) == 0) + return PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT; + } + } + } + } + } + } + } + } + } + } + break; + case 'a': + switch(s[4]) { + default: + break; + case 'a': + switch(s[5]) { + default: + break; + case 'd': + switch(s[6]) { + default: + break; + case 'p': + if (strcmp("ad", s + 7) == 0) + return PIDX_CIPHER_PARAM_AEAD_TLS1_AAD_PAD; + break; + case '\0': + return PIDX_CIPHER_PARAM_AEAD_TLS1_AAD; + } + } + } + break; + case 'i': + switch(s[4]) { + default: + break; + case 'v': + switch(s[5]) { + default: + break; + case 'f': + if (strcmp("ixed", s + 6) == 0) + return PIDX_CIPHER_PARAM_AEAD_TLS1_IV_FIXED; + break; + case 'g': + if (strcmp("en", s + 6) == 0) + return PIDX_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN; + break; + case 'i': + if (strcmp("nv", s + 6) == 0) + return PIDX_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV; + } + } + break; + case 't': + if (strcmp("ree", s + 4) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_TLSTREE; + } + } + break; + case 'p': + switch(s[2]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_EC_CHAR2_TP_BASIS; + } + break; + case 'y': + if (strcmp("pe", s + 2) == 0) + return PIDX_OBJECT_PARAM_TYPE; + } + break; + case 'u': + switch(s[1]) { + default: + break; + case 'k': + if (strcmp("m", s + 2) == 0) + return PIDX_KDF_PARAM_UKM; + break; + case 'p': + if (strcmp("dated-iv", s + 2) == 0) + return PIDX_CIPHER_PARAM_UPDATED_IV; + break; + case 's': + switch(s[2]) { + default: + break; + case 'e': + switch(s[3]) { + default: + break; + case '-': + switch(s[4]) { + default: + break; + case 'b': + if (strcmp("its", s + 5) == 0) + return PIDX_CIPHER_PARAM_USE_BITS; + break; + case 'c': + if (strcmp("ofactor-flag", s + 5) == 0) + return PIDX_PKEY_PARAM_USE_COFACTOR_FLAG; + break; + case 'k': + if (strcmp("eybits", s + 5) == 0) + return PIDX_KDF_PARAM_X942_USE_KEYBITS; + break; + case 'l': + switch(s[5]) { + default: + break; + case '\0': + return PIDX_KDF_PARAM_KBKDF_USE_L; + } + break; + case 's': + if (strcmp("eparator", s + 5) == 0) + return PIDX_KDF_PARAM_KBKDF_USE_SEPARATOR; + } + break; + case '_': + switch(s[4]) { + default: + break; + case 'd': + if (strcmp("erivation_function", s + 5) == 0) + return PIDX_DRBG_PARAM_USE_DF; + break; + case 'e': + if (strcmp("tm", s + 5) == 0) + return PIDX_LIBSSL_RECORD_LAYER_PARAM_USE_ETM; + } + } + } + } + break; + case 'v': + switch(s[1]) { + default: + break; + case 'a': + switch(s[2]) { + default: + break; + case 'l': + switch(s[3]) { + default: + break; + case 'i': + switch(s[4]) { + default: + break; + case 'd': + switch(s[5]) { + default: + break; + case 'a': + switch(s[6]) { + default: + break; + case 't': + switch(s[7]) { + default: + break; + case 'e': + switch(s[8]) { + default: + break; + case '-': + switch(s[9]) { + default: + break; + case 'g': + switch(s[10]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_FFC_VALIDATE_G; + } + break; + case 'l': + if (strcmp("egacy", s + 10) == 0) + return PIDX_PKEY_PARAM_FFC_VALIDATE_LEGACY; + break; + case 'p': + if (strcmp("q", s + 10) == 0) + return PIDX_PKEY_PARAM_FFC_VALIDATE_PQ; + } + } + } + } + } + } + } + } + break; + case 'e': + if (strcmp("rsion", s + 2) == 0) + return PIDX_PROV_PARAM_VERSION; + } + break; + case 'x': + switch(s[1]) { + default: + break; + case 'c': + if (strcmp("ghash", s + 2) == 0) + return PIDX_KDF_PARAM_SSHKDF_XCGHASH; + break; + case 'o': + switch(s[2]) { + default: + break; + case 'f': + switch(s[3]) { + default: + break; + case 'l': + if (strcmp("en", s + 4) == 0) + return PIDX_DIGEST_PARAM_XOFLEN; + break; + case '\0': + return PIDX_MAC_PARAM_XOF; + } + } + break; + case 'p': + switch(s[2]) { + default: + break; + case '1': + switch(s[3]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XP1; + } + break; + case '2': + switch(s[3]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XP2; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XP; + } + break; + case 'q': + switch(s[2]) { + default: + break; + case '1': + switch(s[3]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XQ1; + } + break; + case '2': + switch(s[3]) { + default: + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XQ2; + } + break; + case '\0': + return PIDX_PKEY_PARAM_RSA_TEST_XQ; + } + break; + case 't': + if (strcmp("s_standard", s + 2) == 0) + return PIDX_CIPHER_PARAM_XTS_STANDARD; + } + } + return -1; +} + +/* End of TRIE */ diff --git a/crypto/params_idx.c.in b/crypto/params_idx.c.in new file mode 100644 index 0000000000..f04939b597 --- /dev/null +++ b/crypto/params_idx.c.in @@ -0,0 +1,21 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +{- +use OpenSSL::paramnames qw(produce_decoder); +-} + +#include "internal/e_os.h" +#include "internal/param_names.h" +#include + +/* Machine generated TRIE -- generated by util/perl/OpenSSL/paramnames.pm */ +{- produce_decoder(); -} +/* End of TRIE */ diff --git a/crypto/passphrase.c b/crypto/passphrase.c index fcc40f6dab..563c5acd1e 100644 --- a/crypto/passphrase.c +++ b/crypto/passphrase.c @@ -43,10 +43,8 @@ int ossl_pw_set_passphrase(struct ossl_passphrase_data_st *data, data->_.expl_passphrase.passphrase_copy = passphrase_len != 0 ? OPENSSL_memdup(passphrase, passphrase_len) : OPENSSL_malloc(1); - if (data->_.expl_passphrase.passphrase_copy == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (data->_.expl_passphrase.passphrase_copy == NULL) return 0; - } data->_.expl_passphrase.passphrase_len = passphrase_len; return 1; } @@ -130,7 +128,7 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len, } if ((ui = UI_new()) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); return 0; } @@ -143,16 +141,14 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len, /* Get an application constructed prompt */ prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); if (prompt == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); goto end; } /* Get a buffer for verification prompt */ ipass = OPENSSL_zalloc(pass_size + 1); - if (ipass == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (ipass == NULL) goto end; - } prompt_idx = UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD, @@ -165,10 +161,8 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len, if (verify) { /* Get a buffer for verification prompt */ vpass = OPENSSL_zalloc(pass_size + 1); - if (vpass == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (vpass == NULL) goto end; - } verify_idx = UI_add_verify_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD, vpass, 0, pass_size, @@ -269,7 +263,7 @@ int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len, ui_data = data->_.pem_password.password_cbarg; if (ui_method == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); return 0; } } else if (data->type == is_ui_method) { @@ -299,7 +293,6 @@ int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len, if (new_cache == NULL) { OPENSSL_cleanse(pass, *pass_len); - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } data->cached_passphrase = new_cache; diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index 061c9b9f68..f8dc4416e2 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -67,7 +67,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, if (sk == NULL) { if ((ret = sk_X509_INFO_new_null()) == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_CRYPTO_LIB); goto err; } } else diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 6cd998f216..9d8ad35ad3 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -218,18 +218,25 @@ static int check_pem(const char *nm, const char *name) return 0; } -static void pem_free(void *p, unsigned int flags, size_t num) +#define PEM_FREE(p, flags, num) \ + pem_free((p), (flags), (num), OPENSSL_FILE, OPENSSL_LINE) +static void pem_free(void *p, unsigned int flags, size_t num, + const char *file, int line) { if (flags & PEM_FLAG_SECURE) - OPENSSL_secure_clear_free(p, num); + CRYPTO_secure_clear_free(p, num, file, line); else - OPENSSL_free(p); + CRYPTO_free(p, file, line); } -static void *pem_malloc(int num, unsigned int flags) +#define PEM_MALLOC(num, flags) \ + pem_malloc((num), (flags), OPENSSL_FILE, OPENSSL_LINE) +static void *pem_malloc(int num, unsigned int flags, + const char *file, int line) { - return (flags & PEM_FLAG_SECURE) ? OPENSSL_secure_malloc(num) - : OPENSSL_malloc(num); + return (flags & PEM_FLAG_SECURE) ? CRYPTO_secure_malloc(num, file, line) + : CRYPTO_malloc(num, file, line); + } static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen, @@ -244,9 +251,9 @@ static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen, int ret = 0; do { - pem_free(nm, flags, 0); - pem_free(header, flags, 0); - pem_free(data, flags, len); + PEM_FREE(nm, flags, 0); + PEM_FREE(header, flags, 0); + PEM_FREE(data, flags, len); if (!PEM_read_bio_ex(bp, &nm, &header, &data, &len, flags)) { if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) ERR_add_error_data(2, "Expecting: ", name); @@ -268,10 +275,10 @@ static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen, err: if (!ret || pnm == NULL) - pem_free(nm, flags, 0); - pem_free(header, flags, 0); + PEM_FREE(nm, flags, 0); + PEM_FREE(header, flags, 0); if (!ret) - pem_free(data, flags, len); + PEM_FREE(data, flags, len); return ret; } @@ -345,10 +352,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, /* dsize + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data = OPENSSL_malloc((unsigned int)dsize + 20); - if (data == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (data == NULL) goto err; - } p = data; i = i2d(x, &p); @@ -484,11 +489,11 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, * presumably we also parse rfc822-style headers for S/MIME, so a common * abstraction might well be more generally useful. */ +#define PROC_TYPE "Proc-Type:" +#define ENCRYPTED "ENCRYPTED" +#define DEK_INFO "DEK-Info:" int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) { - static const char ProcType[] = "Proc-Type:"; - static const char ENCRYPTED[] = "ENCRYPTED"; - static const char DEKInfo[] = "DEK-Info:"; const EVP_CIPHER *enc = NULL; int ivlen; char *dekinfostart, c; @@ -498,11 +503,10 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) if ((header == NULL) || (*header == '\0') || (*header == '\n')) return 1; - if (strncmp(header, ProcType, sizeof(ProcType)-1) != 0) { + if (!CHECK_AND_SKIP_PREFIX(header, PROC_TYPE)) { ERR_raise(ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE); return 0; } - header += sizeof(ProcType)-1; header += strspn(header, " \t"); if (*header++ != '4' || *header++ != ',') @@ -510,12 +514,11 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) header += strspn(header, " \t"); /* We expect "ENCRYPTED" followed by optional white-space + line break */ - if (strncmp(header, ENCRYPTED, sizeof(ENCRYPTED)-1) != 0 || - strspn(header+sizeof(ENCRYPTED)-1, " \t\r\n") == 0) { + if (!CHECK_AND_SKIP_PREFIX(header, ENCRYPTED) || + strspn(header, " \t\r\n") == 0) { ERR_raise(ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED); return 0; } - header += sizeof(ENCRYPTED)-1; header += strspn(header, " \t\r"); if (*header++ != '\n') { ERR_raise(ERR_LIB_PEM, PEM_R_SHORT_HEADER); @@ -526,11 +529,10 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) * https://tools.ietf.org/html/rfc1421#section-4.6.1.3 * We expect "DEK-Info: algo[,hex-parameters]" */ - if (strncmp(header, DEKInfo, sizeof(DEKInfo)-1) != 0) { + if (!CHECK_AND_SKIP_PREFIX(header, DEK_INFO)) { ERR_raise(ERR_LIB_PEM, PEM_R_NOT_DEK_INFO); return 0; } - header += sizeof(DEKInfo)-1; header += strspn(header, " \t"); /* @@ -611,11 +613,11 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, int nlen, n, i, j, outl; unsigned char *buf = NULL; EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); - int reason = ERR_R_BUF_LIB; + int reason = 0; int retval = 0; if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; + reason = ERR_R_EVP_LIB; goto err; } @@ -624,43 +626,53 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header, if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) + (BIO_write(bp, "-----\n", 6) != 6)) { + reason = ERR_R_BIO_LIB; goto err; + } i = header != NULL ? strlen(header) : 0; if (i > 0) { - if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) { + reason = ERR_R_BIO_LIB; goto err; + } } buf = OPENSSL_malloc(PEM_BUFSIZE * 8); - if (buf == NULL) { - reason = ERR_R_MALLOC_FAILURE; + if (buf == NULL) goto err; - } i = j = 0; while (len > 0) { n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); - if (!EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n)) + if (!EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n)) { + reason = ERR_R_EVP_LIB; goto err; - if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) + } + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) { + reason = ERR_R_BIO_LIB; goto err; + } i += outl; len -= n; j += n; } EVP_EncodeFinal(ctx, buf, &outl); - if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) { + reason = ERR_R_BIO_LIB; goto err; + } if ((BIO_write(bp, "-----END ", 9) != 9) || (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) + (BIO_write(bp, "-----\n", 6) != 6)) { + reason = ERR_R_BIO_LIB; goto err; + } retval = i + outl; err: - if (retval == 0) + if (retval == 0 && reason != 0) ERR_raise(ERR_LIB_PEM, reason); EVP_ENCODE_CTX_free(ctx); OPENSSL_clear_free(buf, PEM_BUFSIZE * 8); @@ -733,12 +745,12 @@ static int sanitize_line(char *linebuf, int len, unsigned int flags, int first_c #define LINESIZE 255 /* Note trailing spaces for begin and end. */ -static const char beginstr[] = "-----BEGIN "; -static const char endstr[] = "-----END "; -static const char tailstr[] = "-----\n"; -#define BEGINLEN ((int)(sizeof(beginstr) - 1)) -#define ENDLEN ((int)(sizeof(endstr) - 1)) -#define TAILLEN ((int)(sizeof(tailstr) - 1)) +#define BEGINSTR "-----BEGIN " +#define ENDSTR "-----END " +#define TAILSTR "-----\n" +#define BEGINLEN ((int)(sizeof(BEGINSTR) - 1)) +#define ENDLEN ((int)(sizeof(ENDSTR) - 1)) +#define TAILLEN ((int)(sizeof(TAILSTR) - 1)) static int get_name(BIO *bp, char **name, unsigned int flags) { char *linebuf; @@ -750,11 +762,9 @@ static int get_name(BIO *bp, char **name, unsigned int flags) * Need to hold trailing NUL (accounted for by BIO_gets() and the newline * that will be added by sanitize_line() (the extra '1'). */ - linebuf = pem_malloc(LINESIZE + 1, flags); - if (linebuf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + linebuf = PEM_MALLOC(LINESIZE + 1, flags); + if (linebuf == NULL) return 0; - } do { len = BIO_gets(bp, linebuf, LINESIZE); @@ -769,21 +779,19 @@ static int get_name(BIO *bp, char **name, unsigned int flags) first_call = 0; /* Allow leading empty or non-matching lines. */ - } while (strncmp(linebuf, beginstr, BEGINLEN) != 0 + } while (!HAS_PREFIX(linebuf, BEGINSTR) || len < TAILLEN - || strncmp(linebuf + len - TAILLEN, tailstr, TAILLEN) != 0); + || !HAS_PREFIX(linebuf + len - TAILLEN, TAILSTR)); linebuf[len - TAILLEN] = '\0'; len = len - BEGINLEN - TAILLEN + 1; - *name = pem_malloc(len, flags); - if (*name == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + *name = PEM_MALLOC(len, flags); + if (*name == NULL) goto err; - } memcpy(*name, linebuf + BEGINLEN, len); ret = 1; err: - pem_free(linebuf, flags, LINESIZE + 1); + PEM_FREE(linebuf, flags, LINESIZE + 1); return ret; } @@ -818,11 +826,9 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, /* Need to hold trailing NUL (accounted for by BIO_gets() and the newline * that will be added by sanitize_line() (the extra '1'). */ - linebuf = pem_malloc(LINESIZE + 1, flags); - if (linebuf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + linebuf = PEM_MALLOC(LINESIZE + 1, flags); + if (linebuf == NULL) return 0; - } while(1) { flags_mask = ~0u; @@ -844,7 +850,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, if (memchr(linebuf, ':', len) != NULL) got_header = IN_HEADER; } - if (!strncmp(linebuf, endstr, ENDLEN) || got_header == IN_HEADER) + if (HAS_PREFIX(linebuf, ENDSTR) || got_header == IN_HEADER) flags_mask &= ~PEM_FLAG_ONLY_B64; len = sanitize_line(linebuf, len, flags & flags_mask, 0); @@ -867,11 +873,11 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, } /* Check for end of stream (which means there is no header). */ - if (strncmp(linebuf, endstr, ENDLEN) == 0) { - p = linebuf + ENDLEN; + p = linebuf; + if (CHECK_AND_SKIP_PREFIX(p, ENDSTR)) { namelen = strlen(name); if (strncmp(p, name, namelen) != 0 || - strncmp(p + namelen, tailstr, TAILLEN) != 0) { + !HAS_PREFIX(p + namelen, TAILSTR)) { ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE); goto err; } @@ -905,7 +911,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name, ret = 1; err: - pem_free(linebuf, flags, LINESIZE + 1); + PEM_FREE(linebuf, flags, LINESIZE + 1); return ret; } @@ -923,7 +929,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, BIO *headerB = NULL, *dataB = NULL; char *name = NULL; int len, taillen, headerlen, ret = 0; - BUF_MEM * buf_mem; + BUF_MEM *buf_mem; *len_out = 0; *name_out = *header = NULL; @@ -938,7 +944,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, headerB = BIO_new(bmeth); dataB = BIO_new(bmeth); if (headerB == NULL || dataB == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_BIO_LIB); goto end; } @@ -956,7 +962,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, ctx = EVP_ENCODE_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB); goto end; } @@ -972,8 +978,8 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, buf_mem->length = len; headerlen = BIO_get_mem_data(headerB, NULL); - *header = pem_malloc(headerlen + 1, flags); - *data = pem_malloc(len, flags); + *header = PEM_MALLOC(headerlen + 1, flags); + *data = PEM_MALLOC(len, flags); if (*header == NULL || *data == NULL) goto out_free; if (headerlen != 0 && BIO_read(headerB, *header, headerlen) != headerlen) @@ -988,13 +994,13 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header, goto end; out_free: - pem_free(*header, flags, 0); + PEM_FREE(*header, flags, 0); *header = NULL; - pem_free(*data, flags, 0); + PEM_FREE(*data, flags, 0); *data = NULL; end: EVP_ENCODE_CTX_free(ctx); - pem_free(name, flags, 0); + PEM_FREE(name, flags, 0); BIO_free(headerB); BIO_free(dataB); return ret; diff --git a/crypto/pem/pem_sign.c b/crypto/pem/pem_sign.c index 6ad8e43037..f6b0ff4dda 100644 --- a/crypto/pem/pem_sign.c +++ b/crypto/pem/pem_sign.c @@ -33,10 +33,8 @@ int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int m_len; m = OPENSSL_malloc(EVP_PKEY_get_size(pkey)); - if (m == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (m == NULL) goto err; - } if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) goto err; diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 21b16f5928..ed7905661b 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "internal/cryptlib.h" #include "crypto/pem.h" #include "crypto/evp.h" @@ -88,6 +90,7 @@ static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) case EVP_PKEY_RSA: if (EVP_PKEY_set1_RSA(pkey, key)) break; + ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB); EVP_PKEY_free(pkey); pkey = NULL; break; @@ -95,11 +98,14 @@ static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) case EVP_PKEY_DSA: if (EVP_PKEY_set1_DSA(pkey, key)) break; + ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB); EVP_PKEY_free(pkey); pkey = NULL; break; #endif } + } else { + ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB); } switch (evp_type) { @@ -113,8 +119,6 @@ static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) #endif } - if (pkey == NULL) - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); return pkey; } @@ -146,7 +150,7 @@ static EVP_PKEY *evp_pkey_new0_key(void *key, int evp_type) * Read the MSBLOB header and get relevant data from it. * * |pisdss| and |pispub| have a double role, as they can be used for - * discovery as well as to check the the blob meets expectations. + * discovery as well as to check the blob meets expectations. * |*pisdss| is the indicator for whether the key is a DSA key or not. * |*pispub| is the indicator for whether the key is public or not. * In both cases, the following input values apply: @@ -341,10 +345,8 @@ EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub) return NULL; } buf = OPENSSL_malloc(length); - if (buf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto err; - } p = buf; if (BIO_read(in, buf, length) != (int)length) { ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); @@ -382,22 +384,22 @@ DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen, dsa = DSA_new(); if (dsa == NULL) - goto memerr; + goto dsaerr; if (!read_lebn(&p, nbyte, &pbn)) - goto memerr; + goto bnerr; if (!read_lebn(&p, 20, &qbn)) - goto memerr; + goto bnerr; if (!read_lebn(&p, nbyte, &gbn)) - goto memerr; + goto bnerr; if (ispub) { if (!read_lebn(&p, nbyte, &pub_key)) - goto memerr; + goto bnerr; } else { if (!read_lebn(&p, 20, &priv_key)) - goto memerr; + goto bnerr; /* Set constant time flag before public key calculation */ BN_set_flags(priv_key, BN_FLG_CONSTTIME); @@ -405,28 +407,33 @@ DSA *ossl_b2i_DSA_after_header(const unsigned char **in, unsigned int bitlen, /* Calculate public key */ pub_key = BN_new(); if (pub_key == NULL) - goto memerr; + goto bnerr; if ((ctx = BN_CTX_new()) == NULL) - goto memerr; + goto bnerr; if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx)) - goto memerr; + goto bnerr; BN_CTX_free(ctx); ctx = NULL; } if (!DSA_set0_pqg(dsa, pbn, qbn, gbn)) - goto memerr; + goto dsaerr; pbn = qbn = gbn = NULL; if (!DSA_set0_key(dsa, pub_key, priv_key)) - goto memerr; + goto dsaerr; pub_key = priv_key = NULL; *in = p; return dsa; - memerr: - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + dsaerr: + ERR_raise(ERR_LIB_PEM, ERR_R_DSA_LIB); + goto err; + bnerr: + ERR_raise(ERR_LIB_PEM, ERR_R_BN_LIB); + + err: DSA_free(dsa); BN_free(pbn); BN_free(qbn); @@ -450,42 +457,48 @@ RSA *ossl_b2i_RSA_after_header(const unsigned char **in, unsigned int bitlen, rsa = RSA_new(); if (rsa == NULL) - goto memerr; + goto rsaerr; e = BN_new(); if (e == NULL) - goto memerr; + goto bnerr; if (!BN_set_word(e, read_ledword(&pin))) - goto memerr; + goto bnerr; if (!read_lebn(&pin, nbyte, &n)) - goto memerr; + goto bnerr; if (!ispub) { if (!read_lebn(&pin, hnbyte, &p)) - goto memerr; + goto bnerr; if (!read_lebn(&pin, hnbyte, &q)) - goto memerr; + goto bnerr; if (!read_lebn(&pin, hnbyte, &dmp1)) - goto memerr; + goto bnerr; if (!read_lebn(&pin, hnbyte, &dmq1)) - goto memerr; + goto bnerr; if (!read_lebn(&pin, hnbyte, &iqmp)) - goto memerr; + goto bnerr; if (!read_lebn(&pin, nbyte, &d)) - goto memerr; + goto bnerr; if (!RSA_set0_factors(rsa, p, q)) - goto memerr; + goto rsaerr; p = q = NULL; if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) - goto memerr; + goto rsaerr; dmp1 = dmq1 = iqmp = NULL; } if (!RSA_set0_key(rsa, n, e, d)) - goto memerr; + goto rsaerr; n = e = d = NULL; *in = pin; return rsa; - memerr: - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + + rsaerr: + ERR_raise(ERR_LIB_PEM, ERR_R_RSA_LIB); + goto err; + bnerr: + ERR_raise(ERR_LIB_PEM, ERR_R_BN_LIB); + + err: BN_free(e); BN_free(n); BN_free(p); @@ -577,7 +590,6 @@ static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub) p = *out; else { if ((p = OPENSSL_malloc(outlen)) == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); outlen = -1; goto end; } @@ -790,29 +802,34 @@ int ossl_do_PVK_header(const unsigned char **in, unsigned int length, } #ifndef OPENSSL_NO_RC4 -static int derive_pvk_key(unsigned char *key, +static int derive_pvk_key(unsigned char *key, size_t keylen, const unsigned char *salt, unsigned int saltlen, const unsigned char *pass, int passlen, OSSL_LIB_CTX *libctx, const char *propq) { - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - int rv = 0; - EVP_MD *sha1 = NULL; + EVP_KDF *kdf; + EVP_KDF_CTX *ctx; + OSSL_PARAM params[5], *p = params; + int rv; - if ((sha1 = EVP_MD_fetch(libctx, SN_sha1, propq)) == NULL) - goto err; - - if (mctx == NULL - || !EVP_DigestInit_ex(mctx, sha1, NULL) - || !EVP_DigestUpdate(mctx, salt, saltlen) - || !EVP_DigestUpdate(mctx, pass, passlen) - || !EVP_DigestFinal_ex(mctx, key, NULL)) - goto err; + if ((kdf = EVP_KDF_fetch(libctx, "PVKKDF", propq)) == NULL) + return 0; + ctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (ctx == NULL) + return 0; - rv = 1; -err: - EVP_MD_CTX_free(mctx); - EVP_MD_free(sha1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (void *)salt, saltlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + (void *)pass, passlen); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha1, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)propq, 0); + *p = OSSL_PARAM_construct_end(); + + rv = EVP_KDF_derive(ctx, key, keylen, params); + EVP_KDF_CTX_free(ctx); return rv; } #endif @@ -833,7 +850,7 @@ static void *do_PVK_body_key(const unsigned char **in, EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new(); if (cctx == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_EVP_LIB); goto err; } @@ -853,11 +870,9 @@ static void *do_PVK_body_key(const unsigned char **in, goto err; } enctmp = OPENSSL_malloc(keylen + 8); - if (enctmp == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (enctmp == NULL) goto err; - } - if (!derive_pvk_key(keybuf, p, saltlen, + if (!derive_pvk_key(keybuf, sizeof(keybuf), p, saltlen, (unsigned char *)psbuf, inlen, libctx, propq)) goto err; p += saltlen; @@ -934,10 +949,8 @@ static void *do_PVK_key_bio(BIO *in, pem_password_cb *cb, void *u, return 0; buflen = (int)keylen + saltlen; buf = OPENSSL_malloc(buflen); - if (buf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (buf == NULL) return 0; - } p = buf; if (BIO_read(in, buf, buflen) != buflen) { ERR_raise(ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT); @@ -1020,10 +1033,8 @@ static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, p = *out; } else { start = p = OPENSSL_malloc(outlen); - if (p == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (p == NULL) return -1; - } } cctx = EVP_CIPHER_CTX_new(); @@ -1063,7 +1074,7 @@ static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ); goto error; } - if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, + if (!derive_pvk_key(keybuf, sizeof(keybuf), salt, PVK_SALTLEN, (unsigned char *)psbuf, inlen, libctx, propq)) goto error; if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL) diff --git a/crypto/perlasm/arm-xlate.pl b/crypto/perlasm/arm-xlate.pl index 3bdae9c0c7..3b0dcad413 100755 --- a/crypto/perlasm/arm-xlate.pl +++ b/crypto/perlasm/arm-xlate.pl @@ -197,6 +197,16 @@ sub expand_line { } } + # ldr REG, #VALUE psuedo-instruction - avoid clang issue with Neon registers + # + if ($line =~ /^\s*ldr\s+([qd]\d\d?)\s*,\s*=(\w+)/i) { + # Immediate load via literal pool into qN or DN - clang max is 2^32-1 + my ($reg, $value) = ($1, $2); + # If $value is hex, 0x + 8 hex chars = 10 chars total will be okay + # If $value is decimal, 2^32 - 1 = 4294967295 will be okay (also 10 chars) + die("$line: immediate load via literal pool into $reg: value too large for clang - redo manually") if length($value) > 10; + } + print $line if ($line); print "\n"; } diff --git a/crypto/perlasm/riscv.pm b/crypto/perlasm/riscv.pm new file mode 100644 index 0000000000..90540b7dde --- /dev/null +++ b/crypto/perlasm/riscv.pm @@ -0,0 +1,259 @@ +#! /usr/bin/env perl +# This file is dual-licensed, meaning that you can use it under your +# choice of either of the following two licenses: +# +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You can obtain +# a copy in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +# +# or +# +# Copyright (c) 2023, Christoph Müllner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use strict; +use warnings; + +# Set $have_stacktrace to 1 if we have Devel::StackTrace +my $have_stacktrace = 0; +if (eval {require Devel::StackTrace;1;}) { + $have_stacktrace = 1; +} + +my @regs = map("x$_",(0..31)); +# Mapping from the RISC-V psABI ABI mnemonic names to the register number. +my @regaliases = ('zero','ra','sp','gp','tp','t0','t1','t2','s0','s1', + map("a$_",(0..7)), + map("s$_",(2..11)), + map("t$_",(3..6)) +); + +my %reglookup; +@reglookup{@regs} = @regs; +@reglookup{@regaliases} = @regs; + +# Takes a register name, possibly an alias, and converts it to a register index +# from 0 to 31 +sub read_reg { + my $reg = lc shift; + if (!exists($reglookup{$reg})) { + my $trace = ""; + if ($have_stacktrace) { + $trace = Devel::StackTrace->new->as_string; + } + die("Unknown register ".$reg."\n".$trace); + } + my $regstr = $reglookup{$reg}; + if (!($regstr =~ /^x([0-9]+)$/)) { + my $trace = ""; + if ($have_stacktrace) { + $trace = Devel::StackTrace->new->as_string; + } + die("Could not process register ".$reg."\n".$trace); + } + return $1; +} + +# Helper functions + +sub brev8_rv64i { + # brev8 without `brev8` instruction (only in Zbkb) + # Bit-reverses the first argument and needs two scratch registers + my $val = shift; + my $t0 = shift; + my $t1 = shift; + my $brev8_const = shift; + my $seq = <<___; + la $brev8_const, Lbrev8_const + + ld $t0, 0($brev8_const) # 0xAAAAAAAAAAAAAAAA + slli $t1, $val, 1 + and $t1, $t1, $t0 + and $val, $val, $t0 + srli $val, $val, 1 + or $val, $t1, $val + + ld $t0, 8($brev8_const) # 0xCCCCCCCCCCCCCCCC + slli $t1, $val, 2 + and $t1, $t1, $t0 + and $val, $val, $t0 + srli $val, $val, 2 + or $val, $t1, $val + + ld $t0, 16($brev8_const) # 0xF0F0F0F0F0F0F0F0 + slli $t1, $val, 4 + and $t1, $t1, $t0 + and $val, $val, $t0 + srli $val, $val, 4 + or $val, $t1, $val +___ + return $seq; +} + +sub sd_rev8_rv64i { + # rev8 without `rev8` instruction (only in Zbb or Zbkb) + # Stores the given value byte-reversed and needs one scratch register + my $val = shift; + my $addr = shift; + my $off = shift; + my $tmp = shift; + my $off0 = ($off + 0); + my $off1 = ($off + 1); + my $off2 = ($off + 2); + my $off3 = ($off + 3); + my $off4 = ($off + 4); + my $off5 = ($off + 5); + my $off6 = ($off + 6); + my $off7 = ($off + 7); + my $seq = <<___; + sb $val, $off7($addr) + srli $tmp, $val, 8 + sb $tmp, $off6($addr) + srli $tmp, $val, 16 + sb $tmp, $off5($addr) + srli $tmp, $val, 24 + sb $tmp, $off4($addr) + srli $tmp, $val, 32 + sb $tmp, $off3($addr) + srli $tmp, $val, 40 + sb $tmp, $off2($addr) + srli $tmp, $val, 48 + sb $tmp, $off1($addr) + srli $tmp, $val, 56 + sb $tmp, $off0($addr) +___ + return $seq; +} + +# Scalar crypto instructions + +sub aes64ds { + # Encoding for aes64ds rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0011101_00000_00000_000_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64dsm { + # Encoding for aes64dsm rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0011111_00000_00000_000_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64es { + # Encoding for aes64es rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0011001_00000_00000_000_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64esm { + # Encoding for aes64esm rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0011011_00000_00000_000_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64im { + # Encoding for aes64im rd, rs1 instruction on RV64 + # XXXXXXXXXXXX_ rs1 _XXX_ rd _XXXXXXX + my $template = 0b001100000000_00000_001_00000_0010011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + return ".word ".($template | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64ks1i { + # Encoding for aes64ks1i rd, rs1, rnum instruction on RV64 + # XXXXXXXX_rnum_ rs1 _XXX_ rd _XXXXXXX + my $template = 0b00110001_0000_00000_001_00000_0010011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rnum = shift; + return ".word ".($template | ($rnum << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub aes64ks2 { + # Encoding for aes64ks2 rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0111111_00000_00000_000_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub brev8 { + # brev8 rd, rs + my $template = 0b011010000111_00000_101_00000_0010011; + my $rd = read_reg shift; + my $rs = read_reg shift; + return ".word ".($template | ($rs << 15) | ($rd << 7)); +} + +sub clmul { + # Encoding for clmul rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0000101_00000_00000_001_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub clmulh { + # Encoding for clmulh rd, rs1, rs2 instruction on RV64 + # XXXXXXX_ rs2 _ rs1 _XXX_ rd _XXXXXXX + my $template = 0b0000101_00000_00000_011_00000_0110011; + my $rd = read_reg shift; + my $rs1 = read_reg shift; + my $rs2 = read_reg shift; + return ".word ".($template | ($rs2 << 20) | ($rs1 << 15) | ($rd << 7)); +} + +sub rev8 { + # Encoding for rev8 rd, rs instruction on RV64 + # XXXXXXXXXXXXX_ rs _XXX_ rd _XXXXXXX + my $template = 0b011010111000_00000_101_00000_0010011; + my $rd = read_reg shift; + my $rs = read_reg shift; + return ".word ".($template | ($rs << 15) | ($rd << 7)); +} + +1; diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl index 8dcde9eaca..2ec16c5571 100644 --- a/crypto/perlasm/x86asm.pl +++ b/crypto/perlasm/x86asm.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c index 6fd4184af5..64b17d74e8 100644 --- a/crypto/pkcs12/p12_add.c +++ b/crypto/pkcs12/p12_add.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,16 +24,16 @@ PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, PKCS12_SAFEBAG *safebag; if ((bag = PKCS12_BAGS_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } bag->type = OBJ_nid2obj(nid1); if (!ASN1_item_pack(obj, it, &bag->value.octet)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } if ((safebag = PKCS12_SAFEBAG_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } safebag->value.bag = bag; @@ -51,12 +51,12 @@ PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) PKCS7 *p7; if ((p7 = PKCS7_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } p7->type = OBJ_nid2obj(NID_pkcs7_data); if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } @@ -78,7 +78,9 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } - return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); + return ASN1_item_unpack_ex(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), + ossl_pkcs7_ctx_get0_libctx(&p7->ctx), + ossl_pkcs7_ctx_get0_propq(&p7->ctx)); } /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ @@ -94,7 +96,7 @@ PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen, EVP_CIPHER *pbe_ciph_fetch = NULL; if ((p7 = PKCS7_new_ex(ctx, propq)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { @@ -115,7 +117,7 @@ PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen, } if (pbe == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); @@ -181,6 +183,7 @@ int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) { STACK_OF(PKCS7) *p7s; + PKCS7_CTX *p7ctx; PKCS7 *p7; int i; @@ -188,8 +191,11 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); return NULL; } - p7s = ASN1_item_unpack(p12->authsafes->d.data, - ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); + p7ctx = &p12->authsafes->ctx; + p7s = ASN1_item_unpack_ex(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES), + ossl_pkcs7_ctx_get0_libctx(p7ctx), + ossl_pkcs7_ctx_get0_propq(p7ctx)); if (p7s != NULL) { for (i = 0; i < sk_PKCS7_num(p7s); i++) { p7 = sk_PKCS7_value(p7s, i); diff --git a/crypto/pkcs12/p12_asn.c b/crypto/pkcs12/p12_asn.c index aabbd38eef..e4247b27fc 100644 --- a/crypto/pkcs12/p12_asn.c +++ b/crypto/pkcs12/p12_asn.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ #include #include #include "p12_local.h" +#include "crypto/pkcs7.h" /* PKCS#12 ASN1 module */ @@ -21,7 +22,21 @@ ASN1_SEQUENCE(PKCS12) = { ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA) } ASN1_SEQUENCE_END(PKCS12) -IMPLEMENT_ASN1_FUNCTIONS(PKCS12) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(PKCS12, PKCS12, PKCS12) + +PKCS12 *PKCS12_new(void) +{ + return (PKCS12 *)ASN1_item_new(ASN1_ITEM_rptr(PKCS12)); +} + +void PKCS12_free(PKCS12 *p12) +{ + if (p12 != NULL && p12->authsafes != NULL) { + OPENSSL_free(p12->authsafes->ctx.propq); + p12->authsafes->ctx.propq = NULL; + } + ASN1_item_free((ASN1_VALUE *)p12, ASN1_ITEM_rptr(PKCS12)); +} ASN1_SEQUENCE(PKCS12_MAC_DATA) = { ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG), diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c index da228336eb..ea0d027c10 100644 --- a/crypto/pkcs12/p12_attr.c +++ b/crypto/pkcs12/p12_attr.c @@ -95,11 +95,11 @@ int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type, ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) { - X509_ATTRIBUTE *attrib; - int i; - i = X509at_get_attr_by_NID(attrs, attr_nid, -1); - attrib = X509at_get_attr(attrs, i); - return X509_ATTRIBUTE_get0_type(attrib, 0); + int i = X509at_get_attr_by_NID(attrs, attr_nid, -1); + + if (i < 0) + return NULL; + return X509_ATTRIBUTE_get0_type(X509at_get_attr(attrs, i), 0); } char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) @@ -119,3 +119,11 @@ PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag) { return bag->attrib; } + +void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, STACK_OF(X509_ATTRIBUTE) *attrs) +{ + if (bag->attrib != attrs) + sk_X509_ATTRIBUTE_free(bag->attrib); + + bag->attrib = attrs; +} diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index 26a444f868..2e40dd93c2 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -14,6 +14,8 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); +static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag); static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert, const char *name, @@ -23,27 +25,24 @@ static PKCS12_SAFEBAG *pkcs12_add_cert_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) { - int idx; - X509_ATTRIBUTE *attr; - idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + int idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + if (idx < 0) return 1; - attr = EVP_PKEY_get_attr(pkey, idx); - if (!X509at_add1_attr(&bag->attrib, attr)) - return 0; - return 1; + return X509at_add1_attr(&bag->attrib, EVP_PKEY_get_attr(pkey, idx)) != NULL; } -PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, - X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, - int iter, int mac_iter, int keytype, - OSSL_LIB_CTX *ctx, const char *propq) +PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg) { PKCS12 *p12 = NULL; STACK_OF(PKCS7) *safes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; PKCS12_SAFEBAG *bag = NULL; - int i; + int i, cbret; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; int namelen = -1; @@ -83,12 +82,30 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, } bag = pkcs12_add_cert_bag(&bags, cert, name, namelen, pkeyid, pkeyidlen); + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } /* Add all other certificates */ for (i = 0; i < sk_X509_num(ca); i++) { - if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) + if ((bag = PKCS12_add_cert(&bags, sk_X509_value(ca, i))) == NULL) goto err; + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } if (bags && !PKCS12_add_safe_ex(&safes, bags, nid_cert, iter, pass, @@ -114,6 +131,15 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, goto err; if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) goto err; + if (cb != NULL) { + cbret = cb(bag, cbarg); + if (cbret == -1) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED); + goto err; + } else if (cbret == 0) { + pkcs12_remove_bag(&bags, bag); + } + } } if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) @@ -145,6 +171,16 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, } +PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq) +{ + return PKCS12_create_ex2(pass, name, pkey, cert, ca, nid_key, nid_cert, + iter, mac_iter, keytype, ctx, propq, + NULL, NULL); +} + PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype) @@ -307,6 +343,22 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, return PKCS12_add_safe_ex(psafes, bags, nid_safe, iter, pass, NULL, NULL); } + +static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag) +{ + PKCS12_SAFEBAG *tmp; + + if (pbags == NULL || bag == NULL) + return 1; + + if ((tmp = sk_PKCS12_SAFEBAG_delete_ptr(*pbags, bag)) == NULL) + return 0; + + PKCS12_SAFEBAG_free(tmp); + return 1; +} + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag) { diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c index a5adafa954..b916db0ab1 100644 --- a/crypto/pkcs12/p12_decr.c +++ b/crypto/pkcs12/p12_decr.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,7 +28,7 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, int max_out_len, mac_len = 0; if (ctx == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_EVP_LIB); goto err; } @@ -67,10 +67,8 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, } } - if ((out = OPENSSL_malloc(max_out_len)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((out = OPENSSL_malloc(max_out_len)) == NULL) goto err; - } if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) { OPENSSL_free(out); @@ -180,7 +178,7 @@ ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor, int inlen; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } inlen = ASN1_item_i2d(obj, &in, it); diff --git a/crypto/pkcs12/p12_init.c b/crypto/pkcs12/p12_init.c index 45aa2f9154..537a1e3168 100644 --- a/crypto/pkcs12/p12_init.c +++ b/crypto/pkcs12/p12_init.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,7 +20,7 @@ PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq) PKCS12 *pkcs12; if ((pkcs12 = PKCS12_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } if (!ASN1_INTEGER_set(pkcs12->version, 3)) @@ -29,14 +29,14 @@ PKCS12 *PKCS12_init_ex(int mode, OSSL_LIB_CTX *ctx, const char *propq) ossl_pkcs7_set0_libctx(pkcs12->authsafes, ctx); if (!ossl_pkcs7_set1_propq(pkcs12->authsafes, propq)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_PKCS7_LIB); goto err; } switch (mode) { case NID_pkcs7_data: if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } break; @@ -56,3 +56,9 @@ PKCS12 *PKCS12_init(int mode) return PKCS12_init_ex(mode, NULL, NULL); } +const PKCS7_CTX *ossl_pkcs12_get0_pkcs7ctx(const PKCS12 *p12) +{ + if (p12 == NULL || p12->authsafes == NULL) + return NULL; + return &p12->authsafes->ctx; +} diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c index 41a2d7293e..9f7012a2c9 100644 --- a/crypto/pkcs12/p12_key.c +++ b/crypto/pkcs12/p12_key.c @@ -29,7 +29,7 @@ int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt, unipass = NULL; uniplen = 0; } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_PKCS12_LIB); return 0; } ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, @@ -59,7 +59,7 @@ int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt, unipass = NULL; uniplen = 0; } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_PKCS12_LIB); return 0; } ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter, diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c index 229b34cf64..0901dc9408 100644 --- a/crypto/pkcs12/p12_kiss.c +++ b/crypto/pkcs12/p12_kiss.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,10 +18,12 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + OSSL_LIB_CTX *libctx, const char *propq); static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + OSSL_LIB_CTX *libctx, const char *propq); /* * Parse and decrypt a PKCS#12 structure returning user key, user cert and @@ -49,33 +51,34 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, } /* Check the mac */ - - /* - * If password is zero length or NULL then try verifying both cases to - * determine which password is correct. The reason for this is that under - * PKCS#12 password based encryption no password and a zero length - * password are two different things... - */ - - if (pass == NULL || *pass == '\0') { - if (!PKCS12_mac_present(p12) - || PKCS12_verify_mac(p12, NULL, 0)) - pass = NULL; - else if (PKCS12_verify_mac(p12, "", 0)) - pass = ""; - else { + if (PKCS12_mac_present(p12)) { + /* + * If password is zero length or NULL then try verifying both cases to + * determine which password is correct. The reason for this is that under + * PKCS#12 password based encryption no password and a zero length + * password are two different things... + */ + if (pass == NULL || *pass == '\0') { + if (PKCS12_verify_mac(p12, NULL, 0)) + pass = NULL; + else if (PKCS12_verify_mac(p12, "", 0)) + pass = ""; + else { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + } else if (!PKCS12_verify_mac(p12, pass, -1)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); goto err; } - } else if (!PKCS12_verify_mac(p12, pass, -1)) { - ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); - goto err; + } else if (pass == NULL || *pass == '\0') { + pass = NULL; } /* If needed, allocate stack for other certificates */ if ((cert != NULL || ca != NULL) && (ocerts = sk_X509_new_null()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_CRYPTO_LIB); goto err; } @@ -125,7 +128,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, *cert = NULL; } X509_free(x); - sk_X509_pop_free(ocerts, X509_free); + OSSL_STACK_OF_X509_free(ocerts); return 0; } @@ -156,7 +159,8 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; } - if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { + if (!parse_bags(bags, pass, passlen, pkey, ocerts, + p7->ctx.libctx, p7->ctx.propq)) { sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; @@ -169,12 +173,14 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, /* pkey and/or ocerts may be NULL */ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + OSSL_LIB_CTX *libctx, const char *propq) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), - pass, passlen, pkey, ocerts)) + pass, passlen, pkey, ocerts, + libctx, propq)) return 0; } return 1; @@ -182,7 +188,8 @@ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, /* pkey and/or ocerts may be NULL */ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts) + EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + OSSL_LIB_CTX *libctx, const char *propq) { PKCS8_PRIV_KEY_INFO *p8; X509 *x509; @@ -200,7 +207,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, case NID_keyBag: if (pkey == NULL || *pkey != NULL) return 1; - *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag)); + *pkey = EVP_PKCS82PKEY_ex(PKCS12_SAFEBAG_get0_p8inf(bag), + libctx, propq); if (*pkey == NULL) return 0; break; @@ -208,9 +216,10 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, case NID_pkcs8ShroudedKeyBag: if (pkey == NULL || *pkey != NULL) return 1; - if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) + if ((p8 = PKCS12_decrypt_skey_ex(bag, pass, passlen, + libctx, propq)) == NULL) return 0; - *pkey = EVP_PKCS82PKEY(p8); + *pkey = EVP_PKCS82PKEY_ex(p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); if (!(*pkey)) return 0; @@ -220,7 +229,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, if (ocerts == NULL || PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) return 1; - if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) + if ((x509 = PKCS12_SAFEBAG_get1_cert_ex(bag, libctx, propq)) == NULL) return 0; if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { X509_free(x509); @@ -250,7 +259,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, case NID_safeContentsBag: return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey, - ocerts); + ocerts, libctx, propq); default: return 1; diff --git a/crypto/pkcs12/p12_local.h b/crypto/pkcs12/p12_local.h index acaa27b193..7f02874a97 100644 --- a/crypto/pkcs12/p12_local.h +++ b/crypto/pkcs12/p12_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,3 +41,5 @@ struct pkcs12_bag_st { ASN1_TYPE *other; /* Secret or other bag */ } value; }; + +const PKCS7_CTX *ossl_pkcs12_get0_pkcs7ctx(const PKCS12 *p12); diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index 67a885a45f..4096aa1f8a 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -246,11 +246,11 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, return PKCS12_ERROR; if (iter > 1) { if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return 0; } if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return 0; } } @@ -258,10 +258,8 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, saltlen = PKCS12_SALT_LEN; else if (saltlen < 0) return 0; - if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) return 0; - } p12->mac->salt->length = saltlen; if (salt == NULL) { if (RAND_bytes_ex(p12->authsafes->ctx.libctx, p12->mac->salt->data, @@ -273,7 +271,7 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, X509_SIG_getm(p12->mac->dinfo, &macalg, NULL); if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_get_type(md_type)), V_ASN1_NULL, NULL)) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return 0; } diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c index 62230bc618..9ea82d09d8 100644 --- a/crypto/pkcs12/p12_npas.c +++ b/crypto/pkcs12/p12_npas.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,11 +19,13 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, - const char *newpass); + const char *newpass, + OSSL_LIB_CTX *libctx, const char *propq); static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, - const char *newpass); + const char *newpass, + OSSL_LIB_CTX *libctx, const char *propq); static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter, - int *psaltlen); + int *psaltlen, int *cipherid); /* * Change the password on a PKCS#12 structure. @@ -39,12 +41,12 @@ int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) } /* Check the mac */ - - if (!PKCS12_verify_mac(p12, oldpass, -1)) { - ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); - return 0; + if (p12->mac != NULL) { + if (!PKCS12_verify_mac(p12, oldpass, -1)) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); + return 0; + } } - if (!newpass_p12(p12, oldpass, newpass)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); return 0; @@ -59,7 +61,7 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) { STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; - int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; + int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0, cipherid = NID_undef; PKCS7 *p7, *p7new; ASN1_OCTET_STRING *p12_data_tmp = NULL, *macoct = NULL; unsigned char mac[EVP_MAX_MD_SIZE]; @@ -72,27 +74,30 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) goto err; for (i = 0; i < sk_PKCS7_num(asafes); i++) { p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); if (bagnid == NID_pkcs7_data) { bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); if (!alg_get(p7->d.encrypted->enc_data->algorithm, - &pbe_nid, &pbe_iter, &pbe_saltlen)) + &pbe_nid, &pbe_iter, &pbe_saltlen, &cipherid)) goto err; } else { continue; } if (bags == NULL) goto err; - if (!newpass_bags(bags, oldpass, newpass)) + if (!newpass_bags(bags, oldpass, newpass, + p7->ctx.libctx, p7->ctx.propq)) goto err; /* Repack bag in same form with new password */ if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags); else - p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, - pbe_saltlen, pbe_iter, bags); + p7new = PKCS12_pack_p7encdata_ex(pbe_nid, newpass, -1, NULL, + pbe_saltlen, pbe_iter, bags, + p7->ctx.libctx, p7->ctx.propq); if (p7new == NULL || !sk_PKCS7_push(newsafes, p7new)) goto err; sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); @@ -107,11 +112,13 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) if (!PKCS12_pack_authsafes(p12, newsafes)) goto err; - if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) - goto err; - X509_SIG_getm(p12->mac->dinfo, NULL, &macoct); - if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) - goto err; + if (p12->mac != NULL) { + if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) + goto err; + X509_SIG_getm(p12->mac->dinfo, NULL, &macoct); + if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) + goto err; + } rv = 1; @@ -130,11 +137,13 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) } static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, - const char *newpass) + const char *newpass, + OSSL_LIB_CTX *libctx, const char *propq) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { - if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass)) + if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass, + libctx, propq)) return 0; } return 1; @@ -143,26 +152,37 @@ static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, /* Change password of safebag: only needs handle shrouded keybags */ static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, - const char *newpass) + const char *newpass, + OSSL_LIB_CTX *libctx, const char *propq) { + EVP_CIPHER *cipher = NULL; PKCS8_PRIV_KEY_INFO *p8; X509_SIG *p8new; - int p8_nid, p8_saltlen, p8_iter; + int p8_nid, p8_saltlen, p8_iter, cipherid = 0; const X509_ALGOR *shalg; if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag) return 1; - if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL) + if ((p8 = PKCS8_decrypt_ex(bag->value.shkeybag, oldpass, -1, + libctx, propq)) == NULL) return 0; X509_SIG_get0(bag->value.shkeybag, &shalg, NULL); - if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen)) { + if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen, &cipherid)) { PKCS8_PRIV_KEY_INFO_free(p8); return 0; } - p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, - p8_iter, p8); + if (cipherid != NID_undef) { + cipher = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(cipherid), propq); + if (cipher == NULL) { + PKCS8_PRIV_KEY_INFO_free(p8); + return 0; + } + } + p8new = PKCS8_encrypt_ex(p8_nid, cipher, newpass, -1, NULL, p8_saltlen, + p8_iter, p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); + EVP_CIPHER_free(cipher); if (p8new == NULL) return 0; X509_SIG_free(bag->value.shkeybag); @@ -171,16 +191,69 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, } static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter, - int *psaltlen) + int *psaltlen, int *cipherid) { - PBEPARAM *pbe; + int ret = 0, pbenid, aparamtype; + int encnid, prfnid; + const ASN1_OBJECT *aoid; + const void *aparam; + PBEPARAM *pbe = NULL; + PBE2PARAM *pbe2 = NULL; + PBKDF2PARAM *kdf = NULL; - pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), alg->parameter); - if (pbe == NULL) - return 0; - *pnid = OBJ_obj2nid(alg->algorithm); - *piter = ASN1_INTEGER_get(pbe->iter); - *psaltlen = pbe->salt->length; - PBEPARAM_free(pbe); - return 1; + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg); + pbenid = OBJ_obj2nid(aoid); + + switch (pbenid) { + case NID_pbes2: + if (aparamtype == V_ASN1_SEQUENCE) + pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM)); + if (pbe2 == NULL) + goto done; + + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc); + pbenid = OBJ_obj2nid(aoid); + X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption); + encnid = OBJ_obj2nid(aoid); + + if (aparamtype == V_ASN1_SEQUENCE) + kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM)); + if (kdf == NULL) + goto done; + + /* Only OCTET_STRING is supported */ + if (kdf->salt->type != V_ASN1_OCTET_STRING) + goto done; + + if (kdf->prf == NULL) { + prfnid = NID_hmacWithSHA1; + } else { + X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf); + prfnid = OBJ_obj2nid(aoid); + } + *psaltlen = kdf->salt->value.octet_string->length; + *piter = ASN1_INTEGER_get(kdf->iter); + *pnid = prfnid; + *cipherid = encnid; + break; + default: + pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), alg->parameter); + if (pbe == NULL) + goto done; + *pnid = OBJ_obj2nid(alg->algorithm); + *piter = ASN1_INTEGER_get(pbe->iter); + *psaltlen = pbe->salt->length; + *cipherid = NID_undef; + ret = 1; + break; + } + ret = 1; +done: + if (kdf != NULL) + PBKDF2PARAM_free(kdf); + if (pbe2 != NULL) + PBE2PARAM_free(pbe2); + if (pbe != NULL) + PBEPARAM_free(pbe); + return ret; } diff --git a/crypto/pkcs12/p12_p8e.c b/crypto/pkcs12/p12_p8e.c index 9c27534017..1230c8c88c 100644 --- a/crypto/pkcs12/p12_p8e.c +++ b/crypto/pkcs12/p12_p8e.c @@ -84,7 +84,6 @@ X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen, p8 = OPENSSL_zalloc(sizeof(*p8)); if (p8 == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); ASN1_OCTET_STRING_free(enckey); return NULL; } diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c index 7574c54120..04ef0b74ed 100644 --- a/crypto/pkcs12/p12_sbag.c +++ b/crypto/pkcs12/p12_sbag.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include "p12_local.h" +#include "crypto/x509.h" #ifndef OPENSSL_NO_DEPRECATED_1_1_0 ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid) @@ -101,6 +102,42 @@ X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag) ASN1_ITEM_rptr(X509_CRL)); } +X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag, + OSSL_LIB_CTX *libctx, const char *propq) +{ + X509 *ret = NULL; + + if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag) + return NULL; + if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate) + return NULL; + ret = ASN1_item_unpack_ex(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509), libctx, propq); + if (!ossl_x509_set0_libctx(ret, libctx, propq)) { + X509_free(ret); + return NULL; + } + return ret; +} + +X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag, + OSSL_LIB_CTX *libctx, const char *propq) +{ + X509_CRL *ret = NULL; + + if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag) + return NULL; + if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl) + return NULL; + ret = ASN1_item_unpack_ex(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509_CRL), libctx, propq); + if (!ossl_x509_crl_set0_libctx(ret, libctx, propq)) { + X509_CRL_free(ret); + return NULL; + } + return ret; +} + PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509) { return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509), @@ -119,18 +156,18 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned PKCS12_SAFEBAG *safebag; if ((bag = PKCS12_BAGS_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } bag->type = OBJ_nid2obj(type); - switch(vtype) { + switch (vtype) { case V_ASN1_OCTET_STRING: { ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new(); if (strtmp == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } /* Pack data into an octet string */ @@ -142,7 +179,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned bag->value.other = ASN1_TYPE_new(); if (bag->value.other == NULL) { ASN1_OCTET_STRING_free(strtmp); - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } ASN1_TYPE_set(bag->value.other, vtype, strtmp); @@ -155,13 +192,13 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned } if ((safebag = PKCS12_SAFEBAG_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); goto err; } safebag->value.bag = bag; safebag->type = OBJ_nid2obj(NID_secretBag); return safebag; - + err: PKCS12_BAGS_free(bag); return NULL; @@ -174,7 +211,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8) PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new(); if (bag == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } bag->type = OBJ_nid2obj(NID_keyBag); @@ -190,7 +227,7 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8) /* Set up the safe bag */ if (bag == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB); return NULL; } bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c index 3afc8b2f13..a96623f19f 100644 --- a/crypto/pkcs12/p12_utl.c +++ b/crypto/pkcs12/p12_utl.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,8 @@ #include #include "internal/cryptlib.h" #include +#include "p12_local.h" +#include "crypto/pkcs7/pk7_local.h" /* Cheap and nasty Unicode stuff */ @@ -24,10 +26,8 @@ unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, if (asclen < 0) return NULL; ulen = asclen * 2 + 2; - if ((unitmp = OPENSSL_malloc(ulen)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((unitmp = OPENSSL_malloc(ulen)) == NULL) return NULL; - } for (i = 0; i < ulen - 2; i += 2) { unitmp[i] = 0; unitmp[i + 1] = asc[i >> 1]; @@ -57,10 +57,8 @@ char *OPENSSL_uni2asc(const unsigned char *uni, int unilen) if (!unilen || uni[unilen - 1]) asclen++; uni++; - if ((asctmp = OPENSSL_malloc(asclen)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((asctmp = OPENSSL_malloc(asclen)) == NULL) return NULL; - } for (i = 0; i < unilen; i += 2) asctmp[i >> 1] = uni[i]; asctmp[asclen - 1] = 0; @@ -119,10 +117,8 @@ unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, ulen += 2; /* for trailing UTF16 zero */ - if ((ret = OPENSSL_malloc(ulen)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((ret = OPENSSL_malloc(ulen)) == NULL) return NULL; - } /* re-run the loop writing down UTF-16 characters in big-endian order */ for (unitmp = ret, i = 0; i < asclen; i += j) { j = UTF8_getc((const unsigned char *)asc+i, asclen-i, &utf32chr); @@ -204,10 +200,8 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen) if (!unilen || (uni[unilen-2]||uni[unilen - 1])) asclen++; - if ((asctmp = OPENSSL_malloc(asclen)) == NULL) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); + if ((asctmp = OPENSSL_malloc(asclen)) == NULL) return NULL; - } /* re-run the loop emitting UTF-8 string */ for (asclen = 0, i = 0; i < unilen; ) { @@ -238,12 +232,34 @@ int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + const PKCS7_CTX *p7ctx = NULL; + + if (p12 != NULL) { + p7ctx = ossl_pkcs12_get0_pkcs7ctx(*p12); + if (p7ctx != NULL) { + libctx = ossl_pkcs7_ctx_get0_libctx(p7ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7ctx); + } + } + return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(PKCS12), bp, p12, libctx, propq); } #ifndef OPENSSL_NO_STDIO PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) { - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + const PKCS7_CTX *p7ctx = NULL; + + if (p12 != NULL) { + p7ctx = ossl_pkcs12_get0_pkcs7ctx(*p12); + if (p7ctx != NULL) { + libctx = ossl_pkcs7_ctx_get0_libctx(p7ctx); + propq = ossl_pkcs7_ctx_get0_propq(p7ctx); + } + } + return ASN1_item_d2i_fp_ex(ASN1_ITEM_rptr(PKCS12), fp, p12, libctx, propq); } #endif diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index 6e3ec78cd6..e9bcaf4b6e 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,8 +15,9 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA PKCS12_str_reasons[] = { + {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CALLBACK_FAILED), "callback failed"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CANT_PACK_STRUCTURE), - "cant pack structure"}, + "can't pack structure"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_DECODE_ERROR), "decode error"}, diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c index 5a08f8dbcb..3abcc3dc88 100644 --- a/crypto/pkcs7/pk7_asn1.c +++ b/crypto/pkcs7/pk7_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -104,7 +104,6 @@ PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq) if (pkcs7->ctx.propq == NULL) { PKCS7_free(pkcs7); pkcs7 = NULL; - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } } } diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c index e9904c5950..aa27dfddad 100644 --- a/crypto/pkcs7/pk7_attr.c +++ b/crypto/pkcs7/pk7_attr.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,13 +23,17 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, ASN1_STRING *seq; if ((seq = ASN1_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); return 0; } seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, ASN1_ITEM_rptr(X509_ALGORS)); - return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, - V_ASN1_SEQUENCE, seq); + if (!PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, seq)) { + ASN1_STRING_free(seq); + return 0; + } + return 1; } STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) @@ -53,19 +57,22 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) X509_ALGOR *alg; if ((alg = X509_ALGOR_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); return 0; } ASN1_OBJECT_free(alg->algorithm); alg->algorithm = OBJ_nid2obj(nid); if (arg > 0) { if ((alg->parameter = ASN1_TYPE_new()) == NULL) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } if ((nbit = ASN1_INTEGER_new()) == NULL) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } if (!ASN1_INTEGER_set(nbit, arg)) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } alg->parameter->value.integer = nbit; @@ -73,11 +80,11 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) nbit = NULL; } if (!sk_X509_ALGOR_push(sk, alg)) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB); goto err; } return 1; err: - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); ASN1_INTEGER_free(nbit); X509_ALGOR_free(alg); return 0; @@ -95,12 +102,18 @@ int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) { - if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ASN1_TIME *tmp = NULL; + + if (t == NULL && (tmp = t = X509_gmtime_adj(NULL, 0)) == NULL) { + ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); return 0; } - return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, - V_ASN1_UTCTIME, t); + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, + V_ASN1_UTCTIME, t)) { + ASN1_TIME_free(tmp); + return 0; + } + return 1; } int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 1cef67b211..c753a0880b 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -15,6 +15,7 @@ #include #include "internal/cryptlib.h" #include "internal/sizes.h" +#include "crypto/evp.h" #include "pk7_local.h" static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, @@ -131,11 +132,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, goto err; ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + if (ek == NULL) goto err; - } if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) goto err; @@ -170,25 +168,17 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, if (EVP_PKEY_decrypt_init(pctx) <= 0) goto err; - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); + if (EVP_PKEY_is_a(pkey, "RSA")) + /* upper layer pkcs7 code incorrectly assumes that a successful RSA + * decryption means that the key matches ciphertext (which never + * was the case, implicit rejection or not), so to make it work + * disable implicit rejection for RSA keys */ + EVP_PKEY_CTX_ctrl_str(pctx, "rsa_pkcs1_implicit_rejection", "0"); - if (ek == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ret = evp_pkey_decrypt_alloc(pctx, &ek, &eklen, fixlen, + ri->enc_key->data, ri->enc_key->length); + if (ret <= 0) goto err; - } - - if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0 - || eklen == 0 - || (fixlen != 0 && eklen != fixlen)) { - ret = 0; - ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); - goto err; - } ret = 1; @@ -702,7 +692,7 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) /* Add signing time if not already present */ if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { if (!PKCS7_add0_attrib_signing_time(si, NULL)) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return 0; } } @@ -713,7 +703,7 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) return 0; } if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return 0; } @@ -750,7 +740,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) ctx_tmp = EVP_MD_CTX_new(); if (ctx_tmp == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); return 0; } @@ -768,7 +758,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } p7->d.signed_and_enveloped->enc_data->enc_data = os; @@ -780,7 +770,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (os == NULL) { os = ASN1_OCTET_STRING_new(); if (os == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); goto err; } p7->d.enveloped->enc_data->enc_data = os; @@ -844,10 +834,9 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; } else { unsigned char *abuf = NULL; - unsigned int abuflen; - abuflen = EVP_PKEY_get_size(si->pkey); - abuf = OPENSSL_malloc(abuflen); - if (abuf == NULL) + unsigned int abuflen = EVP_PKEY_get_size(si->pkey); + + if (abuflen == 0 || (abuf = OPENSSL_malloc(abuflen)) == NULL) goto err; if (!EVP_SignFinal_ex(ctx_tmp, abuf, &abuflen, si->pkey, @@ -919,7 +908,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } @@ -957,13 +946,15 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) return 0; } +/* This partly overlaps with PKCS7_verify(). It does not support flags. */ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si) { PKCS7_ISSUER_AND_SERIAL *ias; int ret = 0, i; - STACK_OF(X509) *cert; - X509 *x509; + STACK_OF(X509) *untrusted; + STACK_OF(X509_CRL) *crls; + X509 *signer; if (p7 == NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER); @@ -976,26 +967,30 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, } if (PKCS7_type_is_signed(p7)) { - cert = p7->d.sign->cert; + untrusted = p7->d.sign->cert; + crls = p7->d.sign->crl; } else if (PKCS7_type_is_signedAndEnveloped(p7)) { - cert = p7->d.signed_and_enveloped->cert; + untrusted = p7->d.signed_and_enveloped->cert; + crls = p7->d.signed_and_enveloped->crl; } else { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } + X509_STORE_CTX_set0_crls(ctx, crls); + /* XXXXXXXXXXXXXXXXXXXXXXX */ ias = si->issuer_and_serial; - x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); + signer = X509_find_by_issuer_and_serial(untrusted, ias->issuer, ias->serial); - /* were we able to find the cert in passed to us */ - if (x509 == NULL) { + /* Were we able to find the signer certificate in passed to us? */ + if (signer == NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); goto err; } /* Lets verify */ - if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { + if (!X509_STORE_CTX_init(ctx, cert_store, signer, untrusted)) { ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB); goto err; } @@ -1006,13 +1001,13 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, goto err; } - return PKCS7_signatureVerify(bio, p7, si, x509); + return PKCS7_signatureVerify(bio, p7, si, signer); err: return ret; } int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509) + X509 *signer) { ASN1_OCTET_STRING *os; EVP_MD_CTX *mdc_tmp, *mdc; @@ -1029,7 +1024,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, mdc_tmp = EVP_MD_CTX_new(); if (mdc_tmp == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB); goto err; } @@ -1119,7 +1114,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, } os = si->enc_digest; - pkey = X509_get0_pubkey(x509); + pkey = X509_get0_pubkey(signer); if (pkey == NULL) { ret = -1; goto err; @@ -1170,11 +1165,11 @@ ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid) static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid) { - int idx; - X509_ATTRIBUTE *xa; - idx = X509at_get_attr_by_NID(sk, nid, -1); - xa = X509at_get_attr(sk, idx); - return X509_ATTRIBUTE_get0_type(xa, 0); + int idx = X509at_get_attr_by_NID(sk, nid, -1); + + if (idx < 0) + return NULL; + return X509_ATTRIBUTE_get0_type(X509at_get_attr(sk, idx), 0); } ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index 5ce591f758..7be2928542 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -224,7 +224,7 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) if ((alg = X509_ALGOR_new()) == NULL || (alg->parameter = ASN1_TYPE_new()) == NULL) { X509_ALGOR_free(alg); - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); return 0; } /* @@ -290,7 +290,7 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) if (*sk == NULL) *sk = sk_X509_CRL_new_null(); if (*sk == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB); return 0; } @@ -305,7 +305,7 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify) { - if (verify == 0) { + if (!verify) { int snid, hnid; X509_ALGOR *alg1, *alg2; EVP_PKEY *pkey = si->pkey; @@ -318,19 +318,20 @@ static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey))) return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL); } return 1; } static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify) { - if (verify == 0) { + if (!verify) { X509_ALGOR *alg = NULL; PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg); if (alg != NULL) - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, NULL); } return 1; } @@ -342,10 +343,10 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, /* We now need to add another PKCS7_SIGNER_INFO entry */ if (!ASN1_INTEGER_set(p7i->version, 1)) - goto err; + return 0; if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, X509_get_issuer_name(x509))) - goto err; + return 0; /* * because ASN1_INTEGER_set is used to set a 'long' we will do things the @@ -354,7 +355,7 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, ASN1_INTEGER_free(p7i->issuer_and_serial->serial); if (!(p7i->issuer_and_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) - goto err; + return 0; /* lets keep the pkey around for a while */ EVP_PKEY_up_ref(pkey); @@ -362,8 +363,9 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, /* Set the algorithms */ - X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)), - V_ASN1_NULL, NULL); + if (!X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)), + V_ASN1_NULL, NULL)) + return 0; if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA")) return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0); @@ -380,7 +382,6 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, } } ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - err: return 0; } @@ -490,10 +491,8 @@ int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq) } if (propq != NULL) { p7->ctx.propq = OPENSSL_strdup(propq); - if (p7->ctx.propq == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (p7->ctx.propq == NULL) return 0; - } } return 1; } @@ -521,7 +520,7 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) { if (PKCS7_type_is_digest(p7)) { if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB); return 0; } p7->d.digest->md->parameter->type = V_ASN1_NULL; @@ -606,10 +605,11 @@ static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt) { X509_ALGOR *alg = NULL; - if (decrypt == 0) { + if (!decrypt) { PKCS7_RECIP_INFO_get0_alg(ri, &alg); if (alg != NULL) - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, NULL); } return 1; } diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 4593da8f5b..1f951d77fb 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,7 +28,7 @@ PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, int i; if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return NULL; } @@ -77,7 +77,7 @@ int PKCS7_final(PKCS7 *p7, BIO *data, int flags) int ret = 0; if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return 0; } @@ -144,7 +144,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, /* Add SMIMECapabilities */ if (!(flags & PKCS7_NOSMIMECAP)) { if ((smcap = sk_X509_ALGOR_new_null()) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB); goto err; } if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) @@ -210,6 +210,7 @@ static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) return 0; } +/* This strongly overlaps with CMS_verify(), partly with PKCS7_dataVerify() */ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags) { @@ -221,7 +222,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, char *buf = NULL; int i, j = 0, k, ret = 0; BIO *p7bio = NULL; - BIO *tmpin = NULL, *tmpout = NULL; + BIO *tmpout = NULL; const PKCS7_CTX *p7_ctx; if (p7 == NULL) { @@ -235,7 +236,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, } /* Check for no data and no content: no data to verify signature */ - if (PKCS7_get_detached(p7) && !indata) { + if (PKCS7_get_detached(p7) && indata == NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); return 0; } @@ -248,7 +249,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, * tools like osslsigncode need it. In Authenticode the verification * process is different, but the existing PKCs7 verification works. */ - if (!PKCS7_get_detached(p7) && indata) { + if (!PKCS7_get_detached(p7) && indata != NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT); return 0; } @@ -300,31 +301,12 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, /* Check for revocation status here */ } - /* - * Performance optimization: if the content is a memory BIO then store - * its contents in a temporary read only memory BIO. This avoids - * potentially large numbers of slow copies of data which will occur when - * reading from a read write memory BIO when signatures are calculated. - */ - - if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { - char *ptr; - long len; - len = BIO_get_mem_data(indata, &ptr); - tmpin = (len == 0) ? indata : BIO_new_mem_buf(ptr, len); - if (tmpin == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - tmpin = indata; - - if ((p7bio = PKCS7_dataInit(p7, tmpin)) == NULL) + if ((p7bio = PKCS7_dataInit(p7, indata)) == NULL) goto err; if (flags & PKCS7_TEXT) { if ((tmpout = BIO_new(BIO_s_mem())) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); goto err; } BIO_set_mem_eof_return(tmpout, 0); @@ -332,10 +314,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, tmpout = out; /* We now have to 'read' from p7bio to calculate digests etc. */ - if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) goto err; - } for (;;) { i = BIO_read(p7bio, buf, BUFFERSIZE); if (i <= 0) @@ -370,10 +350,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, err: X509_STORE_CTX_free(cert_ctx); OPENSSL_free(buf); - if (tmpin == indata) { - if (indata) - BIO_pop(p7bio); - } + if (indata != NULL) + BIO_pop(p7bio); BIO_free_all(p7bio); sk_X509_free(signers); return ret; @@ -409,7 +387,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, } if ((signers = sk_X509_new_null()) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB); return NULL; } @@ -418,15 +396,15 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, ias = si->issuer_and_serial; signer = NULL; /* If any certificates passed they take priority */ - if (certs) + if (certs != NULL) signer = X509_find_by_issuer_and_serial(certs, ias->issuer, ias->serial); - if (!signer && !(flags & PKCS7_NOINTERN) + if (signer == NULL && !(flags & PKCS7_NOINTERN) && p7->d.sign->cert) signer = X509_find_by_issuer_and_serial(p7->d.sign->cert, ias->issuer, ias->serial); - if (!signer) { + if (signer == NULL) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); sk_X509_free(signers); return 0; @@ -452,7 +430,7 @@ PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in, X509 *x509; if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB); return NULL; } @@ -503,7 +481,8 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) return 0; } - if (!PKCS7_type_is_enveloped(p7)) { + if (!PKCS7_type_is_enveloped(p7) + && !PKCS7_type_is_signedAndEnveloped(p7)) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } @@ -523,12 +502,12 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) BIO *tmpbuf, *bread; /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); BIO_free_all(tmpmem); return 0; } if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB); BIO_free_all(tmpbuf); BIO_free_all(tmpmem); return 0; @@ -541,10 +520,8 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) BIO_free_all(bread); return ret; } - if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { - ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) goto err; - } for (;;) { i = BIO_read(tmpmem, buf, BUFFERSIZE); if (i <= 0) { diff --git a/crypto/poly1305/poly1305_ieee754.c b/crypto/poly1305/poly1305_ieee754.c index 110feb4d57..fa0ab1ed1d 100644 --- a/crypto/poly1305/poly1305_ieee754.c +++ b/crypto/poly1305/poly1305_ieee754.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,7 +10,7 @@ /* * This module is meant to be used as template for non-x87 floating- * point assembly modules. The template itself is x86_64-specific - * though, as it was debugged on x86_64. So that implementor would + * though, as it was debugged on x86_64. So that implementer would * have to recognize platform-specific parts, UxTOy and inline asm, * and act accordingly. * diff --git a/crypto/property/property.c b/crypto/property/property.c index 1d3cb30018..c551c825b1 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -666,7 +666,7 @@ static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store) store->cache_nelem = state.nelem; /* Without a timer, update the global seed */ if (state.using_global_seed) - tsan_store(&global_seed, state.seed); + tsan_add(&global_seed, state.seed); } int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov, diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h index 2cb62bae90..797fb3bf5f 100644 --- a/crypto/property/property_local.h +++ b/crypto/property/property_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/provider.c b/crypto/provider.c index 114b426929..b55561abf8 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,15 +15,15 @@ #include "internal/provider.h" #include "provider_local.h" -OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, - int retain_fallbacks) +OSSL_PROVIDER *OSSL_PROVIDER_try_load_ex(OSSL_LIB_CTX *libctx, const char *name, + OSSL_PARAM *params, int retain_fallbacks) { OSSL_PROVIDER *prov = NULL, *actual; int isnew = 0; /* Find it or create it */ if ((prov = ossl_provider_find(libctx, name, 0)) == NULL) { - if ((prov = ossl_provider_new(libctx, name, NULL, 0)) == NULL) + if ((prov = ossl_provider_new(libctx, name, NULL, params, 0)) == NULL) return NULL; isnew = 1; } @@ -49,14 +49,25 @@ OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, return actual; } -OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, + int retain_fallbacks) +{ + return OSSL_PROVIDER_try_load_ex(libctx, name, NULL, retain_fallbacks); +} + +OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *libctx, const char *name, OSSL_PARAM *params) { /* Any attempt to load a provider disables auto-loading of defaults */ if (ossl_provider_disable_fallback_loading(libctx)) - return OSSL_PROVIDER_try_load(libctx, name, 0); + return OSSL_PROVIDER_try_load_ex(libctx, name, params, 0); return NULL; } +OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +{ + return OSSL_PROVIDER_load_ex(libctx, name, NULL); +} + int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) { if (!ossl_provider_deactivate(prov, 1)) @@ -123,10 +134,8 @@ int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name, } memset(&entry, 0, sizeof(entry)); entry.name = OPENSSL_strdup(name); - if (entry.name == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (entry.name == NULL) return 0; - } entry.init = init_fn; if (!ossl_provider_info_add_to_store(libctx, &entry)) { ossl_provider_info_clear(&entry); diff --git a/crypto/provider_child.c b/crypto/provider_child.c index 2e6dac6d95..52e9cb405f 100644 --- a/crypto/provider_child.c +++ b/crypto/provider_child.c @@ -132,7 +132,7 @@ static int provider_create_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) * init children */ if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init, - 1)) == NULL) + NULL, 1)) == NULL) goto err; if (!ossl_provider_activate(cprov, 0, 0)) { diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 058fb58837..288ade6b4d 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -158,7 +158,7 @@ static int provider_conf_activate(OSSL_LIB_CTX *libctx, const char *name, } prov = ossl_provider_find(libctx, name, 1); if (prov == NULL) - prov = ossl_provider_new(libctx, name, NULL, 1); + prov = ossl_provider_new(libctx, name, NULL, NULL, 1); if (prov == NULL) { CRYPTO_THREAD_unlock(pcgbl->lock); if (soft) @@ -256,17 +256,13 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, ok = 1; if (name != NULL) { entry.name = OPENSSL_strdup(name); - if (entry.name == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (entry.name == NULL) ok = 0; - } } if (ok && path != NULL) { entry.path = OPENSSL_strdup(path); - if (entry.path == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (entry.path == NULL) ok = 0; - } } if (ok) ok = provider_conf_params(NULL, &entry, NULL, value, cnf); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 6627501b00..838bcd161c 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -73,11 +73,10 @@ * The locks available are: * * The provider flag_lock: Used to control updates to the various provider - * "flags" (flag_initialized and flag_activated) and associated - * "counts" (activatecnt). + * "flags" (flag_initialized and flag_activated). * - * The provider refcnt_lock: Only ever used to control updates to the provider - * refcnt value. + * The provider activatecnt_lock: Used to control updates to the provider + * activatecnt value. * * The provider optbits_lock: Used to control access to the provider's * operation_bits and operation_bits_sz fields. @@ -100,12 +99,12 @@ * introducing the possibility of deadlock. The following rules MUST be adhered * to in order to avoid that: * - Holding multiple locks at the same time is only allowed for the - * provider store lock, the provider flag_lock and the provider refcnt_lock. + * provider store lock, the provider activatecnt_lock and the provider flag_lock. * - When holding multiple locks they must be acquired in the following order of * precedence: * 1) provider store lock * 2) provider flag_lock - * 3) provider refcnt_lock + * 3) provider activatecnt_lock * - When releasing locks they must be released in the reverse order to which * they were acquired * - No locks may be held when making an upcall. NOTE: Some common functions @@ -149,7 +148,7 @@ struct ossl_provider_st { /* OpenSSL library side data */ CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */ + CRYPTO_RWLOCK *activatecnt_lock; /* For the activatecnt counter */ int activatecnt; char *name; char *path; @@ -372,10 +371,8 @@ int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx, if (store->provinfosz == 0) { store->provinfo = OPENSSL_zalloc(sizeof(*store->provinfo) * BUILTINS_BLOCK_SIZE); - if (store->provinfo == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (store->provinfo == NULL) goto err; - } store->provinfosz = BUILTINS_BLOCK_SIZE; } else if (store->numprovinfo == store->provinfosz) { OSSL_PROVIDER_INFO *tmpbuiltins; @@ -383,10 +380,8 @@ int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx, tmpbuiltins = OPENSSL_realloc(store->provinfo, sizeof(*store->provinfo) * newsz); - if (tmpbuiltins == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (tmpbuiltins == NULL) goto err; - } store->provinfo = tmpbuiltins; store->provinfosz = newsz; } @@ -421,12 +416,9 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, #endif tmpl.name = (char *)name; - /* - * A "find" operation can sort the stack, and therefore a write lock is - * required. - */ if (!CRYPTO_THREAD_write_lock(store->lock)) return NULL; + sk_OSSL_PROVIDER_sort(store->providers); if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) != -1) prov = sk_OSSL_PROVIDER_value(store->providers, i); CRYPTO_THREAD_unlock(store->lock); @@ -448,26 +440,31 @@ static OSSL_PROVIDER *provider_new(const char *name, { OSSL_PROVIDER *prov = NULL; - if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL -#ifndef HAVE_ATOMICS - || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL -#endif - ) { + if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL) + return NULL; + if (!CRYPTO_NEW_REF(&prov->refcnt, 1)) { OPENSSL_free(prov); - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; } - - prov->refcnt = 1; /* 1 One reference to be returned */ +#ifndef HAVE_ATOMICS + if ((prov->activatecnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + ossl_provider_free(prov); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); + return NULL; + } +#endif if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL - || (prov->name = OPENSSL_strdup(name)) == NULL || (prov->parameters = sk_INFOPAIR_deep_copy(parameters, infopair_copy, infopair_free)) == NULL) { ossl_provider_free(prov); - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); + return NULL; + } + if ((prov->name = OPENSSL_strdup(name)) == NULL) { + ossl_provider_free(prov); return NULL; } @@ -480,7 +477,7 @@ int ossl_provider_up_ref(OSSL_PROVIDER *prov) { int ref = 0; - if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) + if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0) return 0; #ifndef FIPS_MODULE @@ -521,7 +518,7 @@ static int provider_free_intern(OSSL_PROVIDER *prov, int deactivate) */ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, - int noconfig) + OSSL_PARAM *params, int noconfig) { struct provider_store_st *store = NULL; OSSL_PROVIDER_INFO template; @@ -543,7 +540,7 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, } } if (p->name == NULL) { - /* Check if this is a user added builtin provider */ + /* Check if this is a user added provider */ if (!CRYPTO_THREAD_read_lock(store->lock)) return NULL; for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) { @@ -558,8 +555,29 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, template.init = init_function; } + if (params != NULL) { + int i; + + template.parameters = sk_INFOPAIR_new_null(); + if (template.parameters == NULL) + return NULL; + + for (i = 0; params[i].key != NULL; i++) { + if (params[i].data_type != OSSL_PARAM_UTF8_STRING) + continue; + if (ossl_provider_info_add_parameter(&template, params[i].key, + (char *)params[i].data) <= 0) + return NULL; + } + } + /* provider_new() generates an error, so no need here */ - if ((prov = provider_new(name, template.init, template.parameters)) == NULL) + prov = provider_new(name, template.init, template.parameters); + + if (params != NULL) /* We copied the parameters, let's free them */ + sk_INFOPAIR_pop_free(template.parameters, infopair_free); + + if (prov == NULL) return NULL; prov->libctx = libctx; @@ -639,7 +657,7 @@ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov, if (actualprov != NULL) { if (!ossl_provider_up_ref(actualtmp)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); actualtmp = NULL; return 0; } @@ -660,6 +678,15 @@ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov, ossl_provider_deactivate(prov, 0); ossl_provider_free(prov); } +#ifndef FIPS_MODULE + else { + /* + * This can be done outside the lock. We tolerate other threads getting + * the wrong result briefly when creating OSSL_DECODER_CTXs. + */ + ossl_decoder_cache_flush(prov->libctx); + } +#endif return 1; @@ -673,7 +700,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov) if (prov != NULL) { int ref = 0; - CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + CRYPTO_DOWN_REF(&prov->refcnt, &ref); /* * When the refcount drops to zero, we clean up the provider. @@ -716,8 +743,9 @@ void ossl_provider_free(OSSL_PROVIDER *prov) CRYPTO_THREAD_lock_free(prov->opbits_lock); CRYPTO_THREAD_lock_free(prov->flag_lock); #ifndef HAVE_ATOMICS - CRYPTO_THREAD_lock_free(prov->refcnt_lock); + CRYPTO_THREAD_lock_free(prov->activatecnt_lock); #endif + CRYPTO_FREE_REF(&prov->refcnt); OPENSSL_free(prov); } #ifndef FIPS_MODULE @@ -737,7 +765,6 @@ int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path) return 1; if ((prov->path = OPENSSL_strdup(module_path)) != NULL) return 1; - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -746,20 +773,26 @@ static int infopair_add(STACK_OF(INFOPAIR) **infopairsk, const char *name, { INFOPAIR *pair = NULL; - if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL - && (*infopairsk != NULL - || (*infopairsk = sk_INFOPAIR_new_null()) != NULL) - && (pair->name = OPENSSL_strdup(name)) != NULL - && (pair->value = OPENSSL_strdup(value)) != NULL - && sk_INFOPAIR_push(*infopairsk, pair) > 0) - return 1; + if ((pair = OPENSSL_zalloc(sizeof(*pair))) == NULL + || (pair->name = OPENSSL_strdup(name)) == NULL + || (pair->value = OPENSSL_strdup(value)) == NULL) + goto err; + if ((*infopairsk == NULL + && (*infopairsk = sk_INFOPAIR_new_null()) == NULL) + || sk_INFOPAIR_push(*infopairsk, pair) <= 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); + goto err; + } + + return 1; + + err: if (pair != NULL) { OPENSSL_free(pair->name); OPENSSL_free(pair->value); OPENSSL_free(pair); } - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } @@ -798,10 +831,8 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, if (path != NULL) { p = OPENSSL_strdup(path); - if (p == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (p == NULL) return 0; - } } if ((store = get_provider_store(libctx)) != NULL && CRYPTO_THREAD_write_lock(store->default_path_lock)) { @@ -814,6 +845,19 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, return 0; } +const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx) +{ + struct provider_store_st *store; + char *path = NULL; + + if ((store = get_provider_store(libctx)) != NULL + && CRYPTO_THREAD_read_lock(store->default_path_lock)) { + path = store->default_path; + CRYPTO_THREAD_unlock(store->default_path_lock); + } + return path; +} + /* * Internal version that doesn't affect the store flags, and thereby avoid * locking. Direct callers must remember to set the store flags when @@ -863,10 +907,8 @@ static int provider_init(OSSL_PROVIDER *prov) if (store->default_path != NULL) { allocated_load_dir = OPENSSL_strdup(store->default_path); CRYPTO_THREAD_unlock(store->default_path_lock); - if (allocated_load_dir == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (allocated_load_dir == NULL) goto end; - } load_dir = allocated_load_dir; } else { CRYPTO_THREAD_unlock(store->default_path_lock); @@ -1057,8 +1099,9 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls, return -1; } + CRYPTO_atomic_add(&prov->activatecnt, -1, &count, prov->activatecnt_lock); #ifndef FIPS_MODULE - if (prov->activatecnt >= 2 && prov->ischild && upcalls) { + if (count >= 1 && prov->ischild && upcalls) { /* * We have had a direct activation in this child libctx so we need to * now down the ref count in the parent provider. We do the actual down @@ -1069,7 +1112,7 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls, } #endif - if ((count = --prov->activatecnt) < 1) + if (count < 1) prov->flag_activated = 0; #ifndef FIPS_MODULE else @@ -1090,6 +1133,14 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls, if (lock) { CRYPTO_THREAD_unlock(prov->flag_lock); CRYPTO_THREAD_unlock(store->lock); + /* + * This can be done outside the lock. We tolerate other threads getting + * the wrong result briefly when creating OSSL_DECODER_CTXs. + */ +#ifndef FIPS_MODULE + if (count < 1) + ossl_decoder_cache_flush(prov->libctx); +#endif } #ifndef FIPS_MODULE if (freeparent) @@ -1142,16 +1193,24 @@ static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls) #endif return -1; } + if (CRYPTO_atomic_add(&prov->activatecnt, 1, &count, prov->activatecnt_lock)) { + prov->flag_activated = 1; - count = ++prov->activatecnt; - prov->flag_activated = 1; - - if (prov->activatecnt == 1 && store != NULL) { - ret = create_provider_children(prov); + if (count == 1 && store != NULL) { + ret = create_provider_children(prov); + } } if (lock) { CRYPTO_THREAD_unlock(prov->flag_lock); CRYPTO_THREAD_unlock(store->lock); + /* + * This can be done outside the lock. We tolerate other threads getting + * the wrong result briefly when creating OSSL_DECODER_CTXs. + */ +#ifndef FIPS_MODULE + if (count == 1) + ossl_decoder_cache_flush(prov->libctx); +#endif } if (!ret) @@ -1381,7 +1440,7 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, for (curr = max - 1; curr >= 0; curr--) { OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); - if (!CRYPTO_THREAD_write_lock(prov->flag_lock)) + if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) goto err_unlock; if (prov->flag_activated) { /* @@ -1389,20 +1448,19 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, * to avoid upping the ref count on the parent provider, which we * must not do while holding locks. */ - if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) { + if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0) { CRYPTO_THREAD_unlock(prov->flag_lock); goto err_unlock; } /* * It's already activated, but we up the activated count to ensure * it remains activated until after we've called the user callback. - * We do this with no locking (because we already hold the locks) - * and no upcalls (which must not be called when locks are held). In - * theory this could mean the parent provider goes inactive, whilst - * still activated in the child for a short period. That's ok. + * In theory this could mean the parent provider goes inactive, + * whilst still activated in the child for a short period. That's ok. */ - if (provider_activate(prov, 0, 0) < 0) { - CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + if (!CRYPTO_atomic_add(&prov->activatecnt, 1, &ref, + prov->activatecnt_lock)) { + CRYPTO_DOWN_REF(&prov->refcnt, &ref); CRYPTO_THREAD_unlock(prov->flag_lock); goto err_unlock; } @@ -1441,13 +1499,32 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, for (curr++; curr < max; curr++) { OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr); - provider_deactivate(prov, 0, 1); + if (!CRYPTO_atomic_add(&prov->activatecnt, -1, &ref, + prov->activatecnt_lock)) { + ret = 0; + continue; + } + if (ref < 1) { + /* + * Looks like we need to deactivate properly. We could just have + * done this originally, but it involves taking a write lock so + * we avoid it. We up the count again and do a full deactivation + */ + if (CRYPTO_atomic_add(&prov->activatecnt, 1, &ref, + prov->activatecnt_lock)) + provider_deactivate(prov, 0, 1); + else + ret = 0; + } /* * As above where we did the up-ref, we don't call ossl_provider_free * to avoid making upcalls. There should always be at least one ref * to the provider in the store, so this should never drop to 0. */ - CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock); + if (!CRYPTO_DOWN_REF(&prov->refcnt, &ref)) { + ret = 0; + continue; + } /* * Not much we can do if this assert ever fails. So we don't use * ossl_assert here. @@ -1611,7 +1688,6 @@ int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) if (tmp == NULL) { CRYPTO_THREAD_unlock(provider->opbits_lock); - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } provider->operation_bits = tmp; @@ -2218,6 +2294,6 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_OBJ_ADD_SIGID, (void (*)(void))core_obj_add_sigid }, { OSSL_FUNC_CORE_OBJ_CREATE, (void (*)(void))core_obj_create }, #endif - { 0, NULL } + OSSL_DISPATCH_END }; static const OSSL_DISPATCH *core_dispatch = core_dispatch_; diff --git a/crypto/punycode.c b/crypto/punycode.c index 4d9a6d7d8f..68fc586e68 100644 --- a/crypto/punycode.c +++ b/crypto/punycode.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,11 +8,10 @@ */ #include -#include #include #include #include "crypto/punycode.h" -#include "internal/cryptlib.h" +#include "internal/common.h" /* for HAS_PREFIX */ #include "internal/packet.h" /* for WPACKET */ static const unsigned int base = 36; @@ -271,7 +270,7 @@ int ossl_a2ulabel(const char *in, char *out, size_t outlen) char *tmpptr = strchr(inptr, '.'); size_t delta = tmpptr != NULL ? (size_t)(tmpptr - inptr) : strlen(inptr); - if (strncmp(inptr, "xn--", 4) != 0) { + if (!HAS_PREFIX(inptr, "xn--")) { if (!WPACKET_memcpy(&pkt, inptr, delta)) result = 0; } else { @@ -311,22 +310,3 @@ int ossl_a2ulabel(const char *in, char *out, size_t outlen) WPACKET_cleanup(&pkt); return result; } - -/*- - * a MUST be A-label - * u MUST be U-label - * Returns 0 if compared values are equal - * 1 if not - * -1 in case of errors - */ - -int ossl_a2ucompare(const char *a, const char *u) -{ - char a_ulabel[LABEL_BUF_SIZE + 1]; - size_t a_size = sizeof(a_ulabel); - - if (ossl_a2ulabel(a, a_ulabel, a_size) <= 0) - return -1; - - return strcmp(a_ulabel, u) != 0; -} diff --git a/crypto/quic_vlint.c b/crypto/quic_vlint.c new file mode 100644 index 0000000000..0238985963 --- /dev/null +++ b/crypto/quic_vlint.c @@ -0,0 +1,81 @@ +#include "internal/quic_vlint.h" +#include "internal/e_os.h" + +#ifndef OPENSSL_NO_QUIC + +void ossl_quic_vlint_encode_n(uint8_t *buf, uint64_t v, int n) +{ + if (n == 1) { + buf[0] = (uint8_t)v; + } else if (n == 2) { + buf[0] = (uint8_t)(0x40 | ((v >> 8) & 0x3F)); + buf[1] = (uint8_t)v; + } else if (n == 4) { + buf[0] = (uint8_t)(0x80 | ((v >> 24) & 0x3F)); + buf[1] = (uint8_t)(v >> 16); + buf[2] = (uint8_t)(v >> 8); + buf[3] = (uint8_t)v; + } else { + buf[0] = (uint8_t)(0xC0 | ((v >> 56) & 0x3F)); + buf[1] = (uint8_t)(v >> 48); + buf[2] = (uint8_t)(v >> 40); + buf[3] = (uint8_t)(v >> 32); + buf[4] = (uint8_t)(v >> 24); + buf[5] = (uint8_t)(v >> 16); + buf[6] = (uint8_t)(v >> 8); + buf[7] = (uint8_t)v; + } +} + +void ossl_quic_vlint_encode(uint8_t *buf, uint64_t v) +{ + ossl_quic_vlint_encode_n(buf, v, ossl_quic_vlint_encode_len(v)); +} + +uint64_t ossl_quic_vlint_decode_unchecked(const unsigned char *buf) +{ + uint8_t first_byte = buf[0]; + size_t sz = ossl_quic_vlint_decode_len(first_byte); + + if (sz == 1) + return first_byte & 0x3F; + + if (sz == 2) + return ((uint64_t)(first_byte & 0x3F) << 8) + | buf[1]; + + if (sz == 4) + return ((uint64_t)(first_byte & 0x3F) << 24) + | ((uint64_t)buf[1] << 16) + | ((uint64_t)buf[2] << 8) + | buf[3]; + + return ((uint64_t)(first_byte & 0x3F) << 56) + | ((uint64_t)buf[1] << 48) + | ((uint64_t)buf[2] << 40) + | ((uint64_t)buf[3] << 32) + | ((uint64_t)buf[4] << 24) + | ((uint64_t)buf[5] << 16) + | ((uint64_t)buf[6] << 8) + | buf[7]; +} + +int ossl_quic_vlint_decode(const unsigned char *buf, size_t buf_len, uint64_t *v) +{ + size_t dec_len; + uint64_t x; + + if (buf_len < 1) + return 0; + + dec_len = ossl_quic_vlint_decode_len(buf[0]); + if (buf_len < dec_len) + return 0; + + x = ossl_quic_vlint_decode_unchecked(buf); + + *v = x; + return dec_len; +} + +#endif diff --git a/crypto/rand/build.info b/crypto/rand/build.info index a74282516f..7c01577b0d 100644 --- a/crypto/rand/build.info +++ b/crypto/rand/build.info @@ -1,7 +1,8 @@ LIBS=../../libcrypto $COMMON=rand_lib.c -$CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c +$CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c \ + rand_uniform.c IF[{- !$disabled{'egd'} -}] $CRYPTO=$CRYPTO rand_egd.c diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c index 00784f4c56..2985c7f2d8 100644 --- a/crypto/rand/prov_seed.c +++ b/crypto/rand/prov_seed.c @@ -25,7 +25,7 @@ size_t ossl_rand_get_entropy(ossl_unused OSSL_LIB_CTX *ctx, pool = ossl_rand_pool_new(entropy, 1, min_len, max_len); if (pool == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RAND, ERR_R_RAND_LIB); return 0; } @@ -81,7 +81,7 @@ size_t ossl_rand_get_nonce(ossl_unused OSSL_LIB_CTX *ctx, pool = ossl_rand_pool_new(0, 0, min_len, max_len); if (pool == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RAND, ERR_R_RAND_LIB); return 0; } diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c index 1699e7f38f..f44b38d1a9 100644 --- a/crypto/rand/rand_egd.c +++ b/crypto/rand/rand_egd.c @@ -83,14 +83,14 @@ int hpns_socket(int family, socket_transport_name_get(AF_UNIX, current_transport, 20); - if (strcmp(current_transport,transport) == 0) + if (strcmp(current_transport, transport) == 0) return socket(family, type, protocol); /* set the requested socket transport */ if (socket_transport_name_set(AF_UNIX, transport)) return -1; - socket_rc = socket(family,type,protocol); + socket_rc = socket(family, type, protocol); /* set mode back to what it was */ if (socket_transport_name_set(AF_UNIX, current_transport)) @@ -133,7 +133,7 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) setbuf(fp, NULL); /* Try to connect */ - for ( ; ; ) { + for (;;) { if (connect(fd, (struct sockaddr *)&addr, i) == 0) break; # ifdef EISCONN diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 2be5652097..14999540ab 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -190,6 +190,13 @@ const RAND_METHOD *RAND_get_rand_method(void) if (!RUN_ONCE(&rand_init, do_rand_init)) return NULL; + if (!CRYPTO_THREAD_read_lock(rand_meth_lock)) + return NULL; + tmp_meth = default_RAND_meth; + CRYPTO_THREAD_unlock(rand_meth_lock); + if (tmp_meth != NULL) + return tmp_meth; + if (!CRYPTO_THREAD_write_lock(rand_meth_lock)) return NULL; if (default_RAND_meth == NULL) { @@ -631,12 +638,13 @@ EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx) static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, unsigned int reseed_interval, - time_t reseed_time_interval) + time_t reseed_time_interval, int use_df) { EVP_RAND *rand; RAND_GLOBAL *dgbl = rand_get_global(libctx); EVP_RAND_CTX *ctx; - OSSL_PARAM params[7], *p = params; + OSSL_PARAM params[8], *p = params; + const OSSL_PARAM *settables; char *name, *cipher; if (dgbl == NULL) @@ -654,20 +662,23 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, return NULL; } - /* - * Rather than trying to decode the DRBG settings, just pass them through - * and rely on the other end to ignore those it doesn't care about. - */ - cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, - cipher, 0); - if (dgbl->rng_digest != NULL) + settables = EVP_RAND_CTX_settable_params(ctx); + if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_CIPHER)) { + cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + cipher, 0); + } + if (dgbl->rng_digest != NULL + && OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST)) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, dgbl->rng_digest, 0); if (dgbl->rng_propq != NULL) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, dgbl->rng_propq, 0); - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0); + if (OSSL_PARAM_locate_const(settables, OSSL_ALG_PARAM_MAC)) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0); + if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_USE_DF)) + *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &use_df); *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, &reseed_interval); *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, @@ -722,7 +733,7 @@ EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx) ret = dgbl->primary = rand_new_drbg(ctx, dgbl->seed, PRIMARY_RESEED_INTERVAL, - PRIMARY_RESEED_TIME_INTERVAL); + PRIMARY_RESEED_TIME_INTERVAL, 1); /* * The primary DRBG may be shared between multiple threads so we must * enable locking. @@ -764,7 +775,7 @@ EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx) && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) return NULL; rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, - SECONDARY_RESEED_TIME_INTERVAL); + SECONDARY_RESEED_TIME_INTERVAL, 0); CRYPTO_THREAD_set_local(&dgbl->public, rand); } return rand; @@ -797,7 +808,7 @@ EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx) && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) return NULL; rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, - SECONDARY_RESEED_TIME_INTERVAL); + SECONDARY_RESEED_TIME_INTERVAL, 0); CRYPTO_THREAD_set_local(&dgbl->private, rand); } return rand; @@ -850,10 +861,8 @@ static int random_set_string(char **p, const char *s) if (s != NULL) { d = OPENSSL_strdup(s); - if (d == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (d == NULL) return 0; - } } OPENSSL_free(*p); *p = d; diff --git a/crypto/rand/rand_pool.c b/crypto/rand/rand_pool.c index 6059223574..8262ffe305 100644 --- a/crypto/rand/rand_pool.c +++ b/crypto/rand/rand_pool.c @@ -25,10 +25,8 @@ RAND_POOL *ossl_rand_pool_new(int entropy_requested, int secure, RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure); - if (pool == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + if (pool == NULL) return NULL; - } pool->min_len = min_len; pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ? @@ -42,10 +40,8 @@ RAND_POOL *ossl_rand_pool_new(int entropy_requested, int secure, else pool->buffer = OPENSSL_zalloc(pool->alloc_len); - if (pool->buffer == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + if (pool->buffer == NULL) goto err; - } pool->entropy_requested = entropy_requested; pool->secure = secure; @@ -67,10 +63,8 @@ RAND_POOL *ossl_rand_pool_attach(const unsigned char *buffer, size_t len, { RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool)); - if (pool == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + if (pool == NULL) return NULL; - } /* * The const needs to be cast away, but attached buffers will not be @@ -222,10 +216,8 @@ static int rand_pool_grow(RAND_POOL *pool, size_t len) p = OPENSSL_secure_zalloc(newlen); else p = OPENSSL_zalloc(newlen); - if (p == NULL) { - ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + if (p == NULL) return 0; - } memcpy(p, pool->buffer, pool->len); if (pool->secure) OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len); diff --git a/crypto/rand/rand_uniform.c b/crypto/rand/rand_uniform.c new file mode 100644 index 0000000000..b9e2635859 --- /dev/null +++ b/crypto/rand/rand_uniform.c @@ -0,0 +1,109 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "crypto/rand.h" +#include "internal/common.h" + +/* + * Implementation an optimal random integer in a range function. + * + * Essentially it boils down to incrementally generating a fixed point + * number on the interval [0, 1) and multiplying this number by the upper + * range limit. Once it is certain what the fractional part contributes to + * the integral part of the product, the algorithm has produced a definitive + * result. + * + * Refer: https://github.com/apple/swift/pull/39143 for a fuller description + * of the algorithm. + */ +uint32_t ossl_rand_uniform_uint32(OSSL_LIB_CTX *ctx, uint32_t upper, int *err) +{ + uint32_t i, f; /* integer and fractional parts */ + uint32_t f2, rand; /* extra fractional part and random material */ + uint64_t prod; /* temporary holding double width product */ + const int max_followup_iterations = 10; + int j; + + if (!ossl_assert(upper > 0)) { + *err = 0; + return 0; + } + if (unlikely(upper == 1)) + return 0; + + /* Get 32 bits of entropy */ + if (RAND_bytes_ex(ctx, (unsigned char *)&rand, sizeof(rand), 0) <= 0) { + *err = 1; + return 0; + } + + /* + * We are generating a fixed point number on the interval [0, 1). + * Multiplying this by the range gives us a number on [0, upper). + * The high word of the multiplication result represents the integral + * part we want. The lower word is the fractional part. We can early exit if + * if the fractional part is small enough that no carry from the next lower + * word can cause an overflow and carry into the integer part. This + * happens when the fractional part is bounded by 2^32 - upper which + * can be simplified to just -upper (as an unsigned integer). + */ + prod = (uint64_t)upper * rand; + i = prod >> 32; + f = prod & 0xffffffff; + if (likely(f <= 1 + ~upper)) /* 1+~upper == -upper but compilers whine */ + return i; + + /* + * We're in the position where the carry from the next word *might* cause + * a carry to the integral part. The process here is to generate the next + * word, multiply it by the range and add that to the current word. If + * it overflows, the carry propagates to the integer part (return i+1). + * If it can no longer overflow regardless of further lower order bits, + * we are done (return i). If there is still a chance of overflow, we + * repeat the process with the next lower word. + * + * Each *bit* of randomness has a probability of one half of terminating + * this process, so each each word beyond the first has a probability + * of 2^-32 of not terminating the process. That is, we're extremely + * likely to stop very rapidly. + */ + for (j = 0; j < max_followup_iterations; j++) { + if (RAND_bytes_ex(ctx, (unsigned char *)&rand, sizeof(rand), 0) <= 0) { + *err = 1; + return 0; + } + prod = (uint64_t)upper * rand; + f2 = prod >> 32; + f += f2; + /* On overflow, add the carry to our result */ + if (f < f2) + return i + 1; + /* For not all 1 bits, there is no carry so return the result */ + if (likely(f != 0xffffffff)) + return i; + /* setup for the next word of randomness */ + f = prod & 0xffffffff; + } + /* + * If we get here, we've consumed 32 * max_followup_iterations + 32 bits + * with no firm decision, this gives a bias with probability < 2^-(32*n), + * which is likely acceptable. + */ + return i; +} + +uint32_t ossl_rand_range_uint32(OSSL_LIB_CTX *ctx, uint32_t lower, uint32_t upper, + int *err) +{ + if (!ossl_assert(lower < upper)) { + *err = 1; + return 0; + } + return lower + ossl_rand_uniform_uint32(ctx, upper - lower, err); +} diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index 82f4163738..31edd4f560 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -144,14 +144,14 @@ int RAND_load_file(const char *file, long bytes) # pragma environment restore #endif - for ( ; ; ) { + for (;;) { if (bytes > 0) n = (bytes <= RAND_LOAD_BUF_SIZE) ? (int)bytes : RAND_BUF_SIZE; else n = RAND_LOAD_BUF_SIZE; i = fread(buf, 1, n, in); #ifdef EINTR - if (ferror(in) && errno == EINTR){ + if (ferror(in) && errno == EINTR) { clearerr(in); if (i == 0) continue; diff --git a/crypto/rc2/rc2_local.h b/crypto/rc2/rc2_local.h index e23bacd19d..f9ca888a63 100644 --- a/crypto/rc2/rc2_local.h +++ b/crypto/rc2/rc2_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -66,69 +66,3 @@ } \ } -/* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - /* fall through */ \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - /* fall through */ \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - /* fall through */ \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - /* fall through */ \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - /* fall through */ \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - /* fall through */ \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - /* fall through */ \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - /* fall through */ \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - /* fall through */ \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - /* fall through */ \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - /* fall through */ \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - /* fall through */ \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - /* fall through */ \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - /* fall through */ \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -#undef n2l -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -#undef l2n -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#define C_RC2(n) \ - t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ - x0=(t<<1)|(t>>15); \ - t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ - x1=(t<<2)|(t>>14); \ - t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ - x2=(t<<3)|(t>>13); \ - t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ - x3=(t<<5)|(t>>11); diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl index 5a903f5739..83a1d13635 100755 --- a/crypto/rc4/asm/rc4-x86_64.pl +++ b/crypto/rc4/asm/rc4-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -23,7 +23,7 @@ # Presumably it has everything to do with AMD cache architecture and # RAW or whatever penalties. Once again! The module *requires* config # line *without* RC4_CHAR! As for coding "secret," I bet on partial -# register arithmetics. For example instead of 'inc %r8; and $255,%r8' +# register arithmetic. For example instead of 'inc %r8; and $255,%r8' # I simply 'inc %r8b'. Even though optimization manual discourages # to operate on partial registers, it turned out to be the best bet. # At least for AMD... How IA32E would perform remains to be seen... diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 77208d820d..148d0bbbd1 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -154,14 +154,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); if (rklen <= 0) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_ASN1_LIB); ASN1_STRING_free(str); return 0; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, strtype, str, rk, rklen)) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_ASN1_LIB); ASN1_STRING_free(str); OPENSSL_clear_free(rk, rklen); return 0; @@ -220,7 +220,7 @@ static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, return 0; } } else if (pss == NULL) { - if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) + if (BIO_puts(bp, "(INVALID PSS PARAMETERS)\n") <= 0) return 0; return 1; } @@ -850,7 +850,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, int ok = 0; if (rsa == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_RSA_LIB); return 0; } diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index f9d1cb361d..62d0a4c3b3 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -44,7 +44,7 @@ static int collect_numbers(STACK_OF(BIGNUM) *numbers, if (numbers == NULL) return 0; - for (i = 0; names[i] != NULL; i++){ + for (i = 0; names[i] != NULL; i++) { p = OSSL_PARAM_locate_const(params, names[i]); if (p != NULL) { BIGNUM *tmp = NULL; @@ -389,10 +389,8 @@ RSA *ossl_rsa_dup(const RSA *rsa, int selection) const RSA_PRIME_INFO *pinfo = NULL; RSA_PRIME_INFO *duppinfo = NULL; - if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) goto err; - } /* push first so cleanup in error case works */ (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo); @@ -514,7 +512,7 @@ int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, if (pss->trailerField) *ptrailerField = ASN1_INTEGER_get(pss->trailerField); else - *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; + *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params); return 1; } diff --git a/crypto/rsa/rsa_chk.c b/crypto/rsa/rsa_chk.c index c2549188f5..0df254676a 100644 --- a/crypto/rsa/rsa_chk.c +++ b/crypto/rsa/rsa_chk.c @@ -51,7 +51,7 @@ static int rsa_validate_keypair_multiprime(const RSA *key, BN_GENCB *cb) if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } diff --git a/crypto/rsa/rsa_crpt.c b/crypto/rsa/rsa_crpt.c index 6bc6aafcc8..21c922e609 100644 --- a/crypto/rsa/rsa_crpt.c +++ b/crypto/rsa/rsa_crpt.c @@ -129,7 +129,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BN_CTX_start(ctx); e = BN_CTX_get(ctx); if (e == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } @@ -147,7 +147,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BIGNUM *n = BN_new(); if (n == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index e0d139d312..0cdbb3fde2 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -86,21 +86,22 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, int ok = -1; if (bits < RSA_MIN_MODULUS_BITS) { - ok = 0; /* we set our own err */ ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); - goto err; + return 0; + } + if (e_value == NULL) { + ERR_raise(ERR_LIB_RSA, RSA_R_BAD_E_VALUE); + return 0; } - /* A bad value for e can cause infinite loops */ - if (e_value != NULL && !ossl_rsa_check_public_exponent(e_value)) { + if (!ossl_rsa_check_public_exponent(e_value)) { ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); return 0; } if (primes < RSA_DEFAULT_PRIME_NUM || primes > ossl_rsa_multip_cap(bits)) { - ok = 0; /* we set our own err */ ERR_raise(ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID); - goto err; + return 0; } ctx = BN_CTX_new_ex(rsa->libctx); diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 6d0a92cc23..9548054da7 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -76,15 +76,18 @@ static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { RSA *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } - ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_CRYPTO_LIB); + OPENSSL_free(ret); + return NULL; + } + + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; } @@ -137,7 +140,7 @@ void RSA_free(RSA *r) if (r == NULL) return; - CRYPTO_DOWN_REF(&r->references, &i, r->lock); + CRYPTO_DOWN_REF(&r->references, &i); REF_PRINT_COUNT("RSA", r); if (i > 0) return; @@ -154,6 +157,7 @@ void RSA_free(RSA *r) #endif CRYPTO_THREAD_lock_free(r->lock); + CRYPTO_FREE_REF(&r->references); BN_free(r->n); BN_free(r->e); @@ -181,7 +185,7 @@ int RSA_up_ref(RSA *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) + if (CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; REF_PRINT_COUNT("RSA", r); @@ -791,10 +795,8 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, goto err; /* Using ossl_rsa_multip_info_new() is wasteful, so allocate directly */ - if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) goto err; - } pinfo->r = prime; pinfo->d = exp; diff --git a/crypto/rsa/rsa_meth.c b/crypto/rsa/rsa_meth.c index 82f13bb359..f04098bd08 100644 --- a/crypto/rsa/rsa_meth.c +++ b/crypto/rsa/rsa_meth.c @@ -31,7 +31,6 @@ RSA_METHOD *RSA_meth_new(const char *name, int flags) OPENSSL_free(meth); } - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -57,7 +56,6 @@ RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) OPENSSL_free(ret); } - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -70,10 +68,8 @@ int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) { char *tmpname = OPENSSL_strdup(name); - if (tmpname == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (tmpname == NULL) return 0; - } OPENSSL_free(meth->name); meth->name = tmpname; diff --git a/crypto/rsa/rsa_mp.c b/crypto/rsa/rsa_mp.c index ba042ed189..cb2fb7d1e8 100644 --- a/crypto/rsa/rsa_mp.c +++ b/crypto/rsa/rsa_mp.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 BaishanCloud. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -33,10 +33,8 @@ RSA_PRIME_INFO *ossl_rsa_multip_info_new(void) RSA_PRIME_INFO *pinfo; /* create an RSA_PRIME_INFO structure */ - if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if ((pinfo = OPENSSL_zalloc(sizeof(RSA_PRIME_INFO))) == NULL) return NULL; - } if ((pinfo->r = BN_secure_new()) == NULL) goto err; if ((pinfo->d = BN_secure_new()) == NULL) diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index d9be1a4f98..b9030440c4 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -112,10 +112,8 @@ int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx, dbmask_len = emlen - mdlen; dbmask = OPENSSL_malloc(dbmask_len); - if (dbmask == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (dbmask == NULL) goto err; - } /* step 3e: dbMask = MGF(mgfSeed, nLen - HLen - 1) */ if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) @@ -203,16 +201,12 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, dblen = num - mdlen - 1; db = OPENSSL_malloc(dblen); - if (db == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (db == NULL) goto cleanup; - } em = OPENSSL_malloc(num); - if (em == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (em == NULL) goto cleanup; - } /* * Caller is encouraged to pass zero-padded message created with diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index 0fc642e777..14dfd457f9 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -17,6 +17,9 @@ #include "crypto/bn.h" #include "rsa_local.h" #include "internal/constant_time.h" +#include +#include +#include static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); @@ -30,6 +33,27 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); static int rsa_ossl_init(RSA *rsa); static int rsa_ossl_finish(RSA *rsa); +#ifdef S390X_MOD_EXP +static int rsa_ossl_s390x_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx); +static RSA_METHOD rsa_pkcs1_ossl_meth = { + "OpenSSL PKCS#1 RSA", + rsa_ossl_public_encrypt, + rsa_ossl_public_decrypt, /* signature verification */ + rsa_ossl_private_encrypt, /* signing */ + rsa_ossl_private_decrypt, + rsa_ossl_s390x_mod_exp, + s390x_mod_exp, + rsa_ossl_init, + rsa_ossl_finish, + RSA_FLAG_FIPS_METHOD, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL, /* rsa_keygen */ + NULL /* rsa_multi_prime_keygen */ +}; +#else static RSA_METHOD rsa_pkcs1_ossl_meth = { "OpenSSL PKCS#1 RSA", rsa_ossl_public_encrypt, @@ -48,6 +72,7 @@ static RSA_METHOD rsa_pkcs1_ossl_meth = { NULL, /* rsa_keygen */ NULL /* rsa_multi_prime_keygen */ }; +#endif static const RSA_METHOD *default_RSA_meth = &rsa_pkcs1_ossl_meth; @@ -104,10 +129,8 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (ret == NULL || buf == NULL) goto err; - } switch (padding) { case RSA_PKCS1_PADDING: @@ -163,11 +186,21 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; - if (!CRYPTO_THREAD_write_lock(rsa->lock)) + if (!CRYPTO_THREAD_read_lock(rsa->lock)) return NULL; if (rsa->blinding == NULL) { - rsa->blinding = RSA_setup_blinding(rsa, ctx); + /* + * This dance with upgrading the lock from read to write will be + * slower in cases of a single use RSA object, but should be + * significantly better in multi-thread cases (e.g. servers). It's + * probably worth it. + */ + CRYPTO_THREAD_unlock(rsa->lock); + if (!CRYPTO_THREAD_write_lock(rsa->lock)) + return NULL; + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->blinding; @@ -189,7 +222,11 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) *local = 0; if (rsa->mt_blinding == NULL) { - rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + CRYPTO_THREAD_unlock(rsa->lock); + if (!CRYPTO_THREAD_write_lock(rsa->lock)) + return NULL; + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->mt_blinding; } @@ -262,10 +299,8 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (ret == NULL || buf == NULL) goto err; - } switch (padding) { case RSA_PKCS1_PADDING: @@ -308,7 +343,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) @@ -325,7 +360,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, } else { BIGNUM *d = BN_new(); if (d == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } if (rsa->d == NULL) { @@ -371,12 +406,98 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, return r; } +static int derive_kdk(int flen, const unsigned char *from, RSA *rsa, + unsigned char *buf, int num, unsigned char *kdk) +{ + int ret = 0; + HMAC_CTX *hmac = NULL; + EVP_MD *md = NULL; + unsigned int md_len = SHA256_DIGEST_LENGTH; + unsigned char d_hash[SHA256_DIGEST_LENGTH] = {0}; + /* + * because we use d as a handle to rsa->d we need to keep it local and + * free before any further use of rsa->d + */ + BIGNUM *d = BN_new(); + + if (d == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_CRYPTO_LIB); + goto err; + } + if (rsa->d == NULL) { + ERR_raise(ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY); + BN_free(d); + goto err; + } + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + if (BN_bn2binpad(d, buf, num) < 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + BN_free(d); + goto err; + } + BN_free(d); + + /* + * we use hardcoded hash so that migrating between versions that use + * different hash doesn't provide a Bleichenbacher oracle: + * if the attacker can see that different versions return different + * messages for the same ciphertext, they'll know that the message is + * synthetically generated, which means that the padding check failed + */ + md = EVP_MD_fetch(rsa->libctx, "sha256", NULL); + if (md == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_FETCH_FAILED); + goto err; + } + + if (EVP_Digest(buf, num, d_hash, NULL, md, NULL) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + hmac = HMAC_CTX_new(); + if (hmac == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_CRYPTO_LIB); + goto err; + } + + if (HMAC_Init_ex(hmac, d_hash, sizeof(d_hash), md, NULL) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (flen < num) { + memset(buf, 0, num - flen); + if (HMAC_Update(hmac, buf, num - flen) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + } + if (HMAC_Update(hmac, from, flen) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + md_len = SHA256_DIGEST_LENGTH; + if (HMAC_Final(hmac, kdk, &md_len) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + ret = 1; + + err: + HMAC_CTX_free(hmac); + EVP_MD_free(md); + return ret; +} + static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j, num = 0, r = -1; unsigned char *buf = NULL; + unsigned char kdk[SHA256_DIGEST_LENGTH] = {0}; BN_CTX *ctx = NULL; int local_blinding = 0; /* @@ -387,17 +508,25 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; + /* + * we need the value of the private exponent to perform implicit rejection + */ + if ((rsa->flags & RSA_FLAG_EXT_PKEY) && (padding == RSA_PKCS1_PADDING)) + padding = RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING; + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); + if (ret == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); + goto err; + } num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto err; - } /* * This check was for equality but PGP does evil things and chops off the @@ -408,6 +537,11 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, goto err; } + if (flen < 1) { + ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL); + goto err; + } + /* make data into a big number */ if (BN_bin2bn(from, (int)flen, f) == NULL) goto err; @@ -432,7 +566,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) @@ -450,7 +584,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, } else { BIGNUM *d = BN_new(); if (d == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); goto err; } if (rsa->d == NULL) { @@ -472,14 +606,26 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; + /* + * derive the Key Derivation Key from private exponent and public + * ciphertext + */ + if (padding == RSA_PKCS1_PADDING) { + if (derive_kdk(flen, from, rsa, buf, num, kdk) == 0) + goto err; + } + j = BN_bn2binpad(ret, buf, num); if (j < 0) goto err; switch (padding) { - case RSA_PKCS1_PADDING: + case RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING: r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); break; + case RSA_PKCS1_PADDING: + r = ossl_rsa_padding_check_PKCS1_type_2(rsa->libctx, to, num, buf, j, num, kdk); + break; case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; @@ -539,12 +685,14 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); + if (ret == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_BN_LIB); + goto err; + } num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); - if (ret == NULL || buf == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto err; - } /* * This check was for equality but PGP does evil things and chops off the @@ -998,3 +1146,16 @@ static int rsa_ossl_finish(RSA *rsa) BN_MONT_CTX_free(rsa->_method_mod_q); return 1; } + +#ifdef S390X_MOD_EXP +static int rsa_ossl_s390x_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx) +{ + if (rsa->version != RSA_ASN1_VERSION_MULTI) { + if (s390x_crt(r0, i, rsa->p, rsa->q, rsa->dmp1, rsa->dmq1, rsa->iqmp) == 1) + return 1; + } + return rsa_ossl_mod_exp(r0, i, rsa, ctx); +} + +#endif diff --git a/crypto/rsa/rsa_pk1.c b/crypto/rsa/rsa_pk1.c index 51507fc030..7655ef9a97 100644 --- a/crypto/rsa/rsa_pk1.c +++ b/crypto/rsa/rsa_pk1.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,10 +21,14 @@ #include /* Just for the SSL_MAX_MASTER_KEY_LENGTH value */ #include +#include +#include +#include #include "internal/cryptlib.h" #include "crypto/rsa.h" #include "rsa_local.h" + int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, const unsigned char *from, int flen) { @@ -188,10 +192,8 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, } em = OPENSSL_malloc(num); - if (em == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (em == NULL) return -1; - } /* * Caller is encouraged to pass zero-padded message created with * BN_bn2binpad. Trouble is that since we can't read out of |from|'s @@ -273,6 +275,254 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, return constant_time_select_int(good, mlen, -1); } + +static int ossl_rsa_prf(OSSL_LIB_CTX *ctx, + unsigned char *to, int tlen, + const char *label, int llen, + const unsigned char *kdk, + uint16_t bitlen) +{ + int pos; + int ret = -1; + uint16_t iter = 0; + unsigned char be_iter[sizeof(iter)]; + unsigned char be_bitlen[sizeof(bitlen)]; + HMAC_CTX *hmac = NULL; + EVP_MD *md = NULL; + unsigned char hmac_out[SHA256_DIGEST_LENGTH]; + unsigned int md_len; + + if (tlen * 8 != bitlen) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + return ret; + } + + be_bitlen[0] = (bitlen >> 8) & 0xff; + be_bitlen[1] = bitlen & 0xff; + + hmac = HMAC_CTX_new(); + if (hmac == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * we use hardcoded hash so that migrating between versions that use + * different hash doesn't provide a Bleichenbacher oracle: + * if the attacker can see that different versions return different + * messages for the same ciphertext, they'll know that the message is + * synthetically generated, which means that the padding check failed + */ + md = EVP_MD_fetch(ctx, "sha256", NULL); + if (md == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (HMAC_Init_ex(hmac, kdk, SHA256_DIGEST_LENGTH, md, NULL) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + for (pos = 0; pos < tlen; pos += SHA256_DIGEST_LENGTH, iter++) { + if (HMAC_Init_ex(hmac, NULL, 0, NULL, NULL) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + be_iter[0] = (iter >> 8) & 0xff; + be_iter[1] = iter & 0xff; + + if (HMAC_Update(hmac, be_iter, sizeof(be_iter)) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + if (HMAC_Update(hmac, (unsigned char *)label, llen) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + if (HMAC_Update(hmac, be_bitlen, sizeof(be_bitlen)) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * HMAC_Final requires the output buffer to fit the whole MAC + * value, so we need to use the intermediate buffer for the last + * unaligned block + */ + md_len = SHA256_DIGEST_LENGTH; + if (pos + SHA256_DIGEST_LENGTH > tlen) { + if (HMAC_Final(hmac, hmac_out, &md_len) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(to + pos, hmac_out, tlen - pos); + } else { + if (HMAC_Final(hmac, to + pos, &md_len) <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + } + } + + ret = 0; + +err: + HMAC_CTX_free(hmac); + EVP_MD_free(md); + return ret; +} + +/* + * ossl_rsa_padding_check_PKCS1_type_2() checks and removes the PKCS#1 type 2 + * padding from a decrypted RSA message. Unlike the + * RSA_padding_check_PKCS1_type_2() it will not return an error in case it + * detects a padding error, rather it will return a deterministically generated + * random message. In other words it will perform an implicit rejection + * of an invalid padding. This means that the returned value does not indicate + * if the padding of the encrypted message was correct or not, making + * side channel attacks like the ones described by Bleichenbacher impossible + * without access to the full decrypted value and a brute-force search of + * remaining padding bytes + */ +int ossl_rsa_padding_check_PKCS1_type_2(OSSL_LIB_CTX *ctx, + unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, unsigned char *kdk) +{ +/* + * We need to generate a random length for the synthetic message, to avoid + * bias towards zero and avoid non-constant timeness of DIV, we prepare + * 128 values to check if they are not too large for the used key size, + * and use 0 in case none of them are small enough, as 2^-128 is a good enough + * safety margin + */ +#define MAX_LEN_GEN_TRIES 128 + unsigned char *synthetic = NULL; + int synthetic_length; + uint16_t len_candidate; + unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)]; + uint16_t len_mask; + uint16_t max_sep_offset; + int synth_msg_index = 0; + int ret = -1; + int i, j; + unsigned int good, found_zero_byte; + int zero_index = 0, msg_index; + + /* + * If these checks fail then either the message in publicly invalid, or + * we've been called incorrectly. We can fail immediately. + * Since this code is called only internally by openssl, those are just + * sanity checks + */ + if (num != flen || tlen <= 0 || flen <= 0) { + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* Generate a random message to return in case the padding checks fail */ + synthetic = OPENSSL_malloc(flen); + if (synthetic == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + return -1; + } + + if (ossl_rsa_prf(ctx, synthetic, flen, "message", 7, kdk, flen * 8) < 0) + goto err; + + /* decide how long the random message should be */ + if (ossl_rsa_prf(ctx, candidate_lengths, sizeof(candidate_lengths), + "length", 6, kdk, + MAX_LEN_GEN_TRIES * sizeof(len_candidate) * 8) < 0) + goto err; + + /* + * max message size is the size of the modulus size less 2 bytes for + * version and padding type and a minimum of 8 bytes padding + */ + len_mask = max_sep_offset = flen - 2 - 8; + /* + * we want a mask so lets propagate the high bit to all positions less + * significant than it + */ + len_mask |= len_mask >> 1; + len_mask |= len_mask >> 2; + len_mask |= len_mask >> 4; + len_mask |= len_mask >> 8; + + synthetic_length = 0; + for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate); + i += sizeof(len_candidate)) { + len_candidate = (candidate_lengths[i] << 8) | candidate_lengths[i + 1]; + len_candidate &= len_mask; + + synthetic_length = constant_time_select_int( + constant_time_lt(len_candidate, max_sep_offset), + len_candidate, synthetic_length); + } + + synth_msg_index = flen - synthetic_length; + + /* we have alternative message ready, check the real one */ + good = constant_time_is_zero(from[0]); + good &= constant_time_eq(from[1], 2); + + /* then look for the padding|message separator (the first zero byte) */ + found_zero_byte = 0; + for (i = 2; i < flen; i++) { + unsigned int equals0 = constant_time_is_zero(from[i]); + zero_index = constant_time_select_int(~found_zero_byte & equals0, + i, zero_index); + found_zero_byte |= equals0; + } + + /* + * padding must be at least 8 bytes long, and it starts two bytes into + * |from|. If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ + good &= constant_time_ge(zero_index, 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; + + /* + * old code returned an error in case the decrypted message wouldn't fit + * into the |to|, since that would leak information, return the synthetic + * message instead + */ + good &= constant_time_ge(tlen, num - msg_index); + + msg_index = constant_time_select_int(good, msg_index, synth_msg_index); + + /* + * since at this point the |msg_index| does not provide the signal + * indicating if the padding check failed or not, we don't have to worry + * about leaking the length of returned message, we still need to ensure + * that we read contents of both buffers so that cache accesses don't leak + * the value of |good| + */ + for (i = msg_index, j = 0; i < flen && j < tlen; i++, j++) + to[j] = constant_time_select_8(good, from[i], synthetic[i]); + ret = j; + +err: + /* + * the only time ret < 0 is when the ciphertext is publicly invalid + * or we were called with invalid parameters, so we don't have to perform + * a side-channel secure raising of the error + */ + if (ret < 0) + ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); + OPENSSL_free(synthetic); + return ret; +} + /* * ossl_rsa_padding_check_PKCS1_type_2_TLS() checks and removes the PKCS1 type 2 * padding from a decrypted RSA message in a TLS signature. The result is stored diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index 0bf5ac098a..fc3391ead2 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -52,6 +52,8 @@ typedef struct { /* OAEP label */ unsigned char *oaep_label; size_t oaep_labellen; + /* if to use implicit rejection in PKCS#1 v1.5 decryption */ + int implicit_rejection; } RSA_PKEY_CTX; /* True if PSS parameters are restricted */ @@ -72,6 +74,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx) /* Maximum for sign, auto for verify */ rctx->saltlen = RSA_PSS_SALTLEN_AUTO; rctx->min_saltlen = -1; + rctx->implicit_rejection = 1; ctx->data = rctx; ctx->keygen_info = rctx->gentmp; ctx->keygen_info_count = 2; @@ -97,6 +100,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; dctx->saltlen = sctx->saltlen; + dctx->implicit_rejection = sctx->implicit_rejection; if (sctx->oaep_label) { OPENSSL_free(dctx->oaep_label); dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); @@ -112,10 +116,8 @@ static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) if (ctx->tbuf != NULL) return 1; if ((ctx->tbuf = - OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pk->pkey)))) == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pk->pkey)))) == NULL) return 0; - } return 1; } @@ -164,7 +166,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, return -1; } if (!setup_tbuf(rctx, ctx)) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB); return -1; } memcpy(rctx->tbuf, tbs, tbslen); @@ -347,6 +349,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, const unsigned char *in, size_t inlen) { int ret; + int pad_mode; RSA_PKEY_CTX *rctx = ctx->data; /* * Discard const. Its marked as const because this may be a cached copy of @@ -367,7 +370,12 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, rctx->oaep_labellen, rctx->md, rctx->mgf1md); } else { - ret = RSA_private_decrypt(inlen, in, out, rsa, rctx->pad_mode); + if (rctx->pad_mode == RSA_PKCS1_PADDING && + rctx->implicit_rejection == 0) + pad_mode = RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING; + else + pad_mode = rctx->pad_mode; + ret = RSA_private_decrypt(inlen, in, out, rsa, pad_mode); } *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); ret = constant_time_select_int(constant_time_msb(ret), ret, 1); @@ -394,7 +402,7 @@ static int check_padding_md(const EVP_MD *md, int padding) return 0; } } else { - switch(mdnid) { + switch (mdnid) { /* List of all supported RSA digests */ case NID_sha1: case NID_sha224: @@ -591,6 +599,14 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) *(unsigned char **)p2 = rctx->oaep_label; return rctx->oaep_labellen; + case EVP_PKEY_CTRL_RSA_IMPLICIT_REJECTION: + if (rctx->pad_mode != RSA_PKCS1_PADDING) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE); + return -2; + } + rctx->implicit_rejection = p1; + return 1; + case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_SIGN: #ifndef OPENSSL_NO_CMS diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c index bb46ec64c7..089730bbae 100644 --- a/crypto/rsa/rsa_pss.c +++ b/crypto/rsa/rsa_pss.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -98,10 +98,8 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); - if (DB == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (DB == NULL) goto err; - } if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) goto err; for (i = 0; i < maskedDBLen; i++) @@ -219,10 +217,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, } if (sLen > 0) { salt = OPENSSL_malloc(sLen); - if (salt == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (salt == NULL) goto err; - } if (RAND_bytes_ex(rsa->libctx, salt, sLen, 0) <= 0) goto err; } @@ -338,15 +334,6 @@ int ossl_rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int ossl_rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenalg_nid) -{ - if (rsa_pss_params == NULL) - return 0; - rsa_pss_params->mask_gen.algorithm_nid = maskgenalg_nid; - return 1; -} - int ossl_rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, int maskgenhashalg_nid) { diff --git a/crypto/rsa/rsa_saos.c b/crypto/rsa/rsa_saos.c index 58fa50785b..dc96b6dada 100644 --- a/crypto/rsa/rsa_saos.c +++ b/crypto/rsa/rsa_saos.c @@ -40,10 +40,8 @@ int RSA_sign_ASN1_OCTET_STRING(int type, return 0; } s = OPENSSL_malloc((unsigned int)j + 1); - if (s == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (s == NULL) return 0; - } p = s; i2d_ASN1_OCTET_STRING(&sig, &p); i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); @@ -72,10 +70,8 @@ int RSA_verify_ASN1_OCTET_STRING(int dtype, } s = OPENSSL_malloc((unsigned int)siglen); - if (s == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (s == NULL) goto err; - } i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); if (i <= 0) diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 05fb162424..b14b134080 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -258,10 +258,8 @@ static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, } dig_info_len = di_prefix_len + m_len; dig_info = OPENSSL_malloc(dig_info_len); - if (dig_info == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (dig_info == NULL) return 0; - } memcpy(dig_info, di_prefix, di_prefix_len); memcpy(dig_info + di_prefix_len, m, m_len); @@ -343,10 +341,8 @@ int ossl_rsa_verify(int type, const unsigned char *m, unsigned int m_len, /* Recover the encoded digest. */ decrypt_buf = OPENSSL_malloc(siglen); - if (decrypt_buf == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); + if (decrypt_buf == NULL) goto err; - } len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, RSA_PKCS1_PADDING); diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index fc8f19b487..c585465b32 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -403,6 +403,11 @@ int ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); return 0; } + /* (Step 3.c): check that the modulus length is a positive even integer */ + if (nbits <= 0 || (nbits & 0x1)) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); + return 0; + } ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c index f773d1e149..9fa85bfdf3 100644 --- a/crypto/rsa/rsa_sp800_56b_gen.c +++ b/crypto/rsa/rsa_sp800_56b_gen.c @@ -125,7 +125,7 @@ int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->p, Xpo, p1, p2, Xp, Xp1, Xp2, nbits, e, ctx, cb)) goto err; - for(;;) { + for (;;) { /* (Step 5) Generate q, Xq*/ if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->q, Xqo, q1, q2, Xq, Xq1, Xq2, nbits, e, ctx, cb)) @@ -423,7 +423,7 @@ int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, * See SP800-56Br1 6.3.1.3 (Step 6) Perform a pair-wise consistency test by * verifying that: k = (k^e)^d mod n for some integer k where 1 < k < n-1. * - * Returns 1 if the RSA key passes the pairwise test or 0 it it fails. + * Returns 1 if the RSA key passes the pairwise test or 0 if it fails. */ int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) { diff --git a/crypto/rsa/rsa_x931g.c b/crypto/rsa/rsa_x931g.c index 5a309a98c3..290e95b468 100644 --- a/crypto/rsa/rsa_x931g.c +++ b/crypto/rsa/rsa_x931g.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,10 +31,10 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BN_CTX *ctx = NULL, *ctx2 = NULL; int ret = 0; - if (!rsa) + if (rsa == NULL) goto err; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -145,7 +145,6 @@ int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BN_CTX_free(ctx2); return ret; - } int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, @@ -155,7 +154,7 @@ int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BIGNUM *Xp = NULL, *Xq = NULL; BN_CTX *ctx = NULL; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) goto error; diff --git a/crypto/s390x_arch.h b/crypto/s390x_arch.h index a7bde67d90..fdc682af06 100644 --- a/crypto/s390x_arch.h +++ b/crypto/s390x_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,8 @@ # ifndef __ASSEMBLER__ +#include "crypto/bn.h" + void s390x_kimd(const unsigned char *in, size_t len, unsigned int fc, void *param); void s390x_klmd(const unsigned char *in, size_t inlen, unsigned char *out, @@ -77,6 +79,13 @@ __attribute__ ((visibility("hidden"))) #endif extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; +#ifdef S390X_MOD_EXP +# if defined(__GNUC__) && defined(__linux) +__attribute__ ((visibility("hidden"))) +# endif +extern int OPENSSL_s390xcex; +#endif + /* Max number of 64-bit words currently returned by STFLE */ # define S390X_STFLE_MAX 3 @@ -125,6 +134,10 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; # define S390X_SHA3_256 33 # define S390X_SHA3_384 34 # define S390X_SHA3_512 35 +# define S390X_KECCAK_224 32 +# define S390X_KECCAK_256 33 +# define S390X_KECCAK_384 34 +# define S390X_KECCAK_512 35 # define S390X_SHAKE_128 36 # define S390X_SHAKE_256 37 # define S390X_GHASH 65 @@ -169,5 +182,6 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; # define S390X_KMA_LAAD 0x200 # define S390X_KMA_HS 0x400 # define S390X_KDSA_D 0x80 +# define S390X_KLMD_PS 0x100 #endif diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index 970cbe2d32..7721b5c801 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -16,6 +16,15 @@ #include "crypto/ctype.h" #include "s390x_arch.h" +#if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE) +# include +# include +# include +# include +# include +# include +#endif + #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 16) # include @@ -69,19 +78,41 @@ void OPENSSL_vx_probe(void); #endif static const char *env; -static int parse_env(struct OPENSSL_s390xcap_st *cap); +static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex); void OPENSSL_s390x_facilities(void); void OPENSSL_s390x_functions(void); struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; +#ifdef S390X_MOD_EXP +static int probe_cex(void); +int OPENSSL_s390xcex; + +#if defined(__GNUC__) +__attribute__ ((visibility("hidden"))) +#endif +void OPENSSL_s390x_cleanup(void); + +#if defined(__GNUC__) +__attribute__ ((visibility("hidden"))) +#endif +void OPENSSL_s390x_cleanup(void) +{ + if (OPENSSL_s390xcex != -1) { + (void)close(OPENSSL_s390xcex); + OPENSSL_s390xcex = -1; + } +} +#endif + #if defined(__GNUC__) && defined(__linux) __attribute__ ((visibility("hidden"))) #endif void OPENSSL_cpuid_setup(void) { struct OPENSSL_s390xcap_st cap; + int cex = 1; if (OPENSSL_s390xcap_P.stfle[0]) return; @@ -142,7 +173,7 @@ void OPENSSL_cpuid_setup(void) env = getenv("OPENSSL_s390xcap"); if (env != NULL) { - if (!parse_env(&cap)) + if (!parse_env(&cap, &cex)) env = NULL; } @@ -180,9 +211,52 @@ void OPENSSL_cpuid_setup(void) OPENSSL_s390xcap_P.kdsa[0] &= cap.kdsa[0]; OPENSSL_s390xcap_P.kdsa[1] &= cap.kdsa[1]; } + +#ifdef S390X_MOD_EXP + if (cex == 0) { + OPENSSL_s390xcex = -1; + } else { + OPENSSL_s390xcex = open("/dev/z90crypt", O_RDWR | O_CLOEXEC); + if (probe_cex() == 1) + OPENSSL_atexit(OPENSSL_s390x_cleanup); + } +#endif } -static int parse_env(struct OPENSSL_s390xcap_st *cap) +#ifdef S390X_MOD_EXP +static int probe_cex(void) +{ + struct ica_rsa_modexpo me; + const unsigned char inval[16] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,2 + }; + const unsigned char modulus[16] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3 + }; + unsigned char res[16]; + int olderrno; + int rc = 1; + + me.inputdata = (unsigned char *)inval; + me.inputdatalength = sizeof(inval); + me.outputdata = (unsigned char *)res; + me.outputdatalength = sizeof(res); + me.b_key = (unsigned char *)inval; + me.n_modulus = (unsigned char *)modulus; + olderrno = errno; + if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) == -1) { + (void)close(OPENSSL_s390xcex); + OPENSSL_s390xcex = -1; + rc = 0; + } + errno = olderrno; + return rc; +} +#endif + +static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex) { /*- * CPU model data @@ -733,6 +807,13 @@ static int parse_env(struct OPENSSL_s390xcap_st *cap) else if TOK_CPU(z15) else if TOK_CPU_ALIAS(z16, z15) + /* nocex to deactivate cex support */ + else if (sscanf(tok_begin, " %" STR(LEN) "s %" STR(LEN) "s ", + tok[0], tok[1]) == 1 + && !strcmp(tok[0], "nocex")) { + *cex = 0; + } + /* whitespace(ignored) or invalid tokens */ else { while (*tok_begin != '\0') { diff --git a/crypto/sha/asm/keccak1600-ppc64.pl b/crypto/sha/asm/keccak1600-ppc64.pl index 6ab347cefa..bff0d78585 100755 --- a/crypto/sha/asm/keccak1600-ppc64.pl +++ b/crypto/sha/asm/keccak1600-ppc64.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-armv8.pl b/crypto/sha/asm/sha1-armv8.pl index 26b1dba6f8..5f23a20c1a 100644 --- a/crypto/sha/asm/sha1-armv8.pl +++ b/crypto/sha/asm/sha1-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha256-armv8.S b/crypto/sha/asm/sha256-armv8.S index a2de515a86..6d1cb31808 100644 --- a/crypto/sha/asm/sha256-armv8.S +++ b/crypto/sha/asm/sha256-armv8.S @@ -1,4 +1,4 @@ -// Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the Apache License 2.0 (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-armv8.S b/crypto/sha/asm/sha512-armv8.S index 544c23973b..37091dcc70 100644 --- a/crypto/sha/asm/sha512-armv8.S +++ b/crypto/sha/asm/sha512-armv8.S @@ -1,4 +1,4 @@ -// Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the Apache License 2.0 (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-armv8.pl b/crypto/sha/asm/sha512-armv8.pl index ae10d4a33f..f900882fee 100644 --- a/crypto/sha/asm/sha512-armv8.pl +++ b/crypto/sha/asm/sha512-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-ia64.pl b/crypto/sha/asm/sha512-ia64.pl index 178cc149d2..e147f2682d 100755 --- a/crypto/sha/asm/sha512-ia64.pl +++ b/crypto/sha/asm/sha512-ia64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/keccak1600.c b/crypto/sha/keccak1600.c index ccbf12b1c6..c15bc42aaa 100644 --- a/crypto/sha/keccak1600.c +++ b/crypto/sha/keccak1600.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1153,7 +1153,7 @@ void SHA3_sponge(const unsigned char *inp, size_t len, # include -int main() +int main(void) { /* * This is 5-bit SHAKE128 test from http://csrc.nist.gov/groups/ST/toolkit/examples.html#aHashing @@ -1242,11 +1242,11 @@ int main() printf(++i % 16 && i != sizeof(out) ? " " : "\n"); } - if (memcmp(out,result,sizeof(out))) { - fprintf(stderr,"failure\n"); + if (memcmp(out, result, sizeof(out))) { + fprintf(stderr, "failure\n"); return 1; } else { - fprintf(stderr,"success\n"); + fprintf(stderr, "success\n"); return 0; } } diff --git a/crypto/sha/sha1dgst.c b/crypto/sha/sha1dgst.c index 65d7e62e58..e8f1ef5244 100644 --- a/crypto/sha/sha1dgst.c +++ b/crypto/sha/sha1dgst.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,7 +20,7 @@ #include #include -/* The implementation is in ../md32_common.h */ +/* The implementation is in crypto/md32_common.h */ #include "sha_local.h" #include "crypto/sha.h" diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c index 996ef10054..4017137c27 100644 --- a/crypto/sha/sha256.c +++ b/crypto/sha/sha256.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,6 +22,7 @@ #include #include #include "internal/endian.h" +#include "crypto/sha.h" int SHA224_Init(SHA256_CTX *c) { @@ -53,6 +54,13 @@ int SHA256_Init(SHA256_CTX *c) return 1; } +int ossl_sha256_192_init(SHA256_CTX *c) +{ + SHA256_Init(c); + c->md_len = SHA256_192_DIGEST_LENGTH; + return 1; +} + int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) { return SHA256_Update(c, data, len); @@ -81,7 +89,11 @@ int SHA224_Final(unsigned char *md, SHA256_CTX *c) unsigned long ll; \ unsigned int nn; \ switch ((c)->md_len) \ - { case SHA224_DIGEST_LENGTH: \ + { case SHA256_192_DIGEST_LENGTH: \ + for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + case SHA224_DIGEST_LENGTH: \ for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ break; \ diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c index 9d44eb28ec..ee00b55de8 100644 --- a/crypto/sha/sha512.c +++ b/crypto/sha/sha512.c @@ -25,7 +25,7 @@ * on [aligned] data in host byte order and one - on data in input * stream byte order; * - share common byte-order neutral collector and padding function - * implementations, ../md32_common.h; + * implementations, crypto/md32_common.h; * * Neither of the above applies to this SHA-512 implementations. Reasons * [in reverse order] are: diff --git a/crypto/sleep.c b/crypto/sleep.c new file mode 100644 index 0000000000..d9c5b35b21 --- /dev/null +++ b/crypto/sleep.c @@ -0,0 +1,95 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/e_os.h" + +/* system-specific variants defining OSSL_sleep() */ +#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) +#include + +void OSSL_sleep(uint64_t millis) +{ +# ifdef OPENSSL_SYS_VXWORKS + struct timespec ts; + + ts.tv_sec = (long int) (millis / 1000); + ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; + nanosleep(&ts, NULL); +# elif defined(__TANDEM) +# if !defined(_REENTRANT) +# include + + /* HPNS does not support usleep for non threaded apps */ + PROCESS_DELAY_(millis * 1000); +# elif defined(_SPT_MODEL_) +# include +# include + + usleep(millis * 1000); +# else + usleep(millis * 1000); +# endif +# else + unsigned int s = (unsigned int)(millis / 1000); + unsigned int us = (unsigned int)((millis % 1000) * 1000); + + sleep(s); + usleep(us); +# endif +} +#elif defined(_WIN32) && !defined(OPENSSL_SYS_UEFI) +# include + +void OSSL_sleep(uint64_t millis) +{ + /* + * Windows' Sleep() takes a DWORD argument, which is smaller than + * a uint64_t, so we need to limit it to 49 days, which should be enough. + */ + DWORD limited_millis = (DWORD)-1; + + if (millis < limited_millis) + limited_millis = (DWORD)millis; + Sleep(limited_millis); +} + +#else +/* Fallback to a busy wait */ +# include "internal/time.h" + +static void ossl_sleep_secs(uint64_t secs) +{ + /* + * sleep() takes an unsigned int argument, which is smaller than + * a uint64_t, so it needs to be limited to 136 years which + * should be enough even for Sleeping Beauty. + */ + unsigned int limited_secs = UINT_MAX; + + if (secs < limited_secs) + limited_secs = (unsigned int)secs; + sleep(limited_secs); +} + +static void ossl_sleep_millis(uint64_t millis) +{ + const OSSL_TIME finish + = ossl_time_add(ossl_time_now(), ossl_ms2time(millis)); + + while (ossl_time_compare(ossl_time_now(), finish) < 0) + /* busy wait */ ; +} + +void OSSL_sleep(uint64_t millis) +{ + ossl_sleep_secs(millis / 1000); + ossl_sleep_millis(millis % 1000); +} +#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */ diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index 5318c6199f..971d348cce 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -151,9 +151,13 @@ int ossl_sm2_encrypt(const EC_KEY *key, kG = EC_POINT_new(group); kP = EC_POINT_new(group); + if (kG == NULL || kP == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); + goto done; + } ctx = BN_CTX_new_ex(libctx); - if (kG == NULL || kP == NULL || ctx == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -172,10 +176,8 @@ int ossl_sm2_encrypt(const EC_KEY *key, x2y2 = OPENSSL_zalloc(2 * field_size); C3 = OPENSSL_zalloc(C3_size); - if (x2y2 == NULL || C3 == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (x2y2 == NULL || C3 == NULL) goto done; - } memset(ciphertext_buf, 0, *ciphertext_len); @@ -199,10 +201,8 @@ int ossl_sm2_encrypt(const EC_KEY *key, } msg_mask = OPENSSL_zalloc(msg_len); - if (msg_mask == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (msg_mask == NULL) goto done; - } /* X9.63 with no salt happens to match the KDF used in SM2 */ if (!ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, @@ -234,7 +234,7 @@ int ossl_sm2_encrypt(const EC_KEY *key, ctext_struct.C2 = ASN1_OCTET_STRING_new(); if (ctext_struct.C3 == NULL || ctext_struct.C2 == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_ASN1_LIB); goto done; } if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size) @@ -319,7 +319,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, ctx = BN_CTX_new_ex(libctx); if (ctx == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -336,14 +336,12 @@ int ossl_sm2_decrypt(const EC_KEY *key, x2y2 = OPENSSL_zalloc(2 * field_size); computed_C3 = OPENSSL_zalloc(hash_size); - if (msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL) goto done; - } C1 = EC_POINT_new(group); if (C1 == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } @@ -369,7 +367,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, hash = EVP_MD_CTX_new(); if (hash == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); goto done; } diff --git a/crypto/sm2/sm2_key.c b/crypto/sm2/sm2_key.c index 9d0b9208fa..e3a10d38e7 100644 --- a/crypto/sm2/sm2_key.c +++ b/crypto/sm2/sm2_key.c @@ -29,7 +29,7 @@ int ossl_sm2_key_private_check(const EC_KEY *eckey) if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (priv_key = EC_KEY_get0_private_key(eckey)) == NULL - || (order = EC_GROUP_get0_order(group)) == NULL ) { + || (order = EC_GROUP_get0_order(group)) == NULL) { ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); return 0; } diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c index 31b5a63b85..ca76128a24 100644 --- a/crypto/sm2/sm2_sign.c +++ b/crypto/sm2/sm2_sign.c @@ -43,9 +43,13 @@ int ossl_sm2_compute_z_digest(uint8_t *out, uint8_t e_byte = 0; hash = EVP_MD_CTX_new(); + if (hash == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); + goto done; + } ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key)); - if (hash == NULL || ctx == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -58,7 +62,7 @@ int ossl_sm2_compute_z_digest(uint8_t *out, yA = BN_CTX_get(ctx); if (yA == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -100,10 +104,8 @@ int ossl_sm2_compute_z_digest(uint8_t *out, p_bytes = BN_num_bytes(p); buf = OPENSSL_zalloc(p_bytes); - if (buf == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto done; - } if (BN_bn2binpad(a, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) @@ -155,12 +157,14 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_DIGEST); goto done; } + if (hash == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); + goto done; + } z = OPENSSL_zalloc(md_size); - if (hash == NULL || z == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (z == NULL) goto done; - } fetched_digest = EVP_MD_fetch(libctx, EVP_MD_get0_name(digest), propq); if (fetched_digest == NULL) { @@ -210,9 +214,13 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); kG = EC_POINT_new(group); + if (kG == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); + goto done; + } ctx = BN_CTX_new_ex(libctx); - if (kG == NULL || ctx == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) { + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -222,7 +230,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) x1 = BN_CTX_get(ctx); tmp = BN_CTX_get(ctx); if (tmp == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -234,7 +242,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) s = BN_new(); if (r == NULL || s == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -288,7 +296,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) sig = ECDSA_SIG_new(); if (sig == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_ECDSA_LIB); goto done; } @@ -325,7 +333,7 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, ctx = BN_CTX_new_ex(libctx); pt = EC_POINT_new(group); if (ctx == NULL || pt == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB); goto done; } @@ -333,7 +341,7 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, t = BN_CTX_get(ctx); x1 = BN_CTX_get(ctx); if (x1 == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB); goto done; } @@ -382,6 +390,7 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, ret = 1; done: + BN_CTX_end(ctx); EC_POINT_free(pt); BN_CTX_free(ctx); return ret; @@ -481,7 +490,7 @@ int ossl_sm2_internal_verify(const unsigned char *dgst, int dgstlen, s = ECDSA_SIG_new(); if (s == NULL) { - ERR_raise(ERR_LIB_SM2, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SM2, ERR_R_ECDSA_LIB); goto done; } if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { diff --git a/crypto/sm3/sm3_local.h b/crypto/sm3/sm3_local.h index cb5a187a12..101e15c191 100644 --- a/crypto/sm3/sm3_local.h +++ b/crypto/sm3/sm3_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * @@ -34,7 +34,7 @@ } while (0) #if defined(OPENSSL_SM3_ASM) -# if defined(__aarch64__) +# if defined(__aarch64__) || defined(_M_ARM64) # include "crypto/arm_arch.h" # define HWSM3_CAPABLE (OPENSSL_armcap_P & ARMV8_SM3) void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num); diff --git a/crypto/sm4/asm/vpsm4-armv8.S b/crypto/sm4/asm/vpsm4-armv8.S index 5c70a27fa0..b578744823 100644 --- a/crypto/sm4/asm/vpsm4-armv8.S +++ b/crypto/sm4/asm/vpsm4-armv8.S @@ -50,6 +50,8 @@ _vpsm4_consts: .quad 0x56aa3350a3b1bac6,0xb27022dc677d9197 .Lshuffles: .quad 0x0B0A090807060504,0x030201000F0E0D0C +.Lxts_magic: +.quad 0x0101010101010187,0x0101010101010101 .size _vpsm4_consts,.-_vpsm4_consts .type _vpsm4_set_key,%function @@ -2713,3 +2715,2284 @@ vpsm4_ctr32_encrypt_blocks: AARCH64_VALIDATE_LINK_REGISTER ret .size vpsm4_ctr32_encrypt_blocks,.-vpsm4_ctr32_encrypt_blocks +.globl vpsm4_xts_encrypt_gb +.type vpsm4_xts_encrypt_gb,%function +.align 5 +vpsm4_xts_encrypt_gb: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov x26,x3 + mov x27,x4 + mov w28,w6 + ld1 {v8.4s}, [x5] + mov x3,x27 + adr x10,.Lsbox + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x10],#64 + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x10],#64 + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x10],#64 + ld1 {v28.16b,v29.16b,v30.16b,v31.16b},[x10] +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v8.s[0] + mov w13,v8.s[1] + mov w14,v8.s[2] + mov w15,v8.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v8.s[0],w15 + mov v8.s[1],w14 + mov v8.s[2],w13 + mov v8.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x3,x26 + and x29,x2,#0x0F + // convert length into blocks + lsr x2,x2,4 + cmp x2,#1 + b.lt .return_gb + + cmp x29,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks_gb + b.eq .xts_encrypt_blocks_gb + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak_gb or .only_2blks_tweak_gb + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks_gb + subs x2,x2,#1 + b.eq .only_2blks_tweak_gb +.xts_encrypt_blocks_gb: + rbit v8.16b,v8.16b +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x12,v8.d[0] + mov x13,v8.d[1] + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 +.Lxts_8_blocks_process_gb: + cmp x2,#8 + b.lt .Lxts_4_blocks_process_gb + mov v0.d[0],x12 + mov v0.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v0.16b,v0.16b +#endif + mov v1.d[0],x14 + mov v1.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v1.16b,v1.16b +#endif + mov v2.d[0],x16 + mov v2.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v2.16b,v2.16b +#endif + mov v3.d[0],x18 + mov v3.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + mov v12.d[0],x20 + mov v12.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v12.16b,v12.16b +#endif + mov v13.d[0],x22 + mov v13.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v13.16b,v13.16b +#endif + mov v14.d[0],x24 + mov v14.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v14.16b,v14.16b +#endif + mov v15.d[0],x26 + mov v15.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v15.16b,v15.16b +#endif + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + rbit v0.16b,v0.16b + rbit v1.16b,v1.16b + rbit v2.16b,v2.16b + rbit v3.16b,v3.16b + eor v4.16b, v4.16b, v0.16b + eor v5.16b, v5.16b, v1.16b + eor v6.16b, v6.16b, v2.16b + eor v7.16b, v7.16b, v3.16b + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + rbit v12.16b,v12.16b + rbit v13.16b,v13.16b + rbit v14.16b,v14.16b + rbit v15.16b,v15.16b + eor v8.16b, v8.16b, v12.16b + eor v9.16b, v9.16b, v13.16b + eor v10.16b, v10.16b, v14.16b + eor v11.16b, v11.16b, v15.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + zip1 v0.4s,v8.4s,v9.4s + zip2 v1.4s,v8.4s,v9.4s + zip1 v2.4s,v10.4s,v11.4s + zip2 v3.4s,v10.4s,v11.4s + zip1 v8.2d,v0.2d,v2.2d + zip2 v9.2d,v0.2d,v2.2d + zip1 v10.2d,v1.2d,v3.2d + zip2 v11.2d,v1.2d,v3.2d + bl _vpsm4_enc_8blks + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + zip1 v8.4s,v4.4s,v5.4s + zip2 v9.4s,v4.4s,v5.4s + zip1 v10.4s,v6.4s,v7.4s + zip2 v11.4s,v6.4s,v7.4s + zip1 v4.2d,v8.2d,v10.2d + zip2 v5.2d,v8.2d,v10.2d + zip1 v6.2d,v9.2d,v11.2d + zip2 v7.2d,v9.2d,v11.2d + mov v12.d[0],x12 + mov v12.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v12.16b,v12.16b +#endif + mov w7,0x87 + extr x9,x27,x27,#32 + extr x13,x27,x26,#63 + and w8,w7,w9,asr#31 + eor x12,x8,x26,lsl#1 + mov v13.d[0],x14 + mov v13.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v13.16b,v13.16b +#endif + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov v14.d[0],x16 + mov v14.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v14.16b,v14.16b +#endif + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov v15.d[0],x18 + mov v15.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v15.16b,v15.16b +#endif + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov v8.d[0],x20 + mov v8.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov v9.d[0],x22 + mov v9.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov v10.d[0],x24 + mov v10.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov v11.d[0],x26 + mov v11.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 + eor v0.16b, v0.16b, v12.16b + eor v1.16b, v1.16b, v13.16b + eor v2.16b, v2.16b, v14.16b + eor v3.16b, v3.16b, v15.16b + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b + eor v7.16b, v7.16b, v11.16b + + // save the last tweak + st1 {v11.4s},[x5] + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs x2,x2,#8 + b.gt .Lxts_8_blocks_process_gb + b 100f +.Lxts_4_blocks_process_gb: + mov v8.d[0],x12 + mov v8.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov v9.d[0],x14 + mov v9.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v10.d[0],x16 + mov v10.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + mov v11.d[0],x18 + mov v11.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + cmp x2,#4 + b.lt 1f + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + rbit v8.16b,v8.16b + rbit v9.16b,v9.16b + rbit v10.16b,v10.16b + rbit v11.16b,v11.16b + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b + eor v7.16b, v7.16b, v11.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + eor v2.16b, v2.16b, v10.16b + eor v3.16b, v3.16b, v11.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub x2,x2,#4 + mov v8.d[0],x20 + mov v8.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov v9.d[0],x22 + mov v9.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v10.d[0],x24 + mov v10.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + // save the last tweak + st1 {v11.4s},[x5] +1: + // process last block + cmp x2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0],#16 + rbit v8.16b,v8.16b + eor v4.16b, v4.16b, v8.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v8.16b + st1 {v4.4s},[x1],#16 + // save the last tweak + st1 {v8.4s},[x5] + b 100f +1: // process last 2 blocks + cmp x2,#2 + b.gt 1f + ld1 {v4.4s,v5.4s},[x0],#32 + rbit v8.16b,v8.16b + rbit v9.16b,v9.16b + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + st1 {v0.4s,v1.4s},[x1],#32 + // save the last tweak + st1 {v9.4s},[x5] + b 100f +1: // process last 3 blocks + ld1 {v4.4s,v5.4s,v6.4s},[x0],#48 + rbit v8.16b,v8.16b + rbit v9.16b,v9.16b + rbit v10.16b,v10.16b + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + eor v2.16b, v2.16b, v10.16b + st1 {v0.4s,v1.4s,v2.4s},[x1],#48 + // save the last tweak + st1 {v10.4s},[x5] +100: + cmp x29,0 + b.eq .return_gb + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak_gb: + ld1 {v8.4s},[x5] +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + rbit v2.16b,v8.16b + ldr q0, .Lxts_magic + shl v9.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v9.16b, v9.16b, v1.16b + rbit v9.16b,v9.16b + rbit v2.16b,v9.16b + ldr q0, .Lxts_magic + shl v10.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v10.16b, v10.16b, v1.16b + rbit v10.16b,v10.16b + b .check_dec_gb + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak_gb: + mov v9.16b,v8.16b +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v2.16b,v9.16b + ldr q0, .Lxts_magic + shl v10.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v10.16b, v10.16b, v1.16b + b .check_dec_gb + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec_gb: + // encryption:1 decryption:0 + cmp w28,1 + b.eq .prcess_last_2blks_gb + mov v0.16B,v9.16b + mov v9.16B,v10.16b + mov v10.16B,v0.16b + +.prcess_last_2blks_gb: +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v9.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v9.16b + st1 {v4.4s},[x1],#16 + + sub x26,x1,16 +.loop_gb: + subs x29,x29,1 + ldrb w7,[x26,x29] + ldrb w8,[x0,x29] + strb w8,[x26,x29] + strb w7,[x1,x29] + b.gt .loop_gb + ld1 {v4.4s}, [x26] + eor v4.16b, v4.16b, v10.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v10.16b + st1 {v4.4s}, [x26] +.return_gb: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_xts_encrypt_gb,.-vpsm4_xts_encrypt_gb +.globl vpsm4_xts_encrypt +.type vpsm4_xts_encrypt,%function +.align 5 +vpsm4_xts_encrypt: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov x26,x3 + mov x27,x4 + mov w28,w6 + ld1 {v8.4s}, [x5] + mov x3,x27 + adr x10,.Lsbox + ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x10],#64 + ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x10],#64 + ld1 {v24.16b,v25.16b,v26.16b,v27.16b},[x10],#64 + ld1 {v28.16b,v29.16b,v30.16b,v31.16b},[x10] +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v8.s[0] + mov w13,v8.s[1] + mov w14,v8.s[2] + mov w15,v8.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v8.s[0],w15 + mov v8.s[1],w14 + mov v8.s[2],w13 + mov v8.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x3,x26 + and x29,x2,#0x0F + // convert length into blocks + lsr x2,x2,4 + cmp x2,#1 + b.lt .return + + cmp x29,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks + b.eq .xts_encrypt_blocks + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak or .only_2blks_tweak + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks + subs x2,x2,#1 + b.eq .only_2blks_tweak +.xts_encrypt_blocks: +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov x12,v8.d[0] + mov x13,v8.d[1] + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 +.Lxts_8_blocks_process: + cmp x2,#8 + b.lt .Lxts_4_blocks_process + mov v0.d[0],x12 + mov v0.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v0.16b,v0.16b +#endif + mov v1.d[0],x14 + mov v1.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v1.16b,v1.16b +#endif + mov v2.d[0],x16 + mov v2.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v2.16b,v2.16b +#endif + mov v3.d[0],x18 + mov v3.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + mov v12.d[0],x20 + mov v12.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v12.16b,v12.16b +#endif + mov v13.d[0],x22 + mov v13.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v13.16b,v13.16b +#endif + mov v14.d[0],x24 + mov v14.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v14.16b,v14.16b +#endif + mov v15.d[0],x26 + mov v15.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v15.16b,v15.16b +#endif + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + eor v4.16b, v4.16b, v0.16b + eor v5.16b, v5.16b, v1.16b + eor v6.16b, v6.16b, v2.16b + eor v7.16b, v7.16b, v3.16b + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + eor v8.16b, v8.16b, v12.16b + eor v9.16b, v9.16b, v13.16b + eor v10.16b, v10.16b, v14.16b + eor v11.16b, v11.16b, v15.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + zip1 v0.4s,v8.4s,v9.4s + zip2 v1.4s,v8.4s,v9.4s + zip1 v2.4s,v10.4s,v11.4s + zip2 v3.4s,v10.4s,v11.4s + zip1 v8.2d,v0.2d,v2.2d + zip2 v9.2d,v0.2d,v2.2d + zip1 v10.2d,v1.2d,v3.2d + zip2 v11.2d,v1.2d,v3.2d + bl _vpsm4_enc_8blks + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + zip1 v8.4s,v4.4s,v5.4s + zip2 v9.4s,v4.4s,v5.4s + zip1 v10.4s,v6.4s,v7.4s + zip2 v11.4s,v6.4s,v7.4s + zip1 v4.2d,v8.2d,v10.2d + zip2 v5.2d,v8.2d,v10.2d + zip1 v6.2d,v9.2d,v11.2d + zip2 v7.2d,v9.2d,v11.2d + mov v12.d[0],x12 + mov v12.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v12.16b,v12.16b +#endif + mov w7,0x87 + extr x9,x27,x27,#32 + extr x13,x27,x26,#63 + and w8,w7,w9,asr#31 + eor x12,x8,x26,lsl#1 + mov v13.d[0],x14 + mov v13.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v13.16b,v13.16b +#endif + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov v14.d[0],x16 + mov v14.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v14.16b,v14.16b +#endif + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov v15.d[0],x18 + mov v15.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v15.16b,v15.16b +#endif + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov v8.d[0],x20 + mov v8.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov v9.d[0],x22 + mov v9.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov v10.d[0],x24 + mov v10.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov v11.d[0],x26 + mov v11.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 + eor v0.16b, v0.16b, v12.16b + eor v1.16b, v1.16b, v13.16b + eor v2.16b, v2.16b, v14.16b + eor v3.16b, v3.16b, v15.16b + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b + eor v7.16b, v7.16b, v11.16b + + // save the last tweak + st1 {v11.4s},[x5] + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs x2,x2,#8 + b.gt .Lxts_8_blocks_process + b 100f +.Lxts_4_blocks_process: + mov v8.d[0],x12 + mov v8.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov v9.d[0],x14 + mov v9.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v10.d[0],x16 + mov v10.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + mov v11.d[0],x18 + mov v11.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + cmp x2,#4 + b.lt 1f + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b + eor v7.16b, v7.16b, v11.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + eor v2.16b, v2.16b, v10.16b + eor v3.16b, v3.16b, v11.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub x2,x2,#4 + mov v8.d[0],x20 + mov v8.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov v9.d[0],x22 + mov v9.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v10.d[0],x24 + mov v10.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + // save the last tweak + st1 {v11.4s},[x5] +1: + // process last block + cmp x2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v8.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v8.16b + st1 {v4.4s},[x1],#16 + // save the last tweak + st1 {v8.4s},[x5] + b 100f +1: // process last 2 blocks + cmp x2,#2 + b.gt 1f + ld1 {v4.4s,v5.4s},[x0],#32 + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + st1 {v0.4s,v1.4s},[x1],#32 + // save the last tweak + st1 {v9.4s},[x5] + b 100f +1: // process last 3 blocks + ld1 {v4.4s,v5.4s,v6.4s},[x0],#48 + eor v4.16b, v4.16b, v8.16b + eor v5.16b, v5.16b, v9.16b + eor v6.16b, v6.16b, v10.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v8.16b + eor v1.16b, v1.16b, v9.16b + eor v2.16b, v2.16b, v10.16b + st1 {v0.4s,v1.4s,v2.4s},[x1],#48 + // save the last tweak + st1 {v10.4s},[x5] +100: + cmp x29,0 + b.eq .return + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak: + ld1 {v8.4s},[x5] +#ifdef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + mov v2.16b,v8.16b + ldr q0, .Lxts_magic + shl v9.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v9.16b, v9.16b, v1.16b + mov v2.16b,v9.16b + ldr q0, .Lxts_magic + shl v10.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v10.16b, v10.16b, v1.16b + b .check_dec + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak: + mov v9.16b,v8.16b +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif + mov v2.16b,v9.16b + ldr q0, .Lxts_magic + shl v10.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v10.16b, v10.16b, v1.16b + b .check_dec + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec: + // encryption:1 decryption:0 + cmp w28,1 + b.eq .prcess_last_2blks + mov v0.16B,v9.16b + mov v9.16B,v10.16b + mov v10.16B,v0.16b + +.prcess_last_2blks: +#ifdef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifdef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v9.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v9.16b + st1 {v4.4s},[x1],#16 + + sub x26,x1,16 +.loop: + subs x29,x29,1 + ldrb w7,[x26,x29] + ldrb w8,[x0,x29] + strb w8,[x26,x29] + strb w7,[x1,x29] + b.gt .loop + ld1 {v4.4s}, [x26] + eor v4.16b, v4.16b, v10.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + movi v1.16b,#64 + movi v2.16b,#128 + movi v3.16b,#192 + mov v0.s[0],w6 + + sub v1.16b,v0.16b,v1.16b + sub v2.16b,v0.16b,v2.16b + sub v3.16b,v0.16b,v3.16b + + tbl v0.16b,{v16.16b,v17.16b,v18.16b,v19.16b},v0.16b + tbl v1.16b,{v20.16b,v21.16b,v22.16b,v23.16b},v1.16b + tbl v2.16b,{v24.16b,v25.16b,v26.16b,v27.16b},v2.16b + tbl v3.16b,{v28.16b,v29.16b,v30.16b,v31.16b},v3.16b + + mov w6,v0.s[0] + mov w7,v1.s[0] + mov w9,v2.s[0] + add w7,w6,w7 + mov w6,v3.s[0] + add w7,w7,w9 + add w7,w7,w6 + + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v10.16b + st1 {v4.4s}, [x26] +.return: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_xts_encrypt,.-vpsm4_xts_encrypt diff --git a/crypto/sm4/asm/vpsm4-armv8.pl b/crypto/sm4/asm/vpsm4-armv8.pl index a945056ab9..ee96046b95 100755 --- a/crypto/sm4/asm/vpsm4-armv8.pl +++ b/crypto/sm4/asm/vpsm4-armv8.pl @@ -28,6 +28,7 @@ $prefix="vpsm4"; my @vtmp=map("v$_",(0..3)); +my @qtmp=map("q$_",(0..3)); my @data=map("v$_",(4..7)); my @datax=map("v$_",(8..11)); my ($rk0,$rk1)=("v12","v13"); @@ -36,6 +37,7 @@ my @sbox=map("v$_",(16..31)); my ($inp,$outp,$blocks,$rks)=("x0","x1","w2","x3"); my ($tmpw,$tmp,$wtmp0,$wtmp1,$wtmp2)=("w6","x6","w7","w8","w9"); +my ($xtmp1,$xtmp2)=("x8","x9"); my ($ptr,$counter)=("x10","w11"); my ($word0,$word1,$word2,$word3)=("w12","w13","w14","w15"); @@ -60,6 +62,51 @@ () } } +sub rev32_armeb() { + my $dst = shift; + my $src = shift; + + if ($src and ("$src" ne "$dst")) { +$code.=<<___; +#ifdef __AARCH64EB__ + rev32 $dst.16b,$src.16b +#else + mov $dst.16b,$src.16b +#endif +___ + } else { +$code.=<<___; +#ifdef __AARCH64EB__ + rev32 $dst.16b,$dst.16b +#endif +___ + } +} + +sub rbit() { + my $dst = shift; + my $src = shift; + my $std = shift; + + if ($src and ("$src" ne "$dst")) { + if ($std eq "_gb") { +$code.=<<___; + rbit $dst.16b,$src.16b +___ + } else { +$code.=<<___; + mov $dst.16b,$src.16b +___ + } + } else { + if ($std eq "_gb") { +$code.=<<___; + rbit $dst.16b,$src.16b +___ + } + } +} + sub transpose() { my ($dat0,$dat1,$dat2,$dat3,$vt0,$vt1,$vt2,$vt3) = @_; @@ -435,6 +482,58 @@ () ___ } + +sub mov_reg_to_vec() { + my $src0 = shift; + my $src1 = shift; + my $desv = shift; +$code.=<<___; + mov $desv.d[0],$src0 + mov $desv.d[1],$src1 +___ + &rev32_armeb($desv,$desv); +} + +sub mov_vec_to_reg() { + my $srcv = shift; + my $des0 = shift; + my $des1 = shift; +$code.=<<___; + mov $des0,$srcv.d[0] + mov $des1,$srcv.d[1] +___ +} + +sub compute_tweak() { + my $src0 = shift; + my $src1 = shift; + my $des0 = shift; + my $des1 = shift; +$code.=<<___; + mov $wtmp0,0x87 + extr $xtmp2,$src1,$src1,#32 + extr $des1,$src1,$src0,#63 + and $wtmp1,$wtmp0,$wtmp2,asr#31 + eor $des0,$xtmp1,$src0,lsl#1 +___ +} + +sub compute_tweak_vec() { + my $src = shift; + my $des = shift; + my $std = shift; + &rbit(@vtmp[2],$src,$std); +$code.=<<___; + ldr @qtmp[0], .Lxts_magic + shl $des.16b, @vtmp[2].16b, #1 + ext @vtmp[1].16b, @vtmp[2].16b, @vtmp[2].16b,#15 + ushr @vtmp[1].16b, @vtmp[1].16b, #7 + mul @vtmp[1].16b, @vtmp[1].16b, @vtmp[0].16b + eor $des.16b, $des.16b, @vtmp[1].16b +___ + &rbit($des,$des,$std); +} + $code=<<___; #include "arm_arch.h" .arch armv8-a @@ -473,6 +572,8 @@ () .quad 0x56aa3350a3b1bac6,0xb27022dc677d9197 .Lshuffles: .quad 0x0B0A090807060504,0x030201000F0E0D0C +.Lxts_magic: + .quad 0x0101010101010187,0x0101010101010101 .size _vpsm4_consts,.-_vpsm4_consts ___ @@ -1101,6 +1202,365 @@ () .size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks ___ }}} + +{{{ +my ($blocks,$len)=("x2","x2"); +my $ivp=("x5"); +my @twx=map("x$_",(12..27)); +my ($rks1,$rks2)=("x26","x27"); +my $lastBlk=("x26"); +my $enc=("w28"); +my $remain=("x29"); + +my @tweak=@datax; + +sub gen_xts_cipher() { + my $std = shift; +$code.=<<___; +.globl ${prefix}_xts_encrypt${std} +.type ${prefix}_xts_encrypt${std},%function +.align 5 +${prefix}_xts_encrypt${std}: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov $rks1,x3 + mov $rks2,x4 + mov $enc,w6 + ld1 {@tweak[0].4s}, [$ivp] + mov $rks,$rks2 +___ + &load_sbox(); + &rev32(@tweak[0],@tweak[0]); + &encrypt_1blk(@tweak[0]); +$code.=<<___; + mov $rks,$rks1 + and $remain,$len,#0x0F + // convert length into blocks + lsr $blocks,$len,4 + cmp $blocks,#1 + b.lt .return${std} + + cmp $remain,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks${std} + b.eq .xts_encrypt_blocks${std} + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak${std} or .only_2blks_tweak${std} + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks${std} + subs $blocks,$blocks,#1 + b.eq .only_2blks_tweak${std} +.xts_encrypt_blocks${std}: +___ + &rbit(@tweak[0],@tweak[0],$std); + &rev32_armeb(@tweak[0],@tweak[0]); + &mov_vec_to_reg(@tweak[0],@twx[0],@twx[1]); + &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); + &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); + &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); + &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); + &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); + &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); + &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); +$code.=<<___; +.Lxts_8_blocks_process${std}: + cmp $blocks,#8 + b.lt .Lxts_4_blocks_process${std} +___ + &mov_reg_to_vec(@twx[0],@twx[1],@vtmp[0]); + &mov_reg_to_vec(@twx[2],@twx[3],@vtmp[1]); + &mov_reg_to_vec(@twx[4],@twx[5],@vtmp[2]); + &mov_reg_to_vec(@twx[6],@twx[7],@vtmp[3]); + &mov_reg_to_vec(@twx[8],@twx[9],@vtmpx[0]); + &mov_reg_to_vec(@twx[10],@twx[11],@vtmpx[1]); + &mov_reg_to_vec(@twx[12],@twx[13],@vtmpx[2]); + &mov_reg_to_vec(@twx[14],@twx[15],@vtmpx[3]); +$code.=<<___; + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &rbit(@vtmp[0],@vtmp[0],$std); + &rbit(@vtmp[1],@vtmp[1],$std); + &rbit(@vtmp[2],@vtmp[2],$std); + &rbit(@vtmp[3],@vtmp[3],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @vtmp[0].16b + eor @data[1].16b, @data[1].16b, @vtmp[1].16b + eor @data[2].16b, @data[2].16b, @vtmp[2].16b + eor @data[3].16b, @data[3].16b, @vtmp[3].16b + ld1 {@datax[0].4s,$datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 +___ + &rbit(@vtmpx[0],@vtmpx[0],$std); + &rbit(@vtmpx[1],@vtmpx[1],$std); + &rbit(@vtmpx[2],@vtmpx[2],$std); + &rbit(@vtmpx[3],@vtmpx[3],$std); +$code.=<<___; + eor @datax[0].16b, @datax[0].16b, @vtmpx[0].16b + eor @datax[1].16b, @datax[1].16b, @vtmpx[1].16b + eor @datax[2].16b, @datax[2].16b, @vtmpx[2].16b + eor @datax[3].16b, @datax[3].16b, @vtmpx[3].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &rev32(@datax[0],@datax[0]); + &rev32(@datax[1],@datax[1]); + &rev32(@datax[2],@datax[2]); + &rev32(@datax[3],@datax[3]); + &transpose(@data,@vtmp); + &transpose(@datax,@vtmp); +$code.=<<___; + bl _${prefix}_enc_8blks +___ + &transpose(@vtmp,@datax); + &transpose(@data,@datax); + + &mov_reg_to_vec(@twx[0],@twx[1],@vtmpx[0]); + &compute_tweak(@twx[14],@twx[15],@twx[0],@twx[1]); + &mov_reg_to_vec(@twx[2],@twx[3],@vtmpx[1]); + &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); + &mov_reg_to_vec(@twx[4],@twx[5],@vtmpx[2]); + &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); + &mov_reg_to_vec(@twx[6],@twx[7],@vtmpx[3]); + &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); + &mov_reg_to_vec(@twx[8],@twx[9],@tweak[0]); + &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); + &mov_reg_to_vec(@twx[10],@twx[11],@tweak[1]); + &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); + &mov_reg_to_vec(@twx[12],@twx[13],@tweak[2]); + &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); + &mov_reg_to_vec(@twx[14],@twx[15],@tweak[3]); + &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @vtmpx[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @vtmpx[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @vtmpx[2].16b + eor @vtmp[3].16b, @vtmp[3].16b, @vtmpx[3].16b + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b + eor @data[3].16b, @data[3].16b, @tweak[3].16b + + // save the last tweak + st1 {@tweak[3].4s},[$ivp] + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + st1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#8 + b.gt .Lxts_8_blocks_process${std} + b 100f +.Lxts_4_blocks_process${std}: +___ + &mov_reg_to_vec(@twx[0],@twx[1],@tweak[0]); + &mov_reg_to_vec(@twx[2],@twx[3],@tweak[1]); + &mov_reg_to_vec(@twx[4],@twx[5],@tweak[2]); + &mov_reg_to_vec(@twx[6],@twx[7],@tweak[3]); +$code.=<<___; + cmp $blocks,#4 + b.lt 1f + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); + &rbit(@tweak[2],@tweak[2],$std); + &rbit(@tweak[3],@tweak[3],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b + eor @data[3].16b, @data[3].16b, @tweak[3].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b + eor @vtmp[3].16b, @vtmp[3].16b, @tweak[3].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + sub $blocks,$blocks,#4 +___ + &mov_reg_to_vec(@twx[8],@twx[9],@tweak[0]); + &mov_reg_to_vec(@twx[10],@twx[11],@tweak[1]); + &mov_reg_to_vec(@twx[12],@twx[13],@tweak[2]); +$code.=<<___; + // save the last tweak + st1 {@tweak[3].4s},[$ivp] +1: + // process last block + cmp $blocks,#1 + b.lt 100f + b.gt 1f + ld1 {@data[0].4s},[$inp],#16 +___ + &rbit(@tweak[0],@tweak[0],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + st1 {@data[0].4s},[$outp],#16 + // save the last tweak + st1 {@tweak[0].4s},[$ivp] + b 100f +1: // process last 2 blocks + cmp $blocks,#2 + b.gt 1f + ld1 {@data[0].4s,@data[1].4s},[$inp],#32 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + st1 {@vtmp[0].4s,@vtmp[1].4s},[$outp],#32 + // save the last tweak + st1 {@tweak[1].4s},[$ivp] + b 100f +1: // process last 3 blocks + ld1 {@data[0].4s,@data[1].4s,@data[2].4s},[$inp],#48 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); + &rbit(@tweak[2],@tweak[2],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s},[$outp],#48 + // save the last tweak + st1 {@tweak[2].4s},[$ivp] +100: + cmp $remain,0 + b.eq .return${std} + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak${std}: + ld1 {@tweak[0].4s},[$ivp] +___ + &rev32_armeb(@tweak[0],@tweak[0]); + &compute_tweak_vec(@tweak[0],@tweak[1],$std); + &compute_tweak_vec(@tweak[1],@tweak[2],$std); +$code.=<<___; + b .check_dec${std} + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak${std}: + mov @tweak[1].16b,@tweak[0].16b +___ + &rev32_armeb(@tweak[1],@tweak[1]); + &compute_tweak_vec(@tweak[1],@tweak[2]); +$code.=<<___; + b .check_dec${std} + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec${std}: + // encryption:1 decryption:0 + cmp $enc,1 + b.eq .prcess_last_2blks${std} + mov @vtmp[0].16B,@tweak[1].16b + mov @tweak[1].16B,@tweak[2].16b + mov @tweak[2].16B,@vtmp[0].16b + +.prcess_last_2blks${std}: +___ + &rev32_armeb(@tweak[1],@tweak[1]); + &rev32_armeb(@tweak[2],@tweak[2]); +$code.=<<___; + ld1 {@data[0].4s},[$inp],#16 + eor @data[0].16b, @data[0].16b, @tweak[1].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[1].16b + st1 {@data[0].4s},[$outp],#16 + + sub $lastBlk,$outp,16 + .loop${std}: + subs $remain,$remain,1 + ldrb $wtmp0,[$lastBlk,$remain] + ldrb $wtmp1,[$inp,$remain] + strb $wtmp1,[$lastBlk,$remain] + strb $wtmp0,[$outp,$remain] + b.gt .loop${std} + ld1 {@data[0].4s}, [$lastBlk] + eor @data[0].16b, @data[0].16b, @tweak[2].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[2].16b + st1 {@data[0].4s}, [$lastBlk] +.return${std}: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_xts_encrypt${std},.-${prefix}_xts_encrypt${std} +___ +} # end of gen_xts_cipher +&gen_xts_cipher("_gb"); +&gen_xts_cipher(""); +}}} ######################################## open SELF,$0; while() { diff --git a/crypto/sm4/asm/vpsm4_ex-armv8.S b/crypto/sm4/asm/vpsm4_ex-armv8.S new file mode 100644 index 0000000000..af499a364c --- /dev/null +++ b/crypto/sm4/asm/vpsm4_ex-armv8.S @@ -0,0 +1,4504 @@ +// Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License 2.0 (the "License"). You may not use +// this file except in compliance with the License. You can obtain a copy +// in the file LICENSE in the source distribution or at +// https://www.openssl.org/source/license.html + +// +// This module implements SM4 with ASIMD and AESE on AARCH64 +// +// Dec 2022 +// + +// $output is the last argument if it looks like a file (it has an extension) +// $flavour is the first argument if it doesn't look like a file +#include "arm_arch.h" +.arch armv8-a+crypto +.text + +.type _vpsm4_ex_consts,%object +.align 7 +_vpsm4_ex_consts: +.Lck: +.long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 +.long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 +.long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 +.long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 +.long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 +.long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 +.long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 +.long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 +.Lfk: +.quad 0x56aa3350a3b1bac6,0xb27022dc677d9197 +.Lshuffles: +.quad 0x0B0A090807060504,0x030201000F0E0D0C +.Lxts_magic: +.quad 0x0101010101010187,0x0101010101010101 +.Lsbox_magic: +.quad 0x0b0e0104070a0d00,0x0306090c0f020508 +.quad 0x62185a2042387a00,0x22581a6002783a40 +.quad 0x15df62a89e54e923,0xc10bb67c4a803df7 +.quad 0xb9aa6b78c1d21300,0x1407c6d56c7fbead +.quad 0x6404462679195b3b,0xe383c1a1fe9edcbc +.quad 0x0f0f0f0f0f0f0f0f,0x0f0f0f0f0f0f0f0f + +.size _vpsm4_ex_consts,.-_vpsm4_ex_consts +.type _vpsm4_ex_set_key,%function +.align 4 +_vpsm4_ex_set_key: + AARCH64_VALID_CALL_TARGET + ld1 {v5.4s},[x0] + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + adr x5,.Lshuffles + ld1 {v7.2d},[x5] + adr x5,.Lfk + ld1 {v6.2d},[x5] + eor v5.16b,v5.16b,v6.16b + mov x6,#32 + adr x5,.Lck + movi v0.16b,#64 + cbnz w2,1f + add x1,x1,124 +1: + mov w7,v5.s[1] + ldr w8,[x5],#4 + eor w8,w8,w7 + mov w7,v5.s[2] + eor w8,w8,w7 + mov w7,v5.s[3] + eor w8,w8,w7 + // optimize sbox using AESE instruction + mov v4.s[0],w8 + tbl v0.16b, {v4.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + mov w7,v0.s[0] + eor w8,w7,w7,ror #19 + eor w8,w8,w7,ror #9 + mov w7,v5.s[0] + eor w8,w8,w7 + mov v5.s[0],w8 + cbz w2,2f + str w8,[x1],#4 + b 3f +2: + str w8,[x1],#-4 +3: + tbl v5.16b,{v5.16b},v7.16b + subs x6,x6,#1 + b.ne 1b + ret +.size _vpsm4_ex_set_key,.-_vpsm4_ex_set_key +.type _vpsm4_ex_enc_4blks,%function +.align 4 +_vpsm4_ex_enc_4blks: + AARCH64_VALID_CALL_TARGET + mov x10,x3 + mov w11,#8 +10: + ldp w7,w8,[x10],8 + dup v12.4s,w7 + dup v13.4s,w8 + + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor v14.16b,v6.16b,v7.16b + eor v12.16b,v5.16b,v12.16b + eor v12.16b,v14.16b,v12.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + mov v12.16b,v0.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + eor v4.16b,v4.16b,v12.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor v14.16b,v14.16b,v4.16b + eor v13.16b,v14.16b,v13.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + mov v13.16b,v0.16b + + // linear transformation + ushr v0.4s,v13.4s,32-2 + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v0.4s,v13.4s,2 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v0.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + ldp w7,w8,[x10],8 + eor v5.16b,v5.16b,v13.16b + + dup v12.4s,w7 + dup v13.4s,w8 + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor v14.16b,v4.16b,v5.16b + eor v12.16b,v7.16b,v12.16b + eor v12.16b,v14.16b,v12.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + mov v12.16b,v0.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + eor v6.16b,v6.16b,v12.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor v14.16b,v14.16b,v6.16b + eor v13.16b,v14.16b,v13.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + mov v13.16b,v0.16b + + // linear transformation + ushr v0.4s,v13.4s,32-2 + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v0.4s,v13.4s,2 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v0.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + eor v7.16b,v7.16b,v13.16b + subs w11,w11,#1 + b.ne 10b +#ifndef __AARCH64EB__ + rev32 v3.16b,v4.16b +#else + mov v3.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v2.16b,v5.16b +#else + mov v2.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v1.16b,v6.16b +#else + mov v1.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v0.16b,v7.16b +#else + mov v0.16b,v7.16b +#endif + ret +.size _vpsm4_ex_enc_4blks,.-_vpsm4_ex_enc_4blks +.type _vpsm4_ex_enc_8blks,%function +.align 4 +_vpsm4_ex_enc_8blks: + AARCH64_VALID_CALL_TARGET + mov x10,x3 + mov w11,#8 +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + dup v12.4s,w7 + eor v14.16b,v6.16b,v7.16b + eor v15.16b,v10.16b,v11.16b + eor v0.16b,v5.16b,v12.16b + eor v1.16b,v9.16b,v12.16b + eor v12.16b,v14.16b,v0.16b + eor v13.16b,v15.16b,v1.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + tbl v1.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v28.16b}, v1.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + eor v25.16b, v25.16b, v25.16b + aese v0.16b,v25.16b + aese v1.16b,v25.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v30.16b}, v1.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + mov v12.16b,v0.16b + mov v13.16b,v1.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v25.4s,v13.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v25.4s,v13.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v25.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + eor v4.16b,v4.16b,v12.16b + eor v8.16b,v8.16b,v13.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + dup v13.4s,w8 + eor v14.16b,v14.16b,v4.16b + eor v15.16b,v15.16b,v8.16b + eor v12.16b,v14.16b,v13.16b + eor v13.16b,v15.16b,v13.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + tbl v1.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v28.16b}, v1.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + eor v25.16b, v25.16b, v25.16b + aese v0.16b,v25.16b + aese v1.16b,v25.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v30.16b}, v1.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + mov v12.16b,v0.16b + mov v13.16b,v1.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v25.4s,v13.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v25.4s,v13.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v25.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + ldp w7,w8,[x10],8 + eor v5.16b,v5.16b,v12.16b + eor v9.16b,v9.16b,v13.16b + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + dup v12.4s,w7 + eor v14.16b,v4.16b,v5.16b + eor v15.16b,v8.16b,v9.16b + eor v0.16b,v7.16b,v12.16b + eor v1.16b,v11.16b,v12.16b + eor v12.16b,v14.16b,v0.16b + eor v13.16b,v15.16b,v1.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + tbl v1.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v28.16b}, v1.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + eor v25.16b, v25.16b, v25.16b + aese v0.16b,v25.16b + aese v1.16b,v25.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v30.16b}, v1.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + mov v12.16b,v0.16b + mov v13.16b,v1.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v25.4s,v13.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v25.4s,v13.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v25.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + eor v6.16b,v6.16b,v12.16b + eor v10.16b,v10.16b,v13.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + dup v13.4s,w8 + eor v14.16b,v14.16b,v6.16b + eor v15.16b,v15.16b,v10.16b + eor v12.16b,v14.16b,v13.16b + eor v13.16b,v15.16b,v13.16b + // optimize sbox using AESE instruction + tbl v0.16b, {v12.16b}, v26.16b + tbl v1.16b, {v13.16b}, v26.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v28.16b}, v1.16b + tbl v24.16b, {v27.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + eor v25.16b, v25.16b, v25.16b + aese v0.16b,v25.16b + aese v1.16b,v25.16b + ushr v24.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v0.16b, v0.16b, v24.16b + ushr v24.16b, v1.16b, 4 + and v1.16b, v1.16b, v31.16b + tbl v1.16b, {v30.16b}, v1.16b + tbl v24.16b, {v29.16b}, v24.16b + eor v1.16b, v1.16b, v24.16b + mov v12.16b,v0.16b + mov v13.16b,v1.16b + + // linear transformation + ushr v0.4s,v12.4s,32-2 + ushr v25.4s,v13.4s,32-2 + ushr v1.4s,v12.4s,32-10 + ushr v2.4s,v12.4s,32-18 + ushr v3.4s,v12.4s,32-24 + sli v0.4s,v12.4s,2 + sli v25.4s,v13.4s,2 + sli v1.4s,v12.4s,10 + sli v2.4s,v12.4s,18 + sli v3.4s,v12.4s,24 + eor v24.16b,v0.16b,v12.16b + eor v24.16b,v24.16b,v1.16b + eor v12.16b,v2.16b,v3.16b + eor v12.16b,v12.16b,v24.16b + ushr v1.4s,v13.4s,32-10 + ushr v2.4s,v13.4s,32-18 + ushr v3.4s,v13.4s,32-24 + sli v1.4s,v13.4s,10 + sli v2.4s,v13.4s,18 + sli v3.4s,v13.4s,24 + eor v24.16b,v25.16b,v13.16b + eor v24.16b,v24.16b,v1.16b + eor v13.16b,v2.16b,v3.16b + eor v13.16b,v13.16b,v24.16b + eor v7.16b,v7.16b,v12.16b + eor v11.16b,v11.16b,v13.16b + subs w11,w11,#1 + b.ne 10b +#ifndef __AARCH64EB__ + rev32 v3.16b,v4.16b +#else + mov v3.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v2.16b,v5.16b +#else + mov v2.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v1.16b,v6.16b +#else + mov v1.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v0.16b,v7.16b +#else + mov v0.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v8.16b +#else + mov v7.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v9.16b +#else + mov v6.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v10.16b +#else + mov v5.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v4.16b,v11.16b +#else + mov v4.16b,v11.16b +#endif + ret +.size _vpsm4_ex_enc_8blks,.-_vpsm4_ex_enc_8blks +.globl vpsm4_ex_set_encrypt_key +.type vpsm4_ex_set_encrypt_key,%function +.align 5 +vpsm4_ex_set_encrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + mov w2,1 + bl _vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_set_encrypt_key,.-vpsm4_ex_set_encrypt_key +.globl vpsm4_ex_set_decrypt_key +.type vpsm4_ex_set_decrypt_key,%function +.align 5 +vpsm4_ex_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + mov w2,0 + bl _vpsm4_ex_set_key + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_set_decrypt_key,.-vpsm4_ex_set_decrypt_key +.globl vpsm4_ex_encrypt +.type vpsm4_ex_encrypt,%function +.align 5 +vpsm4_ex_encrypt: + AARCH64_VALID_CALL_TARGET + ld1 {v4.4s},[x0] + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x3,x2 + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + st1 {v4.4s},[x1] + ret +.size vpsm4_ex_encrypt,.-vpsm4_ex_encrypt +.globl vpsm4_ex_decrypt +.type vpsm4_ex_decrypt,%function +.align 5 +vpsm4_ex_decrypt: + AARCH64_VALID_CALL_TARGET + ld1 {v4.4s},[x0] + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x3,x2 + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + st1 {v4.4s},[x1] + ret +.size vpsm4_ex_decrypt,.-vpsm4_ex_decrypt +.globl vpsm4_ex_ecb_encrypt +.type vpsm4_ex_ecb_encrypt,%function +.align 5 +vpsm4_ex_ecb_encrypt: + AARCH64_SIGN_LINK_REGISTER + // convert length into blocks + lsr x2,x2,4 + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +.Lecb_8_blocks_process: + cmp w2,#8 + b.lt .Lecb_4_blocks_process + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + bl _vpsm4_ex_enc_8blks + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs w2,w2,#8 + b.gt .Lecb_8_blocks_process + b 100f +.Lecb_4_blocks_process: + cmp w2,#4 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub w2,w2,#4 +1: + // process last block + cmp w2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0] +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + st1 {v4.4s},[x1] + b 100f +1: // process last 2 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[0],[x0],#16 + ld4 {v4.s,v5.s,v6.s,v7.s}[1],[x0],#16 + cmp w2,#2 + b.gt 1f +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + st4 {v0.s,v1.s,v2.s,v3.s}[0],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[x1] + b 100f +1: // process last 3 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[2],[x0],#16 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + st4 {v0.s,v1.s,v2.s,v3.s}[0],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[2],[x1] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_ecb_encrypt,.-vpsm4_ex_ecb_encrypt +.globl vpsm4_ex_cbc_encrypt +.type vpsm4_ex_cbc_encrypt,%function +.align 5 +vpsm4_ex_cbc_encrypt: + AARCH64_VALID_CALL_TARGET + lsr x2,x2,4 + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 + cbz w5,.Ldec + ld1 {v3.4s},[x4] +.Lcbc_4_blocks_enc: + cmp w2,#4 + b.lt 1f + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + eor v4.16b,v4.16b,v3.16b +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 + eor v5.16b,v5.16b,v4.16b + mov x10,x3 + mov w11,#8 + mov w12,v5.s[0] + mov w13,v5.s[1] + mov w14,v5.s[2] + mov w15,v5.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v5.s[0],w15 + mov v5.s[1],w14 + mov v5.s[2],w13 + mov v5.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v6.16b,v6.16b,v5.16b + mov x10,x3 + mov w11,#8 + mov w12,v6.s[0] + mov w13,v6.s[1] + mov w14,v6.s[2] + mov w15,v6.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v6.s[0],w15 + mov v6.s[1],w14 + mov v6.s[2],w13 + mov v6.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + eor v7.16b,v7.16b,v6.16b + mov x10,x3 + mov w11,#8 + mov w12,v7.s[0] + mov w13,v7.s[1] + mov w14,v7.s[2] + mov w15,v7.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v7.s[0],w15 + mov v7.s[1],w14 + mov v7.s[2],w13 + mov v7.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + orr v3.16b,v7.16b,v7.16b + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs w2,w2,#4 + b.ne .Lcbc_4_blocks_enc + b 2f +1: + subs w2,w2,#1 + b.lt 2f + ld1 {v4.4s},[x0],#16 + eor v3.16b,v3.16b,v4.16b +#ifndef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v3.s[0] + mov w13,v3.s[1] + mov w14,v3.s[2] + mov w15,v3.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v3.s[0],w15 + mov v3.s[1],w14 + mov v3.s[2],w13 + mov v3.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + st1 {v3.4s},[x1],#16 + b 1b +2: + // save back IV + st1 {v3.4s},[x4] + ret + +.Ldec: + // decryption mode starts + AARCH64_SIGN_LINK_REGISTER + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] +.Lcbc_8_blocks_dec: + cmp w2,#8 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0] + add x10,x0,#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[x10] +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + bl _vpsm4_ex_enc_8blks + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + zip1 v8.4s,v4.4s,v5.4s + zip2 v9.4s,v4.4s,v5.4s + zip1 v10.4s,v6.4s,v7.4s + zip2 v11.4s,v6.4s,v7.4s + zip1 v4.2d,v8.2d,v10.2d + zip2 v5.2d,v8.2d,v10.2d + zip1 v6.2d,v9.2d,v11.2d + zip2 v7.2d,v9.2d,v11.2d + ld1 {v15.4s},[x4] + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + // note ivec1 and vtmpx[3] are resuing the same register + // care needs to be taken to avoid conflict + eor v0.16b,v0.16b,v15.16b + ld1 {v12.4s,v13.4s,v14.4s,v15.4s},[x0],#64 + eor v1.16b,v1.16b,v8.16b + eor v2.16b,v2.16b,v9.16b + eor v3.16b,v3.16b,v10.16b + // save back IV + st1 {v15.4s}, [x4] + eor v4.16b,v4.16b,v11.16b + eor v5.16b,v5.16b,v12.16b + eor v6.16b,v6.16b,v13.16b + eor v7.16b,v7.16b,v14.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs w2,w2,#8 + b.gt .Lcbc_8_blocks_dec + b.eq 100f +1: + ld1 {v15.4s},[x4] +.Lcbc_4_blocks_dec: + cmp w2,#4 + b.lt 1f + ld4 {v4.4s,v5.4s,v6.4s,v7.4s},[x0] +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + eor v0.16b,v0.16b,v15.16b + eor v1.16b,v1.16b,v4.16b + orr v15.16b,v7.16b,v7.16b + eor v2.16b,v2.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + subs w2,w2,#4 + b.gt .Lcbc_4_blocks_dec + // save back IV + st1 {v7.4s}, [x4] + b 100f +1: // last block + subs w2,w2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0],#16 + // save back IV + st1 {v4.4s}, [x4] +#ifndef __AARCH64EB__ + rev32 v8.16b,v4.16b +#else + mov v8.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v8.s[0] + mov w13,v8.s[1] + mov w14,v8.s[2] + mov w15,v8.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v8.s[0],w15 + mov v8.s[1],w14 + mov v8.s[2],w13 + mov v8.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif + eor v8.16b,v8.16b,v15.16b + st1 {v8.4s},[x1],#16 + b 100f +1: // last two blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[0],[x0] + add x10,x0,#16 + ld4 {v4.s,v5.s,v6.s,v7.s}[1],[x10],#16 + subs w2,w2,1 + b.gt 1f +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + ld1 {v4.4s,v5.4s},[x0],#32 + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + eor v0.16b,v0.16b,v15.16b + eor v1.16b,v1.16b,v4.16b + st1 {v0.4s,v1.4s},[x1],#32 + // save back IV + st1 {v5.4s}, [x4] + b 100f +1: // last 3 blocks + ld4 {v4.s,v5.s,v6.s,v7.s}[2],[x10] +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + bl _vpsm4_ex_enc_4blks + ld1 {v4.4s,v5.4s,v6.4s},[x0],#48 + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + eor v0.16b,v0.16b,v15.16b + eor v1.16b,v1.16b,v4.16b + eor v2.16b,v2.16b,v5.16b + st1 {v0.4s,v1.4s,v2.4s},[x1],#48 + // save back IV + st1 {v6.4s}, [x4] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_cbc_encrypt,.-vpsm4_ex_cbc_encrypt +.globl vpsm4_ex_ctr32_encrypt_blocks +.type vpsm4_ex_ctr32_encrypt_blocks,%function +.align 5 +vpsm4_ex_ctr32_encrypt_blocks: + AARCH64_VALID_CALL_TARGET + ld1 {v3.4s},[x4] +#ifndef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 + cmp w2,#1 + b.ne 1f + // fast processing for one single block without + // context saving overhead + mov x10,x3 + mov w11,#8 + mov w12,v3.s[0] + mov w13,v3.s[1] + mov w14,v3.s[2] + mov w15,v3.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v3.s[0],w15 + mov v3.s[1],w14 + mov v3.s[2],w13 + mov v3.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + ld1 {v4.4s},[x0] + eor v4.16b,v4.16b,v3.16b + st1 {v4.4s},[x1] + ret +1: + AARCH64_SIGN_LINK_REGISTER + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] + mov w12,v3.s[0] + mov w13,v3.s[1] + mov w14,v3.s[2] + mov w5,v3.s[3] +.Lctr32_4_blocks_process: + cmp w2,#4 + b.lt 1f + dup v4.4s,w12 + dup v5.4s,w13 + dup v6.4s,w14 + mov v7.s[0],w5 + add w5,w5,#1 + mov v7.s[1],w5 + add w5,w5,#1 + mov v7.s[2],w5 + add w5,w5,#1 + mov v7.s[3],w5 + add w5,w5,#1 + cmp w2,#8 + b.ge .Lctr32_8_blocks_process + bl _vpsm4_ex_enc_4blks + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[x0],#64 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + subs w2,w2,#4 + b.ne .Lctr32_4_blocks_process + b 100f +.Lctr32_8_blocks_process: + dup v8.4s,w12 + dup v9.4s,w13 + dup v10.4s,w14 + mov v11.s[0],w5 + add w5,w5,#1 + mov v11.s[1],w5 + add w5,w5,#1 + mov v11.s[2],w5 + add w5,w5,#1 + mov v11.s[3],w5 + add w5,w5,#1 + bl _vpsm4_ex_enc_8blks + ld4 {v12.4s,v13.4s,v14.4s,v15.4s},[x0],#64 + ld4 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + eor v4.16b,v4.16b,v8.16b + eor v5.16b,v5.16b,v9.16b + eor v6.16b,v6.16b,v10.16b + eor v7.16b,v7.16b,v11.16b + st4 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st4 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs w2,w2,#8 + b.ne .Lctr32_4_blocks_process + b 100f +1: // last block processing + subs w2,w2,#1 + b.lt 100f + b.gt 1f + mov v3.s[0],w12 + mov v3.s[1],w13 + mov v3.s[2],w14 + mov v3.s[3],w5 + mov x10,x3 + mov w11,#8 + mov w12,v3.s[0] + mov w13,v3.s[1] + mov w14,v3.s[2] + mov w15,v3.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v3.s[0],w15 + mov v3.s[1],w14 + mov v3.s[2],w13 + mov v3.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v3.16b,v3.16b +#endif + ld1 {v4.4s},[x0] + eor v4.16b,v4.16b,v3.16b + st1 {v4.4s},[x1] + b 100f +1: // last 2 blocks processing + dup v4.4s,w12 + dup v5.4s,w13 + dup v6.4s,w14 + mov v7.s[0],w5 + add w5,w5,#1 + mov v7.s[1],w5 + subs w2,w2,#1 + b.ne 1f + bl _vpsm4_ex_enc_4blks + ld4 {v12.s,v13.s,v14.s,v15.s}[0],[x0],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[1],[x0],#16 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.s,v1.s,v2.s,v3.s}[0],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[x1],#16 + b 100f +1: // last 3 blocks processing + add w5,w5,#1 + mov v7.s[2],w5 + bl _vpsm4_ex_enc_4blks + ld4 {v12.s,v13.s,v14.s,v15.s}[0],[x0],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[1],[x0],#16 + ld4 {v12.s,v13.s,v14.s,v15.s}[2],[x0],#16 + eor v0.16b,v0.16b,v12.16b + eor v1.16b,v1.16b,v13.16b + eor v2.16b,v2.16b,v14.16b + eor v3.16b,v3.16b,v15.16b + st4 {v0.s,v1.s,v2.s,v3.s}[0],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[1],[x1],#16 + st4 {v0.s,v1.s,v2.s,v3.s}[2],[x1],#16 +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_ctr32_encrypt_blocks,.-vpsm4_ex_ctr32_encrypt_blocks +.globl vpsm4_ex_xts_encrypt_gb +.type vpsm4_ex_xts_encrypt_gb,%function +.align 5 +vpsm4_ex_xts_encrypt_gb: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov x26,x3 + mov x27,x4 + mov w28,w6 + ld1 {v16.4s}, [x5] + mov x3,x27 + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +#ifndef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v16.s[0] + mov w13,v16.s[1] + mov w14,v16.s[2] + mov w15,v16.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v16.s[0],w15 + mov v16.s[1],w14 + mov v16.s[2],w13 + mov v16.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x3,x26 + and x29,x2,#0x0F + // convert length into blocks + lsr x2,x2,4 + cmp x2,#1 + b.lt .return_gb + + cmp x29,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks_gb + b.eq .xts_encrypt_blocks_gb + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak_gb or .only_2blks_tweak_gb + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks_gb + subs x2,x2,#1 + b.eq .only_2blks_tweak_gb +.xts_encrypt_blocks_gb: + rbit v16.16b,v16.16b +#ifdef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x12,v16.d[0] + mov x13,v16.d[1] + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 +.Lxts_8_blocks_process_gb: + cmp x2,#8 + mov v16.d[0],x12 + mov v16.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov w7,0x87 + extr x9,x27,x27,#32 + extr x13,x27,x26,#63 + and w8,w7,w9,asr#31 + eor x12,x8,x26,lsl#1 + mov v17.d[0],x14 + mov v17.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov v18.d[0],x16 + mov v18.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v18.16b,v18.16b +#endif + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov v19.d[0],x18 + mov v19.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v19.16b,v19.16b +#endif + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov v20.d[0],x20 + mov v20.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v20.16b,v20.16b +#endif + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov v21.d[0],x22 + mov v21.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v21.16b,v21.16b +#endif + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov v22.d[0],x24 + mov v22.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v22.16b,v22.16b +#endif + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov v23.d[0],x26 + mov v23.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v23.16b,v23.16b +#endif + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 + b.lt .Lxts_4_blocks_process_gb + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + rbit v16.16b,v16.16b + rbit v17.16b,v17.16b + rbit v18.16b,v18.16b + rbit v19.16b,v19.16b + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b + eor v7.16b, v7.16b, v19.16b + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + rbit v20.16b,v20.16b + rbit v21.16b,v21.16b + rbit v22.16b,v22.16b + rbit v23.16b,v23.16b + eor v8.16b, v8.16b, v20.16b + eor v9.16b, v9.16b, v21.16b + eor v10.16b, v10.16b, v22.16b + eor v11.16b, v11.16b, v23.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + zip1 v0.4s,v8.4s,v9.4s + zip2 v1.4s,v8.4s,v9.4s + zip1 v2.4s,v10.4s,v11.4s + zip2 v3.4s,v10.4s,v11.4s + zip1 v8.2d,v0.2d,v2.2d + zip2 v9.2d,v0.2d,v2.2d + zip1 v10.2d,v1.2d,v3.2d + zip2 v11.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_8blks + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + zip1 v8.4s,v4.4s,v5.4s + zip2 v9.4s,v4.4s,v5.4s + zip1 v10.4s,v6.4s,v7.4s + zip2 v11.4s,v6.4s,v7.4s + zip1 v4.2d,v8.2d,v10.2d + zip2 v5.2d,v8.2d,v10.2d + zip1 v6.2d,v9.2d,v11.2d + zip2 v7.2d,v9.2d,v11.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + eor v3.16b, v3.16b, v19.16b + eor v4.16b, v4.16b, v20.16b + eor v5.16b, v5.16b, v21.16b + eor v6.16b, v6.16b, v22.16b + eor v7.16b, v7.16b, v23.16b + + // save the last tweak + mov v25.16b,v23.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs x2,x2,#8 + b.gt .Lxts_8_blocks_process_gb + b 100f +.Lxts_4_blocks_process_gb: + cmp x2,#4 + b.lt 1f + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + rbit v16.16b,v16.16b + rbit v17.16b,v17.16b + rbit v18.16b,v18.16b + rbit v19.16b,v19.16b + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b + eor v7.16b, v7.16b, v19.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + eor v3.16b, v3.16b, v19.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub x2,x2,#4 + mov v16.16b,v20.16b + mov v17.16b,v21.16b + mov v18.16b,v22.16b + // save the last tweak + mov v25.16b,v19.16b +1: + // process last block + cmp x2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0],#16 + rbit v16.16b,v16.16b + eor v4.16b, v4.16b, v16.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v16.16b + st1 {v4.4s},[x1],#16 + // save the last tweak + mov v25.16b,v16.16b + b 100f +1: // process last 2 blocks + cmp x2,#2 + b.gt 1f + ld1 {v4.4s,v5.4s},[x0],#32 + rbit v16.16b,v16.16b + rbit v17.16b,v17.16b + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + st1 {v0.4s,v1.4s},[x1],#32 + // save the last tweak + mov v25.16b,v17.16b + b 100f +1: // process last 3 blocks + ld1 {v4.4s,v5.4s,v6.4s},[x0],#48 + rbit v16.16b,v16.16b + rbit v17.16b,v17.16b + rbit v18.16b,v18.16b + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + st1 {v0.4s,v1.4s,v2.4s},[x1],#48 + // save the last tweak + mov v25.16b,v18.16b +100: + cmp x29,0 + b.eq .return_gb + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak_gb: +#ifdef __AARCH64EB__ + rev32 v25.16b,v25.16b +#endif + rbit v2.16b,v25.16b + ldr q0, .Lxts_magic + shl v17.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v17.16b, v17.16b, v1.16b + rbit v17.16b,v17.16b + rbit v2.16b,v17.16b + ldr q0, .Lxts_magic + shl v18.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v18.16b, v18.16b, v1.16b + rbit v18.16b,v18.16b + b .check_dec_gb + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak_gb: + mov v17.16b,v16.16b +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif + mov v2.16b,v17.16b + ldr q0, .Lxts_magic + shl v18.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v18.16b, v18.16b, v1.16b + b .check_dec_gb + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec_gb: + // encryption:1 decryption:0 + cmp w28,1 + b.eq .prcess_last_2blks_gb + mov v0.16B,v17.16b + mov v17.16B,v18.16b + mov v18.16B,v0.16b + +.prcess_last_2blks_gb: +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif +#ifdef __AARCH64EB__ + rev32 v18.16b,v18.16b +#endif + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v17.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v17.16b + st1 {v4.4s},[x1],#16 + + sub x26,x1,16 +.loop_gb: + subs x29,x29,1 + ldrb w7,[x26,x29] + ldrb w8,[x0,x29] + strb w8,[x26,x29] + strb w7,[x1,x29] + b.gt .loop_gb + ld1 {v4.4s}, [x26] + eor v4.16b, v4.16b, v18.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v18.16b + st1 {v4.4s}, [x26] +.return_gb: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_xts_encrypt_gb,.-vpsm4_ex_xts_encrypt_gb +.globl vpsm4_ex_xts_encrypt +.type vpsm4_ex_xts_encrypt,%function +.align 5 +vpsm4_ex_xts_encrypt: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov x26,x3 + mov x27,x4 + mov w28,w6 + ld1 {v16.4s}, [x5] + mov x3,x27 + ldr q26, .Lsbox_magic + ldr q27, .Lsbox_magic+16 + ldr q28, .Lsbox_magic+32 + ldr q29, .Lsbox_magic+48 + ldr q30, .Lsbox_magic+64 + ldr q31, .Lsbox_magic+80 +#ifndef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v16.s[0] + mov w13,v16.s[1] + mov w14,v16.s[2] + mov w15,v16.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v16.s[0],w15 + mov v16.s[1],w14 + mov v16.s[2],w13 + mov v16.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x3,x26 + and x29,x2,#0x0F + // convert length into blocks + lsr x2,x2,4 + cmp x2,#1 + b.lt .return + + cmp x29,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks + b.eq .xts_encrypt_blocks + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak or .only_2blks_tweak + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks + subs x2,x2,#1 + b.eq .only_2blks_tweak +.xts_encrypt_blocks: +#ifdef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov x12,v16.d[0] + mov x13,v16.d[1] + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 +.Lxts_8_blocks_process: + cmp x2,#8 + mov v16.d[0],x12 + mov v16.d[1],x13 +#ifdef __AARCH64EB__ + rev32 v16.16b,v16.16b +#endif + mov w7,0x87 + extr x9,x27,x27,#32 + extr x13,x27,x26,#63 + and w8,w7,w9,asr#31 + eor x12,x8,x26,lsl#1 + mov v17.d[0],x14 + mov v17.d[1],x15 +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif + mov w7,0x87 + extr x9,x13,x13,#32 + extr x15,x13,x12,#63 + and w8,w7,w9,asr#31 + eor x14,x8,x12,lsl#1 + mov v18.d[0],x16 + mov v18.d[1],x17 +#ifdef __AARCH64EB__ + rev32 v18.16b,v18.16b +#endif + mov w7,0x87 + extr x9,x15,x15,#32 + extr x17,x15,x14,#63 + and w8,w7,w9,asr#31 + eor x16,x8,x14,lsl#1 + mov v19.d[0],x18 + mov v19.d[1],x19 +#ifdef __AARCH64EB__ + rev32 v19.16b,v19.16b +#endif + mov w7,0x87 + extr x9,x17,x17,#32 + extr x19,x17,x16,#63 + and w8,w7,w9,asr#31 + eor x18,x8,x16,lsl#1 + mov v20.d[0],x20 + mov v20.d[1],x21 +#ifdef __AARCH64EB__ + rev32 v20.16b,v20.16b +#endif + mov w7,0x87 + extr x9,x19,x19,#32 + extr x21,x19,x18,#63 + and w8,w7,w9,asr#31 + eor x20,x8,x18,lsl#1 + mov v21.d[0],x22 + mov v21.d[1],x23 +#ifdef __AARCH64EB__ + rev32 v21.16b,v21.16b +#endif + mov w7,0x87 + extr x9,x21,x21,#32 + extr x23,x21,x20,#63 + and w8,w7,w9,asr#31 + eor x22,x8,x20,lsl#1 + mov v22.d[0],x24 + mov v22.d[1],x25 +#ifdef __AARCH64EB__ + rev32 v22.16b,v22.16b +#endif + mov w7,0x87 + extr x9,x23,x23,#32 + extr x25,x23,x22,#63 + and w8,w7,w9,asr#31 + eor x24,x8,x22,lsl#1 + mov v23.d[0],x26 + mov v23.d[1],x27 +#ifdef __AARCH64EB__ + rev32 v23.16b,v23.16b +#endif + mov w7,0x87 + extr x9,x25,x25,#32 + extr x27,x25,x24,#63 + and w8,w7,w9,asr#31 + eor x26,x8,x24,lsl#1 + b.lt .Lxts_4_blocks_process + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b + eor v7.16b, v7.16b, v19.16b + ld1 {v8.4s,v9.4s,v10.4s,v11.4s},[x0],#64 + eor v8.16b, v8.16b, v20.16b + eor v9.16b, v9.16b, v21.16b + eor v10.16b, v10.16b, v22.16b + eor v11.16b, v11.16b, v23.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif +#ifndef __AARCH64EB__ + rev32 v8.16b,v8.16b +#endif +#ifndef __AARCH64EB__ + rev32 v9.16b,v9.16b +#endif +#ifndef __AARCH64EB__ + rev32 v10.16b,v10.16b +#endif +#ifndef __AARCH64EB__ + rev32 v11.16b,v11.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + zip1 v0.4s,v8.4s,v9.4s + zip2 v1.4s,v8.4s,v9.4s + zip1 v2.4s,v10.4s,v11.4s + zip2 v3.4s,v10.4s,v11.4s + zip1 v8.2d,v0.2d,v2.2d + zip2 v9.2d,v0.2d,v2.2d + zip1 v10.2d,v1.2d,v3.2d + zip2 v11.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_8blks + zip1 v8.4s,v0.4s,v1.4s + zip2 v9.4s,v0.4s,v1.4s + zip1 v10.4s,v2.4s,v3.4s + zip2 v11.4s,v2.4s,v3.4s + zip1 v0.2d,v8.2d,v10.2d + zip2 v1.2d,v8.2d,v10.2d + zip1 v2.2d,v9.2d,v11.2d + zip2 v3.2d,v9.2d,v11.2d + zip1 v8.4s,v4.4s,v5.4s + zip2 v9.4s,v4.4s,v5.4s + zip1 v10.4s,v6.4s,v7.4s + zip2 v11.4s,v6.4s,v7.4s + zip1 v4.2d,v8.2d,v10.2d + zip2 v5.2d,v8.2d,v10.2d + zip1 v6.2d,v9.2d,v11.2d + zip2 v7.2d,v9.2d,v11.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + eor v3.16b, v3.16b, v19.16b + eor v4.16b, v4.16b, v20.16b + eor v5.16b, v5.16b, v21.16b + eor v6.16b, v6.16b, v22.16b + eor v7.16b, v7.16b, v23.16b + + // save the last tweak + mov v25.16b,v23.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + st1 {v4.4s,v5.4s,v6.4s,v7.4s},[x1],#64 + subs x2,x2,#8 + b.gt .Lxts_8_blocks_process + b 100f +.Lxts_4_blocks_process: + cmp x2,#4 + b.lt 1f + ld1 {v4.4s,v5.4s,v6.4s,v7.4s},[x0],#64 + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b + eor v7.16b, v7.16b, v19.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif +#ifndef __AARCH64EB__ + rev32 v7.16b,v7.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + eor v3.16b, v3.16b, v19.16b + st1 {v0.4s,v1.4s,v2.4s,v3.4s},[x1],#64 + sub x2,x2,#4 + mov v16.16b,v20.16b + mov v17.16b,v21.16b + mov v18.16b,v22.16b + // save the last tweak + mov v25.16b,v19.16b +1: + // process last block + cmp x2,#1 + b.lt 100f + b.gt 1f + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v16.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v16.16b + st1 {v4.4s},[x1],#16 + // save the last tweak + mov v25.16b,v16.16b + b 100f +1: // process last 2 blocks + cmp x2,#2 + b.gt 1f + ld1 {v4.4s,v5.4s},[x0],#32 + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + st1 {v0.4s,v1.4s},[x1],#32 + // save the last tweak + mov v25.16b,v17.16b + b 100f +1: // process last 3 blocks + ld1 {v4.4s,v5.4s,v6.4s},[x0],#48 + eor v4.16b, v4.16b, v16.16b + eor v5.16b, v5.16b, v17.16b + eor v6.16b, v6.16b, v18.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif +#ifndef __AARCH64EB__ + rev32 v5.16b,v5.16b +#endif +#ifndef __AARCH64EB__ + rev32 v6.16b,v6.16b +#endif + zip1 v0.4s,v4.4s,v5.4s + zip2 v1.4s,v4.4s,v5.4s + zip1 v2.4s,v6.4s,v7.4s + zip2 v3.4s,v6.4s,v7.4s + zip1 v4.2d,v0.2d,v2.2d + zip2 v5.2d,v0.2d,v2.2d + zip1 v6.2d,v1.2d,v3.2d + zip2 v7.2d,v1.2d,v3.2d + bl _vpsm4_ex_enc_4blks + zip1 v4.4s,v0.4s,v1.4s + zip2 v5.4s,v0.4s,v1.4s + zip1 v6.4s,v2.4s,v3.4s + zip2 v7.4s,v2.4s,v3.4s + zip1 v0.2d,v4.2d,v6.2d + zip2 v1.2d,v4.2d,v6.2d + zip1 v2.2d,v5.2d,v7.2d + zip2 v3.2d,v5.2d,v7.2d + eor v0.16b, v0.16b, v16.16b + eor v1.16b, v1.16b, v17.16b + eor v2.16b, v2.16b, v18.16b + st1 {v0.4s,v1.4s,v2.4s},[x1],#48 + // save the last tweak + mov v25.16b,v18.16b +100: + cmp x29,0 + b.eq .return + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak: +#ifdef __AARCH64EB__ + rev32 v25.16b,v25.16b +#endif + mov v2.16b,v25.16b + ldr q0, .Lxts_magic + shl v17.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v17.16b, v17.16b, v1.16b + mov v2.16b,v17.16b + ldr q0, .Lxts_magic + shl v18.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v18.16b, v18.16b, v1.16b + b .check_dec + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak: + mov v17.16b,v16.16b +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif + mov v2.16b,v17.16b + ldr q0, .Lxts_magic + shl v18.16b, v2.16b, #1 + ext v1.16b, v2.16b, v2.16b,#15 + ushr v1.16b, v1.16b, #7 + mul v1.16b, v1.16b, v0.16b + eor v18.16b, v18.16b, v1.16b + b .check_dec + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec: + // encryption:1 decryption:0 + cmp w28,1 + b.eq .prcess_last_2blks + mov v0.16B,v17.16b + mov v17.16B,v18.16b + mov v18.16B,v0.16b + +.prcess_last_2blks: +#ifdef __AARCH64EB__ + rev32 v17.16b,v17.16b +#endif +#ifdef __AARCH64EB__ + rev32 v18.16b,v18.16b +#endif + ld1 {v4.4s},[x0],#16 + eor v4.16b, v4.16b, v17.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v17.16b + st1 {v4.4s},[x1],#16 + + sub x26,x1,16 +.loop: + subs x29,x29,1 + ldrb w7,[x26,x29] + ldrb w8,[x0,x29] + strb w8,[x26,x29] + strb w7,[x1,x29] + b.gt .loop + ld1 {v4.4s}, [x26] + eor v4.16b, v4.16b, v18.16b +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + mov x10,x3 + mov w11,#8 + mov w12,v4.s[0] + mov w13,v4.s[1] + mov w14,v4.s[2] + mov w15,v4.s[3] +10: + ldp w7,w8,[x10],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor w6,w14,w15 + eor w9,w7,w13 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w12,w12,w6 + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor w6,w14,w15 + eor w9,w12,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + ldp w7,w8,[x10],8 + eor w13,w13,w6 + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor w6,w12,w13 + eor w9,w7,w15 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w14,w14,w6 + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor w6,w12,w13 + eor w9,w14,w8 + eor w6,w6,w9 + mov v3.s[0],w6 + // optimize sbox using AESE instruction + tbl v0.16b, {v3.16b}, v26.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v28.16b}, v0.16b + tbl v2.16b, {v27.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + eor v1.16b, v1.16b, v1.16b + aese v0.16b,v1.16b + ushr v2.16b, v0.16b, 4 + and v0.16b, v0.16b, v31.16b + tbl v0.16b, {v30.16b}, v0.16b + tbl v2.16b, {v29.16b}, v2.16b + eor v0.16b, v0.16b, v2.16b + + mov w7,v0.s[0] + eor w6,w7,w7,ror #32-2 + eor w6,w6,w7,ror #32-10 + eor w6,w6,w7,ror #32-18 + eor w6,w6,w7,ror #32-24 + eor w15,w15,w6 + subs w11,w11,#1 + b.ne 10b + mov v4.s[0],w15 + mov v4.s[1],w14 + mov v4.s[2],w13 + mov v4.s[3],w12 +#ifndef __AARCH64EB__ + rev32 v4.16b,v4.16b +#endif + eor v4.16b, v4.16b, v18.16b + st1 {v4.4s}, [x26] +.return: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size vpsm4_ex_xts_encrypt,.-vpsm4_ex_xts_encrypt diff --git a/crypto/sm4/asm/vpsm4_ex-armv8.pl b/crypto/sm4/asm/vpsm4_ex-armv8.pl new file mode 100644 index 0000000000..27dd25aa53 --- /dev/null +++ b/crypto/sm4/asm/vpsm4_ex-armv8.pl @@ -0,0 +1,1553 @@ +#! /usr/bin/env perl +# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# +# This module implements SM4 with ASIMD and AESE on AARCH64 +# +# Dec 2022 +# + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or +die "can't locate arm-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +$prefix="vpsm4_ex"; +my @vtmp=map("v$_",(0..3)); +my @qtmp=map("q$_",(0..3)); +my @data=map("v$_",(4..7)); +my @datax=map("v$_",(8..11)); +my ($rk0,$rk1)=("v12","v13"); +my ($rka,$rkb)=("v14","v15"); +my @vtmpx=map("v$_",(12..15)); +my ($vtmp4,$vtmp5)=("v24","v25"); +my ($MaskV,$TAHMatV,$TALMatV,$ATAHMatV,$ATALMatV,$ANDMaskV)=("v26","v27","v28","v29","v30","v31"); +my ($MaskQ,$TAHMatQ,$TALMatQ,$ATAHMatQ,$ATALMatQ,$ANDMaskQ)=("q26","q27","q28","q29","q30","q31"); + +my ($inp,$outp,$blocks,$rks)=("x0","x1","w2","x3"); +my ($tmpw,$tmp,$wtmp0,$wtmp1,$wtmp2)=("w6","x6","w7","w8","w9"); +my ($xtmp1,$xtmp2)=("x8","x9"); +my ($ptr,$counter)=("x10","w11"); +my ($word0,$word1,$word2,$word3)=("w12","w13","w14","w15"); + +sub rev32() { + my $dst = shift; + my $src = shift; + + if ($src and ("$src" ne "$dst")) { +$code.=<<___; +#ifndef __AARCH64EB__ + rev32 $dst.16b,$src.16b +#else + mov $dst.16b,$src.16b +#endif +___ + } else { +$code.=<<___; +#ifndef __AARCH64EB__ + rev32 $dst.16b,$dst.16b +#endif +___ + } +} + +sub rev32_armeb() { + my $dst = shift; + my $src = shift; + + if ($src and ("$src" ne "$dst")) { +$code.=<<___; +#ifdef __AARCH64EB__ + rev32 $dst.16b,$src.16b +#else + mov $dst.16b,$src.16b +#endif +___ + } else { +$code.=<<___; +#ifdef __AARCH64EB__ + rev32 $dst.16b,$dst.16b +#endif +___ + } +} + +sub rbit() { + my $dst = shift; + my $src = shift; + my $std = shift; + + if ($src and ("$src" ne "$dst")) { + if ($std eq "_gb") { +$code.=<<___; + rbit $dst.16b,$src.16b +___ + } else { +$code.=<<___; + mov $dst.16b,$src.16b +___ + } + } else { + if ($std eq "_gb") { +$code.=<<___; + rbit $dst.16b,$src.16b +___ + } + } +} + +sub transpose() { + my ($dat0,$dat1,$dat2,$dat3,$vt0,$vt1,$vt2,$vt3) = @_; + +$code.=<<___; + zip1 $vt0.4s,$dat0.4s,$dat1.4s + zip2 $vt1.4s,$dat0.4s,$dat1.4s + zip1 $vt2.4s,$dat2.4s,$dat3.4s + zip2 $vt3.4s,$dat2.4s,$dat3.4s + zip1 $dat0.2d,$vt0.2d,$vt2.2d + zip2 $dat1.2d,$vt0.2d,$vt2.2d + zip1 $dat2.2d,$vt1.2d,$vt3.2d + zip2 $dat3.2d,$vt1.2d,$vt3.2d +___ +} + +# matrix multiplication Mat*x = (lowerMat*x) ^ (higherMat*x) +sub mul_matrix() { + my $x = shift; + my $higherMat = shift; + my $lowerMat = shift; + my $tmp = shift; +$code.=<<___; + ushr $tmp.16b, $x.16b, 4 + and $x.16b, $x.16b, $ANDMaskV.16b + tbl $x.16b, {$lowerMat.16b}, $x.16b + tbl $tmp.16b, {$higherMat.16b}, $tmp.16b + eor $x.16b, $x.16b, $tmp.16b +___ +} + +# sbox operations for 4-lane of words +# sbox operation for 4-lane of words +sub sbox() { + my $dat = shift; + +$code.=<<___; + // optimize sbox using AESE instruction + tbl @vtmp[0].16b, {$dat.16b}, $MaskV.16b +___ + &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, $vtmp4); +$code.=<<___; + eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b + aese @vtmp[0].16b,@vtmp[1].16b +___ + &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, $vtmp4); +$code.=<<___; + mov $dat.16b,@vtmp[0].16b + + // linear transformation + ushr @vtmp[0].4s,$dat.4s,32-2 + ushr @vtmp[1].4s,$dat.4s,32-10 + ushr @vtmp[2].4s,$dat.4s,32-18 + ushr @vtmp[3].4s,$dat.4s,32-24 + sli @vtmp[0].4s,$dat.4s,2 + sli @vtmp[1].4s,$dat.4s,10 + sli @vtmp[2].4s,$dat.4s,18 + sli @vtmp[3].4s,$dat.4s,24 + eor $vtmp4.16b,@vtmp[0].16b,$dat.16b + eor $vtmp4.16b,$vtmp4.16b,$vtmp[1].16b + eor $dat.16b,@vtmp[2].16b,@vtmp[3].16b + eor $dat.16b,$dat.16b,$vtmp4.16b +___ +} + +# sbox operation for 8-lane of words +sub sbox_double() { + my $dat = shift; + my $datx = shift; + +$code.=<<___; + // optimize sbox using AESE instruction + tbl @vtmp[0].16b, {$dat.16b}, $MaskV.16b + tbl @vtmp[1].16b, {$datx.16b}, $MaskV.16b +___ + &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, $vtmp4); + &mul_matrix(@vtmp[1], $TAHMatV, $TALMatV, $vtmp4); +$code.=<<___; + eor $vtmp5.16b, $vtmp5.16b, $vtmp5.16b + aese @vtmp[0].16b,$vtmp5.16b + aese @vtmp[1].16b,$vtmp5.16b +___ + &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV,$vtmp4); + &mul_matrix(@vtmp[1], $ATAHMatV, $ATALMatV,$vtmp4); +$code.=<<___; + mov $dat.16b,@vtmp[0].16b + mov $datx.16b,@vtmp[1].16b + + // linear transformation + ushr @vtmp[0].4s,$dat.4s,32-2 + ushr $vtmp5.4s,$datx.4s,32-2 + ushr @vtmp[1].4s,$dat.4s,32-10 + ushr @vtmp[2].4s,$dat.4s,32-18 + ushr @vtmp[3].4s,$dat.4s,32-24 + sli @vtmp[0].4s,$dat.4s,2 + sli $vtmp5.4s,$datx.4s,2 + sli @vtmp[1].4s,$dat.4s,10 + sli @vtmp[2].4s,$dat.4s,18 + sli @vtmp[3].4s,$dat.4s,24 + eor $vtmp4.16b,@vtmp[0].16b,$dat.16b + eor $vtmp4.16b,$vtmp4.16b,@vtmp[1].16b + eor $dat.16b,@vtmp[2].16b,@vtmp[3].16b + eor $dat.16b,$dat.16b,$vtmp4.16b + ushr @vtmp[1].4s,$datx.4s,32-10 + ushr @vtmp[2].4s,$datx.4s,32-18 + ushr @vtmp[3].4s,$datx.4s,32-24 + sli @vtmp[1].4s,$datx.4s,10 + sli @vtmp[2].4s,$datx.4s,18 + sli @vtmp[3].4s,$datx.4s,24 + eor $vtmp4.16b,$vtmp5.16b,$datx.16b + eor $vtmp4.16b,$vtmp4.16b,@vtmp[1].16b + eor $datx.16b,@vtmp[2].16b,@vtmp[3].16b + eor $datx.16b,$datx.16b,$vtmp4.16b +___ +} + +# sbox operation for one single word +sub sbox_1word () { + my $word = shift; + +$code.=<<___; + mov @vtmp[3].s[0],$word + // optimize sbox using AESE instruction + tbl @vtmp[0].16b, {@vtmp[3].16b}, $MaskV.16b +___ + &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, @vtmp[2]); +$code.=<<___; + eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b + aese @vtmp[0].16b,@vtmp[1].16b +___ + &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, @vtmp[2]); +$code.=<<___; + + mov $wtmp0,@vtmp[0].s[0] + eor $word,$wtmp0,$wtmp0,ror #32-2 + eor $word,$word,$wtmp0,ror #32-10 + eor $word,$word,$wtmp0,ror #32-18 + eor $word,$word,$wtmp0,ror #32-24 +___ +} + +# sm4 for one block of data, in scalar registers word0/word1/word2/word3 +sub sm4_1blk () { + my $kptr = shift; + +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor $tmpw,$word2,$word3 + eor $wtmp2,$wtmp0,$word1 + eor $tmpw,$tmpw,$wtmp2 +___ + &sbox_1word($tmpw); +$code.=<<___; + eor $word0,$word0,$tmpw + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor $tmpw,$word2,$word3 + eor $wtmp2,$word0,$wtmp1 + eor $tmpw,$tmpw,$wtmp2 +___ + &sbox_1word($tmpw); +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + eor $word1,$word1,$tmpw + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor $tmpw,$word0,$word1 + eor $wtmp2,$wtmp0,$word3 + eor $tmpw,$tmpw,$wtmp2 +___ + &sbox_1word($tmpw); +$code.=<<___; + eor $word2,$word2,$tmpw + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor $tmpw,$word0,$word1 + eor $wtmp2,$word2,$wtmp1 + eor $tmpw,$tmpw,$wtmp2 +___ + &sbox_1word($tmpw); +$code.=<<___; + eor $word3,$word3,$tmpw +___ +} + +# sm4 for 4-lanes of data, in neon registers data0/data1/data2/data3 +sub sm4_4blks () { + my $kptr = shift; + +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + dup $rk0.4s,$wtmp0 + dup $rk1.4s,$wtmp1 + + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + eor $rka.16b,@data[2].16b,@data[3].16b + eor $rk0.16b,@data[1].16b,$rk0.16b + eor $rk0.16b,$rka.16b,$rk0.16b +___ + &sbox($rk0); +$code.=<<___; + eor @data[0].16b,@data[0].16b,$rk0.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + eor $rka.16b,$rka.16b,@data[0].16b + eor $rk1.16b,$rka.16b,$rk1.16b +___ + &sbox($rk1); +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + eor @data[1].16b,@data[1].16b,$rk1.16b + + dup $rk0.4s,$wtmp0 + dup $rk1.4s,$wtmp1 + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + eor $rka.16b,@data[0].16b,@data[1].16b + eor $rk0.16b,@data[3].16b,$rk0.16b + eor $rk0.16b,$rka.16b,$rk0.16b +___ + &sbox($rk0); +$code.=<<___; + eor @data[2].16b,@data[2].16b,$rk0.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + eor $rka.16b,$rka.16b,@data[2].16b + eor $rk1.16b,$rka.16b,$rk1.16b +___ + &sbox($rk1); +$code.=<<___; + eor @data[3].16b,@data[3].16b,$rk1.16b +___ +} + +# sm4 for 8 lanes of data, in neon registers +# data0/data1/data2/data3 datax0/datax1/datax2/datax3 +sub sm4_8blks () { + my $kptr = shift; + +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + // B0 ^= SBOX(B1 ^ B2 ^ B3 ^ RK0) + dup $rk0.4s,$wtmp0 + eor $rka.16b,@data[2].16b,@data[3].16b + eor $rkb.16b,@datax[2].16b,@datax[3].16b + eor @vtmp[0].16b,@data[1].16b,$rk0.16b + eor @vtmp[1].16b,@datax[1].16b,$rk0.16b + eor $rk0.16b,$rka.16b,@vtmp[0].16b + eor $rk1.16b,$rkb.16b,@vtmp[1].16b +___ + &sbox_double($rk0,$rk1); +$code.=<<___; + eor @data[0].16b,@data[0].16b,$rk0.16b + eor @datax[0].16b,@datax[0].16b,$rk1.16b + + // B1 ^= SBOX(B0 ^ B2 ^ B3 ^ RK1) + dup $rk1.4s,$wtmp1 + eor $rka.16b,$rka.16b,@data[0].16b + eor $rkb.16b,$rkb.16b,@datax[0].16b + eor $rk0.16b,$rka.16b,$rk1.16b + eor $rk1.16b,$rkb.16b,$rk1.16b +___ + &sbox_double($rk0,$rk1); +$code.=<<___; + ldp $wtmp0,$wtmp1,[$kptr],8 + eor @data[1].16b,@data[1].16b,$rk0.16b + eor @datax[1].16b,@datax[1].16b,$rk1.16b + + // B2 ^= SBOX(B0 ^ B1 ^ B3 ^ RK2) + dup $rk0.4s,$wtmp0 + eor $rka.16b,@data[0].16b,@data[1].16b + eor $rkb.16b,@datax[0].16b,@datax[1].16b + eor @vtmp[0].16b,@data[3].16b,$rk0.16b + eor @vtmp[1].16b,@datax[3].16b,$rk0.16b + eor $rk0.16b,$rka.16b,@vtmp[0].16b + eor $rk1.16b,$rkb.16b,@vtmp[1].16b +___ + &sbox_double($rk0,$rk1); +$code.=<<___; + eor @data[2].16b,@data[2].16b,$rk0.16b + eor @datax[2].16b,@datax[2].16b,$rk1.16b + + // B3 ^= SBOX(B0 ^ B1 ^ B2 ^ RK3) + dup $rk1.4s,$wtmp1 + eor $rka.16b,$rka.16b,@data[2].16b + eor $rkb.16b,$rkb.16b,@datax[2].16b + eor $rk0.16b,$rka.16b,$rk1.16b + eor $rk1.16b,$rkb.16b,$rk1.16b +___ + &sbox_double($rk0,$rk1); +$code.=<<___; + eor @data[3].16b,@data[3].16b,$rk0.16b + eor @datax[3].16b,@datax[3].16b,$rk1.16b +___ +} + +sub encrypt_1blk_norev() { + my $dat = shift; + +$code.=<<___; + mov $ptr,$rks + mov $counter,#8 + mov $word0,$dat.s[0] + mov $word1,$dat.s[1] + mov $word2,$dat.s[2] + mov $word3,$dat.s[3] +10: +___ + &sm4_1blk($ptr); +$code.=<<___; + subs $counter,$counter,#1 + b.ne 10b + mov $dat.s[0],$word3 + mov $dat.s[1],$word2 + mov $dat.s[2],$word1 + mov $dat.s[3],$word0 +___ +} + +sub encrypt_1blk() { + my $dat = shift; + + &encrypt_1blk_norev($dat); + &rev32($dat,$dat); +} + +sub encrypt_4blks() { +$code.=<<___; + mov $ptr,$rks + mov $counter,#8 +10: +___ + &sm4_4blks($ptr); +$code.=<<___; + subs $counter,$counter,#1 + b.ne 10b +___ + &rev32(@vtmp[3],@data[0]); + &rev32(@vtmp[2],@data[1]); + &rev32(@vtmp[1],@data[2]); + &rev32(@vtmp[0],@data[3]); +} + +sub encrypt_8blks() { +$code.=<<___; + mov $ptr,$rks + mov $counter,#8 +10: +___ + &sm4_8blks($ptr); +$code.=<<___; + subs $counter,$counter,#1 + b.ne 10b +___ + &rev32(@vtmp[3],@data[0]); + &rev32(@vtmp[2],@data[1]); + &rev32(@vtmp[1],@data[2]); + &rev32(@vtmp[0],@data[3]); + &rev32(@data[3],@datax[0]); + &rev32(@data[2],@datax[1]); + &rev32(@data[1],@datax[2]); + &rev32(@data[0],@datax[3]); +} + +sub load_sbox () { + my $data = shift; + +$code.=<<___; + ldr $MaskQ, .Lsbox_magic + ldr $TAHMatQ, .Lsbox_magic+16 + ldr $TALMatQ, .Lsbox_magic+32 + ldr $ATAHMatQ, .Lsbox_magic+48 + ldr $ATALMatQ, .Lsbox_magic+64 + ldr $ANDMaskQ, .Lsbox_magic+80 +___ +} + +sub mov_reg_to_vec() { + my $src0 = shift; + my $src1 = shift; + my $desv = shift; +$code.=<<___; + mov $desv.d[0],$src0 + mov $desv.d[1],$src1 +___ + &rev32_armeb($desv,$desv); +} + +sub mov_vec_to_reg() { + my $srcv = shift; + my $des0 = shift; + my $des1 = shift; +$code.=<<___; + mov $des0,$srcv.d[0] + mov $des1,$srcv.d[1] +___ +} + +sub compute_tweak() { + my $src0 = shift; + my $src1 = shift; + my $des0 = shift; + my $des1 = shift; +$code.=<<___; + mov $wtmp0,0x87 + extr $xtmp2,$src1,$src1,#32 + extr $des1,$src1,$src0,#63 + and $wtmp1,$wtmp0,$wtmp2,asr#31 + eor $des0,$xtmp1,$src0,lsl#1 +___ +} + +sub compute_tweak_vec() { + my $src = shift; + my $des = shift; + my $std = shift; + &rbit(@vtmp[2],$src,$std); +$code.=<<___; + ldr @qtmp[0], .Lxts_magic + shl $des.16b, @vtmp[2].16b, #1 + ext @vtmp[1].16b, @vtmp[2].16b, @vtmp[2].16b,#15 + ushr @vtmp[1].16b, @vtmp[1].16b, #7 + mul @vtmp[1].16b, @vtmp[1].16b, @vtmp[0].16b + eor $des.16b, $des.16b, @vtmp[1].16b +___ + &rbit($des,$des,$std); +} + +$code=<<___; +#include "arm_arch.h" +.arch armv8-a+crypto +.text + +.type _${prefix}_consts,%object +.align 7 +_${prefix}_consts: +.Lck: + .long 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269 + .long 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9 + .long 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249 + .long 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9 + .long 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229 + .long 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299 + .long 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209 + .long 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 +.Lfk: + .quad 0x56aa3350a3b1bac6,0xb27022dc677d9197 +.Lshuffles: + .quad 0x0B0A090807060504,0x030201000F0E0D0C +.Lxts_magic: + .quad 0x0101010101010187,0x0101010101010101 +.Lsbox_magic: + .quad 0x0b0e0104070a0d00,0x0306090c0f020508 + .quad 0x62185a2042387a00,0x22581a6002783a40 + .quad 0x15df62a89e54e923,0xc10bb67c4a803df7 + .quad 0xb9aa6b78c1d21300,0x1407c6d56c7fbead + .quad 0x6404462679195b3b,0xe383c1a1fe9edcbc + .quad 0x0f0f0f0f0f0f0f0f,0x0f0f0f0f0f0f0f0f + +.size _${prefix}_consts,.-_${prefix}_consts +___ + +{{{ +my ($key,$keys,$enc)=("x0","x1","w2"); +my ($pointer,$schedules,$wtmp,$roundkey)=("x5","x6","w7","w8"); +my ($vkey,$vfk,$vmap)=("v5","v6","v7"); +$code.=<<___; +.type _${prefix}_set_key,%function +.align 4 +_${prefix}_set_key: + AARCH64_VALID_CALL_TARGET + ld1 {$vkey.4s},[$key] +___ + &load_sbox(); + &rev32($vkey,$vkey); +$code.=<<___; + adr $pointer,.Lshuffles + ld1 {$vmap.2d},[$pointer] + adr $pointer,.Lfk + ld1 {$vfk.2d},[$pointer] + eor $vkey.16b,$vkey.16b,$vfk.16b + mov $schedules,#32 + adr $pointer,.Lck + movi @vtmp[0].16b,#64 + cbnz $enc,1f + add $keys,$keys,124 +1: + mov $wtmp,$vkey.s[1] + ldr $roundkey,[$pointer],#4 + eor $roundkey,$roundkey,$wtmp + mov $wtmp,$vkey.s[2] + eor $roundkey,$roundkey,$wtmp + mov $wtmp,$vkey.s[3] + eor $roundkey,$roundkey,$wtmp + // optimize sbox using AESE instruction + mov @data[0].s[0],$roundkey + tbl @vtmp[0].16b, {@data[0].16b}, $MaskV.16b +___ + &mul_matrix(@vtmp[0], $TAHMatV, $TALMatV, @vtmp[2]); +$code.=<<___; + eor @vtmp[1].16b, @vtmp[1].16b, @vtmp[1].16b + aese @vtmp[0].16b,@vtmp[1].16b +___ + &mul_matrix(@vtmp[0], $ATAHMatV, $ATALMatV, @vtmp[2]); +$code.=<<___; + mov $wtmp,@vtmp[0].s[0] + eor $roundkey,$wtmp,$wtmp,ror #19 + eor $roundkey,$roundkey,$wtmp,ror #9 + mov $wtmp,$vkey.s[0] + eor $roundkey,$roundkey,$wtmp + mov $vkey.s[0],$roundkey + cbz $enc,2f + str $roundkey,[$keys],#4 + b 3f +2: + str $roundkey,[$keys],#-4 +3: + tbl $vkey.16b,{$vkey.16b},$vmap.16b + subs $schedules,$schedules,#1 + b.ne 1b + ret +.size _${prefix}_set_key,.-_${prefix}_set_key +___ +}}} + + +{{{ +$code.=<<___; +.type _${prefix}_enc_4blks,%function +.align 4 +_${prefix}_enc_4blks: + AARCH64_VALID_CALL_TARGET +___ + &encrypt_4blks(); +$code.=<<___; + ret +.size _${prefix}_enc_4blks,.-_${prefix}_enc_4blks +___ +}}} + +{{{ +$code.=<<___; +.type _${prefix}_enc_8blks,%function +.align 4 +_${prefix}_enc_8blks: + AARCH64_VALID_CALL_TARGET +___ + &encrypt_8blks(); +$code.=<<___; + ret +.size _${prefix}_enc_8blks,.-_${prefix}_enc_8blks +___ +}}} + + +{{{ +my ($key,$keys)=("x0","x1"); +$code.=<<___; +.globl ${prefix}_set_encrypt_key +.type ${prefix}_set_encrypt_key,%function +.align 5 +${prefix}_set_encrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + mov w2,1 + bl _${prefix}_set_key + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key +___ +}}} + +{{{ +my ($key,$keys)=("x0","x1"); +$code.=<<___; +.globl ${prefix}_set_decrypt_key +.type ${prefix}_set_decrypt_key,%function +.align 5 +${prefix}_set_decrypt_key: + AARCH64_SIGN_LINK_REGISTER + stp x29,x30,[sp,#-16]! + mov w2,0 + bl _${prefix}_set_key + ldp x29,x30,[sp],#16 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key +___ +}}} + +{{{ +sub gen_block () { + my $dir = shift; + my ($inp,$outp,$rk)=map("x$_",(0..2)); + +$code.=<<___; +.globl ${prefix}_${dir}crypt +.type ${prefix}_${dir}crypt,%function +.align 5 +${prefix}_${dir}crypt: + AARCH64_VALID_CALL_TARGET + ld1 {@data[0].4s},[$inp] +___ + &load_sbox(); + &rev32(@data[0],@data[0]); +$code.=<<___; + mov $rks,$rk +___ + &encrypt_1blk(@data[0]); +$code.=<<___; + st1 {@data[0].4s},[$outp] + ret +.size ${prefix}_${dir}crypt,.-${prefix}_${dir}crypt +___ +} +&gen_block("en"); +&gen_block("de"); +}}} + +{{{ +$code.=<<___; +.globl ${prefix}_ecb_encrypt +.type ${prefix}_ecb_encrypt,%function +.align 5 +${prefix}_ecb_encrypt: + AARCH64_SIGN_LINK_REGISTER + // convert length into blocks + lsr x2,x2,4 + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] +___ + &load_sbox(); +$code.=<<___; +.Lecb_8_blocks_process: + cmp $blocks,#8 + b.lt .Lecb_4_blocks_process + ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 + ld4 {@datax[0].4s,$datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &rev32(@datax[0],@datax[0]); + &rev32(@datax[1],@datax[1]); + &rev32(@datax[2],@datax[2]); + &rev32(@datax[3],@datax[3]); +$code.=<<___; + bl _${prefix}_enc_8blks + st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + st4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#8 + b.gt .Lecb_8_blocks_process + b 100f +.Lecb_4_blocks_process: + cmp $blocks,#4 + b.lt 1f + ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + sub $blocks,$blocks,#4 +1: + // process last block + cmp $blocks,#1 + b.lt 100f + b.gt 1f + ld1 {@data[0].4s},[$inp] +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + st1 {@data[0].4s},[$outp] + b 100f +1: // process last 2 blocks + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[0],[$inp],#16 + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[1],[$inp],#16 + cmp $blocks,#2 + b.gt 1f +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + st4 {@vtmp[0].s-@vtmp[3].s}[0],[$outp],#16 + st4 {@vtmp[0].s-@vtmp[3].s}[1],[$outp] + b 100f +1: // process last 3 blocks + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[2],[$inp],#16 +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + st4 {@vtmp[0].s-@vtmp[3].s}[0],[$outp],#16 + st4 {@vtmp[0].s-@vtmp[3].s}[1],[$outp],#16 + st4 {@vtmp[0].s-@vtmp[3].s}[2],[$outp] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_ecb_encrypt,.-${prefix}_ecb_encrypt +___ +}}} + +{{{ +my ($len,$ivp,$enc)=("x2","x4","w5"); +my $ivec0=("v3"); +my $ivec1=("v15"); + +$code.=<<___; +.globl ${prefix}_cbc_encrypt +.type ${prefix}_cbc_encrypt,%function +.align 5 +${prefix}_cbc_encrypt: + AARCH64_VALID_CALL_TARGET + lsr $len,$len,4 +___ + &load_sbox(); +$code.=<<___; + cbz $enc,.Ldec + ld1 {$ivec0.4s},[$ivp] +.Lcbc_4_blocks_enc: + cmp $blocks,#4 + b.lt 1f + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 + eor @data[0].16b,@data[0].16b,$ivec0.16b +___ + &rev32(@data[1],@data[1]); + &rev32(@data[0],@data[0]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &encrypt_1blk_norev(@data[0]); +$code.=<<___; + eor @data[1].16b,@data[1].16b,@data[0].16b +___ + &encrypt_1blk_norev(@data[1]); + &rev32(@data[0],@data[0]); + +$code.=<<___; + eor @data[2].16b,@data[2].16b,@data[1].16b +___ + &encrypt_1blk_norev(@data[2]); + &rev32(@data[1],@data[1]); +$code.=<<___; + eor @data[3].16b,@data[3].16b,@data[2].16b +___ + &encrypt_1blk_norev(@data[3]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + orr $ivec0.16b,@data[3].16b,@data[3].16b + st1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#4 + b.ne .Lcbc_4_blocks_enc + b 2f +1: + subs $blocks,$blocks,#1 + b.lt 2f + ld1 {@data[0].4s},[$inp],#16 + eor $ivec0.16b,$ivec0.16b,@data[0].16b +___ + &rev32($ivec0,$ivec0); + &encrypt_1blk($ivec0); +$code.=<<___; + st1 {$ivec0.4s},[$outp],#16 + b 1b +2: + // save back IV + st1 {$ivec0.4s},[$ivp] + ret + +.Ldec: + // decryption mode starts + AARCH64_SIGN_LINK_REGISTER + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] +.Lcbc_8_blocks_dec: + cmp $blocks,#8 + b.lt 1f + ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp] + add $ptr,$inp,#64 + ld4 {@datax[0].4s,@datax[1].4s,@datax[2].4s,@datax[3].4s},[$ptr] +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],$data[3]); + &rev32(@datax[0],@datax[0]); + &rev32(@datax[1],@datax[1]); + &rev32(@datax[2],@datax[2]); + &rev32(@datax[3],$datax[3]); +$code.=<<___; + bl _${prefix}_enc_8blks +___ + &transpose(@vtmp,@datax); + &transpose(@data,@datax); +$code.=<<___; + ld1 {$ivec1.4s},[$ivp] + ld1 {@datax[0].4s,@datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 + // note ivec1 and vtmpx[3] are resuing the same register + // care needs to be taken to avoid conflict + eor @vtmp[0].16b,@vtmp[0].16b,$ivec1.16b + ld1 {@vtmpx[0].4s,@vtmpx[1].4s,@vtmpx[2].4s,@vtmpx[3].4s},[$inp],#64 + eor @vtmp[1].16b,@vtmp[1].16b,@datax[0].16b + eor @vtmp[2].16b,@vtmp[2].16b,@datax[1].16b + eor @vtmp[3].16b,$vtmp[3].16b,@datax[2].16b + // save back IV + st1 {$vtmpx[3].4s}, [$ivp] + eor @data[0].16b,@data[0].16b,$datax[3].16b + eor @data[1].16b,@data[1].16b,@vtmpx[0].16b + eor @data[2].16b,@data[2].16b,@vtmpx[1].16b + eor @data[3].16b,$data[3].16b,@vtmpx[2].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + st1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#8 + b.gt .Lcbc_8_blocks_dec + b.eq 100f +1: + ld1 {$ivec1.4s},[$ivp] +.Lcbc_4_blocks_dec: + cmp $blocks,#4 + b.lt 1f + ld4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp] +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],$data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &transpose(@vtmp,@datax); +$code.=<<___; + eor @vtmp[0].16b,@vtmp[0].16b,$ivec1.16b + eor @vtmp[1].16b,@vtmp[1].16b,@data[0].16b + orr $ivec1.16b,@data[3].16b,@data[3].16b + eor @vtmp[2].16b,@vtmp[2].16b,@data[1].16b + eor @vtmp[3].16b,$vtmp[3].16b,@data[2].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + subs $blocks,$blocks,#4 + b.gt .Lcbc_4_blocks_dec + // save back IV + st1 {@data[3].4s}, [$ivp] + b 100f +1: // last block + subs $blocks,$blocks,#1 + b.lt 100f + b.gt 1f + ld1 {@data[0].4s},[$inp],#16 + // save back IV + st1 {$data[0].4s}, [$ivp] +___ + &rev32(@datax[0],@data[0]); + &encrypt_1blk(@datax[0]); +$code.=<<___; + eor @datax[0].16b,@datax[0].16b,$ivec1.16b + st1 {@datax[0].4s},[$outp],#16 + b 100f +1: // last two blocks + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[0],[$inp] + add $ptr,$inp,#16 + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[1],[$ptr],#16 + subs $blocks,$blocks,1 + b.gt 1f +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + ld1 {@data[0].4s,@data[1].4s},[$inp],#32 +___ + &transpose(@vtmp,@datax); +$code.=<<___; + eor @vtmp[0].16b,@vtmp[0].16b,$ivec1.16b + eor @vtmp[1].16b,@vtmp[1].16b,@data[0].16b + st1 {@vtmp[0].4s,@vtmp[1].4s},[$outp],#32 + // save back IV + st1 {@data[1].4s}, [$ivp] + b 100f +1: // last 3 blocks + ld4 {@data[0].s,@data[1].s,@data[2].s,@data[3].s}[2],[$ptr] +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); +$code.=<<___; + bl _${prefix}_enc_4blks + ld1 {@data[0].4s,@data[1].4s,@data[2].4s},[$inp],#48 +___ + &transpose(@vtmp,@datax); +$code.=<<___; + eor @vtmp[0].16b,@vtmp[0].16b,$ivec1.16b + eor @vtmp[1].16b,@vtmp[1].16b,@data[0].16b + eor @vtmp[2].16b,@vtmp[2].16b,@data[1].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s},[$outp],#48 + // save back IV + st1 {@data[2].4s}, [$ivp] +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt +___ +}}} + +{{{ +my ($ivp)=("x4"); +my ($ctr)=("w5"); +my $ivec=("v3"); + +$code.=<<___; +.globl ${prefix}_ctr32_encrypt_blocks +.type ${prefix}_ctr32_encrypt_blocks,%function +.align 5 +${prefix}_ctr32_encrypt_blocks: + AARCH64_VALID_CALL_TARGET + ld1 {$ivec.4s},[$ivp] +___ + &rev32($ivec,$ivec); + &load_sbox(); +$code.=<<___; + cmp $blocks,#1 + b.ne 1f + // fast processing for one single block without + // context saving overhead +___ + &encrypt_1blk($ivec); +$code.=<<___; + ld1 {@data[0].4s},[$inp] + eor @data[0].16b,@data[0].16b,$ivec.16b + st1 {@data[0].4s},[$outp] + ret +1: + AARCH64_SIGN_LINK_REGISTER + stp d8,d9,[sp,#-80]! + stp d10,d11,[sp,#16] + stp d12,d13,[sp,#32] + stp d14,d15,[sp,#48] + stp x29,x30,[sp,#64] + mov $word0,$ivec.s[0] + mov $word1,$ivec.s[1] + mov $word2,$ivec.s[2] + mov $ctr,$ivec.s[3] +.Lctr32_4_blocks_process: + cmp $blocks,#4 + b.lt 1f + dup @data[0].4s,$word0 + dup @data[1].4s,$word1 + dup @data[2].4s,$word2 + mov @data[3].s[0],$ctr + add $ctr,$ctr,#1 + mov $data[3].s[1],$ctr + add $ctr,$ctr,#1 + mov @data[3].s[2],$ctr + add $ctr,$ctr,#1 + mov @data[3].s[3],$ctr + add $ctr,$ctr,#1 + cmp $blocks,#8 + b.ge .Lctr32_8_blocks_process + bl _${prefix}_enc_4blks + ld4 {@vtmpx[0].4s,@vtmpx[1].4s,@vtmpx[2].4s,@vtmpx[3].4s},[$inp],#64 + eor @vtmp[0].16b,@vtmp[0].16b,@vtmpx[0].16b + eor @vtmp[1].16b,@vtmp[1].16b,@vtmpx[1].16b + eor @vtmp[2].16b,@vtmp[2].16b,@vtmpx[2].16b + eor @vtmp[3].16b,@vtmp[3].16b,@vtmpx[3].16b + st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + subs $blocks,$blocks,#4 + b.ne .Lctr32_4_blocks_process + b 100f +.Lctr32_8_blocks_process: + dup @datax[0].4s,$word0 + dup @datax[1].4s,$word1 + dup @datax[2].4s,$word2 + mov @datax[3].s[0],$ctr + add $ctr,$ctr,#1 + mov $datax[3].s[1],$ctr + add $ctr,$ctr,#1 + mov @datax[3].s[2],$ctr + add $ctr,$ctr,#1 + mov @datax[3].s[3],$ctr + add $ctr,$ctr,#1 + bl _${prefix}_enc_8blks + ld4 {@vtmpx[0].4s,@vtmpx[1].4s,@vtmpx[2].4s,@vtmpx[3].4s},[$inp],#64 + ld4 {@datax[0].4s,@datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 + eor @vtmp[0].16b,@vtmp[0].16b,@vtmpx[0].16b + eor @vtmp[1].16b,@vtmp[1].16b,@vtmpx[1].16b + eor @vtmp[2].16b,@vtmp[2].16b,@vtmpx[2].16b + eor @vtmp[3].16b,@vtmp[3].16b,@vtmpx[3].16b + eor @data[0].16b,@data[0].16b,@datax[0].16b + eor @data[1].16b,@data[1].16b,@datax[1].16b + eor @data[2].16b,@data[2].16b,@datax[2].16b + eor @data[3].16b,@data[3].16b,@datax[3].16b + st4 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + st4 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#8 + b.ne .Lctr32_4_blocks_process + b 100f +1: // last block processing + subs $blocks,$blocks,#1 + b.lt 100f + b.gt 1f + mov $ivec.s[0],$word0 + mov $ivec.s[1],$word1 + mov $ivec.s[2],$word2 + mov $ivec.s[3],$ctr +___ + &encrypt_1blk($ivec); +$code.=<<___; + ld1 {@data[0].4s},[$inp] + eor @data[0].16b,@data[0].16b,$ivec.16b + st1 {@data[0].4s},[$outp] + b 100f +1: // last 2 blocks processing + dup @data[0].4s,$word0 + dup @data[1].4s,$word1 + dup @data[2].4s,$word2 + mov @data[3].s[0],$ctr + add $ctr,$ctr,#1 + mov @data[3].s[1],$ctr + subs $blocks,$blocks,#1 + b.ne 1f + bl _${prefix}_enc_4blks + ld4 {@vtmpx[0].s,@vtmpx[1].s,@vtmpx[2].s,@vtmpx[3].s}[0],[$inp],#16 + ld4 {@vtmpx[0].s,@vtmpx[1].s,@vtmpx[2].s,@vtmpx[3].s}[1],[$inp],#16 + eor @vtmp[0].16b,@vtmp[0].16b,@vtmpx[0].16b + eor @vtmp[1].16b,@vtmp[1].16b,@vtmpx[1].16b + eor @vtmp[2].16b,@vtmp[2].16b,@vtmpx[2].16b + eor @vtmp[3].16b,@vtmp[3].16b,@vtmpx[3].16b + st4 {@vtmp[0].s,@vtmp[1].s,@vtmp[2].s,@vtmp[3].s}[0],[$outp],#16 + st4 {@vtmp[0].s,@vtmp[1].s,@vtmp[2].s,@vtmp[3].s}[1],[$outp],#16 + b 100f +1: // last 3 blocks processing + add $ctr,$ctr,#1 + mov @data[3].s[2],$ctr + bl _${prefix}_enc_4blks + ld4 {@vtmpx[0].s,@vtmpx[1].s,@vtmpx[2].s,@vtmpx[3].s}[0],[$inp],#16 + ld4 {@vtmpx[0].s,@vtmpx[1].s,@vtmpx[2].s,@vtmpx[3].s}[1],[$inp],#16 + ld4 {@vtmpx[0].s,@vtmpx[1].s,@vtmpx[2].s,@vtmpx[3].s}[2],[$inp],#16 + eor @vtmp[0].16b,@vtmp[0].16b,@vtmpx[0].16b + eor @vtmp[1].16b,@vtmp[1].16b,@vtmpx[1].16b + eor @vtmp[2].16b,@vtmp[2].16b,@vtmpx[2].16b + eor @vtmp[3].16b,@vtmp[3].16b,@vtmpx[3].16b + st4 {@vtmp[0].s,@vtmp[1].s,@vtmp[2].s,@vtmp[3].s}[0],[$outp],#16 + st4 {@vtmp[0].s,@vtmp[1].s,@vtmp[2].s,@vtmp[3].s}[1],[$outp],#16 + st4 {@vtmp[0].s,@vtmp[1].s,@vtmp[2].s,@vtmp[3].s}[2],[$outp],#16 +100: + ldp d10,d11,[sp,#16] + ldp d12,d13,[sp,#32] + ldp d14,d15,[sp,#48] + ldp x29,x30,[sp,#64] + ldp d8,d9,[sp],#80 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks +___ +}}} + + +{{{ +my ($blocks,$len)=("x2","x2"); +my $ivp=("x5"); +my @twx=map("x$_",(12..27)); +my ($rks1,$rks2)=("x26","x27"); +my $lastBlk=("x26"); +my $enc=("w28"); +my $remain=("x29"); + +my @tweak=map("v$_",(16..23)); +my $lastTweak=("v25"); + +sub gen_xts_cipher() { + my $std = shift; +$code.=<<___; +.globl ${prefix}_xts_encrypt${std} +.type ${prefix}_xts_encrypt${std},%function +.align 5 +${prefix}_xts_encrypt${std}: + AARCH64_SIGN_LINK_REGISTER + stp x15, x16, [sp, #-0x10]! + stp x17, x18, [sp, #-0x10]! + stp x19, x20, [sp, #-0x10]! + stp x21, x22, [sp, #-0x10]! + stp x23, x24, [sp, #-0x10]! + stp x25, x26, [sp, #-0x10]! + stp x27, x28, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + stp d8, d9, [sp, #-0x10]! + stp d10, d11, [sp, #-0x10]! + stp d12, d13, [sp, #-0x10]! + stp d14, d15, [sp, #-0x10]! + mov $rks1,x3 + mov $rks2,x4 + mov $enc,w6 + ld1 {@tweak[0].4s}, [$ivp] + mov $rks,$rks2 +___ + &load_sbox(); + &rev32(@tweak[0],@tweak[0]); + &encrypt_1blk(@tweak[0]); +$code.=<<___; + mov $rks,$rks1 + and $remain,$len,#0x0F + // convert length into blocks + lsr $blocks,$len,4 + cmp $blocks,#1 + b.lt .return${std} + + cmp $remain,0 + // If the encryption/decryption Length is N times of 16, + // the all blocks are encrypted/decrypted in .xts_encrypt_blocks${std} + b.eq .xts_encrypt_blocks${std} + + // If the encryption/decryption length is not N times of 16, + // the last two blocks are encrypted/decrypted in .last_2blks_tweak${std} or .only_2blks_tweak${std} + // the other blocks are encrypted/decrypted in .xts_encrypt_blocks${std} + subs $blocks,$blocks,#1 + b.eq .only_2blks_tweak${std} +.xts_encrypt_blocks${std}: +___ + &rbit(@tweak[0],@tweak[0],$std); + &rev32_armeb(@tweak[0],@tweak[0]); + &mov_vec_to_reg(@tweak[0],@twx[0],@twx[1]); + &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); + &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); + &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); + &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); + &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); + &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); + &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); +$code.=<<___; +.Lxts_8_blocks_process${std}: + cmp $blocks,#8 +___ + &mov_reg_to_vec(@twx[0],@twx[1],@tweak[0]); + &compute_tweak(@twx[14],@twx[15],@twx[0],@twx[1]); + &mov_reg_to_vec(@twx[2],@twx[3],@tweak[1]); + &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3]); + &mov_reg_to_vec(@twx[4],@twx[5],@tweak[2]); + &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5]); + &mov_reg_to_vec(@twx[6],@twx[7],@tweak[3]); + &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7]); + &mov_reg_to_vec(@twx[8],@twx[9],@tweak[4]); + &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9]); + &mov_reg_to_vec(@twx[10],@twx[11],@tweak[5]); + &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11]); + &mov_reg_to_vec(@twx[12],@twx[13],@tweak[6]); + &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13]); + &mov_reg_to_vec(@twx[14],@twx[15],@tweak[7]); + &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15]); +$code.=<<___; + b.lt .Lxts_4_blocks_process${std} + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); + &rbit(@tweak[2],@tweak[2],$std); + &rbit(@tweak[3],@tweak[3],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b + eor @data[3].16b, @data[3].16b, @tweak[3].16b + ld1 {@datax[0].4s,$datax[1].4s,@datax[2].4s,@datax[3].4s},[$inp],#64 +___ + &rbit(@tweak[4],@tweak[4],$std); + &rbit(@tweak[5],@tweak[5],$std); + &rbit(@tweak[6],@tweak[6],$std); + &rbit(@tweak[7],@tweak[7],$std); +$code.=<<___; + eor @datax[0].16b, @datax[0].16b, @tweak[4].16b + eor @datax[1].16b, @datax[1].16b, @tweak[5].16b + eor @datax[2].16b, @datax[2].16b, @tweak[6].16b + eor @datax[3].16b, @datax[3].16b, @tweak[7].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &rev32(@datax[0],@datax[0]); + &rev32(@datax[1],@datax[1]); + &rev32(@datax[2],@datax[2]); + &rev32(@datax[3],@datax[3]); + &transpose(@data,@vtmp); + &transpose(@datax,@vtmp); +$code.=<<___; + bl _${prefix}_enc_8blks +___ + &transpose(@vtmp,@datax); + &transpose(@data,@datax); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b + eor @vtmp[3].16b, @vtmp[3].16b, @tweak[3].16b + eor @data[0].16b, @data[0].16b, @tweak[4].16b + eor @data[1].16b, @data[1].16b, @tweak[5].16b + eor @data[2].16b, @data[2].16b, @tweak[6].16b + eor @data[3].16b, @data[3].16b, @tweak[7].16b + + // save the last tweak + mov $lastTweak.16b,@tweak[7].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + st1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$outp],#64 + subs $blocks,$blocks,#8 + b.gt .Lxts_8_blocks_process${std} + b 100f +.Lxts_4_blocks_process${std}: + cmp $blocks,#4 + b.lt 1f + ld1 {@data[0].4s,@data[1].4s,@data[2].4s,@data[3].4s},[$inp],#64 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); + &rbit(@tweak[2],@tweak[2],$std); + &rbit(@tweak[3],@tweak[3],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b + eor @data[3].16b, @data[3].16b, @tweak[3].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &rev32(@data[3],@data[3]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b + eor @vtmp[3].16b, @vtmp[3].16b, @tweak[3].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s,@vtmp[3].4s},[$outp],#64 + sub $blocks,$blocks,#4 + mov @tweak[0].16b,@tweak[4].16b + mov @tweak[1].16b,@tweak[5].16b + mov @tweak[2].16b,@tweak[6].16b + // save the last tweak + mov $lastTweak.16b,@tweak[3].16b +1: + // process last block + cmp $blocks,#1 + b.lt 100f + b.gt 1f + ld1 {@data[0].4s},[$inp],#16 +___ + &rbit(@tweak[0],@tweak[0],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + st1 {@data[0].4s},[$outp],#16 + // save the last tweak + mov $lastTweak.16b,@tweak[0].16b + b 100f +1: // process last 2 blocks + cmp $blocks,#2 + b.gt 1f + ld1 {@data[0].4s,@data[1].4s},[$inp],#32 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + st1 {@vtmp[0].4s,@vtmp[1].4s},[$outp],#32 + // save the last tweak + mov $lastTweak.16b,@tweak[1].16b + b 100f +1: // process last 3 blocks + ld1 {@data[0].4s,@data[1].4s,@data[2].4s},[$inp],#48 +___ + &rbit(@tweak[0],@tweak[0],$std); + &rbit(@tweak[1],@tweak[1],$std); + &rbit(@tweak[2],@tweak[2],$std); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[0].16b + eor @data[1].16b, @data[1].16b, @tweak[1].16b + eor @data[2].16b, @data[2].16b, @tweak[2].16b +___ + &rev32(@data[0],@data[0]); + &rev32(@data[1],@data[1]); + &rev32(@data[2],@data[2]); + &transpose(@data,@vtmp); +$code.=<<___; + bl _${prefix}_enc_4blks +___ + &transpose(@vtmp,@data); +$code.=<<___; + eor @vtmp[0].16b, @vtmp[0].16b, @tweak[0].16b + eor @vtmp[1].16b, @vtmp[1].16b, @tweak[1].16b + eor @vtmp[2].16b, @vtmp[2].16b, @tweak[2].16b + st1 {@vtmp[0].4s,@vtmp[1].4s,@vtmp[2].4s},[$outp],#48 + // save the last tweak + mov $lastTweak.16b,@tweak[2].16b +100: + cmp $remain,0 + b.eq .return${std} + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is larger than 32 +.last_2blks_tweak${std}: +___ + &rev32_armeb($lastTweak,$lastTweak); + &compute_tweak_vec($lastTweak,@tweak[1],$std); + &compute_tweak_vec(@tweak[1],@tweak[2],$std); +$code.=<<___; + b .check_dec${std} + + +// This branch calculates the last two tweaks, +// while the encryption/decryption length is equal to 32, who only need two tweaks +.only_2blks_tweak${std}: + mov @tweak[1].16b,@tweak[0].16b +___ + &rev32_armeb(@tweak[1],@tweak[1]); + &compute_tweak_vec(@tweak[1],@tweak[2]); +$code.=<<___; + b .check_dec${std} + + +// Determine whether encryption or decryption is required. +// The last two tweaks need to be swapped for decryption. +.check_dec${std}: + // encryption:1 decryption:0 + cmp $enc,1 + b.eq .prcess_last_2blks${std} + mov @vtmp[0].16B,@tweak[1].16b + mov @tweak[1].16B,@tweak[2].16b + mov @tweak[2].16B,@vtmp[0].16b + +.prcess_last_2blks${std}: +___ + &rev32_armeb(@tweak[1],@tweak[1]); + &rev32_armeb(@tweak[2],@tweak[2]); +$code.=<<___; + ld1 {@data[0].4s},[$inp],#16 + eor @data[0].16b, @data[0].16b, @tweak[1].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[1].16b + st1 {@data[0].4s},[$outp],#16 + + sub $lastBlk,$outp,16 + .loop${std}: + subs $remain,$remain,1 + ldrb $wtmp0,[$lastBlk,$remain] + ldrb $wtmp1,[$inp,$remain] + strb $wtmp1,[$lastBlk,$remain] + strb $wtmp0,[$outp,$remain] + b.gt .loop${std} + ld1 {@data[0].4s}, [$lastBlk] + eor @data[0].16b, @data[0].16b, @tweak[2].16b +___ + &rev32(@data[0],@data[0]); + &encrypt_1blk(@data[0]); +$code.=<<___; + eor @data[0].16b, @data[0].16b, @tweak[2].16b + st1 {@data[0].4s}, [$lastBlk] +.return${std}: + ldp d14, d15, [sp], #0x10 + ldp d12, d13, [sp], #0x10 + ldp d10, d11, [sp], #0x10 + ldp d8, d9, [sp], #0x10 + ldp x29, x30, [sp], #0x10 + ldp x27, x28, [sp], #0x10 + ldp x25, x26, [sp], #0x10 + ldp x23, x24, [sp], #0x10 + ldp x21, x22, [sp], #0x10 + ldp x19, x20, [sp], #0x10 + ldp x17, x18, [sp], #0x10 + ldp x15, x16, [sp], #0x10 + AARCH64_VALIDATE_LINK_REGISTER + ret +.size ${prefix}_xts_encrypt${std},.-${prefix}_xts_encrypt${std} +___ +} # end of gen_xts_cipher +&gen_xts_cipher("_gb"); +&gen_xts_cipher(""); +}}} + +######################################## +open SELF,$0; +while() { + next if (/^#!/); + last if (!s/^#/\/\// and !/^$/); + print; +} +close SELF; + +foreach(split("\n",$code)) { + s/\`([^\`]*)\`/eval($1)/ge; + print $_,"\n"; +} + +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/sm4/build.info b/crypto/sm4/build.info index 75a215ab80..73ffe5ea09 100644 --- a/crypto/sm4/build.info +++ b/crypto/sm4/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto IF[{- !$disabled{asm} -}] $SM4DEF_aarch64=SM4_ASM VPSM4_ASM - $SM4ASM_aarch64=sm4-armv8.S vpsm4-armv8.S + $SM4ASM_aarch64=sm4-armv8.S vpsm4-armv8.S vpsm4_ex-armv8.S # Now that we have defined all the arch specific variables, use the # appropriate one, and define the appropriate macros @@ -30,5 +30,7 @@ ENDIF GENERATE[sm4-armv8.S]=asm/sm4-armv8.pl GENERATE[vpsm4-armv8.S]=asm/vpsm4-armv8.pl +GENERATE[vpsm4_ex-armv8.S]=asm/vpsm4_ex-armv8.pl INCLUDE[sm4-armv8.o]=.. INCLUDE[vpsm4-armv8.o]=.. +INCLUDE[vpsm4_ex-armv8.o]=.. diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c index 96d511ffe6..e89f58b200 100644 --- a/crypto/srp/srp_vfy.c +++ b/crypto/srp/srp_vfy.c @@ -191,10 +191,8 @@ SRP_user_pwd *SRP_user_pwd_new(void) { SRP_user_pwd *ret; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - /* ERR_raise(ERR_LIB_SRP, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/ + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) return NULL; - } ret->N = NULL; ret->g = NULL; ret->s = NULL; @@ -394,7 +392,7 @@ static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) { - int error_code; + int error_code = SRP_ERR_MEMORY; STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); char *last_index = NULL; int i; @@ -406,6 +404,9 @@ int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) TXT_DB *tmpdb = NULL; BIO *in = BIO_new(BIO_s_file()); + if (SRP_gN_tab == NULL) + goto err; + error_code = SRP_ERR_OPEN_FILE; if (in == NULL || BIO_read_filename(in, verifier_file) <= 0) @@ -629,7 +630,7 @@ char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt, if (N_bn_alloc == NULL) goto err; N_bn = N_bn_alloc; - if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0) + if ((len = t_fromb64(tmp, sizeof(tmp), g)) <= 0) goto err; g_bn_alloc = BN_bin2bn(tmp, len, NULL); if (g_bn_alloc == NULL) diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index 51080b8767..72e3087e89 100644 --- a/crypto/stack/stack.c +++ b/crypto/stack/stack.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,10 +10,13 @@ #include #include "internal/cryptlib.h" #include "internal/numbers.h" +#include "internal/safe_math.h" #include #include #include /* For ossl_inline */ +OSSL_SAFE_MATH_SIGNED(int, int) + /* * The initial number of nodes in the array. */ @@ -72,7 +75,6 @@ OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) return ret; err: - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_sk_free(ret); return NULL; } @@ -121,7 +123,6 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, return ret; err: - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_sk_free(ret); return NULL; } @@ -139,32 +140,35 @@ OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c) /* * Calculate the array growth based on the target size. * - * The growth fraction is a rational number and is defined by a numerator + * The growth factor is a rational number and is defined by a numerator * and a denominator. According to Andrew Koenig in his paper "Why Are * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less * than the golden ratio (1.618...). * - * We use 3/2 = 1.5 for simplicity of calculation and overflow checking. - * Another option 8/5 = 1.6 allows for slightly faster growth, although safe - * computation is more difficult. + * Considering only the Fibonacci ratios less than the golden ratio, the + * number of steps from the minimum allocation to integer overflow is: + * factor decimal growths + * 3/2 1.5 51 + * 8/5 1.6 45 + * 21/13 1.615... 44 * - * The limit to avoid overflow is spot on. The modulo three correction term - * ensures that the limit is the largest number than can be expanded by the - * growth factor without exceeding the hard limit. + * All larger factors have the same number of growths. * - * Do not call it with |current| lower than 2, or it will infinitely loop. + * 3/2 and 8/5 have nice power of two shifts, so seem like a good choice. */ static ossl_inline int compute_growth(int target, int current) { - const int limit = (max_nodes / 3) * 2 + (max_nodes % 3 ? 1 : 0); + int err = 0; while (current < target) { - /* Check to see if we're at the hard limit */ if (current >= max_nodes) return 0; - /* Expand the size by a factor of 3/2 if it is within range */ - current = current < limit ? current + current / 2 : max_nodes; + current = safe_muldiv_int(current, 8, 5, &err); + if (err != 0) + return 0; + if (current >= max_nodes) + current = max_nodes; } return current; } @@ -192,10 +196,8 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) * At this point, |st->num_alloc| and |st->num| are 0; * so |num_alloc| value is |n| or |min_nodes| if greater than |n|. */ - if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) return 0; - } st->num_alloc = num_alloc; return 1; } @@ -213,10 +215,8 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) } tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc); - if (tmpdata == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (tmpdata == NULL) return 0; - } st->data = tmpdata; st->num_alloc = num_alloc; @@ -227,10 +227,8 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) { OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK)); - if (st == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (st == NULL) return NULL; - } st->comp = c; @@ -317,39 +315,54 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc) } static int internal_find(OPENSSL_STACK *st, const void *data, - int ret_val_options, int *pnum) + int ret_val_options, int *pnum_matched) { const void *r; - int i; + int i, count = 0; + int *pnum = pnum_matched; if (st == NULL || st->num == 0) return -1; + if (pnum == NULL) + pnum = &count; + if (st->comp == NULL) { for (i = 0; i < st->num; i++) if (st->data[i] == data) { - if (pnum != NULL) - *pnum = 1; + *pnum = 1; return i; } - if (pnum != NULL) - *pnum = 0; + *pnum = 0; return -1; } - if (!st->sorted) { - if (st->num > 1) - qsort(st->data, st->num, sizeof(void *), st->comp); - st->sorted = 1; /* empty or single-element stack is considered sorted */ - } if (data == NULL) return -1; - if (pnum != NULL) + + if (!st->sorted) { + int res = -1; + + for (i = 0; i < st->num; i++) + if (st->comp(&data, st->data + i) == 0) { + if (res == -1) + res = i; + ++*pnum; + /* Check if only one result is wanted and exit if so */ + if (pnum_matched == NULL) + return i; + } + if (res == -1) + *pnum = 0; + return res; + } + + if (pnum_matched != NULL) ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH; r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp, ret_val_options); - if (pnum != NULL) { + if (pnum_matched != NULL) { *pnum = 0; if (r != NULL) { const void **p = (const void **)r; diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index b14db063f8..05a8044f89 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -66,6 +66,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, OSSL_STORE_post_process_info_fn post_process, void *post_process_data) { + struct ossl_passphrase_data_st pwdata = { 0 }; const OSSL_STORE_LOADER *loader = NULL; OSSL_STORE_LOADER *fetched_loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; @@ -94,7 +95,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, if ((p = strchr(scheme_copy, ':')) != NULL) { *p++ = '\0'; if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) { - if (strncmp(p, "//", 2) == 0) + if (HAS_PREFIX(p, "//")) schemes_n--; /* Invalidate the file scheme */ schemes[schemes_n++] = scheme_copy; } @@ -102,6 +103,13 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, ERR_set_mark(); + if (ui_method != NULL + && (!ossl_pw_set_ui_method(&pwdata, ui_method, ui_data) + || !ossl_pw_enable_passphrase_caching(&pwdata))) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + goto err; + } + /* * Try each scheme until we find one that could open the URI. * @@ -135,17 +143,28 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); no_loader_found = 0; - loader_ctx = fetched_loader->p_open(provctx, uri); + if (fetched_loader->p_open_ex != NULL) { + loader_ctx = + fetched_loader->p_open_ex(provctx, uri, params, + ossl_pw_passphrase_callback_dec, + &pwdata); + } else { + loader_ctx = fetched_loader->p_open(provctx, uri); + if (loader_ctx != NULL && + !loader_set_params(fetched_loader, loader_ctx, + params, propq)) { + (void)fetched_loader->p_close(loader_ctx); + loader_ctx = NULL; + } + } if (loader_ctx == NULL) { OSSL_STORE_LOADER_free(fetched_loader); fetched_loader = NULL; - } else if(!loader_set_params(fetched_loader, loader_ctx, - params, propq)) { - (void)fetched_loader->p_close(loader_ctx); - OSSL_STORE_LOADER_free(fetched_loader); - fetched_loader = NULL; } loader = fetched_loader; + + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&pwdata); } } @@ -168,23 +187,16 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) - || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) goto err; - } - if (ui_method != NULL - && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data) - || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); - goto err; - } ctx->properties = propq_copy; ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; ctx->post_process = post_process; ctx->post_process_data = post_process_data; + ctx->pwdata = pwdata; /* * If the attempt to open with the 'file' scheme loader failed and the @@ -215,6 +227,8 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, */ (void)ossl_store_close_it(&tmpctx); } + /* Coverity false positive, the reference counting is confusing it */ + /* coverity[pass_freed_arg] */ OSSL_STORE_LOADER_free(fetched_loader); OPENSSL_free(propq_copy); OPENSSL_free(ctx); @@ -336,7 +350,7 @@ int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) } if ((bld = OSSL_PARAM_BLD_new()) == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); return 0; } @@ -480,6 +494,53 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) return v; } +int OSSL_STORE_delete(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[]) +{ + OSSL_STORE_LOADER *fetched_loader = NULL; + char scheme[256], *p; + int res = 0; + struct ossl_passphrase_data_st pwdata = {0}; + + OPENSSL_strlcpy(scheme, uri, sizeof(scheme)); + if ((p = strchr(scheme, ':')) != NULL) + *p++ = '\0'; + else /* We don't work without explicit scheme */ + return 0; + + if (ui_method != NULL + && (!ossl_pw_set_ui_method(&pwdata, ui_method, ui_data) + || !ossl_pw_enable_passphrase_caching(&pwdata))) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + return 0; + } + + OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); + fetched_loader = OSSL_STORE_LOADER_fetch(libctx, scheme, propq); + + if (fetched_loader != NULL && fetched_loader->p_delete != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_get0_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + + /* + * It's assumed that the loader's delete() method reports its own + * errors + */ + OSSL_TRACE1(STORE, "Performing URI delete %s\n", uri); + res = fetched_loader->p_delete(provctx, uri, params, + ossl_pw_passphrase_callback_dec, + &pwdata); + } + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&pwdata); + + OSSL_STORE_LOADER_free(fetched_loader); + + return res; +} + int OSSL_STORE_error(OSSL_STORE_CTX *ctx) { int ret = 1; @@ -560,7 +621,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); if (info == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return NULL; } @@ -586,7 +647,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); if (info == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return info; } @@ -595,7 +656,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); if (info == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return info; } @@ -604,7 +665,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); if (info == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return info; } @@ -613,7 +674,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); if (info == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return info; } @@ -622,7 +683,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); if (info == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_OSSL_STORE_LIB); return info; } @@ -650,13 +711,8 @@ const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) { - if (info->type == OSSL_STORE_INFO_NAME) { - char *ret = OPENSSL_strdup(info->_.name.name); - - if (ret == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); - return ret; - } + if (info->type == OSSL_STORE_INFO_NAME) + return OPENSSL_strdup(info->_.name.name); ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -670,14 +726,8 @@ const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) { - if (info->type == OSSL_STORE_INFO_NAME) { - char *ret = OPENSSL_strdup(info->_.name.desc - ? info->_.name.desc : ""); - - if (ret == NULL) - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); - return ret; - } + if (info->type == OSSL_STORE_INFO_NAME) + return OPENSSL_strdup(info->_.name.desc ? info->_.name.desc : ""); ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -856,10 +906,8 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) { OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); - if (search == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + if (search == NULL) return NULL; - } search->search_type = OSSL_STORE_SEARCH_BY_NAME; search->name = name; @@ -871,10 +919,8 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, { OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); - if (search == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + if (search == NULL) return NULL; - } search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; search->name = name; @@ -888,10 +934,8 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, { OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); - if (search == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + if (search == NULL) return NULL; - } if (digest != NULL && len != (size_t)EVP_MD_get_size(digest)) { ERR_raise_data(ERR_LIB_OSSL_STORE, @@ -913,10 +957,8 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) { OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); - if (search == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + if (search == NULL) return NULL; - } search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; search->string = (const unsigned char *)alias; @@ -1015,7 +1057,6 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { ERR_clear_last_mark(); - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -1033,7 +1074,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, ctx->post_process_data = post_process_data; /* - * ossl_store_get0_loader_int will raise an error if the loader for the + * ossl_store_get0_loader_int will raise an error if the loader for * the scheme cannot be retrieved. But if a loader was successfully * fetched then we remove this error from the error stack. */ diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h index fcf8e6c240..6ad79180a0 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -103,7 +103,6 @@ struct ossl_store_loader_st { const char *description; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_store_open_fn *p_open; OSSL_FUNC_store_attach_fn *p_attach; @@ -113,6 +112,8 @@ struct ossl_store_loader_st { OSSL_FUNC_store_eof_fn *p_eof; OSSL_FUNC_store_close_fn *p_close; OSSL_FUNC_store_export_object_fn *p_export_object; + OSSL_FUNC_store_delete_fn *p_delete; + OSSL_FUNC_store_open_ex_fn *p_open_ex; }; DEFINE_LHASH_OF_EX(OSSL_STORE_LOADER); diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c index ab1016853e..6ac8fd5f93 100644 --- a/crypto/store/store_meth.c +++ b/crypto/store/store_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,7 +21,7 @@ int OSSL_STORE_LOADER_up_ref(OSSL_STORE_LOADER *loader) int ref = 0; if (loader->prov != NULL) - CRYPTO_UP_REF(&loader->refcnt, &ref, loader->lock); + CRYPTO_UP_REF(&loader->refcnt, &ref); return 1; } @@ -30,11 +30,11 @@ void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader) if (loader != NULL && loader->prov != NULL) { int i; - CRYPTO_DOWN_REF(&loader->refcnt, &i, loader->lock); + CRYPTO_DOWN_REF(&loader->refcnt, &i); if (i > 0) return; ossl_provider_free(loader->prov); - CRYPTO_THREAD_lock_free(loader->lock); + CRYPTO_FREE_REF(&loader->refcnt); } OPENSSL_free(loader); } @@ -48,13 +48,12 @@ static OSSL_STORE_LOADER *new_loader(OSSL_PROVIDER *prov) OSSL_STORE_LOADER *loader; if ((loader = OPENSSL_zalloc(sizeof(*loader))) == NULL - || (loader->lock = CRYPTO_THREAD_lock_new()) == NULL) { + || !CRYPTO_NEW_REF(&loader->refcnt, 1)) { OPENSSL_free(loader); return NULL; } loader->prov = prov; ossl_provider_up_ref(prov); - loader->refcnt = 1; return loader; } @@ -220,6 +219,14 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, if (loader->p_export_object == NULL) loader->p_export_object = OSSL_FUNC_store_export_object(fns); break; + case OSSL_FUNC_STORE_DELETE: + if (loader->p_delete == NULL) + loader->p_delete = OSSL_FUNC_store_delete(fns); + break; + case OSSL_FUNC_STORE_OPEN_EX: + if (loader->p_open_ex == NULL) + loader->p_open_ex = OSSL_FUNC_store_open_ex(fns); + break; } } @@ -227,7 +234,7 @@ static void *loader_from_algorithm(int scheme_id, const OSSL_ALGORITHM *algodef, || loader->p_load == NULL || loader->p_eof == NULL || loader->p_close == NULL) { - /* Only set_ctx_params is optionaal */ + /* Only set_ctx_params is optional */ OSSL_STORE_LOADER_free(loader); ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); return NULL; diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c index 6fa7352ccd..6f73e19720 100644 --- a/crypto/store/store_register.c +++ b/crypto/store/store_register.c @@ -43,10 +43,8 @@ OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme) return NULL; } - if ((res = OPENSSL_zalloc(sizeof(*res))) == NULL) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + if ((res = OPENSSL_zalloc(sizeof(*res))) == NULL) return NULL; - } res->engine = e; res->scheme = scheme; @@ -191,7 +189,8 @@ int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) } if (!RUN_ONCE(®istry_init, do_registry_init)) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + /* Should this error be raised in do_registry_init()? */ + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); return 0; } if (!CRYPTO_THREAD_write_lock(registry_lock)) @@ -224,7 +223,8 @@ const OSSL_STORE_LOADER *ossl_store_get0_loader_int(const char *scheme) template.open_ex = NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + /* Should this error be raised in do_registry_init()? */ + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); return NULL; } if (!CRYPTO_THREAD_write_lock(registry_lock)) @@ -254,7 +254,8 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme) template.closefn = NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + /* Should this error be raised in do_registry_init()? */ + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); return NULL; } if (!CRYPTO_THREAD_write_lock(registry_lock)) diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c index ba718b05c4..27323ad2b0 100644 --- a/crypto/store/store_result.c +++ b/crypto/store/store_result.c @@ -629,7 +629,7 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, } EVP_PKEY_free(pkey); X509_free(cert); - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); OSSL_STORE_INFO_free(osi_pkey); OSSL_STORE_INFO_free(osi_cert); OSSL_STORE_INFO_free(osi_ca); diff --git a/crypto/thread/api.c b/crypto/thread/api.c new file mode 100644 index 0000000000..e025d24cea --- /dev/null +++ b/crypto/thread/api.c @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +uint32_t OSSL_get_thread_support_flags(void) +{ + int support = 0; + +#if !defined(OPENSSL_NO_THREAD_POOL) + support |= OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL; +#endif +#if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL) + support |= OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN; +#endif + + return support; +} + +#if defined(OPENSSL_NO_THREAD_POOL) || defined(OPENSSL_NO_DEFAULT_THREAD_POOL) + +int OSSL_set_max_threads(OSSL_LIB_CTX *ctx, uint64_t max_threads) +{ + return 0; +} + +uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx) +{ + return 0; +} + +#else + +uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx) +{ + uint64_t ret = 0; + OSSL_LIB_CTX_THREADS *tdata = OSSL_LIB_CTX_GET_THREADS(ctx); + + if (tdata == NULL) + goto fail; + + ossl_crypto_mutex_lock(tdata->lock); + ret = tdata->max_threads; + ossl_crypto_mutex_unlock(tdata->lock); + +fail: + return ret; +} + +int OSSL_set_max_threads(OSSL_LIB_CTX *ctx, uint64_t max_threads) +{ + OSSL_LIB_CTX_THREADS *tdata; + + tdata = OSSL_LIB_CTX_GET_THREADS(ctx); + if (tdata == NULL) + return 0; + + ossl_crypto_mutex_lock(tdata->lock); + tdata->max_threads = max_threads; + ossl_crypto_mutex_unlock(tdata->lock); + + return 1; +} + +#endif diff --git a/crypto/thread/arch.c b/crypto/thread/arch.c new file mode 100644 index 0000000000..7c139a6a60 --- /dev/null +++ b/crypto/thread/arch.c @@ -0,0 +1,132 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +CRYPTO_THREAD *ossl_crypto_thread_native_start(CRYPTO_THREAD_ROUTINE routine, + void *data, int joinable) +{ + CRYPTO_THREAD *handle; + + if (routine == NULL) + return NULL; + + handle = OPENSSL_zalloc(sizeof(*handle)); + if (handle == NULL) + return NULL; + + if ((handle->lock = ossl_crypto_mutex_new()) == NULL) + goto fail; + if ((handle->statelock = ossl_crypto_mutex_new()) == NULL) + goto fail; + if ((handle->condvar = ossl_crypto_condvar_new()) == NULL) + goto fail; + + handle->data = data; + handle->routine = routine; + handle->joinable = joinable; + + if (ossl_crypto_thread_native_spawn(handle) == 1) + return handle; + +fail: + ossl_crypto_condvar_free(&handle->condvar); + ossl_crypto_mutex_free(&handle->statelock); + ossl_crypto_mutex_free(&handle->lock); + OPENSSL_free(handle); + return NULL; +} + +int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval) +{ + uint64_t req_state_mask; + + if (thread == NULL) + return 0; + + ossl_crypto_mutex_lock(thread->statelock); + req_state_mask = CRYPTO_THREAD_FINISHED | CRYPTO_THREAD_JOINED; + while (!CRYPTO_THREAD_GET_STATE(thread, req_state_mask)) + ossl_crypto_condvar_wait(thread->condvar, thread->statelock); + + if (CRYPTO_THREAD_GET_STATE(thread, CRYPTO_THREAD_JOINED)) + goto pass; + + /* Await concurrent join completion, if any. */ + while (CRYPTO_THREAD_GET_STATE(thread, CRYPTO_THREAD_JOIN_AWAIT)) { + if (!CRYPTO_THREAD_GET_STATE(thread, CRYPTO_THREAD_JOINED)) + ossl_crypto_condvar_wait(thread->condvar, thread->statelock); + if (CRYPTO_THREAD_GET_STATE(thread, CRYPTO_THREAD_JOINED)) + goto pass; + } + CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_JOIN_AWAIT); + ossl_crypto_mutex_unlock(thread->statelock); + + if (ossl_crypto_thread_native_perform_join(thread, retval) == 0) + goto fail; + + ossl_crypto_mutex_lock(thread->statelock); +pass: + CRYPTO_THREAD_UNSET_ERROR(thread, CRYPTO_THREAD_JOINED); + CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_JOINED); + + /* + * Signal join completion. It is important to signal even if we haven't + * performed an actual join. Multiple threads could be awaiting the + * CRYPTO_THREAD_JOIN_AWAIT -> CRYPTO_THREAD_JOINED transition, but signal + * on actual join would wake only one. Signalling here will always wake one. + */ + ossl_crypto_condvar_signal(thread->condvar); + ossl_crypto_mutex_unlock(thread->statelock); + + if (retval != NULL) + *retval = thread->retval; + return 1; + +fail: + ossl_crypto_mutex_lock(thread->statelock); + CRYPTO_THREAD_SET_ERROR(thread, CRYPTO_THREAD_JOINED); + + /* Have another thread that's awaiting join retry to avoid that + * thread deadlock. */ + CRYPTO_THREAD_UNSET_STATE(thread, CRYPTO_THREAD_JOIN_AWAIT); + ossl_crypto_condvar_signal(thread->condvar); + + ossl_crypto_mutex_unlock(thread->statelock); + return 0; +} + +int ossl_crypto_thread_native_clean(CRYPTO_THREAD *handle) +{ + uint64_t req_state_mask; + + if (handle == NULL) + return 0; + + req_state_mask = 0; + req_state_mask |= CRYPTO_THREAD_FINISHED; + req_state_mask |= CRYPTO_THREAD_JOINED; + + ossl_crypto_mutex_lock(handle->statelock); + if (CRYPTO_THREAD_GET_STATE(handle, req_state_mask) == 0) { + ossl_crypto_mutex_unlock(handle->statelock); + return 0; + } + ossl_crypto_mutex_unlock(handle->statelock); + + ossl_crypto_mutex_free(&handle->lock); + ossl_crypto_mutex_free(&handle->statelock); + ossl_crypto_condvar_free(&handle->condvar); + + OPENSSL_free(handle->handle); + OPENSSL_free(handle); + + return 1; +} diff --git a/crypto/thread/arch/thread_none.c b/crypto/thread/arch/thread_none.c new file mode 100644 index 0000000000..10a804f1b7 --- /dev/null +++ b/crypto/thread/arch/thread_none.c @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#if defined(OPENSSL_THREADS_NONE) + +int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread) +{ + return 0; +} + +int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval) +{ + return 0; +} + +int ossl_crypto_thread_native_exit(void) +{ + return 0; +} + +int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread) +{ + return 0; +} + +CRYPTO_MUTEX *ossl_crypto_mutex_new(void) +{ + return NULL; +} + +void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex) +{ +} + +int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex) +{ + return 0; +} + +void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex) +{ +} + +void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex) +{ +} + +CRYPTO_CONDVAR *ossl_crypto_condvar_new(void) +{ + return NULL; +} + +void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex) +{ +} + +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline) +{ +} + +void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv) +{ +} + +void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv) +{ +} + +void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv) +{ +} + +#endif diff --git a/crypto/thread/arch/thread_posix.c b/crypto/thread/arch/thread_posix.c new file mode 100644 index 0000000000..7650ddc85a --- /dev/null +++ b/crypto/thread/arch/thread_posix.c @@ -0,0 +1,233 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#if defined(OPENSSL_THREADS_POSIX) +# define _GNU_SOURCE +# include +# include +# include + +static void *thread_start_thunk(void *vthread) +{ + CRYPTO_THREAD *thread; + CRYPTO_THREAD_RETVAL ret; + + thread = (CRYPTO_THREAD *)vthread; + + ret = thread->routine(thread->data); + ossl_crypto_mutex_lock(thread->statelock); + CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_FINISHED); + thread->retval = ret; + ossl_crypto_condvar_broadcast(thread->condvar); + ossl_crypto_mutex_unlock(thread->statelock); + + return NULL; +} + +int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread) +{ + int ret; + pthread_attr_t attr; + pthread_t *handle; + + handle = OPENSSL_zalloc(sizeof(*handle)); + if (handle == NULL) + goto fail; + + pthread_attr_init(&attr); + if (!thread->joinable) + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret = pthread_create(handle, &attr, thread_start_thunk, thread); + pthread_attr_destroy(&attr); + + if (ret != 0) + goto fail; + + thread->handle = handle; + return 1; + +fail: + thread->handle = NULL; + OPENSSL_free(handle); + return 0; +} + +int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval) +{ + void *thread_retval; + pthread_t *handle; + + if (thread == NULL || thread->handle == NULL) + return 0; + + handle = (pthread_t *) thread->handle; + if (pthread_join(*handle, &thread_retval) != 0) + return 0; + + /* + * Join return value may be non-NULL when the thread has been cancelled, + * as indicated by thread_retval set to PTHREAD_CANCELLED. + */ + if (thread_retval != NULL) + return 0; + + return 1; +} + +int ossl_crypto_thread_native_exit(void) +{ + pthread_exit(NULL); + return 1; +} + +int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread) +{ + return pthread_equal(*(pthread_t *)thread->handle, pthread_self()); +} + +CRYPTO_MUTEX *ossl_crypto_mutex_new(void) +{ + pthread_mutex_t *mutex; + + if ((mutex = OPENSSL_zalloc(sizeof(*mutex))) == NULL) + return NULL; + if (pthread_mutex_init(mutex, NULL) != 0) { + OPENSSL_free(mutex); + return NULL; + } + return (CRYPTO_MUTEX *)mutex; +} + +int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex) +{ + pthread_mutex_t *mutex_p; + + mutex_p = (pthread_mutex_t *)mutex; + + if (pthread_mutex_trylock(mutex_p) == EBUSY) + return 0; + + return 1; +} + +void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex) +{ + int rc; + pthread_mutex_t *mutex_p; + + mutex_p = (pthread_mutex_t *)mutex; + rc = pthread_mutex_lock(mutex_p); + OPENSSL_assert(rc == 0); +} + +void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex) +{ + int rc; + pthread_mutex_t *mutex_p; + + mutex_p = (pthread_mutex_t *)mutex; + rc = pthread_mutex_unlock(mutex_p); + OPENSSL_assert(rc == 0); +} + +void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex) +{ + pthread_mutex_t **mutex_p; + + if (mutex == NULL) + return; + + mutex_p = (pthread_mutex_t **)mutex; + if (*mutex_p != NULL) + pthread_mutex_destroy(*mutex_p); + OPENSSL_free(*mutex_p); + *mutex = NULL; +} + +CRYPTO_CONDVAR *ossl_crypto_condvar_new(void) +{ + pthread_cond_t *cv_p; + + if ((cv_p = OPENSSL_zalloc(sizeof(*cv_p))) == NULL) + return NULL; + if (pthread_cond_init(cv_p, NULL) != 0) { + OPENSSL_free(cv_p); + return NULL; + } + return (CRYPTO_CONDVAR *) cv_p; +} + +void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex) +{ + pthread_cond_t *cv_p; + pthread_mutex_t *mutex_p; + + cv_p = (pthread_cond_t *)cv; + mutex_p = (pthread_mutex_t *)mutex; + pthread_cond_wait(cv_p, mutex_p); +} + +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline) +{ + pthread_cond_t *cv_p = (pthread_cond_t *)cv; + pthread_mutex_t *mutex_p = (pthread_mutex_t *)mutex; + + if (ossl_time_is_infinite(deadline)) { + /* + * No deadline. Some pthread implementations allow + * pthread_cond_timedwait to work the same as pthread_cond_wait when + * abstime is NULL, but it is unclear whether this is POSIXly correct. + */ + pthread_cond_wait(cv_p, mutex_p); + } else { + struct timespec deadline_ts; + + deadline_ts.tv_sec + = ossl_time2seconds(deadline); + deadline_ts.tv_nsec + = (ossl_time2ticks(deadline) % OSSL_TIME_SECOND) / OSSL_TIME_NS; + + pthread_cond_timedwait(cv_p, mutex_p, &deadline_ts); + } +} + +void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv) +{ + pthread_cond_t *cv_p; + + cv_p = (pthread_cond_t *)cv; + pthread_cond_broadcast(cv_p); +} + +void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv) +{ + pthread_cond_t *cv_p; + + cv_p = (pthread_cond_t *)cv; + pthread_cond_signal(cv_p); +} + +void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv) +{ + pthread_cond_t **cv_p; + + if (cv == NULL) + return; + + cv_p = (pthread_cond_t **)cv; + if (*cv_p != NULL) + pthread_cond_destroy(*cv_p); + OPENSSL_free(*cv_p); + *cv_p = NULL; +} + +#endif diff --git a/crypto/thread/arch/thread_win.c b/crypto/thread/arch/thread_win.c new file mode 100644 index 0000000000..fc0c214770 --- /dev/null +++ b/crypto/thread/arch/thread_win.c @@ -0,0 +1,599 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#if defined(OPENSSL_THREADS_WINNT) +# include +# include + +static unsigned __stdcall thread_start_thunk(LPVOID vthread) +{ + CRYPTO_THREAD *thread; + CRYPTO_THREAD_RETVAL ret; + + thread = (CRYPTO_THREAD *)vthread; + + thread->thread_id = GetCurrentThreadId(); + + ret = thread->routine(thread->data); + ossl_crypto_mutex_lock(thread->statelock); + CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_FINISHED); + thread->retval = ret; + ossl_crypto_condvar_signal(thread->condvar); + ossl_crypto_mutex_unlock(thread->statelock); + + return 0; +} + +int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread) +{ + HANDLE *handle; + + handle = OPENSSL_zalloc(sizeof(*handle)); + if (handle == NULL) + goto fail; + + *handle = (HANDLE)_beginthreadex(NULL, 0, &thread_start_thunk, thread, 0, NULL); + if (*handle == NULL) + goto fail; + + thread->handle = handle; + return 1; + +fail: + thread->handle = NULL; + OPENSSL_free(handle); + return 0; +} + +int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval) +{ + DWORD thread_retval; + HANDLE *handle; + + if (thread == NULL || thread->handle == NULL) + return 0; + + handle = (HANDLE *) thread->handle; + if (WaitForSingleObject(*handle, INFINITE) != WAIT_OBJECT_0) + return 0; + + if (GetExitCodeThread(*handle, &thread_retval) == 0) + return 0; + + /* + * GetExitCodeThread call followed by this check is to make sure that + * the thread exited properly. In particular, thread_retval may be + * non-zero when exited via explicit ExitThread/TerminateThread or + * if the thread is still active (returns STILL_ACTIVE (259)). + */ + if (thread_retval != 0) + return 0; + + if (CloseHandle(*handle) == 0) + return 0; + + return 1; +} + +int ossl_crypto_thread_native_exit(void) +{ + _endthreadex(0); + return 1; +} + +int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread) +{ + return thread->thread_id == GetCurrentThreadId(); +} + +CRYPTO_MUTEX *ossl_crypto_mutex_new(void) +{ + CRITICAL_SECTION *mutex; + + if ((mutex = OPENSSL_zalloc(sizeof(*mutex))) == NULL) + return NULL; + InitializeCriticalSection(mutex); + return (CRYPTO_MUTEX *)mutex; +} + +void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex) +{ + CRITICAL_SECTION *mutex_p; + + mutex_p = (CRITICAL_SECTION *)mutex; + EnterCriticalSection(mutex_p); +} + +int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex) +{ + CRITICAL_SECTION *mutex_p; + + mutex_p = (CRITICAL_SECTION *)mutex; + if (TryEnterCriticalSection(mutex_p)) + return 1; + + return 0; +} + +void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex) +{ + CRITICAL_SECTION *mutex_p; + + mutex_p = (CRITICAL_SECTION *)mutex; + LeaveCriticalSection(mutex_p); +} + +void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex) +{ + CRITICAL_SECTION **mutex_p; + + mutex_p = (CRITICAL_SECTION **)mutex; + if (*mutex_p != NULL) + DeleteCriticalSection(*mutex_p); + OPENSSL_free(*mutex_p); + *mutex = NULL; +} + +static int determine_timeout(OSSL_TIME deadline, DWORD *w_timeout_p) +{ + OSSL_TIME now, delta; + uint64_t ms; + + if (ossl_time_is_infinite(deadline)) { + *w_timeout_p = INFINITE; + return 1; + } + + now = ossl_time_now(); + delta = ossl_time_subtract(deadline, now); + + if (ossl_time_is_zero(delta)) + return 0; + + ms = ossl_time2ms(delta); + + /* + * Amount of time we want to wait is too long for the 32-bit argument to + * the Win32 API, so just wait as long as possible. + */ + if (ms > (uint64_t)(INFINITE - 1)) + *w_timeout_p = INFINITE - 1; + else + *w_timeout_p = (DWORD)ms; + + return 1; +} + +# if defined(OPENSSL_THREADS_WINNT_LEGACY) +# include + +/* + * Win32, before Vista, did not have an OS-provided condition variable + * construct. This leads to the need to construct our own condition variable + * construct in order to support Windows XP. + * + * It is difficult to construct a condition variable construct using the + * OS-provided primitives in a way that is both correct (avoiding race + * conditions where broadcasts get lost) and fair. + * + * CORRECTNESS: + * A blocked thread is a thread which is calling wait(), between the + * precise instants at which the external mutex passed to wait() is + * unlocked and the instant at which it is relocked. + * + * a) + * - If broadcast() is called, ALL blocked threads MUST be unblocked. + * - If signal() is called, at least one blocked thread MUST be unblocked. + * + * (i.e.: a signal or broadcast must never get 'lost') + * + * b) + * - If broadcast() or signal() is called, this must not cause a thread + * which is not blocked to return immediately from a subsequent + * call to wait(). + * + * FAIRNESS: + * If broadcast() is called at time T1, all blocked threads must be unblocked + * before any thread which subsequently calls wait() at time T2 > T1 is + * unblocked. + * + * An example of an implementation which lacks fairness is as follows: + * + * t1 enters wait() + * t2 enters wait() + * + * tZ calls broadcast() + * + * t1 exits wait() + * t1 enters wait() + * + * tZ calls broadcast() + * + * t1 exits wait() + * + * IMPLEMENTATION: + * + * The most suitable primitives available to us in Windows XP are semaphores, + * auto-reset events and manual-reset events. A solution based on semaphores + * is chosen. + * + * PROBLEM. Designing a solution based on semaphores is non-trivial because, + * while it is easy to track the number of waiters in an interlocked data + * structure and then add that number to the semaphore, this does not + * guarantee fairness or correctness. Consider the following situation: + * + * - t1 enters wait(), adding 1 to the wait counter & blocks on the semaphore + * - t2 enters wait(), adding 1 to the wait counter & blocks on the semaphore + * - tZ calls broadcast(), finds the wait counter is 2, adds 2 to the semaphore + * + * - t1 exits wait() + * - t1 immediately reenters wait() and blocks on the semaphore + * - The semaphore is still positive due to also having been signalled + * for t2, therefore it is decremented + * - t1 exits wait() immediately; t2 is never woken + * + * GENERATION COUNTERS. One naive solution to this is to use a generation + * counter. Each broadcast() invocation increments a generation counter. If + * the generation counter has not changed during a semaphore wait operation + * inside wait(), this indicates that no broadcast() call has been made in + * the meantime; therefore, the successful semaphore decrement must have + * 'stolen' a wakeup from another thread which was waiting to wakeup from the + * prior broadcast() call but which had not yet had a chance to do so. The + * semaphore can then be reincremented and the wait() operation repeated. + * + * However, this suffers from the obvious problem that without OS guarantees + * as to how semaphore readiness events are distributed amongst threads, + * there is no particular guarantee that the semaphore readiness event will + * not be immediately redistributed back to the same thread t1. + * + * SOLUTION. A solution is chosen as follows. In its initial state, a + * condition variable can accept waiters, who wait for the semaphore + * normally. However, once broadcast() is called, the condition + * variable becomes 'closed'. Any existing blocked threads are unblocked, + * but any new calls to wait() will instead enter a blocking pre-wait stage. + * Pre-wait threads are not considered to be waiting (and the external + * mutex remains held). A call to wait() in pre-wait cannot progress + * to waiting until all threads due to be unblocked by the prior broadcast() + * call have returned and had a chance to execute. + * + * This pre-wait does not affect a thread if it does not call wait() + * again until after all threads have had a chance to execute. + * + * RESOURCE USAGE. Aside from an allocation for the condition variable + * structure, this solution uses two Win32 semaphores. + * + * FUTURE OPTIMISATIONS: + * + * An optimised multi-generation implementation is possible at the cost of + * higher Win32 resource usage. Multiple 'buckets' could be defined, with + * usage rotating between buckets internally as buckets become closed. + * This would avoid the need for the prewait in more cases, depending + * on intensity of usage. + * + */ +typedef struct legacy_condvar_st { + CRYPTO_MUTEX *int_m; /* internal mutex */ + HANDLE sema; /* main wait semaphore */ + HANDLE prewait_sema; /* prewait semaphore */ + /* + * All of the following fields are protected by int_m. + * + * num_wake only ever increases by virtue of a corresponding decrease in + * num_wait. num_wait can decrease for other reasons (for example due to a + * wait operation timing out). + */ + size_t num_wait; /* Num. threads currently blocked */ + size_t num_wake; /* Num. threads due to wake up */ + size_t num_prewait; /* Num. threads in prewait */ + size_t gen; /* Prewait generation */ + int closed; /* Is closed? */ +} LEGACY_CONDVAR; + +CRYPTO_CONDVAR *ossl_crypto_condvar_new(void) +{ + LEGACY_CONDVAR *cv; + + if ((cv = OPENSSL_malloc(sizeof(LEGACY_CONDVAR))) == NULL) + return NULL; + + if ((cv->int_m = ossl_crypto_mutex_new()) == NULL) { + OPENSSL_free(cv); + return NULL; + } + + if ((cv->sema = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL)) == NULL) { + ossl_crypto_mutex_free(&cv->int_m); + OPENSSL_free(cv); + return NULL; + } + + if ((cv->prewait_sema = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL)) == NULL) { + CloseHandle(cv->sema); + ossl_crypto_mutex_free(&cv->int_m); + OPENSSL_free(cv); + return NULL; + } + + cv->num_wait = 0; + cv->num_wake = 0; + cv->num_prewait = 0; + cv->closed = 0; + + return (CRYPTO_CONDVAR *)cv; +} + +void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv_p) +{ + if (*cv_p != NULL) { + LEGACY_CONDVAR *cv = *(LEGACY_CONDVAR **)cv_p; + + CloseHandle(cv->sema); + CloseHandle(cv->prewait_sema); + ossl_crypto_mutex_free(&cv->int_m); + OPENSSL_free(cv); + } + + *cv_p = NULL; +} + +static uint32_t obj_wait(HANDLE h, OSSL_TIME deadline) +{ + DWORD timeout; + + if (!determine_timeout(deadline, &timeout)) + timeout = 1; + + return WaitForSingleObject(h, timeout); +} + +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv_, CRYPTO_MUTEX *ext_m, + OSSL_TIME deadline) +{ + LEGACY_CONDVAR *cv = (LEGACY_CONDVAR *)cv_; + int closed, set_prewait = 0, have_orig_gen = 0; + uint32_t rc; + size_t orig_gen; + + /* Admission control - prewait until we can enter our actual wait phase. */ + do { + ossl_crypto_mutex_lock(cv->int_m); + + closed = cv->closed; + + /* + * Once prewait is over the prewait semaphore is signalled and + * num_prewait is set to 0. Use a generation counter to track if we need + * to remove a value we added to num_prewait when exiting (e.g. due to + * timeout or failure of WaitForSingleObject). + */ + if (!have_orig_gen) { + orig_gen = cv->gen; + have_orig_gen = 1; + } else if (cv->gen != orig_gen) { + set_prewait = 0; + orig_gen = cv->gen; + } + + if (!closed) { + /* We can now be admitted. */ + ++cv->num_wait; + if (set_prewait) { + --cv->num_prewait; + set_prewait = 0; + } + } else if (!set_prewait) { + ++cv->num_prewait; + set_prewait = 1; + } + + ossl_crypto_mutex_unlock(cv->int_m); + + if (closed) + if (obj_wait(cv->prewait_sema, deadline) != WAIT_OBJECT_0) { + /* + * If we got WAIT_OBJECT_0 we are safe - num_prewait has been + * set to 0 and the semaphore has been consumed. On the other + * hand if we timed out, there may be a residual posting that + * was made just after we timed out. However in the worst case + * this will just cause an internal spurious wakeup here in the + * future, so we do not care too much about this. We treat + * failure and timeout cases as the same, and simply exit in + * this case. + */ + ossl_crypto_mutex_lock(cv->int_m); + if (set_prewait && cv->gen == orig_gen) + --cv->num_prewait; + ossl_crypto_mutex_unlock(cv->int_m); + return; + } + } while (closed); + + /* + * Unlock external mutex. Do not do this until we have been admitted, as we + * must guarantee we wake if broadcast is called at any time after ext_m is + * unlocked. + */ + ossl_crypto_mutex_unlock(ext_m); + + for (;;) { + /* Wait. */ + rc = obj_wait(cv->sema, deadline); + + /* Reacquire internal mutex and probe state. */ + ossl_crypto_mutex_lock(cv->int_m); + + if (cv->num_wake > 0) { + /* + * A wake token is available, so we can wake up. Consume the token + * and get out of here. We don't care what WaitForSingleObject + * returned here (e.g. if it timed out coincidentally). In the + * latter case a signal might be left in the semaphore which causes + * a future WaitForSingleObject call to return immediately, but in + * this case we will just loop again. + */ + --cv->num_wake; + if (cv->num_wake == 0 && cv->closed) { + /* + * We consumed the last wake token, so we can now open the + * condition variable for new admissions. + */ + cv->closed = 0; + if (cv->num_prewait > 0) { + ReleaseSemaphore(cv->prewait_sema, (LONG)cv->num_prewait, NULL); + cv->num_prewait = 0; + ++cv->gen; + } + } + } else if (rc == WAIT_OBJECT_0) { + /* + * We got a wakeup from the semaphore but we did not have any wake + * tokens. This ideally does not happen, but might if during a + * previous wait() call the semaphore is posted just after + * WaitForSingleObject returns due to a timeout (such that the + * num_wake > 0 case is taken above). Just spin again. (It is worth + * noting that repeated WaitForSingleObject calls is the only method + * documented for decrementing a Win32 semaphore, so this is + * basically the best possible strategy.) + */ + ossl_crypto_mutex_unlock(cv->int_m); + continue; + } else { + /* + * Assume we timed out. The WaitForSingleObject call may also have + * failed for some other reason, which we treat as a timeout. + */ + assert(cv->num_wait > 0); + --cv->num_wait; + } + + break; + } + + ossl_crypto_mutex_unlock(cv->int_m); + ossl_crypto_mutex_lock(ext_m); +} + +void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *ext_m) +{ + ossl_crypto_condvar_wait_timeout(cv, ext_m, ossl_time_infinite()); +} + +void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv_) +{ + LEGACY_CONDVAR *cv = (LEGACY_CONDVAR *)cv_; + size_t num_wake; + + ossl_crypto_mutex_lock(cv->int_m); + + num_wake = cv->num_wait; + if (num_wake == 0) { + ossl_crypto_mutex_unlock(cv->int_m); + return; + } + + cv->num_wake += num_wake; + cv->num_wait -= num_wake; + cv->closed = 1; + + ossl_crypto_mutex_unlock(cv->int_m); + ReleaseSemaphore(cv->sema, num_wake, NULL); +} + +void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv_) +{ + LEGACY_CONDVAR *cv = (LEGACY_CONDVAR *)cv_; + + ossl_crypto_mutex_lock(cv->int_m); + + if (cv->num_wait == 0) { + ossl_crypto_mutex_unlock(cv->int_m); + return; + } + + /* + * We do not close the condition variable when merely signalling, as there + * are no guaranteed fairness semantics here, unlike for a broadcast. + */ + --cv->num_wait; + ++cv->num_wake; + + ossl_crypto_mutex_unlock(cv->int_m); + ReleaseSemaphore(cv->sema, 1, NULL); +} + +# else + +CRYPTO_CONDVAR *ossl_crypto_condvar_new(void) +{ + CONDITION_VARIABLE *cv_p; + + if ((cv_p = OPENSSL_zalloc(sizeof(*cv_p))) == NULL) + return NULL; + InitializeConditionVariable(cv_p); + return (CRYPTO_CONDVAR *)cv_p; +} + +void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex) +{ + CONDITION_VARIABLE *cv_p; + CRITICAL_SECTION *mutex_p; + + cv_p = (CONDITION_VARIABLE *)cv; + mutex_p = (CRITICAL_SECTION *)mutex; + SleepConditionVariableCS(cv_p, mutex_p, INFINITE); +} + +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline) +{ + DWORD timeout; + CONDITION_VARIABLE *cv_p = (CONDITION_VARIABLE *)cv; + CRITICAL_SECTION *mutex_p = (CRITICAL_SECTION *)mutex; + + if (!determine_timeout(deadline, &timeout)) + timeout = 1; + + SleepConditionVariableCS(cv_p, mutex_p, timeout); +} + +void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv) +{ + CONDITION_VARIABLE *cv_p; + + cv_p = (CONDITION_VARIABLE *)cv; + WakeAllConditionVariable(cv_p); +} + +void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv) +{ + CONDITION_VARIABLE *cv_p; + + cv_p = (CONDITION_VARIABLE *)cv; + WakeConditionVariable(cv_p); +} + +void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv) +{ + CONDITION_VARIABLE **cv_p; + + cv_p = (CONDITION_VARIABLE **)cv; + OPENSSL_free(*cv_p); + *cv_p = NULL; +} + +# endif + +void ossl_crypto_mem_barrier(void) +{ + MemoryBarrier(); +} + +#endif diff --git a/crypto/thread/build.info b/crypto/thread/build.info new file mode 100644 index 0000000000..191e25e20d --- /dev/null +++ b/crypto/thread/build.info @@ -0,0 +1,21 @@ +LIBS=../../libcrypto + +$THREADS_ARCH=\ + arch.c \ + arch/thread_win.c arch/thread_posix.c arch/thread_none.c + +IF[{- !$disabled{'thread-pool'} -}] + IF[{- !$disabled{quic} -}] + SHARED_SOURCE[../../libssl]=$THREADS_ARCH + ENDIF + $THREADS=\ + api.c internal.c $THREADS_ARCH +ELSE + IF[{- !$disabled{quic} -}] + SOURCE[../../libssl]=$THREADS_ARCH + ENDIF + $THREADS=api.c +ENDIF + +SOURCE[../../libcrypto]=$THREADS +SOURCE[../../providers/libfips.a]=$THREADS diff --git a/crypto/thread/internal.c b/crypto/thread/internal.c new file mode 100644 index 0000000000..61486c8d4d --- /dev/null +++ b/crypto/thread/internal.c @@ -0,0 +1,157 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL) + +static ossl_inline uint64_t _ossl_get_avail_threads(OSSL_LIB_CTX_THREADS *tdata) +{ + /* assumes that tdata->lock is taken */ + return tdata->max_threads - tdata->active_threads; +} + +uint64_t ossl_get_avail_threads(OSSL_LIB_CTX *ctx) +{ + uint64_t retval = 0; + OSSL_LIB_CTX_THREADS *tdata = OSSL_LIB_CTX_GET_THREADS(ctx); + + if (tdata == NULL) + return retval; + + ossl_crypto_mutex_lock(tdata->lock); + retval = _ossl_get_avail_threads(tdata); + ossl_crypto_mutex_unlock(tdata->lock); + + return retval; +} + +void *ossl_crypto_thread_start(OSSL_LIB_CTX *ctx, CRYPTO_THREAD_ROUTINE start, + void *data) +{ + CRYPTO_THREAD *thread; + OSSL_LIB_CTX_THREADS *tdata = OSSL_LIB_CTX_GET_THREADS(ctx); + + if (tdata == NULL) + return NULL; + + ossl_crypto_mutex_lock(tdata->lock); + if (tdata == NULL || tdata->max_threads == 0) { + ossl_crypto_mutex_unlock(tdata->lock); + return NULL; + } + + while (_ossl_get_avail_threads(tdata) == 0) + ossl_crypto_condvar_wait(tdata->cond_finished, tdata->lock); + tdata->active_threads++; + ossl_crypto_mutex_unlock(tdata->lock); + + thread = ossl_crypto_thread_native_start(start, data, 1); + if (thread == NULL) { + ossl_crypto_mutex_lock(tdata->lock); + tdata->active_threads--; + ossl_crypto_mutex_unlock(tdata->lock); + goto fail; + } + thread->ctx = ctx; + +fail: + return (void *) thread; +} + +int ossl_crypto_thread_join(void *vhandle, CRYPTO_THREAD_RETVAL *retval) +{ + CRYPTO_THREAD *handle = vhandle; + OSSL_LIB_CTX_THREADS *tdata; + + if (vhandle == NULL) + return 0; + + tdata = OSSL_LIB_CTX_GET_THREADS(handle->ctx); + if (tdata == NULL) + return 0; + + if (ossl_crypto_thread_native_join(handle, retval) == 0) + return 0; + + ossl_crypto_mutex_lock(tdata->lock); + tdata->active_threads--; + ossl_crypto_condvar_signal(tdata->cond_finished); + ossl_crypto_mutex_unlock(tdata->lock); + return 1; +} + +int ossl_crypto_thread_clean(void *vhandle) +{ + CRYPTO_THREAD *handle = vhandle; + + return ossl_crypto_thread_native_clean(handle); +} + +#else + +ossl_inline uint64_t ossl_get_avail_threads(OSSL_LIB_CTX *ctx) +{ + return 0; +} + +void *ossl_crypto_thread_start(OSSL_LIB_CTX *ctx, CRYPTO_THREAD_ROUTINE start, + void *data) +{ + return NULL; +} + +int ossl_crypto_thread_join(void *vhandle, CRYPTO_THREAD_RETVAL *retval) +{ + return 0; +} + +int ossl_crypto_thread_clean(void *vhandle) +{ + return 0; +} + +#endif + +void *ossl_threads_ctx_new(OSSL_LIB_CTX *ctx) +{ + struct openssl_threads_st *t = OPENSSL_zalloc(sizeof(*t)); + + if (t == NULL) + return NULL; + + t->lock = ossl_crypto_mutex_new(); + t->cond_finished = ossl_crypto_condvar_new(); + + if (t->lock == NULL || t->cond_finished == NULL) + goto fail; + + return t; + +fail: + ossl_threads_ctx_free((void *)t); + return NULL; +} + +void ossl_threads_ctx_free(void *vdata) +{ + OSSL_LIB_CTX_THREADS *t = (OSSL_LIB_CTX_THREADS *) vdata; + + if (t == NULL) + return; + + ossl_crypto_mutex_free(&t->lock); + ossl_crypto_condvar_free(&t->cond_finished); + OPENSSL_free(t); +} diff --git a/crypto/threads_lib.c b/crypto/threads_lib.c index 9859599257..240ef726ec 100644 --- a/crypto/threads_lib.c +++ b/crypto/threads_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/threads_none.c b/crypto/threads_none.c index 2570efde23..580e5345d2 100644 --- a/crypto/threads_none.c +++ b/crypto/threads_none.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,10 +21,9 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { CRYPTO_RWLOCK *lock; - if ((lock = OPENSSL_zalloc(sizeof(unsigned int))) == NULL) { + if ((lock = CRYPTO_zalloc(sizeof(unsigned int), NULL, 0)) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; - } *(unsigned int *)lock = 1; @@ -149,6 +148,13 @@ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) return 1; } +int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) +{ + *ret = *val; + + return 1; +} + int openssl_init_fork_handlers(void) { return 0; diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 801855c930..59ddcdbff8 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -47,10 +47,9 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) # ifdef USE_RWLOCK CRYPTO_RWLOCK *lock; - if ((lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t))) == NULL) { + if ((lock = CRYPTO_zalloc(sizeof(pthread_rwlock_t), NULL, 0)) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; - } if (pthread_rwlock_init(lock, NULL) != 0) { OPENSSL_free(lock); @@ -60,10 +59,9 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) pthread_mutexattr_t attr; CRYPTO_RWLOCK *lock; - if ((lock = OPENSSL_zalloc(sizeof(pthread_mutex_t))) == NULL) { + if ((lock = CRYPTO_zalloc(sizeof(pthread_mutex_t), NULL, 0)) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; - } /* * We don't use recursive mutexes, but try to catch errors if we do. @@ -270,6 +268,30 @@ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) return 1; } + +int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) +{ +# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) + if (__atomic_is_lock_free(sizeof(*val), val)) { + __atomic_load(val, ret, __ATOMIC_ACQUIRE); + return 1; + } +# elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) + /* This will work for all future Solaris versions. */ + if (ret != NULL) { + *ret = (int *)atomic_or_uint_nv((unsigned int *)val, 0); + return 1; + } +# endif + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) + return 0; + *ret = *val; + if (!CRYPTO_THREAD_unlock(lock)) + return 0; + + return 1; +} + # ifndef FIPS_MODULE int openssl_init_fork_handlers(void) { diff --git a/crypto/threads_win.c b/crypto/threads_win.c index dbeda74d73..4cdc62339d 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c @@ -43,16 +43,16 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) # ifdef USE_RWLOCK CRYPTO_win_rwlock *rwlock; - if ((lock = OPENSSL_zalloc(sizeof(CRYPTO_win_rwlock))) == NULL) + if ((lock = CRYPTO_zalloc(sizeof(CRYPTO_win_rwlock), NULL, 0)) == NULL) + /* Don't set error, to avoid recursion blowup. */ return NULL; rwlock = lock; InitializeSRWLock(&rwlock->lock); # else - if ((lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION))) == NULL) { + if ((lock = CRYPTO_zalloc(sizeof(CRITICAL_SECTION), NULL, 0)) == NULL) /* Don't set error, to avoid recursion blowup. */ return NULL; - } # if !defined(_WIN32_WCE) /* 0x400 is the spin count value suggested in the documentation */ @@ -251,6 +251,23 @@ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) #endif } +int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) +{ +#if (defined(NO_INTERLOCKEDOR64)) + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) + return 0; + *ret = *val; + if (!CRYPTO_THREAD_unlock(lock)) + return 0; + + return 1; +#else + /* On Windows, LONG is always the same size as int. */ + *ret = (int)InterlockedOr((LONG volatile *)val, 0); + return 1; +#endif +} + int openssl_init_fork_handlers(void) { return 0; diff --git a/crypto/time.c b/crypto/time.c new file mode 100644 index 0000000000..b0593a238b --- /dev/null +++ b/crypto/time.c @@ -0,0 +1,48 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/time.h" + +OSSL_TIME ossl_time_now(void) +{ + OSSL_TIME r; + +#if defined(_WIN32) && !defined(OPENSSL_SYS_UEFI) + SYSTEMTIME st; + union { + unsigned __int64 ul; + FILETIME ft; + } now; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &now.ft); + /* re-bias to 1/1/1970 */ +# ifdef __MINGW32__ + now.ul -= 116444736000000000ULL; +# else + now.ul -= 116444736000000000UI64; +# endif + r.t = ((uint64_t)now.ul) * (OSSL_TIME_SECOND / 10000000); +#else /* defined(_WIN32) */ + struct timeval t; + + if (gettimeofday(&t, NULL) < 0) { + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling gettimeofday()"); + return ossl_time_zero(); + } + if (t.tv_sec <= 0) + r.t = t.tv_usec <= 0 ? 0 : t.tv_usec * OSSL_TIME_US; + else + r.t = ((uint64_t)t.tv_sec * 1000000 + t.tv_usec) * OSSL_TIME_US; +#endif /* defined(_WIN32) */ + return r; +} diff --git a/crypto/trace.c b/crypto/trace.c index dc308d819d..51387641de 100644 --- a/crypto/trace.c +++ b/crypto/trace.c @@ -18,6 +18,7 @@ #include "internal/nelem.h" #include "internal/refcount.h" #include "crypto/cryptlib.h" +#include "crypto/ctype.h" #ifndef OPENSSL_NO_TRACE @@ -501,7 +502,7 @@ BIO *OSSL_trace_begin(int category) return channel; } -void OSSL_trace_end(int category, BIO * channel) +void OSSL_trace_end(int category, BIO *channel) { #ifndef OPENSSL_NO_TRACE char *suffix = NULL; @@ -530,3 +531,27 @@ void OSSL_trace_end(int category, BIO * channel) } #endif } + +int OSSL_trace_string(BIO *out, int text, int full, + const unsigned char *data, size_t size) +{ + unsigned char buf[OSSL_TRACE_STRING_MAX + 1]; + int len, i; + + if (!full && size > OSSL_TRACE_STRING_MAX) { + BIO_printf(out, "[len %zu limited to %d]: ", + size, OSSL_TRACE_STRING_MAX); + len = OSSL_TRACE_STRING_MAX; + } else { + len = (int)size; + } + if (!text) { /* mask control characters while preserving newlines */ + for (i = 0; i < len; i++, data++) + buf[i] = (char)*data != '\n' && ossl_iscntrl((int)*data) + ? ' ' : *data; + if (len == 0 || data[-1] != '\n') + buf[len++] = '\n'; + data = buf; + } + return BIO_printf(out, "%.*s", len, data); +} diff --git a/crypto/ts/ts_local.h b/crypto/ts/ts_local.h index 3265c762c6..b0dbd5fdd9 100644 --- a/crypto/ts/ts_local.h +++ b/crypto/ts/ts_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/txt_db/txt_db.c b/crypto/txt_db/txt_db.c index 2c1cbfb4f1..25fe9bf64b 100644 --- a/crypto/txt_db/txt_db.c +++ b/crypto/txt_db/txt_db.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -78,7 +78,6 @@ TXT_DB *TXT_DB_read(BIO *in, int num) p += add; n = 0; pp[n++] = p; - i = 0; f = buf->data; esc = 0; diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c index 2ddf76cb53..a8756af1cd 100644 --- a/crypto/ui/ui_lib.c +++ b/crypto/ui/ui_lib.c @@ -24,14 +24,12 @@ UI *UI_new_method(const UI_METHOD *method) { UI *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_CRYPTO_LIB); OPENSSL_free(ret); return NULL; } @@ -210,10 +208,8 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); - if (prompt_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (prompt_copy == NULL) return 0; - } } return general_allocate_string(ui, prompt_copy, 1, @@ -238,10 +234,8 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); - if (prompt_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (prompt_copy == NULL) return -1; - } } return general_allocate_string(ui, prompt_copy, 1, @@ -269,34 +263,26 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, if (prompt != NULL) { prompt_copy = OPENSSL_strdup(prompt); - if (prompt_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (prompt_copy == NULL) goto err; - } } if (action_desc != NULL) { action_desc_copy = OPENSSL_strdup(action_desc); - if (action_desc_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (action_desc_copy == NULL) goto err; - } } if (ok_chars != NULL) { ok_chars_copy = OPENSSL_strdup(ok_chars); - if (ok_chars_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (ok_chars_copy == NULL) goto err; - } } if (cancel_chars != NULL) { cancel_chars_copy = OPENSSL_strdup(cancel_chars); - if (cancel_chars_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (cancel_chars_copy == NULL) goto err; - } } return general_allocate_boolean(ui, prompt_copy, action_desc_copy, @@ -322,10 +308,8 @@ int UI_dup_info_string(UI *ui, const char *text) if (text != NULL) { text_copy = OPENSSL_strdup(text); - if (text_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (text_copy == NULL) return -1; - } } return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, @@ -344,10 +328,8 @@ int UI_dup_error_string(UI *ui, const char *text) if (text != NULL) { text_copy = OPENSSL_strdup(text); - if (text_copy == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if (text_copy == NULL) return -1; - } } return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, 0, 0, NULL); @@ -373,10 +355,8 @@ char *UI_construct_prompt(UI *ui, const char *phrase_desc, len += sizeof(prompt2) - 1 + strlen(object_name); len += sizeof(prompt3) - 1; - if ((prompt = OPENSSL_malloc(len + 1)) == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + if ((prompt = OPENSSL_malloc(len + 1)) == NULL) return NULL; - } OPENSSL_strlcpy(prompt, prompt1, len + 1); OPENSSL_strlcat(prompt, phrase_desc, len + 1); if (object_name != NULL) { @@ -413,7 +393,7 @@ int UI_dup_user_data(UI *ui, void *user_data) duplicate = ui->meth->ui_duplicate_data(ui, user_data); if (duplicate == NULL) { - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_UI, ERR_R_UI_LIB); return -1; } @@ -603,10 +583,17 @@ UI_METHOD *UI_create_method(const char *name) || (ui_method->name = OPENSSL_strdup(name)) == NULL || !CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI_METHOD, ui_method, &ui_method->ex_data)) { - if (ui_method) + + if (ui_method != NULL) { + if (ui_method->name != NULL) + /* + * These conditions indicate that the CRYPTO_new_ex_data() + * call failed. + */ + ERR_raise(ERR_LIB_UI, ERR_R_CRYPTO_LIB); OPENSSL_free(ui_method->name); + } OPENSSL_free(ui_method); - ERR_raise(ERR_LIB_UI, ERR_R_MALLOC_FAILURE); return NULL; } return ui_method; diff --git a/crypto/uid.c b/crypto/uid.c index 698127779f..45b63a431e 100644 --- a/crypto/uid.c +++ b/crypto/uid.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,7 +10,7 @@ #include #include -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI) +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI) || defined(__wasi__) int OPENSSL_issetugid(void) { diff --git a/crypto/x509/build.info b/crypto/x509/build.info index 8820f983bb..3f70f3ff36 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -14,7 +14,8 @@ SOURCE[../../libcrypto]=\ v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \ v3_pcia.c v3_pci.c v3_ist.c \ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ - v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c + v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_no_rev_avail.c \ + v3_soa_id.c v3_no_ass.c v3_group_ac.c v3_single_use.c v3_ind_iss.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x509type.c diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 63213ca2c8..1d401d0420 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -109,20 +109,18 @@ static int new_dir(X509_LOOKUP *lu) { BY_DIR *a = OPENSSL_malloc(sizeof(*a)); - if (a == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (a == NULL) return 0; - } if ((a->buffer = BUF_MEM_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_BN_LIB); goto err; } a->dirs = NULL; a->lock = CRYPTO_THREAD_lock_new(); if (a->lock == NULL) { BUF_MEM_free(a->buffer); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } lu->method_data = a; @@ -197,15 +195,13 @@ 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) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } } ent = OPENSSL_malloc(sizeof(*ent)); - if (ent == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (ent == NULL) return 0; - } ent->dir_type = type; ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); ent->dir = OPENSSL_strndup(ss, len); @@ -215,7 +211,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) } if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { by_dir_entry_free(ent); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } } @@ -272,7 +268,7 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; if (!BUF_MEM_grow(b, j)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); goto finish; } if (type == X509_LU_CRL && ent->hashes) { @@ -347,6 +343,9 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, /* * we have added it to the cache so now pull it out again + * + * Note: quadratic time find here since the objects won't generally be + * sorted and sorting the would result in O(n^2 log n) complexity. */ if (k > 0) { if (!X509_STORE_lock(xl->store_ctx)) @@ -355,7 +354,6 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); X509_STORE_unlock(xl->store_ctx); } else { - j = -1; tmp = NULL; } /* @@ -380,7 +378,6 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, hent = OPENSSL_malloc(sizeof(*hent)); if (hent == NULL) { CRYPTO_THREAD_unlock(ctx->lock); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -389,7 +386,7 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { CRYPTO_THREAD_unlock(ctx->lock); OPENSSL_free(hent); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); ok = 0; goto finish; } @@ -422,6 +419,14 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, } } finish: + /* If we changed anything, resort the objects for faster lookup */ + if (!sk_X509_OBJECT_is_sorted(xl->store_ctx->objs)) { + if (X509_STORE_lock(xl->store_ctx)) { + sk_X509_OBJECT_sort(xl->store_ctx->objs); + X509_STORE_unlock(xl->store_ctx); + } + } + BUF_MEM_free(b); return ok; } diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 37d73ca84c..450bbba053 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -58,15 +58,13 @@ static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, if (file) ok = (X509_load_cert_crl_file_ex(ctx, file, X509_FILETYPE_PEM, libctx, propq) != 0); - else ok = (X509_load_cert_crl_file_ex( ctx, X509_get_default_cert_file(), X509_FILETYPE_PEM, libctx, propq) != 0); - if (!ok) { + if (!ok) ERR_raise(ERR_LIB_X509, X509_R_LOADING_DEFAULTS); - } } else { if (argl == X509_FILETYPE_PEM) ok = (X509_load_cert_crl_file_ex(ctx, argp, X509_FILETYPE_PEM, @@ -89,25 +87,20 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, OSSL_LIB_CTX *libctx, const char *propq) { - int ret = 0; BIO *in = NULL; - int i, count = 0; + int count = 0; X509 *x = NULL; in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BIO_LIB); goto err; } - if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) { - ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); - goto err; - } x = X509_new_ex(libctx, propq); if (x == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } @@ -121,34 +114,36 @@ int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, break; } else { ERR_clear_last_mark(); + if (count == 0) { + ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND); + } else { + ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); + count = 0; + } goto err; } } ERR_clear_last_mark(); - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) + if (!X509_STORE_add_cert(ctx->store_ctx, x)) { + count = 0; goto err; + } count++; - X509_free(x); - x = NULL; } - ret = count; } else if (type == X509_FILETYPE_ASN1) { if (d2i_X509_bio(in, &x) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND); goto err; } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; + count = X509_STORE_add_cert(ctx->store_ctx, x); + } else { + ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); + goto err; } - if (ret == 0) - ERR_raise(ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND); err: X509_free(x); BIO_free(in); - return ret; + return count; } int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) @@ -158,15 +153,14 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { - int ret = 0; BIO *in = NULL; - int i, count = 0; + int count = 0; X509_CRL *x = NULL; in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_X509, ERR_R_BIO_LIB); goto err; } @@ -179,71 +173,73 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) ERR_clear_error(); break; } else { - ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); + if (count == 0) { + ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND); + } else { + ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); + count = 0; + } goto err; } } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) + if (!X509_STORE_add_crl(ctx->store_ctx, x)) { + count = 0; goto err; + } count++; - X509_CRL_free(x); - x = NULL; } - ret = count; } else if (type == X509_FILETYPE_ASN1) { x = d2i_X509_CRL_bio(in, NULL); if (x == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND); goto err; } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; + count = X509_STORE_add_crl(ctx->store_ctx, x); } else { ERR_raise(ERR_LIB_X509, X509_R_BAD_X509_FILETYPE); goto err; } - if (ret == 0) - ERR_raise(ERR_LIB_X509, X509_R_NO_CRL_FOUND); err: X509_CRL_free(x); BIO_free(in); - return ret; + return count; } int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, OSSL_LIB_CTX *libctx, const char *propq) { - STACK_OF(X509_INFO) *inf; - X509_INFO *itmp; - BIO *in; + STACK_OF(X509_INFO) *inf = NULL; + X509_INFO *itmp = NULL; + BIO *in = NULL; int i, count = 0; if (type != X509_FILETYPE_PEM) return X509_load_cert_file_ex(ctx, file, type, libctx, propq); in = BIO_new_file(file, "r"); - if (!in) { - ERR_raise(ERR_LIB_X509, ERR_R_SYS_LIB); + if (in == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_BIO_LIB); return 0; } inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq); BIO_free(in); - if (!inf) { + if (inf == NULL) { ERR_raise(ERR_LIB_X509, ERR_R_PEM_LIB); return 0; } for (i = 0; i < sk_X509_INFO_num(inf); i++) { itmp = sk_X509_INFO_value(inf, i); if (itmp->x509) { - if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) + if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) { + count = 0; goto err; + } count++; } if (itmp->crl) { - if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) + if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) { + count = 0; goto err; + } count++; } } diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c index 5ff1ea0a4e..ee92f4b16f 100644 --- a/crypto/x509/by_store.c +++ b/crypto/x509/by_store.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -114,6 +114,7 @@ static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, /* If no URI is given, use the default cert dir as default URI */ if (argp == NULL) argp = ossl_safe_getenv(X509_get_default_cert_dir_env()); + if (argp == NULL) argp = X509_get_default_cert_dir(); diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index a0a7f88ccd..1ffc816e5e 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,3 +25,9 @@ extern const X509V3_EXT_METHOD ossl_v3_tls_feature; extern const X509V3_EXT_METHOD ossl_v3_ext_admission; extern const X509V3_EXT_METHOD ossl_v3_utf8_list[1]; extern const X509V3_EXT_METHOD ossl_v3_issuer_sign_tool; +extern const X509V3_EXT_METHOD ossl_v3_group_ac; +extern const X509V3_EXT_METHOD ossl_v3_soa_identifier; +extern const X509V3_EXT_METHOD ossl_v3_no_assertion; +extern const X509V3_EXT_METHOD ossl_v3_no_rev_avail; +extern const X509V3_EXT_METHOD ossl_v3_single_use; +extern const X509V3_EXT_METHOD ossl_v3_indirect_issuer; diff --git a/crypto/x509/pcy_cache.c b/crypto/x509/pcy_cache.c index 1339f994ae..2d1d4cd367 100644 --- a/crypto/x509/pcy_cache.c +++ b/crypto/x509/pcy_cache.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -35,14 +35,14 @@ static int policy_cache_create(X509 *x, goto bad_policy; cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); if (cache->data == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto just_cleanup; } for (i = 0; i < num; i++) { policy = sk_POLICYINFO_value(policies, i); data = ossl_policy_data_new(policy, NULL, crit); if (data == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB); goto just_cleanup; } /* @@ -54,15 +54,17 @@ static int policy_cache_create(X509 *x, goto bad_policy; } cache->anyPolicy = data; - } else if (sk_X509_POLICY_DATA_find(cache->data, data) >=0 ) { + } else if (sk_X509_POLICY_DATA_find(cache->data, data) >=0) { ret = -1; goto bad_policy; } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto bad_policy; } data = NULL; } + /* Sort so we can find more quickly */ + sk_X509_POLICY_DATA_sort(cache->data); ret = 1; bad_policy: @@ -90,10 +92,8 @@ static int policy_cache_new(X509 *x) if (x->policy_cache != NULL) return 1; cache = OPENSSL_malloc(sizeof(*cache)); - if (cache == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (cache == NULL) return 0; - } cache->anyPolicy = NULL; cache->data = NULL; cache->any_skip = -1; diff --git a/crypto/x509/pcy_data.c b/crypto/x509/pcy_data.c index 6fb8f14ba8..8e8b91a781 100644 --- a/crypto/x509/pcy_data.c +++ b/crypto/x509/pcy_data.c @@ -52,14 +52,13 @@ X509_POLICY_DATA *ossl_policy_data_new(POLICYINFO *policy, ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { ASN1_OBJECT_free(id); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return NULL; } ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); if (ret->expected_policy_set == NULL) { OPENSSL_free(ret); ASN1_OBJECT_free(id); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return NULL; } diff --git a/crypto/x509/pcy_map.c b/crypto/x509/pcy_map.c index ed71e2202f..60dfd1e320 100644 --- a/crypto/x509/pcy_map.c +++ b/crypto/x509/pcy_map.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/pcy_node.c b/crypto/x509/pcy_node.c index 9b77e6e95e..c6e7af5ab1 100644 --- a/crypto/x509/pcy_node.c +++ b/crypto/x509/pcy_node.c @@ -69,10 +69,8 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, return NULL; node = OPENSSL_zalloc(sizeof(*node)); - if (node == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (node == NULL) return NULL; - } node->data = data; node->parent = parent; if (level != NULL) { @@ -85,11 +83,11 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, if (level->nodes == NULL) level->nodes = ossl_policy_node_cmp_new(); if (level->nodes == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB); goto node_error; } if (!sk_X509_POLICY_NODE_push(level->nodes, node)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto node_error; } } @@ -98,12 +96,12 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, if (extra_data) { if (tree->extra_data == NULL) tree->extra_data = sk_X509_POLICY_DATA_new_null(); - if (tree->extra_data == NULL){ - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (tree->extra_data == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto extra_data_error; } if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto extra_data_error; } } diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c index 2012810303..d7307b12da 100644 --- a/crypto/x509/pcy_tree.c +++ b/crypto/x509/pcy_tree.c @@ -171,10 +171,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, return ret; /* If we get this far initialize the tree */ - if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL) return X509_PCY_TREE_INTERNAL; - } /* Limit the growth of the tree to mitigate CVE-2023-0464 */ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX; @@ -188,7 +186,6 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, */ if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) { OPENSSL_free(tree); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); return X509_PCY_TREE_INTERNAL; } tree->nlevel = n+1; @@ -702,6 +699,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, if ((calc_ret = tree_calculate_authority_set(tree, &auth_nodes)) == 0) goto error; + sk_X509_POLICY_NODE_sort(auth_nodes); ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); if (calc_ret == TREE_CALC_OK_DOFREE) sk_X509_POLICY_NODE_free(auth_nodes); diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index 27a99a4b13..87a564b238 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -53,6 +53,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { #endif &ossl_v3_sinfo, &ossl_v3_policy_constraints, + &ossl_v3_no_rev_avail, #ifndef OPENSSL_NO_OCSP &ossl_v3_crl_hold, #endif @@ -71,7 +72,12 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &ossl_v3_utf8_list[0], &ossl_v3_issuer_sign_tool, &ossl_v3_tls_feature, - &ossl_v3_ext_admission + &ossl_v3_ext_admission, + &ossl_v3_soa_identifier, + &ossl_v3_indirect_issuer, + &ossl_v3_no_assertion, + &ossl_v3_single_use, + &ossl_v3_group_ac }; /* Number of standard extensions */ diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c index 095c165100..fe62a08706 100644 --- a/crypto/x509/t_req.c +++ b/crypto/x509/t_req.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -42,15 +42,15 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, EVP_PKEY *pkey; STACK_OF(X509_EXTENSION) *exts; char mlch = ' '; - int nmindent = 0; + int nmindent = 0, printok = 0; if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } - if (nmflags == X509_FLAG_COMPAT) - nmindent = 16; + if (nmflags == XN_FLAG_COMPAT) + printok = 1; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) @@ -72,7 +72,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, if (BIO_printf(bp, " Subject:%c", mlch) <= 0) goto err; if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x), - nmindent, nmflags) < 0) + nmindent, nmflags) < printok) goto err; if (BIO_write(bp, "\n", 1) <= 0) goto err; diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index 46311377f5..3fc07e6144 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,11 @@ #include "crypto/asn1.h" #include "crypto/x509.h" +void OSSL_STACK_OF_X509_free(STACK_OF(X509) *certs) +{ + sk_X509_pop_free(certs, X509_free); +} + #ifndef OPENSSL_NO_STDIO int X509_print_fp(FILE *fp, X509 *x) { @@ -60,10 +65,8 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, nmindent = 12; } - if (nmflags == X509_FLAG_COMPAT) { - nmindent = 16; + if (nmflags == XN_FLAG_COMPAT) printok = 1; - } if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate:\n", 13) <= 0) @@ -455,7 +458,7 @@ static int print_store_certs(BIO *bio, X509_STORE *store) STACK_OF(X509) *certs = X509_STORE_get1_all_certs(store); int ret = print_certs(bio, certs); - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); return ret; } else { return BIO_printf(bio, " (no trusted store)\n") >= 0; @@ -469,6 +472,8 @@ int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx) int cert_error = X509_STORE_CTX_get_error(ctx); BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */ + if (bio == NULL) + return 0; BIO_printf(bio, "%s at depth = %d error = %d (%s)\n", X509_STORE_CTX_get0_parent_ctx(ctx) != NULL ? "CRL path validation" diff --git a/crypto/x509/v3_addr.c b/crypto/x509/v3_addr.c index db01072074..b990d54048 100644 --- a/crypto/x509/v3_addr.c +++ b/crypto/x509/v3_addr.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,12 +16,13 @@ #include #include -#include "internal/cryptlib.h" #include #include #include #include #include +#include "internal/cryptlib.h" +#include "crypto/asn1.h" #include "crypto/x509.h" #include "ext_dat.h" #include "x509_local.h" @@ -33,28 +34,28 @@ */ ASN1_SEQUENCE(IPAddressRange) = { - ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), - ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) + ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) } ASN1_SEQUENCE_END(IPAddressRange) ASN1_CHOICE(IPAddressOrRange) = { - ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), - ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) + ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) } ASN1_CHOICE_END(IPAddressOrRange) ASN1_CHOICE(IPAddressChoice) = { - ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), - ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) + ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) } ASN1_CHOICE_END(IPAddressChoice) ASN1_SEQUENCE(IPAddressFamily) = { - ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), - ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) + ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), + ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) } ASN1_SEQUENCE_END(IPAddressFamily) ASN1_ITEM_TEMPLATE(IPAddrBlocks) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, - IPAddrBlocks, IPAddressFamily) + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + IPAddrBlocks, IPAddressFamily) static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) @@ -65,7 +66,7 @@ IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) /* * How much buffer space do we need for a raw address? */ -#define ADDR_RAW_BUF_LEN 16 +# define ADDR_RAW_BUF_LEN 16 /* * What's the address length associated with this AFI? @@ -109,6 +110,7 @@ static int addr_expand(unsigned char *addr, memcpy(addr, bs->data, bs->length); if ((bs->flags & 7) != 0) { unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); + if (fill == 0) addr[bs->length - 1] &= ~mask; else @@ -122,7 +124,7 @@ static int addr_expand(unsigned char *addr, /* * Extract the prefix length from a bitstring. */ -#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) +# define addr_prefixlen(bs) ((int)((bs)->length * 8 - ((bs)->flags & 7))) /* * i2r handler for one address bitstring. @@ -173,8 +175,10 @@ static int i2r_IPAddressOrRanges(BIO *out, const unsigned afi) { int i; + for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); + BIO_printf(out, "%*s", indent, ""); switch (aor->type) { case IPAddressOrRange_addressPrefix: @@ -203,9 +207,11 @@ static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, { const IPAddrBlocks *addr = ext; int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); const unsigned int afi = X509v3_addr_get_afi(f); + switch (afi) { case IANA_AFI_IPV4: BIO_printf(out, "%*sIPv4", indent, ""); @@ -409,12 +415,9 @@ static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, goto err; if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) goto err; - aor->u.addressPrefix->flags &= ~7; - aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (bitlen > 0) { + if (bitlen > 0) aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); - aor->u.addressPrefix->flags |= 8 - bitlen; - } + ossl_asn1_string_set_bits_left(aor->u.addressPrefix, 8 - bitlen); *result = aor; return 1; @@ -457,11 +460,11 @@ static int make_addressRange(IPAddressOrRange **result, for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) goto err; - aor->u.addressRange->min->flags &= ~7; - aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(aor->u.addressRange->min, 0); if (i > 0) { unsigned char b = min[i - 1]; int j = 1; + while ((b & (0xFFU >> j)) != 0) ++j; aor->u.addressRange->min->flags |= 8 - j; @@ -470,11 +473,11 @@ static int make_addressRange(IPAddressOrRange **result, for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) goto err; - aor->u.addressRange->max->flags &= ~7; - aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; + ossl_asn1_string_set_bits_left(aor->u.addressRange->max, 0); if (i > 0) { unsigned char b = max[i - 1]; int j = 1; + while ((b & (0xFFU >> j)) != (0xFFU >> j)) ++j; aor->u.addressRange->max->flags |= 8 - j; @@ -543,6 +546,7 @@ int X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi, const unsigned *safi) { IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); + if (f == NULL || f->ipAddressChoice == NULL || (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && @@ -623,6 +627,7 @@ int X509v3_addr_add_range(IPAddrBlocks *addr, IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); IPAddressOrRange *aor; int length = length_from_afi(afi); + if (aors == NULL) return 0; if (!make_addressRange(&aor, min, max, length)) @@ -661,6 +666,7 @@ int X509v3_addr_get_range(IPAddressOrRange *aor, unsigned char *max, const int length) { int afi_length = length_from_afi(afi); + if (aor == NULL || min == NULL || max == NULL || afi_length == 0 || length < afi_length || (aor->type != IPAddressOrRange_addressPrefix && @@ -688,6 +694,7 @@ static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, const ASN1_OCTET_STRING *b = (*b_)->addressFamily; int len = ((a->length <= b->length) ? a->length : b->length); int cmp = memcmp(a->data, b->data, len); + return cmp ? cmp : a->length - b->length; } @@ -799,6 +806,7 @@ int X509v3_addr_is_canonical(IPAddrBlocks *addr) j = sk_IPAddressOrRange_num(aors) - 1; { IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { if (!extract_min_max(a, a_min, a_max, length)) return 0; @@ -861,6 +869,7 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; if (memcmp(a_max, b_min, length) == 0) { IPAddressOrRange *merged; + if (!make_addressRange(&merged, a_min, b_max, length)) return 0; (void)sk_IPAddressOrRange_set(aors, i, merged); @@ -878,8 +887,10 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, j = sk_IPAddressOrRange_num(aors) - 1; { IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + if (!extract_min_max(a, a_min, a_max, length)) return 0; if (memcmp(a_min, a_max, length) > 0) @@ -896,6 +907,7 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, int X509v3_addr_canonize(IPAddrBlocks *addr) { int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); @@ -929,7 +941,7 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, int i; if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return NULL; } @@ -984,10 +996,8 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, } else { s = OPENSSL_strdup(val->value); } - if (s == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (s == NULL) goto err; - } /* * Check for inheritance. Not worth additional complexity to @@ -1027,7 +1037,7 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, goto err; } if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } break; @@ -1050,13 +1060,13 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, goto err; } if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } break; case '\0': if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } break; @@ -1106,10 +1116,12 @@ const X509V3_EXT_METHOD ossl_v3_addr = { int X509v3_addr_inherits(IPAddrBlocks *addr) { int i; + if (addr == NULL) return 0; for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + if (f->ipAddressChoice->type == IPAddressChoice_inherit) return 1; } @@ -1159,11 +1171,14 @@ static int addr_contains(IPAddressOrRanges *parent, int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) { int i; + if (a == NULL || a == b) return 1; if (b == NULL || X509v3_addr_inherits(a) || X509v3_addr_inherits(b)) return 0; (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(b); + /* Could sort a here too and get O(|a|) running time instead of O(|a| ln |b|) */ for (i = 0; i < sk_IPAddressFamily_num(a); i++) { IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); int j = sk_IPAddressFamily_find(b, fa); @@ -1240,11 +1255,12 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, validation_err(X509_V_ERR_INVALID_EXTENSION); (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); if (ctx != NULL) ctx->error = X509_V_ERR_OUT_OF_MEM; goto done; } + sk_IPAddressFamily_sort(child); /* * Now walk up the chain. No cert may list resources that its @@ -1270,6 +1286,7 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, } (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(x->rfc3779_addr); for (j = 0; j < sk_IPAddressFamily_num(child); j++) { IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); @@ -1322,7 +1339,7 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, return ret; } -#undef validation_err +# undef validation_err /* * RFC 3779 2.3 path validation -- called from X509_verify_cert(). @@ -1343,7 +1360,7 @@ int X509v3_addr_validate_path(X509_STORE_CTX *ctx) * Test whether chain covers extension. */ int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, - IPAddrBlocks *ext, int allow_inheritance) + IPAddrBlocks *ext, int allow_inheritance) { if (ext == NULL) return 1; @@ -1354,4 +1371,4 @@ int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, return addr_validate_path_internal(NULL, chain, ext); } -#endif /* OPENSSL_NO_RFC3779 */ +#endif /* OPENSSL_NO_RFC3779 */ diff --git a/crypto/x509/v3_admis.c b/crypto/x509/v3_admis.c index 3bce232ed2..c3182a71db 100644 --- a/crypto/x509/v3_admis.c +++ b/crypto/x509/v3_admis.c @@ -71,7 +71,7 @@ const X509V3_EXT_METHOD ossl_v3_ext_admission = { static int i2r_NAMING_AUTHORITY(const struct v3_ext_method *method, void *in, BIO *bp, int ind) { - NAMING_AUTHORITY * namingAuthority = (NAMING_AUTHORITY*) in; + NAMING_AUTHORITY *namingAuthority = (NAMING_AUTHORITY*) in; if (namingAuthority == NULL) return 0; @@ -103,7 +103,7 @@ static int i2r_NAMING_AUTHORITY(const struct v3_ext_method *method, void *in, || BIO_printf(bp, "\n") <= 0) goto err; } - if (namingAuthority->namingAuthorityUrl != NULL ) { + if (namingAuthority->namingAuthorityUrl != NULL) { if (BIO_printf(bp, "%*s namingAuthorityUrl: ", ind, "") <= 0 || ASN1_STRING_print(bp, namingAuthority->namingAuthorityUrl) <= 0 || BIO_printf(bp, "\n") <= 0) @@ -118,7 +118,7 @@ static int i2r_NAMING_AUTHORITY(const struct v3_ext_method *method, void *in, static int i2r_ADMISSION_SYNTAX(const struct v3_ext_method *method, void *in, BIO *bp, int ind) { - ADMISSION_SYNTAX * admission = (ADMISSION_SYNTAX *)in; + ADMISSION_SYNTAX *admission = (ADMISSION_SYNTAX *)in; int i, j, k; if (admission->admissionAuthority != NULL) { diff --git a/crypto/x509/v3_akid.c b/crypto/x509/v3_akid.c index 43b515f50c..de93dae70e 100644 --- a/crypto/x509/v3_akid.c +++ b/crypto/x509/v3_akid.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -44,9 +44,9 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, STACK_OF(CONF_VALUE) *origextlist = extlist, *tmpextlist; if (akeyid->keyid) { - tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length); + tmp = i2s_ASN1_OCTET_STRING(NULL, akeyid->keyid); if (tmp == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } if (!X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL, @@ -66,9 +66,9 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, extlist = tmpextlist; } if (akeyid->serial) { - tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length); + tmp = i2s_ASN1_OCTET_STRING(NULL, akeyid->serial); if (tmp == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } if (!X509V3_add_value("serial", tmp, &extlist)) { @@ -85,14 +85,14 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, } /*- - * Currently two options: - * keyid: use the issuers subject keyid, the value 'always' means its is - * an error if the issuer certificate doesn't have a key id. - * issuer: use the issuers cert issuer and serial number. The default is - * to only use this if keyid is not present. With the option 'always' + * Three explicit tags may be given, where 'keyid' and 'issuer' may be combined: + * 'none': do not add any authority key identifier. + * 'keyid': use the issuer's subject keyid; the option 'always' means its is + * an error if the issuer certificate doesn't have a subject key id. + * 'issuer': use the issuer's cert issuer and serial number. The default is + * to only use this if 'keyid' is not present. With the option 'always' * this is always included. */ - static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) @@ -119,16 +119,27 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, for (i = 0; i < n; i++) { cnf = sk_CONF_VALUE_value(values, i); - if (strcmp(cnf->name, "keyid") == 0) { + if (cnf->value != NULL && strcmp(cnf->value, "always") != 0) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION, + "name=%s option=%s", cnf->name, cnf->value); + goto err; + } + if (strcmp(cnf->name, "keyid") == 0 && keyid == 0) { keyid = 1; - if (cnf->value && strcmp(cnf->value, "always") == 0) + if (cnf->value != NULL) keyid = 2; - } else if (strcmp(cnf->name, "issuer") == 0) { + } else if (strcmp(cnf->name, "issuer") == 0 && issuer == 0) { issuer = 1; - if (cnf->value && strcmp(cnf->value, "always") == 0) + if (cnf->value != NULL) issuer = 2; + } else if (strcmp(cnf->name, "none") == 0 + || strcmp(cnf->name, "keyid") == 0 + || strcmp(cnf->name, "issuer") == 0) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_VALUE, + "name=%s", cnf->name); + goto err; } else { - ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION, + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_VALUE, "name=%s", cnf->name); goto err; } @@ -161,8 +172,13 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, */ i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1); if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL - && !(same_issuer && !ss)) + && !(same_issuer && !ss)) { ikeyid = X509V3_EXT_d2i(ext); + if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ { + ASN1_OCTET_STRING_free(ikeyid); + ikeyid = NULL; + } + } if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) { /* generate fallback AKID, emulating s2i_skey_id(..., "hash") */ X509_PUBKEY *pubkey = NULL; @@ -171,15 +187,13 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, ikeyid = ossl_x509_pubkey_hash(pubkey); X509_PUBKEY_free(pubkey); } - if ((keyid == 2 || issuer == 0) - && (ikeyid == NULL - || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) { + if (keyid == 2 && ikeyid == NULL) { ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); goto err; } } - if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) { + if (issuer == 2 || (issuer == 1 && !ss && ikeyid == NULL)) { isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert)); serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert)); if (isname == NULL || serial == NULL) { @@ -190,9 +204,12 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, if (isname != NULL) { if ((gens = sk_GENERAL_NAME_new_null()) == NULL - || (gen = GENERAL_NAME_new()) == NULL - || !sk_GENERAL_NAME_push(gens, gen)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + || (gen = GENERAL_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if (!sk_GENERAL_NAME_push(gens, gen)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } gen->type = GEN_DIRNAME; diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index 86577d6ca4..d1c3dd5d9f 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -301,14 +301,14 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || !BN_add_word(bn, 1)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_BN_LIB); goto done; } if ((a_max_plus_one = BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { a_max_plus_one = orig; - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto done; } @@ -422,14 +422,14 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) if ((bn == NULL && (bn = BN_new()) == NULL) || ASN1_INTEGER_to_BN(a_max, bn) == NULL || !BN_add_word(bn, 1)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_BN_LIB); goto done; } if ((a_max_plus_one = BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { a_max_plus_one = orig; - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto done; } @@ -440,10 +440,8 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) ASRange *r; switch (a->type) { case ASIdOrRange_id: - if ((r = OPENSSL_malloc(sizeof(*r))) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((r = OPENSSL_malloc(sizeof(*r))) == NULL) goto done; - } r->min = a_min; r->max = b_max; a->type = ASIdOrRange_range; @@ -517,7 +515,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, int i; if ((asid = ASIdentifiers_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); return NULL; } @@ -578,21 +576,19 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, */ if (!is_range) { if (!X509V3_get_value_int(val, &min)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } } else { char *s = OPENSSL_strdup(val->value); - if (s == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (s == NULL) goto err; - } s[i1] = '\0'; min = s2i_ASN1_INTEGER(NULL, s); max = s2i_ASN1_INTEGER(NULL, s + i2); OPENSSL_free(s); if (min == NULL || max == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } if (ASN1_INTEGER_cmp(min, max) > 0) { @@ -601,7 +597,7 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method, } } if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); goto err; } min = max = NULL; diff --git a/crypto/x509/v3_bcons.c b/crypto/x509/v3_bcons.c index 6e7a165f26..17962ed43f 100644 --- a/crypto/x509/v3_bcons.c +++ b/crypto/x509/v3_bcons.c @@ -61,7 +61,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, int i; if ((bcons = BASIC_CONSTRAINTS_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(values); i++) { diff --git a/crypto/x509/v3_bitst.c b/crypto/x509/v3_bitst.c index b53c5ba3ec..d41c95b513 100644 --- a/crypto/x509/v3_bitst.c +++ b/crypto/x509/v3_bitst.c @@ -64,7 +64,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, int i; BIT_STRING_BITNAME *bnam; if ((bs = ASN1_BIT_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { @@ -73,7 +73,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, if (strcmp(bnam->sname, val->name) == 0 || strcmp(bnam->lname, val->name) == 0) { if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); ASN1_BIT_STRING_free(bs); return NULL; } diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index 1c11d671b2..c575a43459 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -148,34 +148,41 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, ext_der = NULL; ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); - if (ext_len < 0) - goto merr; + if (ext_len < 0) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } } else { unsigned char *p; ext_len = method->i2d(ext_struc, NULL); - if (ext_len <= 0) - goto merr; + if (ext_len <= 0) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } if ((ext_der = OPENSSL_malloc(ext_len)) == NULL) - goto merr; + goto err; p = ext_der; method->i2d(ext_struc, &p); } - if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) - goto merr; + if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } ext_oct->data = ext_der; ext_der = NULL; ext_oct->length = ext_len; ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); - if (!ext) - goto merr; + if (!ext) { + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); + goto err; + } ASN1_OCTET_STRING_free(ext_oct); return ext; - merr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + err: OPENSSL_free(ext_der); ASN1_OCTET_STRING_free(ext_oct); return NULL; @@ -200,9 +207,8 @@ static int v3_check_critical(const char **value) { const char *p = *value; - if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + if (!CHECK_AND_SKIP_PREFIX(p, "critical,")) return 0; - p += 9; while (ossl_isspace(*p)) p++; *value = p; @@ -215,11 +221,9 @@ static int v3_check_generic(const char **value) int gen_type = 0; const char *p = *value; - if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) { - p += 4; + if (CHECK_AND_SKIP_PREFIX(p, "DER:")) { gen_type = 1; - } else if ((strlen(p) >= 5) && strncmp(p, "ASN1:", 5) == 0) { - p += 5; + } else if (CHECK_AND_SKIP_PREFIX(p, "ASN1:")) { gen_type = 2; } else return 0; @@ -259,7 +263,7 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, } if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } @@ -311,13 +315,27 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, { X509_EXTENSION *ext; STACK_OF(CONF_VALUE) *nval; - CONF_VALUE *val; - int i; + const CONF_VALUE *val; + int i, akid = -1, skid = -1; if ((nval = NCONF_get_section(conf, section)) == NULL) return 0; for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); + if (strcmp(val->name, "authorityKeyIdentifier") == 0) + akid = i; + else if (strcmp(val->name, "subjectKeyIdentifier") == 0) + skid = i; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (skid > akid && akid >= 0) { + /* make sure SKID is handled before AKID */ + if (i == akid) + val = sk_CONF_VALUE_value(nval, skid); + else if (i == skid) + val = sk_CONF_VALUE_value(nval, akid); + } if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section, val->name, val->value)) == NULL) return 0; diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c index 5353a69167..ae602ea2cd 100644 --- a/crypto/x509/v3_cpols.c +++ b/crypto/x509/v3_cpols.c @@ -105,7 +105,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, pols = sk_POLICYINFO_new_reserve(NULL, num); if (pols == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } @@ -144,14 +144,14 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, pol = POLICYINFO_new(); if (pol == NULL) { ASN1_OBJECT_free(pobj); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } pol->policyid = pobj; } if (!sk_POLICYINFO_push(pols, pol)) { POLICYINFO_free(pol); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } } @@ -171,8 +171,10 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, POLICYINFO *pol; POLICYQUALINFO *qual; - if ((pol = POLICYINFO_new()) == NULL) - goto merr; + if ((pol = POLICYINFO_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { cnf = sk_CONF_VALUE_value(polstrs, i); if (strcmp(cnf->name, "policyIdentifier") == 0) { @@ -188,19 +190,27 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, } else if (!ossl_v3_name_cmp(cnf->name, "CPS")) { if (pol->qualifiers == NULL) pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if ((qual = POLICYQUALINFO_new()) == NULL) - goto merr; - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; + if ((qual = POLICYQUALINFO_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_cps)) == NULL) { ERR_raise(ERR_LIB_X509V3, ERR_R_INTERNAL_ERROR); goto err; } - if ((qual->d.cpsuri = ASN1_IA5STRING_new()) == NULL) - goto merr; + if ((qual->d.cpsuri = ASN1_IA5STRING_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, - strlen(cnf->value))) - goto merr; + strlen(cnf->value))) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } } else if (!ossl_v3_name_cmp(cnf->name, "userNotice")) { STACK_OF(CONF_VALUE) *unot; if (*cnf->value != '@') { @@ -221,8 +231,10 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, goto err; if (pol->qualifiers == NULL) pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } } else { ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OPTION); X509V3_conf_err(cnf); @@ -236,9 +248,6 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, return pol; - merr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); - err: POLICYINFO_free(pol); return NULL; @@ -261,17 +270,17 @@ static int displaytext_str2tag(const char *tagstr, unsigned int *tag_len) if (len == -1) return V_ASN1_VISIBLESTRING; *tag_len = len; - if (len == sizeof("UTF8") - 1 && strncmp(tagstr, "UTF8", len) == 0) + if (len == sizeof("UTF8") - 1 && HAS_PREFIX(tagstr, "UTF8")) return V_ASN1_UTF8STRING; - if (len == sizeof("UTF8String") - 1 && strncmp(tagstr, "UTF8String", len) == 0) + if (len == sizeof("UTF8String") - 1 && HAS_PREFIX(tagstr, "UTF8String")) return V_ASN1_UTF8STRING; - if (len == sizeof("BMP") - 1 && strncmp(tagstr, "BMP", len) == 0) + if (len == sizeof("BMP") - 1 && HAS_PREFIX(tagstr, "BMP")) return V_ASN1_BMPSTRING; - if (len == sizeof("BMPSTRING") - 1 && strncmp(tagstr, "BMPSTRING", len) == 0) + if (len == sizeof("BMPSTRING") - 1 && HAS_PREFIX(tagstr, "BMPSTRING")) return V_ASN1_BMPSTRING; - if (len == sizeof("VISIBLE") - 1 && strncmp(tagstr, "VISIBLE", len) == 0) + if (len == sizeof("VISIBLE") - 1 && HAS_PREFIX(tagstr, "VISIBLE")) return V_ASN1_VISIBLESTRING; - if (len == sizeof("VISIBLESTRING") - 1 && strncmp(tagstr, "VISIBLESTRING", len) == 0) + if (len == sizeof("VISIBLESTRING") - 1 && HAS_PREFIX(tagstr, "VISIBLESTRING")) return V_ASN1_VISIBLESTRING; *tag_len = 0; return V_ASN1_VISIBLESTRING; @@ -287,14 +296,18 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, POLICYQUALINFO *qual; char *value = NULL; - if ((qual = POLICYQUALINFO_new()) == NULL) - goto merr; + if ((qual = POLICYQUALINFO_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice)) == NULL) { ERR_raise(ERR_LIB_X509V3, ERR_R_INTERNAL_ERROR); goto err; } - if ((not = USERNOTICE_new()) == NULL) - goto merr; + if ((not = USERNOTICE_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } qual->d.usernotice = not; for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { cnf = sk_CONF_VALUE_value(unot, i); @@ -302,19 +315,25 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, value = cnf->value; if (strcmp(cnf->name, "explicitText") == 0) { tag = displaytext_str2tag(value, &tag_len); - if ((not->exptext = ASN1_STRING_type_new(tag)) == NULL) - goto merr; + if ((not->exptext = ASN1_STRING_type_new(tag)) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } if (tag_len != 0) value += tag_len + 1; len = strlen(value); - if (!ASN1_STRING_set(not->exptext, value, len)) - goto merr; + if (!ASN1_STRING_set(not->exptext, value, len)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } } else if (strcmp(cnf->name, "organization") == 0) { NOTICEREF *nref; if (!not->noticeref) { - if ((nref = NOTICEREF_new()) == NULL) - goto merr; + if ((nref = NOTICEREF_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } not->noticeref = nref; } else nref = not->noticeref; @@ -323,15 +342,19 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, else nref->organization->type = V_ASN1_VISIBLESTRING; if (!ASN1_STRING_set(nref->organization, cnf->value, - strlen(cnf->value))) - goto merr; + strlen(cnf->value))) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } } else if (strcmp(cnf->name, "noticeNumbers") == 0) { NOTICEREF *nref; STACK_OF(CONF_VALUE) *nos; if (!not->noticeref) { - if ((nref = NOTICEREF_new()) == NULL) - goto merr; + if ((nref = NOTICEREF_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } not->noticeref = nref; } else nref = not->noticeref; @@ -361,9 +384,6 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, return qual; - merr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); - err: POLICYQUALINFO_free(qual); return NULL; @@ -380,19 +400,15 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) cnf = sk_CONF_VALUE_value(nos, i); if ((aint = s2i_ASN1_INTEGER(NULL, cnf->name)) == NULL) { ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER); - goto err; + return 0; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) { + ASN1_INTEGER_free(aint); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + return 0; } - if (!sk_ASN1_INTEGER_push(nnums, aint)) - goto merr; } return 1; - - merr: - ASN1_INTEGER_free(aint); - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); - - err: - return 0; } static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index 0289df4de7..08df3faf86 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -70,7 +70,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, STACK_OF(GENERAL_NAME) *fnm = NULL; STACK_OF(X509_NAME_ENTRY) *rnm = NULL; - if (strncmp(cnf->name, "fullname", 9) == 0) { + if (HAS_PREFIX(cnf->name, "fullname")) { fnm = gnames_from_sectname(ctx, cnf->value); if (!fnm) goto err; @@ -244,8 +244,10 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, int i; crld = sk_DIST_POINT_new_reserve(NULL, num); - if (crld == NULL) - goto merr; + if (crld == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } for (i = 0; i < num; i++) { DIST_POINT *point; @@ -263,16 +265,24 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, } else { if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) goto err; - if ((gens = GENERAL_NAMES_new()) == NULL) - goto merr; - if (!sk_GENERAL_NAME_push(gens, gen)) - goto merr; + if ((gens = GENERAL_NAMES_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if (!sk_GENERAL_NAME_push(gens, gen)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } gen = NULL; - if ((point = DIST_POINT_new()) == NULL) - goto merr; + if ((point = DIST_POINT_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */ - if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) - goto merr; + if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } point->distpoint->name.fullname = gens; point->distpoint->type = 0; gens = NULL; @@ -280,8 +290,6 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method, } return crld; - merr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: GENERAL_NAME_free(gen); GENERAL_NAMES_free(gens); @@ -364,8 +372,10 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *name, *val; int i, ret; idp = ISSUING_DIST_POINT_new(); - if (idp == NULL) - goto merr; + if (idp == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { cnf = sk_CONF_VALUE_value(nval, i); name = cnf->name; @@ -398,8 +408,6 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, } return idp; - merr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: ISSUING_DIST_POINT_free(idp); return NULL; diff --git a/crypto/x509/v3_extku.c b/crypto/x509/v3_extku.c index 4f2a86bdcb..22c951e251 100644 --- a/crypto/x509/v3_extku.c +++ b/crypto/x509/v3_extku.c @@ -79,7 +79,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, extku = sk_ASN1_OBJECT_new_reserve(NULL, num); if (extku == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); sk_ASN1_OBJECT_free(extku); return NULL; } diff --git a/crypto/x509/v3_group_ac.c b/crypto/x509/v3_group_ac.c new file mode 100644 index 0000000000..9a2b69dece --- /dev/null +++ b/crypto/x509/v3_group_ac.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_GROUP_AC(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_GROUP_AC(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_GROUP_AC(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_GROUP_AC(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The groupAC X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.1.2.6. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_group_ac = { + NID_group_ac, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_GROUP_AC, + (X509V3_EXT_S2I)s2i_GROUP_AC, + 0, 0, + (X509V3_EXT_I2R)i2r_GROUP_AC, + (X509V3_EXT_R2I)r2i_GROUP_AC, + NULL +}; diff --git a/crypto/x509/v3_ia5.c b/crypto/x509/v3_ia5.c index 6722b6c01f..7b79935872 100644 --- a/crypto/x509/v3_ia5.c +++ b/crypto/x509/v3_ia5.c @@ -31,10 +31,8 @@ char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) if (ia5 == NULL || ia5->length <= 0) return NULL; - if ((tmp = OPENSSL_malloc(ia5->length + 1)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((tmp = OPENSSL_malloc(ia5->length + 1)) == NULL) return NULL; - } memcpy(tmp, ia5->data, ia5->length); tmp[ia5->length] = 0; return tmp; @@ -48,8 +46,10 @@ ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); return NULL; } - if ((ia5 = ASN1_IA5STRING_new()) == NULL) - goto err; + if ((ia5 = ASN1_IA5STRING_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + return NULL; + } if (!ASN1_STRING_set((ASN1_STRING *)ia5, str, strlen(str))) { ASN1_IA5STRING_free(ia5); return NULL; @@ -58,7 +58,4 @@ ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ebcdic2ascii(ia5->data, ia5->data, ia5->length); #endif /* CHARSET_EBCDIC */ return ia5; - err: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); - return NULL; } diff --git a/crypto/x509/v3_ind_iss.c b/crypto/x509/v3_ind_iss.c new file mode 100644 index 0000000000..ff41ba7bed --- /dev/null +++ b/crypto/x509/v3_ind_iss.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The indirectIssuer X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.5.2.5. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_indirect_issuer = { + NID_indirect_issuer, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_INDIRECT_ISSUER, + (X509V3_EXT_S2I)s2i_INDIRECT_ISSUER, + 0, 0, + (X509V3_EXT_I2R)i2r_INDIRECT_ISSUER, + (X509V3_EXT_R2I)r2i_INDIRECT_ISSUER, + NULL +}; diff --git a/crypto/x509/v3_info.c b/crypto/x509/v3_info.c index 5f21ce11e7..7e4d9313d8 100644 --- a/crypto/x509/v3_info.c +++ b/crypto/x509/v3_info.c @@ -73,8 +73,10 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); tmp = i2v_GENERAL_NAME(method, desc->location, tret); - if (tmp == NULL) + if (tmp == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; + } tret = tmp; vtmp = sk_CONF_VALUE_value(tret, i); i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method); @@ -91,7 +93,6 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( return tret; err: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); if (ret == NULL && tret != NULL) sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); return NULL; @@ -111,13 +112,13 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD char *objtmp, *ptmp; if ((ainfo = sk_ACCESS_DESCRIPTION_new_reserve(NULL, num)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return NULL; } for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); if ((acc = ACCESS_DESCRIPTION_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } sk_ACCESS_DESCRIPTION_push(ainfo, acc); /* Cannot fail due to reserve */ @@ -130,10 +131,8 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD ctmp.value = cnf->value; if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) goto err; - if ((objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name)) == NULL) goto err; - } acc->method = OBJ_txt2obj(objtmp, 0); if (!acc->method) { ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT, diff --git a/crypto/x509/v3_ist.c b/crypto/x509/v3_ist.c index 7bd49e6b5c..978a0f3ed8 100644 --- a/crypto/x509/v3_ist.c +++ b/crypto/x509/v3_ist.c @@ -39,7 +39,7 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_ int i; if (ist == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(nval); ++i) { @@ -51,25 +51,25 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_ if (strcmp(cnf->name, "signTool") == 0) { ist->signTool = ASN1_UTF8STRING_new(); if (ist->signTool == NULL || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "cATool") == 0) { ist->cATool = ASN1_UTF8STRING_new(); if (ist->cATool == NULL || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "signToolCert") == 0) { ist->signToolCert = ASN1_UTF8STRING_new(); if (ist->signToolCert == NULL || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "cAToolCert") == 0) { ist->cAToolCert = ASN1_UTF8STRING_new(); if (ist->cAToolCert == NULL || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else { diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c index 5ffeb75d9f..077b22c863 100644 --- a/crypto/x509/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,11 +26,11 @@ int X509V3_EXT_add(X509V3_EXT_METHOD *ext) { if (ext_list == NULL && (ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return 0; } if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return 0; } return 1; @@ -63,7 +63,10 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) return *ret; if (!ext_list) return NULL; + /* Ideally, this would be done under a lock */ + sk_X509V3_EXT_METHOD_sort(ext_list); idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); + /* A failure to locate the item is handled by the value method */ return sk_X509V3_EXT_METHOD_value(ext_list, idx); } @@ -92,10 +95,8 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from) ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND); return 0; } - if ((tmpext = OPENSSL_malloc(sizeof(*tmpext))) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((tmpext = OPENSSL_malloc(sizeof(*tmpext))) == NULL) return 0; - } *tmpext = *ext; tmpext->ext_nid = nid_to; tmpext->ext_flags |= X509V3_EXT_DYNAMIC; @@ -291,7 +292,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, return 1; m_fail: - /* ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); */ + /* ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); */ if (ret != *x) sk_X509_EXTENSION_free(ret); X509_EXTENSION_free(ext); diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c index c6112a5d30..a6817b9e17 100644 --- a/crypto/x509/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -9,6 +9,7 @@ #include "internal/cryptlib.h" #include "internal/numbers.h" +#include "internal/safe_math.h" #include #include "crypto/asn1.h" #include @@ -20,6 +21,8 @@ #include "crypto/punycode.h" #include "ext_dat.h" +OSSL_SAFE_MATH_SIGNED(int, int) + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); @@ -132,14 +135,16 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, GENERAL_SUBTREE *sub = NULL; ncons = NAME_CONSTRAINTS_new(); - if (ncons == NULL) - goto memerr; + if (ncons == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); - if (strncmp(val->name, "permitted", 9) == 0 && val->name[9]) { + if (HAS_PREFIX(val->name, "permitted") && val->name[9]) { ptree = &ncons->permittedSubtrees; tval.name = val->name + 10; - } else if (strncmp(val->name, "excluded", 8) == 0 && val->name[8]) { + } else if (HAS_PREFIX(val->name, "excluded") && val->name[8]) { ptree = &ncons->excludedSubtrees; tval.name = val->name + 9; } else { @@ -148,21 +153,25 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, } tval.value = val->value; sub = GENERAL_SUBTREE_new(); - if (sub == NULL) - goto memerr; - if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + if (sub == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; + } + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); + goto err; + } if (*ptree == NULL) *ptree = sk_GENERAL_SUBTREE_new_null(); - if (*ptree == NULL || !sk_GENERAL_SUBTREE_push(*ptree, sub)) - goto memerr; + if (*ptree == NULL || !sk_GENERAL_SUBTREE_push(*ptree, sub)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } sub = NULL; } return ncons; - memerr: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); err: NAME_CONSTRAINTS_free(ncons); GENERAL_SUBTREE_free(sub); @@ -223,16 +232,16 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) static int add_lengths(int *out, int a, int b) { + int err = 0; + /* sk_FOO_num(NULL) returns -1 but is effectively 0 when iterating. */ if (a < 0) a = 0; if (b < 0) b = 0; - if (a > INT_MAX - b) - return 0; - *out = a + b; - return 1; + *out = safe_add_int(a, b, &err); + return !err; } /*- diff --git a/crypto/x509/v3_no_ass.c b/crypto/x509/v3_no_ass.c new file mode 100644 index 0000000000..873e20a751 --- /dev/null +++ b/crypto/x509/v3_no_ass.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_NO_ASSERTION(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_ASSERTION(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_ASSERTION(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_ASSERTION(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The noAssertion X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.5.2.7. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_no_assertion = { + NID_no_assertion, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_ASSERTION, + (X509V3_EXT_S2I)s2i_NO_ASSERTION, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_ASSERTION, + (X509V3_EXT_R2I)r2i_NO_ASSERTION, + NULL +}; diff --git a/crypto/x509/v3_no_rev_avail.c b/crypto/x509/v3_no_rev_avail.c new file mode 100644 index 0000000000..849feda5ec --- /dev/null +++ b/crypto/x509/v3_no_rev_avail.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The noRevAvail X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.2.2.7. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_no_rev_avail = { + NID_no_rev_avail, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_REV_AVAIL, + (X509V3_EXT_S2I)s2i_NO_REV_AVAIL, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_REV_AVAIL, + (X509V3_EXT_R2I)r2i_NO_REV_AVAIL, + NULL +}; diff --git a/crypto/x509/v3_pci.c b/crypto/x509/v3_pci.c index a931e01a9c..8b8b6e3ab8 100644 --- a/crypto/x509/v3_pci.c +++ b/crypto/x509/v3_pci.c @@ -112,21 +112,22 @@ static int process_pci_value(CONF_VALUE *val, return 0; } } else if (strcmp(val->name, "policy") == 0) { + char *valp = val->value; unsigned char *tmp_data = NULL; long val_len; if (*policy == NULL) { *policy = ASN1_OCTET_STRING_new(); if (*policy == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); X509V3_conf_err(val); return 0; } free_policy = 1; } - if (strncmp(val->value, "hex:", 4) == 0) { + if (CHECK_AND_SKIP_PREFIX(valp, "hex:")) { unsigned char *tmp_data2 = - OPENSSL_hexstr2buf(val->value + 4, &val_len); + OPENSSL_hexstr2buf(valp, &val_len); if (!tmp_data2) { X509V3_conf_err(val); @@ -150,15 +151,14 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } OPENSSL_free(tmp_data2); - } else if (strncmp(val->value, "file:", 5) == 0) { + } else if (CHECK_AND_SKIP_PREFIX(valp, "file:")) { unsigned char buf[2048]; int n; - BIO *b = BIO_new_file(val->value + 5, "r"); + BIO *b = BIO_new_file(valp, "r"); if (!b) { ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); X509V3_conf_err(val); @@ -176,7 +176,6 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); BIO_free_all(b); goto err; @@ -194,8 +193,8 @@ static int process_pci_value(CONF_VALUE *val, X509V3_conf_err(val); goto err; } - } else if (strncmp(val->value, "text:", 5) == 0) { - val_len = strlen(val->value + 5); + } else if (CHECK_AND_SKIP_PREFIX(valp, "text:")) { + val_len = strlen(valp); tmp_data = OPENSSL_realloc((*policy)->data, (*policy)->length + val_len + 1); if (tmp_data) { @@ -212,7 +211,6 @@ static int process_pci_value(CONF_VALUE *val, OPENSSL_free((*policy)->data); (*policy)->data = NULL; (*policy)->length = 0; - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } @@ -222,7 +220,6 @@ static int process_pci_value(CONF_VALUE *val, goto err; } if (!tmp_data) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); X509V3_conf_err(val); goto err; } @@ -296,7 +293,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, pci = PROXY_CERT_INFO_EXTENSION_new(); if (pci == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/x509/v3_pcia.c b/crypto/x509/v3_pcia.c index 7f5985f5e8..478de610ae 100644 --- a/crypto/x509/v3_pcia.c +++ b/crypto/x509/v3_pcia.c @@ -47,18 +47,16 @@ #include #include -ASN1_SEQUENCE(PROXY_POLICY) = - { - ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), - ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) +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(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(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(PROXY_CERT_INFO_EXTENSION) diff --git a/crypto/x509/v3_pcons.c b/crypto/x509/v3_pcons.c index 128365f572..72c2364b05 100644 --- a/crypto/x509/v3_pcons.c +++ b/crypto/x509/v3_pcons.c @@ -61,7 +61,7 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, int i; if ((pcons = POLICY_CONSTRAINTS_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } for (i = 0; i < sk_CONF_VALUE_num(values); i++) { diff --git a/crypto/x509/v3_pmaps.c b/crypto/x509/v3_pmaps.c index 2094e96711..e5d7dddc0a 100644 --- a/crypto/x509/v3_pmaps.c +++ b/crypto/x509/v3_pmaps.c @@ -73,7 +73,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, int i; if ((pmaps = sk_POLICY_MAPPING_new_reserve(NULL, num)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return NULL; } @@ -93,7 +93,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, } pmap = POLICY_MAPPING_new(); if (pmap == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } pmap->issuerDomainPolicy = obj1; diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index fbc2f33006..e917c455de 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -18,24 +18,26 @@ static int check_ssl_ca(const X509 *x); static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int require_ca); -static int purpose_smime(const X509 *x, int require_ca); + int non_leaf); +static int purpose_smime(const X509 *x, int non_leaf); static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); +static int check_purpose_code_sign(const X509_PURPOSE *xp, const X509 *x, + int non_leaf); static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int check_purpose_ocsp_helper(const X509_PURPOSE *xp, const X509 *x, - int require_ca); + int non_leaf); static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); static void xptable_free(X509_PURPOSE *p); @@ -61,6 +63,9 @@ static X509_PURPOSE xstandard[] = { {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL}, + {X509_PURPOSE_CODE_SIGN, X509_TRUST_OBJECT_SIGN, 0, + check_purpose_code_sign, "Code signing", "codesign", + NULL}, }; #define X509_PURPOSE_COUNT OSSL_NELEM(xstandard) @@ -78,7 +83,7 @@ static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) * If id == -1 it just calls x509v3_cache_extensions() for its side-effect. * Returns 1 on success, 0 if x does not allow purpose, -1 on (internal) error. */ -int X509_check_purpose(X509 *x, int id, int require_ca) +int X509_check_purpose(X509 *x, int id, int non_leaf) { int idx; const X509_PURPOSE *pt; @@ -92,7 +97,7 @@ int X509_check_purpose(X509 *x, int id, int require_ca) if (idx == -1) return -1; pt = X509_PURPOSE_get0(idx); - return pt->check_purpose(pt, x, require_ca); + return pt->check_purpose(pt, x, non_leaf); } int X509_PURPOSE_set(int *p, int purpose) @@ -125,6 +130,7 @@ int X509_PURPOSE_get_by_sname(const char *sname) { int i; X509_PURPOSE *xptmp; + for (i = 0; i < X509_PURPOSE_get_count(); i++) { xptmp = X509_PURPOSE_get0(i); if (strcmp(xptmp->sname, sname) == 0) @@ -165,26 +171,23 @@ int X509_PURPOSE_add(int id, int trust, int flags, idx = X509_PURPOSE_get_by_id(id); /* Need a new entry */ if (idx == -1) { - if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) return 0; - } ptmp->flags = X509_PURPOSE_DYNAMIC; - } else + } else { ptmp = X509_PURPOSE_get0(idx); + } /* OPENSSL_free existing name if dynamic */ - if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + if ((ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) != 0) { OPENSSL_free(ptmp->name); OPENSSL_free(ptmp->sname); } /* Dup supplied name */ ptmp->name = OPENSSL_strdup(name); ptmp->sname = OPENSSL_strdup(sname); - if (ptmp->name == NULL|| ptmp->sname == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (ptmp->name == NULL || ptmp->sname == NULL) goto err; - } /* Keep the dynamic flag of existing entry */ ptmp->flags &= X509_PURPOSE_DYNAMIC; /* Set all other flags */ @@ -199,11 +202,11 @@ int X509_PURPOSE_add(int id, int trust, int flags, if (idx == -1) { if (xptable == NULL && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } if (!sk_X509_PURPOSE_push(xptable, ptmp)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } } @@ -221,8 +224,8 @@ static void xptable_free(X509_PURPOSE *p) { if (p == NULL) return; - if (p->flags & X509_PURPOSE_DYNAMIC) { - if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + if ((p->flags & X509_PURPOSE_DYNAMIC) != 0) { + if ((p->flags & X509_PURPOSE_DYNAMIC_NAME) != 0) { OPENSSL_free(p->name); OPENSSL_free(p->sname); } @@ -372,14 +375,14 @@ static int check_sig_alg_match(const EVP_PKEY *issuer_key, const X509 *subject) return X509_V_ERR_NO_ISSUER_PUBLIC_KEY; if (OBJ_find_sigid_algs(OBJ_obj2nid(subject->cert_info.signature.algorithm), NULL, &subj_sig_nid) == 0) - return X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM; + return X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM; if (EVP_PKEY_is_a(issuer_key, OBJ_nid2sn(subj_sig_nid)) || (EVP_PKEY_is_a(issuer_key, "RSA") && subj_sig_nid == NID_rsassaPss)) return X509_V_OK; return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH; } -#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define V1_ROOT (EXFLAG_V1 | EXFLAG_SS) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) != 0 && ((x)->ex_kusage & (usage)) == 0) #define xku_reject(x, usage) \ @@ -412,17 +415,17 @@ int ossl_x509v3_cache_extensions(X509 *x) if (!CRYPTO_THREAD_write_lock(x->lock)) return 0; - if (x->ex_flags & EXFLAG_SET) { /* Cert has already been processed */ + if ((x->ex_flags & EXFLAG_SET) != 0) { /* Cert has already been processed */ CRYPTO_THREAD_unlock(x->lock); return (x->ex_flags & EXFLAG_INVALID) == 0; } + ERR_set_mark(); + /* Cache the SHA1 digest of the cert */ if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL)) x->ex_flags |= EXFLAG_NO_FINGERPRINT; - ERR_set_mark(); - /* V1 should mean no extensions ... */ if (X509_get_version(x) == X509_VERSION_1) x->ex_flags |= EXFLAG_V1; @@ -452,7 +455,7 @@ int ossl_x509v3_cache_extensions(X509 *x) /* Handle proxy certificates */ if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL)) != NULL) { - if (x->ex_flags & EXFLAG_CA + if ((x->ex_flags & EXFLAG_CA) != 0 || 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; @@ -573,8 +576,6 @@ int ossl_x509v3_cache_extensions(X509 *x) res = setup_crldp(x); if (res == 0) x->ex_flags |= EXFLAG_INVALID; - else if (res < 0) - goto err; #ifndef OPENSSL_NO_RFC3779 x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); @@ -627,17 +628,13 @@ int ossl_x509v3_cache_extensions(X509 *x) */ #endif ERR_pop_to_mark(); - if ((x->ex_flags & (EXFLAG_INVALID | EXFLAG_NO_FINGERPRINT)) == 0) { + + if ((x->ex_flags & EXFLAG_INVALID) == 0) { CRYPTO_THREAD_unlock(x->lock); return 1; } - if ((x->ex_flags & EXFLAG_INVALID) != 0) - ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_CERTIFICATE); - /* If computing sha1_hash failed the error queue already reflects this. */ - - err: - x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */ CRYPTO_THREAD_unlock(x->lock); + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_CERTIFICATE); return 0; } @@ -668,10 +665,11 @@ static int check_ca(const X509 *x) /* * If key usage present it must have certSign so tolerate it */ - else if (x->ex_flags & EXFLAG_KUSAGE) + else if ((x->ex_flags & EXFLAG_KUSAGE) != 0) return 4; /* Older certificates could have Netscape-specific CA types */ - else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) + else if ((x->ex_flags & EXFLAG_NSCERT) != 0 + && (x->ex_nscert & NS_ANY_CA) != 0) return 5; /* Can this still be regarded a CA certificate? I doubt it. */ return 0; @@ -712,11 +710,11 @@ static int check_ssl_ca(const X509 *x) } static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { if (xku_reject(x, XKU_SSL_CLIENT)) return 0; - if (require_ca) + if (non_leaf) return check_ssl_ca(x); /* We need to do digital signatures or key agreement */ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) @@ -733,14 +731,14 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, * key types. */ #define KU_TLS \ - KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT + KU_DIGITAL_SIGNATURE | KU_KEY_ENCIPHERMENT | KU_KEY_AGREEMENT static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) return 0; - if (require_ca) + if (non_leaf) return check_ssl_ca(x); if (ns_reject(x, NS_SSL_SERVER)) @@ -753,82 +751,70 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, } static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { - int ret; - ret = check_purpose_ssl_server(xp, x, require_ca); - if (!ret || require_ca) + int ret = check_purpose_ssl_server(xp, x, non_leaf); + + if (!ret || non_leaf) return ret; /* We need to encipher or Netscape complains */ - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; + return ku_reject(x, KU_KEY_ENCIPHERMENT) ? 0 : ret; } /* common S/MIME checks */ -static int purpose_smime(const X509 *x, int require_ca) +static int purpose_smime(const X509 *x, int non_leaf) { if (xku_reject(x, XKU_SMIME)) return 0; - if (require_ca) { - int ca_ret; - ca_ret = check_ca(x); + if (non_leaf) { + int ca_ret = check_ca(x); + if (ca_ret == 0) return 0; /* Check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) + if (ca_ret != 5 || (x->ex_nscert & NS_SMIME_CA) != 0) return ca_ret; else return 0; } - if (x->ex_flags & EXFLAG_NSCERT) { - if (x->ex_nscert & NS_SMIME) + if ((x->ex_flags & EXFLAG_NSCERT) != 0) { + if ((x->ex_nscert & NS_SMIME) != 0) return 1; /* Workaround for some buggy certificates */ - if (x->ex_nscert & NS_SSL_CLIENT) - return 2; - return 0; + return (x->ex_nscert & NS_SSL_CLIENT) != 0 ? 2 : 0; } return 1; } static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { - int ret; - ret = purpose_smime(x, require_ca); - if (!ret || require_ca) + int ret = purpose_smime(x, non_leaf); + + if (!ret || non_leaf) return ret; - if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) - return 0; - return ret; + return ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION) ? 0 : ret; } static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { - int ret; - ret = purpose_smime(x, require_ca); - if (!ret || require_ca) + int ret = purpose_smime(x, non_leaf); + + if (!ret || non_leaf) return ret; - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; + return ku_reject(x, KU_KEY_ENCIPHERMENT) ? 0 : ret; } static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { - if (require_ca) { - int ca_ret; - if ((ca_ret = check_ca(x)) != 2) - return ca_ret; - else - return 0; + if (non_leaf) { + int ca_ret = check_ca(x); + + return ca_ret == 2 ? 0 : ca_ret; } - if (ku_reject(x, KU_CRL_SIGN)) - return 0; - return 1; + return !ku_reject(x, KU_CRL_SIGN); } /* @@ -836,55 +822,117 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, * is valid. Additional checks must be made on the chain. */ static int check_purpose_ocsp_helper(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { /* * Must be a valid CA. Should we really support the "I don't know" value * (2)? */ - if (require_ca) + if (non_leaf) return check_ca(x); /* Leaf certificate is checked in OCSP_verify() */ return 1; } static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { int i_ext; - /* If ca is true we must return if this is a valid CA certificate. */ - if (require_ca) + /* + * If non_leaf is true we must check if this is a valid CA certificate. + * The extra requirements by the CA/Browser Forum are not checked. + */ + if (non_leaf) return check_ca(x); + /* + * Key Usage is checked according to RFC 5280 and + * Extended Key Usage attributes is checked according to RFC 3161. + * The extra (and somewhat conflicting) CA/Browser Forum + * Baseline Requirements for the Issuance and Management of + * Publicly‐Trusted Code Signing Certificates, Version 3.0.0, + * Section 7.1.2.3: Code signing and Timestamp Certificate are not checked. + */ /* * Check the optional key usage field: * if Key Usage is present, it must be one of digitalSignature * and/or nonRepudiation (other values are not consistent and shall * be rejected). */ - if ((x->ex_flags & EXFLAG_KUSAGE) + if ((x->ex_flags & EXFLAG_KUSAGE) != 0 && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) return 0; /* Only timestamp key usage is permitted and it's required. */ - if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + if ((x->ex_flags & EXFLAG_XKUSAGE) == 0 || x->ex_xkusage != XKU_TIMESTAMP) return 0; /* Extended Key Usage MUST be critical */ i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); + if (i_ext >= 0 + && !X509_EXTENSION_get_critical(X509_get_ext((X509 *)x, i_ext))) + return 0; + return 1; +} + +static int check_purpose_code_sign(const X509_PURPOSE *xp, const X509 *x, + int non_leaf) +{ + int i_ext; + + /* + * If non_leaf is true we must check if this is a valid CA certificate. + * The extra requirements by the CA/Browser Forum are not checked. + */ + if (non_leaf) + return check_ca(x); + + /* + * Check the key usage and extended key usage fields: + * + * Reference: CA/Browser Forum, + * Baseline Requirements for the Issuance and Management of + * Publicly‐Trusted Code Signing Certificates, Version 3.0.0, + * Section 7.1.2.3: Code signing and Timestamp Certificate + * + * Checking covers Key Usage and Extended Key Usage attributes. + * The certificatePolicies, cRLDistributionPoints (CDP), and + * authorityInformationAccess (AIA) extensions are so far not checked. + */ + /* Key Usage */ + if ((x->ex_flags & EXFLAG_KUSAGE) == 0) + return 0; + if ((x->ex_kusage & KU_DIGITAL_SIGNATURE) == 0) + return 0; + if ((x->ex_kusage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN)) != 0) + return 0; + + /* Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID(x, NID_key_usage, -1); + if (i_ext < 0) + return 0; if (i_ext >= 0) { X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); if (!X509_EXTENSION_get_critical(ext)) return 0; } + /* Extended Key Usage */ + if ((x->ex_flags & EXFLAG_XKUSAGE) == 0) + return 0; + if ((x->ex_xkusage & XKU_CODE_SIGN) == 0) + return 0; + if ((x->ex_xkusage & (XKU_ANYEKU | XKU_SSL_SERVER)) != 0) + return 0; + return 1; + } static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x, - int require_ca) + int non_leaf) { return 1; } @@ -942,11 +990,12 @@ int ossl_x509_likely_issued(X509 *issuer, X509 *subject) */ int ossl_x509_signing_allowed(const X509 *issuer, const X509 *subject) { - if (subject->ex_flags & EXFLAG_PROXY) { + if ((subject->ex_flags & EXFLAG_PROXY) != 0) { if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; - } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) { return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + } return X509_V_OK; } @@ -970,11 +1019,11 @@ int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid) * GeneralName. So look for a DirName. There may be more than one but * we only take any notice of the first. */ - GENERAL_NAMES *gens; + GENERAL_NAMES *gens = akid->issuer; GENERAL_NAME *gen; X509_NAME *nm = NULL; int i; - gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); if (gen->type == GEN_DIRNAME) { @@ -1000,9 +1049,7 @@ uint32_t X509_get_key_usage(X509 *x) /* Call for side-effect of computing hash and caching extensions */ if (X509_check_purpose(x, -1, 0) != 1) return 0; - if (x->ex_flags & EXFLAG_KUSAGE) - return x->ex_kusage; - return UINT32_MAX; + return (x->ex_flags & EXFLAG_KUSAGE) != 0 ? x->ex_kusage : UINT32_MAX; } uint32_t X509_get_extended_key_usage(X509 *x) @@ -1010,9 +1057,7 @@ uint32_t X509_get_extended_key_usage(X509 *x) /* Call for side-effect of computing hash and caching extensions */ if (X509_check_purpose(x, -1, 0) != 1) return 0; - if (x->ex_flags & EXFLAG_XKUSAGE) - return x->ex_xkusage; - return UINT32_MAX; + return (x->ex_flags & EXFLAG_XKUSAGE) != 0 ? x->ex_xkusage : UINT32_MAX; } const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) diff --git a/crypto/x509/v3_san.c b/crypto/x509/v3_san.c index c081f02e19..7798505eec 100644 --- a/crypto/x509/v3_san.c +++ b/crypto/x509/v3_san.c @@ -307,7 +307,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, int i; if (gens == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); sk_GENERAL_NAME_free(gens); return NULL; } @@ -358,7 +358,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) num = sk_GENERAL_NAME_num(ialt); if (!sk_GENERAL_NAME_reserve(gens, num)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } @@ -386,7 +386,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, gens = sk_GENERAL_NAME_new_reserve(NULL, num); if (gens == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); sk_GENERAL_NAME_free(gens); return NULL; } @@ -449,14 +449,14 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) i--; } if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } gen->d.ia5 = email; email = NULL; gen->type = GEN_EMAIL; if (!sk_GENERAL_NAME_push(gens, gen)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; } gen = NULL; @@ -482,7 +482,7 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, gens = sk_GENERAL_NAME_new_reserve(NULL, num); if (gens == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); sk_GENERAL_NAME_free(gens); return NULL; } @@ -523,7 +523,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, else { gen = GENERAL_NAME_new(); if (gen == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } } @@ -581,7 +581,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, strlen(value))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } diff --git a/crypto/x509/v3_single_use.c b/crypto/x509/v3_single_use.c new file mode 100644 index 0000000000..50da6e1770 --- /dev/null +++ b/crypto/x509/v3_single_use.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_SINGLE_USE(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SINGLE_USE(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SINGLE_USE(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SINGLE_USE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The singleUse X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.1.2.5. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_single_use = { + NID_single_use, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SINGLE_USE, + (X509V3_EXT_S2I)s2i_SINGLE_USE, + 0, 0, + (X509V3_EXT_I2R)i2r_SINGLE_USE, + (X509V3_EXT_R2I)r2i_SINGLE_USE, + NULL +}; diff --git a/crypto/x509/v3_skid.c b/crypto/x509/v3_skid.c index 18223f2ef4..8657f4cdf2 100644 --- a/crypto/x509/v3_skid.c +++ b/crypto/x509/v3_skid.c @@ -37,7 +37,7 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, long length; if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } diff --git a/crypto/x509/v3_soa_id.c b/crypto/x509/v3_soa_id.c new file mode 100644 index 0000000000..8be5bd8aa5 --- /dev/null +++ b/crypto/x509/v3_soa_id.c @@ -0,0 +1,53 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include "ext_dat.h" + +static int i2r_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +/* + * The sOAIdentifier X.509v3 extension is defined in ITU Recommendation X.509 + * (2019), Section 17.3.2.1.1. See: https://www.itu.int/rec/T-REC-X.509-201910-I/en. + */ +const X509V3_EXT_METHOD ossl_v3_soa_identifier = { + NID_soa_identifier, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SOA_IDENTIFIER, + (X509V3_EXT_S2I)s2i_SOA_IDENTIFIER, + 0, 0, + (X509V3_EXT_I2R)i2r_SOA_IDENTIFIER, + (X509V3_EXT_R2I)r2i_SOA_IDENTIFIER, + NULL +}; diff --git a/crypto/x509/v3_sxnet.c b/crypto/x509/v3_sxnet.c index 5ac3bab354..8540f10d1e 100644 --- a/crypto/x509/v3_sxnet.c +++ b/crypto/x509/v3_sxnet.c @@ -135,7 +135,7 @@ int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, if ((izone = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(izone, lzone)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); ASN1_INTEGER_free(izone); return 0; } @@ -165,10 +165,14 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, return 0; } if (*psx == NULL) { - if ((sx = SXNET_new()) == NULL) + if ((sx = SXNET_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; - if (!ASN1_INTEGER_set(sx->version, 0)) + } + if (!ASN1_INTEGER_set(sx->version, 0)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; + } } else sx = *psx; if (SXNET_get_id_INTEGER(sx, zone)) { @@ -178,19 +182,24 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, return 0; } - if ((id = SXNETID_new()) == NULL) + if ((id = SXNETID_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; + } - if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen)) + if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen)){ + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; - if (!sk_SXNETID_push(sx->ids, id)) + } + if (!sk_SXNETID_push(sx->ids, id)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; + } id->zone = zone; *psx = sx; return 1; err: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); SXNETID_free(id); if (*psx == NULL) SXNET_free(sx); @@ -218,7 +227,7 @@ ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) if ((izone = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(izone, lzone)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); ASN1_INTEGER_free(izone); return NULL; } diff --git a/crypto/x509/v3_tlsf.c b/crypto/x509/v3_tlsf.c index a1446bc074..85dea65f35 100644 --- a/crypto/x509/v3_tlsf.c +++ b/crypto/x509/v3_tlsf.c @@ -96,7 +96,7 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, long tlsextid; if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); return NULL; } @@ -125,7 +125,7 @@ static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, if ((ai = ASN1_INTEGER_new()) == NULL || !ASN1_INTEGER_set(ai, tlsextid) || sk_ASN1_INTEGER_push(tlsf, ai) <= 0) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } /* So it doesn't get purged if an error occurs next time around */ diff --git a/crypto/x509/v3_utf8.c b/crypto/x509/v3_utf8.c index 51cfbf01cf..22345c3a65 100644 --- a/crypto/x509/v3_utf8.c +++ b/crypto/x509/v3_utf8.c @@ -35,10 +35,8 @@ char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); return NULL; } - if ((tmp = OPENSSL_malloc(utf8->length + 1)) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((tmp = OPENSSL_malloc(utf8->length + 1)) == NULL) return NULL; - } memcpy(tmp, utf8->data, utf8->length); tmp[utf8->length] = 0; return tmp; @@ -53,11 +51,11 @@ ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, return NULL; } if ((utf8 = ASN1_UTF8STRING_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } if (!ASN1_STRING_set((ASN1_STRING *)utf8, str, strlen(str))) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); ASN1_UTF8STRING_free(utf8); return NULL; } diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index f144dababb..1a18174995 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -56,8 +56,10 @@ static int x509v3_add_len_value(const char *name, const char *value, } if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL) goto err; - if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL) + if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); goto err; + } vtmp->section = NULL; vtmp->name = tname; vtmp->value = tvalue; @@ -65,7 +67,6 @@ static int x509v3_add_len_value(const char *name, const char *value, goto err; return 1; err: - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); if (sk_allocated) { sk_CONF_VALUE_free(*extlist); *extlist = NULL; @@ -146,7 +147,6 @@ static char *bignum_to_string(const BIGNUM *bn) len = strlen(tmp) + 3; ret = OPENSSL_malloc(len); if (ret == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); return NULL; } @@ -170,9 +170,10 @@ char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) if (!a) return NULL; - if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL - || (strtmp = bignum_to_string(bntmp)) == NULL) - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL) + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + else if ((strtmp = bignum_to_string(bntmp)) == NULL) + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); BN_free(bntmp); return strtmp; } @@ -184,9 +185,10 @@ char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) if (!a) return NULL; - if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL - || (strtmp = bignum_to_string(bntmp)) == NULL) - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL) + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + else if ((strtmp = bignum_to_string(bntmp)) == NULL) + ERR_raise(ERR_LIB_X509V3, ERR_R_X509V3_LIB); BN_free(bntmp); return strtmp; } @@ -204,7 +206,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) } bn = BN_new(); if (bn == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509V3, ERR_R_BN_LIB); return NULL; } if (value[0] == '-') { @@ -320,10 +322,8 @@ 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) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (linebuf == NULL) goto err; - } state = HDR_NAME; ntmp = NULL; /* Go through all characters */ @@ -715,7 +715,7 @@ static int wildcard_match(const unsigned char *prefix, size_t prefix_len, } /* IDNA labels cannot match partial wildcards */ if (!allow_idna && - subject_len >= 4 && OPENSSL_strncasecmp((char *)subject, "xn--", 4) == 0) + subject_len >= 4 && HAS_CASE_PREFIX((const char *)subject, "xn--")) return 0; /* The wildcard may match a literal '*' */ if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') @@ -775,7 +775,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len, || ('A' <= p[i] && p[i] <= 'Z') || ('0' <= p[i] && p[i] <= '9')) { if ((state & LABEL_START) != 0 - && len - i >= 4 && OPENSSL_strncasecmp((char *)&p[i], "xn--", 4) == 0) + && len - i >= 4 && HAS_CASE_PREFIX((const char *)&p[i], "xn--")) state |= LABEL_IDNA; state &= ~(LABEL_HYPHEN | LABEL_START); } else if (p[i] == '.') { diff --git a/crypto/x509/v3err.c b/crypto/x509/v3err.c index 6f38034c1a..6a75af4168 100644 --- a/crypto/x509/v3err.c +++ b/crypto/x509/v3err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OBJECT), "bad object"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OPTION), "bad option"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_VALUE), "bad value"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BN_TO_ASN1_INTEGER_ERROR), "bn to asn1 integer error"}, @@ -127,6 +129,7 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_OPTION), "unknown option"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_VALUE), "unknown value"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNSUPPORTED_OPTION), "unsupported option"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNSUPPORTED_TYPE), diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c index d9fe7a3791..3878bb3ef5 100644 --- a/crypto/x509/x509_att.c +++ b/crypto/x509/x509_att.c @@ -55,20 +55,28 @@ int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) { - if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; - + } + if (sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } return sk_X509_ATTRIBUTE_value(x, loc); } X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) { - X509_ATTRIBUTE *ret; - - if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; - ret = sk_X509_ATTRIBUTE_delete(x, loc); - return ret; + } + if (sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + return sk_X509_ATTRIBUTE_delete(x, loc); } STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, @@ -77,33 +85,34 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *new_attr = NULL; STACK_OF(X509_ATTRIBUTE) *sk = NULL; - if (x == NULL) { + if (x == NULL || attr == NULL) { ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; } - if (*x != NULL && X509at_get_attr_by_OBJ(*x, attr->object, -1) != -1) { ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE); return NULL; } if (*x == NULL) { - if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; + } } else { sk = *x; } if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) - goto err2; - if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) goto err; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); + goto err; + } if (*x == NULL) *x = sk; return sk; err: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); - err2: X509_ATTRIBUTE_free(new_attr); if (*x == NULL) sk_X509_ATTRIBUTE_free(sk); @@ -118,8 +127,9 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) { X509_ATTRIBUTE *attr; STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); - if (!attr) + if (attr == NULL) return 0; ret = X509at_add1_attr(x, attr); X509_ATTRIBUTE_free(attr); @@ -133,8 +143,9 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) { X509_ATTRIBUTE *attr; STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); - if (!attr) + if (attr == NULL) return 0; ret = X509at_add1_attr(x, attr); X509_ATTRIBUTE_free(attr); @@ -149,8 +160,9 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) { X509_ATTRIBUTE *attr; STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); - if (!attr) + if (attr == NULL) return 0; ret = X509at_add1_attr(x, attr); X509_ATTRIBUTE_free(attr); @@ -160,29 +172,26 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj, int lastpos, int type) { - int i; + int i = X509at_get_attr_by_OBJ(x, obj, lastpos); X509_ATTRIBUTE *at; - i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) return NULL; - if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + if (lastpos <= -2 && X509at_get_attr_by_OBJ(x, obj, i) != -1) return NULL; at = X509at_get_attr(x, i); - if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + if (lastpos <= -3 && X509_ATTRIBUTE_count(at) != 1) return NULL; return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); } STACK_OF(X509_ATTRIBUTE) *ossl_x509at_dup(const STACK_OF(X509_ATTRIBUTE) *x) { - int i, n; + int i, n = sk_X509_ATTRIBUTE_num(x); STACK_OF(X509_ATTRIBUTE) *sk = NULL; - n = sk_X509_ATTRIBUTE_num(x); for (i = 0; i < n; ++i) { - X509_ATTRIBUTE *attr = sk_X509_ATTRIBUTE_value(x, i); - - if (X509at_add1_attr(&sk, attr) == NULL) { + if (X509at_add1_attr(&sk, sk_X509_ATTRIBUTE_value(x, i)) == NULL) { sk_X509_ATTRIBUTE_pop_free(sk, X509_ATTRIBUTE_free); return NULL; } @@ -194,10 +203,9 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, const void *data, int len) { - ASN1_OBJECT *obj; + ASN1_OBJECT *obj = OBJ_nid2obj(nid); X509_ATTRIBUTE *ret; - obj = OBJ_nid2obj(nid); if (obj == NULL) { ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_NID); return NULL; @@ -215,24 +223,25 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, { X509_ATTRIBUTE *ret; - if ((attr == NULL) || (*attr == NULL)) { + if (attr == NULL || *attr == NULL) { if ((ret = X509_ATTRIBUTE_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return NULL; } - } else + } else { ret = *attr; + } if (!X509_ATTRIBUTE_set1_object(ret, obj)) goto err; if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) goto err; - if ((attr != NULL) && (*attr == NULL)) + if (attr != NULL && *attr == NULL) *attr = ret; return ret; err: - if ((attr == NULL) || (ret != *attr)) + if (attr == NULL || ret != *attr) X509_ATTRIBUTE_free(ret); return NULL; } @@ -242,10 +251,9 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const unsigned char *bytes, int len) { - ASN1_OBJECT *obj; + ASN1_OBJECT *obj = OBJ_txt2obj(atrname, 0); X509_ATTRIBUTE *nattr; - obj = OBJ_txt2obj(atrname, 0); if (obj == NULL) { ERR_raise_data(ERR_LIB_X509, X509_R_INVALID_FIELD_NAME, "name=%s", atrname); @@ -258,8 +266,10 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) { - if ((attr == NULL) || (obj == NULL)) + if (attr == NULL || obj == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; + } ASN1_OBJECT_free(attr->object); attr->object = OBJ_dup(obj); return attr->object != NULL; @@ -271,21 +281,25 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, ASN1_TYPE *ttmp = NULL; ASN1_STRING *stmp = NULL; int atype = 0; - if (!attr) + + if (attr == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; - if (attrtype & MBSTRING_FLAG) { + } + if ((attrtype & MBSTRING_FLAG) != 0) { stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, OBJ_obj2nid(attr->object)); - if (!stmp) { + if (stmp == NULL) { ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return 0; } atype = stmp->type; } else if (len != -1) { - if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL) - goto err; - if (!ASN1_STRING_set(stmp, data, len)) + if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL + || !ASN1_STRING_set(stmp, data, len)) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; + } atype = attrtype; } /* @@ -297,20 +311,25 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, ASN1_STRING_free(stmp); return 1; } - if ((ttmp = ASN1_TYPE_new()) == NULL) + if ((ttmp = ASN1_TYPE_new()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; - if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { - if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + } + if (len == -1 && (attrtype & MBSTRING_FLAG) == 0) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; + } } else { ASN1_TYPE_set(ttmp, atype, stmp); stmp = NULL; } - if (!sk_ASN1_TYPE_push(attr->set, ttmp)) + if (!sk_ASN1_TYPE_push(attr->set, ttmp)) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; + } return 1; err: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ASN1_TYPE_free(ttmp); ASN1_STRING_free(stmp); return 0; @@ -325,17 +344,19 @@ int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) { - if (attr == NULL) + if (attr == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } return attr->object; } void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data) { - ASN1_TYPE *ttmp; - ttmp = X509_ATTRIBUTE_get0_type(attr, idx); - if (!ttmp) + ASN1_TYPE *ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + + if (ttmp == NULL) return NULL; if (atrtype == V_ASN1_BOOLEAN || atrtype == V_ASN1_NULL @@ -348,7 +369,9 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) { - if (attr == NULL) + if (attr == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } return sk_ASN1_TYPE_value(attr->set, idx); } diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 989fb8faa9..7094280d48 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -184,7 +184,7 @@ int X509_cmp(const X509 *a, const X509 *b) int ossl_x509_add_cert_new(STACK_OF(X509) **p_sk, X509 *cert, int flags) { if (*p_sk == NULL && (*p_sk = sk_X509_new_null()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } return X509_add_cert(*p_sk, cert, flags); @@ -216,7 +216,7 @@ int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags) } if (!sk_X509_insert(sk, cert, (flags & X509_ADD_FLAG_PREPEND) != 0 ? 0 : -1)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); return 0; } if ((flags & X509_ADD_FLAG_UP_REF) != 0) @@ -392,30 +392,38 @@ EVP_PKEY *X509_get_pubkey(X509 *x) return X509_PUBKEY_get(x->cert_info.key); } -int X509_check_private_key(const X509 *x, const EVP_PKEY *k) +int X509_check_private_key(const X509 *cert, const EVP_PKEY *pkey) { - const EVP_PKEY *xk; - int ret; + const EVP_PKEY *xk = X509_get0_pubkey(cert); - xk = X509_get0_pubkey(x); if (xk == NULL) { ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); return 0; } + return ossl_x509_check_private_key(xk, pkey); +} - switch (ret = EVP_PKEY_eq(xk, k)) { +int ossl_x509_check_private_key(const EVP_PKEY *x, const EVP_PKEY *pkey) +{ + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + switch (EVP_PKEY_eq(x, pkey)) { + case 1: + return 1; case 0: ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); - break; + return 0; case -1: ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); - break; + return 0; case -2: ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); - break; + /* fall thru */ + default: + return 0; } - - return ret > 0; } /* diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index 62aceb7aca..7838b703d4 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/x509_def.c b/crypto/x509/x509_def.c index b8bdcb4841..2851fbcd9f 100644 --- a/crypto/x509/x509_def.c +++ b/crypto/x509/x509_def.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index 37467935c9..226e45a737 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -20,7 +20,7 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_X509_FILETYPE), "bad x509 filetype"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, - {ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "can't check dh key"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERTIFICATE_VERIFICATION_FAILED), "certificate verification failed"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE), diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 8f123aaa5f..0ca7cb960d 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -19,10 +19,8 @@ X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) { X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->method = method; if (method->new_item != NULL && method->new_item(ret) == 0) { @@ -159,7 +157,6 @@ X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx) return ctx->store_ctx; } - static int x509_object_cmp(const X509_OBJECT *const *a, const X509_OBJECT *const *b) { @@ -186,93 +183,95 @@ X509_STORE *X509_STORE_new(void) { X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } ret->cache = 1; if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); goto err; } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } - ret->references = 1; + + if (!CRYPTO_NEW_REF(&ret->references, 1)) + goto err; return ret; err: X509_VERIFY_PARAM_free(ret->param); sk_X509_OBJECT_free(ret->objs); sk_X509_LOOKUP_free(ret->get_cert_methods); + CRYPTO_THREAD_lock_free(ret->lock); OPENSSL_free(ret); return NULL; } -void X509_STORE_free(X509_STORE *vfy) +void X509_STORE_free(X509_STORE *xs) { int i; STACK_OF(X509_LOOKUP) *sk; X509_LOOKUP *lu; - if (vfy == NULL) + if (xs == NULL) return; - CRYPTO_DOWN_REF(&vfy->references, &i, vfy->lock); - REF_PRINT_COUNT("X509_STORE", vfy); + CRYPTO_DOWN_REF(&xs->references, &i); + REF_PRINT_COUNT("X509_STORE", xs); if (i > 0) return; REF_ASSERT_ISNT(i < 0); - sk = vfy->get_cert_methods; + sk = xs->get_cert_methods; for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { lu = sk_X509_LOOKUP_value(sk, i); X509_LOOKUP_shutdown(lu); X509_LOOKUP_free(lu); } sk_X509_LOOKUP_free(sk); - sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free); + sk_X509_OBJECT_pop_free(xs->objs, X509_OBJECT_free); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); - X509_VERIFY_PARAM_free(vfy->param); - CRYPTO_THREAD_lock_free(vfy->lock); - OPENSSL_free(vfy); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, xs, &xs->ex_data); + X509_VERIFY_PARAM_free(xs->param); + CRYPTO_THREAD_lock_free(xs->lock); + CRYPTO_FREE_REF(&xs->references); + OPENSSL_free(xs); } -int X509_STORE_up_ref(X509_STORE *vfy) +int X509_STORE_up_ref(X509_STORE *xs) { int i; - if (CRYPTO_UP_REF(&vfy->references, &i, vfy->lock) <= 0) + if (CRYPTO_UP_REF(&xs->references, &i) <= 0) return 0; - REF_PRINT_COUNT("X509_STORE", vfy); + REF_PRINT_COUNT("X509_STORE", xs); REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); + return i > 1 ? 1 : 0; } -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *xs, X509_LOOKUP_METHOD *m) { int i; STACK_OF(X509_LOOKUP) *sk; X509_LOOKUP *lu; - sk = v->get_cert_methods; + sk = xs->get_cert_methods; for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { lu = sk_X509_LOOKUP_value(sk, i); if (m == lu->method) { @@ -282,20 +281,21 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) /* a new one */ lu = X509_LOOKUP_new(m); if (lu == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); return NULL; } - lu->store_ctx = v; - if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) + lu->store_ctx = xs; + if (sk_X509_LOOKUP_push(xs->get_cert_methods, lu)) return lu; - /* malloc failed */ - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + /* sk_X509_LOOKUP_push() failed */ + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); X509_LOOKUP_free(lu); return NULL; } -X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, +/* Also fill the cache (ctx->store->objs) with all matching certificates. */ +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name) { @@ -303,19 +303,26 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, if (ret == NULL) return NULL; - if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) { + if (!X509_STORE_CTX_get_by_subject(ctx, type, name, ret)) { X509_OBJECT_free(ret); return NULL; } return ret; } -/* Also fill the cache with all matching certificates */ -int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, - X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret) +/* + * May be called with |ret| == NULL just for the side effect of + * caching all certs matching the given subject DN in |ctx->store->objs|. + * Returns 1 if successful, + * 0 if not found or X509_LOOKUP_by_subject_ex() returns an error, + * -1 on failure + */ +static int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + X509_OBJECT *ret) { - X509_STORE *store = vs->store; + X509_STORE *store = ctx->store; X509_LOOKUP *lu; X509_OBJECT stmp, *tmp; int i, j; @@ -332,7 +339,8 @@ int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, if (!sk_X509_OBJECT_is_sorted(store->objs)) { X509_STORE_unlock(store); /* Take a write lock instead of a read lock */ - X509_STORE_lock(store); + if (!X509_STORE_lock(store)) + return 0; /* * Another thread might have sorted it in the meantime. But if so, * sk_X509_OBJECT_sort() exits early. @@ -345,9 +353,13 @@ int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, if (tmp == NULL || type == X509_LU_CRL) { for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) { lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); - j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, vs->libctx, - vs->propq); - if (j) { + if (lu->skip) + continue; + if (lu->method == NULL) + return -1; + j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, + ctx->libctx, ctx->propq); + if (j != 0) { /* non-zero value is considered success here */ tmp = &stmp; break; } @@ -355,17 +367,24 @@ int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, if (tmp == NULL) return 0; } - if (!X509_OBJECT_up_ref_count(tmp)) - return 0; + return -1; ret->type = tmp->type; ret->data.ptr = tmp->data.ptr; - return 1; } -static int x509_store_add(X509_STORE *store, void *x, int crl) { +/* Also fill the cache |ctx->store->objs| with all matching certificates. */ +int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *ctx, + X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) +{ + return ossl_x509_store_ctx_get_by_subject(ctx, type, name, ret) > 0; +} + +static int x509_store_add(X509_STORE *store, void *x, int crl) +{ X509_OBJECT *obj; int ret = 0, added = 0; @@ -408,19 +427,19 @@ static int x509_store_add(X509_STORE *store, void *x, int crl) { return ret; } -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) +int X509_STORE_add_cert(X509_STORE *xs, X509 *x) { - if (!x509_store_add(ctx, x, 0)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (!x509_store_add(xs, x, 0)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); return 0; } return 1; } -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) +int X509_STORE_add_crl(X509_STORE *xs, X509_CRL *x) { - if (!x509_store_add(ctx, x, 1)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (!x509_store_add(xs, x, 1)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); return 0; } return 1; @@ -462,10 +481,8 @@ X509_OBJECT *X509_OBJECT_new(void) { X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } ret->type = X509_LU_NONE; return ret; } @@ -514,6 +531,7 @@ void X509_OBJECT_free(X509_OBJECT *a) OPENSSL_free(a); } +/* Returns -1 if not found, but also on error */ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, const X509_NAME *name, int *pnmatch) { @@ -532,6 +550,7 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */ break; case X509_LU_NONE: + default: /* abort(); */ return -1; } @@ -552,16 +571,16 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, const X509_NAME *name) { - int idx; - idx = X509_OBJECT_idx_by_subject(h, type, name); + int idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) return NULL; return sk_X509_OBJECT_value(h, idx); } -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v) +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs) { - return v->objs; + return xs->objs; } STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) @@ -579,6 +598,7 @@ STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) if (!X509_STORE_lock(store)) goto out_free; + sk_X509_OBJECT_sort(store->objs); objs = X509_STORE_get0_objects(store); for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); @@ -593,10 +613,11 @@ STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) err: X509_STORE_unlock(store); out_free: - sk_X509_pop_free(sk, X509_free); + OSSL_STACK_OF_X509_free(sk); return NULL; } +/* Returns NULL on internal/fatal error, empty stack if not found */ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, const X509_NAME *nm) { @@ -607,11 +628,12 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_STORE *store = ctx->store; if (store == NULL) - return NULL; + return sk_X509_new_null(); if (!X509_STORE_lock(store)) return NULL; + sk_X509_OBJECT_sort(store->objs); idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { /* @@ -621,41 +643,46 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_OBJECT *xobj = X509_OBJECT_new(); X509_STORE_unlock(store); - if (xobj == NULL) return NULL; - if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) { + i = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_X509, nm, xobj); + if (i <= 0) { X509_OBJECT_free(xobj); - return NULL; + return i < 0 ? NULL : sk_X509_new_null(); } X509_OBJECT_free(xobj); if (!X509_STORE_lock(store)) return NULL; + sk_X509_OBJECT_sort(store->objs); idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt); if (idx < 0) { - X509_STORE_unlock(store); - return NULL; + sk = sk_X509_new_null(); + goto end; } } sk = sk_X509_new_null(); + if (sk == NULL) + goto end; for (i = 0; i < cnt; i++, idx++) { obj = sk_X509_OBJECT_value(store->objs, idx); x = obj->data.x509; if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { X509_STORE_unlock(store); - sk_X509_pop_free(sk, X509_free); + OSSL_STACK_OF_X509_free(sk); return NULL; } } + end: X509_STORE_unlock(store); return sk; } +/* Returns NULL on internal/fatal error, empty stack if not found */ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx, const X509_NAME *nm) { - int i, idx, cnt; + int i = 1, idx, cnt; STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null(); X509_CRL *x; X509_OBJECT *obj, *xobj = X509_OBJECT_new(); @@ -663,23 +690,25 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx, /* Always do lookup to possibly add new CRLs to cache */ if (sk == NULL - || xobj == NULL - || store == NULL - || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) { + || xobj == NULL + || (i = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_CRL, + nm, xobj)) < 0) { X509_OBJECT_free(xobj); sk_X509_CRL_free(sk); return NULL; } X509_OBJECT_free(xobj); + if (i == 0) + return sk; if (!X509_STORE_lock(store)) { sk_X509_CRL_free(sk); return NULL; } + sk_X509_OBJECT_sort(store->objs); idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt); if (idx < 0) { X509_STORE_unlock(store); - sk_X509_CRL_free(sk); - return NULL; + return sk; } for (i = 0; i < cnt; i++, idx++) { @@ -723,8 +752,9 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, } else if (x->type == X509_LU_CRL) { if (X509_CRL_match(obj->data.crl, x->data.crl) == 0) return obj; - } else + } else { return obj; + } } return NULL; } @@ -749,10 +779,10 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) return -1; *issuer = NULL; xn = X509_get_issuer_name(x); - ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj); + ok = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_X509, xn, obj); if (ok != 1) { X509_OBJECT_free(obj); - return 0; + return ok; } /* If certificate matches and is currently valid all OK */ if (ctx->check_issued(ctx, x, obj->data.x509)) { @@ -779,6 +809,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) if (!X509_STORE_lock(store)) return 0; + sk_X509_OBJECT_sort(store->objs); idx = x509_object_idx_cnt(store->objs, X509_LU_X509, xn, &nmatch); if (idx != -1) { /* should be true as we've had at least one match */ /* Look through all matching certs for suitable issuer */ @@ -813,176 +844,176 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) return ret; } -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +int X509_STORE_set_flags(X509_STORE *xs, unsigned long flags) { - return X509_VERIFY_PARAM_set_flags(ctx->param, flags); + return X509_VERIFY_PARAM_set_flags(xs->param, flags); } -int X509_STORE_set_depth(X509_STORE *ctx, int depth) +int X509_STORE_set_depth(X509_STORE *xs, int depth) { - X509_VERIFY_PARAM_set_depth(ctx->param, depth); + X509_VERIFY_PARAM_set_depth(xs->param, depth); return 1; } -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +int X509_STORE_set_purpose(X509_STORE *xs, int purpose) { - return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); + return X509_VERIFY_PARAM_set_purpose(xs->param, purpose); } -int X509_STORE_set_trust(X509_STORE *ctx, int trust) +int X509_STORE_set_trust(X509_STORE *xs, int trust) { - return X509_VERIFY_PARAM_set_trust(ctx->param, trust); + return X509_VERIFY_PARAM_set_trust(xs->param, trust); } -int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *param) +int X509_STORE_set1_param(X509_STORE *xs, const X509_VERIFY_PARAM *param) { - return X509_VERIFY_PARAM_set1(ctx->param, param); + return X509_VERIFY_PARAM_set1(xs->param, param); } -X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx) +X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *xs) { - return ctx->param; + return xs->param; } -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) +void X509_STORE_set_verify(X509_STORE *xs, X509_STORE_CTX_verify_fn verify) { - ctx->verify = verify; + xs->verify = verify; } -X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx) +X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *xs) { - return ctx->verify; + return xs->verify; } -void X509_STORE_set_verify_cb(X509_STORE *ctx, +void X509_STORE_set_verify_cb(X509_STORE *xs, X509_STORE_CTX_verify_cb verify_cb) { - ctx->verify_cb = verify_cb; + xs->verify_cb = verify_cb; } -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *xs) { - return ctx->verify_cb; + return xs->verify_cb; } -void X509_STORE_set_get_issuer(X509_STORE *ctx, +void X509_STORE_set_get_issuer(X509_STORE *xs, X509_STORE_CTX_get_issuer_fn get_issuer) { - ctx->get_issuer = get_issuer; + xs->get_issuer = get_issuer; } -X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx) +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *xs) { - return ctx->get_issuer; + return xs->get_issuer; } -void X509_STORE_set_check_issued(X509_STORE *ctx, +void X509_STORE_set_check_issued(X509_STORE *xs, X509_STORE_CTX_check_issued_fn check_issued) { - ctx->check_issued = check_issued; + xs->check_issued = check_issued; } -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx) +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *xs) { - return ctx->check_issued; + return xs->check_issued; } -void X509_STORE_set_check_revocation(X509_STORE *ctx, - X509_STORE_CTX_check_revocation_fn check_revocation) +void X509_STORE_set_check_revocation(X509_STORE *xs, + X509_STORE_CTX_check_revocation_fn cb) { - ctx->check_revocation = check_revocation; + xs->check_revocation = cb; } -X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *ctx) +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(const X509_STORE *xs) { - return ctx->check_revocation; + return xs->check_revocation; } -void X509_STORE_set_get_crl(X509_STORE *ctx, +void X509_STORE_set_get_crl(X509_STORE *xs, X509_STORE_CTX_get_crl_fn get_crl) { - ctx->get_crl = get_crl; + xs->get_crl = get_crl; } -X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx) +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *xs) { - return ctx->get_crl; + return xs->get_crl; } -void X509_STORE_set_check_crl(X509_STORE *ctx, +void X509_STORE_set_check_crl(X509_STORE *xs, X509_STORE_CTX_check_crl_fn check_crl) { - ctx->check_crl = check_crl; + xs->check_crl = check_crl; } -X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx) +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *xs) { - return ctx->check_crl; + return xs->check_crl; } -void X509_STORE_set_cert_crl(X509_STORE *ctx, +void X509_STORE_set_cert_crl(X509_STORE *xs, X509_STORE_CTX_cert_crl_fn cert_crl) { - ctx->cert_crl = cert_crl; + xs->cert_crl = cert_crl; } -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx) +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *xs) { - return ctx->cert_crl; + return xs->cert_crl; } -void X509_STORE_set_check_policy(X509_STORE *ctx, +void X509_STORE_set_check_policy(X509_STORE *xs, X509_STORE_CTX_check_policy_fn check_policy) { - ctx->check_policy = check_policy; + xs->check_policy = check_policy; } -X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx) +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *xs) { - return ctx->check_policy; + return xs->check_policy; } -void X509_STORE_set_lookup_certs(X509_STORE *ctx, +void X509_STORE_set_lookup_certs(X509_STORE *xs, X509_STORE_CTX_lookup_certs_fn lookup_certs) { - ctx->lookup_certs = lookup_certs; + xs->lookup_certs = lookup_certs; } -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx) +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *xs) { - return ctx->lookup_certs; + return xs->lookup_certs; } -void X509_STORE_set_lookup_crls(X509_STORE *ctx, +void X509_STORE_set_lookup_crls(X509_STORE *xs, X509_STORE_CTX_lookup_crls_fn lookup_crls) { - ctx->lookup_crls = lookup_crls; + xs->lookup_crls = lookup_crls; } -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *xs) { - return ctx->lookup_crls; + return xs->lookup_crls; } -void X509_STORE_set_cleanup(X509_STORE *ctx, - X509_STORE_CTX_cleanup_fn ctx_cleanup) +void X509_STORE_set_cleanup(X509_STORE *xs, + X509_STORE_CTX_cleanup_fn cleanup) { - ctx->cleanup = ctx_cleanup; + xs->cleanup = cleanup; } -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx) +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *xs) { - return ctx->cleanup; + return xs->cleanup; } -int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data) +int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data) { - return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); + return CRYPTO_set_ex_data(&xs->ex_data, idx, data); } -void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx) +void *X509_STORE_get_ex_data(const X509_STORE *xs, int idx) { - return CRYPTO_get_ex_data(&ctx->ex_data, idx); + return CRYPTO_get_ex_data(&xs->ex_data, idx); } X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx) diff --git a/crypto/x509/x509_meth.c b/crypto/x509/x509_meth.c index a8eedd9b59..305fe4c6d3 100644 --- a/crypto/x509/x509_meth.c +++ b/crypto/x509/x509_meth.c @@ -23,10 +23,8 @@ X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name) if (method != NULL) { method->name = OPENSSL_strdup(name); - if (method->name == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (method->name == NULL) goto err; - } } return method; diff --git a/crypto/x509/x509_obj.c b/crypto/x509/x509_obj.c index 12c6d6f78b..2af7203b01 100644 --- a/crypto/x509/x509_obj.c +++ b/crypto/x509/x509_obj.c @@ -41,9 +41,9 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) if (buf == NULL) { if ((b = BUF_MEM_new()) == NULL) - goto err; + goto buferr; if (!BUF_MEM_grow(b, 200)) - goto err; + goto buferr; b->data[0] = '\0'; len = 200; } else if (len == 0) { @@ -124,7 +124,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) } if (b != NULL) { if (!BUF_MEM_grow(b, l + 1)) - goto err; + goto buferr; p = &(b->data[lold]); } else if (l > len) { break; @@ -179,8 +179,8 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) if (i == 0) *p = '\0'; return p; - err: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + buferr: + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); end: BUF_MEM_free(b); return NULL; diff --git a/crypto/x509/x509_r2x.c b/crypto/x509/x509_r2x.c index c7f6181c44..a6ea8e36a0 100644 --- a/crypto/x509/x509_r2x.c +++ b/crypto/x509/x509_r2x.c @@ -25,7 +25,7 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) EVP_PKEY *pubkey = NULL; if ((ret = X509_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return NULL; } diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c index 5428bdaf4c..fa73b331a5 100644 --- a/crypto/x509/x509_req.c +++ b/crypto/x509/x509_req.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,7 +28,7 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) ret = X509_REQ_new_ex(x->libctx, x->propq); if (ret == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } @@ -67,7 +67,7 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) return X509_PUBKEY_get(req->req_info.pubkey); } -EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req) +EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req) { if (req == NULL) return NULL; @@ -79,28 +79,9 @@ X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req) return req->req_info.pubkey; } -int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +int X509_REQ_check_private_key(const X509_REQ *req, EVP_PKEY *pkey) { - EVP_PKEY *xk = NULL; - int ok = 0; - - xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_eq(xk, k)) { - case 1: - ok = 1; - break; - case 0: - ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); - break; - case -2: - ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); - } - - EVP_PKEY_free(xk); - return ok; + return ossl_x509_check_private_key(X509_REQ_get0_pubkey(req), pkey); } /* @@ -147,7 +128,7 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) return NULL; for (pnid = ext_nids; *pnid != NID_undef; pnid++) { idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); - if (idx == -1) + if (idx < 0) continue; attr = X509_REQ_get_attr(req, idx); ext = X509_ATTRIBUTE_get0_type(attr, 0); @@ -155,8 +136,10 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) } if (ext == NULL) /* no extensions is not an error */ return sk_X509_EXTENSION_new_null(); - if (ext->type != V_ASN1_SEQUENCE) + if (ext->type != V_ASN1_SEQUENCE) { + ERR_raise(ERR_LIB_X509, X509_R_WRONG_TYPE); return NULL; + } p = ext->value.sequence->data; return (STACK_OF(X509_EXTENSION) *) ASN1_item_d2i(NULL, &p, ext->value.sequence->length, diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index d8ddde8aaa..0881be7292 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,16 +23,22 @@ int X509_set_version(X509 *x, long version) { if (x == NULL) return 0; - if (version == 0) { + if (version == X509_get_version(x)) + return 1; /* avoid needless modification even re-allocation */ + if (version == X509_VERSION_1) { ASN1_INTEGER_free(x->cert_info.version); x->cert_info.version = NULL; + x->cert_info.enc.modified = 1; return 1; } if (x->cert_info.version == NULL) { if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL) return 0; } - return ASN1_INTEGER_set(x->cert_info.version, version); + if (!ASN1_INTEGER_set(x->cert_info.version, version)) + return 0; + x->cert_info.enc.modified = 1; + return 1; } int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) @@ -44,68 +50,78 @@ int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) in = &x->cert_info.serialNumber; if (in != serial) return ASN1_STRING_copy(in, serial); + x->cert_info.enc.modified = 1; return 1; } int X509_set_issuer_name(X509 *x, const X509_NAME *name) { - if (x == NULL) + if (x == NULL || !X509_NAME_set(&x->cert_info.issuer, name)) return 0; - return X509_NAME_set(&x->cert_info.issuer, name); + x->cert_info.enc.modified = 1; + return 1; } int X509_set_subject_name(X509 *x, const X509_NAME *name) { - if (x == NULL) + if (x == NULL || !X509_NAME_set(&x->cert_info.subject, name)) return 0; - return X509_NAME_set(&x->cert_info.subject, name); + x->cert_info.enc.modified = 1; + return 1; } -int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm) +int ossl_x509_set1_time(int *modified, ASN1_TIME **ptm, const ASN1_TIME *tm) { - ASN1_TIME *in; - in = *ptm; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(*ptm); - *ptm = in; - } - } - return (in != NULL); + ASN1_TIME *new; + + if (*ptm == tm) + return 1; + new = ASN1_STRING_dup(tm); + if (tm != NULL && new == NULL) + return 0; + ASN1_TIME_free(*ptm); + *ptm = new; + if (modified != NULL) + *modified = 1; + return 1; } int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) { - if (x == NULL) + if (x == NULL || tm == NULL) return 0; - return ossl_x509_set1_time(&x->cert_info.validity.notBefore, tm); + return ossl_x509_set1_time(&x->cert_info.enc.modified, + &x->cert_info.validity.notBefore, tm); } int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) { - if (x == NULL) + if (x == NULL || tm == NULL) return 0; - return ossl_x509_set1_time(&x->cert_info.validity.notAfter, tm); + return ossl_x509_set1_time(&x->cert_info.enc.modified, + &x->cert_info.validity.notAfter, tm); } int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) { if (x == NULL) return 0; - return X509_PUBKEY_set(&(x->cert_info.key), pkey); + if (!X509_PUBKEY_set(&(x->cert_info.key), pkey)) + return 0; + x->cert_info.enc.modified = 1; + return 1; } int X509_up_ref(X509 *x) { int i; - if (CRYPTO_UP_REF(&x->references, &i, x->lock) <= 0) + if (CRYPTO_UP_REF(&x->references, &i) <= 0) return 0; REF_PRINT_COUNT("X509", x); REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); + return i > 1; } long X509_get_version(const X509 *x) @@ -194,7 +210,7 @@ int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, /* Modify *siginf according to alg and sig. Return 1 on success, else 0. */ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, - const ASN1_STRING *sig) + const ASN1_STRING *sig, const EVP_PKEY *pubkey) { int pknid, mdnid; const EVP_MD *md; @@ -216,12 +232,20 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, case NID_undef: /* If we have one, use a custom handler for this algorithm */ ameth = EVP_PKEY_asn1_find(NULL, pknid); - if (ameth == NULL || ameth->siginf_set == NULL - || !ameth->siginf_set(siginf, alg, sig)) { - ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET); - return 0; + if (ameth != NULL && ameth->siginf_set != NULL + && ameth->siginf_set(siginf, alg, sig)) + break; + if (pubkey != NULL) { + int secbits; + + secbits = EVP_PKEY_get_security_bits(pubkey); + if (secbits != 0) { + siginf->secbits = secbits; + break; + } } - break; + ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET); + return 0; /* * SHA1 and MD5 are known to be broken. Reduce security bits so that * they're no longer accepted at security level 1. @@ -272,5 +296,6 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, /* Returns 1 on success, 0 on failure */ int ossl_x509_init_sig_info(X509 *x) { - return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature); + return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature, + X509_PUBKEY_get0(x->cert_info.key)); } diff --git a/crypto/x509/x509_trust.c b/crypto/x509/x509_trust.c index fd77b0c6fe..1a4345f2fe 100644 --- a/crypto/x509/x509_trust.c +++ b/crypto/x509/x509_trust.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,6 +62,7 @@ int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, return oldtrust; } +/* Returns X509_TRUST_TRUSTED, X509_TRUST_REJECTED, or X509_TRUST_UNTRUSTED */ int X509_check_trust(X509 *x, int id, int flags) { X509_TRUST *pt; @@ -104,6 +105,8 @@ int X509_TRUST_get_by_id(int id) if (trtable == NULL) return -1; tmp.trust = id; + /* Ideally, this would be done under lock */ + sk_X509_TRUST_sort(trtable); idx = sk_X509_TRUST_find(trtable, &tmp); if (idx < 0) return -1; @@ -135,10 +138,8 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), idx = X509_TRUST_get_by_id(id); /* Need a new entry */ if (idx < 0) { - if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) return 0; - } trtmp->flags = X509_TRUST_DYNAMIC; } else trtmp = X509_TRUST_get0(idx); @@ -147,10 +148,8 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name); /* dup supplied name */ - if ((trtmp->name = OPENSSL_strdup(name)) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if ((trtmp->name = OPENSSL_strdup(name)) == NULL) goto err; - } /* Keep the dynamic flag of existing entry */ trtmp->flags &= X509_TRUST_DYNAMIC; /* Set all other flags */ @@ -165,11 +164,11 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), if (idx < 0) { if (trtable == NULL && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); - goto err;; + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); + goto err; } if (!sk_X509_TRUST_push(trtable, trtmp)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } } @@ -253,7 +252,7 @@ static int obj_trust(int id, X509 *x, int flags) X509_CERT_AUX *ax = x->aux; int i; - if (ax && ax->reject) { + if (ax != NULL && ax->reject != NULL) { for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i); int nid = OBJ_obj2nid(obj); @@ -264,7 +263,7 @@ static int obj_trust(int id, X509 *x, int flags) } } - if (ax && ax->trust) { + if (ax != NULL && ax->trust != NULL) { for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i); int nid = OBJ_obj2nid(obj); @@ -276,7 +275,7 @@ static int obj_trust(int id, X509 *x, int flags) /* * Reject when explicit trust EKU are set and none match. * - * Returning untrusted is enough for for full chains that end in + * Returning untrusted is enough for full chains that end in * self-signed roots, because when explicit trust is specified it * suppresses the default blanket trust of self-signed objects. * diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index 61d41117e2..e825ce2db8 100644 --- a/crypto/x509/x509_txt.c +++ b/crypto/x509/x509_txt.c @@ -212,6 +212,8 @@ const char *X509_verify_cert_error_string(long n) return "Using cert extension requires at least X509v3"; case X509_V_ERR_EC_KEY_EXPLICIT_PARAMS: return "Certificate public key has explicit ECC parameters"; + case X509_V_ERR_RPK_UNTRUSTED: + return "Raw public key untrusted, no trusted keys configured"; /* * Entries must be kept consistent with include/openssl/x509_vfy.h.in diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c index adbd676fcb..c29856e5b1 100644 --- a/crypto/x509/x509_v3.c +++ b/crypto/x509/x509_v3.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -105,12 +105,14 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, if (x == NULL) { ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); - goto err2; + goto err; } if (*x == NULL) { - if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; + } } else sk = *x; @@ -120,16 +122,18 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, else if (loc < 0) loc = n; - if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) - goto err2; - if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; + } + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); + goto err; + } if (*x == NULL) *x = sk; return sk; err: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); - err2: X509_EXTENSION_free(new_ex); if (x != NULL && *x == NULL) sk_X509_EXTENSION_free(sk); @@ -162,7 +166,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, if ((ex == NULL) || (*ex == NULL)) { if ((ret = X509_EXTENSION_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return NULL; } } else diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index d19efeaa99..1794c14e99 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -41,9 +41,13 @@ #define CRL_SCORE_AKID 0x004 /* CRL issuer matches CRL AKID */ #define CRL_SCORE_TIME_DELTA 0x002 /* Have a delta CRL with valid times */ +static int x509_verify_x509(X509_STORE_CTX *ctx); +static int x509_verify_rpk(X509_STORE_CTX *ctx); static int build_chain(X509_STORE_CTX *ctx); static int verify_chain(X509_STORE_CTX *ctx); +static int verify_rpk(X509_STORE_CTX *ctx); static int dane_verify(X509_STORE_CTX *ctx); +static int dane_verify_rpk(X509_STORE_CTX *ctx); static int null_callback(int ok, X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); @@ -56,7 +60,8 @@ static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); static int check_dane_issuer(X509_STORE_CTX *ctx, int depth); -static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); +static int check_cert_key_level(X509_STORE_CTX *ctx, X509 *cert); +static int check_key_level(X509_STORE_CTX *ctx, EVP_PKEY *pkey); static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert); static int check_curve(X509 *cert); @@ -124,6 +129,7 @@ static int lookup_cert_match(X509 **result, X509_STORE_CTX *ctx, X509 *x) ERR_pop_to_mark(); if (certs == NULL) return -1; + /* Look for exact match */ for (i = 0; i < sk_X509_num(certs); i++) { xtmp = sk_X509_value(certs, i); @@ -138,7 +144,7 @@ static int lookup_cert_match(X509 **result, X509_STORE_CTX *ctx, X509 *x) else *result = xtmp; } - sk_X509_pop_free(certs, X509_free); + OSSL_STACK_OF_X509_free(certs); return ret; } @@ -147,7 +153,7 @@ static int lookup_cert_match(X509 **result, X509_STORE_CTX *ctx, X509 *x) * The error code is set to |err| if |err| is not X509_V_OK, else * |ctx->error| is left unchanged (under the assumption it is set elsewhere). * The error depth is |depth| if >= 0, else it defaults to |ctx->error_depth|. - * The error cert is |x| if not NULL, else defaults to the chain cert at depth. + * The error cert is |x| if not NULL, else the cert in |ctx->chain| at |depth|. * * Returns 0 to abort verification with an error, non-zero to continue. */ @@ -157,7 +163,7 @@ static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) depth = ctx->error_depth; else ctx->error_depth = depth; - ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); + ctx->current_cert = x != NULL ? x : sk_X509_value(ctx->chain, depth); if (err != X509_V_OK) ctx->error = err; return ctx->verify_cb(0, ctx); @@ -180,6 +186,7 @@ static int verify_cb_crl(X509_STORE_CTX *ctx, int err) return ctx->verify_cb(0, ctx); } +/* Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int check_auth_level(X509_STORE_CTX *ctx) { int i; @@ -195,7 +202,7 @@ static int check_auth_level(X509_STORE_CTX *ctx) * We've already checked the security of the leaf key, so here we only * check the security of issuer keys. */ - CB_FAIL_IF(i > 0 && !check_key_level(ctx, cert), + CB_FAIL_IF(i > 0 && !check_cert_key_level(ctx, cert), ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL); /* * We also check the signature algorithm security of all certificates @@ -207,7 +214,24 @@ static int check_auth_level(X509_STORE_CTX *ctx) return 1; } -/* Returns -1 on internal error */ +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ +static int verify_rpk(X509_STORE_CTX *ctx) +{ + /* Not much to verify on a RPK */ + if (ctx->verify != NULL) + return ctx->verify(ctx); + + return !!ctx->verify_cb(ctx->error == X509_V_OK, ctx); +} + + +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ static int verify_chain(X509_STORE_CTX *ctx) { int err; @@ -253,19 +277,58 @@ int X509_STORE_CTX_verify(X509_STORE_CTX *ctx) ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return -1; } + if (ctx->rpk != NULL) + return x509_verify_rpk(ctx); if (ctx->cert == NULL && sk_X509_num(ctx->untrusted) >= 1) ctx->cert = sk_X509_value(ctx->untrusted, 0); - return X509_verify_cert(ctx); + return x509_verify_x509(ctx); } int X509_verify_cert(X509_STORE_CTX *ctx) { - int ret; - if (ctx == NULL) { ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return -1; } + return (ctx->rpk != NULL) ? x509_verify_rpk(ctx) : x509_verify_x509(ctx); +} + +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ +static int x509_verify_rpk(X509_STORE_CTX *ctx) +{ + int ret; + + /* If the peer's public key is too weak, we can stop early. */ + if (!check_key_level(ctx, ctx->rpk) + && verify_cb_cert(ctx, NULL, 0, X509_V_ERR_EE_KEY_TOO_SMALL) == 0) + return 0; + + /* Barring any data to verify the RPK, simply report it as untrusted */ + ctx->error = X509_V_ERR_RPK_UNTRUSTED; + + ret = DANETLS_ENABLED(ctx->dane) ? dane_verify_rpk(ctx) : verify_rpk(ctx); + + /* + * Safety-net. If we are returning an error, we must also set ctx->error, + * so that the chain is not considered verified should the error be ignored + * (e.g. TLS with SSL_VERIFY_NONE). + */ + if (ret <= 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + return ret; +} + +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ +static int x509_verify_x509(X509_STORE_CTX *ctx) +{ + int ret; + if (ctx->cert == NULL) { ERR_raise(ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); ctx->error = X509_V_ERR_INVALID_CALL; @@ -289,7 +352,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) ctx->num_untrusted = 1; /* If the peer's public key is too weak, we can stop early. */ - CB_FAIL_IF(!check_key_level(ctx, ctx->cert), + CB_FAIL_IF(!check_cert_key_level(ctx, ctx->cert), ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL); ret = DANETLS_ENABLED(ctx->dane) ? dane_verify(ctx) : verify_chain(ctx); @@ -340,7 +403,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) return rv; } -/* Check that the given certificate 'x' is issued by the certificate 'issuer' */ +/* Check that the given certificate |x| is issued by the certificate |issuer| */ static int check_issued(ossl_unused X509_STORE_CTX *ctx, X509 *x, X509 *issuer) { int err = ossl_x509_likely_issued(issuer, x); @@ -361,17 +424,16 @@ static int check_issued(ossl_unused X509_STORE_CTX *ctx, X509 *x, X509 *issuer) static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { *issuer = find_issuer(ctx, ctx->other_ctx, x); - if (*issuer != NULL) - return X509_up_ref(*issuer) ? 1 : -1; - return 0; + if (*issuer == NULL) + return 0; + return X509_up_ref(*issuer) ? 1 : -1; } /*- * Alternative lookup method: look from a STACK stored in other_ctx. - * Returns NULL on internal error (such as out of memory). + * Returns NULL on internal/fatal error, empty stack if not found. */ -static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, - const X509_NAME *nm) +static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, const X509_NAME *nm) { STACK_OF(X509) *sk = sk_X509_new_null(); X509 *x; @@ -383,7 +445,7 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, x = sk_X509_value(ctx->other_ctx, i); if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) { if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { - sk_X509_pop_free(sk, X509_free); + OSSL_STACK_OF_X509_free(sk); ctx->error = X509_V_ERR_OUT_OF_MEM; return NULL; } @@ -395,7 +457,7 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, /* * Check EE or CA certificate purpose. For trusted certificates explicit local * auxiliary trust can be used to override EKU-restrictions. - * Sadly, returns 0 also on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, int must_be_ca) @@ -428,7 +490,7 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, return 1; case X509_TRUST_REJECTED: break; - default: + default: /* can only be X509_TRUST_UNTRUSTED */ switch (X509_check_purpose(x, purpose, must_be_ca > 0)) { case 1: return 1; @@ -444,9 +506,9 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, return verify_cb_cert(ctx, x, depth, X509_V_ERR_INVALID_PURPOSE); } -/* +/*- * Check extensions of a cert chain for consistency with the supplied purpose. - * Sadly, returns 0 also on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int check_extensions(X509_STORE_CTX *ctx) { @@ -642,7 +704,10 @@ static int has_san_id(X509 *x, int gtype) return ret; } -/* Returns -1 on internal error */ +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ static int check_name_constraints(X509_STORE_CTX *ctx) { int i; @@ -703,7 +768,7 @@ static int check_name_constraints(X509_STORE_CTX *ctx) */ tmpsubject = X509_NAME_dup(tmpsubject); if (tmpsubject == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); ctx->error = X509_V_ERR_OUT_OF_MEM; return -1; } @@ -863,7 +928,7 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) res = lookup_cert_match(&mx, ctx, x); if (res < 0) return res; - if (mx == NULL) + if (res == 0) return X509_TRUST_UNTRUSTED; /* @@ -915,7 +980,7 @@ static int check_revocation(X509_STORE_CTX *ctx) last = sk_X509_num(ctx->chain) - 1; } else { /* If checking CRL paths this isn't the EE certificate */ - if (ctx->parent) + if (ctx->parent != NULL) return 1; last = 0; } @@ -1626,6 +1691,7 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) return 1; } +/* Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int check_policy(X509_STORE_CTX *ctx) { int ret; @@ -1643,15 +1709,19 @@ static int check_policy(X509_STORE_CTX *ctx) * was verified via a bare public key, and pop it off right after the * X509_policy_check() call. */ - if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) + if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto memerr; + } ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, ctx->param->policies, ctx->param->flags); if (ctx->bare_ta_signed) (void)sk_X509_pop(ctx->chain); - if (ret == X509_PCY_TREE_INTERNAL) + if (ret == X509_PCY_TREE_INTERNAL) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); goto memerr; + } /* Invalid or inconsistent extensions */ if (ret == X509_PCY_TREE_INVALID) { int i, cbcalled = 0; @@ -1698,7 +1768,6 @@ static int check_policy(X509_STORE_CTX *ctx) return 1; memerr: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; return -1; } @@ -1709,6 +1778,7 @@ static int check_policy(X509_STORE_CTX *ctx) * the validation status. * * Return 1 on success, 0 otherwise. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). */ int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) { @@ -1738,13 +1808,23 @@ int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) /* * Verify the issuer signatures and cert times of ctx->chain. - * Sadly, returns 0 also on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int internal_verify(X509_STORE_CTX *ctx) { - int n = sk_X509_num(ctx->chain) - 1; - X509 *xi = sk_X509_value(ctx->chain, n); - X509 *xs = xi; + int n; + X509 *xi; + X509 *xs; + + /* For RPK: just do the verify callback */ + if (ctx->rpk != NULL) { + if (!ctx->verify_cb(ctx->error == X509_V_OK, ctx)) + return 0; + return 1; + } + n = sk_X509_num(ctx->chain) - 1; + xi = sk_X509_value(ctx->chain, n); + xs = xi; ctx->error_depth = n; if (ctx->bare_ta_signed) { @@ -1853,6 +1933,7 @@ int X509_cmp_current_time(const ASN1_TIME *ctm) return X509_cmp_time(ctm, NULL); } +/* returns 0 on error, otherwise 1 if ctm > cmp_time, else -1 */ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) { static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1; @@ -2022,8 +2103,8 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, { X509_CRL *crl = NULL; int i; - STACK_OF(X509_REVOKED) *revs = NULL; + /* CRLs can't be delta already */ if (base->base_crl_number != NULL || newer->base_crl_number != NULL) { ERR_raise(ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA); @@ -2062,20 +2143,30 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, } /* Create new CRL */ crl = X509_CRL_new_ex(base->libctx, base->propq); - if (crl == NULL || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) - goto memerr; + if (crl == NULL || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } /* Set issuer name */ - if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) - goto memerr; + if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } - if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) - goto memerr; - if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) - goto memerr; + if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } + if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } /* Set base CRL number: must be critical */ - if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) - goto memerr; + if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } /* * Copy extensions across from newest CRL to delta: this will set CRL @@ -2084,8 +2175,10 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { X509_EXTENSION *ext = X509_CRL_get_ext(newer, i); - if (!X509_CRL_add_ext(crl, ext, -1)) - goto memerr; + if (!X509_CRL_add_ext(crl, ext, -1)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } } /* Go through revoked entries, copying as needed */ @@ -2102,22 +2195,26 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, */ if (!X509_CRL_get0_by_serial(base, &rvtmp, &rvn->serialNumber)) { rvtmp = X509_REVOKED_dup(rvn); - if (rvtmp == NULL) - goto memerr; + if (rvtmp == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } if (!X509_CRL_add0_revoked(crl, rvtmp)) { X509_REVOKED_free(rvtmp); - goto memerr; + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; } } } - if (skey != NULL && md != NULL && !X509_CRL_sign(crl, skey, md)) - goto memerr; + if (skey != NULL && md != NULL && !X509_CRL_sign(crl, skey, md)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + goto err; + } return crl; - memerr: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + err: X509_CRL_free(crl); return NULL; } @@ -2194,6 +2291,11 @@ void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) ctx->cert = x; } +void X509_STORE_CTX_set0_rpk(X509_STORE_CTX *ctx, EVP_PKEY *rpk) +{ + ctx->rpk = rpk; +} + void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) { ctx->crls = sk; @@ -2283,17 +2385,14 @@ X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->libctx = libctx; if (propq != NULL) { ctx->propq = OPENSSL_strdup(propq); if (ctx->propq == NULL) { OPENSSL_free(ctx); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); return NULL; } } @@ -2318,6 +2417,15 @@ void X509_STORE_CTX_free(X509_STORE_CTX *ctx) OPENSSL_free(ctx); } + +int X509_STORE_CTX_init_rpk(X509_STORE_CTX *ctx, X509_STORE *store, EVP_PKEY *rpk) +{ + if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) + return 0; + ctx->rpk = rpk; + return 1; +} + int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { @@ -2347,6 +2455,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->parent = NULL; ctx->dane = NULL; ctx->bare_ta_signed = 0; + ctx->rpk = NULL; /* Zero ex_data to make sure we're cleanup-safe */ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); @@ -2413,7 +2522,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->param = X509_VERIFY_PARAM_new(); if (ctx->param == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } @@ -2441,7 +2550,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &ctx->ex_data)) return 1; - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); err: /* @@ -2483,7 +2592,7 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) } X509_policy_tree_free(ctx->tree); ctx->tree = NULL; - sk_X509_pop_free(ctx->chain, X509_free); + OSSL_STACK_OF_X509_free(ctx->chain); ctx->chain = NULL; CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); @@ -2505,11 +2614,22 @@ void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, X509_VERIFY_PARAM_set_time(ctx->param, t); } +void X509_STORE_CTX_set_current_reasons(X509_STORE_CTX *ctx, + unsigned int current_reasons) +{ + ctx->current_reasons = current_reasons; +} + X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx) { return ctx->cert; } +EVP_PKEY *X509_STORE_CTX_get0_rpk(const X509_STORE_CTX *ctx) +{ + return ctx->rpk; +} + STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx) { return ctx->untrusted; @@ -2522,7 +2642,7 @@ void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { - sk_X509_pop_free(ctx->chain, X509_free); + OSSL_STACK_OF_X509_free(ctx->chain); ctx->chain = sk; } @@ -2571,6 +2691,12 @@ X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(const X509_STORE_CTX *ctx) return ctx->get_crl; } +void X509_STORE_CTX_set_get_crl(X509_STORE_CTX *ctx, + X509_STORE_CTX_get_crl_fn get_crl) +{ + ctx->get_crl = get_crl; +} + X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(const X509_STORE_CTX *ctx) { @@ -2671,7 +2797,7 @@ static unsigned char *dane_i2d(X509 *cert, uint8_t selector, } if (len < 0 || buf == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return NULL; } @@ -2682,7 +2808,7 @@ static unsigned char *dane_i2d(X509 *cert, uint8_t selector, #define DANETLS_NONE 256 /* impossible uint8_t */ /* Returns -1 on internal error */ -static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) +static int dane_match_cert(X509_STORE_CTX *ctx, X509 *cert, int depth) { SSL_DANE *dane = ctx->dane; unsigned usage = DANETLS_NONE; @@ -2840,7 +2966,7 @@ static int check_dane_issuer(X509_STORE_CTX *ctx, int depth) * for an exact match for the leaf certificate). */ cert = sk_X509_value(ctx->chain, depth); - if (cert != NULL && (matched = dane_match(ctx, cert, depth)) < 0) + if (cert != NULL && (matched = dane_match_cert(ctx, cert, depth)) < 0) return matched; if (matched > 0) { ctx->num_untrusted = depth - 1; @@ -2887,6 +3013,62 @@ static int check_dane_pkeys(X509_STORE_CTX *ctx) return X509_TRUST_UNTRUSTED; } +/* + * Only DANE-EE and SPKI are supported + * Returns -1 on internal error + */ +static int dane_match_rpk(X509_STORE_CTX *ctx, EVP_PKEY *rpk) +{ + SSL_DANE *dane = ctx->dane; + danetls_record *t = NULL; + int mtype = DANETLS_MATCHING_FULL; + unsigned char *i2dbuf = NULL; + unsigned int i2dlen = 0; + unsigned char mdbuf[EVP_MAX_MD_SIZE]; + unsigned char *cmpbuf; + unsigned int cmplen = 0; + int len; + int recnum = sk_danetls_record_num(dane->trecs); + int i; + int matched = 0; + + /* Calculate ASN.1 DER of RPK */ + if ((len = i2d_PUBKEY(rpk, &i2dbuf)) <= 0) + return -1; + cmplen = i2dlen = (unsigned int)len; + cmpbuf = i2dbuf; + + for (i = 0; i < recnum; i++) { + t = sk_danetls_record_value(dane->trecs, i); + if (t->usage != DANETLS_USAGE_DANE_EE || t->selector != DANETLS_SELECTOR_SPKI) + continue; + + /* Calculate hash - keep only one around */ + if (t->mtype != mtype) { + const EVP_MD *md = dane->dctx->mdevp[mtype = t->mtype]; + + cmpbuf = i2dbuf; + cmplen = i2dlen; + + if (md != NULL) { + cmpbuf = mdbuf; + if (!EVP_Digest(i2dbuf, i2dlen, cmpbuf, &cmplen, md, 0)) { + matched = -1; + break; + } + } + } + if (cmplen == t->dlen && memcmp(cmpbuf, t->data, cmplen) == 0) { + matched = 1; + dane->mdpth = 0; + dane->mtlsa = t; + break; + } + } + OPENSSL_free(i2dbuf); + return matched; +} + static void dane_reset(SSL_DANE *dane) { /* Reset state to verify another chain, or clear after failure. */ @@ -2897,6 +3079,7 @@ static void dane_reset(SSL_DANE *dane) dane->pdpth = -1; } +/* Sadly, returns 0 also on internal error in ctx->verify_cb(). */ static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert) { int err = X509_chain_check_suiteb(NULL, cert, NULL, ctx->param->flags); @@ -2905,6 +3088,36 @@ static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert) return 1; } +/* Returns -1 on internal error */ +static int dane_verify_rpk(X509_STORE_CTX *ctx) +{ + SSL_DANE *dane = ctx->dane; + int matched; + + dane_reset(dane); + + /* + * Look for a DANE record for RPK + * If error, return -1 + * If found, call ctx->verify_cb(1, ctx) + * If not found call ctx->verify_cb(0, ctx) + */ + matched = dane_match_rpk(ctx, ctx->rpk); + ctx->error_depth = 0; + + if (matched < 0) { + ctx->error = X509_V_ERR_UNSPECIFIED; + return -1; + } + + if (matched > 0) + ctx->error = X509_V_OK; + else + ctx->error = X509_V_ERR_DANE_NO_MATCH; + + return verify_rpk(ctx); +} + /* Returns -1 on internal error */ static int dane_verify(X509_STORE_CTX *ctx) { @@ -2927,7 +3140,7 @@ static int dane_verify(X509_STORE_CTX *ctx) * + matched == 0, mdepth < 0 (no PKIX-EE match) and there are no * DANE-TA(2) or PKIX-TA(0) to test. */ - matched = dane_match(ctx, ctx->cert, 0); + matched = dane_match_cert(ctx, ctx->cert, 0); done = matched != 0 || (!DANETLS_HAS_TA(dane) && dane->mdpth < 0); if (done && !X509_get_pubkey_parameters(NULL, ctx->chain)) @@ -2984,7 +3197,10 @@ static int get1_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) return ok; } -/* Returns -1 on internal error */ +/*- + * Returns -1 on internal error. + * Sadly, returns 0 also on internal error in ctx->verify_cb(). + */ static int build_chain(X509_STORE_CTX *ctx) { SSL_DANE *dane = ctx->dane; @@ -3024,24 +3240,30 @@ static int build_chain(X509_STORE_CTX *ctx) } /* Initialize empty untrusted stack. */ - if ((sk_untrusted = sk_X509_new_null()) == NULL) + if ((sk_untrusted = sk_X509_new_null()) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto memerr; + } /* * If we got any "Cert(0) Full(0)" trust anchors from DNS, *prepend* them * to our working copy of the untrusted certificate stack. */ if (DANETLS_ENABLED(dane) && dane->certs != NULL - && !X509_add_certs(sk_untrusted, dane->certs, X509_ADD_FLAG_DEFAULT)) + && !X509_add_certs(sk_untrusted, dane->certs, X509_ADD_FLAG_DEFAULT)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); goto memerr; + } /* * Shallow-copy the stack of untrusted certificates (with TLS, this is * typically the content of the peer's certificate message) so we can make * multiple passes over it, while free to remove elements as we go. */ - if (!X509_add_certs(sk_untrusted, ctx->untrusted, X509_ADD_FLAG_DEFAULT)) + if (!X509_add_certs(sk_untrusted, ctx->untrusted, X509_ADD_FLAG_DEFAULT)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); goto memerr; + } /* * Still absurdly large, but arithmetically safe, a lower hard upper bound @@ -3149,20 +3371,18 @@ static int build_chain(X509_STORE_CTX *ctx) dane->pdpth = -1; } - /* - * Self-signed untrusted certificates get replaced by their - * trusted matching issuer. Otherwise, grow the chain. - */ - if (!self_signed) { + if (!self_signed) { /* untrusted not self-signed certificate */ + /* Grow the chain by trusted issuer */ if (!sk_X509_push(ctx->chain, issuer)) { X509_free(issuer); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto memerr; } if ((self_signed = X509_self_signed(issuer, 0)) < 0) goto int_err; } else { /* - * We have a self-signed certificate that has the same + * We have a self-signed untrusted cert that has the same * subject name (and perhaps keyid and/or serial number) as * a trust anchor. We must have an exact match to avoid * possible impersonation via key substitution etc. @@ -3172,6 +3392,10 @@ static int build_chain(X509_STORE_CTX *ctx) X509_free(issuer); ok = 0; } else { /* curr "==" issuer */ + /* + * Replace self-signed untrusted certificate + * by its trusted matching issuer. + */ X509_free(curr); ctx->num_untrusted = --num; (void)sk_X509_set(ctx->chain, num, issuer); @@ -3224,7 +3448,7 @@ static int build_chain(X509_STORE_CTX *ctx) } /* - * Extend chain with peer-provided untrusted certificates + * Try to extend chain with peer-provided untrusted certificate */ if ((search & S_DOUNTRUSTED) != 0) { num = sk_X509_num(ctx->chain); @@ -3248,6 +3472,7 @@ static int build_chain(X509_STORE_CTX *ctx) /* Drop this issuer from future consideration */ (void)sk_X509_delete_ptr(sk_untrusted, issuer); + /* Grow the chain by untrusted issuer */ if (!X509_add_cert(ctx->chain, issuer, X509_ADD_FLAG_UP_REF)) goto int_err; @@ -3284,12 +3509,12 @@ static int build_chain(X509_STORE_CTX *ctx) return 0; case X509_TRUST_UNTRUSTED: default: - switch(ctx->error) { + switch (ctx->error) { case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: case X509_V_ERR_CERT_HAS_EXPIRED: - return 0; /* Callback already issued by ossl_x509_check_cert_time() */ + return 0; /* Callback already done by ossl_x509_check_cert_time() */ default: /* A preliminary error has become final */ return verify_cb_cert(ctx, NULL, num - 1, ctx->error); case X509_V_OK: @@ -3318,7 +3543,6 @@ static int build_chain(X509_STORE_CTX *ctx) return -1; memerr: - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; sk_X509_free(sk_untrusted); return -1; @@ -3374,12 +3598,11 @@ static const int minbits_table[] = { 80, 112, 128, 192, 256 }; static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table); /*- - * Check whether the public key of `cert` meets the security level of `ctx`. + * Check whether the given public key meets the security level of `ctx`. * Returns 1 on success, 0 otherwise. */ -static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) +static int check_key_level(X509_STORE_CTX *ctx, EVP_PKEY *pkey) { - EVP_PKEY *pkey = X509_get0_pubkey(cert); int level = ctx->param->auth_level; /* @@ -3401,6 +3624,15 @@ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) return EVP_PKEY_get_security_bits(pkey) >= minbits_table[level - 1]; } +/*- + * Check whether the public key of `cert` meets the security level of `ctx`. + * Returns 1 on success, 0 otherwise. + */ +static int check_cert_key_level(X509_STORE_CTX *ctx, X509 *cert) +{ + return check_key_level(ctx, X509_get0_pubkey(cert)); +} + /*- * Check whether the public key of ``cert`` does not use explicit params * for an elliptic curve. @@ -3410,21 +3642,19 @@ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) static int check_curve(X509 *cert) { EVP_PKEY *pkey = X509_get0_pubkey(cert); + int ret, val; /* Unsupported or malformed key */ if (pkey == NULL) return -1; + if (EVP_PKEY_get_id(pkey) != EVP_PKEY_EC) + return 1; - if (EVP_PKEY_get_id(pkey) == EVP_PKEY_EC) { - int ret, val; - - ret = EVP_PKEY_get_int_param(pkey, - OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, - &val); - return ret == 1 ? !val : -1; - } - - return 1; + ret = + EVP_PKEY_get_int_param(pkey, + OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, + &val); + return ret == 1 ? !val : -1; } /*- diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 998ce8ac1b..023a38a1c9 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -84,10 +84,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) X509_VERIFY_PARAM *param; param = OPENSSL_zalloc(sizeof(*param)); - if (param == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (param == NULL) return NULL; - } param->trust = X509_TRUST_DEFAULT; /* param->inh_flags = X509_VP_FLAG_DEFAULT; */ param->depth = -1; @@ -506,6 +504,18 @@ const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) */ static const X509_VERIFY_PARAM default_table[] = { + { + "code_sign", /* Code sign parameters */ + 0, /* check time to use */ + 0, /* inheritance flags */ + 0, /* flags */ + X509_PURPOSE_CODE_SIGN, /* purpose */ + X509_TRUST_OBJECT_SIGN, /* trust */ + -1, /* depth */ + -1, /* auth_level */ + NULL, /* policies */ + vpm_empty_id + }, { "default", /* X509 default parameters */ 0, /* check time to use */ @@ -516,7 +526,8 @@ static const X509_VERIFY_PARAM default_table[] = { 100, /* depth */ -1, /* auth_level */ NULL, /* policies */ - vpm_empty_id}, + vpm_empty_id + }, { "pkcs7", /* S/MIME sign parameters */ 0, /* check time to use */ @@ -527,7 +538,8 @@ static const X509_VERIFY_PARAM default_table[] = { -1, /* depth */ -1, /* auth_level */ NULL, /* policies */ - vpm_empty_id}, + vpm_empty_id + }, { "smime_sign", /* S/MIME sign parameters */ 0, /* check time to use */ @@ -538,7 +550,8 @@ static const X509_VERIFY_PARAM default_table[] = { -1, /* depth */ -1, /* auth_level */ NULL, /* policies */ - vpm_empty_id}, + vpm_empty_id + }, { "ssl_client", /* SSL/TLS client parameters */ 0, /* check time to use */ @@ -549,7 +562,8 @@ static const X509_VERIFY_PARAM default_table[] = { -1, /* depth */ -1, /* auth_level */ NULL, /* policies */ - vpm_empty_id}, + vpm_empty_id + }, { "ssl_server", /* SSL/TLS server parameters */ 0, /* check time to use */ @@ -560,7 +574,8 @@ static const X509_VERIFY_PARAM default_table[] = { -1, /* depth */ -1, /* auth_level */ NULL, /* policies */ - vpm_empty_id} + vpm_empty_id + } }; static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; @@ -626,6 +641,8 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) pm.name = (char *)name; if (param_table != NULL) { + /* Ideally, this would be done under a lock */ + sk_X509_VERIFY_PARAM_sort(param_table); idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); if (idx >= 0) return sk_X509_VERIFY_PARAM_value(param_table, idx); diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c index 2746b98925..205fe3d6e5 100644 --- a/crypto/x509/x509cset.c +++ b/crypto/x509/x509cset.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,34 +24,41 @@ int X509_CRL_set_version(X509_CRL *x, long version) if ((x->crl.version = ASN1_INTEGER_new()) == NULL) return 0; } - return ASN1_INTEGER_set(x->crl.version, version); + if (!ASN1_INTEGER_set(x->crl.version, version)) + return 0; + x->crl.enc.modified = 1; + return 1; } int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name) { if (x == NULL) return 0; - return X509_NAME_set(&x->crl.issuer, name); + if (!X509_NAME_set(&x->crl.issuer, name)) + return 0; + x->crl.enc.modified = 1; + return 1; } int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) { - if (x == NULL) + if (x == NULL || tm == NULL) return 0; - return ossl_x509_set1_time(&x->crl.lastUpdate, tm); + return ossl_x509_set1_time(&x->crl.enc.modified, &x->crl.lastUpdate, tm); } int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { if (x == NULL) return 0; - return ossl_x509_set1_time(&x->crl.nextUpdate, tm); + return ossl_x509_set1_time(&x->crl.enc.modified, &x->crl.nextUpdate, tm); } int X509_CRL_sort(X509_CRL *c) { int i; X509_REVOKED *r; + /* * sort the data so it will be written in serial number order */ @@ -68,12 +75,12 @@ int X509_CRL_up_ref(X509_CRL *crl) { int i; - if (CRYPTO_UP_REF(&crl->references, &i, crl->lock) <= 0) + if (CRYPTO_UP_REF(&crl->references, &i) <= 0) return 0; REF_PRINT_COUNT("X509_CRL", crl); REF_ASSERT_ISNT(i < 2); - return ((i > 1) ? 1 : 0); + return i > 1; } long X509_CRL_get_version(const X509_CRL *crl) @@ -139,19 +146,9 @@ const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x) int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) { - ASN1_TIME *in; - - if (x == NULL) + if (x == NULL || tm == NULL) return 0; - in = x->revocationDate; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->revocationDate); - x->revocationDate = in; - } - } - return (in != NULL); + return ossl_x509_set1_time(NULL, &x->revocationDate, tm); } const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x) @@ -171,7 +168,8 @@ int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) return 1; } -const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r) +const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const + X509_REVOKED *r) { return r->extensions; } diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c index 85a7c8ae5a..75ff07d899 100644 --- a/crypto/x509/x509name.c +++ b/crypto/x509/x509name.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -225,7 +225,7 @@ int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, goto err; new_name->set = set; if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } if (inc) { diff --git a/crypto/x509/x509spki.c b/crypto/x509/x509spki.c index 1d66697db0..142eeb79bd 100644 --- a/crypto/x509/x509spki.c +++ b/crypto/x509/x509spki.c @@ -35,10 +35,8 @@ NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) NETSCAPE_SPKI *spki; if (len <= 0) len = strlen(str); - if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) return NULL; - } spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); if (spki_len < 0) { ERR_raise(ERR_LIB_X509, X509_R_BASE64_DECODE_ERROR); @@ -65,7 +63,6 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) der_spki = OPENSSL_malloc(der_len); b64_str = OPENSSL_malloc(der_len * 2); if (der_spki == NULL || b64_str == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); OPENSSL_free(der_spki); OPENSSL_free(b64_str); return NULL; diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index e58c9ab1c1..3e4c852b70 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -63,6 +63,9 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; } + if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0 + && !X509_set_version(x, X509_VERSION_3)) + return 0; /* * Setting the modified flag before signing it. This makes the cached @@ -83,6 +86,9 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; } + if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0 + && !X509_set_version(x, X509_VERSION_3)) + return 0; x->cert_info.enc.modified = 1; return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, @@ -92,6 +98,7 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio, int timeout, const ASN1_ITEM *it) { +#ifndef OPENSSL_NO_HTTP BIO *mem = OSSL_HTTP_get(url, NULL /* proxy */, NULL /* no_proxy */, bio, rbio, NULL /* cb */, NULL /* arg */, 1024 /* buf_size */, NULL /* headers */, @@ -101,6 +108,9 @@ static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio, BIO_free(mem); return res; +#else + return 0; +#endif } X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) @@ -282,7 +292,8 @@ X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) propq = (*req)->propq; } - return ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(X509_REQ), bp, req, libctx, propq); + return + ASN1_item_d2i_bio_ex(ASN1_ITEM_rptr(X509_REQ), bp, req, libctx, propq); } int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req) @@ -575,15 +586,17 @@ int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); return 1; } - return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, - md, len, data->libctx, data->propq); + return + ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, + md, len, data->libctx, data->propq); } int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { - return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, - md, len, data->libctx, data->propq); + return + ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, + md, len, data->libctx, data->propq); } int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, @@ -705,6 +718,22 @@ int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey) return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); } +EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = d2i_PUBKEY_ex_bio(b, a, libctx, propq); + BIO_free(b); + return ret; +} + EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) { return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); @@ -772,6 +801,25 @@ int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey) return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); } +EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(bp, &b); + if (len < 0) + goto err; + + p = (unsigned char *)b->data; + ret = d2i_PUBKEY_ex(a, &p, len, libctx, propq); + err: + BUF_MEM_free(b); + return ret; +} + EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) { return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c index afb2b49d68..2601a019f8 100644 --- a/crypto/x509/x_crl.c +++ b/crypto/x509/x_crl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,9 +20,9 @@ static int X509_REVOKED_cmp(const X509_REVOKED *const *a, static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); ASN1_SEQUENCE(X509_REVOKED) = { - ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), - ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) + ASN1_EMBED(X509_REVOKED, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_REVOKED, revocationDate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_REVOKED, extensions, X509_EXTENSION) } ASN1_SEQUENCE_END(X509_REVOKED) static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); @@ -94,15 +94,15 @@ static int crl_set_issuers(X509_CRL *crl) STACK_OF(X509_EXTENSION) *exts; ASN1_ENUMERATED *reason; X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL); - if (!gtmp && (j != -1)) { + if (gtmp == NULL && j != -1) { crl->flags |= EXFLAG_INVALID; return 1; } - if (gtmp) { - gens = gtmp; + if (gtmp != NULL) { if (crl->issuers == NULL) { crl->issuers = sk_GENERAL_NAMES_new_null(); if (crl->issuers == NULL) { @@ -114,16 +114,17 @@ static int crl_set_issuers(X509_CRL *crl) GENERAL_NAMES_free(gtmp); return 0; } + gens = gtmp; } rev->issuer = gens; reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); - if (!reason && (j != -1)) { + if (reason == NULL && j != -1) { crl->flags |= EXFLAG_INVALID; return 1; } - if (reason) { + if (reason != NULL) { rev->reason = ASN1_ENUMERATED_get(reason); ASN1_ENUMERATED_free(reason); } else @@ -136,7 +137,8 @@ static int crl_set_issuers(X509_CRL *crl) for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { ext = sk_X509_EXTENSION_value(exts, j); if (X509_EXTENSION_get_critical(ext)) { - if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer) + if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) + == NID_certificate_issuer) continue; crl->flags |= EXFLAG_CRITICAL; break; @@ -364,7 +366,7 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) if (inf->revoked == NULL) inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); if (inf->revoked == NULL || !sk_X509_REVOKED_push(inf->revoked, rev)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); return 0; } inf->enc.modified = 1; @@ -488,10 +490,8 @@ X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), { X509_CRL_METHOD *m = OPENSSL_malloc(sizeof(*m)); - if (m == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (m == NULL) return NULL; - } m->crl_init = crl_init; m->crl_free = crl_free; m->crl_lookup = crl_lookup; diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c index 944eb99924..4568833f81 100644 --- a/crypto/x509/x_name.c +++ b/crypto/x509/x_name.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -92,17 +92,20 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) - goto memerr; - if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) - goto memerr; - if ((ret->bytes = BUF_MEM_new()) == NULL) - goto memerr; + return 0; + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); + goto err; + } + if ((ret->bytes = BUF_MEM_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); + goto err; + } ret->modified = 1; *val = (ASN1_VALUE *)ret; return 1; - memerr: - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + err: if (ret) { sk_X509_NAME_ENTRY_free(ret->entries); OPENSSL_free(ret); @@ -246,26 +249,28 @@ static int x509_name_encode(X509_NAME *a) intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if (!intname.s) - goto memerr; + goto cerr; 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 cerr; if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { sk_X509_NAME_ENTRY_free(entries); - goto memerr; + goto cerr; } set = entry->set; } if (!sk_X509_NAME_ENTRY_push(entries, entry)) - goto memerr; + goto cerr; } len = ASN1_item_ex_i2d(&intname.a, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - if (!BUF_MEM_grow(a->bytes, len)) - goto memerr; + if (!BUF_MEM_grow(a->bytes, len)) { + ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); + goto err; + } p = (unsigned char *)a->bytes->data; ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); @@ -273,10 +278,11 @@ static int x509_name_encode(X509_NAME *a) local_sk_X509_NAME_ENTRY_free); a->modified = 0; return len; - memerr: + cerr: + ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); + err: sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, local_sk_X509_NAME_ENTRY_free); - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); return -1; } @@ -318,7 +324,7 @@ static int x509_name_canon(X509_NAME *a) } intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); if (intname == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { @@ -329,25 +335,25 @@ static int x509_name_canon(X509_NAME *a) goto err; if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { sk_X509_NAME_ENTRY_free(entries); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } set = entry->set; } tmpentry = X509_NAME_ENTRY_new(); if (tmpentry == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } tmpentry->object = OBJ_dup(entry->object); if (tmpentry->object == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_OBJ_LIB); goto err; } if (!asn1_string_canon(tmpentry->value, entry->value)) goto err; if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB); goto err; } tmpentry = NULL; @@ -360,10 +366,8 @@ static int x509_name_canon(X509_NAME *a) a->canon_enclen = len; p = OPENSSL_malloc(a->canon_enclen); - if (p == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (p == NULL) goto err; - } a->canon_enc = p; diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 7245641780..004c7bdfeb 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -66,7 +66,8 @@ ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, - long len, OSSL_LIB_CTX *libctx) + long len, OSSL_LIB_CTX *libctx, + const char *propq) { X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); @@ -74,7 +75,7 @@ X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, return NULL; return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), - libctx, NULL); + libctx, propq); } void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub) @@ -112,12 +113,13 @@ static int x509_pubkey_ex_new_ex(ASN1_VALUE **pval, const ASN1_ITEM *it, { X509_PUBKEY *ret; - if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL - || !x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL) + if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) + return 0; + if (!x509_pubkey_ex_populate((ASN1_VALUE **)&ret, NULL) || !x509_pubkey_set0_libctx(ret, libctx, propq)) { x509_pubkey_ex_free((ASN1_VALUE **)&ret, NULL); ret = NULL; - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); } else { *pval = (ASN1_VALUE *)ret; } @@ -141,7 +143,7 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval, if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, libctx, propq)) return 0; if (!x509_pubkey_ex_populate(pval, NULL)) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_X509_LIB); return 0; } @@ -190,10 +192,8 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval, */ if (aclass != V_ASN1_UNIVERSAL) { tmpbuf = OPENSSL_memdup(in_saved, publen); - if (tmpbuf == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + if (tmpbuf == NULL) return 0; - } in_saved = tmpbuf; *tmpbuf = V_ASN1_CONSTRUCTED | V_ASN1_SEQUENCE; } @@ -284,16 +284,22 @@ X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a) { X509_PUBKEY *pubkey = OPENSSL_zalloc(sizeof(*pubkey)); - if (pubkey == NULL - || !x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq) - || (pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL - || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL - || !ASN1_BIT_STRING_set(pubkey->public_key, - a->public_key->data, - a->public_key->length)) { + if (pubkey == NULL) + return NULL; + if (!x509_pubkey_set0_libctx(pubkey, a->libctx, a->propq)) { + ERR_raise(ERR_LIB_X509, ERR_R_X509_LIB); + x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); + return NULL; + } + if ((pubkey->algor = X509_ALGOR_dup(a->algor)) == NULL + || (pubkey->public_key = ASN1_BIT_STRING_new()) == NULL + || !ASN1_BIT_STRING_set(pubkey->public_key, + a->public_key->data, + a->public_key->length)) { x509_pubkey_ex_free((ASN1_VALUE **)&pubkey, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); return NULL; } @@ -325,7 +331,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) if (pkey->ameth != NULL) { if ((pk = X509_PUBKEY_new()) == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto error; } if (pkey->ameth->pub_encode != NULL) { @@ -416,7 +422,7 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) pkey = EVP_PKEY_new(); if (pkey == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_EVP_LIB); return -1; } @@ -499,10 +505,8 @@ static EVP_PKEY *d2i_PUBKEY_int(EVP_PKEY **a, */ if (libctx != NULL || propq != NULL || force_legacy) { xpk2 = OPENSSL_zalloc(sizeof(*xpk2)); - if (xpk2 == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (xpk2 == NULL) return NULL; - } if (!x509_pubkey_set0_libctx(xpk2, libctx, propq)) goto end; xpk2->flag_force_legacy = !!force_legacy; @@ -628,7 +632,7 @@ int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign_RSA(pktmp, (RSA *)a); @@ -670,7 +674,7 @@ int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign_DH(pktmp, (DH *)a); @@ -711,7 +715,7 @@ int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a); @@ -777,7 +781,7 @@ int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp) return 0; pktmp = EVP_PKEY_new(); if (pktmp == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign_DSA(pktmp, (DSA *)a); @@ -822,7 +826,7 @@ int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign_EC_KEY(pktmp, (EC_KEY *)a); @@ -832,6 +836,7 @@ int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) return ret; } +# ifndef OPENSSL_NO_ECX ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a, const unsigned char **pp, long length) { @@ -863,7 +868,7 @@ int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a); @@ -905,7 +910,7 @@ int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp) if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a); @@ -947,7 +952,7 @@ int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a); @@ -989,7 +994,7 @@ int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) if (a == NULL) return 0; if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); return -1; } (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a); @@ -999,22 +1004,24 @@ int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) return ret; } +# endif /* OPENSSL_NO_ECX */ #endif +void X509_PUBKEY_set0_public_key(X509_PUBKEY *pub, + unsigned char *penc, int penclen) +{ + ASN1_STRING_set0(pub->public_key, penc, penclen); + ossl_asn1_string_set_bits_left(pub->public_key, 0); +} + int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype, void *pval, unsigned char *penc, int penclen) { if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) return 0; - if (penc) { - OPENSSL_free(pub->public_key->data); - pub->public_key->data = penc; - pub->public_key->length = penclen; - /* Set number of unused bits to zero */ - pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; - } + if (penc != NULL) + X509_PUBKEY_set0_public_key(pub, penc, penclen); return 1; } diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c index fc07c90978..ca712386bd 100644 --- a/crypto/x509/x_req.c +++ b/crypto/x509/x_req.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -74,7 +74,7 @@ static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, if (pkey != NULL) { pkey = EVP_PKEY_dup(pkey); if (pkey == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_EVP_LIB); return 0; } if (!X509_PUBKEY_set(&ret->req_info.pubkey, pkey)) { diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 429af13e15..75c5c9223a 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -272,10 +272,8 @@ int i2d_X509_AUX(const X509 *a, unsigned char **pp) /* Allocate requisite combined storage */ *pp = tmp = OPENSSL_malloc(length); - if (tmp == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + if (tmp == NULL) return -1; - } /* Encode, but keep *pp at the originally malloced pointer */ length = i2d_x509_aux_internal(a, &tmp); diff --git a/import_openssl.sh b/import_openssl.sh index 72d566be79..6e7e33b557 100755 --- a/import_openssl.sh +++ b/import_openssl.sh @@ -256,13 +256,13 @@ function generate_build_config_headers() { PERL=/usr/bin/perl run_verbose ./Configure $CONFIGURE_ARGS ${!configure_args_bits} ${!configure_args_stat} fi - make include/openssl/configuration.h - make include/openssl/opensslv.h + make include/openssl/configuration.h include/openssl/opensslv.h make include/crypto/bn_conf.h include/openssl/lhash.h include/crypto/dso_conf.h make providers/common/include/prov/der_ec.h providers/common/include/prov/der_ecx.h providers/common/include/prov/der_sm2.h providers/common/include/prov/der_dsa.h providers/common/include/prov/der_rsa.h providers/common/include/prov/der_digests.h providers/common/include/prov/der_wrap.h make providers/common/der/der_digests_gen.c providers/common/der/der_ecx_gen.c providers/common/der/der_ec_gen.c providers/common/der/der_dsa_gen.c providers/common/der/der_rsa_gen.c providers/common/der/der_sm2_gen.c providers/common/der/der_wrap_gen.c - make include/openssl/asn1.h include/openssl/asn1t.h include/openssl/bio.h include/openssl/cmp.h include/openssl/cms.h include/openssl/conf.h include/openssl/configuration.h include/openssl/crmf.h include/openssl/crypto.h include/openssl/ct.h include/openssl/err.h include/openssl/ess.h include/openssl/fipskey.h include/openssl/ocsp.h include/openssl/opensslv.h include/openssl/pkcs12.h include/openssl/pkcs7.h include/openssl/safestack.h include/openssl/srp.h include/openssl/ssl.h include/openssl/ui.h include/openssl/x509.h include/openssl/x509_vfy.h include/openssl/x509v3.h - + make include/openssl/asn1.h include/openssl/asn1t.h include/openssl/bio.h include/openssl/cmp.h include/openssl/cms.h include/openssl/conf.h include/openssl/configuration.h include/openssl/crmf.h include/openssl/crypto.h include/openssl/ct.h include/openssl/err.h include/openssl/ess.h + make include/openssl/fipskey.h include/openssl/ocsp.h include/openssl/opensslv.h include/openssl/pkcs12.h include/openssl/pkcs7.h include/openssl/safestack.h include/openssl/srp.h include/openssl/ssl.h include/openssl/ui.h include/openssl/x509.h include/openssl/x509_vfy.h include/openssl/x509v3.h + make include/openssl/core_names.h include/internal/param_names.h crypto/params_idx.c rm -f apps/CA.pl.bak openssl/opensslconf.h.bak mv -f include/crypto/bn_conf.h include/crypto/bn_conf-$outname.h @@ -556,6 +556,7 @@ function import() { gen_asm_arm64 crypto/arm64cpuid.pl gen_asm_arm64 crypto/poly1305/asm/poly1305-armv8.pl gen_asm_arm64 crypto/ec/asm/ecp_nistz256-armv8.pl + gen_asm_arm64 crypto/ec/asm/ecp_sm2p256-armv8.pl gen_asm_arm64 crypto/poly1305/asm/poly1305-armv8.pl gen_asm_arm64 crypto/bn/asm/armv8-mont.pl gen_asm_arm64 crypto/sha/asm/keccak1600-armv8.pl @@ -565,6 +566,8 @@ function import() { gen_asm_arm64 crypto/chacha/asm/chacha-armv8-sve.pl gen_asm_arm64 crypto/md5/asm/md5-aarch64.pl gen_asm_arm64 crypto/sm3/asm/sm3-armv8.pl + gen_asm_arm64 crypto/sm4/asm/vpsm4_ex-armv8.pl + # Generate x86 asm diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h index 87c3525543..e641450b15 100644 --- a/include/crypto/aes_platform.h +++ b/include/crypto/aes_platform.h @@ -90,7 +90,7 @@ void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); # endif /* OPENSSL_SYS_AIX || OPENSSL_SYS_MACOSX */ # endif /* PPC */ -# if (defined(__arm__) || defined(__arm) || defined(__aarch64__)) +# if (defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(_M_ARM64)) # include "arm_arch.h" # if __ARM_MAX_ARCH__>=7 # if defined(BSAES_ASM) @@ -106,7 +106,7 @@ void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); # define HWAES_decrypt aes_v8_decrypt # define HWAES_cbc_encrypt aes_v8_cbc_encrypt # define HWAES_ecb_encrypt aes_v8_ecb_encrypt -# if __ARM_MAX_ARCH__>=8 && defined(__aarch64__) +# if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64)) # define HWAES_xts_encrypt aes_v8_xts_encrypt # define HWAES_xts_decrypt aes_v8_xts_decrypt # endif @@ -114,36 +114,36 @@ void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); # define AES_PMULL_CAPABLE ((OPENSSL_armcap_P & ARMV8_PMULL) && (OPENSSL_armcap_P & ARMV8_AES)) # define AES_GCM_ENC_BYTES 512 # define AES_GCM_DEC_BYTES 512 -# if __ARM_MAX_ARCH__>=8 && defined(__aarch64__) +# if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64)) # define AES_gcm_encrypt armv8_aes_gcm_encrypt # define AES_gcm_decrypt armv8_aes_gcm_decrypt # define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_v8_ctr32_encrypt_blocks && \ (gctx)->gcm.funcs.ghash==gcm_ghash_v8) /* The [unroll8_eor3_]aes_gcm_(enc|dec)_(128|192|256)_kernel() functions * take input length in BITS and return number of BYTES processed */ -size_t aes_gcm_enc_128_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t aes_gcm_enc_128_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t aes_gcm_enc_192_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t aes_gcm_enc_192_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t aes_gcm_enc_256_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t aes_gcm_enc_256_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t aes_gcm_dec_128_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t aes_gcm_dec_128_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t aes_gcm_dec_192_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t aes_gcm_dec_192_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t aes_gcm_dec_256_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t aes_gcm_dec_256_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_enc_128_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t unroll8_eor3_aes_gcm_enc_128_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_enc_192_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t unroll8_eor3_aes_gcm_enc_192_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_enc_256_kernel(const uint8_t * plaintext, uint64_t plaintext_length, uint8_t * ciphertext, +size_t unroll8_eor3_aes_gcm_enc_256_kernel(const uint8_t *plaintext, uint64_t plaintext_length, uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_dec_128_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t unroll8_eor3_aes_gcm_dec_128_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_dec_192_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t unroll8_eor3_aes_gcm_dec_192_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); -size_t unroll8_eor3_aes_gcm_dec_256_kernel(const uint8_t * ciphertext, uint64_t plaintext_length, uint8_t * plaintext, +size_t unroll8_eor3_aes_gcm_dec_256_kernel(const uint8_t *ciphertext, uint64_t plaintext_length, uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16], const void *key); size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key, unsigned char ivec[16], u64 *Xi); @@ -434,7 +434,6 @@ void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, # elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64 /* RISC-V 64 support */ # include "riscv_arch.h" -# define RV64I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) int rv64i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); @@ -447,8 +446,6 @@ void rv64i_zknd_decrypt(const unsigned char *in, unsigned char *out, # elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 /* RISC-V 32 support */ # include "riscv_arch.h" -# define RV32I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) -# define RV32I_ZBKB_ZKND_ZKNE_CAPABLE (RV32I_ZKND_ZKNE_CAPABLE && RISCV_HAS_ZBKB()) int rv32i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index ec76ae6fc6..36af1d7689 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -142,8 +142,12 @@ X509_ALGOR *ossl_x509_algor_mgf1_decode(X509_ALGOR *alg); int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md); int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags); -EVP_PKEY * ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, - const unsigned char **pp, long length, - OSSL_LIB_CTX *libctx, const char *propq); +EVP_PKEY *ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, + const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq); +X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval); + +time_t ossl_asn1_string_to_time_t(const char *asn1_string); +void ossl_asn1_string_set_bits_left(ASN1_STRING *str, unsigned int num); #endif /* ndef OSSL_CRYPTO_ASN1_H */ diff --git a/include/crypto/bioerr.h b/include/crypto/bioerr.h index a0c06099f7..e38b981ab5 100644 --- a/include/crypto/bioerr.h +++ b/include/crypto/bioerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/bn.h b/include/crypto/bn.h index 00544d9d25..33f979ce91 100644 --- a/include/crypto/bn.h +++ b/include/crypto/bn.h @@ -116,4 +116,13 @@ OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx); extern const BIGNUM ossl_bn_inv_sqrt_2; +#if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE) && defined (__s390x__) +# define S390X_MOD_EXP +#endif + +int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q, + const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp); + #endif diff --git a/include/crypto/cmserr.h b/include/crypto/cmserr.h index 1de2f9c7d5..a7fcf11fa9 100644 --- a/include/crypto/cmserr.h +++ b/include/crypto/cmserr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/context.h b/include/crypto/context.h index 8ad168344e..7369a730fb 100644 --- a/include/crypto/context.h +++ b/include/crypto/context.h @@ -24,6 +24,9 @@ void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *); int ossl_thread_register_fips(OSSL_LIB_CTX *); void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *); void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *); +#if defined(OPENSSL_THREADS) +void *ossl_threads_ctx_new(OSSL_LIB_CTX *); +#endif void ossl_provider_store_free(void *); void ossl_property_string_data_free(void *); @@ -40,3 +43,6 @@ void ossl_rand_crng_ctx_free(void *); void ossl_thread_event_ctx_free(void *); void ossl_fips_prov_ossl_ctx_free(void *); void ossl_release_default_drbg_ctx(void); +#if defined(OPENSSL_THREADS) +void ossl_threads_ctx_free(void *); +#endif diff --git a/include/crypto/decoder.h b/include/crypto/decoder.h index 6b5ee56ac6..a0d5de6521 100644 --- a/include/crypto/decoder.h +++ b/include/crypto/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,16 +25,16 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, OSSL_DECODER_INSTANCE * ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx); void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst); +OSSL_DECODER_INSTANCE *ossl_decoder_instance_dup(const OSSL_DECODER_INSTANCE *src); int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, OSSL_DECODER_INSTANCE *di); -int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, - EVP_PKEY **pkey, const char *keytype, - OSSL_LIB_CTX *libctx, - const char *propquery); - int ossl_decoder_get_number(const OSSL_DECODER *encoder); int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx); int ossl_decoder_store_remove_all_provided(const OSSL_PROVIDER *prov); +void *ossl_decoder_cache_new(OSSL_LIB_CTX *ctx); +void ossl_decoder_cache_free(void *vcache); +int ossl_decoder_cache_flush(OSSL_LIB_CTX *libctx); + #endif diff --git a/include/crypto/dherr.h b/include/crypto/dherr.h index bb24d131eb..519327f795 100644 --- a/include/crypto/dherr.h +++ b/include/crypto/dherr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h index 260c30fa4b..85d92a18cb 100644 --- a/include/crypto/dsa.h +++ b/include/crypto/dsa.h @@ -26,7 +26,9 @@ int ossl_dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, BN_GENCB *cb); int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa); + unsigned char *sig, unsigned int *siglen, DSA *dsa, + unsigned int nonce_type, const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa); int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]); diff --git a/include/crypto/ec.h b/include/crypto/ec.h index 62163b31ac..da85a7bd88 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -95,6 +95,12 @@ char *ossl_ec_pt_format_id2name(int id); char *ossl_ec_check_group_type_id2name(int flags); int ossl_ec_set_check_group_type_from_name(EC_KEY *ec, const char *name); - +int ossl_ec_generate_key_dhkem(EC_KEY *eckey, + const unsigned char *ikm, size_t ikmlen); +int ossl_ecdsa_deterministic_sign(const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, + EC_KEY *eckey, unsigned int nonce_type, + const char *digestname, + OSSL_LIB_CTX *libctx, const char *propq); # endif /* OPENSSL_NO_EC */ #endif diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 48b95fa5ba..f35b875fb6 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,7 +15,7 @@ # include -# ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX # include # include @@ -72,7 +72,6 @@ struct ecx_key_st { size_t keylen; ECX_KEY_TYPE type; CRYPTO_REF_COUNT references; - CRYPTO_RWLOCK *lock; }; size_t ossl_ecx_key_length(ECX_KEY_TYPE type); @@ -83,6 +82,9 @@ unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key); void ossl_ecx_key_free(ECX_KEY *key); int ossl_ecx_key_up_ref(ECX_KEY *key); ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection); +int ossl_ecx_compute_key(ECX_KEY *peer, ECX_KEY *priv, size_t keylen, + unsigned char *secret, size_t *secretlen, + size_t outlen); int ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32], const uint8_t peer_public_value[32]); @@ -94,27 +96,33 @@ ossl_ed25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[32], const uint8_t private_key[32], const char *propq); int -ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, +ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *tbs, size_t tbs_len, const uint8_t public_key[32], const uint8_t private_key[32], + const uint8_t dom2flag, const uint8_t phflag, const uint8_t csflag, + const uint8_t *context, size_t context_len, OSSL_LIB_CTX *libctx, const char *propq); int -ossl_ed25519_verify(const uint8_t *message, size_t message_len, +ossl_ed25519_verify(const uint8_t *tbs, size_t tbs_len, const uint8_t signature[64], const uint8_t public_key[32], + const uint8_t dom2flag, const uint8_t phflag, const uint8_t csflag, + const uint8_t *context, size_t context_len, OSSL_LIB_CTX *libctx, const char *propq); - int ossl_ed448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57], const uint8_t private_key[57], const char *propq); int -ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message, - size_t message_len, const uint8_t public_key[57], - const uint8_t private_key[57], const uint8_t *context, - size_t context_len, const char *propq); +ossl_ed448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, + const uint8_t *message, size_t message_len, + const uint8_t public_key[57], const uint8_t private_key[57], + const uint8_t *context, size_t context_len, + const uint8_t phflag, const char *propq); int -ossl_ed448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len, +ossl_ed448_verify(OSSL_LIB_CTX *ctx, + const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len, const char *propq); + const uint8_t *context, size_t context_len, + const uint8_t phflag, const char *propq); int ossl_x448(uint8_t out_shared_key[56], const uint8_t private_key[56], @@ -146,5 +154,5 @@ ECX_KEY *ossl_evp_pkey_get1_X25519(EVP_PKEY *pkey); ECX_KEY *ossl_evp_pkey_get1_X448(EVP_PKEY *pkey); ECX_KEY *ossl_evp_pkey_get1_ED25519(EVP_PKEY *pkey); ECX_KEY *ossl_evp_pkey_get1_ED448(EVP_PKEY *pkey); -# endif /* OPENSSL_NO_EC */ +# endif /* OPENSSL_NO_ECX */ #endif diff --git a/include/crypto/encoder.h b/include/crypto/encoder.h index 5c53bbea39..6240438d6d 100644 --- a/include/crypto/encoder.h +++ b/include/crypto/encoder.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/evp.h b/include/crypto/evp.h index a0fff7fded..34cea2f9f4 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -16,11 +16,21 @@ # include "internal/refcount.h" # include "crypto/ecx.h" +/* + * Default PKCS5 PBE KDF salt lengths + * In RFC 8018, PBE1 uses 8 bytes (64 bits) for its salt length. + * It also specifies to use at least 8 bytes for PBES2. + * The NIST requirement for PBKDF2 is 128 bits so we use this as the + * default for PBE2 (scrypt and HKDF2) + */ +# define PKCS5_DEFAULT_PBE1_SALT_LEN PKCS5_SALT_LEN +# define PKCS5_DEFAULT_PBE2_SALT_LEN 16 /* * Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag * values in evp.h */ #define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 +#define EVP_MD_CTX_FLAG_FINALISED 0x0800 #define evp_pkey_ctx_is_legacy(ctx) \ ((ctx)->keymgmt == NULL) @@ -203,7 +213,6 @@ struct evp_mac_st { const char *description; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_mac_newctx_fn *newctx; OSSL_FUNC_mac_dupctx_fn *dupctx; @@ -225,7 +234,6 @@ struct evp_kdf_st { char *type_name; const char *description; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_kdf_newctx_fn *newctx; OSSL_FUNC_kdf_dupctx_fn *dupctx; @@ -270,7 +278,6 @@ struct evp_md_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_digest_newctx_fn *newctx; OSSL_FUNC_digest_init_fn *dinit; OSSL_FUNC_digest_update_fn *dupdate; @@ -326,7 +333,6 @@ struct evp_cipher_st { const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; @@ -646,7 +652,9 @@ union legacy_pkey_st { # endif # ifndef OPENSSL_NO_EC struct ec_key_st *ec; /* ECC */ +# ifndef OPENSSL_NO_ECX ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */ +# endif # endif }; @@ -784,7 +792,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, int selection); -int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking); +int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk); int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt, void *keydata, int selection); void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk); @@ -813,7 +821,7 @@ int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection, const OSSL_PARAM params[]); int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, - void *template); + void *templ); int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, const OSSL_PARAM params[]); void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx, @@ -892,10 +900,6 @@ EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, int evp_pkey_name2type(const char *name); const char *evp_pkey_type2name(int type); -int evp_pkey_ctx_set1_id_prov(EVP_PKEY_CTX *ctx, const void *id, int len); -int evp_pkey_ctx_get1_id_prov(EVP_PKEY_CTX *ctx, void *id); -int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len); - int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx); # endif /* !defined(FIPS_MODULE) */ @@ -959,4 +963,8 @@ void evp_rand_clear_seed(EVP_RAND_CTX *ctx, unsigned char *buffer, size_t b_len); int evp_signature_get_number(const EVP_SIGNATURE *signature); +int evp_pkey_decrypt_alloc(EVP_PKEY_CTX *ctx, unsigned char **outp, + size_t *outlenp, size_t expected_outlen, + const unsigned char *in, size_t inlen); + #endif /* OSSL_CRYPTO_EVP_H */ diff --git a/include/crypto/evperr.h b/include/crypto/evperr.h index d90ba83f8b..4a00110791 100644 --- a/include/crypto/evperr.h +++ b/include/crypto/evperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/md32_common.h b/include/crypto/md32_common.h index 966e2684e4..46214f3237 100644 --- a/include/crypto/md32_common.h +++ b/include/crypto/md32_common.h @@ -63,37 +63,41 @@ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order */ -#include +#ifndef OSSL_CRYPTO_MD32_COMMON_H +# define OSSL_CRYPTO_MD32_COMMON_H +# pragma once -#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) -# error "DATA_ORDER must be defined!" -#endif +# include -#ifndef HASH_CBLOCK -# error "HASH_CBLOCK must be defined!" -#endif -#ifndef HASH_LONG -# error "HASH_LONG must be defined!" -#endif -#ifndef HASH_CTX -# error "HASH_CTX must be defined!" -#endif +# if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# error "DATA_ORDER must be defined!" +# endif -#ifndef HASH_UPDATE -# error "HASH_UPDATE must be defined!" -#endif -#ifndef HASH_TRANSFORM -# error "HASH_TRANSFORM must be defined!" -#endif -#ifndef HASH_FINAL -# error "HASH_FINAL must be defined!" -#endif +# ifndef HASH_CBLOCK +# error "HASH_CBLOCK must be defined!" +# endif +# ifndef HASH_LONG +# error "HASH_LONG must be defined!" +# endif +# ifndef HASH_CTX +# error "HASH_CTX must be defined!" +# endif -#ifndef HASH_BLOCK_DATA_ORDER -# error "HASH_BLOCK_DATA_ORDER must be defined!" -#endif +# ifndef HASH_UPDATE +# error "HASH_UPDATE must be defined!" +# endif +# ifndef HASH_TRANSFORM +# error "HASH_TRANSFORM must be defined!" +# endif +# ifndef HASH_FINAL +# error "HASH_FINAL must be defined!" +# endif + +# ifndef HASH_BLOCK_DATA_ORDER +# error "HASH_BLOCK_DATA_ORDER must be defined!" +# endif -#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) #ifndef PEDANTIC # if defined(__GNUC__) && __GNUC__>=2 && \ @@ -117,31 +121,31 @@ # endif #endif -#if defined(DATA_ORDER_IS_BIG_ENDIAN) +# if defined(DATA_ORDER_IS_BIG_ENDIAN) -# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++))) ) ) -# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l) )&0xff), \ l) -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) -# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<<24) ) -# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>>24)&0xff), \ l) -#endif +# endif /* * Time for some action :-) @@ -226,30 +230,30 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c) memset(p + n, 0, HASH_CBLOCK - 8 - n); p += HASH_CBLOCK - 8; -#if defined(DATA_ORDER_IS_BIG_ENDIAN) +# if defined(DATA_ORDER_IS_BIG_ENDIAN) (void)HOST_l2c(c->Nh, p); (void)HOST_l2c(c->Nl, p); -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) (void)HOST_l2c(c->Nl, p); (void)HOST_l2c(c->Nh, p); -#endif +# endif p -= HASH_CBLOCK; HASH_BLOCK_DATA_ORDER(c, p, 1); c->num = 0; OPENSSL_cleanse(p, HASH_CBLOCK); -#ifndef HASH_MAKE_STRING -# error "HASH_MAKE_STRING must be defined!" -#else +# ifndef HASH_MAKE_STRING +# error "HASH_MAKE_STRING must be defined!" +# else HASH_MAKE_STRING(c, md); -#endif +# endif return 1; } -#ifndef MD32_REG_T -# if defined(__alpha) || defined(__sparcv9) || defined(__mips) -# define MD32_REG_T long +# ifndef MD32_REG_T +# if defined(__alpha) || defined(__sparcv9) || defined(__mips) +# define MD32_REG_T long /* * This comment was originally written for MD5, which is why it * discusses A-D. But it basically applies to all 32-bit digests, @@ -266,13 +270,15 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c) * Well, to be honest it should say that this *prevents* * performance degradation. */ -# else +# else /* * Above is not absolute and there are LP64 compilers that * generate better code if MD32_REG_T is defined int. The above * pre-processor condition reflects the circumstances under which * the conclusion was made and is subject to further extension. */ -# define MD32_REG_T int +# define MD32_REG_T int +# endif # endif + #endif diff --git a/include/crypto/modes.h b/include/crypto/modes.h index 573e1197d0..d03ca83d00 100644 --- a/include/crypto/modes.h +++ b/include/crypto/modes.h @@ -138,6 +138,12 @@ struct gcm128_context { #endif }; +/* GHASH functions */ +void ossl_gcm_init_4bit(u128 Htable[16], const u64 H[2]); +void ossl_gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len); +void ossl_gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); + /* * The maximum permitted number of cipher blocks per data unit in XTS mode. * Reference IEEE Std 1619-2018. @@ -149,6 +155,12 @@ struct xts128_context { block128_f block1, block2; }; +/* XTS mode for SM4 algorithm specified by GB/T 17964-2021 */ +int ossl_crypto_xts128gb_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + struct ccm128_context { union { u64 u[2]; diff --git a/include/crypto/pkcs12err.h b/include/crypto/pkcs12err.h index 662f412e97..114971c607 100644 --- a/include/crypto/pkcs12err.h +++ b/include/crypto/pkcs12err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/punycode.h b/include/crypto/punycode.h index 4c6e49f516..2e1c85c1f7 100644 --- a/include/crypto/punycode.h +++ b/include/crypto/punycode.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,6 +22,4 @@ int ossl_punycode_decode ( int ossl_a2ulabel(const char *in, char *out, size_t outlen); -int ossl_a2ucompare(const char *a, const char *u); - #endif diff --git a/include/crypto/rand.h b/include/crypto/rand.h index 215b3b7af3..d375c2f933 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -140,4 +140,15 @@ EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx); # else EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx); # endif + +/* Generate a uniformly distributed random integer in the interval [0, upper) */ +uint32_t ossl_rand_uniform_uint32(OSSL_LIB_CTX *ctx, uint32_t upper, int *err); + +/* + * Generate a uniformly distributed random integer in the interval + * [lower, upper). + */ +uint32_t ossl_rand_range_uint32(OSSL_LIB_CTX *ctx, uint32_t lower, uint32_t upper, + int *err); + #endif diff --git a/include/crypto/riscv_arch.h b/include/crypto/riscv_arch.h index 89a40bea84..9518584111 100644 --- a/include/crypto/riscv_arch.h +++ b/include/crypto/riscv_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -56,4 +56,9 @@ static const size_t kRISCVNumCaps = # include "riscv_arch.def" ; +/* Extension combination tests. */ +#define RISCV_HAS_ZBB_AND_ZBC() (RISCV_HAS_ZBB() && RISCV_HAS_ZBC()) +#define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) +#define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) + #endif diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 949873d0ee..8eddc168f6 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,8 +34,6 @@ int ossl_rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, int ossl_rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params); int ossl_rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, int hashalg_nid); -int ossl_rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenalg_nid); int ossl_rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, int maskgenhashalg_nid); int ossl_rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, @@ -83,6 +81,10 @@ int ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg); RSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, OSSL_LIB_CTX *libctx, const char *propq); +int ossl_rsa_padding_check_PKCS1_type_2(OSSL_LIB_CTX *ctx, + unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, unsigned char *kdk); int ossl_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX *ctx, unsigned char *to, size_t tlen, const unsigned char *from, diff --git a/include/crypto/sha.h b/include/crypto/sha.h index 64305d1790..99bcf0ff88 100644 --- a/include/crypto/sha.h +++ b/include/crypto/sha.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -14,6 +14,7 @@ # include +int ossl_sha256_192_init(SHA256_CTX *c); int sha512_224_init(SHA512_CTX *); int sha512_256_init(SHA512_CTX *); int ossl_sha1_ctrl(SHA_CTX *ctx, int cmd, int mslen, void *ms); diff --git a/include/crypto/sm4_platform.h b/include/crypto/sm4_platform.h index 6cc1dfa502..cc4f514256 100644 --- a/include/crypto/sm4_platform.h +++ b/include/crypto/sm4_platform.h @@ -12,7 +12,7 @@ # pragma once # if defined(OPENSSL_CPUID_OBJ) -# if defined(__aarch64__) +# if defined(__aarch64__) || defined (_M_ARM64) # include "arm_arch.h" extern unsigned int OPENSSL_arm_midr; static inline int vpsm4_capable(void) @@ -21,8 +21,14 @@ static inline int vpsm4_capable(void) (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)); } +static inline int vpsm4_ex_capable(void) +{ + return (OPENSSL_armcap_P & ARMV8_CPUID) && + (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, HISI_CPU_IMP, HISI_CPU_PART_KP920)); +} # if defined(VPSM4_ASM) # define VPSM4_CAPABLE vpsm4_capable() +# define VPSM4_EX_CAPABLE vpsm4_ex_capable() # endif # define HWSM4_CAPABLE (OPENSSL_armcap_P & ARMV8_SM4) # define HWSM4_set_encrypt_key sm4_v8_set_encrypt_key @@ -53,7 +59,7 @@ void HWSM4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, const unsigned char ivec[16]); # endif /* HWSM4_CAPABLE */ -#ifdef VPSM4_CAPABLE +# ifdef VPSM4_CAPABLE int vpsm4_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); int vpsm4_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); void vpsm4_encrypt(const unsigned char *in, unsigned char *out, @@ -69,7 +75,37 @@ void vpsm4_ecb_encrypt(const unsigned char *in, unsigned char *out, void vpsm4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len, const void *key, const unsigned char ivec[16]); +void vpsm4_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SM4_KEY *key1, const SM4_KEY *key2, + const unsigned char ivec[16], const int enc); +void vpsm4_xts_encrypt_gb(const unsigned char *in, unsigned char *out, + size_t len, const SM4_KEY *key1, const SM4_KEY *key2, + const unsigned char ivec[16], const int enc); # endif /* VPSM4_CAPABLE */ +# ifdef VPSM4_EX_CAPABLE +int vpsm4_ex_set_encrypt_key(const unsigned char *userKey, SM4_KEY *key); +int vpsm4_ex_set_decrypt_key(const unsigned char *userKey, SM4_KEY *key); +void vpsm4_ex_encrypt(const unsigned char *in, unsigned char *out, + const SM4_KEY *key); +void vpsm4_ex_decrypt(const unsigned char *in, unsigned char *out, + const SM4_KEY *key); +void vpsm4_ex_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const SM4_KEY *key, + unsigned char *ivec, const int enc); +void vpsm4_ex_ecb_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const SM4_KEY *key, + const int enc); +void vpsm4_ex_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + const unsigned char ivec[16]); +void vpsm4_ex_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SM4_KEY *key1, const SM4_KEY *key2, + const unsigned char ivec[16], const int enc); +void vpsm4_ex_xts_encrypt_gb(const unsigned char *in, unsigned char *out, + size_t len, const SM4_KEY *key1, + const SM4_KEY *key2, const unsigned char ivec[16], + const int enc); +# endif /* VPSM4_EX_CAPABLE */ #endif /* OSSL_SM4_PLATFORM_H */ diff --git a/include/crypto/store.h b/include/crypto/store.h index 5645fc9235..9b7be71acd 100644 --- a/include/crypto/store.h +++ b/include/crypto/store.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/x509.h b/include/crypto/x509.h index 631150b769..5765b9f719 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -278,6 +278,8 @@ struct x509_store_ctx_st { /* X509_STORE_CTX */ SSL_DANE *dane; /* signed via bare TA public key, rather than CA certificate */ int bare_ta_signed; + /* Raw Public Key */ + EVP_PKEY *rpk; OSSL_LIB_CTX *libctx; char *propq; @@ -309,7 +311,7 @@ struct x509_object_st { }; int ossl_a2i_ipadd(unsigned char *ipout, const char *ipasc); -int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm); +int ossl_x509_set1_time(int *modified, ASN1_TIME **ptm, const ASN1_TIME *tm); int ossl_x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags); int ossl_x509v3_cache_extensions(X509 *x); int ossl_x509_init_sig_info(X509 *x); @@ -334,7 +336,8 @@ int ossl_x509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq, ASN1_OCTET_STRING *ossl_x509_pubkey_hash(X509_PUBKEY *pubkey); X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, - long len, OSSL_LIB_CTX *libctx); + long len, OSSL_LIB_CTX *libctx, + const char *propq); void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub); RSA *ossl_d2i_RSA_PSS_PUBKEY(RSA **a, const unsigned char **pp, long length); @@ -364,6 +367,7 @@ int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp); # endif /* OPENSSL_NO_EC */ EVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **pp, long length); +int ossl_x509_check_private_key(const EVP_PKEY *k, const EVP_PKEY *pkey); int x509v3_add_len_value_uchar(const char *name, const unsigned char *value, size_t vallen, STACK_OF(CONF_VALUE) **extlist); diff --git a/include/crypto/x509err.h b/include/crypto/x509err.h index 0a67975bd0..c7c7d25e97 100644 --- a/include/crypto/x509err.h +++ b/include/crypto/x509err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/asn1.h b/include/internal/asn1.h index 3143e3405f..36dbe0fcd3 100644 --- a/include/internal/asn1.h +++ b/include/internal/asn1.h @@ -11,6 +11,8 @@ # define OSSL_INTERNAL_ASN1_H # pragma once +# include + int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); #endif diff --git a/include/internal/bio.h b/include/internal/bio.h index 547a73d02d..9481f4c985 100644 --- a/include/internal/bio.h +++ b/include/internal/bio.h @@ -27,6 +27,8 @@ struct bio_method_st { int (*create) (BIO *); int (*destroy) (BIO *); long (*callback_ctrl) (BIO *, int, BIO_info_cb *); + int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *); + int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *); }; void bio_free_ex_data(BIO *bio); @@ -41,16 +43,20 @@ int bread_conv(BIO *bio, char *data, size_t datal, size_t *read); # define BIO_CTRL_SET_KTLS 72 # define BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG 74 # define BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG 75 +# define BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE 90 /* * This is used with socket BIOs: * BIO_FLAGS_KTLS_TX means we are using ktls with this BIO for sending. * BIO_FLAGS_KTLS_TX_CTRL_MSG means we are about to send a ctrl message next. * BIO_FLAGS_KTLS_RX means we are using ktls with this BIO for receiving. + * BIO_FLAGS_KTLS_TX_ZEROCOPY_SENDFILE means we are using the zerocopy mode with + * this BIO for sending using sendfile. */ # define BIO_FLAGS_KTLS_TX_CTRL_MSG 0x1000 # define BIO_FLAGS_KTLS_RX 0x2000 # define BIO_FLAGS_KTLS_TX 0x4000 +# define BIO_FLAGS_KTLS_TX_ZEROCOPY_SENDFILE 0x8000 /* KTLS related controls and flags */ # define BIO_set_ktls_flag(b, is_tx) \ @@ -63,6 +69,8 @@ int bread_conv(BIO *bio, char *data, size_t datal, size_t *read); BIO_test_flags(b, BIO_FLAGS_KTLS_TX_CTRL_MSG) # define BIO_clear_ktls_ctrl_msg_flag(b) \ BIO_clear_flags(b, BIO_FLAGS_KTLS_TX_CTRL_MSG) +# define BIO_set_ktls_zerocopy_sendfile_flag(b) \ + BIO_set_flags(b, BIO_FLAGS_KTLS_TX_ZEROCOPY_SENDFILE) # define BIO_set_ktls(b, keyblob, is_tx) \ BIO_ctrl(b, BIO_CTRL_SET_KTLS, is_tx, keyblob) @@ -70,6 +78,8 @@ int bread_conv(BIO *bio, char *data, size_t datal, size_t *read); BIO_ctrl(b, BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG, record_type, NULL) # define BIO_clear_ktls_ctrl_msg(b) \ BIO_ctrl(b, BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG, 0, NULL) +# define BIO_set_ktls_tx_zerocopy_sendfile(b) \ + BIO_ctrl(b, BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE, 0, NULL) /* Functions to allow the core to offer the CORE_BIO type to providers */ OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio); diff --git a/include/internal/bio_addr.h b/include/internal/bio_addr.h new file mode 100644 index 0000000000..a6449b7eb0 --- /dev/null +++ b/include/internal/bio_addr.h @@ -0,0 +1,29 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_BIO_ADDR_H +# define OSSL_BIO_ADDR_H + +# include "internal/e_os.h" +# include "internal/sockets.h" + +# ifndef OPENSSL_NO_SOCK +union bio_addr_st { + struct sockaddr sa; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 s_in6; +# endif + struct sockaddr_in s_in; +# ifndef OPENSSL_NO_UNIX_SOCK + struct sockaddr_un s_un; +# endif +}; +# endif + +#endif diff --git a/include/internal/bio_tfo.h b/include/internal/bio_tfo.h new file mode 100644 index 0000000000..64c0d4c327 --- /dev/null +++ b/include/internal/bio_tfo.h @@ -0,0 +1,151 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Contains definitions for simplifying the use of TCP Fast Open + * (RFC7413) in OpenSSL socket BIOs. + */ + +/* If a supported OS is added here, update test/bio_tfo_test.c */ +#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO) + +# if defined(OPENSSL_SYS_MACOSX) || defined(__FreeBSD__) +# include +# endif + +/* + * OSSL_TFO_SYSCTL is used to determine if TFO is supported by + * this kernel, and if supported, if it is enabled. This is more of + * a problem on FreeBSD 10.3 ~ 11.4, where TCP_FASTOPEN was defined, + * but not enabled by default in the kernel, and only for the server. + * Linux does not have sysctlbyname(), and the closest equivalent + * is to go into the /proc filesystem, but I'm not sure it's + * worthwhile. + * + * On MacOS and Linux: + * These operating systems use a single parameter to control TFO. + * The OSSL_TFO_CLIENT_FLAG and OSSL_TFO_SERVER_FLAGS are used to + * determine if TFO is enabled for the client and server respectively. + * + * OSSL_TFO_CLIENT_FLAG = 1 = client TFO enabled + * OSSL_TFO_SERVER_FLAG = 2 = server TFO enabled + * + * Such that: + * 0 = TFO disabled + * 3 = server and client TFO enabled + * + * macOS 10.14 and later support TFO. + * Linux kernel 3.6 added support for client TFO. + * Linux kernel 3.7 added support for server TFO. + * Linux kernel 3.13 enabled TFO by default. + * Linux kernel 4.11 added the TCP_FASTOPEN_CONNECT option. + * + * On FreeBSD: + * FreeBSD 10.3 ~ 11.4 uses a single sysctl for server enable. + * FreeBSD 12.0 and later uses separate sysctls for server and + * client enable. + * + * Some options are purposely NOT defined per-platform + * + * OSSL_TFO_SYSCTL + * Defined as a sysctlbyname() option to determine if + * TFO is enabled in the kernel (macOS, FreeBSD) + * + * OSSL_TFO_SERVER_SOCKOPT + * Defined to indicate the socket option used to enable + * TFO on a server socket (all) + * + * OSSL_TFO_SERVER_SOCKOPT_VALUE + * Value to be used with OSSL_TFO_SERVER_SOCKOPT + * + * OSSL_TFO_CONNECTX + * Use the connectx() function to make a client connection + * (macOS) + * + * OSSL_TFO_CLIENT_SOCKOPT + * Defined to indicate the socket option used to enable + * TFO on a client socket (FreeBSD, Linux 4.14 and later) + * + * OSSL_TFO_SENDTO + * Defined to indicate the sendto() message type to + * be used to initiate a TFO connection (FreeBSD, + * Linux pre-4.14) + * + * OSSL_TFO_DO_NOT_CONNECT + * Defined to skip calling connect() when creating a + * client socket (macOS, FreeBSD, Linux pre-4.14) + */ + +# if defined(OPENSSL_SYS_WINDOWS) +/* + * NO WINDOWS SUPPORT + * + * But this is what would be used on the server: + * + * define OSSL_TFO_SERVER_SOCKOPT TCP_FASTOPEN + * define OSSL_TFO_SERVER_SOCKOPT_VALUE 1 + * + * Still have to figure out client support + */ +# undef TCP_FASTOPEN +# endif + +/* NO VMS SUPPORT */ +# if defined(OPENSSL_SYS_VMS) +# undef TCP_FASTOPEN +# endif + +# if defined(OPENSSL_SYS_MACOSX) +# define OSSL_TFO_SYSCTL "net.inet.tcp.fastopen" +# define OSSL_TFO_SERVER_SOCKOPT TCP_FASTOPEN +# define OSSL_TFO_SERVER_SOCKOPT_VALUE 1 +# define OSSL_TFO_CONNECTX 1 +# define OSSL_TFO_DO_NOT_CONNECT 1 +# define OSSL_TFO_CLIENT_FLAG 1 +# define OSSL_TFO_SERVER_FLAG 2 +# endif + +# if defined(__FreeBSD__) +# if defined(TCP_FASTOPEN_PSK_LEN) +/* As of 12.0 these are the SYSCTLs */ +# define OSSL_TFO_SYSCTL_SERVER "net.inet.tcp.fastopen.server_enable" +# define OSSL_TFO_SYSCTL_CLIENT "net.inet.tcp.fastopen.client_enable" +# define OSSL_TFO_SERVER_SOCKOPT TCP_FASTOPEN +# define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN +# define OSSL_TFO_CLIENT_SOCKOPT TCP_FASTOPEN +# define OSSL_TFO_DO_NOT_CONNECT 1 +# define OSSL_TFO_SENDTO 0 +/* These are the same because the sysctl are client/server-specific */ +# define OSSL_TFO_CLIENT_FLAG 1 +# define OSSL_TFO_SERVER_FLAG 1 +# else +/* 10.3 through 11.4 SYSCTL - ONLY SERVER SUPPORT */ +# define OSSL_TFO_SYSCTL "net.inet.tcp.fastopen.enabled" +# define OSSL_TFO_SERVER_SOCKOPT TCP_FASTOPEN +# define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN +# define OSSL_TFO_SERVER_FLAG 1 +# endif +# endif + +# if defined(OPENSSL_SYS_LINUX) +/* OSSL_TFO_PROC not used, but of interest */ +# define OSSL_TFO_PROC "/proc/sys/net/ipv4/tcp_fastopen" +# define OSSL_TFO_SERVER_SOCKOPT TCP_FASTOPEN +# define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN +# if defined(TCP_FASTOPEN_CONNECT) +# define OSSL_TFO_CLIENT_SOCKOPT TCP_FASTOPEN_CONNECT +# else +# define OSSL_TFO_SENDTO MSG_FASTOPEN +# define OSSL_TFO_DO_NOT_CONNECT 1 +# endif +# define OSSL_TFO_CLIENT_FLAG 1 +# define OSSL_TFO_SERVER_FLAG 2 +# endif + +#endif diff --git a/include/internal/common.h b/include/internal/common.h new file mode 100644 index 0000000000..15666f1110 --- /dev/null +++ b/include/internal/common.h @@ -0,0 +1,217 @@ +/* + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_COMMON_H +# define OSSL_INTERNAL_COMMON_H +# pragma once + +# include +# include +# include "openssl/configuration.h" + +# include "internal/e_os.h" /* ossl_inline in many files */ +# include "internal/nelem.h" + +# if defined(__GNUC__) || defined(__clang__) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# else +# define likely(x) x +# define unlikely(x) x +# endif + +# if defined(__GNUC__) || defined(__clang__) +# define ALIGN32 __attribute((aligned(32))) +# define ALIGN64 __attribute((aligned(64))) +# elif defined(_MSC_VER) +# define ALIGN32 __declspec(align(32)) +# define ALIGN64 __declspec(align(64)) +# else +# define ALIGN32 +# define ALIGN64 +# endif + +# ifdef NDEBUG +# define ossl_assert(x) ((x) != 0) +# else +__owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, + const char *file, int line) +{ + if (!expr) + OPENSSL_die(exprstr, file, line); + + return expr; +} + +# define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: "#x, \ + __FILE__, __LINE__) + +# endif + +/* Check if |pre|, which must be a string literal, is a prefix of |str| */ +#define HAS_PREFIX(str, pre) (strncmp(str, pre "", sizeof(pre) - 1) == 0) +/* As before, and if check succeeds, advance |str| past the prefix |pre| */ +#define CHECK_AND_SKIP_PREFIX(str, pre) \ + (HAS_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0) +/* Check if the string literal |p| is a case-insensitive prefix of |s| */ +#define HAS_CASE_PREFIX(s, p) (OPENSSL_strncasecmp(s, p "", sizeof(p) - 1) == 0) +/* As before, and if check succeeds, advance |str| past the prefix |pre| */ +#define CHECK_AND_SKIP_CASE_PREFIX(str, pre) \ + (HAS_CASE_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0) +/* Check if the string literal |suffix| is a case-insensitive suffix of |str| */ +#define HAS_CASE_SUFFIX(str, suffix) (strlen(str) < sizeof(suffix) - 1 ? 0 : \ + OPENSSL_strcasecmp(str + strlen(str) - sizeof(suffix) + 1, suffix "") == 0) + +/* + * Use this inside a union with the field that needs to be aligned to a + * reasonable boundary for the platform. The most pessimistic alignment + * of the listed types will be used by the compiler. + */ +# define OSSL_UNION_ALIGN \ + double align; \ + ossl_uintmax_t align_int; \ + void *align_ptr + +# define OPENSSL_CONF "openssl.cnf" + +# ifndef OPENSSL_SYS_VMS +# define X509_CERT_AREA OPENSSLDIR +# define X509_CERT_DIR OPENSSLDIR "/certs" +# define X509_CERT_FILE OPENSSLDIR "/cert.pem" +# define X509_PRIVATE_DIR OPENSSLDIR "/private" +# define CTLOG_FILE OPENSSLDIR "/ct_log_list.cnf" +# else +# define X509_CERT_AREA "OSSL$DATAROOT:[000000]" +# define X509_CERT_DIR "OSSL$DATAROOT:[CERTS]" +# define X509_CERT_FILE "OSSL$DATAROOT:[000000]cert.pem" +# define X509_PRIVATE_DIR "OSSL$DATAROOT:[PRIVATE]" +# define CTLOG_FILE "OSSL$DATAROOT:[000000]ct_log_list.cnf" +# endif + +# define X509_CERT_DIR_EVP "SSL_CERT_DIR" +# define X509_CERT_FILE_EVP "SSL_CERT_FILE" +# define CTLOG_FILE_EVP "CTLOG_FILE" + +/* size of string representations */ +# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) +# define HEX_SIZE(type) (sizeof(type)*2) + +# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))) + +# define n2l8(c,l) (l =((uint64_t)(*((c)++)))<<56, \ + l|=((uint64_t)(*((c)++)))<<48, \ + l|=((uint64_t)(*((c)++)))<<40, \ + l|=((uint64_t)(*((c)++)))<<32, \ + l|=((uint64_t)(*((c)++)))<<24, \ + l|=((uint64_t)(*((c)++)))<<16, \ + l|=((uint64_t)(*((c)++)))<< 8, \ + l|=((uint64_t)(*((c)++)))) + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# define n2s(c,s) ((s=(((unsigned int)((c)[0]))<< 8)| \ + (((unsigned int)((c)[1])) )),(c)+=2) +# define s2n(s,c) (((c)[0]=(unsigned char)(((s)>> 8)&0xff), \ + (c)[1]=(unsigned char)(((s) )&0xff)),(c)+=2) + +# define n2l3(c,l) ((l =(((unsigned long)((c)[0]))<<16)| \ + (((unsigned long)((c)[1]))<< 8)| \ + (((unsigned long)((c)[2])) )),(c)+=3) + +# define l2n3(l,c) (((c)[0]=(unsigned char)(((l)>>16)&0xff), \ + (c)[1]=(unsigned char)(((l)>> 8)&0xff), \ + (c)[2]=(unsigned char)(((l) )&0xff)),(c)+=3) + +static ossl_inline int ossl_ends_with_dirsep(const char *path) +{ + if (*path != '\0') + path += strlen(path) - 1; +# if defined __VMS + if (*path == ']' || *path == '>' || *path == ':') + return 1; +# elif defined _WIN32 + if (*path == '\\') + return 1; +# endif + return *path == '/'; +} + +static ossl_inline int ossl_is_absolute_path(const char *path) +{ +# if defined __VMS + if (strchr(path, ':') != NULL + || ((path[0] == '[' || path[0] == '<') + && path[1] != '.' && path[1] != '-' + && path[1] != ']' && path[1] != '>')) + return 1; +# elif defined _WIN32 + if (path[0] == '\\' + || (path[0] != '\0' && path[1] == ':')) + return 1; +# endif + return path[0] == '/'; +} + +#endif diff --git a/include/internal/comp.h b/include/internal/comp.h index 3ad86fc7b1..c48c29d562 100644 --- a/include/internal/comp.h +++ b/include/internal/comp.h @@ -10,3 +10,5 @@ #include void ossl_comp_zlib_cleanup(void); +void ossl_comp_brotli_cleanup(void); +void ossl_comp_zstd_cleanup(void); diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index ac50eb3bbd..64851fd8ed 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,9 +11,6 @@ # define OSSL_INTERNAL_CRYPTLIB_H # pragma once -# include -# include - # ifdef OPENSSL_USE_APPLINK # define BIO_FLAGS_UPLINK_INTERNAL 0x8000 # include "ms/uplink.h" @@ -21,39 +18,13 @@ # define BIO_FLAGS_UPLINK_INTERNAL 0 # endif +# include "internal/common.h" + # include # include # include # include # include -# include "internal/nelem.h" - -#ifdef NDEBUG -# define ossl_assert(x) ((x) != 0) -#else -__owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, - const char *file, int line) -{ - if (!expr) - OPENSSL_die(exprstr, file, line); - - return expr; -} - -# define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: "#x, \ - __FILE__, __LINE__) - -#endif - -/* - * Use this inside a union with the field that needs to be aligned to a - * reasonable boundary for the platform. The most pessimistic alignment - * of the listed types will be used by the compiler. - */ -# define OSSL_UNION_ALIGN \ - double align; \ - ossl_uintmax_t align_int; \ - void *align_ptr typedef struct ex_callback_st EX_CALLBACK; DEFINE_STACK_OF(EX_CALLBACK) @@ -61,30 +32,6 @@ DEFINE_STACK_OF(EX_CALLBACK) typedef struct mem_st MEM; DEFINE_LHASH_OF_EX(MEM); -# define OPENSSL_CONF "openssl.cnf" - -# ifndef OPENSSL_SYS_VMS -# define X509_CERT_AREA OPENSSLDIR -# define X509_CERT_DIR OPENSSLDIR "/certs" -# define X509_CERT_FILE OPENSSLDIR "/cert.pem" -# define X509_PRIVATE_DIR OPENSSLDIR "/private" -# define CTLOG_FILE OPENSSLDIR "/ct_log_list.cnf" -# else -# define X509_CERT_AREA "OSSL$DATAROOT:[000000]" -# define X509_CERT_DIR "OSSL$DATAROOT:[CERTS]" -# define X509_CERT_FILE "OSSL$DATAROOT:[000000]cert.pem" -# define X509_PRIVATE_DIR "OSSL$DATAROOT:[PRIVATE]" -# define CTLOG_FILE "OSSL$DATAROOT:[000000]ct_log_list.cnf" -# endif - -# define X509_CERT_DIR_EVP "SSL_CERT_DIR" -# define X509_CERT_FILE_EVP "SSL_CERT_FILE" -# define CTLOG_FILE_EVP "CTLOG_FILE" - -/* size of string representations */ -# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) -# define HEX_SIZE(type) (sizeof(type)*2) - void OPENSSL_cpuid_setup(void); #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || \ @@ -168,7 +115,9 @@ typedef struct ossl_ex_data_global_st { # define OSSL_LIB_CTX_PROVIDER_CONF_INDEX 16 # define OSSL_LIB_CTX_BIO_CORE_INDEX 17 # define OSSL_LIB_CTX_CHILD_PROVIDER_INDEX 18 -# define OSSL_LIB_CTX_MAX_INDEXES 19 +# define OSSL_LIB_CTX_THREAD_INDEX 19 +# define OSSL_LIB_CTX_DECODER_CACHE_INDEX 20 +# define OSSL_LIB_CTX_MAX_INDEXES 20 OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx); int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx); @@ -211,34 +160,4 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep); unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen, const char sep); -static ossl_inline int ossl_ends_with_dirsep(const char *path) -{ - if (*path != '\0') - path += strlen(path) - 1; -# if defined __VMS - if (*path == ']' || *path == '>' || *path == ':') - return 1; -# elif defined _WIN32 - if (*path == '\\') - return 1; -# endif - return *path == '/'; -} - -static ossl_inline int ossl_is_absolute_path(const char *path) -{ -# if defined __VMS - if (strchr(path, ':') != NULL - || ((path[0] == '[' || path[0] == '<') - && path[1] != '.' && path[1] != '-' - && path[1] != ']' && path[1] != '>')) - return 1; -# elif defined _WIN32 - if (path[0] == '\\' - || (path[0] != '\0' && path[1] == ':')) - return 1; -# endif - return path[0] == '/'; -} - #endif diff --git a/include/internal/der.h b/include/internal/der.h index f23fabc290..8d6db8f066 100644 --- a/include/internal/der.h +++ b/include/internal/der.h @@ -7,8 +7,12 @@ * https://www.openssl.org/source/license.html */ -#include -#include "internal/packet.h" +#ifndef OSSL_INTERNAL_DER_H +# define OSSL_INTERNAL_DER_H +# pragma once + +# include +# include "internal/packet.h" /* * NOTE: X.690 numbers the identifier octet bits 1 to 8. @@ -22,42 +26,42 @@ * These are only valid for the UNIVERSAL class. With the other classes, * these bits have a different meaning. */ -#define DER_P_EOC 0 /* BER End Of Contents tag */ -#define DER_P_BOOLEAN 1 -#define DER_P_INTEGER 2 -#define DER_P_BIT_STRING 3 -#define DER_P_OCTET_STRING 4 -#define DER_P_NULL 5 -#define DER_P_OBJECT 6 -#define DER_P_OBJECT_DESCRIPTOR 7 -#define DER_P_EXTERNAL 8 -#define DER_P_REAL 9 -#define DER_P_ENUMERATED 10 -#define DER_P_UTF8STRING 12 -#define DER_P_SEQUENCE 16 -#define DER_P_SET 17 -#define DER_P_NUMERICSTRING 18 -#define DER_P_PRINTABLESTRING 19 -#define DER_P_T61STRING 20 -#define DER_P_VIDEOTEXSTRING 21 -#define DER_P_IA5STRING 22 -#define DER_P_UTCTIME 23 -#define DER_P_GENERALIZEDTIME 24 -#define DER_P_GRAPHICSTRING 25 -#define DER_P_ISO64STRING 26 -#define DER_P_GENERALSTRING 27 -#define DER_P_UNIVERSALSTRING 28 -#define DER_P_BMPSTRING 30 +# define DER_P_EOC 0 /* BER End Of Contents tag */ +# define DER_P_BOOLEAN 1 +# define DER_P_INTEGER 2 +# define DER_P_BIT_STRING 3 +# define DER_P_OCTET_STRING 4 +# define DER_P_NULL 5 +# define DER_P_OBJECT 6 +# define DER_P_OBJECT_DESCRIPTOR 7 +# define DER_P_EXTERNAL 8 +# define DER_P_REAL 9 +# define DER_P_ENUMERATED 10 +# define DER_P_UTF8STRING 12 +# define DER_P_SEQUENCE 16 +# define DER_P_SET 17 +# define DER_P_NUMERICSTRING 18 +# define DER_P_PRINTABLESTRING 19 +# define DER_P_T61STRING 20 +# define DER_P_VIDEOTEXSTRING 21 +# define DER_P_IA5STRING 22 +# define DER_P_UTCTIME 23 +# define DER_P_GENERALIZEDTIME 24 +# define DER_P_GRAPHICSTRING 25 +# define DER_P_ISO64STRING 26 +# define DER_P_GENERALSTRING 27 +# define DER_P_UNIVERSALSTRING 28 +# define DER_P_BMPSTRING 30 /* DER Flags, occupying bit 6 in the DER identifier byte */ -#define DER_F_PRIMITIVE 0x00 -#define DER_F_CONSTRUCTED 0x20 +# define DER_F_PRIMITIVE 0x00 +# define DER_F_CONSTRUCTED 0x20 /* DER classes tags, occupying bits 7-8 in the DER identifier byte */ -#define DER_C_UNIVERSAL 0x00 -#define DER_C_APPLICATION 0x40 -#define DER_C_CONTEXT 0x80 -#define DER_C_PRIVATE 0xC0 +# define DER_C_UNIVERSAL 0x00 +# define DER_C_APPLICATION 0x40 +# define DER_C_CONTEXT 0x80 +# define DER_C_PRIVATE 0xC0 /* * Run-time constructors. @@ -67,7 +71,7 @@ */ /* This can be used for all items that don't have a context */ -#define DER_NO_CONTEXT -1 +# define DER_NO_CONTEXT -1 int ossl_DER_w_precompiled(WPACKET *pkt, int tag, const unsigned char *precompiled, @@ -86,3 +90,5 @@ int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value); */ int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag); int ossl_DER_w_end_sequence(WPACKET *pkt, int tag); + +#endif diff --git a/include/internal/deterministic_nonce.h b/include/internal/deterministic_nonce.h new file mode 100644 index 0000000000..5f0313fe38 --- /dev/null +++ b/include/internal/deterministic_nonce.h @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_DETERMINISTIC_NONCE_H +# define OSSL_INTERNAL_DETERMINISTIC_NONCE_H +# pragma once + +# include + +int ossl_gen_deterministic_nonce_rfc6979(BIGNUM *out, const BIGNUM *q, + const BIGNUM *priv, + const unsigned char *message, + size_t message_len, + const char *digestname, + OSSL_LIB_CTX *libctx, + const char *propq); + +#endif /*OSSL_INTERNAL_DETERMINISTIC_NONCE_H */ diff --git a/include/internal/e_os.h b/include/internal/e_os.h index 7fdc389982..d1ed62e890 100644 --- a/include/internal/e_os.h +++ b/include/internal/e_os.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -143,7 +143,7 @@ static __inline unsigned int _strlen31(const char *str) # undef stdin # undef stdout # undef stderr -FILE *__iob_func(); +FILE *__iob_func(void); # define stdin (&__iob_func()[0]) # define stdout (&__iob_func()[1]) # define stderr (&__iob_func()[2]) @@ -249,7 +249,7 @@ FILE *__iob_func(); /***********************************************/ # if defined(OPENSSL_SYS_WINDOWS) -# if (_MSC_VER >= 1310) && !defined(_WIN32_WCE) +# if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(_WIN32_WCE) # define open _open # define fdopen _fdopen # define close _close @@ -286,54 +286,6 @@ struct servent *getservbyname(const char *name, const char *proto); # endif /* end vxworks */ -/* system-specific variants defining ossl_sleep() */ -#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) -# include -static ossl_inline void ossl_sleep(unsigned long millis) -{ -# ifdef OPENSSL_SYS_VXWORKS - struct timespec ts; - ts.tv_sec = (long int) (millis / 1000); - ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; - nanosleep(&ts, NULL); -# elif defined(__TANDEM) -# if !defined(_REENTRANT) -# include - /* HPNS does not support usleep for non threaded apps */ - PROCESS_DELAY_(millis * 1000); -# elif defined(_SPT_MODEL_) -# include -# include - usleep(millis * 1000); -# else - usleep(millis * 1000); -# endif -# else - usleep(millis * 1000); -# endif -} -#elif defined(_WIN32) -# include -static ossl_inline void ossl_sleep(unsigned long millis) -{ - Sleep(millis); -} -#else -/* Fallback to a busy wait */ -static ossl_inline void ossl_sleep(unsigned long millis) -{ - struct timeval start, now; - unsigned long elapsedms; - - gettimeofday(&start, NULL); - do { - gettimeofday(&now, NULL); - elapsedms = (((now.tv_sec - start.tv_sec) * 1000000) - + now.tv_usec - start.tv_usec) / 1000; - } while (elapsedms < millis); -} -#endif /* defined OPENSSL_SYS_UNIX */ - /* ----------------------------- HP NonStop -------------------------------- */ /* Required to support platform variant without getpid() and pid_t. */ # if defined(__TANDEM) && defined(_GUARDIAN_TARGET) @@ -343,12 +295,12 @@ static ossl_inline void ossl_sleep(unsigned long millis) # define gethostbyname(name) gethostbyname((char*)name) # define ioctlsocket(a,b,c) ioctl(a,b,c) # ifdef NO_GETPID -inline int nssgetpid(); +inline int nssgetpid(void); # ifndef NSSGETPID_MACRO # define NSSGETPID_MACRO # include # include - inline int nssgetpid() + inline int nssgetpid(void) { short phandle[10]={0}; union pseudo_pid { diff --git a/include/internal/endian.h b/include/internal/endian.h index 8b34e03e44..7d5a73b1bb 100644 --- a/include/internal/endian.h +++ b/include/internal/endian.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,7 +12,7 @@ # pragma once /* - * IS_LITTLE_ENDIAN and IS_BIG_ENDIAN can be used to detect the endiannes + * IS_LITTLE_ENDIAN and IS_BIG_ENDIAN can be used to detect the endianness * at compile time. To use it, DECLARE_IS_ENDIAN must be used to declare * a variable. * diff --git a/include/internal/event_queue.h b/include/internal/event_queue.h new file mode 100644 index 0000000000..bda1ee6ad4 --- /dev/null +++ b/include/internal/event_queue.h @@ -0,0 +1,163 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_EVENT_QUEUE_H +# define OSSL_INTERNAL_EVENT_QUEUE_H +# pragma once + +# include "internal/priority_queue.h" +# include "internal/time.h" + +/* + * Opaque type holding an event. + */ +typedef struct ossl_event_st OSSL_EVENT; + +DEFINE_PRIORITY_QUEUE_OF(OSSL_EVENT); + +/* + * Public type representing an event queue, the underlying structure being + * opaque. + */ +typedef struct ossl_event_queue_st OSSL_EVENT_QUEUE; + +/* + * Public type representing a event queue entry. + * It is (internally) public so that it can be embedded into other structures, + * it should otherwise be treated as opaque. + */ +struct ossl_event_st { + uint32_t type; /* What type of event this is */ + uint32_t priority; /* What priority this event has */ + OSSL_TIME when; /* When the event is scheduled to happen */ + void *ctx; /* User argument passed to call backs */ + void *payload; /* Event specific data of unknown kind */ + size_t payload_size; /* Length (in bytes) of event specific data */ + + /* These fields are for internal use only */ + PRIORITY_QUEUE_OF(OSSL_EVENT) *queue; /* Queue containing this event */ + size_t ref; /* ID for this event */ + unsigned int flag_dynamic : 1; /* Malloced or not? */ +}; + +/* + * Utility function to populate an event structure and add it to the queue + */ +int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event, + uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size); + +/* + * Utility functions to extract event fields + */ +static ossl_unused ossl_inline +uint32_t ossl_event_get_type(const OSSL_EVENT *event) +{ + return event->type; +} + +static ossl_unused ossl_inline +uint32_t ossl_event_get_priority(const OSSL_EVENT *event) +{ + return event->priority; +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_event_get_when(const OSSL_EVENT *event) +{ + return event->when; +} + +static ossl_unused ossl_inline +void *ossl_event_get0_ctx(const OSSL_EVENT *event) +{ + return event->ctx; +} + +static ossl_unused ossl_inline +void *ossl_event_get0_payload(const OSSL_EVENT *event, size_t *length) +{ + if (length != NULL) + *length = event->payload_size; + return event->payload; +} + +/* + * Create and free a queue. + */ +OSSL_EVENT_QUEUE *ossl_event_queue_new(void); +void ossl_event_queue_free(OSSL_EVENT_QUEUE *queue); + +/* + * Schedule a new event into an event queue. + * + * The event parameters are taken from the function arguments. + * + * The function returns NULL on failure and the added event on success. + */ +OSSL_EVENT *ossl_event_queue_add_new(OSSL_EVENT_QUEUE *queue, + uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size) +; + +/* + * Schedule an event into an event queue. + * + * The event parameters are taken from the function arguments. + * + * The function returns 0 on failure and 1 on success. + */ +int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event, + uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size); + +/* + * Delete an event from the queue. + * This will cause the early deletion function to be called if it is non-NULL. + * A pointer to the event structure is returned. + */ +int ossl_event_queue_remove(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event); + +/* + * Free a dynamic event. + * Is a NOP for a static event. + */ +void ossl_event_free(OSSL_EVENT *event); + +/* + * Return the time until the next event for the specified event, if the event's + * time is past, zero is returned. Once activated, the event reference becomes + * invalid and this function becomes undefined. + */ +OSSL_TIME ossl_event_time_until(const OSSL_EVENT *event); + +/* + * Return the time until the next event in the queue. + * If the next event is in the past, zero is returned. + */ +OSSL_TIME ossl_event_queue_time_until_next(const OSSL_EVENT_QUEUE *queue); + +/* + * Postpone an event to trigger at the specified time. + * If the event has triggered, this function's behaviour is undefined. + */ +int ossl_event_queue_postpone_until(OSSL_EVENT_QUEUE *queue, + OSSL_EVENT *event, + OSSL_TIME when); + +/* + * Return the next event to process. + */ +int ossl_event_queue_get1_next_event(OSSL_EVENT_QUEUE *queue, + OSSL_EVENT **event); + +#endif diff --git a/include/internal/ffc.h b/include/internal/ffc.h index c4f090875f..edd8381e8d 100644 --- a/include/internal/ffc.h +++ b/include/internal/ffc.h @@ -58,8 +58,11 @@ # define FFC_CHECK_INVALID_Q_VALUE 0x00020 # define FFC_CHECK_INVALID_J_VALUE 0x00040 -# define FFC_CHECK_BAD_LN_PAIR 0x00080 -# define FFC_CHECK_INVALID_SEED_SIZE 0x00100 +/* + * 0x80, 0x100 reserved by include/openssl/dh.h with check bits that are not + * relevant for FFC. + */ + # define FFC_CHECK_MISSING_SEED_OR_COUNTER 0x00200 # define FFC_CHECK_INVALID_G 0x00400 # define FFC_CHECK_INVALID_PQ 0x00800 @@ -68,6 +71,8 @@ # define FFC_CHECK_Q_MISMATCH 0x04000 # define FFC_CHECK_G_MISMATCH 0x08000 # define FFC_CHECK_COUNTER_MISMATCH 0x10000 +# define FFC_CHECK_BAD_LN_PAIR 0x20000 +# define FFC_CHECK_INVALID_SEED_SIZE 0x40000 /* Validation Return codes */ # define FFC_ERROR_PUBKEY_TOO_SMALL 0x01 @@ -132,7 +137,7 @@ void ossl_ffc_params_set_h(FFC_PARAMS *params, int index); void ossl_ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags); void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, int enable); -int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props); +void ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props); int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, const unsigned char *seed, diff --git a/include/internal/hpke_util.h b/include/internal/hpke_util.h new file mode 100644 index 0000000000..e1da5e0596 --- /dev/null +++ b/include/internal/hpke_util.h @@ -0,0 +1,100 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_HPKE_UTIL_H +# define OSSL_INTERNAL_HPKE_UTIL_H +# pragma once + +/* Constants from RFC 9180 Section 7.1 and 7.3 */ +# define OSSL_HPKE_MAX_SECRET 64 +# define OSSL_HPKE_MAX_PUBLIC 133 +# define OSSL_HPKE_MAX_PRIVATE 66 +# define OSSL_HPKE_MAX_KDF_INPUTLEN 64 + +/* + * max length of a base-nonce (the Nn field from OSSL_HPKE_AEAD_INFO), this + * is used for a local stack array size + */ +# define OSSL_HPKE_MAX_NONCELEN 12 + +/* + * @brief info about a KEM + * Used to store constants from Section 7.1 "Table 2 KEM IDs" + * and the bitmask for EC curves described in Section 7.1.3 DeriveKeyPair + */ +typedef struct { + uint16_t kem_id; /* code point for key encipherment method */ + const char *keytype; /* string form of algtype "EC"/"X25519"/"X448" */ + const char *groupname; /* string form of EC group for NIST curves */ + const char *mdname; /* hash alg name for the HKDF */ + size_t Nsecret; /* size of secrets */ + size_t Nenc; /* length of encapsulated key */ + size_t Npk; /* length of public key */ + size_t Nsk; /* length of raw private key */ + uint8_t bitmask; +} OSSL_HPKE_KEM_INFO; + +/* + * @brief info about a KDF + */ +typedef struct { + uint16_t kdf_id; /* code point for KDF */ + const char *mdname; /* hash alg name for the HKDF */ + size_t Nh; /* length of hash/extract output */ +} OSSL_HPKE_KDF_INFO; + +/* + * @brief info about an AEAD + */ +typedef struct { + uint16_t aead_id; /* code point for aead alg */ + const char *name; /* alg name */ + size_t taglen; /* aead tag len */ + size_t Nk; /* size of a key for this aead */ + size_t Nn; /* length of a nonce for this aead */ +} OSSL_HPKE_AEAD_INFO; + +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_curve(const char *curve); +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_id(uint16_t kemid); +const OSSL_HPKE_KEM_INFO *ossl_HPKE_KEM_INFO_find_random(OSSL_LIB_CTX *ctx); +const OSSL_HPKE_KDF_INFO *ossl_HPKE_KDF_INFO_find_id(uint16_t kdfid); +const OSSL_HPKE_KDF_INFO *ossl_HPKE_KDF_INFO_find_random(OSSL_LIB_CTX *ctx); +const OSSL_HPKE_AEAD_INFO *ossl_HPKE_AEAD_INFO_find_id(uint16_t aeadid); +const OSSL_HPKE_AEAD_INFO *ossl_HPKE_AEAD_INFO_find_random(OSSL_LIB_CTX *ctx); + +int ossl_hpke_kdf_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const unsigned char *ikm, size_t ikmlen); + +int ossl_hpke_kdf_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const unsigned char *info, size_t infolen); + +int ossl_hpke_labeled_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const char *protocol_label, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *ikm, size_t ikmlen); +int ossl_hpke_labeled_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const char *protocol_label, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *info, size_t infolen); + +EVP_KDF_CTX *ossl_kdf_ctx_create(const char *kdfname, const char *mdname, + OSSL_LIB_CTX *libctx, const char *propq); + +int ossl_hpke_str2suite(const char *suitestr, OSSL_HPKE_SUITE *suite); +#endif diff --git a/include/internal/ktls.h b/include/internal/ktls.h index 95492fd065..af27a32569 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,11 @@ # define OPENSSL_KTLS_AES_GCM_128 # define OPENSSL_KTLS_AES_GCM_256 # define OPENSSL_KTLS_TLS13 +# ifdef TLS_CHACHA20_IV_LEN +# ifndef OPENSSL_NO_CHACHA +# define OPENSSL_KTLS_CHACHA20_POLY1305 +# endif +# endif typedef struct tls_enable ktls_crypto_info_t; @@ -209,6 +214,13 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, # warning "Skipping Compilation of KTLS receive data path" # endif # endif +# if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) +# define OPENSSL_NO_KTLS_ZC_TX +# ifndef PEDANTIC +# warning "KTLS requires Kernel Headers >= 5.19.0 for zerocopy sendfile" +# warning "Skipping Compilation of KTLS zerocopy sendfile" +# endif +# endif # define OPENSSL_KTLS_AES_GCM_128 # if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) # define OPENSSL_KTLS_AES_GCM_256 @@ -288,6 +300,18 @@ static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *crypto_info, crypto_info, crypto_info->tls_crypto_info_len) ? 0 : 1; } +static ossl_inline int ktls_enable_tx_zerocopy_sendfile(int fd) +{ +#ifndef OPENSSL_NO_KTLS_ZC_TX + int enable = 1; + + return setsockopt(fd, SOL_TLS, TLS_TX_ZEROCOPY_RO, + &enable, sizeof(enable)) ? 0 : 1; +#else + return 0; +#endif +} + /* * Send a TLS record using the crypto_info provided in ktls_start and use * record_type instead of the default SSL3_RT_APPLICATION_DATA. diff --git a/include/internal/list.h b/include/internal/list.h new file mode 100644 index 0000000000..fdd356c407 --- /dev/null +++ b/include/internal/list.h @@ -0,0 +1,169 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_LIST_H +# define OSSL_INTERNAL_LIST_H +# pragma once + +# include +# include + +# ifdef NDEBUG +# define OSSL_LIST_DBG(x) +# else +# define OSSL_LIST_DBG(x) x; +# endif + +/* Define a list structure */ +# define OSSL_LIST(name) OSSL_LIST_ ## name + +/* Define fields to include an element of a list */ +# define OSSL_LIST_MEMBER(name, type) \ + struct { \ + type *next, *prev; \ + OSSL_LIST_DBG(struct ossl_list_st_ ## name *list) \ + } ossl_list_ ## name + +# define DEFINE_LIST_OF(name, type) \ + typedef struct ossl_list_st_ ## name OSSL_LIST(name); \ + struct ossl_list_st_ ## name { \ + type *alpha, *omega; \ + size_t num_elems; \ + }; \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_init(OSSL_LIST(name) *list) \ + { \ + memset(list, 0, sizeof(*list)); \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_init_elem(type *elem) \ + { \ + memset(&elem->ossl_list_ ## name, 0, \ + sizeof(elem->ossl_list_ ## name)); \ + } \ + static ossl_unused ossl_inline int \ + ossl_list_##name##_is_empty(const OSSL_LIST(name) *list) \ + { \ + return list->num_elems == 0; \ + } \ + static ossl_unused ossl_inline size_t \ + ossl_list_##name##_num(const OSSL_LIST(name) *list) \ + { \ + return list->num_elems; \ + } \ + static ossl_unused ossl_inline type * \ + ossl_list_##name##_head(const OSSL_LIST(name) *list) \ + { \ + assert(list->alpha == NULL \ + || list->alpha->ossl_list_ ## name.list == list); \ + return list->alpha; \ + } \ + static ossl_unused ossl_inline type * \ + ossl_list_##name##_tail(const OSSL_LIST(name) *list) \ + { \ + assert(list->omega == NULL \ + || list->omega->ossl_list_ ## name.list == list); \ + return list->omega; \ + } \ + static ossl_unused ossl_inline type * \ + ossl_list_##name##_next(const type *elem) \ + { \ + assert(elem->ossl_list_ ## name.next == NULL \ + || elem->ossl_list_ ## name.next \ + ->ossl_list_ ## name.prev == elem); \ + return elem->ossl_list_ ## name.next; \ + } \ + static ossl_unused ossl_inline type * \ + ossl_list_##name##_prev(const type *elem) \ + { \ + assert(elem->ossl_list_ ## name.prev == NULL \ + || elem->ossl_list_ ## name.prev \ + ->ossl_list_ ## name.next == elem); \ + return elem->ossl_list_ ## name.prev; \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_remove(OSSL_LIST(name) *list, type *elem) \ + { \ + assert(elem->ossl_list_ ## name.list == list); \ + OSSL_LIST_DBG(elem->ossl_list_ ## name.list = NULL) \ + if (list->alpha == elem) \ + list->alpha = elem->ossl_list_ ## name.next; \ + if (list->omega == elem) \ + list->omega = elem->ossl_list_ ## name.prev; \ + if (elem->ossl_list_ ## name.prev != NULL) \ + elem->ossl_list_ ## name.prev->ossl_list_ ## name.next = \ + elem->ossl_list_ ## name.next; \ + if (elem->ossl_list_ ## name.next != NULL) \ + elem->ossl_list_ ## name.next->ossl_list_ ## name.prev = \ + elem->ossl_list_ ## name.prev; \ + list->num_elems--; \ + memset(&elem->ossl_list_ ## name, 0, \ + sizeof(elem->ossl_list_ ## name)); \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_insert_head(OSSL_LIST(name) *list, type *elem) \ + { \ + assert(elem->ossl_list_ ## name.list == NULL); \ + OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \ + if (list->alpha != NULL) \ + list->alpha->ossl_list_ ## name.prev = elem; \ + elem->ossl_list_ ## name.next = list->alpha; \ + elem->ossl_list_ ## name.prev = NULL; \ + list->alpha = elem; \ + if (list->omega == NULL) \ + list->omega = elem; \ + list->num_elems++; \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_insert_tail(OSSL_LIST(name) *list, type *elem) \ + { \ + assert(elem->ossl_list_ ## name.list == NULL); \ + OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \ + if (list->omega != NULL) \ + list->omega->ossl_list_ ## name.next = elem; \ + elem->ossl_list_ ## name.prev = list->omega; \ + elem->ossl_list_ ## name.next = NULL; \ + list->omega = elem; \ + if (list->alpha == NULL) \ + list->alpha = elem; \ + list->num_elems++; \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_insert_before(OSSL_LIST(name) *list, type *e, \ + type *elem) \ + { \ + assert(elem->ossl_list_ ## name.list == NULL); \ + OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \ + elem->ossl_list_ ## name.next = e; \ + elem->ossl_list_ ## name.prev = e->ossl_list_ ## name.prev; \ + if (e->ossl_list_ ## name.prev != NULL) \ + e->ossl_list_ ## name.prev->ossl_list_ ## name.next = elem; \ + e->ossl_list_ ## name.prev = elem; \ + if (list->alpha == e) \ + list->alpha = elem; \ + list->num_elems++; \ + } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_insert_after(OSSL_LIST(name) *list, type *e, \ + type *elem) \ + { \ + assert(elem->ossl_list_ ## name.list == NULL); \ + OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \ + elem->ossl_list_ ## name.prev = e; \ + elem->ossl_list_ ## name.next = e->ossl_list_ ## name.next; \ + if (e->ossl_list_ ## name.next != NULL) \ + e->ossl_list_ ## name.next->ossl_list_ ## name.prev = elem; \ + e->ossl_list_ ## name.next = elem; \ + if (list->omega == e) \ + list->omega = elem; \ + list->num_elems++; \ + } \ + struct ossl_list_st_ ## name + +#endif diff --git a/include/internal/namemap.h b/include/internal/namemap.h index fd36883fc4..6c42a9cd7c 100644 --- a/include/internal/namemap.h +++ b/include/internal/namemap.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/numbers.h b/include/internal/numbers.h index 4f4d3306d5..47fb167709 100644 --- a/include/internal/numbers.h +++ b/include/internal/numbers.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,6 +61,31 @@ # define UINT64_MAX __MAXUINT__(uint64_t) # endif +/* + * 64-bit processor with LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT_LONG +# ifndef UINT32_C +# define UINT32_C(c) (c) +# endif +# ifndef UINT64_C +# define UINT64_C(c) (c##UL) +# endif +# endif + +/* + * 64-bit processor other than LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT +# ifndef UINT32_C +# define UINT32_C(c) (c##UL) +# endif +# ifndef UINT64_C +# define UINT64_C(c) (c##ULL) +# endif +# endif + + # ifndef INT128_MAX # if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16 typedef __int128_t int128_t; diff --git a/include/internal/packet.h b/include/internal/packet.h index ed76172078..7abc6b8b1b 100644 --- a/include/internal/packet.h +++ b/include/internal/packet.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -691,6 +691,8 @@ struct wpacket_st { */ #define WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH 2 +/* QUIC variable-length integer length prefix */ +#define WPACKET_FLAGS_QUIC_VLINT 4 /* * Initialise a WPACKET with the buffer in |buf|. The buffer must exist diff --git a/include/internal/packet_quic.h b/include/internal/packet_quic.h new file mode 100644 index 0000000000..5173b4675d --- /dev/null +++ b/include/internal/packet_quic.h @@ -0,0 +1,150 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_PACKET_QUIC_H +# define OSSL_INTERNAL_PACKET_QUIC_H +# pragma once + +# include "internal/packet.h" +# include "internal/quic_vlint.h" + +# ifndef OPENSSL_NO_QUIC +/* + * Decodes a QUIC variable-length integer in |pkt| and stores the result in + * |data|. + */ +__owur static ossl_inline int PACKET_get_quic_vlint(PACKET *pkt, + uint64_t *data) +{ + size_t enclen; + + if (PACKET_remaining(pkt) < 1) + return 0; + + enclen = ossl_quic_vlint_decode_len(*pkt->curr); + + if (PACKET_remaining(pkt) < enclen) + return 0; + + *data = ossl_quic_vlint_decode_unchecked(pkt->curr); + packet_forward(pkt, enclen); + return 1; +} + +/* + * Decodes a QUIC variable-length integer in |pkt| and stores the result in + * |data|. Unlike PACKET_get_quic_vlint, this does not advance the current + * position. If was_minimal is non-NULL, *was_minimal is set to 1 if the integer + * was encoded using the minimal possible number of bytes and 0 otherwise. + */ +__owur static ossl_inline int PACKET_peek_quic_vlint_ex(PACKET *pkt, + uint64_t *data, + int *was_minimal) +{ + size_t enclen; + + if (PACKET_remaining(pkt) < 1) + return 0; + + enclen = ossl_quic_vlint_decode_len(*pkt->curr); + + if (PACKET_remaining(pkt) < enclen) + return 0; + + *data = ossl_quic_vlint_decode_unchecked(pkt->curr); + + if (was_minimal != NULL) + *was_minimal = (enclen == ossl_quic_vlint_encode_len(*data)); + + return 1; +} + +__owur static ossl_inline int PACKET_peek_quic_vlint(PACKET *pkt, + uint64_t *data) +{ + return PACKET_peek_quic_vlint_ex(pkt, data, NULL); +} + +/* + * Skips over a QUIC variable-length integer in |pkt| without decoding it. + */ +__owur static ossl_inline int PACKET_skip_quic_vlint(PACKET *pkt) +{ + size_t enclen; + + if (PACKET_remaining(pkt) < 1) + return 0; + + enclen = ossl_quic_vlint_decode_len(*pkt->curr); + + if (PACKET_remaining(pkt) < enclen) + return 0; + + packet_forward(pkt, enclen); + return 1; +} + +/* + * Reads a variable-length vector prefixed with a QUIC variable-length integer + * denoting the length, and stores the contents in |subpkt|. |pkt| can equal + * |subpkt|. Data is not copied: the |subpkt| packet will share its underlying + * buffer with the original |pkt|, so data wrapped by |pkt| must outlive the + * |subpkt|. Upon failure, the original |pkt| and |subpkt| are not modified. + */ +__owur static ossl_inline int PACKET_get_quic_length_prefixed(PACKET *pkt, + PACKET *subpkt) +{ + uint64_t length; + const unsigned char *data; + PACKET tmp = *pkt; + + if (!PACKET_get_quic_vlint(&tmp, &length) || + length > SIZE_MAX || + !PACKET_get_bytes(&tmp, &data, (size_t)length)) { + return 0; + } + + *pkt = tmp; + subpkt->curr = data; + subpkt->remaining = (size_t)length; + + return 1; +} + +/* + * Starts a QUIC sub-packet headed by a QUIC variable-length integer. A 4-byte + * representation is used. + */ +__owur int WPACKET_start_quic_sub_packet(WPACKET *pkt); + +/* + * Starts a QUIC sub-packet headed by a QUIC variable-length integer. max_len + * specifies the upper bound for the sub-packet size at the time the sub-packet + * is closed, which determines the encoding size for the variable-length + * integer header. max_len can be a precise figure or a worst-case bound + * if a precise figure is not available. + */ +__owur int WPACKET_start_quic_sub_packet_bound(WPACKET *pkt, size_t max_len); + +/* + * Allocates a QUIC sub-packet with exactly len bytes of payload, headed by a + * QUIC variable-length integer. The pointer to the payload buffer is output and + * must be filled by the caller. This function assures optimal selection of + * variable-length integer encoding length. + */ +__owur int WPACKET_quic_sub_allocate_bytes(WPACKET *pkt, size_t len, + unsigned char **bytes); + +/* + * Write a QUIC variable-length integer to the packet. + */ +__owur int WPACKET_quic_write_vlint(WPACKET *pkt, uint64_t v); + +# endif /* OPENSSL_NO_QUIC */ +#endif /* OSSL_INTERNAL_PACKET_QUIC_H */ diff --git a/include/internal/param_build_set.h b/include/internal/param_build_set.h index 126211b7f2..3518f008f0 100644 --- a/include/internal/param_build_set.h +++ b/include/internal/param_build_set.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,6 +39,11 @@ int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, const char *key, const BIGNUM *bn); int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, const char *key, const BIGNUM *bn, size_t sz); +int ossl_param_build_set_signed_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, const BIGNUM *bn); +int ossl_param_build_set_signed_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, + const char *key, const BIGNUM *bn, + size_t sz); int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, const char *names[], STACK_OF(BIGNUM_const) *stk); diff --git a/include/internal/param_names.h b/include/internal/param_names.h new file mode 100644 index 0000000000..e721d07161 --- /dev/null +++ b/include/internal/param_names.h @@ -0,0 +1,376 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from include/internal/param_names.h.in + * + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + + +int ossl_param_find_pidx(const char *s); + +/* Parameter name definitions - generated by util/perl/OpenSSL/paramnames.pm */ +#define NUM_PIDX 290 + +#define PIDX_ALG_PARAM_CIPHER 0 +#define PIDX_ALG_PARAM_DIGEST 1 +#define PIDX_ALG_PARAM_ENGINE 2 +#define PIDX_ALG_PARAM_MAC 3 +#define PIDX_ALG_PARAM_PROPERTIES 4 +#define PIDX_ASYM_CIPHER_PARAM_DIGEST PIDX_PKEY_PARAM_DIGEST +#define PIDX_ASYM_CIPHER_PARAM_ENGINE PIDX_PKEY_PARAM_ENGINE +#define PIDX_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION 5 +#define PIDX_ASYM_CIPHER_PARAM_MGF1_DIGEST PIDX_PKEY_PARAM_MGF1_DIGEST +#define PIDX_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS PIDX_PKEY_PARAM_MGF1_PROPERTIES +#define PIDX_ASYM_CIPHER_PARAM_OAEP_DIGEST PIDX_ALG_PARAM_DIGEST +#define PIDX_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS 6 +#define PIDX_ASYM_CIPHER_PARAM_OAEP_LABEL 7 +#define PIDX_ASYM_CIPHER_PARAM_PAD_MODE PIDX_PKEY_PARAM_PAD_MODE +#define PIDX_ASYM_CIPHER_PARAM_PROPERTIES PIDX_PKEY_PARAM_PROPERTIES +#define PIDX_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION 8 +#define PIDX_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION 9 +#define PIDX_CAPABILITY_TLS_GROUP_ALG 10 +#define PIDX_CAPABILITY_TLS_GROUP_ID 11 +#define PIDX_CAPABILITY_TLS_GROUP_IS_KEM 12 +#define PIDX_CAPABILITY_TLS_GROUP_MAX_DTLS 13 +#define PIDX_CAPABILITY_TLS_GROUP_MAX_TLS 14 +#define PIDX_CAPABILITY_TLS_GROUP_MIN_DTLS 15 +#define PIDX_CAPABILITY_TLS_GROUP_MIN_TLS 16 +#define PIDX_CAPABILITY_TLS_GROUP_NAME 17 +#define PIDX_CAPABILITY_TLS_GROUP_NAME_INTERNAL 18 +#define PIDX_CAPABILITY_TLS_GROUP_SECURITY_BITS 19 +#define PIDX_CAPABILITY_TLS_SIGALG_CODE_POINT 20 +#define PIDX_CAPABILITY_TLS_SIGALG_HASH_NAME 21 +#define PIDX_CAPABILITY_TLS_SIGALG_HASH_OID 22 +#define PIDX_CAPABILITY_TLS_SIGALG_IANA_NAME 23 +#define PIDX_CAPABILITY_TLS_SIGALG_KEYTYPE 24 +#define PIDX_CAPABILITY_TLS_SIGALG_KEYTYPE_OID 25 +#define PIDX_CAPABILITY_TLS_SIGALG_MAX_TLS 14 +#define PIDX_CAPABILITY_TLS_SIGALG_MIN_TLS 16 +#define PIDX_CAPABILITY_TLS_SIGALG_NAME 26 +#define PIDX_CAPABILITY_TLS_SIGALG_OID 27 +#define PIDX_CAPABILITY_TLS_SIGALG_SECURITY_BITS 28 +#define PIDX_CAPABILITY_TLS_SIGALG_SIG_NAME 29 +#define PIDX_CAPABILITY_TLS_SIGALG_SIG_OID 30 +#define PIDX_CIPHER_PARAM_AEAD 31 +#define PIDX_CIPHER_PARAM_AEAD_IVLEN PIDX_CIPHER_PARAM_IVLEN +#define PIDX_CIPHER_PARAM_AEAD_MAC_KEY 32 +#define PIDX_CIPHER_PARAM_AEAD_TAG 33 +#define PIDX_CIPHER_PARAM_AEAD_TAGLEN 34 +#define PIDX_CIPHER_PARAM_AEAD_TLS1_AAD 35 +#define PIDX_CIPHER_PARAM_AEAD_TLS1_AAD_PAD 36 +#define PIDX_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN 37 +#define PIDX_CIPHER_PARAM_AEAD_TLS1_IV_FIXED 38 +#define PIDX_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV 39 +#define PIDX_CIPHER_PARAM_ALGORITHM_ID_PARAMS 40 +#define PIDX_CIPHER_PARAM_BLOCK_SIZE 41 +#define PIDX_CIPHER_PARAM_CTS 42 +#define PIDX_CIPHER_PARAM_CTS_MODE 43 +#define PIDX_CIPHER_PARAM_CUSTOM_IV 44 +#define PIDX_CIPHER_PARAM_HAS_RAND_KEY 45 +#define PIDX_CIPHER_PARAM_IV 46 +#define PIDX_CIPHER_PARAM_IVLEN 47 +#define PIDX_CIPHER_PARAM_KEYLEN 48 +#define PIDX_CIPHER_PARAM_MODE 49 +#define PIDX_CIPHER_PARAM_NUM 50 +#define PIDX_CIPHER_PARAM_PADDING 51 +#define PIDX_CIPHER_PARAM_RANDOM_KEY 52 +#define PIDX_CIPHER_PARAM_RC2_KEYBITS 53 +#define PIDX_CIPHER_PARAM_ROUNDS 54 +#define PIDX_CIPHER_PARAM_SPEED 55 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK 56 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD 57 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN 58 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC 59 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN 60 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN 61 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE 62 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE 63 +#define PIDX_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT 64 +#define PIDX_CIPHER_PARAM_TLS_MAC 65 +#define PIDX_CIPHER_PARAM_TLS_MAC_SIZE 66 +#define PIDX_CIPHER_PARAM_TLS_VERSION 67 +#define PIDX_CIPHER_PARAM_UPDATED_IV 68 +#define PIDX_CIPHER_PARAM_USE_BITS 69 +#define PIDX_CIPHER_PARAM_XTS_STANDARD 70 +#define PIDX_DECODER_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_DIGEST_PARAM_ALGID_ABSENT 71 +#define PIDX_DIGEST_PARAM_BLOCK_SIZE 41 +#define PIDX_DIGEST_PARAM_MICALG 72 +#define PIDX_DIGEST_PARAM_PAD_TYPE 73 +#define PIDX_DIGEST_PARAM_SIZE 74 +#define PIDX_DIGEST_PARAM_SSL3_MS 75 +#define PIDX_DIGEST_PARAM_XOF 76 +#define PIDX_DIGEST_PARAM_XOFLEN 77 +#define PIDX_DRBG_PARAM_CIPHER PIDX_ALG_PARAM_CIPHER +#define PIDX_DRBG_PARAM_DIGEST PIDX_ALG_PARAM_DIGEST +#define PIDX_DRBG_PARAM_ENTROPY_REQUIRED 78 +#define PIDX_DRBG_PARAM_MAC PIDX_ALG_PARAM_MAC +#define PIDX_DRBG_PARAM_MAX_ADINLEN 79 +#define PIDX_DRBG_PARAM_MAX_ENTROPYLEN 80 +#define PIDX_DRBG_PARAM_MAX_LENGTH 81 +#define PIDX_DRBG_PARAM_MAX_NONCELEN 82 +#define PIDX_DRBG_PARAM_MAX_PERSLEN 83 +#define PIDX_DRBG_PARAM_MIN_ENTROPYLEN 84 +#define PIDX_DRBG_PARAM_MIN_LENGTH 85 +#define PIDX_DRBG_PARAM_MIN_NONCELEN 86 +#define PIDX_DRBG_PARAM_PREDICTION_RESISTANCE 87 +#define PIDX_DRBG_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_DRBG_PARAM_RANDOM_DATA 88 +#define PIDX_DRBG_PARAM_RESEED_COUNTER 89 +#define PIDX_DRBG_PARAM_RESEED_REQUESTS 90 +#define PIDX_DRBG_PARAM_RESEED_TIME 91 +#define PIDX_DRBG_PARAM_RESEED_TIME_INTERVAL 92 +#define PIDX_DRBG_PARAM_SIZE 74 +#define PIDX_DRBG_PARAM_USE_DF 93 +#define PIDX_ENCODER_PARAM_CIPHER PIDX_ALG_PARAM_CIPHER +#define PIDX_ENCODER_PARAM_ENCRYPT_LEVEL 94 +#define PIDX_ENCODER_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_ENCODER_PARAM_SAVE_PARAMETERS 95 +#define PIDX_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE 96 +#define PIDX_EXCHANGE_PARAM_KDF_DIGEST 97 +#define PIDX_EXCHANGE_PARAM_KDF_DIGEST_PROPS 98 +#define PIDX_EXCHANGE_PARAM_KDF_OUTLEN 99 +#define PIDX_EXCHANGE_PARAM_KDF_TYPE 100 +#define PIDX_EXCHANGE_PARAM_KDF_UKM 101 +#define PIDX_EXCHANGE_PARAM_PAD 102 +#define PIDX_GEN_PARAM_ITERATION 103 +#define PIDX_GEN_PARAM_POTENTIAL 104 +#define PIDX_KDF_PARAM_ARGON2_AD 105 +#define PIDX_KDF_PARAM_ARGON2_LANES 106 +#define PIDX_KDF_PARAM_ARGON2_MEMCOST 107 +#define PIDX_KDF_PARAM_ARGON2_VERSION 108 +#define PIDX_KDF_PARAM_CEK_ALG 109 +#define PIDX_KDF_PARAM_CIPHER PIDX_ALG_PARAM_CIPHER +#define PIDX_KDF_PARAM_CONSTANT 110 +#define PIDX_KDF_PARAM_DATA 111 +#define PIDX_KDF_PARAM_DIGEST PIDX_ALG_PARAM_DIGEST +#define PIDX_KDF_PARAM_EARLY_CLEAN 112 +#define PIDX_KDF_PARAM_HMACDRBG_ENTROPY 113 +#define PIDX_KDF_PARAM_HMACDRBG_NONCE 114 +#define PIDX_KDF_PARAM_INFO 115 +#define PIDX_KDF_PARAM_ITER 116 +#define PIDX_KDF_PARAM_KBKDF_R 117 +#define PIDX_KDF_PARAM_KBKDF_USE_L 118 +#define PIDX_KDF_PARAM_KBKDF_USE_SEPARATOR 119 +#define PIDX_KDF_PARAM_KEY 120 +#define PIDX_KDF_PARAM_LABEL 121 +#define PIDX_KDF_PARAM_MAC PIDX_ALG_PARAM_MAC +#define PIDX_KDF_PARAM_MAC_SIZE 122 +#define PIDX_KDF_PARAM_MODE 49 +#define PIDX_KDF_PARAM_PASSWORD 123 +#define PIDX_KDF_PARAM_PKCS12_ID 124 +#define PIDX_KDF_PARAM_PKCS5 125 +#define PIDX_KDF_PARAM_PREFIX 126 +#define PIDX_KDF_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_KDF_PARAM_SALT 127 +#define PIDX_KDF_PARAM_SCRYPT_MAXMEM 128 +#define PIDX_KDF_PARAM_SCRYPT_N 129 +#define PIDX_KDF_PARAM_SCRYPT_P 130 +#define PIDX_KDF_PARAM_SCRYPT_R 117 +#define PIDX_KDF_PARAM_SECRET 131 +#define PIDX_KDF_PARAM_SEED 132 +#define PIDX_KDF_PARAM_SIZE 74 +#define PIDX_KDF_PARAM_SSHKDF_SESSION_ID 133 +#define PIDX_KDF_PARAM_SSHKDF_TYPE 134 +#define PIDX_KDF_PARAM_SSHKDF_XCGHASH 135 +#define PIDX_KDF_PARAM_THREADS 136 +#define PIDX_KDF_PARAM_UKM 137 +#define PIDX_KDF_PARAM_X942_ACVPINFO 138 +#define PIDX_KDF_PARAM_X942_PARTYUINFO 139 +#define PIDX_KDF_PARAM_X942_PARTYVINFO 140 +#define PIDX_KDF_PARAM_X942_SUPP_PRIVINFO 141 +#define PIDX_KDF_PARAM_X942_SUPP_PUBINFO 142 +#define PIDX_KDF_PARAM_X942_USE_KEYBITS 143 +#define PIDX_KEM_PARAM_IKME 144 +#define PIDX_KEM_PARAM_OPERATION 145 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_BLOCK_PADDING 146 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_MAX_EARLY_DATA 147 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN 148 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_MODE 49 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_OPTIONS 149 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD 150 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_STREAM_MAC 151 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_TLSTREE 152 +#define PIDX_LIBSSL_RECORD_LAYER_PARAM_USE_ETM 153 +#define PIDX_LIBSSL_RECORD_LAYER_READ_BUFFER_LEN 154 +#define PIDX_MAC_PARAM_BLOCK_SIZE 155 +#define PIDX_MAC_PARAM_CIPHER PIDX_ALG_PARAM_CIPHER +#define PIDX_MAC_PARAM_CUSTOM 156 +#define PIDX_MAC_PARAM_C_ROUNDS 157 +#define PIDX_MAC_PARAM_DIGEST PIDX_ALG_PARAM_DIGEST +#define PIDX_MAC_PARAM_DIGEST_NOINIT 158 +#define PIDX_MAC_PARAM_DIGEST_ONESHOT 159 +#define PIDX_MAC_PARAM_D_ROUNDS 160 +#define PIDX_MAC_PARAM_IV 46 +#define PIDX_MAC_PARAM_KEY 120 +#define PIDX_MAC_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_MAC_PARAM_SALT 127 +#define PIDX_MAC_PARAM_SIZE 74 +#define PIDX_MAC_PARAM_TLS_DATA_SIZE 161 +#define PIDX_MAC_PARAM_XOF 76 +#define PIDX_OBJECT_PARAM_DATA 111 +#define PIDX_OBJECT_PARAM_DATA_STRUCTURE 162 +#define PIDX_OBJECT_PARAM_DATA_TYPE 163 +#define PIDX_OBJECT_PARAM_DESC 164 +#define PIDX_OBJECT_PARAM_REFERENCE 165 +#define PIDX_OBJECT_PARAM_TYPE 134 +#define PIDX_PASSPHRASE_PARAM_INFO 115 +#define PIDX_PKEY_PARAM_BITS 166 +#define PIDX_PKEY_PARAM_CIPHER PIDX_ALG_PARAM_CIPHER +#define PIDX_PKEY_PARAM_DEFAULT_DIGEST 167 +#define PIDX_PKEY_PARAM_DHKEM_IKM 168 +#define PIDX_PKEY_PARAM_DH_GENERATOR 169 +#define PIDX_PKEY_PARAM_DH_PRIV_LEN 170 +#define PIDX_PKEY_PARAM_DIGEST PIDX_ALG_PARAM_DIGEST +#define PIDX_PKEY_PARAM_DIGEST_SIZE 171 +#define PIDX_PKEY_PARAM_DIST_ID 172 +#define PIDX_PKEY_PARAM_EC_A 173 +#define PIDX_PKEY_PARAM_EC_B 174 +#define PIDX_PKEY_PARAM_EC_CHAR2_M 175 +#define PIDX_PKEY_PARAM_EC_CHAR2_PP_K1 176 +#define PIDX_PKEY_PARAM_EC_CHAR2_PP_K2 177 +#define PIDX_PKEY_PARAM_EC_CHAR2_PP_K3 178 +#define PIDX_PKEY_PARAM_EC_CHAR2_TP_BASIS 179 +#define PIDX_PKEY_PARAM_EC_CHAR2_TYPE 180 +#define PIDX_PKEY_PARAM_EC_COFACTOR 181 +#define PIDX_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS 182 +#define PIDX_PKEY_PARAM_EC_ENCODING 183 +#define PIDX_PKEY_PARAM_EC_FIELD_TYPE 184 +#define PIDX_PKEY_PARAM_EC_GENERATOR 185 +#define PIDX_PKEY_PARAM_EC_GROUP_CHECK_TYPE 186 +#define PIDX_PKEY_PARAM_EC_INCLUDE_PUBLIC 187 +#define PIDX_PKEY_PARAM_EC_ORDER 188 +#define PIDX_PKEY_PARAM_EC_P 130 +#define PIDX_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT 189 +#define PIDX_PKEY_PARAM_EC_PUB_X 190 +#define PIDX_PKEY_PARAM_EC_PUB_Y 191 +#define PIDX_PKEY_PARAM_EC_SEED 132 +#define PIDX_PKEY_PARAM_ENCODED_PUBLIC_KEY 192 +#define PIDX_PKEY_PARAM_ENGINE PIDX_ALG_PARAM_ENGINE +#define PIDX_PKEY_PARAM_FFC_COFACTOR 193 +#define PIDX_PKEY_PARAM_FFC_DIGEST PIDX_PKEY_PARAM_DIGEST +#define PIDX_PKEY_PARAM_FFC_DIGEST_PROPS PIDX_PKEY_PARAM_PROPERTIES +#define PIDX_PKEY_PARAM_FFC_G 194 +#define PIDX_PKEY_PARAM_FFC_GINDEX 195 +#define PIDX_PKEY_PARAM_FFC_H 196 +#define PIDX_PKEY_PARAM_FFC_P 130 +#define PIDX_PKEY_PARAM_FFC_PBITS 197 +#define PIDX_PKEY_PARAM_FFC_PCOUNTER 198 +#define PIDX_PKEY_PARAM_FFC_Q 199 +#define PIDX_PKEY_PARAM_FFC_QBITS 200 +#define PIDX_PKEY_PARAM_FFC_SEED 132 +#define PIDX_PKEY_PARAM_FFC_TYPE 134 +#define PIDX_PKEY_PARAM_FFC_VALIDATE_G 201 +#define PIDX_PKEY_PARAM_FFC_VALIDATE_LEGACY 202 +#define PIDX_PKEY_PARAM_FFC_VALIDATE_PQ 203 +#define PIDX_PKEY_PARAM_GROUP_NAME 204 +#define PIDX_PKEY_PARAM_IMPLICIT_REJECTION 5 +#define PIDX_PKEY_PARAM_MANDATORY_DIGEST 205 +#define PIDX_PKEY_PARAM_MASKGENFUNC 206 +#define PIDX_PKEY_PARAM_MAX_SIZE 207 +#define PIDX_PKEY_PARAM_MGF1_DIGEST 208 +#define PIDX_PKEY_PARAM_MGF1_PROPERTIES 209 +#define PIDX_PKEY_PARAM_PAD_MODE 210 +#define PIDX_PKEY_PARAM_PRIV_KEY 211 +#define PIDX_PKEY_PARAM_PROPERTIES PIDX_ALG_PARAM_PROPERTIES +#define PIDX_PKEY_PARAM_PUB_KEY 212 +#define PIDX_PKEY_PARAM_RSA_BITS PIDX_PKEY_PARAM_BITS +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT 213 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT1 214 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT2 215 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT3 216 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT4 217 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT5 218 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT6 219 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT7 220 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT8 221 +#define PIDX_PKEY_PARAM_RSA_COEFFICIENT9 222 +#define PIDX_PKEY_PARAM_RSA_D 223 +#define PIDX_PKEY_PARAM_RSA_DIGEST PIDX_PKEY_PARAM_DIGEST +#define PIDX_PKEY_PARAM_RSA_DIGEST_PROPS PIDX_PKEY_PARAM_PROPERTIES +#define PIDX_PKEY_PARAM_RSA_E 224 +#define PIDX_PKEY_PARAM_RSA_EXPONENT 225 +#define PIDX_PKEY_PARAM_RSA_EXPONENT1 226 +#define PIDX_PKEY_PARAM_RSA_EXPONENT10 227 +#define PIDX_PKEY_PARAM_RSA_EXPONENT2 228 +#define PIDX_PKEY_PARAM_RSA_EXPONENT3 229 +#define PIDX_PKEY_PARAM_RSA_EXPONENT4 230 +#define PIDX_PKEY_PARAM_RSA_EXPONENT5 231 +#define PIDX_PKEY_PARAM_RSA_EXPONENT6 232 +#define PIDX_PKEY_PARAM_RSA_EXPONENT7 233 +#define PIDX_PKEY_PARAM_RSA_EXPONENT8 234 +#define PIDX_PKEY_PARAM_RSA_EXPONENT9 235 +#define PIDX_PKEY_PARAM_RSA_FACTOR 236 +#define PIDX_PKEY_PARAM_RSA_FACTOR1 237 +#define PIDX_PKEY_PARAM_RSA_FACTOR10 238 +#define PIDX_PKEY_PARAM_RSA_FACTOR2 239 +#define PIDX_PKEY_PARAM_RSA_FACTOR3 240 +#define PIDX_PKEY_PARAM_RSA_FACTOR4 241 +#define PIDX_PKEY_PARAM_RSA_FACTOR5 242 +#define PIDX_PKEY_PARAM_RSA_FACTOR6 243 +#define PIDX_PKEY_PARAM_RSA_FACTOR7 244 +#define PIDX_PKEY_PARAM_RSA_FACTOR8 245 +#define PIDX_PKEY_PARAM_RSA_FACTOR9 246 +#define PIDX_PKEY_PARAM_RSA_MASKGENFUNC PIDX_PKEY_PARAM_MASKGENFUNC +#define PIDX_PKEY_PARAM_RSA_MGF1_DIGEST PIDX_PKEY_PARAM_MGF1_DIGEST +#define PIDX_PKEY_PARAM_RSA_N 129 +#define PIDX_PKEY_PARAM_RSA_PRIMES 247 +#define PIDX_PKEY_PARAM_RSA_PSS_SALTLEN 248 +#define PIDX_PKEY_PARAM_RSA_TEST_P1 249 +#define PIDX_PKEY_PARAM_RSA_TEST_P2 250 +#define PIDX_PKEY_PARAM_RSA_TEST_Q1 251 +#define PIDX_PKEY_PARAM_RSA_TEST_Q2 252 +#define PIDX_PKEY_PARAM_RSA_TEST_XP 253 +#define PIDX_PKEY_PARAM_RSA_TEST_XP1 254 +#define PIDX_PKEY_PARAM_RSA_TEST_XP2 255 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ 256 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ1 257 +#define PIDX_PKEY_PARAM_RSA_TEST_XQ2 258 +#define PIDX_PKEY_PARAM_SECURITY_BITS 259 +#define PIDX_PKEY_PARAM_USE_COFACTOR_ECDH PIDX_PKEY_PARAM_USE_COFACTOR_FLAG +#define PIDX_PKEY_PARAM_USE_COFACTOR_FLAG 260 +#define PIDX_PROV_PARAM_BUILDINFO 261 +#define PIDX_PROV_PARAM_CORE_MODULE_FILENAME 262 +#define PIDX_PROV_PARAM_CORE_PROV_NAME 263 +#define PIDX_PROV_PARAM_CORE_VERSION 264 +#define PIDX_PROV_PARAM_DRBG_TRUNC_DIGEST 265 +#define PIDX_PROV_PARAM_NAME 266 +#define PIDX_PROV_PARAM_SECURITY_CHECKS 267 +#define PIDX_PROV_PARAM_SELF_TEST_DESC 268 +#define PIDX_PROV_PARAM_SELF_TEST_PHASE 269 +#define PIDX_PROV_PARAM_SELF_TEST_TYPE 270 +#define PIDX_PROV_PARAM_STATUS 271 +#define PIDX_PROV_PARAM_TLS1_PRF_EMS_CHECK 272 +#define PIDX_PROV_PARAM_VERSION 108 +#define PIDX_RAND_PARAM_GENERATE 273 +#define PIDX_RAND_PARAM_MAX_REQUEST 274 +#define PIDX_RAND_PARAM_STATE 275 +#define PIDX_RAND_PARAM_STRENGTH 276 +#define PIDX_RAND_PARAM_TEST_ENTROPY 277 +#define PIDX_RAND_PARAM_TEST_NONCE 278 +#define PIDX_SIGNATURE_PARAM_ALGORITHM_ID 279 +#define PIDX_SIGNATURE_PARAM_CONTEXT_STRING 280 +#define PIDX_SIGNATURE_PARAM_DIGEST PIDX_PKEY_PARAM_DIGEST +#define PIDX_SIGNATURE_PARAM_DIGEST_SIZE PIDX_PKEY_PARAM_DIGEST_SIZE +#define PIDX_SIGNATURE_PARAM_INSTANCE 281 +#define PIDX_SIGNATURE_PARAM_KAT 282 +#define PIDX_SIGNATURE_PARAM_MGF1_DIGEST PIDX_PKEY_PARAM_MGF1_DIGEST +#define PIDX_SIGNATURE_PARAM_MGF1_PROPERTIES PIDX_PKEY_PARAM_MGF1_PROPERTIES +#define PIDX_SIGNATURE_PARAM_NONCE_TYPE 283 +#define PIDX_SIGNATURE_PARAM_PAD_MODE PIDX_PKEY_PARAM_PAD_MODE +#define PIDX_SIGNATURE_PARAM_PROPERTIES PIDX_PKEY_PARAM_PROPERTIES +#define PIDX_SIGNATURE_PARAM_PSS_SALTLEN 248 +#define PIDX_STORE_PARAM_ALIAS 284 +#define PIDX_STORE_PARAM_DIGEST 1 +#define PIDX_STORE_PARAM_EXPECT 285 +#define PIDX_STORE_PARAM_FINGERPRINT 286 +#define PIDX_STORE_PARAM_INPUT_TYPE 287 +#define PIDX_STORE_PARAM_ISSUER 266 +#define PIDX_STORE_PARAM_PROPERTIES 4 +#define PIDX_STORE_PARAM_SERIAL 288 +#define PIDX_STORE_PARAM_SUBJECT 289 diff --git a/include/internal/param_names.h.in b/include/internal/param_names.h.in new file mode 100644 index 0000000000..f34db21951 --- /dev/null +++ b/include/internal/param_names.h.in @@ -0,0 +1,18 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +{- +use OpenSSL::paramnames qw(generate_internal_macros); +-} + +int ossl_param_find_pidx(const char *s); + +/* Parameter name definitions - generated by util/perl/OpenSSL/paramnames.pm */ +{- generate_internal_macros(); -} diff --git a/include/internal/params.h b/include/internal/params.h new file mode 100644 index 0000000000..3fbd0cf954 --- /dev/null +++ b/include/internal/params.h @@ -0,0 +1,38 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +/* + * Extract the parameter into an allocated buffer. + * Any existing allocation in *out is cleared and freed. + * + * Returns 1 on success, 0 on failure and -1 if there are no matching params. + * + * *out and *out_len are guaranteed to be untouched if this function + * doesn't return success. + */ +int ossl_param_get1_octet_string(const OSSL_PARAM *params, const char *name, + unsigned char **out, size_t *out_len); +/* + * Concatenate all of the matching params together. + * *out will point to an allocated buffer on successful return. + * Any existing allocation in *out is cleared and freed. + * + * Passing 0 for maxsize means unlimited size output. + * + * Returns 1 on success, 0 on failure and -1 if there are no matching params. + * + * *out and *out_len are guaranteed to be untouched if this function + * doesn't return success. + */ +int ossl_param_get1_concat_octet_string(const OSSL_PARAM *params, const char *name, + unsigned char **out, size_t *out_len, + size_t maxsize); diff --git a/include/internal/priority_queue.h b/include/internal/priority_queue.h new file mode 100644 index 0000000000..5be03bf131 --- /dev/null +++ b/include/internal/priority_queue.h @@ -0,0 +1,88 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_PRIORITY_QUEUE_H +# define OSSL_INTERNAL_PRIORITY_QUEUE_H +# pragma once + +# include +# include + +# define PRIORITY_QUEUE_OF(type) OSSL_PRIORITY_QUEUE_ ## type + +# define DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, ctype) \ + typedef struct ossl_priority_queue_st_ ## type PRIORITY_QUEUE_OF(type); \ + static ossl_unused ossl_inline PRIORITY_QUEUE_OF(type) * \ + ossl_pqueue_##type##_new(int (*compare)(const ctype *, const ctype *)) \ + { \ + return (PRIORITY_QUEUE_OF(type) *)ossl_pqueue_new( \ + (int (*)(const void *, const void *))compare); \ + } \ + static ossl_unused ossl_inline void \ + ossl_pqueue_##type##_free(PRIORITY_QUEUE_OF(type) *pq) \ + { \ + ossl_pqueue_free((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline void \ + ossl_pqueue_##type##_pop_free(PRIORITY_QUEUE_OF(type) *pq, \ + void (*freefunc)(ctype *)) \ + { \ + ossl_pqueue_pop_free((OSSL_PQUEUE *)pq, (void (*)(void *))freefunc);\ + } \ + static ossl_unused ossl_inline int \ + ossl_pqueue_##type##_reserve(PRIORITY_QUEUE_OF(type) *pq, size_t n) \ + { \ + return ossl_pqueue_reserve((OSSL_PQUEUE *)pq, n); \ + } \ + static ossl_unused ossl_inline size_t \ + ossl_pqueue_##type##_num(const PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return ossl_pqueue_num((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline int \ + ossl_pqueue_##type##_push(PRIORITY_QUEUE_OF(type) *pq, \ + ctype *data, size_t *elem) \ + { \ + return ossl_pqueue_push((OSSL_PQUEUE *)pq, (void *)data, elem); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_peek(const PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return (type *)ossl_pqueue_peek((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_pop(PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return (type *)ossl_pqueue_pop((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_remove(PRIORITY_QUEUE_OF(type) *pq, \ + size_t elem) \ + { \ + return (type *)ossl_pqueue_remove((OSSL_PQUEUE *)pq, elem); \ + } \ + struct ossl_priority_queue_st_ ## type + +# define DEFINE_PRIORITY_QUEUE_OF(type) \ + DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, type) + +typedef struct ossl_pqueue_st OSSL_PQUEUE; + +OSSL_PQUEUE *ossl_pqueue_new(int (*compare)(const void *, const void *)); +void ossl_pqueue_free(OSSL_PQUEUE *pq); +void ossl_pqueue_pop_free(OSSL_PQUEUE *pq, void (*freefunc)(void *)); +int ossl_pqueue_reserve(OSSL_PQUEUE *pq, size_t n); + +size_t ossl_pqueue_num(const OSSL_PQUEUE *pq); +int ossl_pqueue_push(OSSL_PQUEUE *pq, void *data, size_t *elem); +void *ossl_pqueue_peek(const OSSL_PQUEUE *pq); +void *ossl_pqueue_pop(OSSL_PQUEUE *pq); +void *ossl_pqueue_remove(OSSL_PQUEUE *pq, size_t elem); + +#endif diff --git a/include/internal/property.h b/include/internal/property.h index d09274d0c9..3adff49940 100644 --- a/include/internal/property.h +++ b/include/internal/property.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/include/internal/provider.h b/include/internal/provider.h index 18937f84c7..ab41d643df 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,7 +32,7 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, int noconfig); OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, - int noconfig); + OSSL_PARAM *params, int noconfig); int ossl_provider_up_ref(OSSL_PROVIDER *prov); void ossl_provider_free(OSSL_PROVIDER *prov); diff --git a/include/internal/quic_ackm.h b/include/internal/quic_ackm.h new file mode 100644 index 0000000000..03fc608867 --- /dev/null +++ b/include/internal/quic_ackm.h @@ -0,0 +1,297 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef OSSL_QUIC_ACKM_H +# define OSSL_QUIC_ACKM_H + +# include "internal/quic_statm.h" +# include "internal/quic_cc.h" +# include "internal/quic_types.h" +# include "internal/quic_wire.h" +# include "internal/time.h" +# include "internal/list.h" + +# ifndef OPENSSL_NO_QUIC + +typedef struct ossl_ackm_st OSSL_ACKM; + +OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg), + void *now_arg, + OSSL_STATM *statm, + const OSSL_CC_METHOD *cc_method, + OSSL_CC_DATA *cc_data); +void ossl_ackm_free(OSSL_ACKM *ackm); + +void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm, + void (*fn)(OSSL_TIME deadline, + void *arg), + void *arg); + +void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm, + void (*fn)(OSSL_TIME deadline, + int pkt_space, + void *arg), + void *arg); + +/* + * Configures the RX-side maximum ACK delay. This is the maximum amount of time + * the peer is allowed to delay sending an ACK frame after receiving an + * ACK-eliciting packet. The peer communicates this value via a transport + * parameter and it must be provided to the ACKM. + */ +void ossl_ackm_set_rx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME rx_max_ack_delay); + +/* + * Configures the TX-side maximum ACK delay. This is the maximum amount of time + * we are allowed to delay sending an ACK frame after receiving an ACK-eliciting + * packet. Note that this cannot be changed after a connection is established as + * it must be accurately reported in the transport parameters we send to our + * peer. + */ +void ossl_ackm_set_tx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME tx_max_ack_delay); + +typedef struct ossl_ackm_tx_pkt_st OSSL_ACKM_TX_PKT; +struct ossl_ackm_tx_pkt_st { + /* The packet number of the transmitted packet. */ + QUIC_PN pkt_num; + + /* The number of bytes in the packet which was sent. */ + size_t num_bytes; + + /* The time at which the packet was sent. */ + OSSL_TIME time; + + /* + * If the packet being described by this structure contains an ACK frame, + * this must be set to the largest PN ACK'd by that frame. + * + * Otherwise, it should be set to QUIC_PN_INVALID. + * + * This is necessary to bound the number of PNs we have to keep track of on + * the RX side (RFC 9000 s. 13.2.4). It allows older PN tracking information + * on the RX side to be discarded. + */ + QUIC_PN largest_acked; + + /* + * One of the QUIC_PN_SPACE_* values. This qualifies the pkt_num field + * into a packet number space. + */ + unsigned int pkt_space :2; + + /* + * 1 if the packet is in flight. A packet is considered 'in flight' if it is + * counted for purposes of congestion control and 'bytes in flight' counts. + * Most packets are considered in flight. The only circumstance where a + * numbered packet is not considered in flight is if it contains only ACK + * frames (not even PADDING frames), as these frames can bypass CC. + */ + unsigned int is_inflight :1; + + /* + * 1 if the packet has one or more ACK-eliciting frames. + * Note that if this is set, is_inflight must be set. + */ + unsigned int is_ack_eliciting :1; + + /* 1 if the packet is a PTO probe. */ + unsigned int is_pto_probe :1; + + /* 1 if the packet is an MTU probe. */ + unsigned int is_mtu_probe :1; + + /* Callback called if frames in this packet are lost. arg is cb_arg. */ + void (*on_lost)(void *arg); + /* Callback called if frames in this packet are acked. arg is cb_arg. */ + void (*on_acked)(void *arg); + /* + * Callback called if frames in this packet are neither acked nor lost. arg + * is cb_arg. + */ + void (*on_discarded)(void *arg); + void *cb_arg; + + /* + * (Internal use fields; must be zero-initialized.) + * + * Keep a TX history list, anext is used to manifest + * a singly-linked list of newly-acknowledged packets, and lnext is used to + * manifest a singly-linked list of newly lost packets. + */ + OSSL_LIST_MEMBER(tx_history, OSSL_ACKM_TX_PKT); + + struct ossl_ackm_tx_pkt_st *anext; + struct ossl_ackm_tx_pkt_st *lnext; +}; + +int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt); +int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes); + +# define OSSL_ACKM_ECN_NONE 0 +# define OSSL_ACKM_ECN_ECT1 1 +# define OSSL_ACKM_ECN_ECT0 2 +# define OSSL_ACKM_ECN_ECNCE 3 + +typedef struct ossl_ackm_rx_pkt_st { + /* The packet number of the received packet. */ + QUIC_PN pkt_num; + + /* The time at which the packet was received. */ + OSSL_TIME time; + + /* + * One of the QUIC_PN_SPACE_* values. This qualifies the pkt_num field + * into a packet number space. + */ + unsigned int pkt_space :2; + + /* 1 if the packet has one or more ACK-eliciting frames. */ + unsigned int is_ack_eliciting :1; + + /* + * One of the OSSL_ACKM_ECN_* values. This is the ECN labelling applied to + * the received packet. If unknown, use OSSL_ACKM_ECN_NONE. + */ + unsigned int ecn :2; +} OSSL_ACKM_RX_PKT; + +int ossl_ackm_on_rx_packet(OSSL_ACKM *ackm, const OSSL_ACKM_RX_PKT *pkt); + +int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack, + int pkt_space, OSSL_TIME rx_time); + +/* + * Discards a PN space. This must be called for a PN space before freeing the + * ACKM if you want in-flight packets to have their discarded callbacks called. + * This should never be called in ordinary QUIC usage for the Application Data + * PN space, but it may be called for the Application Data PN space prior to + * freeing the ACKM to simplify teardown implementations. + */ +int ossl_ackm_on_pkt_space_discarded(OSSL_ACKM *ackm, int pkt_space); + +int ossl_ackm_on_handshake_confirmed(OSSL_ACKM *ackm); +int ossl_ackm_on_timeout(OSSL_ACKM *ackm); + +OSSL_TIME ossl_ackm_get_loss_detection_deadline(OSSL_ACKM *ackm); + +/* + * Generates an ACK frame, regardless of whether the ACK manager thinks + * one should currently be sent. + * + * This clears the flag returned by ossl_ackm_is_ack_desired and the deadline + * returned by ossl_ackm_get_ack_deadline. + */ +const OSSL_QUIC_FRAME_ACK *ossl_ackm_get_ack_frame(OSSL_ACKM *ackm, + int pkt_space); + +/* + * Returns the deadline after which an ACK frame should be generated by calling + * ossl_ackm_get_ack_frame, or OSSL_TIME_INFINITY if no deadline is currently + * applicable. If the deadline has already passed, this function may return that + * deadline, or may return OSSL_TIME_ZERO. + */ +OSSL_TIME ossl_ackm_get_ack_deadline(OSSL_ACKM *ackm, int pkt_space); + +/* + * Returns 1 if the ACK manager thinks an ACK frame ought to be generated and + * sent at this time. ossl_ackm_get_ack_frame will always provide an ACK frame + * whether or not this returns 1, so it is suggested that you call this function + * first to determine whether you need to generate an ACK frame. + * + * The return value of this function can change based on calls to + * ossl_ackm_on_rx_packet and based on the passage of time (see + * ossl_ackm_get_ack_deadline). + */ +int ossl_ackm_is_ack_desired(OSSL_ACKM *ackm, int pkt_space); + +/* + * Returns 1 if the given RX PN is 'processable'. A processable PN is one that + * is not either + * + * - duplicate, meaning that we have already been passed such a PN in a call + * to ossl_ackm_on_rx_packet; or + * + * - written off, meaning that the PN is so old we have stopped tracking state + * for it (meaning that we cannot tell whether it is a duplicate and cannot + * process it safely). + * + * This should be called for a packet before attempting to process its contents. + * Failure to do so may result in processing a duplicated packet in violation of + * the RFC. + * + * The return value of this function transitions from 1 to 0 for a given PN once + * that PN is passed to ossl_ackm_on_rx_packet, thus this function must be used + * before calling ossl_ackm_on_rx_packet. + */ +int ossl_ackm_is_rx_pn_processable(OSSL_ACKM *ackm, QUIC_PN pn, int pkt_space); + +typedef struct ossl_ackm_probe_info_st { + /* + * The following two probe request types are used only for anti-deadlock + * purposes in relation to the anti-amplification logic, by generating + * packets to buy ourselves more anti-amplification credit with the server + * until a client address is verified. Note that like all Initial packets, + * any Initial probes are padded. + * + * Note: The ACKM will only ever increase these by one at a time, + * as only one probe packet should be generated for these cases. + */ + uint32_t anti_deadlock_initial, anti_deadlock_handshake; + + /* + * Send an ACK-eliciting packet for each count here. + * + * Note: The ACKM may increase this by either one or two for each probe + * request, depending on how many probe packets it thinks should be + * generated. + */ + uint32_t pto[QUIC_PN_SPACE_NUM]; +} OSSL_ACKM_PROBE_INFO; + +/* + * Returns a pointer to a structure counting any pending probe requests which + * have been generated by the ACKM. The fields in the structure are incremented + * by one every time the ACKM wants another probe of the given type to be sent. + * If the ACKM thinks two packets should be generated for a probe, it will + * increment the field twice. + * + * It is permissible for the caller to decrement or zero these fields to keep + * track of when it has generated a probe as asked. The returned structure + * has the same lifetime as the ACKM. + * + * This function should be called after calling e.g. ossl_ackm_on_timeout + * to determine if any probe requests have been generated. + */ +OSSL_ACKM_PROBE_INFO *ossl_ackm_get0_probe_request(OSSL_ACKM *ackm); + +int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn); + +/* + * Forces the ACKM to consider a packet with the given PN in the given PN space + * as having been pseudo-lost. The main reason to use this is during a Retry, to + * force any resources sent in the first Initial packet to be resent. + * + * The lost callback is called for the packet, but the packet is NOT considered + * lost for congestion control purposes. Thus this is not exactly the same as a + * true loss situation. + */ +int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm, + int pkt_space, QUIC_PN pn); + +/* + * Returns the PTO duration as currently calculated. This is a quantity of time. + * This duration is used in various parts of QUIC besides the ACKM. + */ +OSSL_TIME ossl_ackm_get_pto_duration(OSSL_ACKM *ackm); + +/* Returns the largest acked PN in the given PN space. */ +QUIC_PN ossl_ackm_get_largest_acked(OSSL_ACKM *ackm, int pkt_space); + +# endif + +#endif diff --git a/include/internal/quic_cc.h b/include/internal/quic_cc.h new file mode 100644 index 0000000000..60c710b0bd --- /dev/null +++ b/include/internal/quic_cc.h @@ -0,0 +1,219 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef OSSL_QUIC_CC_H +# define OSSL_QUIC_CC_H + +#include "openssl/params.h" +#include "internal/time.h" + +# ifndef OPENSSL_NO_QUIC + +typedef struct ossl_cc_data_st OSSL_CC_DATA; + +typedef struct ossl_cc_ack_info_st { + /* The time the packet being acknowledged was originally sent. */ + OSSL_TIME tx_time; + + /* The size in bytes of the packet being acknowledged. */ + size_t tx_size; +} OSSL_CC_ACK_INFO; + +typedef struct ossl_cc_loss_info_st { + /* The time the packet being lost was originally sent. */ + OSSL_TIME tx_time; + + /* The size in bytes of the packet which has been determined lost. */ + size_t tx_size; +} OSSL_CC_LOSS_INFO; + +typedef struct ossl_cc_ecn_info_st { + /* + * The time at which the largest acked PN (in the incoming ACK frame) was + * sent. + */ + OSSL_TIME largest_acked_time; +} OSSL_CC_ECN_INFO; + +/* Parameter (read-write): Maximum datagram payload length in bytes. */ +#define OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN "max_dgram_payload_len" + +/* Diagnostic (read-only): current congestion window size in bytes. */ +#define OSSL_CC_OPTION_CUR_CWND_SIZE "cur_cwnd_size" + +/* Diagnostic (read-only): minimum congestion window size in bytes. */ +#define OSSL_CC_OPTION_MIN_CWND_SIZE "min_cwnd_size" + +/* Diagnostic (read-only): current net bytes in flight. */ +#define OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT "bytes_in_flight" + +/* Diagnostic (read-only): method-specific state value. */ +#define OSSL_CC_OPTION_CUR_STATE "cur_state" + +/* + * Congestion control abstract interface. + * + * This interface is broadly based on the design described in RFC 9002. However, + * the demarcation between the ACKM and the congestion controller does not + * exactly match that delineated in the RFC 9002 pseudocode. Where aspects of + * the demarcation involve the congestion controller accessing internal state of + * the ACKM, the interface has been revised where possible to provide the + * information needed by the congestion controller and avoid needing to give the + * congestion controller access to the ACKM's internal data structures. + * + * Particular changes include: + * + * - In our implementation, it is the responsibility of the ACKM to determine + * if a loss event constitutes persistent congestion. + * + * - In our implementation, it is the responsibility of the ACKM to determine + * if the ECN-CE counter has increased. The congestion controller is simply + * informed when an ECN-CE event occurs. + * + * All of these changes are intended to avoid having a congestion controller + * have to access ACKM internal state. + */ +#define OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION (1U << 0) + +typedef struct ossl_cc_method_st { + /* + * Instantiation. + */ + OSSL_CC_DATA *(*new)(OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); + + void (*free)(OSSL_CC_DATA *ccdata); + + /* + * Reset of state. + */ + void (*reset)(OSSL_CC_DATA *ccdata); + + /* + * Escape hatch for option configuration. + * + * params is an array of OSSL_PARAM structures. + * + * Returns 1 on success and 0 on failure. + */ + int (*set_input_params)(OSSL_CC_DATA *ccdata, + const OSSL_PARAM *params); + + /* + * (Re)bind output (diagnostic) information. + * + * params is an array of OSSL_PARAM structures used to output values. The + * storage locations associated with each parameter are stored internally + * and updated whenever the state of the congestion controller is updated; + * thus, the storage locations associated with the OSSL_PARAMs passed in the + * call to this function must remain valid until the congestion controller + * is freed or those parameters are unbound. A given parameter name may be + * bound to only one location at a time. The params structures themselves + * do not need to remain allocated after this call returns. + * + * Returns 1 on success and 0 on failure. + */ + int (*bind_diagnostics)(OSSL_CC_DATA *ccdata, + OSSL_PARAM *params); + + /* + * Unbind diagnostic information. The parameters with the given names are + * unbound, cancelling the effects of a previous call to bind_diagnostic(). + * params is an array of OSSL_PARAMs. The values of the parameters are + * ignored. If a parameter is already unbound, there is no effect for that + * parameter but other parameters are still unbound. + * + * Returns 1 on success or 0 on failure. + */ + int (*unbind_diagnostics)(OSSL_CC_DATA *ccdata, + OSSL_PARAM *params); + + /* + * Returns the amount of additional data (above and beyond the data + * currently in flight) which can be sent in bytes. Returns 0 if no more + * data can be sent at this time. The return value of this method + * can vary as time passes. + */ + uint64_t (*get_tx_allowance)(OSSL_CC_DATA *ccdata); + + /* + * Returns the time at which the return value of get_tx_allowance might be + * higher than its current value. This is not a guarantee and spurious + * wakeups are allowed. Returns ossl_time_infinite() if there is no current + * wakeup deadline. + */ + OSSL_TIME (*get_wakeup_deadline)(OSSL_CC_DATA *ccdata); + + /* + * The On Data Sent event. num_bytes should be the size of the packet in + * bytes (or the aggregate size of multiple packets which have just been + * sent). + */ + int (*on_data_sent)(OSSL_CC_DATA *ccdata, + uint64_t num_bytes); + + /* + * The On Data Acked event. See OSSL_CC_ACK_INFO structure for details + * of the information to be passed. + */ + int (*on_data_acked)(OSSL_CC_DATA *ccdata, + const OSSL_CC_ACK_INFO *info); + + /* + * The On Data Lost event. See OSSL_CC_LOSS_INFO structure for details + * of the information to be passed. + * + * Note: When the ACKM determines that a set of multiple packets has been + * lost, it is useful for a congestion control algorithm to be able to + * process this as a single loss event rather than multiple loss events. + * Thus, calling this function may cause the congestion controller to defer + * state updates under the assumption that subsequent calls to + * on_data_lost() representing further lost packets in the same loss event + * may be forthcoming. Always call on_data_lost_finished() after one or more + * calls to on_data_lost(). + */ + int (*on_data_lost)(OSSL_CC_DATA *ccdata, + const OSSL_CC_LOSS_INFO *info); + + /* + * To be called after a sequence of one or more on_data_lost() calls + * representing multiple packets in a single loss detection incident. + * + * Flags may be 0 or OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION. + */ + int (*on_data_lost_finished)(OSSL_CC_DATA *ccdata, uint32_t flags); + + /* + * For use when a PN space is invalidated or a packet must otherwise be + * 'undone' for congestion control purposes without acting as a loss signal. + * Only the size of the packet is needed. + */ + int (*on_data_invalidated)(OSSL_CC_DATA *ccdata, + uint64_t num_bytes); + + /* + * Called from the ACKM when detecting an increased ECN-CE value in an ACK + * frame. This indicates congestion. + * + * Note that this differs from the RFC's conceptual segregation of the loss + * detection and congestion controller functions, as in our implementation + * the ACKM is responsible for detecting increases to ECN-CE and simply + * tells the congestion controller when ECN-triggered congestion has + * occurred. This allows a slightly more efficient implementation and + * narrower interface between the ACKM and CC. + */ + int (*on_ecn)(OSSL_CC_DATA *ccdata, + const OSSL_CC_ECN_INFO *info); +} OSSL_CC_METHOD; + +extern const OSSL_CC_METHOD ossl_cc_dummy_method; +extern const OSSL_CC_METHOD ossl_cc_newreno_method; + +# endif + +#endif diff --git a/include/internal/quic_cfq.h b/include/internal/quic_cfq.h new file mode 100644 index 0000000000..22c436dc07 --- /dev/null +++ b/include/internal/quic_cfq.h @@ -0,0 +1,154 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_CFQ_H +# define OSSL_QUIC_CFQ_H + +# include +# include "internal/quic_types.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Control Frame Queue Item + * ============================= + * + * The CFQ item structure has a public and a private part. This structure + * documents the public part. + */ +typedef struct quic_cfq_item_st QUIC_CFQ_ITEM; + +struct quic_cfq_item_st { + /* + * These fields are not used by the CFQ, but are a convenience to assist the + * TXPIM in keeping a list of GCR control frames which were sent in a + * packet. They may be used for any purpose. + */ + QUIC_CFQ_ITEM *pkt_prev, *pkt_next; + + /* All other fields are private; use ossl_quic_cfq_item_* accessors. */ +}; + +# define QUIC_CFQ_STATE_NEW 0 +# define QUIC_CFQ_STATE_TX 1 + +/* If set, do not retransmit on loss */ +#define QUIC_CFQ_ITEM_FLAG_UNRELIABLE (1U << 0) + +/* Returns the frame type of a CFQ item. */ +uint64_t ossl_quic_cfq_item_get_frame_type(const QUIC_CFQ_ITEM *item); + +/* Returns a pointer to the encoded buffer of a CFQ item. */ +const unsigned char *ossl_quic_cfq_item_get_encoded(const QUIC_CFQ_ITEM *item); + +/* Returns the length of the encoded buffer in bytes. */ +size_t ossl_quic_cfq_item_get_encoded_len(const QUIC_CFQ_ITEM *item); + +/* Returns the CFQ item state, a QUIC_CFQ_STATE_* value. */ +int ossl_quic_cfq_item_get_state(const QUIC_CFQ_ITEM *item); + +/* Returns the PN space for the CFQ item. */ +uint32_t ossl_quic_cfq_item_get_pn_space(const QUIC_CFQ_ITEM *item); + +/* Returns 1 if this is an unreliable frame. */ +int ossl_quic_cfq_item_is_unreliable(const QUIC_CFQ_ITEM *item); + +/* + * QUIC Control Frame Queue + * ======================== + */ +typedef struct quic_cfq_st QUIC_CFQ; + +QUIC_CFQ *ossl_quic_cfq_new(void); +void ossl_quic_cfq_free(QUIC_CFQ *cfq); + +/* + * Input Side + * ---------- + */ + +/* + * Enqueue a frame to the CFQ. + * + * encoded points to the opaque encoded frame. + * + * free_cb is called by the CFQ when the buffer is no longer needed; + * free_cb_arg is an opaque value passed to free_cb. + * + * priority determines the relative ordering of control frames in a packet. + * Lower numerical values for priority mean that a frame should come earlier in + * a packet. pn_space is a QUIC_PN_SPACE_* value. + * + * On success, returns a QUIC_CFQ_ITEM pointer which acts as a handle to + * the queued frame. On failure, returns NULL. + * + * The frame is initially in the TX state, so there is no need to call + * ossl_quic_cfq_mark_tx() immediately after calling this function. + * + * The frame type is duplicated as the frame_type argument here, even though it + * is also encoded into the buffer. This allows the caller to determine the + * frame type if desired without having to decode the frame. + * + * flags is zero or more QUIC_CFQ_ITEM_FLAG values. + */ +typedef void (cfq_free_cb)(unsigned char *buf, size_t buf_len, void *arg); + +QUIC_CFQ_ITEM *ossl_quic_cfq_add_frame(QUIC_CFQ *cfq, + uint32_t priority, + uint32_t pn_space, + uint64_t frame_type, + uint32_t flags, + const unsigned char *encoded, + size_t encoded_len, + cfq_free_cb *free_cb, + void *free_cb_arg); + +/* + * Effects an immediate transition of the given CFQ item to the TX state. + */ +void ossl_quic_cfq_mark_tx(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item); + +/* + * Effects an immediate transition of the given CFQ item to the NEW state, + * allowing the frame to be retransmitted. If priority is not UINT32_MAX, + * the priority is changed to the given value. + */ +void ossl_quic_cfq_mark_lost(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item, + uint32_t priority); + +/* + * Releases a CFQ item. The item may be in either state (NEW or TX) prior to the + * call. The QUIC_CFQ_ITEM pointer must not be used following this call. + */ +void ossl_quic_cfq_release(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item); + +/* + * Output Side + * ----------- + */ + +/* + * Gets the highest priority CFQ item in the given PN space awaiting + * transmission. If there are none, returns NULL. + */ +QUIC_CFQ_ITEM *ossl_quic_cfq_get_priority_head(const QUIC_CFQ *cfq, + uint32_t pn_space); + +/* + * Given a CFQ item, gets the next CFQ item awaiting transmission in priority + * order in the given PN space. In other words, given the return value of + * ossl_quic_cfq_get_priority_head(), returns the next-lower priority item. + * Returns NULL if the given item is the last item in priority order. + */ +QUIC_CFQ_ITEM *ossl_quic_cfq_item_get_priority_next(const QUIC_CFQ_ITEM *item, + uint32_t pn_space); + +# endif + +#endif diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h new file mode 100644 index 0000000000..f46db0637e --- /dev/null +++ b/include/internal/quic_channel.h @@ -0,0 +1,429 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_CHANNEL_H +# define OSSL_QUIC_CHANNEL_H + +# include +# include "internal/quic_types.h" +# include "internal/quic_stream_map.h" +# include "internal/quic_reactor.h" +# include "internal/quic_statm.h" +# include "internal/time.h" +# include "internal/thread.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Channel + * ============ + * + * A QUIC channel (QUIC_CHANNEL) is an object which binds together all of the + * various pieces of QUIC into a single top-level object, and handles connection + * state which is not specific to the client or server roles. In particular, it + * is strictly separated from the libssl front end I/O API personality layer, + * and is not an SSL object. + * + * The name QUIC_CHANNEL is chosen because QUIC_CONNECTION is already in use, + * but functionally these relate to the same thing (a QUIC connection). The use + * of two separate objects ensures clean separation between the API personality + * layer and common code for handling connections, and between the functionality + * which is specific to clients and which is specific to servers, and the + * functionality which is common to both. + * + * The API personality layer provides SSL objects (e.g. a QUIC_CONNECTION) which + * consume a QUIC channel and implement a specific public API. Things which are + * handled by the API personality layer include emulation of blocking semantics, + * handling of SSL object mode flags like non-partial write mode, etc. + * + * Where the QUIC_CHANNEL is used in a server role, there is one QUIC_CHANNEL + * per connection. In the future a QUIC Channel Manager will probably be defined + * to handle ownership of resources which are shared between connections (e.g. + * demuxers). Since we only use server-side functionality for dummy test servers + * for now, which only need to handle one connection at a time, this is not + * currently modelled. + * + * Synchronisation + * --------------- + * + * To support thread assisted mode, QUIC_CHANNEL can be used by multiple + * threads. **It is the caller's responsibility to ensure that the QUIC_CHANNEL + * is only accessed (whether via its methods or via direct access to its state) + * while the channel mutex is held**, except for methods explicitly marked as + * not requiring prior locking. This is an unchecked precondition. + * + * The instantiator of the channel is responsible for providing a suitable + * mutex which then serves as the channel mutex; see QUIC_CHANNEL_ARGS. + */ + +/* + * The function does not acquire the channel mutex and assumes it is already + * held by the calling thread. + * + * Any function tagged with this has the following precondition: + * + * Precondition: must hold channel mutex (unchecked) + */ +# define QUIC_NEEDS_LOCK + +/* + * The function acquires the channel mutex and releases it before returning in + * all circumstances. + * + * Any function tagged with this has the following precondition and + * postcondition: + * + * Precondition: must not hold channel mutex (unchecked) + * Postcondition: channel mutex is not held (by calling thread) + */ +# define QUIC_TAKES_LOCK + +/* + * The function acquires the channel mutex and leaves it acquired + * when returning success. + * + * Any function tagged with this has the following precondition and + * postcondition: + * + * Precondition: must not hold channel mutex (unchecked) + * Postcondition: channel mutex is held by calling thread + * or function returned failure + */ +# define QUIC_ACQUIRES_LOCK + +# define QUIC_TODO_LOCK + +# define QUIC_CHANNEL_STATE_IDLE 0 +# define QUIC_CHANNEL_STATE_ACTIVE 1 +# define QUIC_CHANNEL_STATE_TERMINATING_CLOSING 2 +# define QUIC_CHANNEL_STATE_TERMINATING_DRAINING 3 +# define QUIC_CHANNEL_STATE_TERMINATED 4 + +typedef struct quic_channel_args_st { + OSSL_LIB_CTX *libctx; + const char *propq; + int is_server; + SSL *tls; + + /* + * This must be a mutex the lifetime of which will exceed that of the + * channel. The instantiator of the channel is responsible for providing a + * mutex as this makes it easier to handle instantiation and teardown of + * channels in situations potentially requiring locking. + * + * Note that this is a MUTEX not a RWLOCK as it needs to be an OS mutex for + * compatibility with an OS's condition variable wait API, whereas RWLOCK + * may, depending on the build configuration, be implemented using an OS's + * mutex primitive or using its RW mutex primitive. + */ + CRYPTO_MUTEX *mutex; + + /* + * Optional function pointer to use to retrieve the current time. If NULL, + * ossl_time_now() is used. + */ + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; +} QUIC_CHANNEL_ARGS; + +typedef struct quic_channel_st QUIC_CHANNEL; + +/* Represents the cause for a connection's termination. */ +typedef struct quic_terminate_cause_st { + /* + * If we are in a TERMINATING or TERMINATED state, this is the error code + * associated with the error. This field is valid iff we are in the + * TERMINATING or TERMINATED states. + */ + uint64_t error_code; + + /* + * If terminate_app is set and this is nonzero, this is the frame type which + * caused the connection to be terminated. + */ + uint64_t frame_type; + + /* + * Optional reason string. When calling ossl_quic_channel_local_close, if a + * reason string pointer is passed, it is copied and stored inside + * QUIC_CHANNEL for the remainder of the lifetime of the channel object. + * Thus the string pointed to by this value, if non-NULL, is valid for the + * lifetime of the QUIC_CHANNEL object. + */ + const char *reason; + + /* + * Length of reason in bytes. The reason is supposed to contain a UTF-8 + * string but may be arbitrary data if the reason came from the network. + */ + size_t reason_len; + + /* Is this error code in the transport (0) or application (1) space? */ + unsigned int app : 1; + + /* + * If set, the cause of the termination is a received CONNECTION_CLOSE + * frame. Otherwise, we decided to terminate ourselves and sent a + * CONNECTION_CLOSE frame (regardless of whether the peer later also sends + * one). + */ + unsigned int remote : 1; +} QUIC_TERMINATE_CAUSE; + + +/* + * Create a new QUIC channel using the given arguments. The argument structure + * does not need to remain allocated. Returns NULL on failure. + */ +QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args); + +/* No-op if ch is NULL. */ +void ossl_quic_channel_free(QUIC_CHANNEL *ch); + +/* Set mutator callbacks for test framework support */ +int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch, + ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, + void *mutatearg); + +/* + * Connection Lifecycle Events + * =========================== + * + * Various events that can be raised on the channel by other parts of the QUIC + * implementation. Some of these are suitable for general use by any part of the + * code (e.g. ossl_quic_channel_raise_protocol_error), others are for very + * specific use by particular components only (e.g. + * ossl_quic_channel_on_handshake_confirmed). + */ + +/* + * To be used by a QUIC connection. Starts the channel. For a client-mode + * channel, this starts sending the first handshake layer message, etc. Can only + * be called in the idle state; successive calls are ignored. + */ +int ossl_quic_channel_start(QUIC_CHANNEL *ch); + +/* Start a locally initiated connection shutdown. */ +void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code, + const char *app_reason); + +/* + * Called when the handshake is confirmed. + */ +int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch); + +/* + * Raises a protocol error. This is intended to be the universal call suitable + * for handling of all peer-triggered protocol violations or errors detected by + * us. We specify a QUIC transport-scope error code and optional frame type + * which was responsible. If a frame type is not applicable, specify zero. The + * reason string is not currently handled, but should be a string of static + * storage duration. If the connection has already terminated due to a previous + * protocol error, this is a no-op; first error wins. + * + * Usually the ossl_quic_channel_raise_protocol_error() function should be used. + * The ossl_quic_channel_raise_protocol_error_loc() function can be used + * directly for passing through existing call site information from an existing + * error. + */ +void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch, + uint64_t error_code, + uint64_t frame_type, + const char *reason, + ERR_STATE *err_state, + const char *src_file, + int src_line, + const char *src_func); + +#define ossl_quic_channel_raise_protocol_error(ch, error_code, frame_type, reason) \ + ossl_quic_channel_raise_protocol_error_loc((ch), (error_code), \ + (frame_type), \ + (reason), \ + NULL, \ + OPENSSL_FILE, \ + OPENSSL_LINE, \ + OPENSSL_FUNC) + +#define ossl_quic_channel_raise_protocol_error_state(ch, error_code, frame_type, reason, state) \ + ossl_quic_channel_raise_protocol_error_loc((ch), (error_code), \ + (frame_type), \ + (reason), \ + (state), \ + OPENSSL_FILE, \ + OPENSSL_LINE, \ + OPENSSL_FUNC) + + +/* + * Returns 1 if permanent net error was detected on the QUIC_CHANNEL, + * 0 otherwise. + */ +int ossl_quic_channel_net_error(QUIC_CHANNEL *ch); + +/* Restore saved error state (best effort) */ +void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch); + +/* For RXDP use. */ +void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch, + OSSL_QUIC_FRAME_CONN_CLOSE *f); +void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, + OSSL_QUIC_FRAME_NEW_CONN_ID *f); + +/* + * Queries and Accessors + * ===================== + */ + +/* Gets the reactor which can be used to tick/poll on the channel. */ +QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch); + +/* Gets the QSM used with the channel. */ +QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch); + +/* Gets the statistics manager used with the channel. */ +OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch); + +/* + * Gets/sets the current peer address. Generally this should be used before + * starting a channel in client mode. + */ +int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr); +int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr); + +/* Gets/sets the underlying network read and write BIOs. */ +BIO *ossl_quic_channel_get_net_rbio(QUIC_CHANNEL *ch); +BIO *ossl_quic_channel_get_net_wbio(QUIC_CHANNEL *ch); +int ossl_quic_channel_set_net_rbio(QUIC_CHANNEL *ch, BIO *net_rbio); +int ossl_quic_channel_set_net_wbio(QUIC_CHANNEL *ch, BIO *net_wbio); + +/* + * Re-poll the network BIOs already set to determine if their support + * for polling has changed. + */ +int ossl_quic_channel_update_poll_descriptors(QUIC_CHANNEL *ch); + +/* + * Returns an existing stream by stream ID. Returns NULL if the stream does not + * exist. + */ +QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch, + uint64_t stream_id); + +/* Returns 1 if channel is terminating or terminated. */ +int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch); +const QUIC_TERMINATE_CAUSE * +ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch); +int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch); +int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch); +int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch); +int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch); +int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch); + +QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch); + +SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch); + +/* + * Retrieves a pointer to the channel mutex which was provided at the time the + * channel was instantiated. In order to allow locks to be acquired and released + * with the correct granularity, it is the caller's responsibility to ensure + * this lock is held for write while calling any QUIC_CHANNEL method, except for + * methods explicitly designed otherwise. + * + * This method is thread safe and does not require prior locking. It can also be + * called while the lock is already held. Note that this is simply a convenience + * function to access the mutex which was passed to the channel at instantiation + * time; it does not belong to the channel but rather is presumed to belong to + * the owner of the channel. + */ +CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch); + +/* + * Creates a new locally-initiated stream in the stream mapper, choosing an + * appropriate stream ID. If is_uni is 1, creates a unidirectional stream, else + * creates a bidirectional stream. Returns NULL on failure. + */ +QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni); + +/* + * Creates a new remotely-initiated stream in the stream mapper. The stream ID + * is used to confirm the initiator and determine the stream type. The stream is + * automatically added to the QSM's accept queue. A pointer to the stream is + * also returned. Returns NULL on failure. + */ +QUIC_STREAM *ossl_quic_channel_new_stream_remote(QUIC_CHANNEL *ch, + uint64_t stream_id); + +/* + * Configures incoming stream auto-reject. If enabled, incoming streams have + * both their sending and receiving parts automatically rejected using + * STOP_SENDING and STREAM_RESET frames. aec is the application error + * code to be used for those frames. + */ +void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch, + int enable, + uint64_t aec); + +/* + * Causes the channel to reject the sending and receiving parts of a stream, + * as though autorejected. Can be used if a stream has already been + * accepted. + */ +void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs); + +/* Replace local connection ID in TXP and DEMUX for testing purposes. */ +int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch, + const QUIC_CONN_ID *conn_id); + +/* Setters for the msg_callback and msg_callback_arg */ +void ossl_quic_channel_set_msg_callback(QUIC_CHANNEL *ch, + ossl_msg_cb msg_callback, + SSL *msg_callback_ssl); +void ossl_quic_channel_set_msg_callback_arg(QUIC_CHANNEL *ch, + void *msg_callback_arg); + +/* Testing use only - sets a TXKU threshold packet count override value. */ +void ossl_quic_channel_set_txku_threshold_override(QUIC_CHANNEL *ch, + uint64_t tx_pkt_threshold); + +/* Testing use only - gets current 1-RTT key epochs for QTX and QRX. */ +uint64_t ossl_quic_channel_get_tx_key_epoch(QUIC_CHANNEL *ch); +uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch); + +/* Artificially trigger a spontaneous TXKU if possible. */ +int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch); +int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch); + +/* Force transmission of an ACK-eliciting packet. */ +int ossl_quic_channel_ping(QUIC_CHANNEL *ch); + +/* For testing use. While enabled, ticking is not performed. */ +void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit); + +/* + * These queries exist for diagnostic purposes only. They may roll over. + * Do not rely on them for non-testing purposes. + */ +uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch); + +/* + * Diagnostic use only. Gets the current local CID. + */ +void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid); + +/* + * Returns 1 if stream count flow control allows us to create a new + * locally-initiated stream. + */ +int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch, int is_uni); + +# endif + +#endif diff --git a/include/internal/quic_demux.h b/include/internal/quic_demux.h new file mode 100644 index 0000000000..444249e728 --- /dev/null +++ b/include/internal/quic_demux.h @@ -0,0 +1,364 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_DEMUX_H +# define OSSL_QUIC_DEMUX_H + +# include +# include "internal/quic_types.h" +# include "internal/bio_addr.h" +# include "internal/time.h" +# include "internal/list.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Demuxer + * ============ + * + * The QUIC connection demuxer is the entity responsible for receiving datagrams + * from the network via a datagram BIO. It parses packet headers to determine + * each packet's destination connection ID (DCID) and hands off processing of + * the packet to the correct QUIC Record Layer (QRL)'s RX side (known as the + * QRX). + * + * A QRX is instantiated per QUIC connection and contains the cryptographic + * resources needed to decrypt QUIC packets for that connection. Received + * datagrams are passed from the demuxer to the QRX via a callback registered + * for a specific DCID by the QRX; thus the demuxer has no specific knowledge of + * the QRX and is not coupled to it. + * + * A connection may have multiple connection IDs associated with it; a QRX + * handles this simply by registering multiple connection IDs with the demuxer + * via multiple register calls. + * + * URX Queue + * --------- + * + * Since the demuxer must handle the initial reception of datagrams from the OS, + * RX queue management for new, unprocessed datagrams is also handled by the + * demuxer. + * + * The demuxer maintains a queue of Unprocessed RX Entries (URXEs), which store + * unprocessed (i.e., encrypted, unvalidated) data received from the network. + * The URXE queue is designed to allow multiple datagrams to be received in a + * single call to BIO_recvmmsg, where supported. + * + * One URXE is used per received datagram. Each datagram may contain multiple + * packets, however, this is not the demuxer's concern. QUIC prohibits different + * packets in the same datagram from containing different DCIDs; the demuxer + * only considers the DCID of the first packet in a datagram when deciding how + * to route a received datagram, and it is the responsibility of the QRX to + * enforce this rule. Packets other than the first packet in a datagram are not + * examined by the demuxer, and the demuxer does not perform validation of + * packet headers other than to the minimum extent necessary to extract the + * DCID; further parsing and validation of packet headers is the responsibility + * of the QRX. + * + * Rather than defining an opaque interface, the URXE structure internals + * are exposed. Since the demuxer is only exposed to other parts of the QUIC + * implementation internals, this poses no problem, and has a number of + * advantages: + * + * - Fields in the URXE can be allocated to support requirements in other + * components, like the QRX, which would otherwise have to allocate extra + * memory corresponding to each URXE. + * + * - Other components, like the QRX, can keep the URXE in queues of its own + * when it is not being managed by the demuxer. + * + * URX Queue Structure + * ------------------- + * + * The URXE queue is maintained as a simple doubly-linked list. URXE entries are + * moved between different lists in their lifecycle (for example, from a free + * list to a pending list and vice versa). The buffer into which datagrams are + * received immediately follows this URXE header structure and is part of the + * same allocation. + */ + +typedef struct quic_urxe_st QUIC_URXE; + +/* Maximum number of packets we allow to exist in one datagram. */ +#define QUIC_MAX_PKT_PER_URXE (sizeof(uint64_t) * 8) + +struct quic_urxe_st { + OSSL_LIST_MEMBER(urxe, QUIC_URXE); + + /* + * The URXE data starts after this structure so we don't need a pointer. + * data_len stores the current length (i.e., the length of the received + * datagram) and alloc_len stores the allocation length. The URXE will be + * reallocated if we need a larger allocation than is available, though this + * should not be common as we will have a good idea of worst-case MTUs up + * front. + */ + size_t data_len, alloc_len; + + /* + * Bitfields per packet. processed indicates the packet has been processed + * and must not be processed again, hpr_removed indicates header protection + * has already been removed. Used by QRX only; not used by the demuxer. + */ + uint64_t processed, hpr_removed; + + /* + * Address of peer we received the datagram from, and the local interface + * address we received it on. If local address support is not enabled, local + * is zeroed. + */ + BIO_ADDR peer, local; + + /* + * Time at which datagram was received (or ossl_time_zero()) if a now + * function was not provided). + */ + OSSL_TIME time; + + /* + * Used by the QRX to mark whether a datagram has been deferred. Used by the + * QRX only; not used by the demuxer. + */ + char deferred; + + /* + * Used by the DEMUX to track if a URXE has been handed out. Used primarily + * for debugging purposes. + */ + char demux_state; +}; + +/* Accessors for URXE buffer. */ +static ossl_unused ossl_inline unsigned char * +ossl_quic_urxe_data(const QUIC_URXE *e) +{ + return (unsigned char *)&e[1]; +} + +static ossl_unused ossl_inline unsigned char * +ossl_quic_urxe_data_end(const QUIC_URXE *e) +{ + return ossl_quic_urxe_data(e) + e->data_len; +} + +/* List structure tracking a queue of URXEs. */ +DEFINE_LIST_OF(urxe, QUIC_URXE); +typedef OSSL_LIST(urxe) QUIC_URXE_LIST; + +/* + * List management helpers. These are used by the demuxer but can also be used + * by users of the demuxer to manage URXEs. + */ +void ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e); +void ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e); +void ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e); + +/* Opaque type representing a demuxer. */ +typedef struct quic_demux_st QUIC_DEMUX; + +/* + * Called when a datagram is received for a given connection ID. + * + * e is a URXE containing the datagram payload. It is permissible for the callee + * to mutate this buffer; once the demuxer calls this callback, it will never + * read the buffer again. + * + * The callee must arrange for ossl_quic_demux_release_urxe or + * ossl_quic_demux_reinject_urxe to be called on the URXE at some point in the + * future (this need not be before the callback returns). + * + * At the time the callback is made, the URXE will not be in any queue, + * therefore the callee can use the prev and next fields as it wishes. + */ +typedef void (ossl_quic_demux_cb_fn)(QUIC_URXE *e, void *arg); + +/* + * Called when a datagram is received. + * Returns 1 if the datagram ends with a stateless reset token and + * 0 if not. + */ +typedef int (ossl_quic_stateless_reset_cb_fn)(const unsigned char *data, + size_t data_len, void *arg); + +/* + * Creates a new demuxer. The given BIO is used to receive datagrams from the + * network using BIO_recvmmsg. short_conn_id_len is the length of destination + * connection IDs used in RX'd packets; it must have the same value for all + * connections used on a socket. default_urxe_alloc_len is the buffer size to + * receive datagrams into; it should be a value large enough to contain any + * received datagram according to local MTUs, etc. + * + * now is an optional function used to determine the time a datagram was + * received. now_arg is an opaque argument passed to the function. If now is + * NULL, ossl_time_zero() is used as the datagram reception time. + */ +QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, + size_t short_conn_id_len, + OSSL_TIME (*now)(void *arg), + void *now_arg); + +/* + * Destroy a demuxer. All URXEs must have been released back to the demuxer + * before calling this. No-op if demux is NULL. + */ +void ossl_quic_demux_free(QUIC_DEMUX *demux); + +/* + * Changes the BIO which the demuxer reads from. This also sets the MTU if the + * BIO supports querying the MTU. + */ +void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio); + +/* + * Changes the MTU in bytes we use to receive datagrams. + */ +int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu); + +/* + * Register a datagram handler callback for a connection ID. + * + * ossl_quic_demux_pump will call the specified function if it receives a datagram + * the first packet of which has the specified destination connection ID. + * + * It is assumed all packets in a datagram have the same destination connection + * ID (as QUIC mandates this), but it is the user's responsibility to check for + * this and reject subsequent packets in a datagram that violate this rule. + * + * dst_conn_id is a destination connection ID; it is copied and need not remain + * valid after this function returns. + * + * cb_arg is passed to cb when it is called. For information on the callback, + * see its typedef above. + * + * Only one handler can be set for a given connection ID. If a handler is + * already set for the given connection ID, returns 0. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_demux_register(QUIC_DEMUX *demux, + const QUIC_CONN_ID *dst_conn_id, + ossl_quic_demux_cb_fn *cb, + void *cb_arg); + +/* + * Unregisters any datagram handler callback set for the given connection ID. + * Fails if no handler is registered for the given connection ID. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_demux_unregister(QUIC_DEMUX *demux, + const QUIC_CONN_ID *dst_conn_id); + +/* + * Unregisters any datagram handler callback from all connection IDs it is used + * for. cb and cb_arg must both match the values passed to + * ossl_quic_demux_register. + */ +void ossl_quic_demux_unregister_by_cb(QUIC_DEMUX *demux, + ossl_quic_demux_cb_fn *cb, + void *cb_arg); + +/* + * Set the default packet handler. This is used for incoming packets which don't + * match a registered DCID. This is only needed for servers. If a default packet + * handler is not set, a packet which doesn't match a registered DCID is + * silently dropped. A default packet handler may be unset by passing NULL. + * + * The handler is responsible for ensuring that ossl_quic_demux_reinject_urxe or + * ossl_quic_demux_release_urxe is called on the passed packet at some point in + * the future, which may or may not be before the handler returns. + */ +void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, + ossl_quic_demux_cb_fn *cb, + void *cb_arg); + +/* + * Sets a callback for stateless reset processing. + * + * If set, this callback is called for datagrams for which we cannot identify + * a CID. This function should return 1 if there is a stateless reset token + * present and 0 if not. If there is a token present, the connection should + * also be reset. + */ +void ossl_quic_demux_set_stateless_reset_handler( + QUIC_DEMUX *demux, + ossl_quic_stateless_reset_cb_fn *cb, void *cb_arg); + +/* + * Releases a URXE back to the demuxer. No reference must be made to the URXE or + * its buffer after calling this function. The URXE must not be in any queue; + * that is, its prev and next pointers must be NULL. + */ +void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux, + QUIC_URXE *e); + +/* + * Reinjects a URXE which was issued to a registered DCID callback or the + * default packet handler callback back into the pending queue. This is useful + * when a packet has been handled by the default packet handler callback such + * that a DCID has now been registered and can be dispatched normally by DCID. + * Once this has been called, the caller must not touch the URXE anymore and + * must not also call ossl_quic_demux_release_urxe(). + * + * The URXE is reinjected at the head of the queue, so it will be reprocessed + * immediately. + */ +void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux, + QUIC_URXE *e); + +/* + * Process any unprocessed RX'd datagrams, by calling registered callbacks by + * connection ID, reading more datagrams from the BIO if necessary. + * + * Returns one of the following values: + * + * QUIC_DEMUX_PUMP_RES_OK + * At least one incoming datagram was processed. + * + * QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL + * No more incoming datagrams are currently available. + * Call again later. + * + * QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL + * Either the network read BIO has failed in a non-transient fashion, or + * the QUIC implementation has encountered an internal state, assertion + * or allocation error. The caller should tear down the connection + * similarly to in the case of a protocol violation. + * + */ +#define QUIC_DEMUX_PUMP_RES_OK 1 +#define QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL (-1) +#define QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL (-2) +#define QUIC_DEMUX_PUMP_RES_STATELESS_RESET (-3) + +int ossl_quic_demux_pump(QUIC_DEMUX *demux); + +/* + * Artificially inject a packet into the demuxer for testing purposes. The + * buffer must not exceed the URXE size being used by the demuxer. + * + * If peer or local are NULL, their respective fields are zeroed in the injected + * URXE. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_demux_inject(QUIC_DEMUX *demux, + const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); + +/* + * Returns 1 if there are any pending URXEs. + */ +int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux); + +# endif + +#endif diff --git a/include/internal/quic_error.h b/include/internal/quic_error.h new file mode 100644 index 0000000000..ae195a5f88 --- /dev/null +++ b/include/internal/quic_error.h @@ -0,0 +1,56 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_ERROR_H +# define OSSL_QUIC_ERROR_H + +# include + +# ifndef OPENSSL_NO_QUIC + +/* RFC 9000 Section 20.1 */ +# define QUIC_ERR_NO_ERROR 0x00 +# define QUIC_ERR_INTERNAL_ERROR 0x01 +# define QUIC_ERR_CONNECTION_REFUSED 0x02 +# define QUIC_ERR_FLOW_CONTROL_ERROR 0x03 +# define QUIC_ERR_STREAM_LIMIT_ERROR 0x04 +# define QUIC_ERR_STREAM_STATE_ERROR 0x05 +# define QUIC_ERR_FINAL_SIZE_ERROR 0x06 +# define QUIC_ERR_FRAME_ENCODING_ERROR 0x07 +# define QUIC_ERR_TRANSPORT_PARAMETER_ERROR 0x08 +# define QUIC_ERR_CONNECTION_ID_LIMIT_ERROR 0x09 +# define QUIC_ERR_PROTOCOL_VIOLATION 0x0A +# define QUIC_ERR_INVALID_TOKEN 0x0B +# define QUIC_ERR_APPLICATION_ERROR 0x0C +# define QUIC_ERR_CRYPTO_BUFFER_EXCEEDED 0x0D +# define QUIC_ERR_KEY_UPDATE_ERROR 0x0E +# define QUIC_ERR_AEAD_LIMIT_REACHED 0x0F +# define QUIC_ERR_NO_VIABLE_PATH 0x10 + +/* Inclusive range for handshake-specific errors. */ +# define QUIC_ERR_CRYPTO_ERR_BEGIN 0x0100 +# define QUIC_ERR_CRYPTO_ERR_END 0x01FF + +# define QUIC_ERR_CRYPTO_ERR(X) \ + (QUIC_ERR_CRYPTO_ERR_BEGIN + (X)) + +# define QUIC_ERR_CRYPTO_UNEXPECTED_MESSAGE \ + QUIC_ERR_CRYPTO_ERR(SSL3_AD_UNEXPECTED_MESSAGE) + +# define QUIC_ERR_CRYPTO_MISSING_EXT \ + QUIC_ERR_CRYPTO_ERR(TLS13_AD_MISSING_EXTENSION) + +# define QUIC_ERR_CRYPTO_NO_APP_PROTO \ + QUIC_ERR_CRYPTO_ERR(TLS1_AD_NO_APPLICATION_PROTOCOL) + +const char *ossl_quic_err_to_string(uint64_t error_code); + +# endif + +#endif diff --git a/include/internal/quic_fc.h b/include/internal/quic_fc.h new file mode 100644 index 0000000000..49b448a3a4 --- /dev/null +++ b/include/internal/quic_fc.h @@ -0,0 +1,277 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_FC_H +# define OSSL_QUIC_FC_H + +# include +# include "internal/time.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * TX Flow Controller (TXFC) + * ========================= + * + * For discussion, see doc/designs/quic-design/quic-fc.md. + */ +typedef struct quic_txfc_st QUIC_TXFC; + +struct quic_txfc_st { + QUIC_TXFC *parent; /* stream-level iff non-NULL */ + uint64_t swm, cwm; + char has_become_blocked; +}; + +/* + * Initialises a TX flow controller. conn_txfc should be non-NULL and point to + * the connection-level flow controller if the TXFC is for stream-level flow + * control, and NULL otherwise. + */ +int ossl_quic_txfc_init(QUIC_TXFC *txfc, QUIC_TXFC *conn_txfc); + +/* + * Gets the parent (i.e., connection-level) TX flow controller. Returns NULL if + * called on a connection-level TX flow controller. + */ +QUIC_TXFC *ossl_quic_txfc_get_parent(QUIC_TXFC *txfc); + +/* + * Bump the credit watermark (CWM) value. This is the 'On TX Window Updated' + * operation. This function is a no-op if it has already been called with an + * equal or higher CWM value. + * + * It returns 1 iff the call resulted in the CWM being bumped and 0 if it was + * not increased because it has already been called with an equal or higher CWM + * value. This is not an error per se but may indicate a local programming error + * or a protocol error in a remote peer. + */ +int ossl_quic_txfc_bump_cwm(QUIC_TXFC *txfc, uint64_t cwm); + +/* + * Get the number of bytes by which we are in credit. This is the number of + * controlled bytes we are allowed to send. (Thus if this function returns 0, we + * are currently blocked.) + * + * If called on a stream-level TXFC, ossl_quic_txfc_get_credit is called on + * the connection-level TXFC as well, and the lesser of the two values is + * returned. The consumed value is the amount already consumed on the connection + * level TXFC. + */ +uint64_t ossl_quic_txfc_get_credit(QUIC_TXFC *txfc, uint64_t consumed); + +/* + * Like ossl_quic_txfc_get_credit(), but when called on a stream-level TXFC, + * retrieves only the stream-level credit value and does not clamp it based on + * connection-level flow control. Any credit value is reduced by the consumed + * amount. + */ +uint64_t ossl_quic_txfc_get_credit_local(QUIC_TXFC *txfc, uint64_t consumed); + +/* + * Consume num_bytes of credit. This is the 'On TX' operation. This should be + * called when we transmit any controlled bytes. Calling this with an argument + * of 0 is a no-op. + * + * We must never transmit more controlled bytes than we are in credit for (see + * the return value of ossl_quic_txfc_get_credit()). If you call this function + * with num_bytes greater than our current credit, this function consumes the + * remainder of the credit and returns 0. This indicates a serious programming + * error on the caller's part. Otherwise, the function returns 1. + * + * If called on a stream-level TXFC, ossl_quic_txfc_consume_credit() is called + * on the connection-level TXFC also. If the call to that function on the + * connection-level TXFC returns zero, this function will also return zero. + */ +int ossl_quic_txfc_consume_credit(QUIC_TXFC *txfc, uint64_t num_bytes); + +/* + * Like ossl_quic_txfc_consume_credit(), but when called on a stream-level TXFC, + * consumes only from the stream-level credit and does not inform the + * connection-level TXFC. + */ +int ossl_quic_txfc_consume_credit_local(QUIC_TXFC *txfc, uint64_t num_bytes); + +/* + * This flag is provided for convenience. A caller is not required to use it. It + * is a boolean flag set whenever our credit drops to zero. If clear is 1, the + * flag is cleared. The old value of the flag is returned. Callers may use this + * to determine if they need to send a DATA_BLOCKED or STREAM_DATA_BLOCKED + * frame, which should contain the value returned by ossl_quic_txfc_get_cwm(). + */ +int ossl_quic_txfc_has_become_blocked(QUIC_TXFC *txfc, int clear); + +/* + * Get the current CWM value. This is mainly only needed when generating a + * DATA_BLOCKED or STREAM_DATA_BLOCKED frame, or for diagnostic purposes. + */ +uint64_t ossl_quic_txfc_get_cwm(QUIC_TXFC *txfc); + +/* + * Get the current spent watermark (SWM) value. This is purely for diagnostic + * use and should not be needed in normal circumstances. + */ +uint64_t ossl_quic_txfc_get_swm(QUIC_TXFC *txfc); + +/* + * RX Flow Controller (RXFC) + * ========================= + */ +typedef struct quic_rxfc_st QUIC_RXFC; + +struct quic_rxfc_st { + /* + * swm is the sent/received watermark, which tracks how much we have + * received from the peer. rwm is the retired watermark, which tracks how + * much has been passed to the application. esrwm is the rwm value at which + * the current auto-tuning epoch started. hwm is the highest stream length + * (STREAM frame offset + payload length) we have seen from a STREAM frame + * yet. + */ + uint64_t cwm, swm, rwm, esrwm, hwm, cur_window_size, max_window_size; + OSSL_TIME epoch_start; + OSSL_TIME (*now)(void *arg); + void *now_arg; + QUIC_RXFC *parent; + unsigned char error_code, has_cwm_changed, is_fin, standalone; +}; + +/* + * Initialises an RX flow controller. conn_rxfc should be non-NULL and point to + * a connection-level RXFC if the RXFC is for stream-level flow control, and + * NULL otherwise. initial_window_size and max_window_size specify the initial + * and absolute maximum window sizes, respectively. Window size values are + * expressed in bytes and determine how much credit the RXFC extends to the peer + * to transmit more data at a time. + */ +int ossl_quic_rxfc_init(QUIC_RXFC *rxfc, QUIC_RXFC *conn_rxfc, + uint64_t initial_window_size, + uint64_t max_window_size, + OSSL_TIME (*now)(void *arg), + void *now_arg); + +/* + * Initialises an RX flow controller which is used by itself and not under a + * connection-level RX flow controller. This can be used for stream count + * enforcement as well as CRYPTO buffer enforcement. + */ +int ossl_quic_rxfc_init_standalone(QUIC_RXFC *rxfc, + uint64_t initial_window_size, + OSSL_TIME (*now)(void *arg), + void *now_arg); + +/* + * Gets the parent (i.e., connection-level) RXFC. Returns NULL if called on a + * connection-level RXFC. + */ +QUIC_RXFC *ossl_quic_rxfc_get_parent(QUIC_RXFC *rxfc); + +/* + * Changes the current maximum window size value. + */ +void ossl_quic_rxfc_set_max_window_size(QUIC_RXFC *rxfc, + size_t max_window_size); + +/* + * To be called whenever a STREAM frame is received. + * + * end is the value (offset + len), where offset is the offset field of the + * STREAM frame and len is the length of the STREAM frame's payload in bytes. + * + * is_fin should be 1 if the STREAM frame had the FIN flag set and 0 otherwise. + * + * This function may be used on a stream-level RXFC only. The connection-level + * RXFC will have its state updated by the stream-level RXFC. + * + * You should check ossl_quic_rxfc_has_error() on both connection-level and + * stream-level RXFCs after calling this function, as an incoming STREAM frame + * may cause flow control limits to be exceeded by an errant peer. This + * function still returns 1 in this case, as this is not a caller error. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, + uint64_t end, int is_fin); + +/* + * To be called whenever controlled bytes are retired, i.e. when bytes are + * dequeued from a QUIC stream and passed to the application. num_bytes + * is the number of bytes which were passed to the application. + * + * You should call this only on a stream-level RXFC. This function will update + * the connection-level RXFC automatically. + * + * rtt should be the current best understanding of the RTT to the peer, as + * offered by the Statistics Manager. + * + * You should check ossl_quic_rxfc_has_cwm_changed() after calling this + * function, as it may have caused the RXFC to decide to grant more flow control + * credit to the peer. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_rxfc_on_retire(QUIC_RXFC *rxfc, + uint64_t num_bytes, + OSSL_TIME rtt); + +/* + * Returns the current CWM which the RXFC thinks the peer should have. + * + * Note that the RXFC will increase this value in response to events, at which + * time a MAX_DATA or MAX_STREAM_DATA frame must be generated. Use + * ossl_quic_rxfc_has_cwm_changed() to detect this condition. + * + * This value increases monotonically. + */ +uint64_t ossl_quic_rxfc_get_cwm(QUIC_RXFC *rxfc); + +/* + * Returns the current SWM. This is the total number of bytes the peer has + * transmitted to us. This is intended for diagnostic use only; you should + * not need it. + */ +uint64_t ossl_quic_rxfc_get_swm(QUIC_RXFC *rxfc); + +/* + * Returns the current RWM. This is the total number of bytes that has been + * retired. This is intended for diagnostic use only; you should not need it. + */ +uint64_t ossl_quic_rxfc_get_rwm(QUIC_RXFC *rxfc); + +/* + * Returns the CWM changed flag. If clear is 1, the flag is cleared and the old + * value is returned. + */ +int ossl_quic_rxfc_has_cwm_changed(QUIC_RXFC *rxfc, int clear); + +/* + * Returns a QUIC_ERR_* error code if a flow control error has been detected. + * Otherwise, returns QUIC_ERR_NO_ERROR. If clear is 1, the error is cleared + * and the old value is returned. + * + * May return one of the following values: + * + * QUIC_ERR_FLOW_CONTROL_ERROR: + * This indicates a flow control protocol violation by the remote peer; the + * connection should be terminated in this event. + * QUIC_ERR_FINAL_SIZE: + * The peer attempted to change the stream length after ending the stream. + */ +int ossl_quic_rxfc_get_error(QUIC_RXFC *rxfc, int clear); + +/* + * Returns 1 if the RXFC is a stream-level RXFC and the RXFC knows the final + * size for the stream in bytes. If this is the case and final_size is non-NULL, + * writes the final size to *final_size. Otherwise, returns 0. + */ +int ossl_quic_rxfc_get_final_size(const QUIC_RXFC *rxfc, uint64_t *final_size); + +# endif + +#endif diff --git a/include/internal/quic_fifd.h b/include/internal/quic_fifd.h new file mode 100644 index 0000000000..a260ec4471 --- /dev/null +++ b/include/internal/quic_fifd.h @@ -0,0 +1,80 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_FIFD_H +# define OSSL_QUIC_FIFD_H + +# include +# include "internal/quic_types.h" +# include "internal/quic_cfq.h" +# include "internal/quic_ackm.h" +# include "internal/quic_txpim.h" +# include "internal/quic_stream.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Frame-in-Flight Dispatcher (FIFD) + * ====================================== + */ +struct quic_fifd_st { + /* Internal data; use the ossl_quic_fifd functions. */ + QUIC_CFQ *cfq; + OSSL_ACKM *ackm; + QUIC_TXPIM *txpim; + QUIC_SSTREAM *(*get_sstream_by_id)(uint64_t stream_id, + uint32_t pn_space, + void *arg); + void *get_sstream_by_id_arg; + void (*regen_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg); + void *regen_frame_arg; + void (*confirm_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg); + void *confirm_frame_arg; + void (*sstream_updated)(uint64_t stream_id, + void *arg); + void *sstream_updated_arg; +}; + +int ossl_quic_fifd_init(QUIC_FIFD *fifd, + QUIC_CFQ *cfq, + OSSL_ACKM *ackm, + QUIC_TXPIM *txpim, + /* stream_id is UINT64_MAX for the crypto stream */ + QUIC_SSTREAM *(*get_sstream_by_id)(uint64_t stream_id, + uint32_t pn_space, + void *arg), + void *get_sstream_by_id_arg, + /* stream_id is UINT64_MAX if not applicable */ + void (*regen_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg), + void *regen_frame_arg, + void (*confirm_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg), + void *confirm_frame_arg, + void (*sstream_updated)(uint64_t stream_id, + void *arg), + void *sstream_updated_arg); + +void ossl_quic_fifd_cleanup(QUIC_FIFD *fifd); /* (no-op) */ + +int ossl_quic_fifd_pkt_commit(QUIC_FIFD *fifd, QUIC_TXPIM_PKT *pkt); + +# endif + +#endif diff --git a/include/internal/quic_reactor.h b/include/internal/quic_reactor.h new file mode 100644 index 0000000000..57bb551e27 --- /dev/null +++ b/include/internal/quic_reactor.h @@ -0,0 +1,188 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef OSSL_QUIC_REACTOR_H +# define OSSL_QUIC_REACTOR_H + +# include "internal/time.h" +# include "internal/sockets.h" +# include + +# ifndef OPENSSL_NO_QUIC + +/* + * Core I/O Reactor Framework + * ========================== + * + * Manages use of async network I/O which the QUIC stack is built on. The core + * mechanic looks like this: + * + * - There is a pollable FD for both the read and write side respectively. + * Readability and writeability of these FDs respectively determines when + * network I/O is available. + * + * - The reactor can export these FDs to the user, as well as flags indicating + * whether the user should listen for readability, writeability, or neither. + * + * - The reactor can export a timeout indication to the user, indicating when + * the reactor should be called (via libssl APIs) regardless of whether + * the network socket has become ready. + * + * The reactor is based around a tick callback which is essentially the mutator + * function. The mutator attempts to do whatever it can, attempting to perform + * network I/O to the extent currently feasible. When done, the mutator returns + * information to the reactor indicating when it should be woken up again: + * + * - Should it be woken up when network RX is possible? + * - Should it be woken up when network TX is possible? + * - Should it be woken up no later than some deadline X? + * + * The intention is that ALL I/O-related SSL_* functions with side effects (e.g. + * SSL_read/SSL_write) consist of three phases: + * + * - Optionally mutate the QUIC machine's state. + * - Optionally tick the QUIC reactor. + * - Optionally mutate the QUIC machine's state. + * + * For example, SSL_write is a mutation (appending to a stream buffer) followed + * by an optional tick (generally expected as we may want to send the data + * immediately, though not strictly needed if transmission is being deferred due + * to Nagle's algorithm, etc.). + * + * SSL_read is also a mutation and in principle does not need to tick the + * reactor, but it generally will anyway to ensure that the reactor is regularly + * ticked by an application which is only reading and not writing. + * + * If the SSL object is being used in blocking mode, SSL_read may need to block + * if no data is available yet, and SSL_write may need to block if buffers + * are full. + * + * The internals of the QUIC I/O engine always use asynchronous I/O. If the + * application desires blocking semantics, we handle this by adding a blocking + * adaptation layer on top of our internal asynchronous I/O API as exposed by + * the reactor interface. + */ +typedef struct quic_tick_result_st { + char net_read_desired; + char net_write_desired; + OSSL_TIME tick_deadline; +} QUIC_TICK_RESULT; + +typedef struct quic_reactor_st { + /* + * BIO poll descriptors which can be polled. poll_r is a poll descriptor + * which becomes readable when the QUIC state machine can potentially do + * work, and poll_w is a poll descriptor which becomes writable when the + * QUIC state machine can potentially do work. Generally, either of these + * conditions means that SSL_tick() should be called, or another SSL + * function which implicitly calls SSL_tick() (e.g. SSL_read/SSL_write()). + */ + BIO_POLL_DESCRIPTOR poll_r, poll_w; + OSSL_TIME tick_deadline; /* ossl_time_infinite() if none currently applicable */ + + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); + void *tick_cb_arg; + + /* + * These are true if we would like to know when we can read or write from + * the network respectively. + */ + unsigned int net_read_desired : 1; + unsigned int net_write_desired : 1; + + /* + * Are the read and write poll descriptors we are currently configured with + * things we can actually poll? + */ + unsigned int can_poll_r : 1; + unsigned int can_poll_w : 1; +} QUIC_REACTOR; + +void ossl_quic_reactor_init(QUIC_REACTOR *rtor, + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, + uint32_t flags), + void *tick_cb_arg, + OSSL_TIME initial_tick_deadline); + +void ossl_quic_reactor_set_poll_r(QUIC_REACTOR *rtor, + const BIO_POLL_DESCRIPTOR *r); + +void ossl_quic_reactor_set_poll_w(QUIC_REACTOR *rtor, + const BIO_POLL_DESCRIPTOR *w); + +const BIO_POLL_DESCRIPTOR *ossl_quic_reactor_get_poll_r(const QUIC_REACTOR *rtor); +const BIO_POLL_DESCRIPTOR *ossl_quic_reactor_get_poll_w(const QUIC_REACTOR *rtor); + +int ossl_quic_reactor_can_poll_r(const QUIC_REACTOR *rtor); +int ossl_quic_reactor_can_poll_w(const QUIC_REACTOR *rtor); + +int ossl_quic_reactor_can_support_poll_descriptor(const QUIC_REACTOR *rtor, + const BIO_POLL_DESCRIPTOR *d); + +int ossl_quic_reactor_net_read_desired(QUIC_REACTOR *rtor); +int ossl_quic_reactor_net_write_desired(QUIC_REACTOR *rtor); + +OSSL_TIME ossl_quic_reactor_get_tick_deadline(QUIC_REACTOR *rtor); + +/* + * Do whatever work can be done, and as much work as can be done. This involves + * e.g. seeing if we can read anything from the network (if we want to), seeing + * if we can write anything to the network (if we want to), etc. + * + * If the CHANNEL_ONLY flag is set, this indicates that we should only + * touch state which is synchronised by the channel mutex. + */ +#define QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY (1U << 0) + +int ossl_quic_reactor_tick(QUIC_REACTOR *rtor, uint32_t flags); + +/* + * Blocking I/O Adaptation Layer + * ============================= + * + * The blocking I/O adaptation layer implements blocking I/O on top of our + * asynchronous core. + * + * The core mechanism is block_until_pred(), which does not return until pred() + * returns a value other than 0. The blocker uses OS I/O synchronisation + * primitives (e.g. poll(2)) and ticks the reactor until the predicate is + * satisfied. The blocker is not required to call pred() more than once between + * tick calls. + * + * When pred returns a non-zero value, that value is returned by this function. + * This can be used to allow pred() to indicate error conditions and short + * circuit the blocking process. + * + * A return value of -1 is reserved for network polling errors. Therefore this + * return value should not be used by pred() if ambiguity is not desired. Note + * that the predicate function can always arrange its own output mechanism, for + * example by passing a structure of its own as the argument. + * + * If the SKIP_FIRST_TICK flag is set, the first call to reactor_tick() before + * the first call to pred() is skipped. This is useful if it is known that + * ticking the reactor again will not be useful (e.g. because it has already + * been done). + * + * This function assumes a write lock is held for the entire QUIC_CHANNEL. If + * mutex is non-NULL, it must be a lock currently held for write; it will be + * unlocked during any sleep, and then relocked for write afterwards. + * + * Precondition: mutex is NULL or is held for write (unchecked) + * Postcondition: mutex is NULL or is held for write (unless + * CRYPTO_THREAD_write_lock fails) + */ +#define SKIP_FIRST_TICK (1U << 0) + +int ossl_quic_reactor_block_until_pred(QUIC_REACTOR *rtor, + int (*pred)(void *arg), void *pred_arg, + uint32_t flags, + CRYPTO_RWLOCK *mutex); + +# endif + +#endif diff --git a/include/internal/quic_record_rx.h b/include/internal/quic_record_rx.h new file mode 100644 index 0000000000..e26fd35600 --- /dev/null +++ b/include/internal/quic_record_rx.h @@ -0,0 +1,569 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RECORD_RX_H +# define OSSL_QUIC_RECORD_RX_H + +# include +# include "internal/quic_wire_pkt.h" +# include "internal/quic_types.h" +# include "internal/quic_record_util.h" +# include "internal/quic_demux.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Record Layer - RX + * ====================== + */ +typedef struct ossl_qrx_st OSSL_QRX; + +typedef struct ossl_qrx_args_st { + OSSL_LIB_CTX *libctx; + const char *propq; + + /* Demux to receive datagrams from. */ + QUIC_DEMUX *demux; + + /* Length of connection IDs used in short-header packets in bytes. */ + size_t short_conn_id_len; + + /* + * Maximum number of deferred datagrams buffered at any one time. + * Suggested value: 32. + */ + size_t max_deferred; + + /* Initial reference PN used for RX. */ + QUIC_PN init_largest_pn[QUIC_PN_SPACE_NUM]; + + /* Initial key phase. For debugging use only; always 0 in real use. */ + unsigned char init_key_phase_bit; +} OSSL_QRX_ARGS; + +/* Instantiates a new QRX. */ +OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args); + +/* + * Frees the QRX. All packets obtained using ossl_qrx_read_pkt must already + * have been released by calling ossl_qrx_release_pkt. + * + * You do not need to call ossl_qrx_remove_dst_conn_id first; this function will + * unregister the QRX from the demuxer for all registered destination connection + * IDs (DCIDs) automatically. + */ +void ossl_qrx_free(OSSL_QRX *qrx); + +/* Setters for the msg_callback and msg_callback_arg */ +void ossl_qrx_set_msg_callback(OSSL_QRX *qrx, ossl_msg_cb msg_callback, + SSL *msg_callback_ssl); +void ossl_qrx_set_msg_callback_arg(OSSL_QRX *qrx, + void *msg_callback_arg); + +/* + * DCID Management + * =============== + */ + +/* + * Adds a given DCID to the QRX. The QRX will register the DCID with the demuxer + * so that incoming packets with that DCID are passed to the given QRX. Multiple + * DCIDs may be associated with a QRX at any one time. You will need to add at + * least one DCID after instantiating the QRX. A zero-length DCID is a valid + * input to this function. This function fails if the DCID is already + * registered. + * + * Returns 1 on success or 0 on error. + */ +int ossl_qrx_add_dst_conn_id(OSSL_QRX *qrx, + const QUIC_CONN_ID *dst_conn_id); + +/* + * Remove a DCID previously registered with ossl_qrx_add_dst_conn_id. The DCID + * is unregistered from the demuxer. Fails if the DCID is not registered with + * the demuxer. + * + * Returns 1 on success or 0 on error. + */ +int ossl_qrx_remove_dst_conn_id(OSSL_QRX *qrx, + const QUIC_CONN_ID *dst_conn_id); + +/* + * Secret Management + * ================= + * + * A QRX has several encryption levels (Initial, Handshake, 0-RTT, 1-RTT) and + * two directions (RX, TX). At any given time, key material is managed for each + * (EL, RX/TX) combination. + * + * Broadly, for a given (EL, RX/TX), the following state machine is applicable: + * + * WAITING_FOR_KEYS --[Provide]--> HAVE_KEYS --[Discard]--> | DISCARDED | + * \-------------------------------------[Discard]--> | | + * + * To transition the RX side of an EL from WAITING_FOR_KEYS to HAVE_KEYS, call + * ossl_qrx_provide_secret (for the INITIAL EL, use of + * ossl_quic_provide_initial_secret is recommended). + * + * Once keys have been provisioned for an EL, you call + * ossl_qrx_discard_enc_level to transition the EL to the DISCARDED state. You + * can also call this function to transition directly to the DISCARDED state + * even before any keys have been provisioned for that EL. + * + * The DISCARDED state is terminal for a given EL; you cannot provide a secret + * again for that EL after reaching it. + * + * Incoming packets cannot be processed and decrypted if they target an EL + * not in the HAVE_KEYS state. However, there is a distinction between + * the WAITING_FOR_KEYS and DISCARDED states: + * + * - In the WAITING_FOR_KEYS state, the QRX assumes keys for the given + * EL will eventually arrive. Therefore, if it receives any packet + * for an EL in this state, it buffers it and tries to process it + * again once the EL reaches HAVE_KEYS. + * + * - In the DISCARDED state, the QRX assumes no keys for the given + * EL will ever arrive again. If it receives any packet for an EL + * in this state, it is simply discarded. + * + * If the user wishes to instantiate a new QRX to replace an old one for + * whatever reason, for example to take over for an already established QUIC + * connection, it is important that all ELs no longer being used (i.e., INITIAL, + * 0-RTT, 1-RTT) are transitioned to the DISCARDED state. Otherwise, the QRX + * will assume that keys for these ELs will arrive in future, and will buffer + * any received packets for those ELs perpetually. This can be done by calling + * ossl_qrx_discard_enc_level for all non-1-RTT ELs immediately after + * instantiating the QRX. + * + * The INITIAL EL is not setup automatically when the QRX is instantiated. This + * allows the caller to instead discard it immediately after instantiation of + * the QRX if it is not needed, for example if the QRX is being instantiated to + * take over handling of an existing connection which has already passed the + * INITIAL phase. This avoids the unnecessary derivation of INITIAL keys where + * they are not needed. In the ordinary case, ossl_quic_provide_initial_secret + * should be called immediately after instantiation. + */ + +/* + * Provides a secret to the QRX, which arises due to an encryption level change. + * enc_level is a QUIC_ENC_LEVEL_* value. To initialise the INITIAL encryption + * level, it is recommended to use ossl_quic_provide_initial_secret instead. + * + * You should seek to call this function for a given EL before packets of that + * EL arrive and are processed by the QRX. However, if packets have already + * arrived for a given EL, the QRX will defer processing of them and perform + * processing of them when this function is eventually called for the EL in + * question. + * + * suite_id is a QRL_SUITE_* value which determines the AEAD function used for + * the QRX. + * + * The secret passed is used directly to derive the "quic key", "quic iv" and + * "quic hp" values. + * + * secret_len is the length of the secret buffer in bytes. The buffer must be + * sized correctly to the chosen suite, else the function fails. + * + * This function can only be called once for a given EL, except for the INITIAL + * EL, which can need rekeying when a connection retry occurs. Subsequent calls + * for non-INITIAL ELs fail, as do calls made after a corresponding call to + * ossl_qrx_discard_enc_level for that EL. The secret for a non-INITIAL EL + * cannot be changed after it is set because QUIC has no facility for + * introducing additional key material after an EL is setup. QUIC key updates + * are managed semi-automatically by the QRX but do require some caller handling + * (see below). + * + * md is for internal use and should be NULL. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_qrx_provide_secret(OSSL_QRX *qrx, + uint32_t enc_level, + uint32_t suite_id, + EVP_MD *md, + const unsigned char *secret, + size_t secret_len); + +/* + * Informs the QRX that it can now discard key material for a given EL. The QRX + * will no longer be able to process incoming packets received at that + * encryption level. This function is idempotent and succeeds if the EL has + * already been discarded. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_qrx_discard_enc_level(OSSL_QRX *qrx, uint32_t enc_level); + +/* + * Packet Reception + * ================ + */ + +/* Information about a received packet. */ +typedef struct ossl_qrx_pkt_st { + /* + * Points to a logical representation of the decoded QUIC packet header. The + * data and len fields point to the decrypted QUIC payload (i.e., to a + * sequence of zero or more (potentially malformed) frames to be decoded). + */ + QUIC_PKT_HDR *hdr; + + /* + * Address the packet was received from. If this is not available for this + * packet, this field is NULL (but this can only occur for manually injected + * packets). + */ + const BIO_ADDR *peer; + + /* + * Local address the packet was sent to. If this is not available for this + * packet, this field is NULL. + */ + const BIO_ADDR *local; + + /* + * This is the length of the datagram which contained this packet. Note that + * the datagram may have contained other packets than this. The intended use + * for this is so that the user can enforce minimum datagram sizes (e.g. for + * datagrams containing INITIAL packets), as required by RFC 9000. + */ + size_t datagram_len; + + /* The PN which was decoded for the packet, if the packet has a PN field. */ + QUIC_PN pn; + + /* + * Time the packet was received, or ossl_time_zero() if the demuxer is not + * using a now() function. + */ + OSSL_TIME time; + + /* The QRX which was used to receive the packet. */ + OSSL_QRX *qrx; + + /* + * The key epoch the packet was received with. Always 0 for non-1-RTT + * packets. + */ + uint64_t key_epoch; +} OSSL_QRX_PKT; + +/* + * Tries to read a new decrypted packet from the QRX. + * + * On success, *pkt points to a OSSL_QRX_PKT structure. The structure should be + * freed when no longer needed by calling ossl_qrx_pkt_release(). The structure + * is refcounted; to gain extra references, call ossl_qrx_pkt_up_ref(). This + * will cause a corresponding number of calls to ossl_qrx_pkt_release() to be + * ignored. + * + * The resources referenced by (*pkt)->hdr, (*pkt)->hdr->data and (*pkt)->peer + * have the same lifetime as *pkt. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **pkt); + +/* + * Decrement the reference count for the given packet and frees it if the + * reference count drops to zero. No-op if pkt is NULL. + */ +void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt); + +/* Increments the reference count for the given packet. */ +void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt); + +/* + * Returns 1 if there are any already processed (i.e. decrypted) packets waiting + * to be read from the QRX. + */ +int ossl_qrx_processed_read_pending(OSSL_QRX *qrx); + +/* + * Returns 1 if there are any unprocessed (i.e. not yet decrypted) packets + * waiting to be processed by the QRX. These may or may not result in + * successfully decrypted packets once processed. This indicates whether + * unprocessed data is buffered by the QRX, not whether any data is available in + * a kernel socket buffer. + */ +int ossl_qrx_unprocessed_read_pending(OSSL_QRX *qrx); + +/* + * Returns the number of UDP payload bytes received from the network so far + * since the last time this counter was cleared. If clear is 1, clears the + * counter and returns the old value. + * + * The intended use of this is to allow callers to determine how much credit to + * add to their anti-amplification budgets. This is reported separately instead + * of in the OSSL_QRX_PKT structure so that a caller can apply + * anti-amplification credit as soon as a datagram is received, before it has + * necessarily read all processed packets contained within that datagram from + * the QRX. + */ +uint64_t ossl_qrx_get_bytes_received(OSSL_QRX *qrx, int clear); + +/* + * Sets a callback which is called when a packet is received and being validated + * before being queued in the read queue. This is called after packet body + * decryption and authentication to prevent exposing side channels. pn_space is + * a QUIC_PN_SPACE_* value denoting which PN space the PN belongs to. + * + * If this callback returns 1, processing continues normally. + * If this callback returns 0, the packet is discarded. + * + * Other packets in the same datagram will still be processed where possible. + * + * The callback is optional and can be unset by passing NULL for cb. + * cb_arg is an opaque value passed to cb. + */ +typedef int (ossl_qrx_late_validation_cb)(QUIC_PN pn, int pn_space, + void *arg); + +int ossl_qrx_set_late_validation_cb(OSSL_QRX *qrx, + ossl_qrx_late_validation_cb *cb, + void *cb_arg); + +/* + * Forcibly injects a URXE which has been issued by the DEMUX into the QRX for + * processing. This can be used to pass a received datagram to the QRX if it + * would not be correctly routed to the QRX via standard DCID-based routing; for + * example, when handling an incoming Initial packet which is attempting to + * establish a new connection. + */ +void ossl_qrx_inject_urxe(OSSL_QRX *qrx, QUIC_URXE *e); + +/* + * Decryption of 1-RTT packets must be explicitly enabled by calling this + * function. This is to comply with the requirement that we not process 1-RTT + * packets until the handshake is complete, even if we already have 1-RTT + * secrets. Even if a 1-RTT secret is provisioned for the QRX, incoming 1-RTT + * packets will be handled as though no key is available until this function is + * called. Calling this function will then requeue any such deferred packets for + * processing. + */ +void ossl_qrx_allow_1rtt_processing(OSSL_QRX *qrx); + +/* + * Key Update (RX) + * =============== + * + * Key update on the RX side is a largely but not entirely automatic process. + * + * Key update is initially triggered by receiving a 1-RTT packet with a + * different Key Phase value. This could be caused by an attacker in the network + * flipping random bits, therefore such a key update is tentative until the + * packet payload is successfully decrypted and authenticated by the AEAD with + * the 'next' keys. These 'next' keys then become the 'current' keys and the + * 'current' keys then become the 'previous' keys. The 'previous' keys must be + * kept around temporarily as some packets may still be in flight in the network + * encrypted with the old keys. If the old Key Phase value is X and the new Key + * Phase Value is Y (where obviously X != Y), this creates an ambiguity as any + * new packet received with a KP of X could either be an attempt to initiate yet + * another key update right after the last one, or an old packet encrypted + * before the key update. + * + * RFC 9001 provides some guidance on handling this issue: + * + * Strategy 1: + * Three keys, disambiguation using packet numbers + * + * "A recovered PN that is lower than any PN from the current KP uses the + * previous packet protection keys; a recovered PN that is higher than any + * PN from the current KP requires use of the next packet protection + * keys." + * + * Strategy 2: + * Two keys and a timer + * + * "Alternatively, endpoints can retain only two sets of packet protection + * keys, swapping previous keys for next after enough time has passed to + * allow for reordering in the network. In this case, the KP bit alone can + * be used to select keys." + * + * Strategy 2 is more efficient (we can keep fewer cipher contexts around) and + * should cover all actually possible network conditions. It also allows a delay + * after we make the 'next' keys our 'current' keys before we generate new + * 'next' keys, which allows us to mitigate against malicious peers who try to + * initiate an excessive number of key updates. + * + * We therefore model the following state machine: + * + * + * PROVISIONED + * _______________________________ + * | | + * UNPROVISIONED --|----> NORMAL <----------\ |------> DISCARDED + * | | | | + * | | | | + * | v | | + * | UPDATING | | + * | | | | + * | | | | + * | v | | + * | COOLDOWN | | + * | | | | + * | | | | + * | \---------------| | + * |_______________________________| + * + * + * The RX starts (once a secret has been provisioned) in the NORMAL state. In + * the NORMAL state, the current expected value of the Key Phase bit is + * recorded. When a flipped Key Phase bit is detected, the RX attempts to + * decrypt and authenticate the received packet with the 'next' keys rather than + * the 'current' keys. If (and only if) this authentication is successful, we + * move to the UPDATING state. (An attacker in the network could flip + * the Key Phase bit randomly, so it is essential we do nothing until AEAD + * authentication is complete.) + * + * In the UPDATING state, we know a key update is occurring and record + * the new Key Phase bit value as the newly current value, but we still keep the + * old keys around so that we can still process any packets which were still in + * flight when the key update was initiated. In the UPDATING state, a + * Key Phase bit value different to the current expected value is treated not as + * the initiation of another key update, but a reference to our old keys. + * + * Eventually we will be reasonably sure we are not going to receive any more + * packets with the old keys. At this point, we can transition to the COOLDOWN + * state. This transition occurs automatically after a certain amount of time; + * RFC 9001 recommends it be the PTO interval, which relates to our RTT to the + * peer. The duration also SHOULD NOT exceed three times the PTO to assist with + * maintaining PFS. + * + * In the COOLDOWN phase, the old keys have been securely erased and only one + * set of keys can be used: the current keys. If a packet is received with a Key + * Phase bit value different to the current Key Phase Bit value, this is treated + * as a request for a Key Update, but this request is ignored and the packet is + * treated as malformed. We do this to allow mitigation against malicious peers + * trying to initiate an excessive number of Key Updates. The timeout for the + * transition from UPDATING to COOLDOWN is recommended as adequate for + * this purpose in itself by the RFC, so the normal additional timeout value for + * the transition from COOLDOWN to normal is zero (immediate transition). + * + * A summary of each state: + * + * Epoch Exp KP Uses Keys KS0 KS1 If Non-Expected KP Bit + * ----- ------ --------- ------ ----- ---------------------- + * NORMAL 0 0 Keyset 0 Gen 0 Gen 1 → UPDATING + * UPDATING 1 1 Keyset 1 Gen 0 Gen 1 Use Keyset 0 + * COOLDOWN 1 1 Keyset 1 Erased Gen 1 Ignore Packet (*) + * + * NORMAL 1 1 Keyset 1 Gen 2 Gen 1 → UPDATING + * UPDATING 2 0 Keyset 0 Gen 2 Gen 1 Use Keyset 1 + * COOLDOWN 2 0 Keyset 0 Gen 2 Erased Ignore Packet (*) + * + * (*) Actually implemented by attempting to decrypt the packet with the + * wrong keys (which ultimately has the same outcome), as recommended + * by RFC 9001 to avoid creating timing channels. + * + * Note that the key material for the next key generation ("key epoch") is + * always kept in the NORMAL state (necessary to avoid side-channel attacks). + * This material is derived during the transition from COOLDOWN to NORMAL. + * + * Note that when a peer initiates a Key Update, we MUST also initiate a Key + * Update as per the RFC. The caller is responsible for detecting this condition + * and making the necessary calls to the TX side by detecting changes to the + * return value of ossl_qrx_get_key_epoch(). + * + * The above states (NORMAL, UPDATING, COOLDOWN) can themselves be + * considered substates of the PROVISIONED state. Providing a secret to the QRX + * for an EL transitions from UNPROVISIONED, the initial state, to PROVISIONED + * (NORMAL). Dropping key material for an EL transitions from whatever the + * current substate of the PROVISIONED state is to the DISCARDED state, which is + * the terminal state. + * + * Note that non-1RTT ELs cannot undergo key update, therefore a non-1RTT EL is + * always in the NORMAL substate if it is in the PROVISIONED state. + */ + +/* + * Return the current RX key epoch for the 1-RTT encryption level. This is + * initially zero and is incremented by one for every Key Update successfully + * signalled by the peer. If the 1-RTT EL has not yet been provisioned or has + * been discarded, returns UINT64_MAX. + * + * A necessary implication of this API is that the least significant bit of the + * returned value corresponds to the currently expected Key Phase bit, though + * callers are not anticipated to have any need of this information. + * + * It is not possible for the returned value to overflow, as a QUIC connection + * cannot support more than 2**62 packet numbers, and a connection must be + * terminated if this limit is reached. + * + * The caller should use this function to detect when the key epoch has changed + * and use it to initiate a key update on the TX side. + * + * The value returned by this function increments specifically at the transition + * from the NORMAL to the UPDATING state discussed above. + */ +uint64_t ossl_qrx_get_key_epoch(OSSL_QRX *qrx); + +/* + * Sets an optional callback which will be called when the key epoch changes. + * + * The callback is optional and can be unset by passing NULL for cb. + * cb_arg is an opaque value passed to cb. pn is the PN of the packet. + * Since key update is only supported for 1-RTT packets, the PN is always + * in the Application Data PN space. +*/ +typedef void (ossl_qrx_key_update_cb)(QUIC_PN pn, void *arg); + +int ossl_qrx_set_key_update_cb(OSSL_QRX *qrx, + ossl_qrx_key_update_cb *cb, void *cb_arg); + +/* + * Relates to the 1-RTT encryption level. The caller should call this after the + * UPDATING state is reached, after a timeout to be determined by the caller. + * + * This transitions from the UPDATING state to the COOLDOWN state (if + * still in the UPDATING state). If normal is 1, then transitions from + * the COOLDOWN state to the NORMAL state. Both transitions can be performed at + * once if desired. + * + * If in the normal state, or if in the COOLDOWN state and normal is 0, this is + * a no-op and returns 1. Returns 0 if the 1-RTT EL has not been provisioned or + * has been dropped. + * + * It is essential that the caller call this within a few PTO intervals of a key + * update occurring (as detected by the caller in a call to + * ossl_qrx_key_get_key_epoch()), as otherwise the peer will not be able to + * perform a Key Update ever again. + */ +int ossl_qrx_key_update_timeout(OSSL_QRX *qrx, int normal); + + +/* + * Key Expiration + * ============== + */ + +/* + * Returns the number of seemingly forged packets which have been received by + * the QRX. If this value reaches the value returned by + * ossl_qrx_get_max_epoch_forged_pkt_count() for a given EL, all further + * received encrypted packets for that EL will be discarded without processing. + * + * Note that the forged packet limit is for the connection lifetime, thus it is + * not reset by a key update. It is suggested that the caller terminate the + * connection a reasonable margin before the limit is reached. However, the + * exact limit imposed does vary by EL due to the possibility that different ELs + * use different AEADs. + */ +uint64_t ossl_qrx_get_cur_forged_pkt_count(OSSL_QRX *qrx); + +/* + * Returns the maximum number of forged packets which the record layer will + * permit to be verified using this QRX instance. + */ +uint64_t ossl_qrx_get_max_forged_pkt_count(OSSL_QRX *qrx, + uint32_t enc_level); + +# endif + +#endif diff --git a/include/internal/quic_record_tx.h b/include/internal/quic_record_tx.h new file mode 100644 index 0000000000..f3b798fea0 --- /dev/null +++ b/include/internal/quic_record_tx.h @@ -0,0 +1,383 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RECORD_TX_H +# define OSSL_QUIC_RECORD_TX_H + +# include +# include "internal/quic_wire_pkt.h" +# include "internal/quic_types.h" +# include "internal/quic_record_util.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Record Layer - TX + * ====================== + */ +typedef struct ossl_qtx_iovec_st { + const unsigned char *buf; + size_t buf_len; +} OSSL_QTX_IOVEC; + +typedef struct ossl_qtx_st OSSL_QTX; + +typedef int (*ossl_mutate_packet_cb)(const QUIC_PKT_HDR *hdrin, + const OSSL_QTX_IOVEC *iovecin, size_t numin, + QUIC_PKT_HDR **hdrout, + const OSSL_QTX_IOVEC **iovecout, + size_t *numout, + void *arg); + +typedef void (*ossl_finish_mutate_cb)(void *arg); + +typedef struct ossl_qtx_args_st { + OSSL_LIB_CTX *libctx; + const char *propq; + + /* BIO to transmit to. */ + BIO *bio; + + /* Maximum datagram payload length (MDPL) for TX purposes. */ + size_t mdpl; +} OSSL_QTX_ARGS; + +/* Instantiates a new QTX. */ +OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args); + +/* Frees the QTX. */ +void ossl_qtx_free(OSSL_QTX *qtx); + +/* Set mutator callbacks for test framework support */ +void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, void *mutatearg); + +/* Setters for the msg_callback and the msg_callback_arg */ +void ossl_qtx_set_msg_callback(OSSL_QTX *qtx, ossl_msg_cb msg_callback, + SSL *msg_callback_ssl); +void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg); + +/* + * Secret Management + * ----------------- + */ + +/* + * Provides a secret to the QTX, which arises due to an encryption level change. + * enc_level is a QUIC_ENC_LEVEL_* value. + * + * This function can be used to initialise the INITIAL encryption level, but you + * should not do so directly; see the utility function + * ossl_qrl_provide_initial_secret() instead, which can initialise the INITIAL + * encryption level of a QRX and QTX simultaneously without duplicating certain + * key derivation steps. + * + * You must call this function for a given EL before transmitting packets at + * that EL using this QTX, otherwise ossl_qtx_write_pkt will fail. + * + * suite_id is a QRL_SUITE_* value which determines the AEAD function used for + * the QTX. + * + * The secret passed is used directly to derive the "quic key", "quic iv" and + * "quic hp" values. + * + * secret_len is the length of the secret buffer in bytes. The buffer must be + * sized correctly to the chosen suite, else the function fails. + * + * This function can only be called once for a given EL, except for the INITIAL + * EL, as the INITIAL EL can need to be rekeyed if connection retry occurs. + * Subsequent calls for non-INITIAL ELs fail. Calls made after a corresponding + * call to ossl_qtx_discard_enc_level for a given EL also fail, including for + * the INITIAL EL. The secret for a non-INITIAL EL cannot be changed after it is + * set because QUIC has no facility for introducing additional key material + * after an EL is setup. (QUIC key updates generate new keys from existing key + * material and do not introduce new entropy into a connection's key material.) + * + * Returns 1 on success or 0 on failure. + */ +int ossl_qtx_provide_secret(OSSL_QTX *qtx, + uint32_t enc_level, + uint32_t suite_id, + EVP_MD *md, + const unsigned char *secret, + size_t secret_len); + +/* + * Informs the QTX that it can now discard key material for a given EL. The QTX + * will no longer be able to generate packets at that EL. This function is + * idempotent and succeeds if the EL has already been discarded. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_qtx_discard_enc_level(OSSL_QTX *qtx, uint32_t enc_level); + +/* Returns 1 if the given encryption level is provisioned. */ +int ossl_qtx_is_enc_level_provisioned(OSSL_QTX *qtx, uint32_t enc_level); + +/* + * Given the value ciphertext_len representing an encrypted packet payload + * length in bytes, determines how many plaintext bytes it will decrypt to. + * Returns 0 if the specified EL is not provisioned or ciphertext_len is too + * small. The result is written to *plaintext_len. + */ +int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, + size_t ciphertext_len, + size_t *plaintext_len); + +/* + * Given the value plaintext_len represented a plaintext packet payload length + * in bytes, determines how many ciphertext bytes it will encrypt to. The value + * output does not include packet headers. Returns 0 if the specified EL is not + * provisioned. The result is written to *ciphertext_len. + */ +int ossl_qtx_calculate_ciphertext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, + size_t plaintext_len, + size_t *ciphertext_len); + +uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id); + + +/* + * Packet Transmission + * ------------------- + */ + +typedef struct ossl_qtx_pkt_st { + /* Logical packet header to be serialized. */ + QUIC_PKT_HDR *hdr; + + /* + * iovecs expressing the logical packet payload buffer. Zero-length entries + * are permitted. + */ + const OSSL_QTX_IOVEC *iovec; + size_t num_iovec; + + /* Destination address. Will be passed through to the BIO if non-NULL. */ + const BIO_ADDR *peer; + + /* + * Local address (optional). Specify as non-NULL only if TX BIO + * has local address support enabled. + */ + const BIO_ADDR *local; + + /* + * Logical PN. Used for encryption. This will automatically be encoded to + * hdr->pn, which need not be initialized. + */ + QUIC_PN pn; + + /* Packet flags. Zero or more OSSL_QTX_PKT_FLAG_* values. */ + uint32_t flags; +} OSSL_QTX_PKT; + +/* + * More packets will be written which should be coalesced into a single + * datagram; do not send this packet yet. To use this, set this flag for all + * packets but the final packet in a datagram, then send the final packet + * without this flag set. + * + * This flag is not a guarantee and the QTX may transmit immediately anyway if + * it is not possible to fit any more packets in the current datagram. + * + * If the caller change its mind and needs to cause a packet queued with + * COALESCE after having passed it to this function but without writing another + * packet, it should call ossl_qtx_flush_pkt(). + */ +#define OSSL_QTX_PKT_FLAG_COALESCE (1U << 0) + +/* + * Writes a packet. + * + * *pkt need be valid only for the duration of the call to this function. + * + * pkt->hdr->data and pkt->hdr->len are unused. The payload buffer is specified + * via an array of OSSL_QTX_IOVEC structures. The API is designed to support + * single-copy transmission; data is copied from the iovecs as it is encrypted + * into an internal staging buffer for transmission. + * + * The function may modify and clobber pkt->hdr->data, pkt->hdr->len, + * pkt->hdr->key_phase and pkt->hdr->pn for its own internal use. No other + * fields of pkt or pkt->hdr will be modified. + * + * It is the callers responsibility to determine how long the PN field in the + * encoded packet should be by setting pkt->hdr->pn_len. This function takes + * care of the PN encoding. Set pkt->pn to the desired PN. + * + * Note that 1-RTT packets do not have a DCID Length field, therefore the DCID + * length must be understood contextually. This function assumes the caller + * knows what it is doing and will serialize a DCID of whatever length is given. + * It is the caller's responsibility to ensure it uses a consistent DCID length + * for communication with any given set of remote peers. + * + * The packet is queued regardless of whether it is able to be sent immediately. + * This enables packets to be batched and sent at once on systems which support + * system calls to send multiple datagrams in a single system call (see + * BIO_sendmmsg). To flush queued datagrams to the network, see + * ossl_qtx_flush_net(). + * + * Returns 1 on success or 0 on failure. + */ +int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt); + +/* + * Finish any incomplete datagrams for transmission which were flagged for + * coalescing. If there is no current coalescing datagram, this is a no-op. + */ +void ossl_qtx_finish_dgram(OSSL_QTX *qtx); + +/* + * (Attempt to) flush any datagrams which are queued for transmission. Note that + * this does not cancel coalescing; call ossl_qtx_finish_dgram() first if that + * is desired. The queue is drained into the OS's sockets as much as possible. + * To determine if there is still data to be sent after calling this function, + * use ossl_qtx_get_queue_len_bytes(). + * + * Returns one of the following values: + * + * QTX_FLUSH_NET_RES_OK + * Either no packets are currently queued for transmission, + * or at least one packet was successfully submitted. + * + * QTX_FLUSH_NET_RES_TRANSIENT_FAIL + * The underlying network write BIO indicated a transient error + * (e.g. buffers full). + * + * QTX_FLUSH_NET_RES_PERMANENT_FAIL + * Internal error (e.g. assertion or allocation error) + * or the underlying network write BIO indicated a non-transient + * error. + */ +#define QTX_FLUSH_NET_RES_OK 1 +#define QTX_FLUSH_NET_RES_TRANSIENT_FAIL (-1) +#define QTX_FLUSH_NET_RES_PERMANENT_FAIL (-2) + +int ossl_qtx_flush_net(OSSL_QTX *qtx); + +/* + * Diagnostic function. If there is any datagram pending transmission, pops it + * and writes the details of the datagram as they would have been passed to + * *msg. Returns 1, or 0 if there are no datagrams pending. For test use only. + */ +int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg); + +/* Returns number of datagrams which are fully-formed but not yet sent. */ +size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx); + +/* + * Returns number of payload bytes across all datagrams which are fully-formed + * but not yet sent. Does not count any incomplete coalescing datagram. + */ +size_t ossl_qtx_get_queue_len_bytes(OSSL_QTX *qtx); + +/* + * Returns number of bytes in the current coalescing datagram, or 0 if there is + * no current coalescing datagram. Returns 0 after a call to + * ossl_qtx_finish_dgram(). + */ +size_t ossl_qtx_get_cur_dgram_len_bytes(OSSL_QTX *qtx); + +/* + * Returns number of queued coalesced packets which have not been put into a + * datagram yet. If this is non-zero, ossl_qtx_flush_pkt() needs to be called. + */ +size_t ossl_qtx_get_unflushed_pkt_count(OSSL_QTX *qtx); + +/* + * Change the BIO being used by the QTX. May be NULL if actual transmission is + * not currently required. Does not up-ref the BIO; the caller is responsible + * for ensuring the lifetime of the BIO exceeds the lifetime of the QTX. + */ +void ossl_qtx_set_bio(OSSL_QTX *qtx, BIO *bio); + +/* Changes the MDPL. */ +int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl); + +/* Retrieves the current MDPL. */ +size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx); + + +/* + * Key Update + * ---------- + * + * For additional discussion of key update considerations, see QRX header file. + */ + +/* + * Triggers a key update. The key update will be started by inverting the Key + * Phase bit of the next packet transmitted; no key update occurs until the next + * packet is transmitted. Thus, this function should generally be called + * immediately before queueing the next packet. + * + * There are substantial requirements imposed by RFC 9001 on under what + * circumstances a key update can be initiated. The caller is responsible for + * meeting most of these requirements. For example, this function cannot be + * called too soon after a previous key update has occurred. Key updates also + * cannot be initiated until the 1-RTT encryption level is reached. + * + * As a sanity check, this function will fail and return 0 if the non-1RTT + * encryption levels have not yet been dropped. + * + * The caller may decide itself to initiate a key update, but it also MUST + * initiate a key update where it detects that the peer has initiated a key + * update. The caller is responsible for initiating a TX key update by calling + * this function in this circumstance; thus, the caller is responsible for + * coupling the RX and TX QUIC record layers in this way. + */ +int ossl_qtx_trigger_key_update(OSSL_QTX *qtx); + + +/* + * Key Expiration + * -------------- + */ + +/* + * Returns the number of packets which have been encrypted for transmission with + * the current set of TX keys (the current "TX key epoch"). Reset to zero after + * a key update and incremented for each packet queued. If enc_level is not + * valid or relates to an EL which is not currently available, returns + * UINT64_MAX. + */ +uint64_t ossl_qtx_get_cur_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level); + +/* + * Returns the maximum number of packets which the record layer will permit to + * be encrypted using the current set of TX keys. If this limit is reached (that + * is, if the counter returned by ossl_qrx_tx_get_cur_epoch_pkt_count() reaches + * this value), as a safety measure, the QTX will not permit any further packets + * to be queued. All calls to ossl_qrx_write_pkt that try to send packets of a + * kind which need to be encrypted will fail. It is not possible to recover from + * this condition and the QTX must then be destroyed; therefore, callers should + * ensure they always trigger a key update well in advance of reaching this + * limit. + * + * The value returned by this function is based on the ciphersuite configured + * for the given encryption level. If keys have not been provisioned for the + * specified enc_level or the enc_level argument is invalid, this function + * returns UINT64_MAX, which is not a valid value. Note that it is not possible + * to perform a key update at any encryption level other than 1-RTT, therefore + * if this limit is reached at earlier encryption levels (which should not be + * possible) the connection must be terminated. Since this condition precludes + * the transmission of further packets, the only possible signalling of such an + * error condition to a peer is a Stateless Reset packet. + */ +uint64_t ossl_qtx_get_max_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level); + +/* + * Get the 1-RTT EL key epoch number for the QTX. This is intended for + * diagnostic purposes. Returns 0 if 1-RTT EL is not provisioned yet. + */ +uint64_t ossl_qtx_get_key_epoch(OSSL_QTX *qtx); + +# endif + +#endif diff --git a/include/internal/quic_record_util.h b/include/internal/quic_record_util.h new file mode 100644 index 0000000000..97e630d924 --- /dev/null +++ b/include/internal/quic_record_util.h @@ -0,0 +1,116 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RECORD_UTIL_H +# define OSSL_QUIC_RECORD_UTIL_H + +# include +# include "internal/quic_types.h" + +# ifndef OPENSSL_NO_QUIC + +struct ossl_qrx_st; +struct ossl_qtx_st; + +/* + * QUIC Key Derivation Utilities + * ============================= + */ + +/* HKDF-Extract(salt, IKM) (RFC 5869) */ +int ossl_quic_hkdf_extract(OSSL_LIB_CTX *libctx, + const char *propq, + const EVP_MD *md, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *out, size_t out_len); + +/* + * A QUIC client sends its first INITIAL packet with a random DCID, which + * is used to compute the secrets used for INITIAL packet encryption in both + * directions (both client-to-server and server-to-client). + * + * This function performs the necessary DCID-based key derivation, and then + * provides the derived key material for the INITIAL encryption level to a QRX + * instance, a QTX instance, or both. + * + * This function derives the necessary key material and then: + * - if qrx is non-NULL, provides the appropriate secret to it; + * - if qtx is non-NULL, provides the appropriate secret to it. + * + * If both qrx and qtx are NULL, this is a no-op. This function is equivalent to + * making the appropriate calls to ossl_qrx_provide_secret() and + * ossl_qtx_provide_secret(). + * + * It is possible to use a QRX or QTX without ever calling this, for example if + * there is no desire to handle INITIAL packets (e.g. if a QRX/QTX is + * instantiated to succeed a previous QRX/QTX and handle a connection which is + * already established). However in this case you should make sure you call + * ossl_qrx_discard_enc_level(); see the header for that function for more + * details. Calling ossl_qtx_discard_enc_level() is not essential but could + * protect against programming errors. + * + * Returns 1 on success or 0 on error. + */ +int ossl_quic_provide_initial_secret(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_CONN_ID *dst_conn_id, + int is_server, + struct ossl_qrx_st *qrx, + struct ossl_qtx_st *qtx); + +/* + * QUIC Record Layer Ciphersuite Info + * ================================== + */ + +/* Available QUIC Record Layer (QRL) ciphersuites. */ +# define QRL_SUITE_AES128GCM 1 /* SHA256 */ +# define QRL_SUITE_AES256GCM 2 /* SHA384 */ +# define QRL_SUITE_CHACHA20POLY1305 3 /* SHA256 */ + +/* Returns cipher name in bytes or NULL if suite ID is invalid. */ +const char *ossl_qrl_get_suite_cipher_name(uint32_t suite_id); + +/* Returns hash function name in bytes or NULL if suite ID is invalid. */ +const char *ossl_qrl_get_suite_md_name(uint32_t suite_id); + +/* Returns secret length in bytes or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_secret_len(uint32_t suite_id); + +/* Returns key length in bytes or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_cipher_key_len(uint32_t suite_id); + +/* Returns IV length in bytes or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_cipher_iv_len(uint32_t suite_id); + +/* Returns AEAD auth tag length in bytes or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id); + +/* Returns a QUIC_HDR_PROT_CIPHER_* value or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_hdr_prot_cipher_id(uint32_t suite_id); + +/* Returns header protection key length in bytes or 0 if suite ID is invalid. */ +uint32_t ossl_qrl_get_suite_hdr_prot_key_len(uint32_t suite_id); + +/* + * Returns maximum number of packets which may be safely encrypted with a suite + * or 0 if suite ID is invalid. + */ +uint64_t ossl_qrl_get_suite_max_pkt(uint32_t suite_id); + +/* + * Returns maximum number of RX'd packets which may safely fail AEAD decryption + * for a given suite or 0 if suite ID is invalid. + */ +uint64_t ossl_qrl_get_suite_max_forged_pkt(uint32_t suite_id); + +# endif + +#endif diff --git a/include/internal/quic_rx_depack.h b/include/internal/quic_rx_depack.h new file mode 100644 index 0000000000..c90964a7c1 --- /dev/null +++ b/include/internal/quic_rx_depack.h @@ -0,0 +1,21 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RX_DEPACK_H +# define OSSL_QUIC_RX_DEPACK_H + +# include "internal/quic_channel.h" + +# ifndef OPENSSL_NO_QUIC + +int ossl_quic_handle_frames(QUIC_CHANNEL *qc, OSSL_QRX_PKT *qpacket); + +# endif + +#endif diff --git a/include/internal/quic_sf_list.h b/include/internal/quic_sf_list.h new file mode 100644 index 0000000000..8ed1dcb137 --- /dev/null +++ b/include/internal/quic_sf_list.h @@ -0,0 +1,151 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_SF_LIST_H +# define OSSL_QUIC_SF_LIST_H + +#include "internal/common.h" +#include "internal/uint_set.h" +#include "internal/quic_record_rx.h" + +/* + * Stream frame list + * ================= + * + * This data structure supports similar operations as uint64 set but + * it has slightly different invariants and also carries data associated with + * the ranges in the list. + * + * Operations: + * Insert frame (optimized insertion at the beginning and at the end). + * Iterated peek into the frame(s) from the beginning. + * Dropping frames from the beginning up to an offset (exclusive). + * + * Invariant: The frames in the list are sorted by the start and end bounds. + * Invariant: There are no fully overlapping frames or frames that would + * be fully encompassed by another frame in the list. + * Invariant: No frame has start > end. + * Invariant: The range start is inclusive the end is exclusive to be + * able to mark an empty frame. + * Invariant: The offset never points further than into the first frame. + */ +# ifndef OPENSSL_NO_QUIC + +typedef struct stream_frame_st STREAM_FRAME; + +typedef struct sframe_list_st { + STREAM_FRAME *head, *tail; + /* Is the tail frame final. */ + unsigned int fin; + /* Number of stream frames in the list. */ + size_t num_frames; + /* Offset of data not yet dropped */ + uint64_t offset; + /* Is head locked ? */ + int head_locked; + /* Cleanse data on release? */ + int cleanse; +} SFRAME_LIST; + +/* + * Initializes the stream frame list fl. + */ +void ossl_sframe_list_init(SFRAME_LIST *fl); + +/* + * Destroys the stream frame list fl releasing any data + * still present inside it. + */ +void ossl_sframe_list_destroy(SFRAME_LIST *fl); + +/* + * Insert a stream frame data into the list. + * The data covers an offset range (range.start is inclusive, + * range.end is exclusive). + * fin should be set if this is the final frame of the stream. + * Returns an error if a frame cannot be inserted - due to + * STREAM_FRAME allocation error, or in case of erroneous + * fin flag (this is an ossl_assert() check so a caller must + * check it on its own too). + */ +int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range, + OSSL_QRX_PKT *pkt, + const unsigned char *data, int fin); + +/* + * Iterator to peek at the contiguous frames at the beginning + * of the frame list fl. + * The *data covers an offset range (range.start is inclusive, + * range.end is exclusive). + * *fin is set if this is the final frame of the stream. + * Opaque iterator *iter can be used to peek at the subsequent + * frame if there is any without any gap before it. + * Returns 1 on success. + * Returns 0 if there is no further contiguous frame. In that + * case *fin is set, if the end of the stream is reached. + */ +int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter, + UINT_RANGE *range, const unsigned char **data, + int *fin); + +/* + * Drop all frames up to the offset limit. + * Also unlocks the head frame if locked. + * Returns 1 on success. + * Returns 0 when trying to drop frames at offsets that were not + * received yet. (ossl_assert() is used to check, so this is an invalid call.) + */ +int ossl_sframe_list_drop_frames(SFRAME_LIST *fl, uint64_t limit); + +/* + * Locks and returns the head frame of fl if it is readable - read offset is + * at the beginning or middle of the frame. + * range is set to encompass the not yet read part of the head frame, + * data pointer is set to appropriate offset within the frame if the read + * offset points in the middle of the frame, + * fin is set to 1 if the head frame is also the tail frame. + * Returns 1 on success, 0 if there is no readable data or the head + * frame is already locked. + */ +int ossl_sframe_list_lock_head(SFRAME_LIST *fl, UINT_RANGE *range, + const unsigned char **data, + int *fin); + +/* + * Just returns whether the head frame is locked by previous + * ossl_sframe_list_lock_head() call. + */ +int ossl_sframe_list_is_head_locked(SFRAME_LIST *fl); + +/* + * Callback function type to write stream frame data to some + * side storage before the packet containing the frame data + * is released. + * It should return 1 on success or 0 if there is not enough + * space available in the side storage. + */ +typedef int (sframe_list_write_at_cb)(uint64_t logical_offset, + const unsigned char *buf, + size_t buf_len, + void *cb_arg); + +/* + * Move the frame data in all the stream frames in the list fl + * from the packets to the side storage using the write_at_cb + * callback. + * Returns 1 if all the calls to the callback return 1. + * If the callback returns 0, the function stops processing further + * frames and returns 0. + */ +int ossl_sframe_list_move_data(SFRAME_LIST *fl, + sframe_list_write_at_cb *write_at_cb, + void *cb_arg); +# endif + +#endif diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h new file mode 100644 index 0000000000..52d4527c81 --- /dev/null +++ b/include/internal/quic_ssl.h @@ -0,0 +1,132 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_SSL_H +# define OSSL_QUIC_SSL_H + +# include +# include +# include "internal/quic_record_rx.h" /* OSSL_QRX */ +# include "internal/quic_ackm.h" /* OSSL_ACKM */ +# include "internal/quic_channel.h" /* QUIC_CHANNEL */ + +# ifndef OPENSSL_NO_QUIC + +__owur SSL *ossl_quic_new(SSL_CTX *ctx); +__owur int ossl_quic_init(SSL *s); +void ossl_quic_deinit(SSL *s); +void ossl_quic_free(SSL *s); +int ossl_quic_reset(SSL *s); +int ossl_quic_clear(SSL *s); +__owur int ossl_quic_accept(SSL *s); +__owur int ossl_quic_connect(SSL *s); +__owur int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *readbytes); +__owur int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *readbytes); +__owur int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written); +__owur long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg); +__owur long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +__owur long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); +__owur long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)); +__owur size_t ossl_quic_pending(const SSL *s); +__owur int ossl_quic_key_update(SSL *s, int update_type); +__owur int ossl_quic_get_key_update_type(const SSL *s); +__owur const SSL_CIPHER *ossl_quic_get_cipher_by_char(const unsigned char *p); +__owur int ossl_quic_num_ciphers(void); +__owur const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u); +int ossl_quic_renegotiate_check(SSL *ssl, int initok); + +typedef struct quic_conn_st QUIC_CONNECTION; +typedef struct quic_xso_st QUIC_XSO; + +int ossl_quic_do_handshake(SSL *s); +void ossl_quic_set_connect_state(SSL *s); +void ossl_quic_set_accept_state(SSL *s); + +__owur int ossl_quic_has_pending(const SSL *s); +__owur int ossl_quic_handle_events(SSL *s); +__owur int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, + int *is_infinite); +OSSL_TIME ossl_quic_get_event_deadline(SSL *s); +__owur int ossl_quic_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *d); +__owur int ossl_quic_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *d); +__owur int ossl_quic_get_net_read_desired(SSL *s); +__owur int ossl_quic_get_net_write_desired(SSL *s); +__owur int ossl_quic_get_error(const SSL *s, int i); +__owur int ossl_quic_want(const SSL *s); +__owur int ossl_quic_conn_get_blocking_mode(const SSL *s); +__owur int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking); +__owur int ossl_quic_conn_shutdown(SSL *s, uint64_t flags, + const SSL_SHUTDOWN_EX_ARGS *args, + size_t args_len); +__owur int ossl_quic_conn_stream_conclude(SSL *s); +void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_wbio); +void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio); +BIO *ossl_quic_conn_get_net_rbio(const SSL *s); +BIO *ossl_quic_conn_get_net_wbio(const SSL *s); +__owur int ossl_quic_conn_set_initial_peer_addr(SSL *s, + const BIO_ADDR *peer_addr); +__owur SSL *ossl_quic_conn_stream_new(SSL *s, uint64_t flags); +__owur SSL *ossl_quic_get0_connection(SSL *s); +__owur int ossl_quic_get_stream_type(SSL *s); +__owur uint64_t ossl_quic_get_stream_id(SSL *s); +__owur int ossl_quic_is_stream_local(SSL *s); +__owur int ossl_quic_set_default_stream_mode(SSL *s, uint32_t mode); +__owur SSL *ossl_quic_detach_stream(SSL *s); +__owur int ossl_quic_attach_stream(SSL *conn, SSL *stream); +__owur int ossl_quic_set_incoming_stream_policy(SSL *s, int policy, + uint64_t aec); +__owur SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags); +__owur size_t ossl_quic_get_accept_stream_queue_len(SSL *s); + +__owur int ossl_quic_stream_reset(SSL *ssl, + const SSL_STREAM_RESET_ARGS *args, + size_t args_len); + +__owur int ossl_quic_get_stream_read_state(SSL *ssl); +__owur int ossl_quic_get_stream_write_state(SSL *ssl); +__owur int ossl_quic_get_stream_read_error_code(SSL *ssl, + uint64_t *app_error_code); +__owur int ossl_quic_get_stream_write_error_code(SSL *ssl, + uint64_t *app_error_code); +__owur int ossl_quic_get_conn_close_info(SSL *ssl, + SSL_CONN_CLOSE_INFO *info, + size_t info_len); + +uint64_t ossl_quic_set_options(SSL *s, uint64_t opts); +uint64_t ossl_quic_clear_options(SSL *s, uint64_t opts); +uint64_t ossl_quic_get_options(const SSL *s); + +/* Modifies write buffer size for a stream. */ +__owur int ossl_quic_set_write_buffer_size(SSL *s, size_t size); + +/* + * Used to override ossl_time_now() for debug purposes. While this may be + * overridden at any time, expect strange results if you change it after + * connecting. + */ +int ossl_quic_conn_set_override_now_cb(SSL *s, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); + +/* + * Condvar waiting in the assist thread doesn't support time faking as it relies + * on the OS's notion of time, thus this is used in test code to force a + * spurious wakeup instead. + */ +void ossl_quic_conn_force_assist_thread_wake(SSL *s); + +/* For use by tests only. */ +QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s); + +int ossl_quic_has_pending(const SSL *s); +int ossl_quic_get_shutdown(const SSL *s); + +# endif + +#endif diff --git a/include/internal/quic_statm.h b/include/internal/quic_statm.h new file mode 100644 index 0000000000..5b33551b06 --- /dev/null +++ b/include/internal/quic_statm.h @@ -0,0 +1,40 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_STATS_H +# define OSSL_QUIC_STATS_H + +# include +# include "internal/time.h" + +# ifndef OPENSSL_NO_QUIC + +typedef struct ossl_statm_st { + OSSL_TIME smoothed_rtt, latest_rtt, min_rtt, rtt_variance; + char have_first_sample; +} OSSL_STATM; + +typedef struct ossl_rtt_info_st { + /* As defined in RFC 9002. */ + OSSL_TIME smoothed_rtt, latest_rtt, rtt_variance, min_rtt; +} OSSL_RTT_INFO; + +int ossl_statm_init(OSSL_STATM *statm); + +void ossl_statm_destroy(OSSL_STATM *statm); + +void ossl_statm_get_rtt_info(OSSL_STATM *statm, OSSL_RTT_INFO *rtt_info); + +void ossl_statm_update_rtt(OSSL_STATM *statm, + OSSL_TIME ack_delay, + OSSL_TIME override_latest_rtt); + +# endif + +#endif diff --git a/include/internal/quic_stream.h b/include/internal/quic_stream.h new file mode 100644 index 0000000000..0da8febd5a --- /dev/null +++ b/include/internal/quic_stream.h @@ -0,0 +1,429 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_STREAM_H +# define OSSL_INTERNAL_QUIC_STREAM_H +# pragma once + +#include "internal/e_os.h" +#include "internal/time.h" +#include "internal/quic_types.h" +#include "internal/quic_wire.h" +#include "internal/quic_record_tx.h" +#include "internal/quic_record_rx.h" +#include "internal/quic_fc.h" +#include "internal/quic_statm.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Send Stream + * ================ + * + * The QUIC Send Stream Manager (QUIC_SSTREAM) is responsible for: + * + * - accepting octet strings of stream data; + * + * - generating corresponding STREAM frames; + * + * - receiving notifications of lost frames, in order to generate new STREAM + * frames for the lost data; + * + * - receiving notifications of acknowledged frames, in order to internally + * reuse memory used to store acknowledged stream data; + * + * - informing the caller of how much more stream data it can accept into + * its internal buffers, so as to ensure that the amount of unacknowledged + * data which can be written to a stream is not infinite and to allow the + * caller to manifest backpressure conditions to the user. + * + * The QUIC_SSTREAM is instantiated once for every stream with a send component + * (i.e., for a unidirectional send stream or for the send component of a + * bidirectional stream). + * + * Note: The terms 'TX' and 'RX' are used when referring to frames, packets and + * datagrams. The terms 'send' and 'receive' are used when referring to the + * stream abstraction. Applications send; we transmit. + */ +typedef struct quic_sstream_st QUIC_SSTREAM; + +/* + * Instantiates a new QUIC_SSTREAM. init_buf_size specifies the initial size of + * the stream data buffer in bytes, which must be positive. + */ +QUIC_SSTREAM *ossl_quic_sstream_new(size_t init_buf_size); + +/* + * Frees a QUIC_SSTREAM and associated stream data storage. + * + * Any iovecs returned by ossl_quic_sstream_get_stream_frame cease to be valid after + * calling this function. + */ +void ossl_quic_sstream_free(QUIC_SSTREAM *qss); + +/* + * (For TX packetizer use.) Retrieves information about application stream data + * which is ready for transmission. + * + * *hdr is filled with the logical offset, maximum possible length of stream + * data which can be transmitted, and a pointer to the stream data to be + * transmitted. is_fin is set to 1 if hdr->offset + hdr->len is the final size + * of the stream and 0 otherwise. hdr->stream_id is not set; the caller must set + * it. + * + * The caller is not obligated to send all of the data. If the caller does not + * send all of the data, the caller must reduce hdr->len before serializing the + * header structure and must ensure that hdr->is_fin is cleared. + * + * hdr->has_explicit_len is always set. It is the caller's responsibility to + * clear this if it wants to use the optimization of omitting the length field, + * as only the caller can know when this optimization can be performed. + * + * *num_iov must be set to the size of the iov array at call time. When this + * function returns successfully, it is updated to the number of iov entries + * which have been written. + * + * The stream data may be split across up to two IOVs due to internal ring + * buffer organisation. The sum of the lengths of the IOVs and the value written + * to hdr->len will always match. If the caller decides to send less than + * hdr->len of stream data, it must adjust the IOVs accordingly. This may be + * done by updating hdr->len and then calling the utility function + * ossl_quic_sstream_adjust_iov(). + * + * After committing one or more bytes returned by ossl_quic_sstream_get_stream_frame to a + * packet, call ossl_quic_sstream_mark_transmitted with the inclusive range of logical + * byte numbers of the transmitted bytes (i.e., hdr->offset, hdr->offset + + * hdr->len - 1). If you do not call ossl_quic_sstream_mark_transmitted, the next call to + * ossl_quic_sstream_get_stream_frame will return the same data (or potentially the same + * and more, if more data has been appended by the application). + * + * It is the caller's responsibility to clamp the length of data which this + * function indicates is available according to other concerns, such as + * stream-level flow control, connection-level flow control, or the applicable + * maximum datagram payload length (MDPL) for a packet under construction. + * + * The skip argument can usually be given as zero. If it is non-zero, this + * function outputs a range which would be output if it were called again after + * calling ossl_quic_sstream_mark_transmitted() with the returned range, repeated 'skip' + * times, and so on. This may be useful for callers which wish to enumerate + * available stream frames and batch their calls to ossl_quic_sstream_mark_transmitted at + * a later time. + * + * On success, this function will never write *num_iov with a value other than + * 0, 1 or 2. A *num_iov value of 0 can only occurs when hdr->is_fin is set (for + * example, when a stream is closed after all existing data has been sent, and + * without sending any more data); otherwise the function returns 0 as there is + * nothing useful to report. + * + * Returns 1 on success and 0 if there is no stream data available for + * transmission, or on other error (such as if the caller provides fewer + * than two IOVs.) + */ +int ossl_quic_sstream_get_stream_frame(QUIC_SSTREAM *qss, + size_t skip, + OSSL_QUIC_FRAME_STREAM *hdr, + OSSL_QTX_IOVEC *iov, + size_t *num_iov); + +/* + * Returns 1 if there is data pending transmission. Equivalent to calling + * ossl_quic_sstream_get_stream_frame and seeing if it succeeds. + */ +int ossl_quic_sstream_has_pending(QUIC_SSTREAM *qss); + +/* + * Returns the current size of the stream; i.e., the number of bytes which have + * been appended to the stream so far. + */ +uint64_t ossl_quic_sstream_get_cur_size(QUIC_SSTREAM *qss); + +/* + * (For TX packetizer use.) Marks a logical range of the send stream as having + * been transmitted. + * + * 0 denotes the first byte ever sent on the stream. The start and end values + * are both inclusive, therefore all calls to this function always mark at least + * one byte as being transmitted; if no bytes have been transmitted, do not call + * this function. + * + * If the STREAM frame sent had the FIN bit set, you must also call + * ossl_quic_sstream_mark_transmitted_fin() after calling this function. + * + * If you sent a zero-length STREAM frame with the FIN bit set, you need only + * call ossl_quic_sstream_mark_transmitted_fin() and must not call this function. + * + * Returns 1 on success and 0 on error (e.g. if end < start). + */ +int ossl_quic_sstream_mark_transmitted(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end); + +/* + * (For TX packetizer use.) Marks a STREAM frame with the FIN bit set as having + * been transmitted. final_size is the final size of the stream (i.e., the value + * offset + len of the transmitted STREAM frame). + * + * This function fails returning 0 if ossl_quic_sstream_fin() has not been called or if + * final_size is not correct. The final_size argument is not strictly needed by + * the QUIC_SSTREAM but is required as a sanity check. + */ +int ossl_quic_sstream_mark_transmitted_fin(QUIC_SSTREAM *qss, + uint64_t final_size); + +/* + * (RX/ACKM use.) Marks a logical range of the send stream as having been lost. + * The send stream will return the lost data for retransmission on a future call + * to ossl_quic_sstream_get_stream_frame. The start and end values denote logical byte + * numbers and are inclusive. + * + * If the lost frame had the FIN bit set, you must also call + * ossl_quic_sstream_mark_lost_fin() after calling this function. + * + * Returns 1 on success and 0 on error (e.g. if end < start). + */ +int ossl_quic_sstream_mark_lost(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end); + +/* + * (RX/ACKM use.) Informs the QUIC_SSTREAM that a STREAM frame with the FIN bit + * set was lost. + * + * Returns 1 on success and 0 on error. + */ +int ossl_quic_sstream_mark_lost_fin(QUIC_SSTREAM *qss); + +/* + * (RX/ACKM use.) Marks a logical range of the send stream as having been + * acknowledged, meaning that the storage for the data in that range of the + * stream can be now recycled and neither that logical range of the stream nor + * any subset of it can be retransmitted again. The start and end values are + * inclusive. + * + * If the acknowledged frame had the FIN bit set, you must also call + * ossl_quic_sstream_mark_acked_fin() after calling this function. + * + * Returns 1 on success and 0 on error (e.g. if end < start). + */ +int ossl_quic_sstream_mark_acked(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end); + +/* + * (RX/ACKM use.) Informs the QUIC_SSTREAM that a STREAM frame with the FIN bit + * set was acknowledged. + * + * Returns 1 on success and 0 on error. + */ +int ossl_quic_sstream_mark_acked_fin(QUIC_SSTREAM *qss); + +/* + * (Front end use.) Appends user data to the stream. The data is copied into the + * stream. The amount of data consumed from buf is written to *consumed on + * success (short writes are possible). The amount of data which can be written + * can be determined in advance by calling the ossl_quic_sstream_get_buffer_avail() + * function; data is copied into an internal ring buffer of finite size. + * + * If the buffer is full, this should be materialised as a backpressure + * condition by the front end. This is not considered a failure condition; + * *consumed is written as 0 and the function returns 1. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_sstream_append(QUIC_SSTREAM *qss, + const unsigned char *buf, + size_t buf_len, + size_t *consumed); + +/* + * Marks a stream as finished. ossl_quic_sstream_append() may not be called anymore + * after calling this. + */ +void ossl_quic_sstream_fin(QUIC_SSTREAM *qss); + +/* + * If the stream has had ossl_quic_sstream_fin() called, returns 1 and writes + * the final size to *final_size. Otherwise, returns 0. + */ +int ossl_quic_sstream_get_final_size(QUIC_SSTREAM *qss, uint64_t *final_size); + +/* + * Returns 1 iff all bytes (and any FIN, if any) which have been appended to the + * QUIC_SSTREAM so far, and any FIN (if any), have been both sent and acked. + */ +int ossl_quic_sstream_is_totally_acked(QUIC_SSTREAM *qss); + +/* + * Resizes the internal ring buffer. All stream data is preserved safely. + * + * This can be used to expand or contract the ring buffer, but not to contract + * the ring buffer below the amount of stream data currently stored in it. + * Returns 1 on success and 0 on failure. + * + * IMPORTANT: Any buffers referenced by iovecs output by + * ossl_quic_sstream_get_stream_frame() cease to be valid after calling this function. + */ +int ossl_quic_sstream_set_buffer_size(QUIC_SSTREAM *qss, size_t num_bytes); + +/* + * Gets the internal ring buffer size in bytes. + */ +size_t ossl_quic_sstream_get_buffer_size(QUIC_SSTREAM *qss); + +/* + * Gets the number of bytes used in the internal ring buffer. + */ +size_t ossl_quic_sstream_get_buffer_used(QUIC_SSTREAM *qss); + +/* + * Gets the number of bytes free in the internal ring buffer. + */ +size_t ossl_quic_sstream_get_buffer_avail(QUIC_SSTREAM *qss); + +/* + * Utility function to ensure the length of an array of iovecs matches the + * length given as len. Trailing iovecs have their length values reduced or set + * to 0 as necessary. + */ +void ossl_quic_sstream_adjust_iov(size_t len, + OSSL_QTX_IOVEC *iov, + size_t num_iov); + +/* + * Sets flag to cleanse the buffered data when it is acked. + */ +void ossl_quic_sstream_set_cleanse(QUIC_SSTREAM *qss, int cleanse); + +/* + * QUIC Receive Stream Manager + * =========================== + * + * The QUIC Receive Stream Manager (QUIC_RSTREAM) is responsible for + * storing the received stream data frames until the application + * is able to read the data. + * + * The QUIC_RSTREAM is instantiated once for every stream that can receive data. + * (i.e., for a unidirectional receiving stream or for the receiving component + * of a bidirectional stream). + */ +typedef struct quic_rstream_st QUIC_RSTREAM; + +/* + * Create a new instance of QUIC_RSTREAM with pointers to the flow + * controller and statistics module. They can be NULL for unit testing. + * If they are non-NULL, the `rxfc` is called when receive stream data + * is read by application. `statm` is queried for current rtt. + * `rbuf_size` is the initial size of the ring buffer to be used + * when ossl_quic_rstream_move_to_rbuf() is called. + */ +QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc, + OSSL_STATM *statm, size_t rbuf_size); + +/* + * Frees a QUIC_RSTREAM and any associated storage. + */ +void ossl_quic_rstream_free(QUIC_RSTREAM *qrs); + +/* + * Adds received stream frame data to `qrs`. The `pkt_wrap` refcount is + * incremented if the `data` is queued directly without copying. + * It can be NULL for unit-testing purposes, i.e. if `data` is static or + * never released before calling ossl_quic_rstream_free(). + * The `offset` is the absolute offset of the data in the stream. + * `data_len` can be 0 - can be useful for indicating `fin` for empty stream. + * Or to indicate `fin` without any further data added to the stream. + */ + +int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt, + uint64_t offset, + const unsigned char *data, uint64_t data_len, + int fin); + +/* + * Copies the data from the stream storage to buffer `buf` of size `size`. + * `readbytes` is set to the number of bytes actually copied. + * `fin` is set to 1 if all the data from the stream were read so the + * stream is finished. It is set to 0 otherwise. + */ +int ossl_quic_rstream_read(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size, + size_t *readbytes, int *fin); + +/* + * Peeks at the data in the stream storage. It copies them to buffer `buf` + * of size `size` and sets `readbytes` to the number of bytes actually copied. + * `fin` is set to 1 if the copied data reach end of the stream. + * It is set to 0 otherwise. + */ +int ossl_quic_rstream_peek(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size, + size_t *readbytes, int *fin); + +/* + * Returns the size of the data available for reading. `fin` is set to 1 if + * after reading all the available data the stream will be finished, + * set to 0 otherwise. + */ +int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin); + +/* + * Sets *record to the beginning of the first readable stream data chunk and + * *reclen to the size of the chunk. *fin is set to 1 if the end of the + * chunk is the last of the stream data chunks. + * If there is no record available *record is set to NULL and *rec_len to 0; + * ossl_quic_rstream_release_record() should not be called in that case. + * Returns 1 on success (including calls if no record is available, or + * after end of the stream - in that case *fin will be set to 1 and + * *rec_len to 0), 0 on error. + * It is an error to call ossl_quic_rstream_get_record() multiple times + * without calling ossl_quic_rstream_release_record() in between. + */ +int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs, + const unsigned char **record, size_t *rec_len, + int *fin); + +/* + * Releases (possibly partially) the record returned by + * previous ossl_quic_rstream_get_record() call. + * read_len between previously returned *rec_len and SIZE_MAX indicates + * release of the whole record. Otherwise only part of the record is + * released. The remaining part of the record is unlocked, another + * call to ossl_quic_rstream_get_record() is needed to obtain further + * stream data. + * Returns 1 on success, 0 on error. + * It is an error to call ossl_quic_rstream_release_record() multiple + * times without calling ossl_quic_rstream_get_record() in between. + */ +int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len); + +/* + * Moves received frame data from decrypted packets to ring buffer. + * This should be called when there are too many decrypted packets allocated. + * Returns 1 on success, 0 when it was not possible to release all + * referenced packets due to an insufficient size of the ring buffer. + * Exception is the packet from the record returned previously by + * ossl_quic_rstream_get_record() - that one will be always skipped. + */ +int ossl_quic_rstream_move_to_rbuf(QUIC_RSTREAM *qrs); + +/* + * Resizes the internal ring buffer to a new `rbuf_size` size. + * Returns 1 on success, 0 on error. + * Possible error conditions are an allocation failure, trying to resize + * the ring buffer when ossl_quic_rstream_get_record() was called and + * not yet released, or trying to resize the ring buffer to a smaller size + * than currently occupied. + */ +int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size); + +/* + * Sets flag to cleanse the buffered data when user reads it. + */ +void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse); +# endif + +#endif diff --git a/include/internal/quic_stream_map.h b/include/internal/quic_stream_map.h new file mode 100644 index 0000000000..ae7490619b --- /dev/null +++ b/include/internal/quic_stream_map.h @@ -0,0 +1,878 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_STREAM_MAP_H +# define OSSL_INTERNAL_QUIC_STREAM_MAP_H +# pragma once + +# include "internal/e_os.h" +# include "internal/time.h" +# include "internal/common.h" +# include "internal/quic_types.h" +# include "internal/quic_stream.h" +# include "internal/quic_fc.h" +# include + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Stream + * =========== + * + * Logical QUIC stream composing all relevant send and receive components. + */ +typedef struct quic_stream_st QUIC_STREAM; + +typedef struct quic_stream_list_node_st QUIC_STREAM_LIST_NODE; + +struct quic_stream_list_node_st { + QUIC_STREAM_LIST_NODE *prev, *next; +}; + +/* + * QUIC Send Stream States + * ----------------------- + * + * These correspond to the states defined in RFC 9000 s. 3.1, with the + * exception of the NONE state which represents the absence of a send stream + * part. + * + * Invariants in each state are noted in comments below. In particular, once all + * data has been acknowledged received, or we have reset the stream, we don't + * need to keep the QUIC_SSTREAM and data buffers around. Of course, we also + * don't have a QUIC_SSTREAM on a receive-only stream. + */ +#define QUIC_SSTREAM_STATE_NONE 0 /* --- sstream == NULL */ +#define QUIC_SSTREAM_STATE_READY 1 /* \ */ +#define QUIC_SSTREAM_STATE_SEND 2 /* |-- sstream != NULL */ +#define QUIC_SSTREAM_STATE_DATA_SENT 3 /* / */ +#define QUIC_SSTREAM_STATE_DATA_RECVD 4 /* \ */ +#define QUIC_SSTREAM_STATE_RESET_SENT 5 /* |-- sstream == NULL */ +#define QUIC_SSTREAM_STATE_RESET_RECVD 6 /* / */ + +/* + * QUIC Receive Stream States + * -------------------------- + * + * These correspond to the states defined in RFC 9000 s. 3.2, with the exception + * of the NONE state which represents the absence of a receive stream part. + * + * Invariants in each state are noted in comments below. In particular, once all + * data has been read by the application, we don't need to keep the QUIC_RSTREAM + * and data buffers around. If the receive part is instead reset before it is + * finished, we also don't need to keep the QUIC_RSTREAM around. Finally, we + * don't need a QUIC_RSTREAM on a send-only stream. + */ +#define QUIC_RSTREAM_STATE_NONE 0 /* --- rstream == NULL */ +#define QUIC_RSTREAM_STATE_RECV 1 /* \ */ +#define QUIC_RSTREAM_STATE_SIZE_KNOWN 2 /* |-- rstream != NULL */ +#define QUIC_RSTREAM_STATE_DATA_RECVD 3 /* / */ +#define QUIC_RSTREAM_STATE_DATA_READ 4 /* \ */ +#define QUIC_RSTREAM_STATE_RESET_RECVD 5 /* |-- rstream == NULL */ +#define QUIC_RSTREAM_STATE_RESET_READ 6 /* / */ + +struct quic_stream_st { + QUIC_STREAM_LIST_NODE active_node; /* for use by QUIC_STREAM_MAP */ + QUIC_STREAM_LIST_NODE accept_node; /* accept queue of remotely-created streams */ + QUIC_STREAM_LIST_NODE ready_for_gc_node; /* queue of streams now ready for GC */ + + /* Temporary link used by TXP. */ + QUIC_STREAM *txp_next; + + /* + * QUIC Stream ID. Do not assume that this encodes a type as this is a + * version-specific property and may change between QUIC versions; instead, + * use the type field. + */ + uint64_t id; + + /* + * Application Error Code (AEC) used for STOP_SENDING frame. + * This is only valid if stop_sending is 1. + */ + uint64_t stop_sending_aec; + + /* + * Application Error Code (AEC) used for RESET_STREAM frame. + * This is only valid if reset_stream is 1. + */ + uint64_t reset_stream_aec; + + /* + * Application Error Code (AEC) for incoming STOP_SENDING frame. + * This is only valid if peer_stop_sending is 1. + */ + uint64_t peer_stop_sending_aec; + + /* + * Application Error Code (AEC) for incoming RESET_STREAM frame. + * This is only valid if peer_reset_stream is 1. + */ + uint64_t peer_reset_stream_aec; + + /* Temporary value used by TXP. */ + uint64_t txp_txfc_new_credit_consumed; + + /* + * The final size of the send stream. Although this information can be + * discerned from a QUIC_SSTREAM, it is stored separately as we need to keep + * track of this even if we have thrown away the QUIC_SSTREAM. Use + * ossl_quic_stream_send_get_final_size to determine if this contain a + * valid value or if there is no final size yet for a sending part. + * + * For the receive part, the final size is tracked by the stream-level RXFC; + * use ossl_quic_stream_recv_get_final_size or + * ossl_quic_rxfc_get_final_size. + */ + uint64_t send_final_size; + + /* + * Send stream part and receive stream part buffer management objects. + * + * DO NOT test these pointers (sstream, rstream) for NULL. Determine the + * state of the send or receive stream part first using the appropriate + * function; then the invariant of that state guarantees that sstream or + * rstream either is or is not NULL respectively, therefore there is no + * valid use case for testing these pointers for NULL. In particular, a + * stream with a send part can still have sstream as NULL, and a stream with + * a receive part can still have rstream as NULL. QUIC_SSTREAM and + * QUIC_RSTREAM are stream buffer resource management objects which exist + * only when they need to for buffer management purposes. The existence or + * non-existence of a QUIC_SSTREAM or QUIC_RSTREAM object does not + * correspond with whether a stream's respective send or receive part + * logically exists or not. + */ + QUIC_SSTREAM *sstream; /* NULL if RX-only */ + QUIC_RSTREAM *rstream; /* NULL if TX only */ + + /* Stream-level flow control managers. */ + QUIC_TXFC txfc; /* NULL if RX-only */ + QUIC_RXFC rxfc; /* NULL if TX-only */ + + unsigned int type : 8; /* QUIC_STREAM_INITIATOR_*, QUIC_STREAM_DIR_* */ + + unsigned int send_state : 8; /* QUIC_SSTREAM_STATE_* */ + unsigned int recv_state : 8; /* QUIC_RSTREAM_STATE_* */ + + /* 1 iff this QUIC_STREAM is on the active queue (invariant). */ + unsigned int active : 1; + + /* + * This is a copy of the QUIC connection as_server value, indicating + * whether we are locally operating as a server or not. Having this + * significantly simplifies stream type determination relative to our + * perspective. It never changes after a QUIC_STREAM is created and is the + * same for all QUIC_STREAMS under a QUIC_STREAM_MAP. + */ + unsigned int as_server : 1; + + /* + * Has STOP_SENDING been requested (by us)? Note that this is not the same + * as want_stop_sending below, as a STOP_SENDING frame may already have been + * sent and fully acknowledged. + */ + unsigned int stop_sending : 1; + + /* + * Has RESET_STREAM been requested (by us)? Works identically to + * STOP_SENDING for transmission purposes. + */ + /* Has our peer sent a STOP_SENDING frame? */ + unsigned int peer_stop_sending : 1; + + /* Temporary flags used by TXP. */ + unsigned int txp_sent_fc : 1; + unsigned int txp_sent_stop_sending : 1; + unsigned int txp_sent_reset_stream : 1; + unsigned int txp_drained : 1; + unsigned int txp_blocked : 1; + + /* Frame regeneration flags. */ + unsigned int want_max_stream_data : 1; /* used for regen only */ + unsigned int want_stop_sending : 1; /* used for gen or regen */ + unsigned int want_reset_stream : 1; /* used for gen or regen */ + + /* Flags set when frames *we* sent were acknowledged. */ + unsigned int acked_stop_sending : 1; + + /* + * The stream's XSO has been deleted. Pending GC. + * + * Here is how stream deletion works: + * + * - A QUIC_STREAM cannot be deleted until it is neither in the accept + * queue nor has an associated XSO. This condition occurs when and only + * when deleted is true. + * + * - Once this is the case (i.e., no user-facing API object exposing the + * stream), we can delete the stream once we determine that all of our + * protocol obligations requiring us to keep the QUIC_STREAM around have + * been met. + * + * The following frames relate to the streams layer for a specific + * stream: + * + * STREAM + * + * RX Obligations: + * Ignore for a deleted stream. + * + * (This is different from our obligation for a + * locally-initiated stream ID we have not created yet, + * which we must treat as a protocol error. This can be + * distinguished via a simple monotonic counter.) + * + * TX Obligations: + * None, once we've decided to (someday) delete the stream. + * + * STOP_SENDING + * + * We cannot delete the stream until we have finished informing + * the peer that we are not going to be listening to it + * anymore. + * + * RX Obligations: + * When we delete a stream we must have already had a FIN + * or RESET_STREAM we transmitted acknowledged by the peer. + * Thus we can ignore STOP_SENDING frames for deleted + * streams (if they occur, they are probably just + * retransmissions). + * + * TX Obligations: + * _Acknowledged_ receipt of a STOP_SENDING frame by the + * peer (unless the peer's send part has already FIN'd). + * + * RESET_STREAM + * + * We cannot delete the stream until we have finished informing + * the peer that we are not going to be transmitting on it + * anymore. + * + * RX Obligations: + * This indicates the peer is not going to send any more + * data on the stream. We don't need to care about this + * since once a stream is marked for deletion we don't care + * about any data it does send. We can ignore this for + * deleted streams. The important criterion is that the + * peer has been successfully delivered our STOP_SENDING + * frame. + * + * TX Obligations: + * _Acknowledged_ receipt of a RESET_STREAM frame or FIN by + * the peer. + * + * MAX_STREAM_DATA + * + * RX Obligations: + * Ignore. Since we are not going to be sending any more + * data on a stream once it has been marked for deletion, + * we don't need to care about flow control information. + * + * TX Obligations: + * None. + * + * In other words, our protocol obligation is simply: + * + * - either: + * - the peer has acknowledged receipt of a STOP_SENDING frame sent + * by us; -or- + * - we have received a FIN and all preceding segments from the peer + * + * [NOTE: The actual criterion required here is simply 'we have + * received a FIN from the peer'. However, due to reordering and + * retransmissions we might subsequently receive non-FIN segments + * out of order. The FIN means we know the peer will stop + * transmitting on the stream at *some* point, but by sending + * STOP_SENDING we can avoid these needless retransmissions we + * will just ignore anyway. In actuality we could just handle all + * cases by sending a STOP_SENDING. The strategy we choose is to + * only avoid sending a STOP_SENDING and rely on a received FIN + * when we have received all preceding data, as this makes it + * reasonably certain no benefit would be gained by sending + * STOP_SENDING.] + * + * TODO(QUIC FUTURE): Implement the latter case (currently we + just always do STOP_SENDING). + * + * and; + * + * - we have drained our send stream (for a finished send stream) + * and got acknowledgement all parts of it including the FIN, or + * sent a RESET_STREAM frame and got acknowledgement of that frame. + * + * Once these conditions are met, we can GC the QUIC_STREAM. + * + */ + unsigned int deleted : 1; + /* Set to 1 once the above conditions are actually met. */ + unsigned int ready_for_gc : 1; + /* Set to 1 if this is currently counted in the shutdown flush stream count. */ + unsigned int shutdown_flush : 1; +}; + +#define QUIC_STREAM_INITIATOR_CLIENT 0 +#define QUIC_STREAM_INITIATOR_SERVER 1 +#define QUIC_STREAM_INITIATOR_MASK 1 + +#define QUIC_STREAM_DIR_BIDI 0 +#define QUIC_STREAM_DIR_UNI 2 +#define QUIC_STREAM_DIR_MASK 2 + +void ossl_quic_stream_check(const QUIC_STREAM *s); + +/* + * Returns 1 if the QUIC_STREAM was initiated by the endpoint with the server + * role. + */ +static ossl_inline ossl_unused int ossl_quic_stream_is_server_init(const QUIC_STREAM *s) +{ + return (s->type & QUIC_STREAM_INITIATOR_MASK) == QUIC_STREAM_INITIATOR_SERVER; +} + +/* + * Returns 1 if the QUIC_STREAM is bidirectional and 0 if it is unidirectional. + */ +static ossl_inline ossl_unused int ossl_quic_stream_is_bidi(const QUIC_STREAM *s) +{ + return (s->type & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_BIDI; +} + +/* Returns 1 if the QUIC_STREAM was locally initiated. */ +static ossl_inline ossl_unused int ossl_quic_stream_is_local_init(const QUIC_STREAM *s) +{ + return ossl_quic_stream_is_server_init(s) == s->as_server; +} + +/* + * Returns 1 if the QUIC_STREAM has a sending part, based on its stream type. + * + * Do NOT use (s->sstream != NULL) to test this; use this function. Note that + * even if this function returns 1, s->sstream might be NULL if the QUIC_SSTREAM + * has been deemed no longer needed, for example due to a RESET_STREAM. + */ +static ossl_inline ossl_unused int ossl_quic_stream_has_send(const QUIC_STREAM *s) +{ + return s->send_state != QUIC_SSTREAM_STATE_NONE; +} + +/* + * Returns 1 if the QUIC_STREAM has a receiving part, based on its stream type. + * + * Do NOT use (s->rstream != NULL) to test this; use this function. Note that + * even if this function returns 1, s->rstream might be NULL if the QUIC_RSTREAM + * has been deemed no longer needed, for example if the receive stream is + * completely finished with. + */ +static ossl_inline ossl_unused int ossl_quic_stream_has_recv(const QUIC_STREAM *s) +{ + return s->recv_state != QUIC_RSTREAM_STATE_NONE; +} + +/* + * Returns 1 if the QUIC_STREAM has a QUIC_SSTREAM send buffer associated with + * it. If this returns 1, s->sstream is guaranteed to be non-NULL. The converse + * is not necessarily true; erasure of a send stream buffer which is no longer + * required is an optimisation which the QSM may, but is not obliged, to + * perform. + * + * This call should be used where it is desired to do something with the send + * stream buffer but there is no more specific send state restriction which is + * applicable. + * + * Note: This does NOT indicate whether it is suitable to allow an application + * to append to the buffer. DATA_SENT indicates all data (including FIN) has + * been *sent*; the absence of DATA_SENT does not mean a FIN has not been queued + * (meaning no more application data can be appended). This is enforced by + * QUIC_SSTREAM. + */ +static ossl_inline ossl_unused int ossl_quic_stream_has_send_buffer(const QUIC_STREAM *s) +{ + switch (s->send_state) { + case QUIC_SSTREAM_STATE_READY: + case QUIC_SSTREAM_STATE_SEND: + case QUIC_SSTREAM_STATE_DATA_SENT: + return 1; + default: + return 0; + } +} + +/* + * Returns 1 if the QUIC_STREAM has a sending part which is in one of the reset + * states. + */ +static ossl_inline ossl_unused int ossl_quic_stream_send_is_reset(const QUIC_STREAM *s) +{ + return s->send_state == QUIC_SSTREAM_STATE_RESET_SENT + || s->send_state == QUIC_SSTREAM_STATE_RESET_RECVD; +} + +/* + * Returns 1 if the QUIC_STREAM has a QUIC_RSTREAM receive buffer associated + * with it. If this returns 1, s->rstream is guaranteed to be non-NULL. The + * converse is not necessarily true; erasure of a receive stream buffer which is + * no longer required is an optimisation which the QSM may, but is not obliged, + * to perform. + * + * This call should be used where it is desired to do something with the receive + * stream buffer but there is no more specific receive state restriction which is + * applicable. + */ +static ossl_inline ossl_unused int ossl_quic_stream_has_recv_buffer(const QUIC_STREAM *s) +{ + switch (s->recv_state) { + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + return 1; + default: + return 0; + } +} + +/* + * Returns 1 if the QUIC_STREAM has a receiving part which is in one of the + * reset states. + */ +static ossl_inline ossl_unused int ossl_quic_stream_recv_is_reset(const QUIC_STREAM *s) +{ + return s->recv_state == QUIC_RSTREAM_STATE_RESET_RECVD + || s->recv_state == QUIC_RSTREAM_STATE_RESET_READ; +} + +/* + * Returns 1 if the stream has a send part and that part has a final size. + * + * If final_size is non-NULL, *final_size is the final size (on success) or an + * undefined value otherwise. + */ +static ossl_inline ossl_unused int ossl_quic_stream_send_get_final_size(const QUIC_STREAM *s, + uint64_t *final_size) +{ + switch (s->send_state) { + default: + case QUIC_SSTREAM_STATE_NONE: + return 0; + case QUIC_SSTREAM_STATE_SEND: + /* + * SEND may or may not have had a FIN - even if we have a FIN we do not + * move to DATA_SENT until we have actually sent all the data. So + * ask the QUIC_SSTREAM. + */ + return ossl_quic_sstream_get_final_size(s->sstream, final_size); + case QUIC_SSTREAM_STATE_DATA_SENT: + case QUIC_SSTREAM_STATE_DATA_RECVD: + case QUIC_SSTREAM_STATE_RESET_SENT: + case QUIC_SSTREAM_STATE_RESET_RECVD: + if (final_size != NULL) + *final_size = s->send_final_size; + return 1; + } +} + +/* + * Returns 1 if the stream has a receive part and that part has a final size. + * + * If final_size is non-NULL, *final_size is the final size (on success) or an + * undefined value otherwise. + */ +static ossl_inline ossl_unused int ossl_quic_stream_recv_get_final_size(const QUIC_STREAM *s, + uint64_t *final_size) +{ + switch (s->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + case QUIC_RSTREAM_STATE_RECV: + return 0; + + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + case QUIC_RSTREAM_STATE_DATA_READ: + case QUIC_RSTREAM_STATE_RESET_RECVD: + case QUIC_RSTREAM_STATE_RESET_READ: + if (!ossl_assert(ossl_quic_rxfc_get_final_size(&s->rxfc, final_size))) + return 0; + + return 1; + } +} + +/* + * QUIC Stream Map + * =============== + * + * The QUIC stream map: + * + * - maps stream IDs to QUIC_STREAM objects; + * - tracks which streams are 'active' (currently have data for transmission); + * - allows iteration over the active streams only. + * + */ +typedef struct quic_stream_map_st { + LHASH_OF(QUIC_STREAM) *map; + QUIC_STREAM_LIST_NODE active_list; + QUIC_STREAM_LIST_NODE accept_list; + QUIC_STREAM_LIST_NODE ready_for_gc_list; + size_t rr_stepping, rr_counter; + size_t num_accept, num_shutdown_flush; + QUIC_STREAM *rr_cur; + uint64_t (*get_stream_limit_cb)(int uni, void *arg); + void *get_stream_limit_cb_arg; + QUIC_RXFC *max_streams_bidi_rxfc; + QUIC_RXFC *max_streams_uni_rxfc; + int is_server; +} QUIC_STREAM_MAP; + +/* + * get_stream_limit is a callback which is called to retrieve the current stream + * limit for streams created by us. This mechanism is not used for + * peer-initiated streams. If a stream's stream ID is x, a stream is allowed if + * (x >> 2) < returned limit value; i.e., the returned value is exclusive. + * + * If uni is 1, get the limit for locally-initiated unidirectional streams, else + * get the limit for locally-initiated bidirectional streams. + * + * If the callback is NULL, stream limiting is not applied. + * Stream limiting is used to determine if frames can currently be produced for + * a stream. + */ +int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm, + uint64_t (*get_stream_limit_cb)(int uni, void *arg), + void *get_stream_limit_cb_arg, + QUIC_RXFC *max_streams_bidi_rxfc, + QUIC_RXFC *max_streams_uni_rxfc, + int is_server); + +/* + * Any streams still in the map will be released as though + * ossl_quic_stream_map_release was called on them. + */ +void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm); + +/* + * Allocate a new stream. type is a combination of one QUIC_STREAM_INITIATOR_* + * value and one QUIC_STREAM_DIR_* value. Note that clients can e.g. allocate + * server-initiated streams as they will need to allocate a QUIC_STREAM + * structure to track any stream created by the server, etc. + * + * stream_id must be a valid value. Returns NULL if a stream already exists + * with the given ID. + */ +QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm, + uint64_t stream_id, + int type); + +/* + * Releases a stream object. Note that this must only be done once the teardown + * process is entirely complete and the object will never be referenced again. + */ +void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream); + +/* + * Calls visit_cb() for each stream in the map. visit_cb_arg is an opaque + * argument which is passed through. + */ +void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm, + void (*visit_cb)(QUIC_STREAM *stream, void *arg), + void *visit_cb_arg); + +/* + * Retrieves a stream by stream ID. Returns NULL if it does not exist. + */ +QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm, + uint64_t stream_id); + +/* + * Marks the given stream as active or inactive based on its state. Idempotent. + * + * When a stream is marked active, it becomes available in the iteration list, + * and when a stream is marked inactive, it no longer appears in the iteration + * list. + * + * Calling this function invalidates any iterator currently pointing at the + * given stream object, but iterators not currently pointing at the given stream + * object are not invalidated. + */ +void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s); + +/* + * Sets the RR stepping value, n. The RR rotation will be advanced every n + * packets. The default value is 1. + */ +void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping); + +/* + * Returns 1 if the stream ordinal given is allowed by the current stream count + * flow control limit, assuming a locally initiated stream of a type described + * by is_uni. + * + * Note that stream_ordinal is a stream ordinal, not a stream ID. + */ +int ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP *qsm, + uint64_t stream_ordinal, + int is_uni); + +/* + * Stream Send Part + * ================ + */ + +/* + * Ensures that the sending part has transitioned out of the READY state (i.e., + * to SEND, or a subsequent state). This function is named as it is because, + * while on paper the distinction between READY and SEND is whether we have + * started transmitting application data, in practice the meaningful distinction + * between the two states is whether we have allocated a stream ID to the stream + * or not. QUIC permits us to defer stream ID allocation until first STREAM (or + * STREAM_DATA_BLOCKED) frame transmission for locally-initiated streams. + * + * Our implementation does not currently do this and we allocate stream IDs up + * front, however we may revisit this in the future. Calling this represents a + * demand for a stream ID by the caller and ensures one has been allocated to + * the stream, and causes us to transition to SEND if we are still in the READY + * state. + * + * Returns 0 if there is no send part (caller error) and 1 otherwise. + */ +int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Transitions from SEND to the DATA_SENT state. Note that this is NOT the same + * as the point in time at which the final size of the stream becomes known + * (i.e., the time at which ossl_quic_sstream_fin()) is called as it occurs when + * we have SENT all data on a given stream send part, not merely buffered it. + * Note that this transition is NOT reversed in the event of some of that data + * being lost. + * + * Returns 1 if the state transition was successfully taken. Returns 0 if there + * is no send part (caller error) or if the state transition cannot be taken + * because the send part is not in the SEND state. + */ +int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Transitions from the DATA_SENT to DATA_RECVD state; should be called + * when all transmitted stream data is ACKed by the peer. + * + * Returns 1 if the state transition was successfully taken. Returns 0 if there + * is no send part (caller error) or the state transition cannot be taken + * because the send part is not in the DATA_SENT state. Because + * ossl_quic_stream_map_notify_all_data_sent() should always be called prior to + * this function, the send state must already be in DATA_SENT in order for this + * function to succeed. + */ +int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Resets the sending part of a stream. This is a transition from the READY, + * SEND or DATA_SENT send stream states to the RESET_SENT state. + * + * This function returns 1 if the transition is taken (i.e., if the send stream + * part was in one of the states above), or if it is already in the RESET_SENT + * state (idempotent operation), or if it has reached the RESET_RECVD state. + * + * It returns 0 if in the DATA_RECVD state, as a send stream cannot be reset + * in this state. It also returns 0 if there is no send part (caller error). + */ +int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t aec); + +/* + * Transitions from the RESET_SENT to the RESET_RECVD state. This should be + * called when a sent RESET_STREAM frame has been acknowledged by the peer. + * + * This function returns 1 if the transition is taken (i.e., if the send stream + * part was in one of the states above) or if it is already in the RESET_RECVD + * state (idempotent operation). + * + * It returns 0 if not in the RESET_SENT or RESET_RECVD states, as this function + * should only be called after we have already sent a RESET_STREAM frame and + * entered the RESET_SENT state. It also returns 0 if there is no send part + * (caller error). + */ +int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + + +/* + * Stream Receive Part + * =================== + */ + +/* + * Transitions from the RECV receive stream state to the SIZE_KNOWN state. This + * should be called once a STREAM frame is received for the stream with the FIN + * bit set. final_size should be the final size of the stream in bytes. + * + * Returns 1 if the transition was taken. + */ +int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t final_size); + +/* + * Transitions from the SIZE_KNOWN receive stream state to the DATA_RECVD state. + * This should be called once all data for a receive stream is received. + * + * Returns 1 if the transition was taken. + */ +int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Transitions from the DATA_RECVD receive stream state to the DATA_READ state. + * This should be called once all data for a receive stream is read by the + * application. + * + * Returns 1 if the transition was taken. + */ +int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Transitions from the RECV, SIZE_KNOWN or DATA_RECVD receive stream state to + * the RESET_RECVD state. This should be called on RESET_STREAM. + * + * Returns 1 if the transition was taken. + */ +int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t app_error_code, + uint64_t final_size); + +/* + * Transitions from the RESET_RECVD receive stream state to the RESET_READ + * receive stream state. This should be called when the application is notified + * of a stream reset. + */ +int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + +/* + * Marks the receiving part of a stream for STOP_SENDING. This is orthogonal to + * receive stream state as it does not affect it directly. + * + * Returns 1 if the receiving part of a stream was not already marked for + * STOP_SENDING. + * Returns 0 otherwise, which need not be considered an error. + */ +int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t aec); + +/* + * Marks the stream as wanting a STOP_SENDING frame transmitted. It is not valid + * to call this if ossl_quic_stream_map_stop_sending_recv_part() has not been + * called. For TXP use. + */ +int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs); + + +/* + * Accept Queue Management + * ======================= + */ + +/* + * Adds a stream to the accept queue. + */ +void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s); + +/* + * Returns the next item to be popped from the accept queue, or NULL if it is + * empty. + */ +QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm); + +/* + * Removes a stream from the accept queue. rtt is the estimated connection RTT. + * The stream is retired for the purposes of MAX_STREAMS RXFC. + * + * Precondition: s is in the accept queue. + */ +void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s, + OSSL_TIME rtt); + +/* Returns the length of the accept queue. */ +size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm); + +/* + * Shutdown Flush and GC + * ===================== + */ + +/* + * Delete streams ready for GC. Pointers to those QUIC_STREAM objects become + * invalid. + */ +void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm); + +/* + * Begins shutdown stream flush triage. Analyses all streams, including deleted + * but not yet GC'd streams, to determine if we should wait for that stream to + * be fully flushed before shutdown. After calling this, call + * ossl_quic_stream_map_is_shutdown_flush_finished() to determine if all + * shutdown flush eligible streams have been flushed. + */ +void ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP *qsm); + +/* + * Returns 1 if all shutdown flush eligible streams have finished flushing, + * or if ossl_quic_stream_map_begin_shutdown_flush() has not been called. + */ +int ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP *qsm); + +/* + * QUIC Stream Iterator + * ==================== + * + * Allows the current set of active streams to be walked using a RR-based + * algorithm. Each time ossl_quic_stream_iter_init is called, the RR algorithm + * is stepped. The RR algorithm rotates the iteration order such that the next + * active stream is returned first after n calls to ossl_quic_stream_iter_init, + * where n is the stepping value configured via + * ossl_quic_stream_map_set_rr_stepping. + * + * Suppose there are three active streams and the configured stepping is n: + * + * Iteration 0n: [Stream 1] [Stream 2] [Stream 3] + * Iteration 1n: [Stream 2] [Stream 3] [Stream 1] + * Iteration 2n: [Stream 3] [Stream 1] [Stream 2] + * + */ +typedef struct quic_stream_iter_st { + QUIC_STREAM_MAP *qsm; + QUIC_STREAM *first_stream, *stream; +} QUIC_STREAM_ITER; + +/* + * Initialise an iterator, advancing the RR algorithm as necessary (if + * advance_rr is 1). After calling this, it->stream will be the first stream in + * the iteration sequence, or NULL if there are no active streams. + */ +void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm, + int advance_rr); + +/* + * Advances to next stream in iteration sequence. You do not need to call this + * immediately after calling ossl_quic_stream_iter_init(). If the end of the + * list is reached, it->stream will be NULL after calling this. + */ +void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it); + +# endif + +#endif diff --git a/include/internal/quic_thread_assist.h b/include/internal/quic_thread_assist.h new file mode 100644 index 0000000000..592c2ffabf --- /dev/null +++ b/include/internal/quic_thread_assist.h @@ -0,0 +1,102 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_THREAD_ASSIST_H +# define OSSL_QUIC_THREAD_ASSIST_H + +# include +# include "internal/thread.h" +# include "internal/time.h" + +# if defined(OPENSSL_NO_QUIC) || defined(OPENSSL_NO_THREAD_POOL) +# define OPENSSL_NO_QUIC_THREAD_ASSIST +# endif + +# ifndef OPENSSL_NO_QUIC_THREAD_ASSIST + +/* + * QUIC Thread Assisted Functionality + * ================================== + * + * Where OS threading support is available, QUIC can optionally support a thread + * assisted mode of operation. The purpose of this mode of operation is to + * ensure that assorted timeout events which QUIC expects to be handled in a + * timely manner can be handled without the application needing to ensure that + * SSL_tick() is called on time. This is not needed if the application always + * has a call blocking to SSL_read() or SSL_write() (or another I/O function) on + * a QUIC SSL object, but if the application goes for long periods of time + * without making any such call to a QUIC SSL object, libssl cannot ordinarily + * guarantee that QUIC timeout events will be serviced in a timely fashion. + * Thread assisted mode is therefore of use to applications which do not always + * have an ongoing call to an I/O function on a QUIC SSL object but also do not + * want to have to arrange periodic ticking. + * + * A consequence of this is that the intrusiveness of thread assisted mode upon + * the general architecture of our QUIC engine is actually fairly limited and + * amounts to an automatic ticking of the QUIC engine when timeouts expire, + * synchronised correctly with an application's own threads using locking. + */ +typedef struct quic_thread_assist_st { + QUIC_CHANNEL *ch; + CRYPTO_CONDVAR *cv; + CRYPTO_THREAD *t; + int teardown, joined; + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; +} QUIC_THREAD_ASSIST; + +/* + * Initialise the thread assist object. The channel must have a valid mutex + * configured on it which will be retrieved automatically. It is assumed that + * the mutex is currently held when this function is called. This function does + * not affect the state of the mutex. + */ +int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); + +/* + * Request the thread assist helper to begin stopping the assist thread. This + * returns before the teardown is complete. Idempotent; multiple calls to this + * function are inconsequential. + * + * Precondition: channel mutex must be held (unchecked) + */ +int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta); + +/* + * Wait until the thread assist helper is torn down. This automatically implies + * the effects of ossl_quic_thread_assist_stop_async(). Returns immediately + * if the teardown has already completed. + * + * Precondition: channel mutex must be held (unchecked) + */ +int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta); + +/* + * Deallocates state associated with the thread assist helper. + * ossl_quic_thread_assist_wait_stopped() must have returned successfully before + * calling this. It does not matter whether the channel mutex is held or not. + * + * Precondition: ossl_quic_thread_assist_wait_stopped() has returned 1 + * (asserted) + */ +int ossl_quic_thread_assist_cleanup(QUIC_THREAD_ASSIST *qta); + +/* + * Must be called to notify the assist thread if the channel deadline changes. + * + * Precondition: channel mutex must be held (unchecked) + */ +int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta); + +# endif + +#endif diff --git a/include/internal/quic_tls.h b/include/internal/quic_tls.h new file mode 100644 index 0000000000..0e4a9d339b --- /dev/null +++ b/include/internal/quic_tls.h @@ -0,0 +1,106 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_TLS_H +# define OSSL_QUIC_TLS_H + +# include +# include "internal/quic_stream.h" + + +typedef struct quic_tls_st QUIC_TLS; + +typedef struct quic_tls_args_st { + /* + * The "inner" SSL object for the QUIC Connection. Contains an + * SSL_CONNECTION + */ + SSL *s; + + /* + * Called to send data on the crypto stream. We use a callback rather than + * passing the crypto stream QUIC_SSTREAM directly because this lets the CSM + * dynamically select the correct outgoing crypto stream based on the + * current EL. + */ + int (*crypto_send_cb)(const unsigned char *buf, size_t buf_len, + size_t *consumed, void *arg); + void *crypto_send_cb_arg; + + /* + * Call to receive crypto stream data. A pointer to the underlying buffer + * is provided, and subsequently released to avoid unnecessary copying of + * data. + */ + int (*crypto_recv_rcd_cb)(const unsigned char **buf, size_t *bytes_read, + void *arg); + void *crypto_recv_rcd_cb_arg; + int (*crypto_release_rcd_cb)(size_t bytes_read, void *arg); + void *crypto_release_rcd_cb_arg; + + + /* Called when a traffic secret is available for a given encryption level. */ + int (*yield_secret_cb)(uint32_t enc_level, int direction /* 0=RX, 1=TX */, + uint32_t suite_id, EVP_MD *md, + const unsigned char *secret, size_t secret_len, + void *arg); + void *yield_secret_cb_arg; + + /* + * Called when we receive transport parameters from the peer. + * + * Note: These parameters are not authenticated until the handshake is + * marked as completed. + */ + int (*got_transport_params_cb)(const unsigned char *params, + size_t params_len, + void *arg); + void *got_transport_params_cb_arg; + + /* + * Called when the handshake has been completed as far as the handshake + * protocol is concerned, meaning that the connection has been + * authenticated. + */ + int (*handshake_complete_cb)(void *arg); + void *handshake_complete_cb_arg; + + /* + * Called when something has gone wrong with the connection as far as the + * handshake layer is concerned, meaning that it should be immediately torn + * down. Note that this may happen at any time, including after a connection + * has been fully established. + */ + int (*alert_cb)(void *arg, unsigned char alert_code); + void *alert_cb_arg; + + /* Set to 1 if we are running in the server role. */ + int is_server; +} QUIC_TLS_ARGS; + +QUIC_TLS *ossl_quic_tls_new(const QUIC_TLS_ARGS *args); + +void ossl_quic_tls_free(QUIC_TLS *qtls); + +/* Advance the state machine */ +int ossl_quic_tls_tick(QUIC_TLS *qtls); + +int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls, + const unsigned char *transport_params, + size_t transport_params_len); + +int ossl_quic_tls_get_error(QUIC_TLS *qtls, + uint64_t *error_code, + const char **error_msg, + ERR_STATE **error_state); + +int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls); +int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls); + +#endif diff --git a/include/internal/quic_tserver.h b/include/internal/quic_tserver.h new file mode 100644 index 0000000000..4f358dd4e8 --- /dev/null +++ b/include/internal/quic_tserver.h @@ -0,0 +1,220 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_TSERVER_H +# define OSSL_QUIC_TSERVER_H + +# include +# include +# include "internal/quic_stream.h" +# include "internal/quic_channel.h" +# include "internal/statem.h" +# include "internal/time.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Test Server Module + * ======================= + * + * This implements a QUIC test server. Since full QUIC server support is not yet + * implemented this server is limited in features and scope. It exists to + * provide a target for our QUIC client to talk to for testing purposes. + * + * A given QUIC test server instance supports only one client at a time. + * + * Note that this test server is not suitable for production use because it does + * not implement address verification, anti-amplification or retry logic. + */ +typedef struct quic_tserver_st QUIC_TSERVER; + +typedef struct quic_tserver_args_st { + OSSL_LIB_CTX *libctx; + const char *propq; + SSL_CTX *ctx; + BIO *net_rbio, *net_wbio; + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; + const unsigned char *alpn; + size_t alpnlen; +} QUIC_TSERVER_ARGS; + +QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, + const char *certfile, const char *keyfile); + +void ossl_quic_tserver_free(QUIC_TSERVER *srv); + +/* Set mutator callbacks for test framework support */ +int ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER *srv, + ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, + void *mutatearg); + +int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv, + ossl_statem_mutate_handshake_cb mutate_handshake_cb, + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, + void *mutatearg); + +/* Advances the state machine. */ +int ossl_quic_tserver_tick(QUIC_TSERVER *srv); + +/* Returns 1 if we have a (non-terminated) client. */ +int ossl_quic_tserver_is_connected(QUIC_TSERVER *srv); + +/* + * Returns 1 if we have finished the TLS handshake + */ +int ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER *srv); + +/* Returns 1 if the server is in any terminating or terminated state */ +int ossl_quic_tserver_is_term_any(const QUIC_TSERVER *srv); + +const QUIC_TERMINATE_CAUSE * +ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER *srv); + +/* Returns 1 if the server is in a terminated state */ +int ossl_quic_tserver_is_terminated(const QUIC_TSERVER *srv); + +/* + * Attempts to read from stream 0. Writes the number of bytes read to + * *bytes_read and returns 1 on success. If no bytes are available, 0 is written + * to *bytes_read and 1 is returned (this is considered a success case). + * + * Returns 0 if connection is not currently active. If the receive part of + * the stream has reached the end of stream condition, returns 0; call + * ossl_quic_tserver_has_read_ended() to identify this condition. + */ +int ossl_quic_tserver_read(QUIC_TSERVER *srv, + uint64_t stream_id, + unsigned char *buf, + size_t buf_len, + size_t *bytes_read); + +/* + * Returns 1 if the read part of the stream has ended normally. + */ +int ossl_quic_tserver_has_read_ended(QUIC_TSERVER *srv, uint64_t stream_id); + +/* + * Attempts to write to the given stream. Writes the number of bytes consumed to + * *bytes_written and returns 1 on success. If there is no space currently + * available to write any bytes, 0 is written to *consumed and 1 is returned + * (this is considered a success case). + * + * Note that unlike libssl public APIs, this API always works in a 'partial + * write' mode. + * + * Returns 0 if connection is not currently active. + */ +int ossl_quic_tserver_write(QUIC_TSERVER *srv, + uint64_t stream_id, + const unsigned char *buf, + size_t buf_len, + size_t *bytes_written); + +/* + * Signals normal end of the stream. + */ +int ossl_quic_tserver_conclude(QUIC_TSERVER *srv, uint64_t stream_id); + +/* + * Create a server-initiated stream. The stream ID of the newly + * created stream is written to *stream_id. + */ +int ossl_quic_tserver_stream_new(QUIC_TSERVER *srv, + int is_uni, + uint64_t *stream_id); + +BIO *ossl_quic_tserver_get0_rbio(QUIC_TSERVER *srv); + +SSL_CTX *ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER *srv); + +/* + * Returns 1 if the peer has sent a STOP_SENDING frame for a stream. + * app_error_code is written if this returns 1. + */ +int ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER *srv, + uint64_t stream_id, + uint64_t *app_error_code); + +/* + * Returns 1 if the peer has sent a RESET_STREAM frame for a stream. + * app_error_code is written if this returns 1. + */ +int ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER *srv, + uint64_t stream_id, + uint64_t *app_error_code); + +/* + * Replaces existing local connection ID in the underlying QUIC_CHANNEL. + */ +int ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER *srv, + const QUIC_CONN_ID *conn_id); + +/* + * Returns the stream ID of the next incoming stream, or UINT64_MAX if there + * currently is none. + */ +uint64_t ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER *srv); + +/* + * Returns 1 if all data sent on the given stream_id has been acked by the peer. + */ +int ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER *srv, + uint64_t stream_id); + +/* Returns 1 if we are currently interested in reading data from the network */ +int ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER *srv); + +/* Returns 1 if we are currently interested in writing data to the network */ +int ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER *srv); + +/* Returns the next event deadline */ +OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv); + +/* + * Shutdown the QUIC connection. Returns 1 if the connection is terminated and + * 0 otherwise. + */ +int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv, uint64_t app_error_code); + +/* Force generation of an ACK-eliciting packet. */ +int ossl_quic_tserver_ping(QUIC_TSERVER *srv); + +/* Set tracing callback on channel. */ +void ossl_quic_tserver_set_msg_callback(QUIC_TSERVER *srv, + void (*f)(int write_p, int version, + int content_type, + const void *buf, size_t len, + SSL *ssl, void *arg), + void *arg); + +/* + * This is similar to ossl_quic_conn_get_channel; it should be used for test + * instrumentation only and not to bypass QUIC_TSERVER for 'normal' operations. + */ +QUIC_CHANNEL *ossl_quic_tserver_get_channel(QUIC_TSERVER *srv); + +/* Send a TLS new session ticket */ +int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv); + +/* + * Set the max_early_data value to be sent in NewSessionTickets. Only the + * values 0 and 0xffffffff are valid for use in QUIC. + */ +int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv, + uint32_t max_early_data); + +/* Set the find session callback for getting a server PSK */ +void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv, + SSL_psk_find_session_cb_func cb); + +# endif + +#endif diff --git a/include/internal/quic_txp.h b/include/internal/quic_txp.h new file mode 100644 index 0000000000..ae508f2393 --- /dev/null +++ b/include/internal/quic_txp.h @@ -0,0 +1,209 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_TXP_H +# define OSSL_QUIC_TXP_H + +# include +# include "internal/quic_types.h" +# include "internal/quic_record_tx.h" +# include "internal/quic_cfq.h" +# include "internal/quic_txpim.h" +# include "internal/quic_stream.h" +# include "internal/quic_stream_map.h" +# include "internal/quic_fc.h" +# include "internal/bio_addr.h" +# include "internal/time.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC TX Packetiser + * ================== + */ +typedef struct ossl_quic_tx_packetiser_args_st { + /* Configuration Settings */ + QUIC_CONN_ID cur_scid; /* Current Source Connection ID we use. */ + QUIC_CONN_ID cur_dcid; /* Current Destination Connection ID we use. */ + BIO_ADDR peer; /* Current destination L4 address we use. */ + uint32_t ack_delay_exponent; /* ACK delay exponent used when encoding. */ + + /* Injected Dependencies */ + OSSL_QTX *qtx; /* QUIC Record Layer TX we are using */ + QUIC_TXPIM *txpim; /* QUIC TX'd Packet Information Manager */ + QUIC_CFQ *cfq; /* QUIC Control Frame Queue */ + OSSL_ACKM *ackm; /* QUIC Acknowledgement Manager */ + QUIC_STREAM_MAP *qsm; /* QUIC Streams Map */ + QUIC_TXFC *conn_txfc; /* QUIC Connection-Level TX Flow Controller */ + QUIC_RXFC *conn_rxfc; /* QUIC Connection-Level RX Flow Controller */ + QUIC_RXFC *max_streams_bidi_rxfc; /* QUIC RXFC for MAX_STREAMS generation */ + QUIC_RXFC *max_streams_uni_rxfc; + const OSSL_CC_METHOD *cc_method; /* QUIC Congestion Controller */ + OSSL_CC_DATA *cc_data; /* QUIC Congestion Controller Instance */ + OSSL_TIME (*now)(void *arg); /* Callback to get current time. */ + void *now_arg; + + /* + * Injected dependencies - crypto streams. + * + * Note: There is no crypto stream for the 0-RTT EL. + * crypto[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream. + */ + QUIC_SSTREAM *crypto[QUIC_PN_SPACE_NUM]; + + } OSSL_QUIC_TX_PACKETISER_ARGS; + +typedef struct ossl_quic_tx_packetiser_st OSSL_QUIC_TX_PACKETISER; + +OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args); + +typedef void (ossl_quic_initial_token_free_fn)(const unsigned char *buf, + size_t buf_len, void *arg); + +void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp); + +/* + * When in the closing state we need to maintain a count of received bytes + * so that we can limit the number of close connection frames we send. + * Refer RFC 9000 s. 10.2.1 Closing Connection State. + */ +void ossl_quic_tx_packetiser_record_received_closing_bytes( + OSSL_QUIC_TX_PACKETISER *txp, size_t n); + +/* + * Generates a datagram by polling the various ELs to determine if they want to + * generate any frames, and generating a datagram which coalesces packets for + * any ELs which do. + * + * Returns 0 on failure (e.g. allocation error or other errors), 1 otherwise. + * + * *status is filled with status information about the generated packet. + * It is always filled even in case of failure. In particular, packets can be + * sent even if failure is later returned. + * See QUIC_TXP_STATUS for details. + */ +typedef struct quic_txp_status_st { + int sent_ack_eliciting; /* Was an ACK-eliciting packet sent? */ + int sent_handshake; /* Was a Handshake packet sent? */ + size_t sent_pkt; /* Number of packets sent (0 if nothing was sent) */ +} QUIC_TXP_STATUS; + +int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, + QUIC_TXP_STATUS *status); + +/* + * Returns a deadline after which a call to ossl_quic_tx_packetiser_generate() + * might succeed even if it did not previously. This may return + * ossl_time_infinite() if there is no such deadline currently applicable. It + * returns ossl_time_zero() if there is (potentially) more data to be generated + * immediately. The value returned is liable to change after any call to + * ossl_quic_tx_packetiser_generate() (or after ACKM or CC state changes). Note + * that ossl_quic_tx_packetiser_generate() can also start to succeed for other + * non-chronological reasons, such as changes to send stream buffers, etc. + */ +OSSL_TIME ossl_quic_tx_packetiser_get_deadline(OSSL_QUIC_TX_PACKETISER *txp); + +/* + * Set the token used in Initial packets. The callback is called when the buffer + * is no longer needed; for example, when the TXP is freed or when this function + * is called again with a new buffer. Fails returning 0 if the token is too big + * to ever be reasonably encapsulated in an outgoing packet based on our current + * understanding of our PMTU. + */ +int ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp, + const unsigned char *token, + size_t token_len, + ossl_quic_initial_token_free_fn *free_cb, + void *free_cb_arg); + +/* Change the DCID the TXP uses to send outgoing packets. */ +int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp, + const QUIC_CONN_ID *dcid); + +/* Change the SCID the TXP uses to send outgoing (long) packets. */ +int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp, + const QUIC_CONN_ID *scid); + +/* + * Change the destination L4 address the TXP uses to send datagrams. Specify + * NULL (or AF_UNSPEC) to disable use of addressed mode. + */ +int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp, + const BIO_ADDR *peer); + +/* + * Inform the TX packetiser that an EL has been discarded. Idempotent. + * + * This does not inform the QTX as well; the caller must also inform the QTX. + * + * The TXP will no longer reference the crypto[enc_level] QUIC_SSTREAM which was + * provided in the TXP arguments. However, it is the callers responsibility to + * free that QUIC_SSTREAM if desired. + */ +int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level); + +/* + * Informs the TX packetiser that the handshake is complete. The TX packetiser + * will not send 1-RTT application data until the handshake is complete, + * as the authenticity of the peer is not confirmed until the handshake + * complete event occurs. + */ +void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp); + +/* Asks the TXP to generate a HANDSHAKE_DONE frame in the next 1-RTT packet. */ +void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp); + +/* Asks the TXP to ensure the next packet in the given PN space is ACK-eliciting. */ +void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space); + +/* + * Asks the TXP to ensure an ACK is put in the next packet in the given PN + * space. + */ +void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space); + +/* + * Schedules a connection close. *f and f->reason are copied. This operation is + * irreversible and causes all further packets generated by the TXP to contain a + * CONNECTION_CLOSE frame. This function fails if it has already been called + * successfully; the information in *f cannot be changed after the first + * successful call to this function. + */ +int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp, + const OSSL_QUIC_FRAME_CONN_CLOSE *f); + +/* Setters for the msg_callback and msg_callback_arg */ +void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp, + ossl_msg_cb msg_callback, + SSL *msg_callback_ssl); +void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp, + void *msg_callback_arg); + +/* + * Determines the next PN which will be used for a given PN space. + */ +QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space); + +/* + * Sets a callback which is called whenever TXP sends an ACK frame. The callee + * must not modify the ACK frame data. Can be used to snoop on PNs being ACKed. + */ +void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, + void (*cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg), + void *cb_arg); + +# endif + +#endif diff --git a/include/internal/quic_txpim.h b/include/internal/quic_txpim.h new file mode 100644 index 0000000000..ed6e3875c4 --- /dev/null +++ b/include/internal/quic_txpim.h @@ -0,0 +1,133 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_TXPIM_H +# define OSSL_QUIC_TXPIM_H + +# include +# include "internal/quic_types.h" +# include "internal/quic_cfq.h" +# include "internal/quic_ackm.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Transmitted Packet Information Manager + * =========================================== + */ +typedef struct quic_txpim_st QUIC_TXPIM; +typedef struct quic_fifd_st QUIC_FIFD; + +typedef struct quic_txpim_pkt_st { + /* ACKM-specific data. Caller should fill this. */ + OSSL_ACKM_TX_PKT ackm_pkt; + + /* Linked list of CFQ items in this packet. */ + QUIC_CFQ_ITEM *retx_head; + + /* Reserved for FIFD use. */ + QUIC_FIFD *fifd; + + /* Regenerate-strategy frames. */ + unsigned int had_handshake_done_frame : 1; + unsigned int had_max_data_frame : 1; + unsigned int had_max_streams_bidi_frame : 1; + unsigned int had_max_streams_uni_frame : 1; + unsigned int had_ack_frame : 1; + unsigned int had_conn_close : 1; + + /* Private data follows. */ +} QUIC_TXPIM_PKT; + +/* Represents a range of bytes in an application or CRYPTO stream. */ +typedef struct quic_txpim_chunk_st { + /* The stream ID, or UINT64_MAX for the CRYPTO stream. */ + uint64_t stream_id; + /* + * The inclusive range of bytes in the stream. Exceptionally, if end < + * start, designates a frame of zero length (used for FIN-only frames). In + * this case end is the number of the final byte (i.e., one less than the + * final size of the stream). + */ + uint64_t start, end; + /* + * Whether a FIN was sent for this stream in the packet. Not valid for + * CRYPTO stream. + */ + unsigned int has_fin : 1; + /* + * If set, a STOP_SENDING frame was sent for this stream ID. (If no data was + * sent for the stream, set end < start.) + */ + unsigned int has_stop_sending : 1; + /* + * If set, a RESET_STREAM frame was sent for this stream ID. (If no data was + * sent for the stream, set end < start.) + */ + unsigned int has_reset_stream : 1; +} QUIC_TXPIM_CHUNK; + +QUIC_TXPIM *ossl_quic_txpim_new(void); + +/* + * Frees the TXPIM. All QUIC_TXPIM_PKTs which have been handed out by the TXPIM + * must be released via a call to ossl_quic_txpim_pkt_release() before calling + * this function. + */ +void ossl_quic_txpim_free(QUIC_TXPIM *txpim); + +/* + * Allocates a new QUIC_TXPIM_PKT structure from the pool. Returns NULL on + * failure. The returned structure is cleared of all data and is in a fresh + * initial state. + */ +QUIC_TXPIM_PKT *ossl_quic_txpim_pkt_alloc(QUIC_TXPIM *txpim); + +/* + * Releases the TXPIM packet, returning it to the pool. + */ +void ossl_quic_txpim_pkt_release(QUIC_TXPIM *txpim, QUIC_TXPIM_PKT *fpkt); + +/* Clears the chunk list of the packet, removing all entries. */ +void ossl_quic_txpim_pkt_clear_chunks(QUIC_TXPIM_PKT *fpkt); + +/* Appends a chunk to the packet. The structure is copied. */ +int ossl_quic_txpim_pkt_append_chunk(QUIC_TXPIM_PKT *fpkt, + const QUIC_TXPIM_CHUNK *chunk); + +/* Adds a CFQ item to the packet by prepending it to the retx_head list. */ +void ossl_quic_txpim_pkt_add_cfq_item(QUIC_TXPIM_PKT *fpkt, + QUIC_CFQ_ITEM *item); + +/* + * Returns a pointer to an array of stream chunk information structures for the + * given packet. The caller must call ossl_quic_txpim_pkt_get_num_chunks() to + * determine the length of this array. The returned pointer is invalidated + * if the chunk list is mutated, for example via a call to + * ossl_quic_txpim_pkt_append_chunk() or ossl_quic_txpim_pkt_clear_chunks(). + * + * The chunks are sorted by (stream_id, start) in ascending order. + */ +const QUIC_TXPIM_CHUNK *ossl_quic_txpim_pkt_get_chunks(const QUIC_TXPIM_PKT *fpkt); + +/* + * Returns the number of entries in the array returned by + * ossl_quic_txpim_pkt_get_chunks(). + */ +size_t ossl_quic_txpim_pkt_get_num_chunks(const QUIC_TXPIM_PKT *fpkt); + +/* + * Returns the number of QUIC_TXPIM_PKTs allocated by the given TXPIM that have + * yet to be returned to the TXPIM. + */ +size_t ossl_quic_txpim_get_in_use(const QUIC_TXPIM *txpim); + +# endif + +#endif diff --git a/include/internal/quic_types.h b/include/internal/quic_types.h new file mode 100644 index 0000000000..d42164ba56 --- /dev/null +++ b/include/internal/quic_types.h @@ -0,0 +1,116 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_TYPES_H +# define OSSL_QUIC_TYPES_H + +# include +# include +# include +# include + +# ifndef OPENSSL_NO_QUIC + +/* QUIC encryption levels. */ +enum { + QUIC_ENC_LEVEL_INITIAL = 0, + QUIC_ENC_LEVEL_HANDSHAKE, + QUIC_ENC_LEVEL_0RTT, + QUIC_ENC_LEVEL_1RTT, + QUIC_ENC_LEVEL_NUM /* Must be the ultimate entry */ +}; + +/* QUIC packet number spaces. */ +enum { + QUIC_PN_SPACE_INITIAL = 0, + QUIC_PN_SPACE_HANDSHAKE, + /* New entries must go here, so that QUIC_PN_SPACE_APP is the penultimate */ + QUIC_PN_SPACE_APP, + QUIC_PN_SPACE_NUM /* Must be the ultimate entry */ +}; + +static ossl_unused ossl_inline uint32_t +ossl_quic_enc_level_to_pn_space(uint32_t enc_level) +{ + switch (enc_level) { + case QUIC_ENC_LEVEL_INITIAL: + return QUIC_PN_SPACE_INITIAL; + case QUIC_ENC_LEVEL_HANDSHAKE: + return QUIC_PN_SPACE_HANDSHAKE; + case QUIC_ENC_LEVEL_0RTT: + case QUIC_ENC_LEVEL_1RTT: + return QUIC_PN_SPACE_APP; + default: + assert(0); + return QUIC_PN_SPACE_APP; + } +} + +/* QUIC packet number representation. */ +typedef uint64_t QUIC_PN; +# define QUIC_PN_INVALID UINT64_MAX + +static ossl_unused ossl_inline QUIC_PN ossl_quic_pn_max(QUIC_PN a, QUIC_PN b) +{ + return a > b ? a : b; +} + +static ossl_unused ossl_inline QUIC_PN ossl_quic_pn_min(QUIC_PN a, QUIC_PN b) +{ + return a < b ? a : b; +} + +static ossl_unused ossl_inline int ossl_quic_pn_valid(QUIC_PN pn) +{ + return pn < (((QUIC_PN)1) << 62); +} + +/* QUIC connection ID representation. */ +# define QUIC_MAX_CONN_ID_LEN 20 + +typedef struct quic_conn_id_st { + unsigned char id_len, id[QUIC_MAX_CONN_ID_LEN]; +} QUIC_CONN_ID; + +static ossl_unused ossl_inline int ossl_quic_conn_id_eq(const QUIC_CONN_ID *a, + const QUIC_CONN_ID *b) +{ + if (a->id_len != b->id_len || a->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + return memcmp(a->id, b->id, a->id_len) == 0; +} + +# define QUIC_MIN_INITIAL_DGRAM_LEN 1200 + +# define QUIC_DEFAULT_ACK_DELAY_EXP 3 +# define QUIC_MAX_ACK_DELAY_EXP 20 + +# define QUIC_DEFAULT_MAX_ACK_DELAY 25 + +# define QUIC_MIN_ACTIVE_CONN_ID_LIMIT 2 + +/* Arbitrary choice of default idle timeout (not an RFC value). */ +# define QUIC_DEFAULT_IDLE_TIMEOUT 30000 + +# define QUIC_STATELESS_RESET_TOKEN_LEN 16 + +typedef struct { + unsigned char token[QUIC_STATELESS_RESET_TOKEN_LEN]; +} QUIC_STATELESS_RESET_TOKEN; + +/* + * An encoded preferred_addr transport parameter cannot be shorter or longer + * than these lengths in bytes. + */ +# define QUIC_MIN_ENCODED_PREFERRED_ADDR_LEN 41 +# define QUIC_MAX_ENCODED_PREFERRED_ADDR_LEN 61 + +# endif + +#endif diff --git a/include/internal/quic_vlint.h b/include/internal/quic_vlint.h new file mode 100644 index 0000000000..d4b70b229c --- /dev/null +++ b/include/internal/quic_vlint.h @@ -0,0 +1,127 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_VLINT_H +# define OSSL_INTERNAL_QUIC_VLINT_H +# pragma once + +# include "internal/e_os.h" + +# ifndef OPENSSL_NO_QUIC + +/* The smallest value requiring a 1, 2, 4, or 8-byte representation. */ +#define OSSL_QUIC_VLINT_1B_MIN 0 +#define OSSL_QUIC_VLINT_2B_MIN 64 +#define OSSL_QUIC_VLINT_4B_MIN 16384 +#define OSSL_QUIC_VLINT_8B_MIN 1073741824 + +/* The largest value representable in a given number of bytes. */ +#define OSSL_QUIC_VLINT_1B_MAX (OSSL_QUIC_VLINT_2B_MIN - 1) +#define OSSL_QUIC_VLINT_2B_MAX (OSSL_QUIC_VLINT_4B_MIN - 1) +#define OSSL_QUIC_VLINT_4B_MAX (OSSL_QUIC_VLINT_8B_MIN - 1) +#define OSSL_QUIC_VLINT_8B_MAX (((uint64_t)1 << 62) - 1) + +/* The largest value representable as a variable-length integer. */ +#define OSSL_QUIC_VLINT_MAX OSSL_QUIC_VLINT_8B_MAX + +/* + * Returns the number of bytes needed to encode v in the QUIC variable-length + * integer encoding. + * + * Returns 0 if v exceeds OSSL_QUIC_VLINT_MAX. + */ +static ossl_unused ossl_inline size_t ossl_quic_vlint_encode_len(uint64_t v) +{ + if (v < OSSL_QUIC_VLINT_2B_MIN) + return 1; + + if (v < OSSL_QUIC_VLINT_4B_MIN) + return 2; + + if (v < OSSL_QUIC_VLINT_8B_MIN) + return 4; + + if (v <= OSSL_QUIC_VLINT_MAX) + return 8; + + return 0; +} + +/* + * This function writes a QUIC varable-length encoded integer to buf. + * The smallest usable representation is used. + * + * It is the caller's responsibility to ensure that the buffer is big enough by + * calling ossl_quic_vlint_encode_len(v) before calling this function. + * + * Precondition: buf is at least ossl_quic_vlint_enc_len(v) bytes in size + * (unchecked) + * Precondition: v does not exceed OSSL_QUIC_VLINT_MAX + * (unchecked) + */ +void ossl_quic_vlint_encode(unsigned char *buf, uint64_t v); + +/* + * This function writes a QUIC variable-length encoded integer to buf. The + * specified number of bytes n are used for the encoding, which means that the + * encoded value may take up more space than necessary. + * + * It is the caller's responsibility to ensure that the buffer is of at least n + * bytes, and that v is representable by a n-byte QUIC variable-length integer. + * The representable ranges are: + * + * 1-byte encoding: [0, 2** 6-1] + * 2-byte encoding: [0, 2**14-1] + * 4-byte encoding: [0, 2**30-1] + * 8-byte encoding: [0, 2**62-1] + * + * Precondition: buf is at least n bytes in size (unchecked) + * Precondition: v does not exceed the representable range + * (ossl_quic_vlint_encode_len(v) <= n) (unchecked) + * Precondition: v does not exceed OSSL_QUIC_VLINT_MAX + * (unchecked) + */ +void ossl_quic_vlint_encode_n(unsigned char *buf, uint64_t v, int n); + +/* + * Given the first byte of an encoded QUIC variable-length integer, returns + * the number of bytes comprising the encoded integer, including the first + * byte. + */ +static ossl_unused ossl_inline size_t ossl_quic_vlint_decode_len(uint8_t first_byte) +{ + return 1U << ((first_byte & 0xC0) >> 6); +} + +/* + * Given a buffer containing an encoded QUIC variable-length integer, returns + * the decoded value. The buffer must be of at least + * ossl_quic_vlint_decode_len(buf[0]) bytes in size, and the caller is responsible + * for checking this. + * + * Precondition: buf is at least ossl_quic_vlint_decode_len(buf[0]) bytes in size + * (unchecked) + */ +uint64_t ossl_quic_vlint_decode_unchecked(const unsigned char *buf); + +/* + * Given a buffer buf of buf_len bytes in length, attempts to decode an encoded + * QUIC variable-length integer at the start of the buffer and writes the result + * to *v. If buf_len is inadequate, suggesting a truncated encoded integer, the + * function fails and 0 is returned. Otherwise, returns the number of bytes + * consumed. + * + * Precondition: buf is at least buf_len bytes in size + * Precondition: v (unchecked) + */ +int ossl_quic_vlint_decode(const unsigned char *buf, size_t buf_len, uint64_t *v); + +# endif + +#endif diff --git a/include/internal/quic_wire.h b/include/internal/quic_wire.h new file mode 100644 index 0000000000..cd01feb036 --- /dev/null +++ b/include/internal/quic_wire.h @@ -0,0 +1,784 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_WIRE_H +# define OSSL_INTERNAL_QUIC_WIRE_H +# pragma once + +# include "internal/e_os.h" +# include "internal/time.h" +# include "internal/quic_types.h" +# include "internal/packet_quic.h" + +# ifndef OPENSSL_NO_QUIC + +# define OSSL_QUIC_FRAME_TYPE_PADDING 0x00 +# define OSSL_QUIC_FRAME_TYPE_PING 0x01 +# define OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN 0x02 +# define OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN 0x03 +# define OSSL_QUIC_FRAME_TYPE_RESET_STREAM 0x04 +# define OSSL_QUIC_FRAME_TYPE_STOP_SENDING 0x05 +# define OSSL_QUIC_FRAME_TYPE_CRYPTO 0x06 +# define OSSL_QUIC_FRAME_TYPE_NEW_TOKEN 0x07 +# define OSSL_QUIC_FRAME_TYPE_MAX_DATA 0x10 +# define OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA 0x11 +# define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI 0x12 +# define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI 0x13 +# define OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED 0x14 +# define OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED 0x15 +# define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI 0x16 +# define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI 0x17 +# define OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID 0x18 +# define OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID 0x19 +# define OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE 0x1A +# define OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE 0x1B +# define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT 0x1C +# define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP 0x1D +# define OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE 0x1E + +# define OSSL_QUIC_FRAME_FLAG_STREAM_FIN 0x01 +# define OSSL_QUIC_FRAME_FLAG_STREAM_LEN 0x02 +# define OSSL_QUIC_FRAME_FLAG_STREAM_OFF 0x04 +# define OSSL_QUIC_FRAME_FLAG_STREAM_MASK ((uint64_t)0x07) + +/* Low 3 bits of the type contain flags */ +# define OSSL_QUIC_FRAME_TYPE_STREAM 0x08 /* base ID */ +# define OSSL_QUIC_FRAME_TYPE_STREAM_FIN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_FIN) +# define OSSL_QUIC_FRAME_TYPE_STREAM_LEN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_LEN) +# define OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_LEN | \ + OSSL_QUIC_FRAME_FLAG_STREAM_FIN) +# define OSSL_QUIC_FRAME_TYPE_STREAM_OFF \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_OFF) +# define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_OFF | \ + OSSL_QUIC_FRAME_FLAG_STREAM_FIN) +# define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_OFF | \ + OSSL_QUIC_FRAME_FLAG_STREAM_LEN) +# define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN \ + (OSSL_QUIC_FRAME_TYPE_STREAM | \ + OSSL_QUIC_FRAME_FLAG_STREAM_OFF | \ + OSSL_QUIC_FRAME_FLAG_STREAM_LEN | \ + OSSL_QUIC_FRAME_FLAG_STREAM_FIN) + +# define OSSL_QUIC_FRAME_TYPE_IS_STREAM(x) \ + (((x) & ~OSSL_QUIC_FRAME_FLAG_STREAM_MASK) == OSSL_QUIC_FRAME_TYPE_STREAM) +# define OSSL_QUIC_FRAME_TYPE_IS_ACK(x) \ + (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN) +# define OSSL_QUIC_FRAME_TYPE_IS_MAX_STREAMS(x) \ + (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI) +# define OSSL_QUIC_FRAME_TYPE_IS_STREAMS_BLOCKED(x) \ + (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI) +# define OSSL_QUIC_FRAME_TYPE_IS_CONN_CLOSE(x) \ + (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT) + +const char *ossl_quic_frame_type_to_string(uint64_t frame_type); + +static ossl_unused ossl_inline int +ossl_quic_frame_type_is_ack_eliciting(uint64_t frame_type) +{ + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_PADDING: + case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + return 0; + default: + return 1; + } +} + +/* QUIC Transport Parameter Types */ +# define QUIC_TPARAM_ORIG_DCID 0x00 +# define QUIC_TPARAM_MAX_IDLE_TIMEOUT 0x01 +# define QUIC_TPARAM_STATELESS_RESET_TOKEN 0x02 +# define QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE 0x03 +# define QUIC_TPARAM_INITIAL_MAX_DATA 0x04 +# define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05 +# define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 0x06 +# define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI 0x07 +# define QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI 0x08 +# define QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI 0x09 +# define QUIC_TPARAM_ACK_DELAY_EXP 0x0A +# define QUIC_TPARAM_MAX_ACK_DELAY 0x0B +# define QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION 0x0C +# define QUIC_TPARAM_PREFERRED_ADDR 0x0D +# define QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT 0x0E +# define QUIC_TPARAM_INITIAL_SCID 0x0F +# define QUIC_TPARAM_RETRY_SCID 0x10 + +/* + * QUIC Frame Logical Representations + * ================================== + */ + +/* QUIC Frame: ACK */ +typedef struct ossl_quic_ack_range_st { + /* + * Represents an inclusive range of packet numbers [start, end]. + * start must be <= end. + */ + QUIC_PN start, end; +} OSSL_QUIC_ACK_RANGE; + +typedef struct ossl_quic_frame_ack_st { + /* + * A sequence of packet number ranges [[start, end]...]. + * + * The ranges must be sorted in descending order, for example: + * [ 95, 100] + * [ 90, 92] + * etc. + * + * As such, ack_ranges[0].end is always the highest packet number + * being acknowledged and ack_ranges[num_ack_ranges-1].start is + * always the lowest packet number being acknowledged. + * + * num_ack_ranges must be greater than zero, as an ACK frame must + * acknowledge at least one packet number. + */ + OSSL_QUIC_ACK_RANGE *ack_ranges; + size_t num_ack_ranges; + + OSSL_TIME delay_time; + uint64_t ect0, ect1, ecnce; + unsigned int ecn_present : 1; +} OSSL_QUIC_FRAME_ACK; + +/* Returns 1 if the given frame contains the given PN. */ +int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn); + +/* QUIC Frame: STREAM */ +typedef struct ossl_quic_frame_stream_st { + uint64_t stream_id; /* Stream ID */ + uint64_t offset; /* Logical offset in stream */ + uint64_t len; /* Length of data in bytes */ + const unsigned char *data; + + /* + * On encode, this determines whether the len field should be encoded or + * not. If zero, the len field is not encoded and it is assumed the frame + * runs to the end of the packet. + * + * On decode, this determines whether the frame had an explicitly encoded + * length. If not set, the frame runs to the end of the packet and len has + * been set accordingly. + */ + unsigned int has_explicit_len : 1; + + /* 1 if this is the end of the stream */ + unsigned int is_fin : 1; +} OSSL_QUIC_FRAME_STREAM; + +/* QUIC Frame: CRYPTO */ +typedef struct ossl_quic_frame_crypto_st { + uint64_t offset; /* Logical offset in stream */ + uint64_t len; /* Length of the data in bytes */ + const unsigned char *data; +} OSSL_QUIC_FRAME_CRYPTO; + +/* QUIC Frame: RESET_STREAM */ +typedef struct ossl_quic_frame_reset_stream_st { + uint64_t stream_id; + uint64_t app_error_code; + uint64_t final_size; +} OSSL_QUIC_FRAME_RESET_STREAM; + +/* QUIC Frame: STOP_SENDING */ +typedef struct ossl_quic_frame_stop_sending_st { + uint64_t stream_id; + uint64_t app_error_code; +} OSSL_QUIC_FRAME_STOP_SENDING; + +/* QUIC Frame: NEW_CONNECTION_ID */ +typedef struct ossl_quic_frame_new_conn_id_st { + uint64_t seq_num; + uint64_t retire_prior_to; + QUIC_CONN_ID conn_id; + QUIC_STATELESS_RESET_TOKEN stateless_reset; +} OSSL_QUIC_FRAME_NEW_CONN_ID; + +/* QUIC Frame: CONNECTION_CLOSE */ +typedef struct ossl_quic_frame_conn_close_st { + unsigned int is_app : 1; /* 0: transport error, 1: app error */ + uint64_t error_code; /* 62-bit transport or app error code */ + uint64_t frame_type; /* transport errors only */ + char *reason; /* UTF-8 string, not necessarily zero-terminated */ + size_t reason_len; /* Length of reason in bytes */ +} OSSL_QUIC_FRAME_CONN_CLOSE; + +/* + * QUIC Wire Format Encoding + * ========================= + * + * These functions return 1 on success and 0 on failure. + */ + +/* + * Encodes zero or more QUIC PADDING frames to the packet writer. Each PADDING + * frame consumes one byte; num_bytes specifies the number of bytes of padding + * to write. + */ +int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes); + +/* + * Encodes a QUIC PING frame to the packet writer. This frame type takes + * no arguments. +*/ +int ossl_quic_wire_encode_frame_ping(WPACKET *pkt); + +/* + * Encodes a QUIC ACK frame to the packet writer, given a logical representation + * of the ACK frame. + * + * The ACK ranges passed must be sorted in descending order. + * + * The logical representation stores a list of packet number ranges. The wire + * encoding is slightly different and stores the first range in the list + * in a different manner. + * + * The ack_delay_exponent argument specifies the index of a power of two by + * which the ack->ack_delay field is be divided. This exponent value must match + * the value used when decoding. + */ +int ossl_quic_wire_encode_frame_ack(WPACKET *pkt, + uint32_t ack_delay_exponent, + const OSSL_QUIC_FRAME_ACK *ack); + +/* + * Encodes a QUIC RESET_STREAM frame to the packet writer, given a logical + * representation of the RESET_STREAM frame. + */ +int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt, + const OSSL_QUIC_FRAME_RESET_STREAM *f); + +/* + * Encodes a QUIC STOP_SENDING frame to the packet writer, given a logical + * representation of the STOP_SENDING frame. + */ +int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt, + const OSSL_QUIC_FRAME_STOP_SENDING *f); + +/* + * Encodes a QUIC CRYPTO frame header to the packet writer. + * + * To create a well-formed frame, the data written using this function must be + * immediately followed by f->len bytes of data. + */ +int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *hdr, + const OSSL_QUIC_FRAME_CRYPTO *f); + +/* + * Returns the number of bytes which will be required to encode the given + * CRYPTO frame header. Does not include the payload bytes in the count. + * Returns 0 if input is invalid. + */ +size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f); + +/* + * Encodes a QUIC CRYPTO frame to the packet writer. + * + * This function returns a pointer to a buffer of f->len bytes which the caller + * should fill however it wishes. If f->data is non-NULL, it is automatically + * copied to the target buffer, otherwise the caller must fill the returned + * buffer. Returns NULL on failure. + */ +void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt, + const OSSL_QUIC_FRAME_CRYPTO *f); + +/* + * Encodes a QUIC NEW_TOKEN frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt, + const unsigned char *token, + size_t token_len); + +/* + * Encodes a QUIC STREAM frame's header to the packet writer. The f->stream_id, + * f->offset and f->len fields are the values for the respective Stream ID, + * Offset and Length fields. + * + * If f->is_fin is non-zero, the frame is marked as the final frame in the + * stream. + * + * If f->has_explicit_len is zerro, the frame is assumed to be the final frame + * in the packet, which the caller is responsible for ensuring; the Length + * field is then omitted. + * + * To create a well-formed frame, the data written using this function must be + * immediately followed by f->len bytes of stream data. + */ +int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt, + const OSSL_QUIC_FRAME_STREAM *f); + +/* + * Returns the number of bytes which will be required to encode the given + * STREAM frame header. Does not include the payload bytes in the count. + * Returns 0 if input is invalid. + */ +size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f); + +/* + * Functions similarly to ossl_quic_wire_encode_frame_stream_hdr, but it also + * allocates space for f->len bytes of data after the header, creating a + * well-formed QUIC STREAM frame in one call. + * + * A pointer to the bytes allocated for the framme payload is returned, + * which the caller can fill however it wishes. If f->data is non-NULL, + * it is automatically copied to the target buffer, otherwise the caller + * must fill the returned buffer. Returns NULL on failure. + */ +void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt, + const OSSL_QUIC_FRAME_STREAM *f); + +/* + * Encodes a QUIC MAX_DATA frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt, + uint64_t max_data); + +/* + * Encodes a QUIC MAX_STREAM_DATA frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt, + uint64_t stream_id, + uint64_t max_data); + +/* + * Encodes a QUIC MAX_STREAMS frame to the packet writer. + * + * If is_uni is 0, the count specifies the maximum number of + * bidirectional streams; else it specifies the maximum number of unidirectional + * streams. + */ +int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt, + char is_uni, + uint64_t max_streams); + +/* + * Encodes a QUIC DATA_BLOCKED frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt, + uint64_t max_data); + +/* + * Encodes a QUIC STREAM_DATA_BLOCKED frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt, + uint64_t stream_id, + uint64_t max_stream_data); +/* + * Encodes a QUIC STREAMS_BLOCKED frame to the packet writer. + * + * If is_uni is 0, the count specifies the maximum number of + * bidirectional streams; else it specifies the maximum number of unidirectional + * streams. + */ +int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt, + char is_uni, + uint64_t max_streams); + +/* + * Encodes a QUIC NEW_CONNECTION_ID frame to the packet writer, given a logical + * representation of the NEW_CONNECTION_ID frame. + * + * The buffer pointed to by the conn_id field must be valid for the duration of + * the call. + */ +int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt, + const OSSL_QUIC_FRAME_NEW_CONN_ID *f); + +/* + * Encodes a QUIC RETIRE_CONNECTION_ID frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt, + uint64_t seq_num); + +/* + * Encodes a QUIC PATH_CHALLENGE frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt, + uint64_t data); + +/* + * Encodes a QUIC PATH_RESPONSE frame to the packet writer. + */ +int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt, + uint64_t data); + +/* + * Encodes a QUIC CONNECTION_CLOSE frame to the packet writer, given a logical + * representation of the CONNECTION_CLOSE frame. + * + * The reason field may be NULL, in which case no reason is encoded. If the + * reason field is non-NULL, it must point to a valid UTF-8 string and + * reason_len must be set to the length of the reason string in bytes. The + * reason string need not be zero terminated. + */ +int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt, + const OSSL_QUIC_FRAME_CONN_CLOSE *f); + +/* + * Encodes a QUIC HANDSHAKE_DONE frame to the packet writer. This frame type + * takes no arguiments. + */ +int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt); + +/* + * Encodes a QUIC transport parameter TLV with the given ID into the WPACKET. + * The payload is an arbitrary buffer. + * + * If value is non-NULL, the value is copied into the packet. + * If it is NULL, value_len bytes are allocated for the payload and the caller + * should fill the buffer using the returned pointer. + * + * Returns a pointer to the start of the payload on success, or NULL on failure. + */ +unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt, + uint64_t id, + const unsigned char *value, + size_t value_len); + +/* + * Encodes a QUIC transport parameter TLV with the given ID into the WPACKET. + * The payload is a QUIC variable-length integer with the given value. + */ +int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt, + uint64_t id, + uint64_t value); + +/* + * Encodes a QUIC transport parameter TLV with a given ID into the WPACKET. + * The payload is a QUIC connection ID. + */ +int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt, + uint64_t id, + const QUIC_CONN_ID *cid); + +/* + * QUIC Wire Format Decoding + * ========================= + * + * These functions return 1 on success or 0 for failure. Typical reasons + * why these functions may fail include: + * + * - A frame decode function is called but the frame in the PACKET's buffer + * is not of the correct type. + * + * - A variable-length field in the encoded frame appears to exceed the bounds + * of the PACKET's buffer. + * + * These functions should be called with the PACKET pointing to the start of the + * frame (including the initial type field), and consume an entire frame + * including its type field. The expectation is that the caller will have + * already discerned the frame type using ossl_quic_wire_peek_frame_header(). + */ + +/* + * Decodes the type field header of a QUIC frame (without advancing the current + * position). This can be used to determine the frame type and determine which + * frame decoding function to call. + */ +int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type, + int *was_minimal); + +/* + * Like ossl_quic_wire_peek_frame_header, but advances the current position + * so that the type field is consumed. For advanced use only. + */ +int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type); + +/* + * Determines how many ranges are needed to decode a QUIC ACK frame. + * + * The number of ranges which must be allocated before the call to + * ossl_quic_wire_decode_frame_ack is written to *total_ranges. + * + * The PACKET is not advanced. + */ +int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *pkt, + uint64_t *total_ranges); + +/* + * Decodes a QUIC ACK frame. The ack_ranges field of the passed structure should + * point to a preallocated array of ACK ranges and the num_ack_ranges field + * should specify the length of allocation. + * + * *total_ranges is written with the number of ranges in the decoded frame, + * which may be greater than the number of ranges which were decoded (i.e. if + * num_ack_ranges was too small to decode all ranges). + * + * On success, this function modifies the num_ack_ranges field to indicate the + * number of ranges in the decoded frame. This is the number of entries in the + * ACK ranges array written by this function; any additional entries are not + * modified. + * + * If the number of ACK ranges in the decoded frame exceeds that in + * num_ack_ranges, as many ACK ranges as possible are decoded into the range + * array. The caller can use the value written to *total_ranges to detect this + * condition, as *total_ranges will exceed num_ack_ranges. + * + * If ack is NULL, the frame is still decoded, but only *total_ranges is + * written. This can be used to determine the number of ranges which must be + * allocated. + * + * The ack_delay_exponent argument specifies the index of a power of two used to + * decode the ack_delay field. This must match the ack_delay_exponent value used + * to encode the frame. + */ +int ossl_quic_wire_decode_frame_ack(PACKET *pkt, + uint32_t ack_delay_exponent, + OSSL_QUIC_FRAME_ACK *ack, + uint64_t *total_ranges); + +/* + * Decodes a QUIC RESET_STREAM frame. + */ +int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt, + OSSL_QUIC_FRAME_RESET_STREAM *f); + +/* + * Decodes a QUIC STOP_SENDING frame. + */ +int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt, + OSSL_QUIC_FRAME_STOP_SENDING *f); + +/* + * Decodes a QUIC CRYPTO frame. + * + * f->data is set to point inside the packet buffer inside the PACKET, therefore + * it is safe to access for as long as the packet buffer exists. If nodata is + * set to 1 then reading the PACKET stops after the frame header and f->data is + * set to NULL. + */ +int ossl_quic_wire_decode_frame_crypto(PACKET *pkt, int nodata, + OSSL_QUIC_FRAME_CRYPTO *f); + +/* + * Decodes a QUIC NEW_TOKEN frame. *token is written with a pointer to the token + * bytes and *token_len is written with the length of the token in bytes. + */ +int ossl_quic_wire_decode_frame_new_token(PACKET *pkt, + const unsigned char **token, + size_t *token_len); + +/* + * Decodes a QUIC STREAM frame. + * + * If nodata is set to 1 then reading the PACKET stops after the frame header + * and f->data is set to NULL. In this case f->len will also be 0 in the event + * that "has_explicit_len" is 0. + * + * If the frame did not contain an offset field, f->offset is set to 0, as the + * absence of an offset field is equivalent to an offset of 0. + * + * If the frame contained a length field, f->has_explicit_len is set to 1 and + * the length of the data is placed in f->len. This function ensures that the + * length does not exceed the packet buffer, thus it is safe to access f->data. + * + * If the frame did not contain a length field, this means that the frame runs + * until the end of the packet. This function sets f->has_explicit_len to zero, + * and f->len to the amount of data remaining in the input buffer. Therefore, + * this function should be used with a PACKET representing a single packet (and + * not e.g. multiple packets). + * + * Note also that this means f->len is always valid after this function returns + * successfully, regardless of the value of f->has_explicit_len. + * + * f->data points inside the packet buffer inside the PACKET, therefore it is + * safe to access for as long as the packet buffer exists. + * + * f->is_fin is set according to whether the frame was marked as ending the + * stream. + */ +int ossl_quic_wire_decode_frame_stream(PACKET *pkt, int nodata, + OSSL_QUIC_FRAME_STREAM *f); + +/* + * Decodes a QUIC MAX_DATA frame. The Maximum Data field is written to + * *max_data. + */ +int ossl_quic_wire_decode_frame_max_data(PACKET *pkt, + uint64_t *max_data); + +/* + * Decodes a QUIC MAX_STREAM_DATA frame. The Stream ID is written to *stream_id + * and Maximum Stream Data field is written to *max_stream_data. + */ +int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt, + uint64_t *stream_id, + uint64_t *max_stream_data); +/* + * Decodes a QUIC MAX_STREAMS frame. The Maximum Streams field is written to + * *max_streams. + * + * Whether the limit concerns bidirectional streams or unidirectional streams is + * denoted by the frame type; the caller should examine the frame type to + * determine this. + */ +int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt, + uint64_t *max_streams); + +/* + * Decodes a QUIC DATA_BLOCKED frame. The Maximum Data field is written to + * *max_data. + */ +int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt, + uint64_t *max_data); + +/* + * Decodes a QUIC STREAM_DATA_BLOCKED frame. The Stream ID and Maximum Stream + * Data fields are written to *stream_id and *max_stream_data respectively. + */ +int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt, + uint64_t *stream_id, + uint64_t *max_stream_data); + +/* + * Decodes a QUIC STREAMS_BLOCKED frame. The Maximum Streams field is written to + * *max_streams. + * + * Whether the limit concerns bidirectional streams or unidirectional streams is + * denoted by the frame type; the caller should examine the frame type to + * determine this. + */ +int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt, + uint64_t *max_streams); + + +/* + * Decodes a QUIC NEW_CONNECTION_ID frame. The logical representation of the + * frame is written to *f. + * + * The conn_id field is set to point to the connection ID string inside the + * packet buffer; it is therefore valid for as long as the PACKET's buffer is + * valid. The conn_id_len field is set to the length of the connection ID string + * in bytes. + */ +int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt, + OSSL_QUIC_FRAME_NEW_CONN_ID *f); + +/* + * Decodes a QUIC RETIRE_CONNECTION_ID frame. The Sequence Number field + * is written to *seq_num. + */ +int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt, + uint64_t *seq_num); + +/* + * Decodes a QUIC PATH_CHALLENGE frame. The Data field is written to *data. + */ +int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt, + uint64_t *data); + +/* + * Decodes a QUIC PATH_CHALLENGE frame. The Data field is written to *data. + */ +int ossl_quic_wire_decode_frame_path_response(PACKET *pkt, + uint64_t *data); + +/* + * Decodes a QUIC CONNECTION_CLOSE frame. The logical representation + * of the frame is written to *f. + * + * The reason field is set to point to the UTF-8 reason string inside + * the packet buffer; it is therefore valid for as long as the PACKET's + * buffer is valid. The reason_len field is set to the length of the + * reason string in bytes. + * + * IMPORTANT: The reason string is not zero-terminated. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt, + OSSL_QUIC_FRAME_CONN_CLOSE *f); + +/* + * Decodes one or more PADDING frames. PADDING frames have no arguments. + * + * Returns the number of PADDING frames decoded or 0 on error. + */ +size_t ossl_quic_wire_decode_padding(PACKET *pkt); + +/* + * Decodes a PING frame. The frame has no arguments. + */ +int ossl_quic_wire_decode_frame_ping(PACKET *pkt); + +/* + * Decodes a HANDSHAKE_DONE frame. The frame has no arguments. + */ +int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt); + +/* + * Peeks at the ID of the next QUIC transport parameter TLV in the stream. + * The ID is written to *id. + */ +int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id); + +/* + * Decodes a QUIC transport parameter TLV. A pointer to the value buffer is + * returned on success. This points inside the PACKET's buffer and is therefore + * valid as long as the PACKET's buffer is valid. + * + * The transport parameter ID is written to *id (if non-NULL) and the length of + * the payload in bytes is written to *len. + * + * Returns NULL on failure. + */ +const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt, + uint64_t *id, + size_t *len); + +/* + * Decodes a QUIC transport parameter TLV containing a variable-length integer. + * + * The transport parameter ID is written to *id (if non-NULL) and the value is + * written to *value. + */ +int ossl_quic_wire_decode_transport_param_int(PACKET *pkt, + uint64_t *id, + uint64_t *value); + +/* + * Decodes a QUIC transport parameter TLV containing a connection ID. + * + * The transport parameter ID is written to *id (if non-NULL) and the value is + * written to *value. + */ +int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt, + uint64_t *id, + QUIC_CONN_ID *cid); + +/* + * Decodes a QUIC transport parameter TLV containing a preferred_address. + */ +typedef struct quic_preferred_addr_st { + uint16_t ipv4_port, ipv6_port; + unsigned char ipv4[4], ipv6[16]; + QUIC_STATELESS_RESET_TOKEN stateless_reset; + QUIC_CONN_ID cid; +} QUIC_PREFERRED_ADDR; + +int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt, + QUIC_PREFERRED_ADDR *p); + +# endif + +#endif diff --git a/include/internal/quic_wire_pkt.h b/include/internal/quic_wire_pkt.h new file mode 100644 index 0000000000..18a483fc2c --- /dev/null +++ b/include/internal/quic_wire_pkt.h @@ -0,0 +1,629 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_WIRE_PKT_H +# define OSSL_QUIC_WIRE_PKT_H + +# include +# include "internal/packet_quic.h" +# include "internal/quic_types.h" + +# ifndef OPENSSL_NO_QUIC + +# define QUIC_VERSION_NONE ((uint32_t)0) /* Used for version negotiation */ +# define QUIC_VERSION_1 ((uint32_t)1) /* QUIC v1 */ + +/* QUIC logical packet type. These do not match wire values. */ +# define QUIC_PKT_TYPE_INITIAL 1 +# define QUIC_PKT_TYPE_0RTT 2 +# define QUIC_PKT_TYPE_HANDSHAKE 3 +# define QUIC_PKT_TYPE_RETRY 4 +# define QUIC_PKT_TYPE_1RTT 5 +# define QUIC_PKT_TYPE_VERSION_NEG 6 + +/* + * Determine encryption level from packet type. Returns QUIC_ENC_LEVEL_NUM if + * the packet is not of a type which is encrypted. + */ +static ossl_inline ossl_unused uint32_t +ossl_quic_pkt_type_to_enc_level(uint32_t pkt_type) +{ + switch (pkt_type) { + case QUIC_PKT_TYPE_INITIAL: + return QUIC_ENC_LEVEL_INITIAL; + case QUIC_PKT_TYPE_HANDSHAKE: + return QUIC_ENC_LEVEL_HANDSHAKE; + case QUIC_PKT_TYPE_0RTT: + return QUIC_ENC_LEVEL_0RTT; + case QUIC_PKT_TYPE_1RTT: + return QUIC_ENC_LEVEL_1RTT; + default: + return QUIC_ENC_LEVEL_NUM; + } +} + +static ossl_inline ossl_unused uint32_t +ossl_quic_enc_level_to_pkt_type(uint32_t enc_level) +{ + switch (enc_level) { + case QUIC_ENC_LEVEL_INITIAL: + return QUIC_PKT_TYPE_INITIAL; + case QUIC_ENC_LEVEL_HANDSHAKE: + return QUIC_PKT_TYPE_HANDSHAKE; + case QUIC_ENC_LEVEL_0RTT: + return QUIC_PKT_TYPE_0RTT; + case QUIC_ENC_LEVEL_1RTT: + return QUIC_PKT_TYPE_1RTT; + default: + return UINT32_MAX; + } +} + +/* Determine if a packet type contains an encrypted payload. */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_is_encrypted(uint32_t pkt_type) +{ + switch (pkt_type) { + case QUIC_PKT_TYPE_RETRY: + case QUIC_PKT_TYPE_VERSION_NEG: + return 0; + default: + return 1; + } +} + +/* Determine if a packet type contains a PN field. */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_has_pn(uint32_t pkt_type) +{ + /* + * Currently a packet has a PN iff it is encrypted. This could change + * someday. + */ + return ossl_quic_pkt_type_is_encrypted(pkt_type); +} + +/* + * Determine if a packet type can appear with other packets in a datagram. Some + * packet types must be the sole packet in a datagram. + */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_can_share_dgram(uint32_t pkt_type) +{ + /* + * Currently only the encrypted packet types can share a datagram. This + * could change someday. + */ + return ossl_quic_pkt_type_is_encrypted(pkt_type); +} + +/* + * Determine if the packet type must come at the end of the datagram (due to the + * lack of a length field). + */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_must_be_last(uint32_t pkt_type) +{ + /* + * Any packet type which cannot share a datagram obviously must come last. + * 1-RTT also must come last as it lacks a length field. + */ + return !ossl_quic_pkt_type_can_share_dgram(pkt_type) + || pkt_type == QUIC_PKT_TYPE_1RTT; +} + +/* + * Determine if the packet type has a version field. + */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_has_version(uint32_t pkt_type) +{ + return pkt_type != QUIC_PKT_TYPE_1RTT && pkt_type != QUIC_PKT_TYPE_VERSION_NEG; +} + +/* + * Determine if the packet type has a SCID field. + */ +static ossl_inline ossl_unused int +ossl_quic_pkt_type_has_scid(uint32_t pkt_type) +{ + return pkt_type != QUIC_PKT_TYPE_1RTT; +} + +/* + * Smallest possible QUIC packet size as per RFC (aside from version negotiation + * packets). + */ +# define QUIC_MIN_VALID_PKT_LEN_CRYPTO 21 +# define QUIC_MIN_VALID_PKT_LEN_VERSION_NEG 7 +# define QUIC_MIN_VALID_PKT_LEN QUIC_MIN_VALID_PKT_LEN_VERSION_NEG + +typedef struct quic_pkt_hdr_ptrs_st QUIC_PKT_HDR_PTRS; + +/* + * QUIC Packet Header Protection + * ============================= + * + * Functions to apply and remove QUIC packet header protection. A header + * protector is initialised using ossl_quic_hdr_protector_init and must be + * destroyed using ossl_quic_hdr_protector_cleanup when no longer needed. + */ +typedef struct quic_hdr_protector_st { + OSSL_LIB_CTX *libctx; + const char *propq; + EVP_CIPHER_CTX *cipher_ctx; + EVP_CIPHER *cipher; + uint32_t cipher_id; +} QUIC_HDR_PROTECTOR; + +# define QUIC_HDR_PROT_CIPHER_AES_128 1 +# define QUIC_HDR_PROT_CIPHER_AES_256 2 +# define QUIC_HDR_PROT_CIPHER_CHACHA 3 + +/* + * Initialises a header protector. + * + * cipher_id: + * The header protection cipher method to use. One of + * QUIC_HDR_PROT_CIPHER_*. Must be chosen based on negotiated TLS cipher + * suite. + * + * quic_hp_key: + * This must be the "quic hp" key derived from a traffic secret. + * + * The length of the quic_hp_key must correspond to that expected for the + * given cipher ID. + * + * The header protector performs amortisable initialisation in this function, + * therefore a header protector should be used for as long as possible. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr, + OSSL_LIB_CTX *libctx, + const char *propq, + uint32_t cipher_id, + const unsigned char *quic_hp_key, + size_t quic_hp_key_len); + +/* + * Destroys a header protector. This is also safe to call on a zero-initialized + * OSSL_QUIC_HDR_PROTECTOR structure which has not been initialized, or which + * has already been destroyed. + */ +void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr); + +/* + * Removes header protection from a packet. The packet payload must currently be + * encrypted (i.e., you must remove header protection before decrypting packets + * received). The function examines the header buffer to determine which bytes + * of the header need to be decrypted. + * + * If this function fails, no data is modified. + * + * This is implemented as a call to ossl_quic_hdr_protector_decrypt_fields(). + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr, + QUIC_PKT_HDR_PTRS *ptrs); + +/* + * Applies header protection to a packet. The packet payload must already have + * been encrypted (i.e., you must apply header protection after encrypting + * a packet). The function examines the header buffer to determine which bytes + * of the header need to be encrypted. + * + * This is implemented as a call to ossl_quic_hdr_protector_encrypt_fields(). + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr, + QUIC_PKT_HDR_PTRS *ptrs); + +/* + * Removes header protection from a packet. The packet payload must currently + * be encrypted. This is a low-level function which assumes you have already + * determined which parts of the packet header need to be decrypted. + * + * sample: + * The range of bytes in the packet to be used to generate the header + * protection mask. It is permissible to set sample_len to the size of the + * remainder of the packet; this function will only use as many bytes as + * needed. If not enough sample bytes are provided, this function fails. + * + * first_byte: + * The first byte of the QUIC packet header to be decrypted. + * + * pn: + * Pointer to the start of the PN field. The caller is responsible + * for ensuring at least four bytes follow this pointer. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr, + const unsigned char *sample, + size_t sample_len, + unsigned char *first_byte, + unsigned char *pn_bytes); + +/* + * Works analogously to ossl_hdr_protector_decrypt_fields, but applies header + * protection instead of removing it. + */ +int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr, + const unsigned char *sample, + size_t sample_len, + unsigned char *first_byte, + unsigned char *pn_bytes); + +/* + * QUIC Packet Header + * ================== + * + * This structure provides a logical representation of a QUIC packet header. + * + * QUIC packet formats fall into the following categories: + * + * Long Packets, which is subdivided into five possible packet types: + * Version Negotiation (a special case); + * Initial; + * 0-RTT; + * Handshake; and + * Retry + * + * Short Packets, which comprises only a single packet type (1-RTT). + * + * The packet formats vary and common fields are found in some packets but + * not others. The below table indicates which fields are present in which + * kinds of packet. * indicates header protection is applied. + * + * SLLLLL Legend: 1=1-RTT, i=Initial, 0=0-RTT, h=Handshake + * 1i0hrv r=Retry, v=Version Negotiation + * ------ + * 1i0hrv Header Form (0=Short, 1=Long) + * 1i0hr Fixed Bit (always 1) + * 1 Spin Bit + * 1 * Reserved Bits + * 1 * Key Phase + * 1i0h * Packet Number Length + * i0hr? Long Packet Type + * i0h Type-Specific Bits + * i0hr Version (note: always 0 for Version Negotiation packets) + * 1i0hrv Destination Connection ID + * i0hrv Source Connection ID + * 1i0h * Packet Number + * i Token + * i0h Length + * r Retry Token + * r Retry Integrity Tag + * + * For each field below, the conditions under which the field is valid are + * specified. If a field is not currently valid, it is initialized to a zero or + * NULL value. + */ +typedef struct quic_pkt_hdr_st { + /* [ALL] A QUIC_PKT_TYPE_* value. Always valid. */ + unsigned int type :8; + + /* [S] Value of the spin bit. Valid if (type == 1RTT). */ + unsigned int spin_bit :1; + + /* + * [S] Value of the Key Phase bit in the short packet. + * Valid if (type == 1RTT && !partial). + */ + unsigned int key_phase :1; + + /* + * [1i0h] Length of packet number in bytes. This is the decoded value. + * Valid if ((type == 1RTT || (version && type != RETRY)) && !partial). + */ + unsigned int pn_len :4; + + /* + * [ALL] Set to 1 if this is a partial decode because the packet header + * has not yet been deprotected. pn_len, pn and key_phase are not valid if + * this is set. + */ + unsigned int partial :1; + + /* + * [ALL] Whether the fixed bit was set. Note that only Version Negotiation + * packets are allowed to have this unset, so this will always be 1 for all + * other packet types (decode will fail if it is not set). Ignored when + * encoding unless encoding a Version Negotiation packet. + */ + unsigned int fixed :1; + + /* + * The unused bits in the low 4 bits of a Retry packet header's first byte. + * This is used to ensure that Retry packets have the same bit-for-bit + * representation in their header when decoding and encoding them again. + * This is necessary to validate Retry packet headers. + */ + unsigned int unused :4; + + /* + * The 'Reserved' bits in an Initial, Handshake, 0-RTT or 1-RTT packet + * header's first byte. These are provided so that the caller can validate + * that they are zero, as this must be done after packet protection is + * successfully removed to avoid creating a timing channel. + */ + unsigned int reserved :2; + + /* [L] Version field. Valid if (type != 1RTT). */ + uint32_t version; + + /* [ALL] The destination connection ID. Always valid. */ + QUIC_CONN_ID dst_conn_id; + + /* + * [L] The source connection ID. + * Valid if (type != 1RTT). + */ + QUIC_CONN_ID src_conn_id; + + /* + * [1i0h] Relatively-encoded packet number in raw, encoded form. The correct + * decoding of this value is context-dependent. The number of bytes valid in + * this buffer is determined by pn_len above. If the decode was partial, + * this field is not valid. + * + * Valid if ((type == 1RTT || (version && type != RETRY)) && !partial). + */ + unsigned char pn[4]; + + /* + * [i] Token field in Initial packet. Points to memory inside the decoded + * PACKET, and therefore is valid for as long as the PACKET's buffer is + * valid. token_len is the length of the token in bytes. + * + * Valid if (type == INITIAL). + */ + const unsigned char *token; + size_t token_len; + + /* + * [ALL] Payload length in bytes. + * + * Though 1-RTT, Retry and Version Negotiation packets do not contain an + * explicit length field, this field is always valid and is used by the + * packet header encoding and decoding routines to describe the payload + * length, regardless of whether the packet type encoded or decoded uses an + * explicit length indication. + */ + size_t len; + + /* + * Pointer to start of payload data in the packet. Points to memory inside + * the decoded PACKET, and therefore is valid for as long as the PACKET'S + * buffer is valid. The length of the buffer in bytes is in len above. + * + * For Version Negotiation packets, points to the array of supported + * versions. + * + * For Retry packets, points to the Retry packet payload, which comprises + * the Retry Token followed by a 16-byte Retry Integrity Tag. + * + * Regardless of whether a packet is a Version Negotiation packet (where the + * payload contains a list of supported versions), a Retry packet (where the + * payload contains a Retry Token and Retry Integrity Tag), or any other + * packet type (where the payload contains frames), the payload is not + * validated and the user must parse the payload bearing this in mind. + * + * If the decode was partial (partial is set), this points to the start of + * the packet number field, rather than the protected payload, as the length + * of the packet number field is unknown. The len field reflects this in + * this case (i.e., the len field is the number of payload bytes plus the + * number of bytes comprising the PN). + */ + const unsigned char *data; +} QUIC_PKT_HDR; + +/* + * Extra information which can be output by the packet header decode functions + * for the assistance of the header protector. This avoids the header protector + * needing to partially re-decode the packet header. + */ +struct quic_pkt_hdr_ptrs_st { + unsigned char *raw_start; /* start of packet */ + unsigned char *raw_sample; /* start of sampling range */ + size_t raw_sample_len; /* maximum length of sampling range */ + + /* + * Start of PN field. Guaranteed to be NULL unless at least four bytes are + * available via this pointer. + */ + unsigned char *raw_pn; +}; + +/* + * If partial is 1, reads the unprotected parts of a protected packet header + * from a PACKET, performing a partial decode. + * + * If partial is 0, the input is assumed to have already had header protection + * removed, and all header fields are decoded. + * + * If nodata is 1, the input is assumed to have no payload data in it. Otherwise + * payload data must be present. + * + * On success, the logical decode of the packet header is written to *hdr. + * hdr->partial is set or cleared according to whether a partial decode was + * performed. *ptrs is filled with pointers to various parts of the packet + * buffer. + * + * In order to decode short packets, the connection ID length being used must be + * known contextually, and should be passed as short_conn_id_len. If + * short_conn_id_len is set to an invalid value (a value greater than + * QUIC_MAX_CONN_ID_LEN), this function fails when trying to decode a short + * packet, but succeeds for long packets. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt, + size_t short_conn_id_len, + int partial, + int nodata, + QUIC_PKT_HDR *hdr, + QUIC_PKT_HDR_PTRS *ptrs); + +/* + * Encodes a packet header. The packet is written to pkt. + * + * The length of the (encrypted) packet payload should be written to hdr->len + * and will be placed in the serialized packet header. The payload data itself + * is not copied; the caller should write hdr->len bytes of encrypted payload to + * the WPACKET immediately after the call to this function. However, + * WPACKET_reserve_bytes is called for the payload size. + * + * This function does not apply header protection. You must apply header + * protection yourself after calling this function. *ptrs is filled with + * pointers which can be passed to a header protector, but this must be + * performed after the encrypted payload is written. + * + * The pointers in *ptrs are direct pointers into the WPACKET buffer. If more + * data is written to the WPACKET buffer, WPACKET buffer reallocations may + * occur, causing these pointers to become invalid. Therefore, you must not call + * any write WPACKET function between this call and the call to + * ossl_quic_hdr_protector_encrypt. This function calls WPACKET_reserve_bytes + * for the payload length, so you may assume hdr->len bytes are already free to + * write at the WPACKET cursor location once this function returns successfully. + * It is recommended that you call this function, write the encrypted payload, + * call ossl_quic_hdr_protector_encrypt, and then call + * WPACKET_allocate_bytes(hdr->len). + * + * Version Negotiation and Retry packets do not use header protection; for these + * header types, the fields in *ptrs are all written as zero. Version + * Negotiation, Retry and 1-RTT packets do not contain a Length field, but + * hdr->len bytes of data are still reserved in the WPACKET. + * + * If serializing a short packet and short_conn_id_len does not match the DCID + * specified in hdr, the function fails. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt, + size_t short_conn_id_len, + const QUIC_PKT_HDR *hdr, + QUIC_PKT_HDR_PTRS *ptrs); + +/* + * Retrieves only the DCID from a packet header. This is intended for demuxer + * use. It avoids the need to parse the rest of the packet header twice. + * + * Information on packet length is not decoded, as this only needs to be used on + * the first packet in a datagram, therefore this takes a buffer and not a + * PACKET. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf, + size_t buf_len, + size_t short_conn_id_len, + QUIC_CONN_ID *dst_conn_id); + +/* + * Precisely predicts the encoded length of a packet header structure. + * + * May return 0 if the packet header is not valid, but the fact that this + * function returns non-zero does not guarantee that + * ossl_quic_wire_encode_pkt_hdr() will succeed. + */ +int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len, + const QUIC_PKT_HDR *hdr); + +/* + * Packet Number Encoding + * ====================== + */ + +/* + * Decode an encoded packet header QUIC PN. + * + * enc_pn is the raw encoded PN to decode. enc_pn_len is its length in bytes as + * indicated by packet headers. largest_pn is the largest PN successfully + * processed in the relevant PN space. + * + * The resulting PN is written to *res_pn. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn, + size_t enc_pn_len, + QUIC_PN largest_pn, + QUIC_PN *res_pn); + +/* + * Determine how many bytes should be used to encode a PN. Returns the number of + * bytes (which will be in range [1, 4]). + */ +int ossl_quic_wire_determine_pn_len(QUIC_PN pn, QUIC_PN largest_acked); + +/* + * Encode a PN for a packet header using the specified number of bytes, which + * should have been determined by calling ossl_quic_wire_determine_pn_len. The + * PN encoding process is done in two parts to allow the caller to override PN + * encoding length if it wishes. + * + * Returns 1 on success and 0 on failure. + */ +int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn, + unsigned char *enc_pn, + size_t enc_pn_len); + +/* + * Retry Integrity Tags + * ==================== + */ + +# define QUIC_RETRY_INTEGRITY_TAG_LEN 16 + +/* + * Validate a retry integrity tag. Returns 1 if the tag is valid. + * + * Must be called on a hdr with a type of QUIC_PKT_TYPE_RETRY with a valid data + * pointer. + * + * client_initial_dcid must be the original DCID used by the client in its first + * Initial packet, as this is used to calculate the Retry Integrity Tag. + * + * Returns 0 if the tag is invalid, if called on any other type of packet or if + * the body is too short. + */ +int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_PKT_HDR *hdr, + const QUIC_CONN_ID *client_initial_dcid); + +/* + * Calculates a retry integrity tag. Returns 0 on error, for example if hdr does + * not have a type of QUIC_PKT_TYPE_RETRY. + * + * client_initial_dcid must be the original DCID used by the client in its first + * Initial packet, as this is used to calculate the Retry Integrity Tag. + * + * tag must point to a buffer of QUIC_RETRY_INTEGRITY_TAG_LEN bytes in size. + * + * Note that hdr->data must point to the Retry packet body, and hdr->len must + * include the space for the Retry Integrity Tag. (This means that you can + * easily fill in a tag in a Retry packet you are generating by calling this + * function and passing (hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) as + * the tag argument.) This function fails if hdr->len is too short to contain a + * Retry Integrity Tag. + */ +int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_PKT_HDR *hdr, + const QUIC_CONN_ID *client_initial_dcid, + unsigned char *tag); + +# endif + +#endif diff --git a/include/internal/recordmethod.h b/include/internal/recordmethod.h new file mode 100644 index 0000000000..53bd4ca6d2 --- /dev/null +++ b/include/internal/recordmethod.h @@ -0,0 +1,339 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_RECORDMETHOD_H +# define OSSL_INTERNAL_RECORDMETHOD_H +# pragma once + +# include + +/* + * We use the term "record" here to refer to a packet of data. Records are + * typically protected via a cipher and MAC, or an AEAD cipher (although not + * always). This usage of the term record is consistent with the TLS concept. + * In QUIC the term "record" is not used but it is analogous to the QUIC term + * "packet". The interface in this file applies to all protocols that protect + * records/packets of data, i.e. (D)TLS and QUIC. The term record is used to + * refer to both contexts. + */ + +/* + * An OSSL_RECORD_METHOD is a protocol specific method which provides the + * functions for reading and writing records for that protocol. Which + * OSSL_RECORD_METHOD to use for a given protocol is defined by the SSL_METHOD. + */ +typedef struct ossl_record_method_st OSSL_RECORD_METHOD; + +/* + * An OSSL_RECORD_LAYER is just an externally defined opaque pointer created by + * the method + */ +typedef struct ossl_record_layer_st OSSL_RECORD_LAYER; + + +# define OSSL_RECORD_ROLE_CLIENT 0 +# define OSSL_RECORD_ROLE_SERVER 1 + +# define OSSL_RECORD_DIRECTION_READ 0 +# define OSSL_RECORD_DIRECTION_WRITE 1 + +/* + * Protection level. For <= TLSv1.2 only "NONE" and "APPLICATION" are used. + */ +# define OSSL_RECORD_PROTECTION_LEVEL_NONE 0 +# define OSSL_RECORD_PROTECTION_LEVEL_EARLY 1 +# define OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE 2 +# define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3 + +# define OSSL_RECORD_RETURN_SUCCESS 1 +# define OSSL_RECORD_RETURN_RETRY 0 +# define OSSL_RECORD_RETURN_NON_FATAL_ERR -1 +# define OSSL_RECORD_RETURN_FATAL -2 +# define OSSL_RECORD_RETURN_EOF -3 + +/* + * Template for creating a record. A record consists of the |type| of data it + * will contain (e.g. alert, handshake, application data, etc) along with a + * buffer of payload data in |buf| of length |buflen|. + */ +struct ossl_record_template_st { + unsigned char type; + unsigned int version; + const unsigned char *buf; + size_t buflen; +}; + +typedef struct ossl_record_template_st OSSL_RECORD_TEMPLATE; + +/* + * Rather than a "method" approach, we could make this fetchable - Should we? + * There could be some complexity in finding suitable record layer implementations + * e.g. we need to find one that matches the negotiated protocol, cipher, + * extensions, etc. The selection_cb approach given above doesn't work so well + * if unknown third party providers with OSSL_RECORD_METHOD implementations are + * loaded. + */ + +/* + * If this becomes public API then we will need functions to create and + * free an OSSL_RECORD_METHOD, as well as functions to get/set the various + * function pointers....unless we make it fetchable. + */ +struct ossl_record_method_st { + /* + * Create a new OSSL_RECORD_LAYER object for handling the protocol version + * set by |vers|. |role| is 0 for client and 1 for server. |direction| + * indicates either read or write. |level| is the protection level as + * described above. |settings| are mandatory settings that will cause the + * new() call to fail if they are not understood (for example to require + * Encrypt-Then-Mac support). |options| are optional settings that will not + * cause the new() call to fail if they are not understood (for example + * whether to use "read ahead" or not). + * + * The BIO in |transport| is the BIO for the underlying transport layer. + * Where the direction is "read", then this BIO will only ever be used for + * reading data. Where the direction is "write", then this BIO will only + * every be used for writing data. + * + * An SSL object will always have at least 2 OSSL_RECORD_LAYER objects in + * force at any one time (one for reading and one for writing). In some + * protocols more than 2 might be used (e.g. in DTLS for retransmitting + * messages from an earlier epoch). + * + * The created OSSL_RECORD_LAYER object is stored in *ret on success (or + * NULL otherwise). The return value will be one of + * OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or + * OSSL_RECORD_RETURN_NON_FATAL. A non-fatal return means that creation of + * the record layer has failed because it is unsuitable, but an alternative + * record layer can be tried instead. + */ + + /* + * If we eventually make this fetchable then we will need to use something + * other than EVP_CIPHER. Also mactype would not be a NID, but a string. For + * now though, this works. + */ + int (*new_record_layer)(OSSL_LIB_CTX *libctx, + const char *propq, int vers, + int role, int direction, + int level, + uint16_t epoch, + unsigned char *secret, + size_t secretlen, + unsigned char *key, + size_t keylen, + unsigned char *iv, + size_t ivlen, + unsigned char *mackey, + size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp, + const EVP_MD *kdfdigest, + BIO *prev, + BIO *transport, + BIO *next, + BIO_ADDR *local, + BIO_ADDR *peer, + const OSSL_PARAM *settings, + const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, + void *cbarg, + void *rlarg, + OSSL_RECORD_LAYER **ret); + int (*free)(OSSL_RECORD_LAYER *rl); + + /* Returns 1 if we have unprocessed data buffered or 0 otherwise */ + int (*unprocessed_read_pending)(OSSL_RECORD_LAYER *rl); + + /* + * Returns 1 if we have processed data buffered that can be read or 0 otherwise + * - not necessarily app data + */ + int (*processed_read_pending)(OSSL_RECORD_LAYER *rl); + + /* + * The amount of processed app data that is internally buffered and + * available to read + */ + size_t (*app_data_pending)(OSSL_RECORD_LAYER *rl); + + /* + * Find out the maximum number of records that the record layer is prepared + * to process in a single call to write_records. It is the caller's + * responsibility to ensure that no call to write_records exceeds this + * number of records. |type| is the type of the records that the caller + * wants to write, and |len| is the total amount of data that it wants + * to send. |maxfrag| is the maximum allowed fragment size based on user + * configuration, or TLS parameter negotiation. |*preffrag| contains on + * entry the default fragment size that will actually be used based on user + * configuration. This will always be less than or equal to |maxfrag|. On + * exit the record layer may update this to an alternative fragment size to + * be used. This must always be less than or equal to |maxfrag|. + */ + size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len, + size_t maxfrag, size_t *preffrag); + + /* + * Write |numtempl| records from the array of record templates pointed to + * by |templates|. Each record should be no longer than the value returned + * by get_max_record_len(), and there should be no more records than the + * value returned by get_max_records(). + * Where possible the caller will attempt to ensure that all records are the + * same length, except the last record. This may not always be possible so + * the record method implementation should not rely on this being the case. + * In the event of a retry the caller should call retry_write_records() + * to try again. No more calls to write_records() should be attempted until + * retry_write_records() returns success. + * Buffers allocated for the record templates can be freed immediately after + * write_records() returns - even in the case a retry. + * The record templates represent the plaintext payload. The encrypted + * output is written to the |transport| BIO. + * Returns: + * 1 on success + * 0 on retry + * -1 on failure + */ + int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, + size_t numtempl); + + /* + * Retry a previous call to write_records. The caller should continue to + * call this until the function returns with success or failure. After + * each retry more of the data may have been incrementally sent. + * Returns: + * 1 on success + * 0 on retry + * -1 on failure + */ + int (*retry_write_records)(OSSL_RECORD_LAYER *rl); + + /* + * Read a record and return the record layer version and record type in + * the |rversion| and |type| parameters. |*data| is set to point to a + * record layer buffer containing the record payload data and |*datalen| + * is filled in with the length of that data. The |epoch| and |seq_num| + * values are only used if DTLS has been negotiated. In that case they are + * filled in with the epoch and sequence number from the record. + * An opaque record layer handle for the record is returned in |*rechandle| + * which is used in a subsequent call to |release_record|. The buffer must + * remain available until all the bytes from record are released via one or + * more release_record calls. + * + * Internally the OSSL_RECORD_METHOD implementation may read/process + * multiple records in one go and buffer them. + */ + int (*read_record)(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, + uint8_t *type, const unsigned char **data, size_t *datalen, + uint16_t *epoch, unsigned char *seq_num); + /* + * Release length bytes from a buffer associated with a record previously + * read with read_record. Once all the bytes from a record are released, the + * whole record and its associated buffer is released. Records are + * guaranteed to be released in the order that they are read. + */ + int (*release_record)(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length); + + /* + * In the event that a fatal error is returned from the functions above then + * get_alert_code() can be called to obtain a more details identifier for + * the error. In (D)TLS this is the alert description code. + */ + int (*get_alert_code)(OSSL_RECORD_LAYER *rl); + + /* + * Update the transport BIO from the one originally set in the + * new_record_layer call + */ + int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio); + + /* Called when protocol negotiation selects a protocol version to use */ + int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version); + + /* + * Whether we are allowed to receive unencrypted alerts, even if we might + * otherwise expect encrypted records. Ignored by protocol versions where + * this isn't relevant + */ + void (*set_plain_alerts)(OSSL_RECORD_LAYER *rl, int allow); + + /* + * Called immediately after creation of the record layer if we are in a + * first handshake. Also called at the end of the first handshake + */ + void (*set_first_handshake)(OSSL_RECORD_LAYER *rl, int first); + + /* + * Set the maximum number of pipelines that the record layer should process. + * The default is 1. + */ + void (*set_max_pipelines)(OSSL_RECORD_LAYER *rl, size_t max_pipelines); + + /* + * Called to tell the record layer whether we are currently "in init" or + * not. Default at creation of the record layer is "yes". + */ + void (*set_in_init)(OSSL_RECORD_LAYER *rl, int in_init); + + /* + * Get a short or long human readable description of the record layer state + */ + void (*get_state)(OSSL_RECORD_LAYER *rl, const char **shortstr, + const char **longstr); + + /* + * Set new options or modify ones that were originally specified in the + * new_record_layer call. + */ + int (*set_options)(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options); + + const COMP_METHOD *(*get_compression)(OSSL_RECORD_LAYER *rl); + + /* + * Set the maximum fragment length to be used for the record layer. This + * will override any previous value supplied for the "max_frag_len" + * setting during construction of the record layer. + */ + void (*set_max_frag_len)(OSSL_RECORD_LAYER *rl, size_t max_frag_len); + + /* + * The maximum expansion in bytes that the record layer might add while + * writing a record + */ + size_t (*get_max_record_overhead)(OSSL_RECORD_LAYER *rl); + + /* + * Increment the record sequence number + */ + int (*increment_sequence_ctr)(OSSL_RECORD_LAYER *rl); + + /* + * Allocate read or write buffers. Does nothing if already allocated. + * Assumes default buffer length and 1 pipeline. + */ + int (*alloc_buffers)(OSSL_RECORD_LAYER *rl); + + /* + * Free read or write buffers. Fails if there is pending read or write + * data. Buffers are automatically reallocated on next read/write. + */ + int (*free_buffers)(OSSL_RECORD_LAYER *rl); +}; + + +/* Standard built-in record methods */ +extern const OSSL_RECORD_METHOD ossl_tls_record_method; +# ifndef OPENSSL_NO_KTLS +extern const OSSL_RECORD_METHOD ossl_ktls_record_method; +# endif +extern const OSSL_RECORD_METHOD ossl_dtls_record_method; + +#endif /* !defined(OSSL_INTERNAL_RECORDMETHOD_H) */ diff --git a/include/internal/refcount.h b/include/internal/refcount.h index 3392d3b490..4c9ab266d3 100644 --- a/include/internal/refcount.h +++ b/include/internal/refcount.h @@ -12,6 +12,7 @@ # include # include +# include # if defined(OPENSSL_THREADS) && !defined(OPENSSL_DEV_NO_ATOMICS) # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \ @@ -25,12 +26,13 @@ # define HAVE_ATOMICS 1 -typedef _Atomic int CRYPTO_REF_COUNT; +typedef struct { + _Atomic int val; +} CRYPTO_REF_COUNT; -static inline int CRYPTO_UP_REF(_Atomic int *val, int *ret, - ossl_unused void *lock) +static inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = atomic_fetch_add_explicit(val, 1, memory_order_relaxed) + 1; + *ret = atomic_fetch_add_explicit(&refcnt->val, 1, memory_order_relaxed) + 1; return 1; } @@ -44,50 +46,70 @@ static inline int CRYPTO_UP_REF(_Atomic int *val, int *ret, * to mutable members doesn't have to be serialized anymore, which would * otherwise imply an acquire fence. Hence conditional acquire fence... */ -static inline int CRYPTO_DOWN_REF(_Atomic int *val, int *ret, - ossl_unused void *lock) +static inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = atomic_fetch_sub_explicit(val, 1, memory_order_relaxed) - 1; + *ret = atomic_fetch_sub_explicit(&refcnt->val, 1, memory_order_relaxed) - 1; if (*ret == 0) atomic_thread_fence(memory_order_acquire); return 1; } +static inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +{ + *ret = atomic_load_explicit(&refcnt->val, memory_order_relaxed); + return 1; +} + # elif defined(__GNUC__) && defined(__ATOMIC_RELAXED) && __GCC_ATOMIC_INT_LOCK_FREE > 0 # define HAVE_ATOMICS 1 -typedef int CRYPTO_REF_COUNT; +typedef struct { + int val; +} CRYPTO_REF_COUNT; -static __inline__ int CRYPTO_UP_REF(int *val, int *ret, ossl_unused void *lock) +static __inline__ int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = __atomic_fetch_add(val, 1, __ATOMIC_RELAXED) + 1; + *ret = __atomic_fetch_add(&refcnt->val, 1, __ATOMIC_RELAXED) + 1; return 1; } -static __inline__ int CRYPTO_DOWN_REF(int *val, int *ret, - ossl_unused void *lock) +static __inline__ int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = __atomic_fetch_sub(val, 1, __ATOMIC_RELAXED) - 1; + *ret = __atomic_fetch_sub(&refcnt->val, 1, __ATOMIC_RELAXED) - 1; if (*ret == 0) __atomic_thread_fence(__ATOMIC_ACQUIRE); return 1; } + +static __inline__ int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +{ + *ret = __atomic_load_n(&refcnt->val, __ATOMIC_RELAXED); + return 1; +} + # elif defined(__ICL) && defined(_WIN32) # define HAVE_ATOMICS 1 -typedef volatile int CRYPTO_REF_COUNT; -static __inline int CRYPTO_UP_REF(volatile int *val, int *ret, - ossl_unused void *lock) +typedef struct { + volatile int val; +} CRYPTO_REF_COUNT; + +static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +{ + *ret = _InterlockedExchangeAdd((void *)&refcnt->val, 1) + 1; + return 1; +} + +static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *val, int *refcnt) { - *ret = _InterlockedExchangeAdd((void *)val, 1) + 1; + *ret = _InterlockedExchangeAdd((void *)&refcnt->val, -1) - 1; return 1; } -static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, - ossl_unused void *lock) +static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd((void *)val, -1) - 1; + *ret = _InterlockedOr((void *)&refcnt->val, 0); return 1; } @@ -95,7 +117,9 @@ static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, # define HAVE_ATOMICS 1 -typedef volatile int CRYPTO_REF_COUNT; +typedef struct { + volatile int val; +} CRYPTO_REF_COUNT; # if (defined(_M_ARM) && _M_ARM>=7 && !defined(_WIN32_WCE)) || defined(_M_ARM64) # include @@ -103,21 +127,26 @@ typedef volatile int CRYPTO_REF_COUNT; # define _ARM_BARRIER_ISH _ARM64_BARRIER_ISH # endif -static __inline int CRYPTO_UP_REF(volatile int *val, int *ret, - ossl_unused void *lock) +static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd_nf(val, 1) + 1; + *ret = _InterlockedExchangeAdd_nf(&refcnt->val, 1) + 1; return 1; } -static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, - ossl_unused void *lock) +static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd_nf(val, -1) - 1; + *ret = _InterlockedExchangeAdd_nf(&refcnt->val, -1) - 1; if (*ret == 0) __dmb(_ARM_BARRIER_ISH); return 1; } + +static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +{ + *ret = _InterlockedOr_nf((void *)&refcnt->val, 0); + return 1; +} + # else # if !defined(_WIN32_WCE) # pragma intrinsic(_InterlockedExchangeAdd) @@ -131,19 +160,24 @@ static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, # endif # endif -static __inline int CRYPTO_UP_REF(volatile int *val, int *ret, - ossl_unused void *lock) +static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +{ + *ret = _InterlockedExchangeAdd(&refcnt->val, 1) + 1; + return 1; +} + +static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd(val, 1) + 1; + *ret = _InterlockedExchangeAdd(&refcnt->val, -1) - 1; return 1; } -static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, - ossl_unused void *lock) +static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd(val, -1) - 1; + *ret = _InterlockedExchangeAdd(&refcnt->val, 0); return 1; } + # endif # endif @@ -156,13 +190,92 @@ static __inline int CRYPTO_DOWN_REF(volatile int *val, int *ret, */ # ifndef HAVE_ATOMICS -typedef int CRYPTO_REF_COUNT; +typedef struct { + int val; +# ifdef OPENSSL_THREADS + CRYPTO_RWLOCK *lock; +# endif +} CRYPTO_REF_COUNT; + +# ifdef OPENSSL_THREADS -# define CRYPTO_UP_REF(val, ret, lock) CRYPTO_atomic_add(val, 1, ret, lock) -# define CRYPTO_DOWN_REF(val, ret, lock) CRYPTO_atomic_add(val, -1, ret, lock) +static ossl_unused ossl_inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + return CRYPTO_atomic_add(&refcnt->val, 1, ret, refcnt->lock); +} + +static ossl_unused ossl_inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + return CRYPTO_atomic_add(&refcnt->val, -1, ret, refcnt->lock); +} +static ossl_unused ossl_inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + return CRYPTO_atomic_load_int(&refcnt->val, ret, refcnt->lock); +} + +# define CRYPTO_NEW_FREE_DEFINED 1 +static ossl_unused ossl_inline int CRYPTO_NEW_REF(CRYPTO_REF_COUNT *refcnt, int n) +{ + refcnt->val = n; + refcnt->lock = CRYPTO_THREAD_lock_new(); + if (refcnt->lock == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); + return 0; + } + return 1; +} + +static ossl_unused ossl_inline void CRYPTO_FREE_REF(CRYPTO_REF_COUNT *refcnt) \ +{ + if (refcnt != NULL) + CRYPTO_THREAD_lock_free(refcnt->lock); +} + +# else /* OPENSSL_THREADS */ + +static ossl_unused ossl_inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + refcnt->val++; + *ret = refcnt->val; + return 1; +} + +static ossl_unused ossl_inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + refcnt->val--; + *ret = refcnt->val; + return 1; +} + +static ossl_unused ossl_inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, + int *ret) +{ + *ret = refcnt->val; + return 1; +} + +# endif /* OPENSSL_THREADS */ # endif +# ifndef CRYPTO_NEW_FREE_DEFINED +static ossl_unused ossl_inline int CRYPTO_NEW_REF(CRYPTO_REF_COUNT *refcnt, int n) +{ + refcnt->val = n; + return 1; +} + +static ossl_unused ossl_inline void CRYPTO_FREE_REF(CRYPTO_REF_COUNT *refcnt) \ +{ +} +# endif /* CRYPTO_NEW_FREE_DEFINED */ +#undef CRYPTO_NEW_FREE_DEFINED + # if !defined(NDEBUG) && !defined(OPENSSL_NO_STDIO) # define REF_ASSERT_ISNT(test) \ (void)((test) ? (OPENSSL_die("refcount error", __FILE__, __LINE__), 1) : 0) @@ -173,6 +286,6 @@ typedef int CRYPTO_REF_COUNT; # define REF_PRINT_EX(text, count, object) \ OSSL_TRACE3(REF_COUNT, "%p:%4d:%s\n", (object), (count), (text)); # define REF_PRINT_COUNT(text, object) \ - REF_PRINT_EX(text, object->references, (void *)object) + REF_PRINT_EX(text, object->references.val, (void *)object) #endif diff --git a/include/internal/ring_buf.h b/include/internal/ring_buf.h new file mode 100644 index 0000000000..436f1ca146 --- /dev/null +++ b/include/internal/ring_buf.h @@ -0,0 +1,277 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_RING_BUF_H +# define OSSL_INTERNAL_RING_BUF_H +# pragma once + +# include /* For 'ossl_inline' */ +# include "internal/safe_math.h" + +/* + * ================================================================== + * Byte-wise ring buffer which supports pushing and popping blocks of multiple + * bytes at a time. The logical offset of each byte for the purposes of a QUIC + * stream is tracked. Bytes can be popped from the ring buffer in two stages; + * first they are popped, and then they are culled. Bytes which have been popped + * but not yet culled will not be overwritten, and can be restored. + */ +struct ring_buf { + void *start; + size_t alloc; /* size of buffer allocation in bytes */ + + /* + * Logical offset of the head (where we append to). This is the current size + * of the QUIC stream. This increases monotonically. + */ + uint64_t head_offset; + + /* + * Logical offset of the cull tail. Data is no longer needed and is + * deallocated as the cull tail advances, which occurs as data is + * acknowledged. This increases monotonically. + */ + uint64_t ctail_offset; +}; + +OSSL_SAFE_MATH_UNSIGNED(u64, uint64_t) + +#define MAX_OFFSET (((uint64_t)1) << 62) /* QUIC-imposed limit */ + +static ossl_inline int ring_buf_init(struct ring_buf *r) +{ + r->start = NULL; + r->alloc = 0; + r->head_offset = r->ctail_offset = 0; + return 1; +} + +static ossl_inline void ring_buf_destroy(struct ring_buf *r, int cleanse) +{ + if (cleanse) + OPENSSL_clear_free(r->start, r->alloc); + else + OPENSSL_free(r->start); + r->start = NULL; + r->alloc = 0; +} + +static ossl_inline size_t ring_buf_used(struct ring_buf *r) +{ + return (size_t)(r->head_offset - r->ctail_offset); +} + +static ossl_inline size_t ring_buf_avail(struct ring_buf *r) +{ + return r->alloc - ring_buf_used(r); +} + +static ossl_inline int ring_buf_write_at(struct ring_buf *r, + uint64_t logical_offset, + const unsigned char *buf, + size_t buf_len) +{ + size_t avail, idx, l; + unsigned char *start = r->start; + int i, err = 0; + + avail = ring_buf_avail(r); + if (logical_offset < r->ctail_offset + || safe_add_u64(logical_offset, buf_len, &err) + > safe_add_u64(r->head_offset, avail, &err) + || safe_add_u64(r->head_offset, buf_len, &err) + > MAX_OFFSET + || err) + return 0; + + for (i = 0; buf_len > 0 && i < 2; ++i) { + idx = logical_offset % r->alloc; + l = r->alloc - idx; + if (buf_len < l) + l = buf_len; + + memcpy(start + idx, buf, l); + if (r->head_offset < logical_offset + l) + r->head_offset = logical_offset + l; + + logical_offset += l; + buf += l; + buf_len -= l; + } + + assert(buf_len == 0); + + return 1; +} + +static ossl_inline size_t ring_buf_push(struct ring_buf *r, + const unsigned char *buf, + size_t buf_len) +{ + size_t pushed = 0, avail, idx, l; + unsigned char *start = r->start; + + for (;;) { + avail = ring_buf_avail(r); + if (buf_len > avail) + buf_len = avail; + + if (buf_len > MAX_OFFSET - r->head_offset) + buf_len = (size_t)(MAX_OFFSET - r->head_offset); + + if (buf_len == 0) + break; + + idx = r->head_offset % r->alloc; + l = r->alloc - idx; + if (buf_len < l) + l = buf_len; + + memcpy(start + idx, buf, l); + r->head_offset += l; + buf += l; + buf_len -= l; + pushed += l; + } + + return pushed; +} + +static ossl_inline const unsigned char *ring_buf_get_ptr(const struct ring_buf *r, + uint64_t logical_offset, + size_t *max_len) +{ + unsigned char *start = r->start; + size_t idx; + + if (logical_offset >= r->head_offset || logical_offset < r->ctail_offset) + return NULL; + idx = logical_offset % r->alloc; + *max_len = r->alloc - idx; + return start + idx; +} + +/* + * Retrieves data out of the read side of the ring buffer starting at the given + * logical offset. *buf is set to point to a contiguous span of bytes and + * *buf_len is set to the number of contiguous bytes. After this function + * returns, there may or may not be more bytes available at the logical offset + * of (logical_offset + *buf_len) by calling this function again. If the logical + * offset is out of the range retained by the ring buffer, returns 0, else + * returns 1. A logical offset at the end of the range retained by the ring + * buffer is not considered an error and is returned with a *buf_len of 0. + * + * The ring buffer state is not changed. + */ +static ossl_inline int ring_buf_get_buf_at(const struct ring_buf *r, + uint64_t logical_offset, + const unsigned char **buf, + size_t *buf_len) +{ + const unsigned char *start = r->start; + size_t idx, l; + + if (logical_offset > r->head_offset || logical_offset < r->ctail_offset) + return 0; + + if (r->alloc == 0) { + *buf = NULL; + *buf_len = 0; + return 1; + } + + idx = logical_offset % r->alloc; + l = (size_t)(r->head_offset - logical_offset); + if (l > r->alloc - idx) + l = r->alloc - idx; + + *buf = start + idx; + *buf_len = l; + return 1; +} + +static ossl_inline void ring_buf_cpop_range(struct ring_buf *r, + uint64_t start, uint64_t end, + int cleanse) +{ + assert(end >= start); + + if (start > r->ctail_offset || end >= MAX_OFFSET) + return; + + if (cleanse && r->alloc > 0 && end > r->ctail_offset) { + size_t idx = r->ctail_offset % r->alloc; + uint64_t cleanse_end = end + 1; + size_t l; + + if (cleanse_end > r->head_offset) + cleanse_end = r->head_offset; + l = (size_t)(cleanse_end - r->ctail_offset); + if (l > r->alloc - idx) { + OPENSSL_cleanse((unsigned char *)r->start + idx, r->alloc - idx); + l -= r->alloc - idx; + idx = 0; + } + if (l > 0) + OPENSSL_cleanse((unsigned char *)r->start + idx, l); + } + + r->ctail_offset = end + 1; + /* Allow culling unpushed data */ + if (r->head_offset < r->ctail_offset) + r->head_offset = r->ctail_offset; +} + +static ossl_inline int ring_buf_resize(struct ring_buf *r, size_t num_bytes, + int cleanse) +{ + struct ring_buf rnew = {0}; + const unsigned char *src = NULL; + size_t src_len = 0, copied = 0; + + if (num_bytes == r->alloc) + return 1; + + if (num_bytes < ring_buf_used(r)) + return 0; + + rnew.start = OPENSSL_malloc(num_bytes); + if (rnew.start == NULL) + return 0; + + rnew.alloc = num_bytes; + rnew.head_offset = r->head_offset - ring_buf_used(r); + rnew.ctail_offset = rnew.head_offset; + + for (;;) { + if (!ring_buf_get_buf_at(r, r->ctail_offset + copied, &src, &src_len)) { + OPENSSL_free(rnew.start); + return 0; + } + + if (src_len == 0) + break; + + if (ring_buf_push(&rnew, src, src_len) != src_len) { + OPENSSL_free(rnew.start); + return 0; + } + + copied += src_len; + } + + assert(rnew.head_offset == r->head_offset); + rnew.ctail_offset = r->ctail_offset; + + ring_buf_destroy(r, cleanse); + memcpy(r, &rnew, sizeof(*r)); + return 1; +} + +#endif /* OSSL_INTERNAL_RING_BUF_H */ diff --git a/include/internal/safe_math.h b/include/internal/safe_math.h new file mode 100644 index 0000000000..be37e6ab88 --- /dev/null +++ b/include/internal/safe_math.h @@ -0,0 +1,443 @@ +/* + * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_SAFE_MATH_H +# define OSSL_INTERNAL_SAFE_MATH_H +# pragma once + +# include /* For 'ossl_inline' */ + +# ifndef OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING +# ifdef __has_builtin +# define has(func) __has_builtin(func) +# elif __GNUC__ > 5 +# define has(func) 1 +# endif +# endif /* OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING */ + +# ifndef has +# define has(func) 0 +# endif + +/* + * Safe addition helpers + */ +# if has(__builtin_add_overflow) +# define OSSL_SAFE_MATH_ADDS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_add_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + type r; \ + \ + if (!__builtin_add_overflow(a, b, &r)) \ + return r; \ + *err |= 1; \ + return a < 0 ? min : max; \ + } + +# define OSSL_SAFE_MATH_ADDU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_add_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + type r; \ + \ + if (!__builtin_add_overflow(a, b, &r)) \ + return r; \ + *err |= 1; \ + return a + b; \ + } + +# else /* has(__builtin_add_overflow) */ +# define OSSL_SAFE_MATH_ADDS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_add_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if ((a < 0) ^ (b < 0) \ + || (a > 0 && b <= max - a) \ + || (a < 0 && b >= min - a) \ + || a == 0) \ + return a + b; \ + *err |= 1; \ + return a < 0 ? min : max; \ + } + +# define OSSL_SAFE_MATH_ADDU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_add_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b > max - a) \ + *err |= 1; \ + return a + b; \ + } +# endif /* has(__builtin_add_overflow) */ + +/* + * Safe subtraction helpers + */ +# if has(__builtin_sub_overflow) +# define OSSL_SAFE_MATH_SUBS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_sub_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + type r; \ + \ + if (!__builtin_sub_overflow(a, b, &r)) \ + return r; \ + *err |= 1; \ + return a < 0 ? min : max; \ + } + +# else /* has(__builtin_sub_overflow) */ +# define OSSL_SAFE_MATH_SUBS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_sub_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (!((a < 0) ^ (b < 0)) \ + || (b > 0 && a >= min + b) \ + || (b < 0 && a <= max + b) \ + || b == 0) \ + return a - b; \ + *err |= 1; \ + return a < 0 ? min : max; \ + } + +# endif /* has(__builtin_sub_overflow) */ + +# define OSSL_SAFE_MATH_SUBU(type_name, type) \ + static ossl_inline ossl_unused type safe_sub_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b > a) \ + *err |= 1; \ + return a - b; \ + } + +/* + * Safe multiplication helpers + */ +# if has(__builtin_mul_overflow) +# define OSSL_SAFE_MATH_MULS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_mul_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + type r; \ + \ + if (!__builtin_mul_overflow(a, b, &r)) \ + return r; \ + *err |= 1; \ + return (a < 0) ^ (b < 0) ? min : max; \ + } + +# define OSSL_SAFE_MATH_MULU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_mul_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + type r; \ + \ + if (!__builtin_mul_overflow(a, b, &r)) \ + return r; \ + *err |= 1; \ + return a * b; \ + } + +# else /* has(__builtin_mul_overflow) */ +# define OSSL_SAFE_MATH_MULS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_mul_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (a == 0 || b == 0) \ + return 0; \ + if (a == 1) \ + return b; \ + if (b == 1) \ + return a; \ + if (a != min && b != min) { \ + const type x = a < 0 ? -a : a; \ + const type y = b < 0 ? -b : b; \ + \ + if (x <= max / y) \ + return a * b; \ + } \ + *err |= 1; \ + return (a < 0) ^ (b < 0) ? min : max; \ + } + +# define OSSL_SAFE_MATH_MULU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_mul_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b != 0 && a > max / b) \ + *err |= 1; \ + return a * b; \ + } +# endif /* has(__builtin_mul_overflow) */ + +/* + * Safe division helpers + */ +# define OSSL_SAFE_MATH_DIVS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_div_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b == 0) { \ + *err |= 1; \ + return a < 0 ? min : max; \ + } \ + if (b == -1 && a == min) { \ + *err |= 1; \ + return max; \ + } \ + return a / b; \ + } + +# define OSSL_SAFE_MATH_DIVU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_div_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b != 0) \ + return a / b; \ + *err |= 1; \ + return max; \ + } + +/* + * Safe modulus helpers + */ +# define OSSL_SAFE_MATH_MODS(type_name, type, min, max) \ + static ossl_inline ossl_unused type safe_mod_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b == 0) { \ + *err |= 1; \ + return 0; \ + } \ + if (b == -1 && a == min) { \ + *err |= 1; \ + return max; \ + } \ + return a % b; \ + } + +# define OSSL_SAFE_MATH_MODU(type_name, type) \ + static ossl_inline ossl_unused type safe_mod_ ## type_name(type a, \ + type b, \ + int *err) \ + { \ + if (b != 0) \ + return a % b; \ + *err |= 1; \ + return 0; \ + } + +/* + * Safe negation helpers + */ +# define OSSL_SAFE_MATH_NEGS(type_name, type, min) \ + static ossl_inline ossl_unused type safe_neg_ ## type_name(type a, \ + int *err) \ + { \ + if (a != min) \ + return -a; \ + *err |= 1; \ + return min; \ + } + +# define OSSL_SAFE_MATH_NEGU(type_name, type) \ + static ossl_inline ossl_unused type safe_neg_ ## type_name(type a, \ + int *err) \ + { \ + if (a == 0) \ + return a; \ + *err |= 1; \ + return 1 + ~a; \ + } + +/* + * Safe absolute value helpers + */ +# define OSSL_SAFE_MATH_ABSS(type_name, type, min) \ + static ossl_inline ossl_unused type safe_abs_ ## type_name(type a, \ + int *err) \ + { \ + if (a != min) \ + return a < 0 ? -a : a; \ + *err |= 1; \ + return min; \ + } + +# define OSSL_SAFE_MATH_ABSU(type_name, type) \ + static ossl_inline ossl_unused type safe_abs_ ## type_name(type a, \ + int *err) \ + { \ + return a; \ + } + +/* + * Safe fused multiply divide helpers + * + * These are a bit obscure: + * . They begin by checking the denominator for zero and getting rid of this + * corner case. + * + * . Second is an attempt to do the multiplication directly, if it doesn't + * overflow, the quotient is returned (for signed values there is a + * potential problem here which isn't present for unsigned). + * + * . Finally, the multiplication/division is transformed so that the larger + * of the numerators is divided first. This requires a remainder + * correction: + * + * a b / c = (a / c) b + (a mod c) b / c, where a > b + * + * The individual operations need to be overflow checked (again signed + * being more problematic). + * + * The algorithm used is not perfect but it should be "good enough". + */ +# define OSSL_SAFE_MATH_MULDIVS(type_name, type, max) \ + static ossl_inline ossl_unused type safe_muldiv_ ## type_name(type a, \ + type b, \ + type c, \ + int *err) \ + { \ + int e2 = 0; \ + type q, r, x, y; \ + \ + if (c == 0) { \ + *err |= 1; \ + return a == 0 || b == 0 ? 0 : max; \ + } \ + x = safe_mul_ ## type_name(a, b, &e2); \ + if (!e2) \ + return safe_div_ ## type_name(x, c, err); \ + if (b > a) { \ + x = b; \ + b = a; \ + a = x; \ + } \ + q = safe_div_ ## type_name(a, c, err); \ + r = safe_mod_ ## type_name(a, c, err); \ + x = safe_mul_ ## type_name(r, b, err); \ + y = safe_mul_ ## type_name(q, b, err); \ + q = safe_div_ ## type_name(x, c, err); \ + return safe_add_ ## type_name(y, q, err); \ + } + +# define OSSL_SAFE_MATH_MULDIVU(type_name, type, max) \ + static ossl_inline ossl_unused type safe_muldiv_ ## type_name(type a, \ + type b, \ + type c, \ + int *err) \ + { \ + int e2 = 0; \ + type x, y; \ + \ + if (c == 0) { \ + *err |= 1; \ + return a == 0 || b == 0 ? 0 : max; \ + } \ + x = safe_mul_ ## type_name(a, b, &e2); \ + if (!e2) \ + return x / c; \ + if (b > a) { \ + x = b; \ + b = a; \ + a = x; \ + } \ + x = safe_mul_ ## type_name(a % c, b, err); \ + y = safe_mul_ ## type_name(a / c, b, err); \ + return safe_add_ ## type_name(y, x / c, err); \ + } + +/* + * Calculate a / b rounding up: + * i.e. a / b + (a % b != 0) + * Which is usually (less safely) converted to (a + b - 1) / b + * If you *know* that b != 0, then it's safe to ignore err. + */ +#define OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type, max) \ + static ossl_inline ossl_unused type safe_div_round_up_ ## type_name \ + (type a, type b, int *errp) \ + { \ + type x; \ + int *err, err_local = 0; \ + \ + /* Allow errors to be ignored by callers */ \ + err = errp != NULL ? errp : &err_local; \ + /* Fast path, both positive */ \ + if (b > 0 && a > 0) { \ + /* Faster path: no overflow concerns */ \ + if (a < max - b) \ + return (a + b - 1) / b; \ + return a / b + (a % b != 0); \ + } \ + if (b == 0) { \ + *err |= 1; \ + return a == 0 ? 0 : max; \ + } \ + if (a == 0) \ + return 0; \ + /* Rather slow path because there are negatives involved */ \ + x = safe_mod_ ## type_name(a, b, err); \ + return safe_add_ ## type_name(safe_div_ ## type_name(a, b, err), \ + x != 0, err); \ + } + +/* Calculate ranges of types */ +# define OSSL_SAFE_MATH_MINS(type) ((type)1 << (sizeof(type) * 8 - 1)) +# define OSSL_SAFE_MATH_MAXS(type) (~OSSL_SAFE_MATH_MINS(type)) +# define OSSL_SAFE_MATH_MAXU(type) (~(type)0) + +/* + * Wrapper macros to create all the functions of a given type + */ +# define OSSL_SAFE_MATH_SIGNED(type_name, type) \ + OSSL_SAFE_MATH_ADDS(type_name, type, OSSL_SAFE_MATH_MINS(type), \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_SUBS(type_name, type, OSSL_SAFE_MATH_MINS(type), \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_MULS(type_name, type, OSSL_SAFE_MATH_MINS(type), \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_DIVS(type_name, type, OSSL_SAFE_MATH_MINS(type), \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_MODS(type_name, type, OSSL_SAFE_MATH_MINS(type), \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type, \ + OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_MULDIVS(type_name, type, OSSL_SAFE_MATH_MAXS(type)) \ + OSSL_SAFE_MATH_NEGS(type_name, type, OSSL_SAFE_MATH_MINS(type)) \ + OSSL_SAFE_MATH_ABSS(type_name, type, OSSL_SAFE_MATH_MINS(type)) + +# define OSSL_SAFE_MATH_UNSIGNED(type_name, type) \ + OSSL_SAFE_MATH_ADDU(type_name, type, OSSL_SAFE_MATH_MAXU(type)) \ + OSSL_SAFE_MATH_SUBU(type_name, type) \ + OSSL_SAFE_MATH_MULU(type_name, type, OSSL_SAFE_MATH_MAXU(type)) \ + OSSL_SAFE_MATH_DIVU(type_name, type, OSSL_SAFE_MATH_MAXU(type)) \ + OSSL_SAFE_MATH_MODU(type_name, type) \ + OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type, \ + OSSL_SAFE_MATH_MAXU(type)) \ + OSSL_SAFE_MATH_MULDIVU(type_name, type, OSSL_SAFE_MATH_MAXU(type)) \ + OSSL_SAFE_MATH_NEGU(type_name, type) \ + OSSL_SAFE_MATH_ABSU(type_name, type) + +#endif /* OSSL_INTERNAL_SAFE_MATH_H */ diff --git a/include/internal/sockets.h b/include/internal/sockets.h index 1f5fefccff..2550c56bd0 100644 --- a/include/internal/sockets.h +++ b/include/internal/sockets.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,7 +61,25 @@ struct servent *PASCAL getservbyname(const char *, const char *); # define accept(s,f,l) ((int)accept(s,f,l)) # endif +/* Windows have other names for shutdown() reasons */ +# ifndef SHUT_RD +# define SHUT_RD SD_RECEIVE +# endif +# ifndef SHUT_WR +# define SHUT_WR SD_SEND +# endif +# ifndef SHUT_RDWR +# define SHUT_RDWR SD_BOTH +# endif + # else +# if defined(__APPLE__) + /* + * This must be defined before including to get + * IPV6_RECVPKTINFO + */ +# define __APPLE_USE_RFC_3542 +# endif # ifndef NO_SYS_PARAM_H # include @@ -71,6 +89,9 @@ struct servent *PASCAL getservbyname(const char *, const char *); # endif # include +# if defined(OPENSSL_SYS_VMS) +typedef size_t socklen_t; /* Currently appears to be missing on VMS */ +# endif # if defined(OPENSSL_SYS_VMS_NODECC) # include # include @@ -95,6 +116,13 @@ struct servent *PASCAL getservbyname(const char *, const char *); # include # endif +# ifdef OPENSSL_SYS_UNIX +# ifndef OPENSSL_SYS_TANDEM +# include +# endif +# include +# endif + # ifndef VMS # include # else @@ -136,12 +164,15 @@ struct servent *PASCAL getservbyname(const char *, const char *); # define get_last_socket_error() errno # define clear_socket_error() errno=0 +# define get_last_socket_error_is_eintr() (get_last_socket_error() == EINTR) # if defined(OPENSSL_SYS_WINDOWS) # undef get_last_socket_error # undef clear_socket_error +# undef get_last_socket_error_is_eintr # define get_last_socket_error() WSAGetLastError() # define clear_socket_error() WSASetLastError(0) +# define get_last_socket_error_is_eintr() (get_last_socket_error() == WSAEINTR) # define readsocket(s,b,n) recv((s),(b),(n),0) # define writesocket(s,b,n) send((s),(b),(n),0) # elif defined(__DJGPP__) diff --git a/include/internal/ssl.h b/include/internal/ssl.h new file mode 100644 index 0000000000..8a0c797496 --- /dev/null +++ b/include/internal/ssl.h @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifndef OSSL_INTERNAL_SSL_H +# define OSSL_INTERNAL_SSL_H +# pragma once + +typedef void (*ossl_msg_cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + +int ossl_ssl_get_error(const SSL *s, int i, int check_err); + +/* Set if this is the QUIC handshake layer */ +# define TLS1_FLAGS_QUIC 0x2000 + +#endif diff --git a/include/internal/ssl3_cbc.h b/include/internal/ssl3_cbc.h new file mode 100644 index 0000000000..4fb5da1906 --- /dev/null +++ b/include/internal/ssl3_cbc.h @@ -0,0 +1,40 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +/* tls_pad.c */ +int ssl3_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + OSSL_LIB_CTX *libctx); + +int tls1_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + int aead, + OSSL_LIB_CTX *libctx); + +/* ssl3_cbc.c */ +__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +__owur int ssl3_cbc_digest_record(const EVP_MD *md, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char *header, + const unsigned char *data, + size_t data_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + size_t mac_secret_length, char is_sslv3); diff --git a/ssl/statem/statem.h b/include/internal/statem.h similarity index 67% rename from ssl/statem/statem.h rename to include/internal/statem.h index 5db31b6358..136e652366 100644 --- a/ssl/statem/statem.h +++ b/include/internal/statem.h @@ -1,11 +1,13 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +#ifndef OSSL_INTERNAL_STATEM_H +# define OSSL_INTERNAL_STATEM_H /***************************************************************************** * * @@ -72,20 +74,18 @@ typedef enum { } WRITE_STATE; typedef enum { - /* The enc_write_ctx can be used normally */ - ENC_WRITE_STATE_VALID, - /* The enc_write_ctx cannot be used */ - ENC_WRITE_STATE_INVALID, - /* Write alerts in plaintext, but otherwise use the enc_write_ctx */ - ENC_WRITE_STATE_WRITE_PLAIN_ALERTS -} ENC_WRITE_STATES; + CON_FUNC_ERROR = 0, + CON_FUNC_SUCCESS, + CON_FUNC_DONT_SEND +} CON_FUNC_RETURN; -typedef enum { - /* The enc_read_ctx can be used normally */ - ENC_READ_STATE_VALID, - /* We may receive encrypted or plaintext alerts */ - ENC_READ_STATE_ALLOW_PLAIN_ALERTS -} ENC_READ_STATES; +typedef int (*ossl_statem_mutate_handshake_cb)(const unsigned char *msgin, + size_t inlen, + unsigned char **msgout, + size_t *outlen, + void *arg); + +typedef void (*ossl_statem_finish_mutate_handshake_cb)(void *arg); /***************************************************************************** * * @@ -116,8 +116,12 @@ struct ossl_statem_st { /* Should we skip the CertificateVerify message? */ unsigned int no_cert_verify; int use_timer; - ENC_WRITE_STATES enc_write_state; - ENC_READ_STATES enc_read_state; + + /* Test harness message mutator callbacks */ + ossl_statem_mutate_handshake_cb mutate_handshake_cb; + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb; + void *mutatearg; + unsigned int write_in_progress : 1; }; typedef struct ossl_statem_st OSSL_STATEM; @@ -128,13 +132,16 @@ typedef struct ossl_statem_st OSSL_STATEM; * * *****************************************************************************/ +typedef struct ssl_connection_st SSL_CONNECTION; + __owur int ossl_statem_accept(SSL *s); __owur int ossl_statem_connect(SSL *s); -void ossl_statem_clear(SSL *s); -void ossl_statem_set_renegotiate(SSL *s); -void ossl_statem_send_fatal(SSL *s, int al); -void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...); -# define SSL_AD_NO_ALERT -1 +OSSL_HANDSHAKE_STATE ossl_statem_get_state(SSL_CONNECTION *s); +void ossl_statem_clear(SSL_CONNECTION *s); +void ossl_statem_set_renegotiate(SSL_CONNECTION *s); +void ossl_statem_send_fatal(SSL_CONNECTION *s, int al); +void ossl_statem_fatal(SSL_CONNECTION *s, int al, int reason, + const char *fmt, ...); # define SSLfatal_alert(s, al) ossl_statem_send_fatal((s), (al)) # define SSLfatal(s, al, r) SSLfatal_data((s), (al), (r), NULL) # define SSLfatal_data \ @@ -142,16 +149,23 @@ void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...); ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \ ossl_statem_fatal) -int ossl_statem_in_error(const SSL *s); -void ossl_statem_set_in_init(SSL *s, int init); -int ossl_statem_get_in_handshake(SSL *s); -void ossl_statem_set_in_handshake(SSL *s, int inhand); -__owur int ossl_statem_skip_early_data(SSL *s); -void ossl_statem_check_finish_init(SSL *s, int send); -void ossl_statem_set_hello_verify_done(SSL *s); -__owur int ossl_statem_app_data_allowed(SSL *s); -__owur int ossl_statem_export_allowed(SSL *s); -__owur int ossl_statem_export_early_allowed(SSL *s); +int ossl_statem_in_error(const SSL_CONNECTION *s); +void ossl_statem_set_in_init(SSL_CONNECTION *s, int init); +int ossl_statem_get_in_handshake(SSL_CONNECTION *s); +void ossl_statem_set_in_handshake(SSL_CONNECTION *s, int inhand); +__owur int ossl_statem_skip_early_data(SSL_CONNECTION *s); +void ossl_statem_check_finish_init(SSL_CONNECTION *s, int send); +void ossl_statem_set_hello_verify_done(SSL_CONNECTION *s); +__owur int ossl_statem_app_data_allowed(SSL_CONNECTION *s); +__owur int ossl_statem_export_allowed(SSL_CONNECTION *s); +__owur int ossl_statem_export_early_allowed(SSL_CONNECTION *s); /* Flush the write BIO */ -int statem_flush(SSL *s); +int statem_flush(SSL_CONNECTION *s); + +int ossl_statem_set_mutator(SSL *s, + ossl_statem_mutate_handshake_cb mutate_handshake_cb, + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, + void *mutatearg); + +#endif diff --git a/include/internal/thread.h b/include/internal/thread.h new file mode 100644 index 0000000000..8c5bad7763 --- /dev/null +++ b/include/internal/thread.h @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_INTERNAL_THREAD_H +# define OPENSSL_INTERNAL_THREAD_H +# include +# include +# include +# include +# include +# include "crypto/context.h" + +void *ossl_crypto_thread_start(OSSL_LIB_CTX *ctx, CRYPTO_THREAD_ROUTINE start, + void *data); +int ossl_crypto_thread_join(void *task, CRYPTO_THREAD_RETVAL *retval); +int ossl_crypto_thread_clean(void *vhandle); +uint64_t ossl_get_avail_threads(OSSL_LIB_CTX *ctx); + +# if defined(OPENSSL_THREADS) + +# define OSSL_LIB_CTX_GET_THREADS(CTX) \ + ossl_lib_ctx_get_data(CTX, OSSL_LIB_CTX_THREAD_INDEX); + +typedef struct openssl_threads_st { + uint64_t max_threads; + uint64_t active_threads; + CRYPTO_MUTEX *lock; + CRYPTO_CONDVAR *cond_finished; +} OSSL_LIB_CTX_THREADS; + +# endif /* defined(OPENSSL_THREADS) */ + +#endif /* OPENSSL_INTERNAL_THREAD_H */ diff --git a/include/internal/thread_arch.h b/include/internal/thread_arch.h new file mode 100644 index 0000000000..1bfc0ebb3d --- /dev/null +++ b/include/internal/thread_arch.h @@ -0,0 +1,127 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_THREAD_ARCH_H +# define OSSL_INTERNAL_THREAD_ARCH_H +# include +# include +# include "internal/time.h" + +# if defined(_WIN32) +# include +# endif + +# if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_UNIX) +# define OPENSSL_THREADS_POSIX +# elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_VMS) +# define OPENSSL_THREADS_POSIX +# elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_WINDOWS) && \ + defined(_WIN32_WINNT) +# if _WIN32_WINNT >= 0x0600 +# define OPENSSL_THREADS_WINNT +# elif _WIN32_WINNT >= 0x0501 +# define OPENSSL_THREADS_WINNT +# define OPENSSL_THREADS_WINNT_LEGACY +# else +# define OPENSSL_THREADS_NONE +# endif +# else +# define OPENSSL_THREADS_NONE +# endif + +# include + +typedef void CRYPTO_MUTEX; +typedef void CRYPTO_CONDVAR; + +CRYPTO_MUTEX *ossl_crypto_mutex_new(void); +void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex); +int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex); +void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex); +void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex); + +CRYPTO_CONDVAR *ossl_crypto_condvar_new(void); +void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex); +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline); +void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv); +void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv); +void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv); + +typedef uint32_t CRYPTO_THREAD_RETVAL; +typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE)(void *); +typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE_CB)(void *, + void (**)(void *), + void **); + +# define CRYPTO_THREAD_NO_STATE 0UL +# define CRYPTO_THREAD_FINISHED (1UL << 0) +# define CRYPTO_THREAD_JOIN_AWAIT (1UL << 1) +# define CRYPTO_THREAD_JOINED (1UL << 2) + +# define CRYPTO_THREAD_GET_STATE(THREAD, FLAG) ((THREAD)->state & (FLAG)) +# define CRYPTO_THREAD_GET_ERROR(THREAD, FLAG) (((THREAD)->state >> 16) & (FLAG)) + +typedef struct crypto_thread_st { + uint32_t state; + void *data; + CRYPTO_THREAD_ROUTINE routine; + CRYPTO_THREAD_RETVAL retval; + void *handle; + CRYPTO_MUTEX *lock; + CRYPTO_MUTEX *statelock; + CRYPTO_CONDVAR *condvar; + unsigned long thread_id; + int joinable; + OSSL_LIB_CTX *ctx; +} CRYPTO_THREAD; + +# if defined(OPENSSL_THREADS) + +# define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG) \ + do { \ + (THREAD)->state &= ~(FLAG); \ + } while ((void)0, 0) + +# define CRYPTO_THREAD_SET_STATE(THREAD, FLAG) \ + do { \ + (THREAD)->state |= (FLAG); \ + } while ((void)0, 0) + +# define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG) \ + do { \ + (THREAD)->state |= ((FLAG) << 16); \ + } while ((void)0, 0) + +# define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG) \ + do { \ + (THREAD)->state &= ~((FLAG) << 16); \ + } while ((void)0, 0) + +# else + +# define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG) +# define CRYPTO_THREAD_SET_STATE(THREAD, FLAG) +# define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG) +# define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG) + +# endif /* defined(OPENSSL_THREADS) */ + +CRYPTO_THREAD * ossl_crypto_thread_native_start(CRYPTO_THREAD_ROUTINE routine, + void *data, int joinable); +int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread); +int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread, + CRYPTO_THREAD_RETVAL *retval); +int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, + CRYPTO_THREAD_RETVAL *retval); +int ossl_crypto_thread_native_exit(void); +int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread); +int ossl_crypto_thread_native_clean(CRYPTO_THREAD *thread); + +#endif /* OSSL_INTERNAL_THREAD_ARCH_H */ diff --git a/include/internal/time.h b/include/internal/time.h new file mode 100644 index 0000000000..14d724abf5 --- /dev/null +++ b/include/internal/time.h @@ -0,0 +1,242 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_TIME_H +# define OSSL_INTERNAL_TIME_H +# pragma once + +# include /* uint64_t */ +# include "internal/e_os.h" /* for struct timeval */ +# include "internal/safe_math.h" + +/* + * Internal type defining a time. + * This should be treated as an opaque structure. + * + * The time datum is Unix's 1970 and at nanosecond precision, this gives + * a range of 584 years roughly. + */ +typedef struct { + uint64_t t; /* Ticks since the epoch */ +} OSSL_TIME; + +/* The precision of times allows this many values per second */ +# define OSSL_TIME_SECOND ((uint64_t)1000000000) + +/* One millisecond. */ +# define OSSL_TIME_MS (OSSL_TIME_SECOND / 1000) + +/* One microsecond. */ +# define OSSL_TIME_US (OSSL_TIME_MS / 1000) + +/* One nanosecond. */ +# define OSSL_TIME_NS (OSSL_TIME_US / 1000) + +#define ossl_seconds2time(s) ossl_ticks2time((s) * OSSL_TIME_SECOND) +#define ossl_time2seconds(t) (ossl_time2ticks(t) / OSSL_TIME_SECOND) +#define ossl_ms2time(ms) ossl_ticks2time((ms) * OSSL_TIME_MS) +#define ossl_time2ms(t) (ossl_time2ticks(t) / OSSL_TIME_MS) +#define ossl_us2time(us) ossl_ticks2time((us) * OSSL_TIME_US) +#define ossl_time2us(t) (ossl_time2ticks(t) / OSSL_TIME_US) + +/* + * Arithmetic operations on times. + * These operations are saturating, in that an overflow or underflow returns + * the largest or smallest value respectively. + */ +OSSL_SAFE_MATH_UNSIGNED(time, uint64_t) + +/* Convert a tick count into a time */ +static ossl_unused ossl_inline +OSSL_TIME ossl_ticks2time(uint64_t ticks) +{ + OSSL_TIME r; + + r.t = ticks; + return r; +} + +/* Convert a time to a tick count */ +static ossl_unused ossl_inline +uint64_t ossl_time2ticks(OSSL_TIME t) +{ + return t.t; +} + +/* Get current time */ +OSSL_TIME ossl_time_now(void); + +/* The beginning and end of the time range */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_zero(void) +{ + return ossl_ticks2time(0); +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_infinite(void) +{ + return ossl_ticks2time(~(uint64_t)0); +} + + +/* Convert time to timeval */ +static ossl_unused ossl_inline +struct timeval ossl_time_to_timeval(OSSL_TIME t) +{ + struct timeval tv; + int err = 0; + + /* + * Round up any nano secs which struct timeval doesn't support. Ensures that + * we never return a zero time if the input time is non zero + */ + t.t = safe_add_time(t.t, OSSL_TIME_US - 1, &err); + if (err) + t = ossl_time_infinite(); + +#ifdef _WIN32 + tv.tv_sec = (long int)(t.t / OSSL_TIME_SECOND); +#else + tv.tv_sec = (time_t)(t.t / OSSL_TIME_SECOND); +#endif + tv.tv_usec = (t.t % OSSL_TIME_SECOND) / OSSL_TIME_US; + return tv; +} + +/* Convert timeval to time */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_from_timeval(struct timeval tv) +{ + OSSL_TIME t; + +#ifndef __DJGPP__ /* tv_sec is unsigned on djgpp. */ + if (tv.tv_sec < 0) + return ossl_time_zero(); +#endif + t.t = tv.tv_sec * OSSL_TIME_SECOND + tv.tv_usec * OSSL_TIME_US; + return t; +} + +/* Convert OSSL_TIME to time_t */ +static ossl_unused ossl_inline +time_t ossl_time_to_time_t(OSSL_TIME t) +{ + return (time_t)(t.t / OSSL_TIME_SECOND); +} + +/* Convert time_t to OSSL_TIME */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_from_time_t(time_t t) +{ + OSSL_TIME ot; + + ot.t = t; + ot.t *= OSSL_TIME_SECOND; + return ot; +} + +/* Compare two time values, return -1 if less, 1 if greater and 0 if equal */ +static ossl_unused ossl_inline +int ossl_time_compare(OSSL_TIME a, OSSL_TIME b) +{ + if (a.t > b.t) + return 1; + if (a.t < b.t) + return -1; + return 0; +} + +/* Returns true if an OSSL_TIME is ossl_time_zero(). */ +static ossl_unused ossl_inline +int ossl_time_is_zero(OSSL_TIME t) +{ + return ossl_time_compare(t, ossl_time_zero()) == 0; +} + +/* Returns true if an OSSL_TIME is ossl_time_infinite(). */ +static ossl_unused ossl_inline +int ossl_time_is_infinite(OSSL_TIME t) +{ + return ossl_time_compare(t, ossl_time_infinite()) == 0; +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_add(OSSL_TIME a, OSSL_TIME b) +{ + OSSL_TIME r; + int err = 0; + + r.t = safe_add_time(a.t, b.t, &err); + return err ? ossl_time_infinite() : r; +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_subtract(OSSL_TIME a, OSSL_TIME b) +{ + OSSL_TIME r; + int err = 0; + + r.t = safe_sub_time(a.t, b.t, &err); + return err ? ossl_time_zero() : r; +} + +/* Returns |a - b|. */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_abs_difference(OSSL_TIME a, OSSL_TIME b) +{ + return a.t > b.t ? ossl_time_subtract(a, b) + : ossl_time_subtract(b, a); +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_multiply(OSSL_TIME a, uint64_t b) +{ + OSSL_TIME r; + int err = 0; + + r.t = safe_mul_time(a.t, b, &err); + return err ? ossl_time_infinite() : r; +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_divide(OSSL_TIME a, uint64_t b) +{ + OSSL_TIME r; + int err = 0; + + r.t = safe_div_time(a.t, b, &err); + return err ? ossl_time_zero() : r; +} + +static ossl_unused ossl_inline +OSSL_TIME ossl_time_muldiv(OSSL_TIME a, uint64_t b, uint64_t c) +{ + OSSL_TIME r; + int err = 0; + + r.t = safe_muldiv_time(a.t, b, c, &err); + return err ? ossl_time_zero() : r; +} + +/* Return higher of the two given time values. */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_max(OSSL_TIME a, OSSL_TIME b) +{ + return a.t > b.t ? a : b; +} + +/* Return the lower of the two given time values. */ +static ossl_unused ossl_inline +OSSL_TIME ossl_time_min(OSSL_TIME a, OSSL_TIME b) +{ + return a.t < b.t ? a : b; +} + +#endif diff --git a/include/internal/tlsgroups.h b/include/internal/tlsgroups.h index 8a35ced122..73fb53bc5f 100644 --- a/include/internal/tlsgroups.h +++ b/include/internal/tlsgroups.h @@ -41,6 +41,16 @@ # define OSSL_TLS_GROUP_ID_brainpoolP512r1 0x001C # define OSSL_TLS_GROUP_ID_x25519 0x001D # define OSSL_TLS_GROUP_ID_x448 0x001E +# define OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13 0x001F +# define OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13 0x0020 +# define OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13 0x0021 +# define OSSL_TLS_GROUP_ID_gc256A 0x0022 +# define OSSL_TLS_GROUP_ID_gc256B 0x0023 +# define OSSL_TLS_GROUP_ID_gc256C 0x0024 +# define OSSL_TLS_GROUP_ID_gc256D 0x0025 +# define OSSL_TLS_GROUP_ID_gc512A 0x0026 +# define OSSL_TLS_GROUP_ID_gc512B 0x0027 +# define OSSL_TLS_GROUP_ID_gc512C 0x0028 # define OSSL_TLS_GROUP_ID_ffdhe2048 0x0100 # define OSSL_TLS_GROUP_ID_ffdhe3072 0x0101 # define OSSL_TLS_GROUP_ID_ffdhe4096 0x0102 diff --git a/include/internal/tsan_assist.h b/include/internal/tsan_assist.h index 17205d1074..a840df0b24 100644 --- a/include/internal/tsan_assist.h +++ b/include/internal/tsan_assist.h @@ -47,33 +47,37 @@ * can use TSAN_QUALIFIER in cast specifically when it has to count. */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \ +#ifndef OSSL_INTERNAL_TSAN_ASSIST_H +# define OSSL_INTERNAL_TSAN_ASSIST_H +# pragma once + +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \ && !defined(__STDC_NO_ATOMICS__) -# include +# include -# if defined(ATOMIC_POINTER_LOCK_FREE) \ +# if defined(ATOMIC_POINTER_LOCK_FREE) \ && ATOMIC_POINTER_LOCK_FREE >= 2 -# define TSAN_QUALIFIER _Atomic -# define tsan_load(ptr) atomic_load_explicit((ptr), memory_order_relaxed) -# define tsan_store(ptr, val) atomic_store_explicit((ptr), (val), memory_order_relaxed) -# define tsan_add(ptr, n) atomic_fetch_add_explicit((ptr), (n), memory_order_relaxed) -# define tsan_ld_acq(ptr) atomic_load_explicit((ptr), memory_order_acquire) -# define tsan_st_rel(ptr, val) atomic_store_explicit((ptr), (val), memory_order_release) -# endif +# define TSAN_QUALIFIER _Atomic +# define tsan_load(ptr) atomic_load_explicit((ptr), memory_order_relaxed) +# define tsan_store(ptr, val) atomic_store_explicit((ptr), (val), memory_order_relaxed) +# define tsan_add(ptr, n) atomic_fetch_add_explicit((ptr), (n), memory_order_relaxed) +# define tsan_ld_acq(ptr) atomic_load_explicit((ptr), memory_order_acquire) +# define tsan_st_rel(ptr, val) atomic_store_explicit((ptr), (val), memory_order_release) +# endif -#elif defined(__GNUC__) && defined(__ATOMIC_RELAXED) +# elif defined(__GNUC__) && defined(__ATOMIC_RELAXED) -# if defined(__GCC_ATOMIC_POINTER_LOCK_FREE) \ +# if defined(__GCC_ATOMIC_POINTER_LOCK_FREE) \ && __GCC_ATOMIC_POINTER_LOCK_FREE >= 2 -# define TSAN_QUALIFIER volatile -# define tsan_load(ptr) __atomic_load_n((ptr), __ATOMIC_RELAXED) -# define tsan_store(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELAXED) -# define tsan_add(ptr, n) __atomic_fetch_add((ptr), (n), __ATOMIC_RELAXED) -# define tsan_ld_acq(ptr) __atomic_load_n((ptr), __ATOMIC_ACQUIRE) -# define tsan_st_rel(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELEASE) -# endif +# define TSAN_QUALIFIER volatile +# define tsan_load(ptr) __atomic_load_n((ptr), __ATOMIC_RELAXED) +# define tsan_store(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELAXED) +# define tsan_add(ptr, n) __atomic_fetch_add((ptr), (n), __ATOMIC_RELAXED) +# define tsan_ld_acq(ptr) __atomic_load_n((ptr), __ATOMIC_ACQUIRE) +# define tsan_st_rel(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELEASE) +# endif -#elif defined(_MSC_VER) && _MSC_VER>=1200 \ +# elif defined(_MSC_VER) && _MSC_VER>=1200 \ && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ defined(_M_ARM64) || (defined(_M_ARM) && _M_ARM >= 7 && !defined(_WIN32_WCE))) /* @@ -87,62 +91,63 @@ * with additional instructions and penalties, it kind of makes sense to * default to "iso"... */ -# define TSAN_QUALIFIER volatile -# if defined(_M_ARM) || defined(_M_ARM64) -# define _InterlockedExchangeAdd _InterlockedExchangeAdd_nf -# pragma intrinsic(_InterlockedExchangeAdd_nf) -# pragma intrinsic(__iso_volatile_load32, __iso_volatile_store32) -# ifdef _WIN64 -# define _InterlockedExchangeAdd64 _InterlockedExchangeAdd64_nf -# pragma intrinsic(_InterlockedExchangeAdd64_nf) -# pragma intrinsic(__iso_volatile_load64, __iso_volatile_store64) -# define tsan_load(ptr) (sizeof(*(ptr)) == 8 ? __iso_volatile_load64(ptr) \ +# define TSAN_QUALIFIER volatile +# if defined(_M_ARM) || defined(_M_ARM64) +# define _InterlockedExchangeAdd _InterlockedExchangeAdd_nf +# pragma intrinsic(_InterlockedExchangeAdd_nf) +# pragma intrinsic(__iso_volatile_load32, __iso_volatile_store32) +# ifdef _WIN64 +# define _InterlockedExchangeAdd64 _InterlockedExchangeAdd64_nf +# pragma intrinsic(_InterlockedExchangeAdd64_nf) +# pragma intrinsic(__iso_volatile_load64, __iso_volatile_store64) +# define tsan_load(ptr) (sizeof(*(ptr)) == 8 ? __iso_volatile_load64(ptr) \ : __iso_volatile_load32(ptr)) -# define tsan_store(ptr, val) (sizeof(*(ptr)) == 8 ? __iso_volatile_store64((ptr), (val)) \ +# define tsan_store(ptr, val) (sizeof(*(ptr)) == 8 ? __iso_volatile_store64((ptr), (val)) \ : __iso_volatile_store32((ptr), (val))) +# else +# define tsan_load(ptr) __iso_volatile_load32(ptr) +# define tsan_store(ptr, val) __iso_volatile_store32((ptr), (val)) +# endif # else -# define tsan_load(ptr) __iso_volatile_load32(ptr) -# define tsan_store(ptr, val) __iso_volatile_store32((ptr), (val)) +# define tsan_load(ptr) (*(ptr)) +# define tsan_store(ptr, val) (*(ptr) = (val)) # endif -# else -# define tsan_load(ptr) (*(ptr)) -# define tsan_store(ptr, val) (*(ptr) = (val)) -# endif -# pragma intrinsic(_InterlockedExchangeAdd) -# ifdef _WIN64 -# pragma intrinsic(_InterlockedExchangeAdd64) -# define tsan_add(ptr, n) (sizeof(*(ptr)) == 8 ? _InterlockedExchangeAdd64((ptr), (n)) \ +# pragma intrinsic(_InterlockedExchangeAdd) +# ifdef _WIN64 +# pragma intrinsic(_InterlockedExchangeAdd64) +# define tsan_add(ptr, n) (sizeof(*(ptr)) == 8 ? _InterlockedExchangeAdd64((ptr), (n)) \ : _InterlockedExchangeAdd((ptr), (n))) -# else -# define tsan_add(ptr, n) _InterlockedExchangeAdd((ptr), (n)) -# endif -# if !defined(_ISO_VOLATILE) -# define tsan_ld_acq(ptr) (*(ptr)) -# define tsan_st_rel(ptr, val) (*(ptr) = (val)) -# endif +# else +# define tsan_add(ptr, n) _InterlockedExchangeAdd((ptr), (n)) +# endif +# if !defined(_ISO_VOLATILE) +# define tsan_ld_acq(ptr) (*(ptr)) +# define tsan_st_rel(ptr, val) (*(ptr) = (val)) +# endif -#endif +# endif -#ifndef TSAN_QUALIFIER +# ifndef TSAN_QUALIFIER -# ifdef OPENSSL_THREADS -# define TSAN_QUALIFIER volatile -# define TSAN_REQUIRES_LOCKING -# else /* OPENSSL_THREADS */ -# define TSAN_QUALIFIER -# endif /* OPENSSL_THREADS */ +# ifdef OPENSSL_THREADS +# define TSAN_QUALIFIER volatile +# define TSAN_REQUIRES_LOCKING +# else /* OPENSSL_THREADS */ +# define TSAN_QUALIFIER +# endif /* OPENSSL_THREADS */ -# define tsan_load(ptr) (*(ptr)) -# define tsan_store(ptr, val) (*(ptr) = (val)) -# define tsan_add(ptr, n) (*(ptr) += (n)) +# define tsan_load(ptr) (*(ptr)) +# define tsan_store(ptr, val) (*(ptr) = (val)) +# define tsan_add(ptr, n) (*(ptr) += (n)) /* * Lack of tsan_ld_acq and tsan_ld_rel means that compiler support is not * sophisticated enough to support them. Code that relies on them should be * protected with #ifdef tsan_ld_acq with locked fallback. */ -#endif +# endif -#define tsan_counter(ptr) tsan_add((ptr), 1) -#define tsan_decr(ptr) tsan_add((ptr), -1) +# define tsan_counter(ptr) tsan_add((ptr), 1) +# define tsan_decr(ptr) tsan_add((ptr), -1) +#endif diff --git a/include/internal/uint_set.h b/include/internal/uint_set.h new file mode 100644 index 0000000000..dcb29b33f3 --- /dev/null +++ b/include/internal/uint_set.h @@ -0,0 +1,63 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef OSSL_UINT_SET_H +# define OSSL_UINT_SET_H + +#include "openssl/params.h" +#include "internal/list.h" + +/* + * uint64_t Integer Sets + * ===================== + * + * Utilities for managing a logical set of unsigned 64-bit integers. The + * structure tracks each contiguous range of integers using one allocation and + * is thus optimised for cases where integers tend to appear consecutively. + * Queries are optimised under the assumption that they will generally be made + * on integers near the end of the set. + * + * Discussion of implementation details can be found in uint_set.c. + */ +typedef struct uint_range_st { + uint64_t start, end; +} UINT_RANGE; + +typedef struct uint_set_item_st UINT_SET_ITEM; +struct uint_set_item_st { + OSSL_LIST_MEMBER(uint_set, UINT_SET_ITEM); + UINT_RANGE range; +}; + +DEFINE_LIST_OF(uint_set, UINT_SET_ITEM); + +typedef OSSL_LIST(uint_set) UINT_SET; + +void ossl_uint_set_init(UINT_SET *s); +void ossl_uint_set_destroy(UINT_SET *s); + +/* + * Insert a range into a integer set. Returns 0 on allocation failure, in which + * case the integer set is in a valid but undefined state. Otherwise, returns 1. + * Ranges can overlap existing ranges without limitation. If a range is a subset + * of an existing range in the set, this is a no-op and returns 1. + */ +int ossl_uint_set_insert(UINT_SET *s, const UINT_RANGE *range); + +/* + * Remove a range from the set. Returns 0 on allocation failure, in which case + * the integer set is unchanged. Otherwise, returns 1. Ranges which are not + * already in the set can be removed without issue. If a passed range is not in + * the integer set at all, this is a no-op and returns 1. + */ +int ossl_uint_set_remove(UINT_SET *s, const UINT_RANGE *range); + +/* Returns 1 iff the given integer is in the integer set. */ +int ossl_uint_set_query(const UINT_SET *s, uint64_t v); + +#endif diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index 85ae8d589a..0971234594 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/asn1.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -158,7 +158,7 @@ SKM_DEFINE_STACK_OF_INTERNAL(X509_ALGOR, X509_ALGOR, X509_ALGOR) -# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +# define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ /* * This indicates that the ASN1_STRING is not a real value but just a place * holder for the location where indefinite length constructed data should be @@ -999,6 +999,8 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, unsigned char *data, int max_len); void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); +void *ASN1_item_unpack_ex(const ASN1_STRING *oct, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); diff --git a/include/openssl/asn1.h.in b/include/openssl/asn1.h.in index d478bc96d6..798b22115c 100644 --- a/include/openssl/asn1.h.in +++ b/include/openssl/asn1.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -135,7 +135,7 @@ extern "C" { -} -# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +# define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ /* * This indicates that the ASN1_STRING is not a real value but just a place * holder for the location where indefinite length constructed data should be @@ -832,6 +832,8 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, unsigned char *data, int max_len); void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); +void *ASN1_item_unpack_ex(const ASN1_STRING *oct, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); diff --git a/include/openssl/async.h b/include/openssl/async.h index bc27d5db06..826ffb9934 100644 --- a/include/openssl/async.h +++ b/include/openssl/async.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -80,6 +80,14 @@ int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); int ASYNC_is_capable(void); +typedef void *(*ASYNC_stack_alloc_fn)(size_t *num); +typedef void (*ASYNC_stack_free_fn)(void *addr); + +int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn, + ASYNC_stack_free_fn free_fn); +void ASYNC_get_mem_functions(ASYNC_stack_alloc_fn *alloc_fn, + ASYNC_stack_free_fn *free_fn); + int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret, int (*func)(void *), void *args, size_t size); int ASYNC_pause_job(void); diff --git a/include/openssl/bio.h b/include/openssl/bio.h index e16cf622c6..ea584defe5 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/bio.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -67,6 +67,8 @@ extern "C" { # define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) # endif # define BIO_TYPE_CORE_TO_PROV (25|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_DGRAM_PAIR (26|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_DGRAM_MEM (27|BIO_TYPE_SOURCE_SINK) #define BIO_TYPE_START 128 @@ -171,6 +173,30 @@ extern "C" { # define BIO_CTRL_SET_INDENT 80 # define BIO_CTRL_GET_INDENT 81 +# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP 82 +# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE 83 +# define BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE 84 +# define BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS 85 +# define BIO_CTRL_DGRAM_GET_CAPS 86 +# define BIO_CTRL_DGRAM_SET_CAPS 87 +# define BIO_CTRL_DGRAM_GET_NO_TRUNC 88 +# define BIO_CTRL_DGRAM_SET_NO_TRUNC 89 + +/* + * internal BIO: + * # define BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE 90 + */ + +# define BIO_CTRL_GET_RPOLL_DESCRIPTOR 91 +# define BIO_CTRL_GET_WPOLL_DESCRIPTOR 92 +# define BIO_CTRL_DGRAM_DETECT_PEER_ADDR 93 + +# define BIO_DGRAM_CAP_NONE 0U +# define BIO_DGRAM_CAP_HANDLES_SRC_ADDR (1U << 0) +# define BIO_DGRAM_CAP_HANDLES_DST_ADDR (1U << 1) +# define BIO_DGRAM_CAP_PROVIDES_SRC_ADDR (1U << 2) +# define BIO_DGRAM_CAP_PROVIDES_DST_ADDR (1U << 3) + # ifndef OPENSSL_NO_KTLS # define BIO_get_ktls_send(b) \ (BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL) > 0) @@ -208,7 +234,7 @@ extern "C" { # define BIO_FLAGS_NONCLEAR_RST 0x400 # define BIO_FLAGS_IN_EOF 0x800 -/* the BIO FLAGS values 0x1000 to 0x4000 are reserved for internal KTLS flags */ +/* the BIO FLAGS values 0x1000 to 0x8000 are reserved for internal KTLS flags */ typedef union bio_addr_st BIO_ADDR; typedef struct bio_addrinfo_st BIO_ADDRINFO; @@ -256,12 +282,14 @@ void BIO_clear_flags(BIO *b, int flags); # define BIO_RR_ACCEPT 0x03 /* These are passed by the BIO callback */ -# define BIO_CB_FREE 0x01 -# define BIO_CB_READ 0x02 -# define BIO_CB_WRITE 0x03 -# define BIO_CB_PUTS 0x04 -# define BIO_CB_GETS 0x05 -# define BIO_CB_CTRL 0x06 +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 +# define BIO_CB_RECVMMSG 0x07 +# define BIO_CB_SENDMMSG 0x08 /* * The callback is called before and after the underling operation, The @@ -362,6 +390,34 @@ struct bio_dgram_sctp_prinfo { }; # endif +/* BIO_sendmmsg/BIO_recvmmsg-related definitions */ +typedef struct bio_msg_st { + void *data; + size_t data_len; + BIO_ADDR *peer, *local; + uint64_t flags; +} BIO_MSG; + +typedef struct bio_mmsg_cb_args_st { + BIO_MSG *msg; + size_t stride, num_msg; + uint64_t flags; + size_t *msgs_processed; +} BIO_MMSG_CB_ARGS; + +#define BIO_POLL_DESCRIPTOR_TYPE_NONE 0 +#define BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD 1 +#define BIO_POLL_DESCRIPTOR_CUSTOM_START 8192 + +typedef struct bio_poll_descriptor_st { + uint32_t type; + union { + int fd; + void *custom; + uintptr_t custom_ui; + } value; +} BIO_POLL_DESCRIPTOR; + /* * #define BIO_CONN_get_param_hostname BIO_ctrl */ @@ -428,10 +484,17 @@ struct bio_dgram_sctp_prinfo { # define BIO_C_SET_CONNECT_MODE 155 +# define BIO_C_SET_TFO 156 /* like BIO_C_SET_NBIO */ + +# define BIO_C_SET_SOCK_TYPE 157 +# define BIO_C_GET_SOCK_TYPE 158 +# define BIO_C_GET_DGRAM_BIO 159 + # define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) # define BIO_get_app_data(s) BIO_get_ex_data(s,0) -# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) +# define BIO_set_tfo(b,n) BIO_ctrl(b,BIO_C_SET_TFO,(n),NULL) # ifndef OPENSSL_NO_SOCK /* IP families we support, for BIO_s_connect() and BIO_s_accept() */ @@ -452,7 +515,11 @@ struct bio_dgram_sctp_prinfo { # define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) # define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) # define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_get_conn_mode(b) BIO_ctrl(b,BIO_C_GET_CONNECT,4,NULL) # define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) +# define BIO_set_sock_type(b,t) BIO_ctrl(b,BIO_C_SET_SOCK_TYPE,(t),NULL) +# define BIO_get_sock_type(b) BIO_ctrl(b,BIO_C_GET_SOCK_TYPE,0,NULL) +# define BIO_get0_dgram_bio(b, p) BIO_ctrl(b,BIO_C_GET_DGRAM_BIO,0,(void *)(BIO **)(p)) /* BIO_s_accept() */ # define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ @@ -469,6 +536,7 @@ struct bio_dgram_sctp_prinfo { (char *)(bio)) # define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) # define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) +# define BIO_set_tfo_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,5,(n)?(void *)"a":NULL) /* Aliases kept for backward compatibility */ # define BIO_BIND_NORMAL 0 @@ -596,8 +664,30 @@ int BIO_ctrl_reset_read_request(BIO *b); (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) # define BIO_dgram_set_peer(b,peer) \ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_detect_peer_addr(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_DETECT_PEER_ADDR, 0, (char *)(peer)) # define BIO_dgram_get_mtu_overhead(b) \ (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) +# define BIO_dgram_get_local_addr_cap(b) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, NULL) +# define BIO_dgram_get_local_addr_enable(b, penable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, (char *)(penable)) +# define BIO_dgram_set_local_addr_enable(b, enable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, (enable), NULL) +# define BIO_dgram_get_effective_caps(b) \ + (uint32_t)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS, 0, NULL) +# define BIO_dgram_get_caps(b) \ + (uint32_t)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_CAPS, 0, NULL) +# define BIO_dgram_set_caps(b, caps) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_CAPS, (long)(caps), NULL) +# define BIO_dgram_get_no_trunc(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_NO_TRUNC, 0, NULL) +# define BIO_dgram_set_no_trunc(b, enable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_NO_TRUNC, (enable), NULL) +# define BIO_dgram_get_mtu(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU, 0, NULL) +# define BIO_dgram_set_mtu(b, mtu) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_MTU, (mtu), NULL) /* ctrl macros for BIO_f_prefix */ # define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p)) @@ -640,10 +730,18 @@ void BIO_vfree(BIO *a); int BIO_up_ref(BIO *a); int BIO_read(BIO *b, void *data, int dlen); int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +__owur int BIO_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed); int BIO_gets(BIO *bp, char *buf, int size); int BIO_get_line(BIO *bio, char *buf, int size); int BIO_write(BIO *b, const void *data, int dlen); int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +__owur int BIO_sendmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed); +__owur int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc); +__owur int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc); int BIO_puts(BIO *bp, const char *buf); int BIO_indent(BIO *b, int indent, int max); long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); @@ -667,6 +765,9 @@ int BIO_nwrite0(BIO *bio, char **buf); int BIO_nwrite(BIO *bio, char **buf, int num); const BIO_METHOD *BIO_s_mem(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_dgram_mem(void); +# endif const BIO_METHOD *BIO_s_secmem(void); BIO *BIO_new_mem_buf(const void *buf, int len); # ifndef OPENSSL_NO_SOCK @@ -686,6 +787,7 @@ const BIO_METHOD *BIO_f_nbio_test(void); const BIO_METHOD *BIO_f_prefix(void); const BIO_METHOD *BIO_s_core(void); # ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_dgram_pair(void); const BIO_METHOD *BIO_s_datagram(void); int BIO_dgram_non_fatal_error(int error); BIO *BIO_new_dgram(int fd, int close_flag); @@ -704,6 +806,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b); # ifndef OPENSSL_NO_SOCK int BIO_sock_should_retry(int i); int BIO_sock_non_fatal_error(int error); +int BIO_err_is_non_fatal(unsigned int errcode); int BIO_socket_wait(int fd, int for_read, time_t max_time); # endif int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds); @@ -726,6 +829,8 @@ int BIO_hex_string(BIO *out, int indent, int width, const void *data, # ifndef OPENSSL_NO_SOCK BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src); +BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap); int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, const void *where, size_t wherelen, unsigned short port); void BIO_ADDR_free(BIO_ADDR *); @@ -788,6 +893,7 @@ int BIO_sock_info(int sock, # define BIO_SOCK_KEEPALIVE 0x04 # define BIO_SOCK_NONBLOCK 0x08 # define BIO_SOCK_NODELAY 0x10 +# define BIO_SOCK_TFO 0x20 int BIO_socket(int domain, int socktype, int protocol, int options); int BIO_connect(int sock, const BIO_ADDR *addr, int options); @@ -805,6 +911,11 @@ BIO *BIO_new_fd(int fd, int close_flag); int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, BIO **bio2, size_t writebuf2); +# ifndef OPENSSL_NO_DGRAM +int BIO_new_bio_dgram_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +# endif + /* * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default @@ -856,18 +967,30 @@ int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); int BIO_meth_set_write_ex(BIO_METHOD *biom, int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int BIO_meth_set_sendmmsg(BIO_METHOD *biom, + int (*f) (BIO *, BIO_MSG *, size_t, size_t, + uint64_t, size_t *)); +int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, + size_t, size_t, + uint64_t, size_t *); int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); int BIO_meth_set_read_ex(BIO_METHOD *biom, int (*bread) (BIO *, char *, size_t, size_t *)); +int BIO_meth_set_recvmmsg(BIO_METHOD *biom, + int (*f) (BIO *, BIO_MSG *, size_t, size_t, + uint64_t, size_t *)); +int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, + size_t, size_t, + uint64_t, size_t *); int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); int BIO_meth_set_gets(BIO_METHOD *biom, - int (*gets) (BIO *, char *, int)); + int (*ossl_gets) (BIO *, char *, int)); long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in index c521e41e4a..418d119737 100644 --- a/include/openssl/bio.h.in +++ b/include/openssl/bio.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -68,6 +68,8 @@ extern "C" { # define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) # endif # define BIO_TYPE_CORE_TO_PROV (25|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_DGRAM_PAIR (26|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_DGRAM_MEM (27|BIO_TYPE_SOURCE_SINK) #define BIO_TYPE_START 128 @@ -172,6 +174,30 @@ extern "C" { # define BIO_CTRL_SET_INDENT 80 # define BIO_CTRL_GET_INDENT 81 +# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP 82 +# define BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE 83 +# define BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE 84 +# define BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS 85 +# define BIO_CTRL_DGRAM_GET_CAPS 86 +# define BIO_CTRL_DGRAM_SET_CAPS 87 +# define BIO_CTRL_DGRAM_GET_NO_TRUNC 88 +# define BIO_CTRL_DGRAM_SET_NO_TRUNC 89 + +/* + * internal BIO: + * # define BIO_CTRL_SET_KTLS_TX_ZEROCOPY_SENDFILE 90 + */ + +# define BIO_CTRL_GET_RPOLL_DESCRIPTOR 91 +# define BIO_CTRL_GET_WPOLL_DESCRIPTOR 92 +# define BIO_CTRL_DGRAM_DETECT_PEER_ADDR 93 + +# define BIO_DGRAM_CAP_NONE 0U +# define BIO_DGRAM_CAP_HANDLES_SRC_ADDR (1U << 0) +# define BIO_DGRAM_CAP_HANDLES_DST_ADDR (1U << 1) +# define BIO_DGRAM_CAP_PROVIDES_SRC_ADDR (1U << 2) +# define BIO_DGRAM_CAP_PROVIDES_DST_ADDR (1U << 3) + # ifndef OPENSSL_NO_KTLS # define BIO_get_ktls_send(b) \ (BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL) > 0) @@ -209,7 +235,7 @@ extern "C" { # define BIO_FLAGS_NONCLEAR_RST 0x400 # define BIO_FLAGS_IN_EOF 0x800 -/* the BIO FLAGS values 0x1000 to 0x4000 are reserved for internal KTLS flags */ +/* the BIO FLAGS values 0x1000 to 0x8000 are reserved for internal KTLS flags */ typedef union bio_addr_st BIO_ADDR; typedef struct bio_addrinfo_st BIO_ADDRINFO; @@ -257,12 +283,14 @@ void BIO_clear_flags(BIO *b, int flags); # define BIO_RR_ACCEPT 0x03 /* These are passed by the BIO callback */ -# define BIO_CB_FREE 0x01 -# define BIO_CB_READ 0x02 -# define BIO_CB_WRITE 0x03 -# define BIO_CB_PUTS 0x04 -# define BIO_CB_GETS 0x05 -# define BIO_CB_CTRL 0x06 +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 +# define BIO_CB_RECVMMSG 0x07 +# define BIO_CB_SENDMMSG 0x08 /* * The callback is called before and after the underling operation, The @@ -339,6 +367,34 @@ struct bio_dgram_sctp_prinfo { }; # endif +/* BIO_sendmmsg/BIO_recvmmsg-related definitions */ +typedef struct bio_msg_st { + void *data; + size_t data_len; + BIO_ADDR *peer, *local; + uint64_t flags; +} BIO_MSG; + +typedef struct bio_mmsg_cb_args_st { + BIO_MSG *msg; + size_t stride, num_msg; + uint64_t flags; + size_t *msgs_processed; +} BIO_MMSG_CB_ARGS; + +#define BIO_POLL_DESCRIPTOR_TYPE_NONE 0 +#define BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD 1 +#define BIO_POLL_DESCRIPTOR_CUSTOM_START 8192 + +typedef struct bio_poll_descriptor_st { + uint32_t type; + union { + int fd; + void *custom; + uintptr_t custom_ui; + } value; +} BIO_POLL_DESCRIPTOR; + /* * #define BIO_CONN_get_param_hostname BIO_ctrl */ @@ -405,10 +461,17 @@ struct bio_dgram_sctp_prinfo { # define BIO_C_SET_CONNECT_MODE 155 +# define BIO_C_SET_TFO 156 /* like BIO_C_SET_NBIO */ + +# define BIO_C_SET_SOCK_TYPE 157 +# define BIO_C_GET_SOCK_TYPE 158 +# define BIO_C_GET_DGRAM_BIO 159 + # define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) # define BIO_get_app_data(s) BIO_get_ex_data(s,0) -# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) +# define BIO_set_tfo(b,n) BIO_ctrl(b,BIO_C_SET_TFO,(n),NULL) # ifndef OPENSSL_NO_SOCK /* IP families we support, for BIO_s_connect() and BIO_s_accept() */ @@ -429,7 +492,11 @@ struct bio_dgram_sctp_prinfo { # define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) # define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) # define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_get_conn_mode(b) BIO_ctrl(b,BIO_C_GET_CONNECT,4,NULL) # define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) +# define BIO_set_sock_type(b,t) BIO_ctrl(b,BIO_C_SET_SOCK_TYPE,(t),NULL) +# define BIO_get_sock_type(b) BIO_ctrl(b,BIO_C_GET_SOCK_TYPE,0,NULL) +# define BIO_get0_dgram_bio(b, p) BIO_ctrl(b,BIO_C_GET_DGRAM_BIO,0,(void *)(BIO **)(p)) /* BIO_s_accept() */ # define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ @@ -446,6 +513,7 @@ struct bio_dgram_sctp_prinfo { (char *)(bio)) # define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) # define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) +# define BIO_set_tfo_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,5,(n)?(void *)"a":NULL) /* Aliases kept for backward compatibility */ # define BIO_BIND_NORMAL 0 @@ -573,8 +641,30 @@ int BIO_ctrl_reset_read_request(BIO *b); (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) # define BIO_dgram_set_peer(b,peer) \ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_detect_peer_addr(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_DETECT_PEER_ADDR, 0, (char *)(peer)) # define BIO_dgram_get_mtu_overhead(b) \ (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) +# define BIO_dgram_get_local_addr_cap(b) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, NULL) +# define BIO_dgram_get_local_addr_enable(b, penable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, (char *)(penable)) +# define BIO_dgram_set_local_addr_enable(b, enable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, (enable), NULL) +# define BIO_dgram_get_effective_caps(b) \ + (uint32_t)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS, 0, NULL) +# define BIO_dgram_get_caps(b) \ + (uint32_t)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_CAPS, 0, NULL) +# define BIO_dgram_set_caps(b, caps) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_CAPS, (long)(caps), NULL) +# define BIO_dgram_get_no_trunc(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_NO_TRUNC, 0, NULL) +# define BIO_dgram_set_no_trunc(b, enable) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_NO_TRUNC, (enable), NULL) +# define BIO_dgram_get_mtu(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU, 0, NULL) +# define BIO_dgram_set_mtu(b, mtu) \ + (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_MTU, (mtu), NULL) /* ctrl macros for BIO_f_prefix */ # define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p)) @@ -617,10 +707,18 @@ void BIO_vfree(BIO *a); int BIO_up_ref(BIO *a); int BIO_read(BIO *b, void *data, int dlen); int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +__owur int BIO_recvmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed); int BIO_gets(BIO *bp, char *buf, int size); int BIO_get_line(BIO *bio, char *buf, int size); int BIO_write(BIO *b, const void *data, int dlen); int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +__owur int BIO_sendmmsg(BIO *b, BIO_MSG *msg, + size_t stride, size_t num_msg, uint64_t flags, + size_t *msgs_processed); +__owur int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc); +__owur int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc); int BIO_puts(BIO *bp, const char *buf); int BIO_indent(BIO *b, int indent, int max); long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); @@ -644,6 +742,9 @@ int BIO_nwrite0(BIO *bio, char **buf); int BIO_nwrite(BIO *bio, char **buf, int num); const BIO_METHOD *BIO_s_mem(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_dgram_mem(void); +# endif const BIO_METHOD *BIO_s_secmem(void); BIO *BIO_new_mem_buf(const void *buf, int len); # ifndef OPENSSL_NO_SOCK @@ -663,6 +764,7 @@ const BIO_METHOD *BIO_f_nbio_test(void); const BIO_METHOD *BIO_f_prefix(void); const BIO_METHOD *BIO_s_core(void); # ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_dgram_pair(void); const BIO_METHOD *BIO_s_datagram(void); int BIO_dgram_non_fatal_error(int error); BIO *BIO_new_dgram(int fd, int close_flag); @@ -681,6 +783,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b); # ifndef OPENSSL_NO_SOCK int BIO_sock_should_retry(int i); int BIO_sock_non_fatal_error(int error); +int BIO_err_is_non_fatal(unsigned int errcode); int BIO_socket_wait(int fd, int for_read, time_t max_time); # endif int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds); @@ -703,6 +806,8 @@ int BIO_hex_string(BIO *out, int indent, int width, const void *data, # ifndef OPENSSL_NO_SOCK BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_copy(BIO_ADDR *dst, const BIO_ADDR *src); +BIO_ADDR *BIO_ADDR_dup(const BIO_ADDR *ap); int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, const void *where, size_t wherelen, unsigned short port); void BIO_ADDR_free(BIO_ADDR *); @@ -765,6 +870,7 @@ int BIO_sock_info(int sock, # define BIO_SOCK_KEEPALIVE 0x04 # define BIO_SOCK_NONBLOCK 0x08 # define BIO_SOCK_NODELAY 0x10 +# define BIO_SOCK_TFO 0x20 int BIO_socket(int domain, int socktype, int protocol, int options); int BIO_connect(int sock, const BIO_ADDR *addr, int options); @@ -782,6 +888,11 @@ BIO *BIO_new_fd(int fd, int close_flag); int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, BIO **bio2, size_t writebuf2); +# ifndef OPENSSL_NO_DGRAM +int BIO_new_bio_dgram_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +# endif + /* * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default @@ -833,18 +944,30 @@ int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int)); int BIO_meth_set_write_ex(BIO_METHOD *biom, int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int BIO_meth_set_sendmmsg(BIO_METHOD *biom, + int (*f) (BIO *, BIO_MSG *, size_t, size_t, + uint64_t, size_t *)); +int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, + size_t, size_t, + uint64_t, size_t *); int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int)); int BIO_meth_set_read_ex(BIO_METHOD *biom, int (*bread) (BIO *, char *, size_t, size_t *)); +int BIO_meth_set_recvmmsg(BIO_METHOD *biom, + int (*f) (BIO *, BIO_MSG *, size_t, size_t, + uint64_t, size_t *)); +int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, + size_t, size_t, + uint64_t, size_t *); int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *)); int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); int BIO_meth_set_gets(BIO_METHOD *biom, - int (*gets) (BIO *, char *, int)); + int (*ossl_gets) (BIO *, char *, int)); long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *)); diff --git a/include/openssl/bioerr.h b/include/openssl/bioerr.h index 787b30afce..e4fdb64974 100644 --- a/include/openssl/bioerr.h +++ b/include/openssl/bioerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -37,14 +37,18 @@ # define BIO_R_IN_USE 123 # define BIO_R_LENGTH_TOO_LONG 102 # define BIO_R_LISTEN_V6_ONLY 136 +# define BIO_R_LOCAL_ADDR_NOT_AVAILABLE 111 # define BIO_R_LOOKUP_RETURNED_NOTHING 142 # define BIO_R_MALFORMED_HOST_OR_SERVICE 130 # define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NON_FATAL 112 # define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 # define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 # define BIO_R_NO_PORT_DEFINED 113 # define BIO_R_NO_SUCH_FILE 128 # define BIO_R_NULL_PARAMETER 115 /* unused */ +# define BIO_R_TFO_DISABLED 106 +# define BIO_R_TFO_NO_KERNEL_SUPPORT 108 # define BIO_R_TRANSFER_ERROR 104 # define BIO_R_TRANSFER_TIMEOUT 105 # define BIO_R_UNABLE_TO_BIND_SOCKET 117 @@ -53,6 +57,7 @@ # define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 # define BIO_R_UNABLE_TO_NODELAY 138 # define BIO_R_UNABLE_TO_REUSEADDR 139 +# define BIO_R_UNABLE_TO_TFO 109 # define BIO_R_UNAVAILABLE_IP_FAMILY 145 # define BIO_R_UNINITIALIZED 120 # define BIO_R_UNKNOWN_INFO_TYPE 140 @@ -61,5 +66,7 @@ # define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 # define BIO_R_WRITE_TO_READ_ONLY_BIO 126 # define BIO_R_WSASTARTUP 122 +# define BIO_R_PORT_MISMATCH 150 +# define BIO_R_PEER_ADDR_NOT_AVAILABLE 151 #endif diff --git a/include/openssl/bn.h b/include/openssl/bn.h index 27b127a588..ea706dca7f 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -241,12 +241,18 @@ void BN_clear_free(BIGNUM *a); BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); void BN_swap(BIGNUM *a, BIGNUM *b); BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret); int BN_bn2bin(const BIGNUM *a, unsigned char *to); int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen); BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret); +BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret); int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen); +int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen); BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); int BN_bn2mpi(const BIGNUM *a, unsigned char *to); int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); diff --git a/include/openssl/cmp.h b/include/openssl/cmp.h index 49825570d8..60beffd57e 100644 --- a/include/openssl/cmp.h +++ b/include/openssl/cmp.h @@ -35,7 +35,9 @@ extern "C" { # endif -# define OSSL_CMP_PVNO 2 +# define OSSL_CMP_PVNO_2 2 +# define OSSL_CMP_PVNO_3 3 +# define OSSL_CMP_PVNO OSSL_CMP_PVNO_2 /* v2 is the default */ /*- * PKIFailureInfo ::= BIT STRING { @@ -137,7 +139,6 @@ extern "C" { # if OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN > INT_MAX # error CMP_PKIFAILUREINFO_MAX bit pattern does not fit in type int # endif - typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO; # define OSSL_CMP_CTX_FAILINFO_badAlg (1 << 0) @@ -203,8 +204,8 @@ typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO; # define OSSL_CMP_PKISTATUS_revocationWarning 4 # define OSSL_CMP_PKISTATUS_revocationNotification 5 # define OSSL_CMP_PKISTATUS_keyUpdateWarning 6 - typedef ASN1_INTEGER OSSL_CMP_PKISTATUS; + DECLARE_ASN1_ITEM(OSSL_CMP_PKISTATUS) # define OSSL_CMP_CERTORENCCERT_CERTIFICATE 0 @@ -378,18 +379,35 @@ ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav); int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, OSSL_CMP_ITAV *itav); void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts); +int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out); + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaCert(const X509 *rootCaCert); +int OSSL_CMP_ITAV_get0_rootCaCert(const OSSL_CMP_ITAV *itav, X509 **out); +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, + const X509 *newWithOld, + const X509 *oldWithNew); +int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, + X509 **newWithNew, + X509 **newWithOld, + X509 **oldWithNew); + void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); /* from cmp_ctx.c */ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx); +OSSL_LIB_CTX *OSSL_CMP_CTX_get0_libctx(const OSSL_CMP_CTX *ctx); +const char *OSSL_CMP_CTX_get0_propq(const OSSL_CMP_CTX *ctx); /* CMP general options: */ # define OSSL_CMP_OPT_LOG_VERBOSITY 0 /* CMP transfer options: */ -# define OSSL_CMP_OPT_KEEP_ALIVE 10 -# define OSSL_CMP_OPT_MSG_TIMEOUT 11 +# define OSSL_CMP_OPT_KEEP_ALIVE 10 +# define OSSL_CMP_OPT_MSG_TIMEOUT 11 # define OSSL_CMP_OPT_TOTAL_TIMEOUT 12 +# define OSSL_CMP_OPT_USE_TLS 13 /* CMP request options: */ # define OSSL_CMP_OPT_VALIDITY_DAYS 20 # define OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT 21 @@ -420,9 +438,11 @@ int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address); int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port); int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name); int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names); +# ifndef OPENSSL_NO_HTTP int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb); int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg); void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx); +# endif typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req); int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb); @@ -432,7 +452,9 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert); int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store); +# define OSSL_CMP_CTX_set0_trusted OSSL_CMP_CTX_set0_trustedStore X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx); +# define OSSL_CMP_CTX_get0_trusted OSSL_CMP_CTX_get0_trustedStore int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs); STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx); /* client authentication: */ @@ -454,6 +476,7 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey); EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv); int OSSL_CMP_CTX_set1_issuer(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_set1_serialNumber(OSSL_CMP_CTX *ctx, const ASN1_INTEGER *sn); int OSSL_CMP_CTX_set1_subjectName(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, const GENERAL_NAME *name); @@ -477,6 +500,7 @@ int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx); OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx); # define OSSL_CMP_PKISI_BUFLEN 1024 +X509 *OSSL_CMP_CTX_get0_validatedSrvCert(const OSSL_CMP_CTX *ctx); X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx); @@ -517,8 +541,10 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *trusted_store, X509 *cert); /* from cmp_http.c */ +# ifndef OPENSSL_NO_HTTP OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req); +# endif /* from cmp_server.c */ typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX; @@ -590,6 +616,12 @@ int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx); STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx); +/* from cmp_genm.c */ +int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out); +int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, + const X509 *oldWithOld, X509 **newWithNew, + X509 **newWithOld, X509 **oldWithNew); + # ifdef __cplusplus } # endif diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in index fb5ae6717f..5bd8beb57a 100644 --- a/include/openssl/cmp.h.in +++ b/include/openssl/cmp.h.in @@ -36,7 +36,9 @@ use OpenSSL::stackhash qw(generate_stack_macros); extern "C" { # endif -# define OSSL_CMP_PVNO 2 +# define OSSL_CMP_PVNO_2 2 +# define OSSL_CMP_PVNO_3 3 +# define OSSL_CMP_PVNO OSSL_CMP_PVNO_2 /* v2 is the default */ /*- * PKIFailureInfo ::= BIT STRING { @@ -138,7 +140,6 @@ extern "C" { # if OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN > INT_MAX # error CMP_PKIFAILUREINFO_MAX bit pattern does not fit in type int # endif - typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO; # define OSSL_CMP_CTX_FAILINFO_badAlg (1 << 0) @@ -204,8 +205,8 @@ typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO; # define OSSL_CMP_PKISTATUS_revocationWarning 4 # define OSSL_CMP_PKISTATUS_revocationNotification 5 # define OSSL_CMP_PKISTATUS_keyUpdateWarning 6 - typedef ASN1_INTEGER OSSL_CMP_PKISTATUS; + DECLARE_ASN1_ITEM(OSSL_CMP_PKISTATUS) # define OSSL_CMP_CERTORENCCERT_CERTIFICATE 0 @@ -259,18 +260,35 @@ ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav); int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, OSSL_CMP_ITAV *itav); void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_caCerts(const STACK_OF(X509) *caCerts); +int OSSL_CMP_ITAV_get0_caCerts(const OSSL_CMP_ITAV *itav, STACK_OF(X509) **out); + +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaCert(const X509 *rootCaCert); +int OSSL_CMP_ITAV_get0_rootCaCert(const OSSL_CMP_ITAV *itav, X509 **out); +OSSL_CMP_ITAV *OSSL_CMP_ITAV_new_rootCaKeyUpdate(const X509 *newWithNew, + const X509 *newWithOld, + const X509 *oldWithNew); +int OSSL_CMP_ITAV_get0_rootCaKeyUpdate(const OSSL_CMP_ITAV *itav, + X509 **newWithNew, + X509 **newWithOld, + X509 **oldWithNew); + void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); /* from cmp_ctx.c */ OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx); +OSSL_LIB_CTX *OSSL_CMP_CTX_get0_libctx(const OSSL_CMP_CTX *ctx); +const char *OSSL_CMP_CTX_get0_propq(const OSSL_CMP_CTX *ctx); /* CMP general options: */ # define OSSL_CMP_OPT_LOG_VERBOSITY 0 /* CMP transfer options: */ -# define OSSL_CMP_OPT_KEEP_ALIVE 10 -# define OSSL_CMP_OPT_MSG_TIMEOUT 11 +# define OSSL_CMP_OPT_KEEP_ALIVE 10 +# define OSSL_CMP_OPT_MSG_TIMEOUT 11 # define OSSL_CMP_OPT_TOTAL_TIMEOUT 12 +# define OSSL_CMP_OPT_USE_TLS 13 /* CMP request options: */ # define OSSL_CMP_OPT_VALIDITY_DAYS 20 # define OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT 21 @@ -301,9 +319,11 @@ int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address); int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port); int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name); int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names); +# ifndef OPENSSL_NO_HTTP int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb); int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg); void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx); +# endif typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req); int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb); @@ -313,7 +333,9 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert); int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store); +# define OSSL_CMP_CTX_set0_trusted OSSL_CMP_CTX_set0_trustedStore X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx); +# define OSSL_CMP_CTX_get0_trusted OSSL_CMP_CTX_get0_trustedStore int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs); STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx); /* client authentication: */ @@ -335,6 +357,7 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey); EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv); int OSSL_CMP_CTX_set1_issuer(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_set1_serialNumber(OSSL_CMP_CTX *ctx, const ASN1_INTEGER *sn); int OSSL_CMP_CTX_set1_subjectName(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, const GENERAL_NAME *name); @@ -358,6 +381,7 @@ int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx); OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx); # define OSSL_CMP_PKISI_BUFLEN 1024 +X509 *OSSL_CMP_CTX_get0_validatedSrvCert(const OSSL_CMP_CTX *ctx); X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx); @@ -398,8 +422,10 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *trusted_store, X509 *cert); /* from cmp_http.c */ +# ifndef OPENSSL_NO_HTTP OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req); +# endif /* from cmp_server.c */ typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX; @@ -471,6 +497,12 @@ int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx); STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx); +/* from cmp_genm.c */ +int OSSL_CMP_get1_caCerts(OSSL_CMP_CTX *ctx, STACK_OF(X509) **out); +int OSSL_CMP_get1_rootCaKeyUpdate(OSSL_CMP_CTX *ctx, + const X509 *oldWithOld, X509 **newWithNew, + X509 **newWithOld, X509 **oldWithNew); + # ifdef __cplusplus } # endif diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index 49fd5e392a..57a6effbe3 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -59,8 +59,11 @@ # define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILURE_OBTAINING_RANDOM 110 # define CMP_R_FAIL_INFO_OUT_OF_RANGE 129 +# define CMP_R_GETTING_GENP 192 # define CMP_R_INVALID_ARGS 100 +# define CMP_R_INVALID_GENP 193 # define CMP_R_INVALID_OPTION 174 +# define CMP_R_INVALID_ROOTCAKEYUPDATE 195 # define CMP_R_MISSING_CERTID 165 # define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130 # define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142 @@ -94,6 +97,7 @@ # define CMP_R_TOTAL_TIMEOUT 184 # define CMP_R_TRANSACTIONID_UNMATCHED 152 # define CMP_R_TRANSFER_ERROR 159 +# define CMP_R_UNCLEAN_CTX 191 # define CMP_R_UNEXPECTED_PKIBODY 133 # define CMP_R_UNEXPECTED_PKISTATUS 185 # define CMP_R_UNEXPECTED_PVNO 153 diff --git a/include/openssl/cms.h b/include/openssl/cms.h index 3b453e6a21..fe86a5c7da 100644 --- a/include/openssl/cms.h +++ b/include/openssl/cms.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/cms.h.in * - * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,8 +31,10 @@ extern "C" { # endif +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; typedef struct CMS_ContentInfo_st CMS_ContentInfo; typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_SignedData_st CMS_SignedData; typedef struct CMS_CertificateChoices CMS_CertificateChoices; typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; @@ -147,6 +149,8 @@ SKM_DEFINE_STACK_OF_INTERNAL(CMS_RevocationInfoChoice, CMS_RevocationInfoChoice, #define sk_CMS_RevocationInfoChoice_set_cmp_func(sk, cmp) ((sk_CMS_RevocationInfoChoice_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_compfunc_type(cmp))) +DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_SignedData) DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) @@ -217,13 +221,16 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags); +int CMS_final_digest(CMS_ContentInfo *cms, + const unsigned char *md, unsigned int mdlen, BIO *dcont, + unsigned int flags); CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, unsigned int flags); CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, - unsigned int flags, OSSL_LIB_CTX *ctx, + unsigned int flags, OSSL_LIB_CTX *libctx, const char *propq); CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, @@ -233,27 +240,26 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, - OSSL_LIB_CTX *ctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags); CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, - unsigned int flags, OSSL_LIB_CTX *ctx, + unsigned int flags, OSSL_LIB_CTX *libctx, const char *propq); int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, size_t keylen, BIO *dcont, BIO *out, unsigned int flags); - CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen, unsigned int flags); CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen, unsigned int flags, - OSSL_LIB_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, @@ -272,7 +278,7 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags); CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags, - OSSL_LIB_CTX *ctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags); @@ -291,12 +297,16 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher); CMS_ContentInfo * -CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *ctx, +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, const char *propq); CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, - OSSL_LIB_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); +BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, + EVP_PKEY *pkey, X509 *cert, + ASN1_OCTET_STRING *secret, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq); CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags); @@ -385,6 +395,11 @@ ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); int CMS_SignerInfo_sign(CMS_SignerInfo *si); int CMS_SignerInfo_verify(CMS_SignerInfo *si); int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); +BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data, + STACK_OF(X509) *scerts, X509_STORE *store, + STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls, + unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq); int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, @@ -441,7 +456,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( unsigned char *id, int idlen, int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, - OSSL_LIB_CTX *ctx); + OSSL_LIB_CTX *libctx); int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, diff --git a/include/openssl/cms.h.in b/include/openssl/cms.h.in index da20ddf2f4..239667700a 100644 --- a/include/openssl/cms.h.in +++ b/include/openssl/cms.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,8 +32,10 @@ use OpenSSL::stackhash qw(generate_stack_macros); extern "C" { # endif +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; typedef struct CMS_ContentInfo_st CMS_ContentInfo; typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_SignedData_st CMS_SignedData; typedef struct CMS_CertificateChoices CMS_CertificateChoices; typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; @@ -49,6 +51,8 @@ typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; .generate_stack_macros("CMS_RevocationInfoChoice"); -} +DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_SignedData) DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) @@ -119,13 +123,16 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags); +int CMS_final_digest(CMS_ContentInfo *cms, + const unsigned char *md, unsigned int mdlen, BIO *dcont, + unsigned int flags); CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, unsigned int flags); CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, - unsigned int flags, OSSL_LIB_CTX *ctx, + unsigned int flags, OSSL_LIB_CTX *libctx, const char *propq); CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, @@ -135,27 +142,26 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, - OSSL_LIB_CTX *ctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags); CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, - unsigned int flags, OSSL_LIB_CTX *ctx, + unsigned int flags, OSSL_LIB_CTX *libctx, const char *propq); int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, size_t keylen, BIO *dcont, BIO *out, unsigned int flags); - CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen, unsigned int flags); CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen, unsigned int flags, - OSSL_LIB_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, @@ -174,7 +180,7 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags); CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags, - OSSL_LIB_CTX *ctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags); @@ -193,12 +199,16 @@ int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher); CMS_ContentInfo * -CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *ctx, +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, const char *propq); CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, - OSSL_LIB_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); +BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, + EVP_PKEY *pkey, X509 *cert, + ASN1_OCTET_STRING *secret, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq); CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags); @@ -287,6 +297,11 @@ ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); int CMS_SignerInfo_sign(CMS_SignerInfo *si); int CMS_SignerInfo_verify(CMS_SignerInfo *si); int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); +BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data, + STACK_OF(X509) *scerts, X509_STORE *store, + STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls, + unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq); int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, @@ -343,7 +358,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( unsigned char *id, int idlen, int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, - OSSL_LIB_CTX *ctx); + OSSL_LIB_CTX *libctx); int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index f2d7708f10..887035b1bf 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -86,6 +86,7 @@ # define CMS_R_NO_PUBLIC_KEY 134 # define CMS_R_NO_RECEIPT_REQUEST 168 # define CMS_R_NO_SIGNERS 135 +# define CMS_R_OPERATION_UNSUPPORTED 182 # define CMS_R_PEER_KEY_ERROR 188 # define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 # define CMS_R_RECEIPT_DECODE_ERROR 169 diff --git a/include/openssl/comp.h b/include/openssl/comp.h index 06ff58100f..f81ba0f39c 100644 --- a/include/openssl/comp.h +++ b/include/openssl/comp.h @@ -40,15 +40,20 @@ int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, unsigned char *in, int ilen); COMP_METHOD *COMP_zlib(void); +COMP_METHOD *COMP_zlib_oneshot(void); +COMP_METHOD *COMP_brotli(void); +COMP_METHOD *COMP_brotli_oneshot(void); +COMP_METHOD *COMP_zstd(void); +COMP_METHOD *COMP_zstd_oneshot(void); #ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define COMP_zlib_cleanup() while(0) continue #endif # ifdef OPENSSL_BIO_H -# ifdef ZLIB const BIO_METHOD *BIO_f_zlib(void); -# endif +const BIO_METHOD *BIO_f_brotli(void); +const BIO_METHOD *BIO_f_zstd(void); # endif diff --git a/include/openssl/comperr.h b/include/openssl/comperr.h index 01dd3e6bc6..1948d37f1a 100644 --- a/include/openssl/comperr.h +++ b/include/openssl/comperr.h @@ -23,9 +23,16 @@ /* * COMP reason codes. */ +# define COMP_R_BROTLI_DECODE_ERROR 102 +# define COMP_R_BROTLI_ENCODE_ERROR 103 +# define COMP_R_BROTLI_NOT_SUPPORTED 104 # define COMP_R_ZLIB_DEFLATE_ERROR 99 # define COMP_R_ZLIB_INFLATE_ERROR 100 # define COMP_R_ZLIB_NOT_SUPPORTED 101 +# define COMP_R_ZSTD_COMPRESS_ERROR 105 +# define COMP_R_ZSTD_DECODE_ERROR 106 +# define COMP_R_ZSTD_DECOMPRESS_ERROR 107 +# define COMP_R_ZSTD_NOT_SUPPORTED 108 # endif #endif diff --git a/include/openssl/conf.h b/include/openssl/conf.h index e8fcf315e8..61bb008770 100644 --- a/include/openssl/conf.h +++ b/include/openssl/conf.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/conf.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/conf.h.in b/include/openssl/conf.h.in index 044b3eb538..5663287089 100644 --- a/include/openssl/conf.h.in +++ b/include/openssl/conf.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/configuration-32.h b/include/openssl/configuration-32.h index 113e6f657e..ac83e64936 100644 --- a/include/openssl/configuration-32.h +++ b/include/openssl/configuration-32.h @@ -27,7 +27,7 @@ extern "C" { * OpenSSL was configured with the following options: */ -# define OPENSSL_CONFIGURED_API 30100 +# define OPENSSL_CONFIGURED_API 30200 # ifndef OPENSSL_RAND_SEED_OS # define OPENSSL_RAND_SEED_OS # endif @@ -40,6 +40,12 @@ extern "C" { # ifndef OPENSSL_NO_ASAN # define OPENSSL_NO_ASAN # endif +# ifndef OPENSSL_NO_BROTLI +# define OPENSSL_NO_BROTLI +# endif +# ifndef OPENSSL_NO_BROTLI_DYNAMIC +# define OPENSSL_NO_BROTLI_DYNAMIC +# endif # ifndef OPENSSL_NO_CAMELLIA # define OPENSSL_NO_CAMELLIA # endif @@ -127,6 +133,9 @@ extern "C" { # ifndef OPENSSL_NO_SSL3_METHOD # define OPENSSL_NO_SSL3_METHOD # endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif # ifndef OPENSSL_NO_TRACE # define OPENSSL_NO_TRACE # endif @@ -145,6 +154,21 @@ extern "C" { # ifndef OPENSSL_NO_WHIRLPOOL # define OPENSSL_NO_WHIRLPOOL # endif +# ifndef OPENSSL_NO_WINSTORE +# define OPENSSL_NO_WINSTORE +# endif +# ifndef OPENSSL_NO_ZLIB +# define OPENSSL_NO_ZLIB +# endif +# ifndef OPENSSL_NO_ZLIB_DYNAMIC +# define OPENSSL_NO_ZLIB_DYNAMIC +# endif +# ifndef OPENSSL_NO_ZSTD +# define OPENSSL_NO_ZSTD +# endif +# ifndef OPENSSL_NO_ZSTD_DYNAMIC +# define OPENSSL_NO_ZSTD_DYNAMIC +# endif # ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE # endif @@ -166,6 +190,12 @@ extern "C" { # define RC4_INT unsigned char +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + # ifdef __cplusplus } # endif diff --git a/include/openssl/configuration-64.h b/include/openssl/configuration-64.h index f13b0bae5a..9297a23c02 100644 --- a/include/openssl/configuration-64.h +++ b/include/openssl/configuration-64.h @@ -27,7 +27,7 @@ extern "C" { * OpenSSL was configured with the following options: */ -# define OPENSSL_CONFIGURED_API 30100 +# define OPENSSL_CONFIGURED_API 30200 # ifndef OPENSSL_RAND_SEED_OS # define OPENSSL_RAND_SEED_OS # endif @@ -40,6 +40,12 @@ extern "C" { # ifndef OPENSSL_NO_ASAN # define OPENSSL_NO_ASAN # endif +# ifndef OPENSSL_NO_BROTLI +# define OPENSSL_NO_BROTLI +# endif +# ifndef OPENSSL_NO_BROTLI_DYNAMIC +# define OPENSSL_NO_BROTLI_DYNAMIC +# endif # ifndef OPENSSL_NO_CAMELLIA # define OPENSSL_NO_CAMELLIA # endif @@ -127,6 +133,9 @@ extern "C" { # ifndef OPENSSL_NO_SSL3_METHOD # define OPENSSL_NO_SSL3_METHOD # endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif # ifndef OPENSSL_NO_TRACE # define OPENSSL_NO_TRACE # endif @@ -145,6 +154,21 @@ extern "C" { # ifndef OPENSSL_NO_WHIRLPOOL # define OPENSSL_NO_WHIRLPOOL # endif +# ifndef OPENSSL_NO_WINSTORE +# define OPENSSL_NO_WINSTORE +# endif +# ifndef OPENSSL_NO_ZLIB +# define OPENSSL_NO_ZLIB +# endif +# ifndef OPENSSL_NO_ZLIB_DYNAMIC +# define OPENSSL_NO_ZLIB_DYNAMIC +# endif +# ifndef OPENSSL_NO_ZSTD +# define OPENSSL_NO_ZSTD +# endif +# ifndef OPENSSL_NO_ZSTD_DYNAMIC +# define OPENSSL_NO_ZSTD_DYNAMIC +# endif # ifndef OPENSSL_NO_STATIC_ENGINE # define OPENSSL_NO_STATIC_ENGINE # endif @@ -166,6 +190,12 @@ extern "C" { # define RC4_INT unsigned char +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + # ifdef __cplusplus } # endif diff --git a/include/openssl/configuration-static-32.h b/include/openssl/configuration-static-32.h index 77217c3280..4ce700cd9a 100644 --- a/include/openssl/configuration-static-32.h +++ b/include/openssl/configuration-static-32.h @@ -27,7 +27,7 @@ extern "C" { * OpenSSL was configured with the following options: */ -# define OPENSSL_CONFIGURED_API 30100 +# define OPENSSL_CONFIGURED_API 30200 # ifndef OPENSSL_RAND_SEED_OS # define OPENSSL_RAND_SEED_OS # endif @@ -43,6 +43,12 @@ extern "C" { # ifndef OPENSSL_NO_ASM # define OPENSSL_NO_ASM # endif +# ifndef OPENSSL_NO_BROTLI +# define OPENSSL_NO_BROTLI +# endif +# ifndef OPENSSL_NO_BROTLI_DYNAMIC +# define OPENSSL_NO_BROTLI_DYNAMIC +# endif # ifndef OPENSSL_NO_CAMELLIA # define OPENSSL_NO_CAMELLIA # endif @@ -136,6 +142,9 @@ extern "C" { # ifndef OPENSSL_NO_SSL3_METHOD # define OPENSSL_NO_SSL3_METHOD # endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif # ifndef OPENSSL_NO_TRACE # define OPENSSL_NO_TRACE # endif @@ -154,6 +163,21 @@ extern "C" { # ifndef OPENSSL_NO_WHIRLPOOL # define OPENSSL_NO_WHIRLPOOL # endif +# ifndef OPENSSL_NO_WINSTORE +# define OPENSSL_NO_WINSTORE +# endif +# ifndef OPENSSL_NO_ZLIB +# define OPENSSL_NO_ZLIB +# endif +# ifndef OPENSSL_NO_ZLIB_DYNAMIC +# define OPENSSL_NO_ZLIB_DYNAMIC +# endif +# ifndef OPENSSL_NO_ZSTD +# define OPENSSL_NO_ZSTD +# endif +# ifndef OPENSSL_NO_ZSTD_DYNAMIC +# define OPENSSL_NO_ZSTD_DYNAMIC +# endif # ifndef OPENSSL_NO_DYNAMIC_ENGINE # define OPENSSL_NO_DYNAMIC_ENGINE # endif @@ -175,6 +199,12 @@ extern "C" { # define RC4_INT unsigned char +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + # ifdef __cplusplus } # endif diff --git a/include/openssl/configuration-static-64.h b/include/openssl/configuration-static-64.h index 651dee0602..c45da678c6 100644 --- a/include/openssl/configuration-static-64.h +++ b/include/openssl/configuration-static-64.h @@ -27,7 +27,7 @@ extern "C" { * OpenSSL was configured with the following options: */ -# define OPENSSL_CONFIGURED_API 30100 +# define OPENSSL_CONFIGURED_API 30200 # ifndef OPENSSL_RAND_SEED_OS # define OPENSSL_RAND_SEED_OS # endif @@ -43,6 +43,12 @@ extern "C" { # ifndef OPENSSL_NO_ASM # define OPENSSL_NO_ASM # endif +# ifndef OPENSSL_NO_BROTLI +# define OPENSSL_NO_BROTLI +# endif +# ifndef OPENSSL_NO_BROTLI_DYNAMIC +# define OPENSSL_NO_BROTLI_DYNAMIC +# endif # ifndef OPENSSL_NO_CAMELLIA # define OPENSSL_NO_CAMELLIA # endif @@ -136,6 +142,9 @@ extern "C" { # ifndef OPENSSL_NO_SSL3_METHOD # define OPENSSL_NO_SSL3_METHOD # endif +# ifndef OPENSSL_NO_TFO +# define OPENSSL_NO_TFO +# endif # ifndef OPENSSL_NO_TRACE # define OPENSSL_NO_TRACE # endif @@ -154,6 +163,21 @@ extern "C" { # ifndef OPENSSL_NO_WHIRLPOOL # define OPENSSL_NO_WHIRLPOOL # endif +# ifndef OPENSSL_NO_WINSTORE +# define OPENSSL_NO_WINSTORE +# endif +# ifndef OPENSSL_NO_ZLIB +# define OPENSSL_NO_ZLIB +# endif +# ifndef OPENSSL_NO_ZLIB_DYNAMIC +# define OPENSSL_NO_ZLIB_DYNAMIC +# endif +# ifndef OPENSSL_NO_ZSTD +# define OPENSSL_NO_ZSTD +# endif +# ifndef OPENSSL_NO_ZSTD_DYNAMIC +# define OPENSSL_NO_ZSTD_DYNAMIC +# endif # ifndef OPENSSL_NO_DYNAMIC_ENGINE # define OPENSSL_NO_DYNAMIC_ENGINE # endif @@ -175,6 +199,12 @@ extern "C" { # define RC4_INT unsigned char +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + # ifdef __cplusplus } # endif diff --git a/include/openssl/configuration.h.in b/include/openssl/configuration.h.in index b84dc1dfe3..86077d0a6f 100644 --- a/include/openssl/configuration.h.in +++ b/include/openssl/configuration.h.in @@ -62,6 +62,12 @@ extern "C" { # define RC4_INT {- $config{rc4_int} -} +# if defined(OPENSSL_NO_COMP) || (defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) && defined(OPENSSL_NO_ZLIB)) +# define OPENSSL_NO_COMP_ALG +# else +# undef OPENSSL_NO_COMP_ALG +# endif + # ifdef __cplusplus } # endif diff --git a/include/openssl/core.h b/include/openssl/core.h index 9683ac70a5..18c199182e 100644 --- a/include/openssl/core.h +++ b/include/openssl/core.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -42,6 +42,9 @@ struct ossl_dispatch_st { void (*function)(void); }; +# define OSSL_DISPATCH_END \ + { 0, NULL } + /* * Other items, essentially an int<->pointer map element. * diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 61d75a3821..9b03f20c3b 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -661,6 +661,14 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_export_types, OSSL_CORE_MAKE_FUNC(void *, keymgmt_dup, (const void *keydata_from, int selection)) +/* Extended import and export functions */ +# define OSSL_FUNC_KEYMGMT_IMPORT_TYPES_EX 45 +# define OSSL_FUNC_KEYMGMT_EXPORT_TYPES_EX 46 +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_import_types_ex, + (void *provctx, int selection)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_export_types_ex, + (void *provctx, int selection)) + /* Key Exchange */ # define OSSL_FUNC_KEYEXCH_NEWCTX 1 @@ -832,16 +840,24 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_settable_ctx_params, # define OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS 9 # define OSSL_FUNC_KEM_SET_CTX_PARAMS 10 # define OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS 11 +# define OSSL_FUNC_KEM_AUTH_ENCAPSULATE_INIT 12 +# define OSSL_FUNC_KEM_AUTH_DECAPSULATE_INIT 13 OSSL_CORE_MAKE_FUNC(void *, kem_newctx, (void *provctx)) OSSL_CORE_MAKE_FUNC(int, kem_encapsulate_init, (void *ctx, void *provkey, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, kem_auth_encapsulate_init, (void *ctx, void *provkey, + void *authprivkey, + const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, kem_encapsulate, (void *ctx, unsigned char *out, size_t *outlen, unsigned char *secret, size_t *secretlen)) OSSL_CORE_MAKE_FUNC(int, kem_decapsulate_init, (void *ctx, void *provkey, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, kem_auth_decapsulate_init, (void *ctx, void *provkey, + void *authpubkey, + const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, kem_decapsulate, (void *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen)) @@ -937,6 +953,8 @@ OSSL_CORE_MAKE_FUNC(int, decoder_export_object, #define OSSL_FUNC_STORE_EOF 6 #define OSSL_FUNC_STORE_CLOSE 7 #define OSSL_FUNC_STORE_EXPORT_OBJECT 8 +#define OSSL_FUNC_STORE_DELETE 9 +#define OSSL_FUNC_STORE_OPEN_EX 10 OSSL_CORE_MAKE_FUNC(void *, store_open, (void *provctx, const char *uri)) OSSL_CORE_MAKE_FUNC(void *, store_attach, (void *provctx, OSSL_CORE_BIO *in)) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, store_settable_ctx_params, @@ -952,6 +970,12 @@ OSSL_CORE_MAKE_FUNC(int, store_close, (void *loaderctx)) OSSL_CORE_MAKE_FUNC(int, store_export_object, (void *loaderctx, const void *objref, size_t objref_sz, OSSL_CALLBACK *export_cb, void *export_cbarg)) +OSSL_CORE_MAKE_FUNC(int, store_delete, + (void *provctx, const char *uri, const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) +OSSL_CORE_MAKE_FUNC(void *, store_open_ex, + (void *provctx, const char *uri, const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) # ifdef __cplusplus } diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 0a6ec1bbba..ffffe90f16 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/core_names.h.in + * * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,7 @@ * https://www.openssl.org/source/license.html */ + #ifndef OPENSSL_CORE_NAMES_H # define OPENSSL_CORE_NAMES_H # pragma once @@ -15,544 +19,454 @@ extern "C" { # endif -/* Well known parameter names that core passes to providers */ -#define OSSL_PROV_PARAM_CORE_VERSION "openssl-version" /* utf8_ptr */ -#define OSSL_PROV_PARAM_CORE_PROV_NAME "provider-name" /* utf8_ptr */ -#define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" /* utf8_ptr */ - -/* Well known parameter names that Providers can define */ -#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */ -#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */ -#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */ -#define OSSL_PROV_PARAM_STATUS "status" /* uint */ -#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */ -#define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" /* uint */ -#define OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md" /* uint */ - -/* Self test callback parameters */ -#define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */ -#define OSSL_PROV_PARAM_SELF_TEST_TYPE "st-type" /* utf8_string */ -#define OSSL_PROV_PARAM_SELF_TEST_DESC "st-desc" /* utf8_string */ - -/*- - * Provider-native object abstractions - * - * These are used when a provider wants to pass object data or an object - * reference back to libcrypto. This is only useful for provider functions - * that take a callback to which an OSSL_PARAM array with these parameters - * can be passed. - * - * This set of parameter names is explained in detail in provider-object(7) - * (doc/man7/provider-object.pod) - */ -#define OSSL_OBJECT_PARAM_TYPE "type" /* INTEGER */ -#define OSSL_OBJECT_PARAM_DATA_TYPE "data-type" /* UTF8_STRING */ -#define OSSL_OBJECT_PARAM_DATA_STRUCTURE "data-structure" /* UTF8_STRING */ -#define OSSL_OBJECT_PARAM_REFERENCE "reference" /* OCTET_STRING */ -#define OSSL_OBJECT_PARAM_DATA "data" /* OCTET_STRING or UTF8_STRING */ -#define OSSL_OBJECT_PARAM_DESC "desc" /* UTF8_STRING */ - -/* - * Algorithm parameters - * If "engine" or "properties" are specified, they should always be paired - * with the algorithm type. - * Note these are common names that are shared by many types (such as kdf, mac, - * and pkey) e.g: see OSSL_MAC_PARAM_DIGEST below. - */ -#define OSSL_ALG_PARAM_DIGEST "digest" /* utf8_string */ -#define OSSL_ALG_PARAM_CIPHER "cipher" /* utf8_string */ -#define OSSL_ALG_PARAM_ENGINE "engine" /* utf8_string */ -#define OSSL_ALG_PARAM_MAC "mac" /* utf8_string */ -#define OSSL_ALG_PARAM_PROPERTIES "properties"/* utf8_string */ - -/* cipher parameters */ -#define OSSL_CIPHER_PARAM_PADDING "padding" /* uint */ -#define OSSL_CIPHER_PARAM_USE_BITS "use-bits" /* uint */ -#define OSSL_CIPHER_PARAM_TLS_VERSION "tls-version" /* uint */ -#define OSSL_CIPHER_PARAM_TLS_MAC "tls-mac" /* octet_ptr */ -#define OSSL_CIPHER_PARAM_TLS_MAC_SIZE "tls-mac-size" /* size_t */ -#define OSSL_CIPHER_PARAM_MODE "mode" /* uint */ -#define OSSL_CIPHER_PARAM_BLOCK_SIZE "blocksize" /* size_t */ -#define OSSL_CIPHER_PARAM_AEAD "aead" /* int, 0 or 1 */ -#define OSSL_CIPHER_PARAM_CUSTOM_IV "custom-iv" /* int, 0 or 1 */ -#define OSSL_CIPHER_PARAM_CTS "cts" /* int, 0 or 1 */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK "tls-multi" /* int, 0 or 1 */ -#define OSSL_CIPHER_PARAM_HAS_RAND_KEY "has-randkey" /* int, 0 or 1 */ -#define OSSL_CIPHER_PARAM_KEYLEN "keylen" /* size_t */ -#define OSSL_CIPHER_PARAM_IVLEN "ivlen" /* size_t */ -#define OSSL_CIPHER_PARAM_IV "iv" /* octet_string OR octet_ptr */ -#define OSSL_CIPHER_PARAM_UPDATED_IV "updated-iv" /* octet_string OR octet_ptr */ -#define OSSL_CIPHER_PARAM_NUM "num" /* uint */ -#define OSSL_CIPHER_PARAM_ROUNDS "rounds" /* uint */ -#define OSSL_CIPHER_PARAM_AEAD_TAG "tag" /* octet_string */ -#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD "tlsaad" /* octet_string */ -#define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD "tlsaadpad" /* size_t */ -#define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED "tlsivfixed" /* octet_string */ -#define OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN "tlsivgen" /* octet_string */ -#define OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV "tlsivinv" /* octet_string */ -#define OSSL_CIPHER_PARAM_AEAD_IVLEN OSSL_CIPHER_PARAM_IVLEN -#define OSSL_CIPHER_PARAM_AEAD_TAGLEN "taglen" /* size_t */ -#define OSSL_CIPHER_PARAM_AEAD_MAC_KEY "mackey" /* octet_string */ -#define OSSL_CIPHER_PARAM_RANDOM_KEY "randkey" /* octet_string */ -#define OSSL_CIPHER_PARAM_RC2_KEYBITS "keybits" /* size_t */ -#define OSSL_CIPHER_PARAM_SPEED "speed" /* uint */ -#define OSSL_CIPHER_PARAM_CTS_MODE "cts_mode" /* utf8_string */ -/* For passing the AlgorithmIdentifier parameter in DER form */ -#define OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS "alg_id_param" /* octet_string */ - -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT \ - "tls1multi_maxsndfrag" /* uint */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE \ - "tls1multi_maxbufsz" /* size_t */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE \ - "tls1multi_interleave" /* uint */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD \ - "tls1multi_aad" /* octet_string */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN \ - "tls1multi_aadpacklen" /* uint */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC \ - "tls1multi_enc" /* octet_string */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN \ - "tls1multi_encin" /* octet_string */ -#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN \ - "tls1multi_enclen" /* size_t */ - /* OSSL_CIPHER_PARAM_CTS_MODE Values */ -#define OSSL_CIPHER_CTS_MODE_CS1 "CS1" -#define OSSL_CIPHER_CTS_MODE_CS2 "CS2" -#define OSSL_CIPHER_CTS_MODE_CS3 "CS3" +# define OSSL_CIPHER_CTS_MODE_CS1 "CS1" +# define OSSL_CIPHER_CTS_MODE_CS2 "CS2" +# define OSSL_CIPHER_CTS_MODE_CS3 "CS3" -/* digest parameters */ -#define OSSL_DIGEST_PARAM_XOFLEN "xoflen" /* size_t */ -#define OSSL_DIGEST_PARAM_SSL3_MS "ssl3-ms" /* octet string */ -#define OSSL_DIGEST_PARAM_PAD_TYPE "pad-type" /* uint */ -#define OSSL_DIGEST_PARAM_MICALG "micalg" /* utf8 string */ -#define OSSL_DIGEST_PARAM_BLOCK_SIZE "blocksize" /* size_t */ -#define OSSL_DIGEST_PARAM_SIZE "size" /* size_t */ -#define OSSL_DIGEST_PARAM_XOF "xof" /* int, 0 or 1 */ -#define OSSL_DIGEST_PARAM_ALGID_ABSENT "algid-absent" /* int, 0 or 1 */ +/* Known CIPHER names (not a complete list) */ +# define OSSL_CIPHER_NAME_AES_128_GCM_SIV "AES-128-GCM-SIV" +# define OSSL_CIPHER_NAME_AES_192_GCM_SIV "AES-192-GCM-SIV" +# define OSSL_CIPHER_NAME_AES_256_GCM_SIV "AES-256-GCM-SIV" /* Known DIGEST names (not a complete list) */ -#define OSSL_DIGEST_NAME_MD5 "MD5" -#define OSSL_DIGEST_NAME_MD5_SHA1 "MD5-SHA1" -#define OSSL_DIGEST_NAME_SHA1 "SHA1" -#define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224" -#define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256" -#define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384" -#define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512" -#define OSSL_DIGEST_NAME_SHA2_512_224 "SHA2-512/224" -#define OSSL_DIGEST_NAME_SHA2_512_256 "SHA2-512/256" -#define OSSL_DIGEST_NAME_MD2 "MD2" -#define OSSL_DIGEST_NAME_MD4 "MD4" -#define OSSL_DIGEST_NAME_MDC2 "MDC2" -#define OSSL_DIGEST_NAME_RIPEMD160 "RIPEMD160" -#define OSSL_DIGEST_NAME_SHA3_224 "SHA3-224" -#define OSSL_DIGEST_NAME_SHA3_256 "SHA3-256" -#define OSSL_DIGEST_NAME_SHA3_384 "SHA3-384" -#define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512" -#define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128" -#define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256" -#define OSSL_DIGEST_NAME_SM3 "SM3" - -/* MAC parameters */ -#define OSSL_MAC_PARAM_KEY "key" /* octet string */ -#define OSSL_MAC_PARAM_IV "iv" /* octet string */ -#define OSSL_MAC_PARAM_CUSTOM "custom" /* utf8 string */ -#define OSSL_MAC_PARAM_SALT "salt" /* octet string */ -#define OSSL_MAC_PARAM_XOF "xof" /* int, 0 or 1 */ -#define OSSL_MAC_PARAM_DIGEST_NOINIT "digest-noinit" /* int, 0 or 1 */ -#define OSSL_MAC_PARAM_DIGEST_ONESHOT "digest-oneshot" /* int, 0 or 1 */ -#define OSSL_MAC_PARAM_C_ROUNDS "c-rounds" /* unsigned int */ -#define OSSL_MAC_PARAM_D_ROUNDS "d-rounds" /* unsigned int */ - -/* - * If "engine" or "properties" are specified, they should always be paired - * with "cipher" or "digest". - */ -#define OSSL_MAC_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ -#define OSSL_MAC_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */ -#define OSSL_MAC_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */ -#define OSSL_MAC_PARAM_SIZE "size" /* size_t */ -#define OSSL_MAC_PARAM_BLOCK_SIZE "block-size" /* size_t */ -#define OSSL_MAC_PARAM_TLS_DATA_SIZE "tls-data-size" /* size_t */ +# define OSSL_DIGEST_NAME_MD5 "MD5" +# define OSSL_DIGEST_NAME_MD5_SHA1 "MD5-SHA1" +# define OSSL_DIGEST_NAME_SHA1 "SHA1" +# define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224" +# define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256" +# define OSSL_DIGEST_NAME_SHA2_256_192 "SHA2-256/192" +# define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384" +# define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512" +# define OSSL_DIGEST_NAME_SHA2_512_224 "SHA2-512/224" +# define OSSL_DIGEST_NAME_SHA2_512_256 "SHA2-512/256" +# define OSSL_DIGEST_NAME_MD2 "MD2" +# define OSSL_DIGEST_NAME_MD4 "MD4" +# define OSSL_DIGEST_NAME_MDC2 "MDC2" +# define OSSL_DIGEST_NAME_RIPEMD160 "RIPEMD160" +# define OSSL_DIGEST_NAME_SHA3_224 "SHA3-224" +# define OSSL_DIGEST_NAME_SHA3_256 "SHA3-256" +# define OSSL_DIGEST_NAME_SHA3_384 "SHA3-384" +# define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512" +# define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128" +# define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256" +# define OSSL_DIGEST_NAME_SM3 "SM3" /* Known MAC names */ -#define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC" -#define OSSL_MAC_NAME_BLAKE2SMAC "BLAKE2SMAC" -#define OSSL_MAC_NAME_CMAC "CMAC" -#define OSSL_MAC_NAME_GMAC "GMAC" -#define OSSL_MAC_NAME_HMAC "HMAC" -#define OSSL_MAC_NAME_KMAC128 "KMAC128" -#define OSSL_MAC_NAME_KMAC256 "KMAC256" -#define OSSL_MAC_NAME_POLY1305 "POLY1305" -#define OSSL_MAC_NAME_SIPHASH "SIPHASH" - -/* KDF / PRF parameters */ -#define OSSL_KDF_PARAM_SECRET "secret" /* octet string */ -#define OSSL_KDF_PARAM_KEY "key" /* octet string */ -#define OSSL_KDF_PARAM_SALT "salt" /* octet string */ -#define OSSL_KDF_PARAM_PASSWORD "pass" /* octet string */ -#define OSSL_KDF_PARAM_PREFIX "prefix" /* octet string */ -#define OSSL_KDF_PARAM_LABEL "label" /* octet string */ -#define OSSL_KDF_PARAM_DATA "data" /* octet string */ -#define OSSL_KDF_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */ -#define OSSL_KDF_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ -#define OSSL_KDF_PARAM_MAC OSSL_ALG_PARAM_MAC /* utf8 string */ -#define OSSL_KDF_PARAM_MAC_SIZE "maclen" /* size_t */ -#define OSSL_KDF_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */ -#define OSSL_KDF_PARAM_ITER "iter" /* unsigned int */ -#define OSSL_KDF_PARAM_MODE "mode" /* utf8 string or int */ -#define OSSL_KDF_PARAM_PKCS5 "pkcs5" /* int */ -#define OSSL_KDF_PARAM_UKM "ukm" /* octet string */ -#define OSSL_KDF_PARAM_CEK_ALG "cekalg" /* utf8 string */ -#define OSSL_KDF_PARAM_SCRYPT_N "n" /* uint64_t */ -#define OSSL_KDF_PARAM_SCRYPT_R "r" /* uint32_t */ -#define OSSL_KDF_PARAM_SCRYPT_P "p" /* uint32_t */ -#define OSSL_KDF_PARAM_SCRYPT_MAXMEM "maxmem_bytes" /* uint64_t */ -#define OSSL_KDF_PARAM_INFO "info" /* octet string */ -#define OSSL_KDF_PARAM_SEED "seed" /* octet string */ -#define OSSL_KDF_PARAM_SSHKDF_XCGHASH "xcghash" /* octet string */ -#define OSSL_KDF_PARAM_SSHKDF_SESSION_ID "session_id" /* octet string */ -#define OSSL_KDF_PARAM_SSHKDF_TYPE "type" /* int */ -#define OSSL_KDF_PARAM_SIZE "size" /* size_t */ -#define OSSL_KDF_PARAM_CONSTANT "constant" /* octet string */ -#define OSSL_KDF_PARAM_PKCS12_ID "id" /* int */ -#define OSSL_KDF_PARAM_KBKDF_USE_L "use-l" /* int */ -#define OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR "use-separator" /* int */ -#define OSSL_KDF_PARAM_KBKDF_R "r" /* int */ -#define OSSL_KDF_PARAM_X942_ACVPINFO "acvp-info" -#define OSSL_KDF_PARAM_X942_PARTYUINFO "partyu-info" -#define OSSL_KDF_PARAM_X942_PARTYVINFO "partyv-info" -#define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo" -#define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO "supp-privinfo" -#define OSSL_KDF_PARAM_X942_USE_KEYBITS "use-keybits" +# define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC" +# define OSSL_MAC_NAME_BLAKE2SMAC "BLAKE2SMAC" +# define OSSL_MAC_NAME_CMAC "CMAC" +# define OSSL_MAC_NAME_GMAC "GMAC" +# define OSSL_MAC_NAME_HMAC "HMAC" +# define OSSL_MAC_NAME_KMAC128 "KMAC128" +# define OSSL_MAC_NAME_KMAC256 "KMAC256" +# define OSSL_MAC_NAME_POLY1305 "POLY1305" +# define OSSL_MAC_NAME_SIPHASH "SIPHASH" /* Known KDF names */ -#define OSSL_KDF_NAME_HKDF "HKDF" -#define OSSL_KDF_NAME_TLS1_3_KDF "TLS13-KDF" -#define OSSL_KDF_NAME_PBKDF1 "PBKDF1" -#define OSSL_KDF_NAME_PBKDF2 "PBKDF2" -#define OSSL_KDF_NAME_SCRYPT "SCRYPT" -#define OSSL_KDF_NAME_SSHKDF "SSHKDF" -#define OSSL_KDF_NAME_SSKDF "SSKDF" -#define OSSL_KDF_NAME_TLS1_PRF "TLS1-PRF" -#define OSSL_KDF_NAME_X942KDF_ASN1 "X942KDF-ASN1" -#define OSSL_KDF_NAME_X942KDF_CONCAT "X942KDF-CONCAT" -#define OSSL_KDF_NAME_X963KDF "X963KDF" -#define OSSL_KDF_NAME_KBKDF "KBKDF" -#define OSSL_KDF_NAME_KRB5KDF "KRB5KDF" - -/* Known RAND names */ -#define OSSL_RAND_PARAM_STATE "state" -#define OSSL_RAND_PARAM_STRENGTH "strength" -#define OSSL_RAND_PARAM_MAX_REQUEST "max_request" -#define OSSL_RAND_PARAM_TEST_ENTROPY "test_entropy" -#define OSSL_RAND_PARAM_TEST_NONCE "test_nonce" -#define OSSL_RAND_PARAM_GENERATE "generate" - -/* RAND/DRBG names */ -#define OSSL_DRBG_PARAM_RESEED_REQUESTS "reseed_requests" -#define OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL "reseed_time_interval" -#define OSSL_DRBG_PARAM_MIN_ENTROPYLEN "min_entropylen" -#define OSSL_DRBG_PARAM_MAX_ENTROPYLEN "max_entropylen" -#define OSSL_DRBG_PARAM_MIN_NONCELEN "min_noncelen" -#define OSSL_DRBG_PARAM_MAX_NONCELEN "max_noncelen" -#define OSSL_DRBG_PARAM_MAX_PERSLEN "max_perslen" -#define OSSL_DRBG_PARAM_MAX_ADINLEN "max_adinlen" -#define OSSL_DRBG_PARAM_RESEED_COUNTER "reseed_counter" -#define OSSL_DRBG_PARAM_RESEED_TIME "reseed_time" -#define OSSL_DRBG_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -#define OSSL_DRBG_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST -#define OSSL_DRBG_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER -#define OSSL_DRBG_PARAM_MAC OSSL_ALG_PARAM_MAC -#define OSSL_DRBG_PARAM_USE_DF "use_derivation_function" - -/* DRBG call back parameters */ -#define OSSL_DRBG_PARAM_ENTROPY_REQUIRED "entropy_required" -#define OSSL_DRBG_PARAM_PREDICTION_RESISTANCE "prediction_resistance" -#define OSSL_DRBG_PARAM_MIN_LENGTH "minium_length" -#define OSSL_DRBG_PARAM_MAX_LENGTH "maxium_length" -#define OSSL_DRBG_PARAM_RANDOM_DATA "random_data" -#define OSSL_DRBG_PARAM_SIZE "size" - -/* PKEY parameters */ -/* Common PKEY parameters */ -#define OSSL_PKEY_PARAM_BITS "bits" /* integer */ -#define OSSL_PKEY_PARAM_MAX_SIZE "max-size" /* integer */ -#define OSSL_PKEY_PARAM_SECURITY_BITS "security-bits" /* integer */ -#define OSSL_PKEY_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST -#define OSSL_PKEY_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ -#define OSSL_PKEY_PARAM_ENGINE OSSL_ALG_PARAM_ENGINE /* utf8 string */ -#define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -#define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" /* utf8 string */ -#define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" /* utf8 string */ -#define OSSL_PKEY_PARAM_PAD_MODE "pad-mode" -#define OSSL_PKEY_PARAM_DIGEST_SIZE "digest-size" -#define OSSL_PKEY_PARAM_MASKGENFUNC "mgf" -#define OSSL_PKEY_PARAM_MGF1_DIGEST "mgf1-digest" -#define OSSL_PKEY_PARAM_MGF1_PROPERTIES "mgf1-properties" -#define OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY "encoded-pub-key" -#define OSSL_PKEY_PARAM_GROUP_NAME "group" -#define OSSL_PKEY_PARAM_DIST_ID "distid" -#define OSSL_PKEY_PARAM_PUB_KEY "pub" -#define OSSL_PKEY_PARAM_PRIV_KEY "priv" - -/* Diffie-Hellman/DSA Parameters */ -#define OSSL_PKEY_PARAM_FFC_P "p" -#define OSSL_PKEY_PARAM_FFC_G "g" -#define OSSL_PKEY_PARAM_FFC_Q "q" -#define OSSL_PKEY_PARAM_FFC_GINDEX "gindex" -#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter" -#define OSSL_PKEY_PARAM_FFC_SEED "seed" -#define OSSL_PKEY_PARAM_FFC_COFACTOR "j" -#define OSSL_PKEY_PARAM_FFC_H "hindex" -#define OSSL_PKEY_PARAM_FFC_VALIDATE_PQ "validate-pq" -#define OSSL_PKEY_PARAM_FFC_VALIDATE_G "validate-g" -#define OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY "validate-legacy" - -/* Diffie-Hellman params */ -#define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator" -#define OSSL_PKEY_PARAM_DH_PRIV_LEN "priv_len" - -/* Elliptic Curve Domain Parameters */ -#define OSSL_PKEY_PARAM_EC_PUB_X "qx" -#define OSSL_PKEY_PARAM_EC_PUB_Y "qy" - -/* Elliptic Curve Explicit Domain Parameters */ -#define OSSL_PKEY_PARAM_EC_FIELD_TYPE "field-type" -#define OSSL_PKEY_PARAM_EC_P "p" -#define OSSL_PKEY_PARAM_EC_A "a" -#define OSSL_PKEY_PARAM_EC_B "b" -#define OSSL_PKEY_PARAM_EC_GENERATOR "generator" -#define OSSL_PKEY_PARAM_EC_ORDER "order" -#define OSSL_PKEY_PARAM_EC_COFACTOR "cofactor" -#define OSSL_PKEY_PARAM_EC_SEED "seed" -#define OSSL_PKEY_PARAM_EC_CHAR2_M "m" -#define OSSL_PKEY_PARAM_EC_CHAR2_TYPE "basis-type" -#define OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS "tp" -#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K1 "k1" -#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K2 "k2" -#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K3 "k3" -#define OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS "decoded-from-explicit" - -/* Elliptic Curve Key Parameters */ -#define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag" -#define OSSL_PKEY_PARAM_USE_COFACTOR_ECDH \ - OSSL_PKEY_PARAM_USE_COFACTOR_FLAG - -/* RSA Keys */ -/* - * n, e, d are the usual public and private key components - * - * rsa-num is the number of factors, including p and q - * rsa-factor is used for each factor: p, q, r_i (i = 3, ...) - * rsa-exponent is used for each exponent: dP, dQ, d_i (i = 3, ...) - * rsa-coefficient is used for each coefficient: qInv, t_i (i = 3, ...) - * - * The number of rsa-factor items must be equal to the number of rsa-exponent - * items, and the number of rsa-coefficients must be one less. - * (the base i for the coefficients is 2, not 1, at least as implied by - * RFC 8017) - */ -#define OSSL_PKEY_PARAM_RSA_N "n" -#define OSSL_PKEY_PARAM_RSA_E "e" -#define OSSL_PKEY_PARAM_RSA_D "d" -#define OSSL_PKEY_PARAM_RSA_FACTOR "rsa-factor" -#define OSSL_PKEY_PARAM_RSA_EXPONENT "rsa-exponent" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient" -#define OSSL_PKEY_PARAM_RSA_FACTOR1 OSSL_PKEY_PARAM_RSA_FACTOR"1" -#define OSSL_PKEY_PARAM_RSA_FACTOR2 OSSL_PKEY_PARAM_RSA_FACTOR"2" -#define OSSL_PKEY_PARAM_RSA_FACTOR3 OSSL_PKEY_PARAM_RSA_FACTOR"3" -#define OSSL_PKEY_PARAM_RSA_FACTOR4 OSSL_PKEY_PARAM_RSA_FACTOR"4" -#define OSSL_PKEY_PARAM_RSA_FACTOR5 OSSL_PKEY_PARAM_RSA_FACTOR"5" -#define OSSL_PKEY_PARAM_RSA_FACTOR6 OSSL_PKEY_PARAM_RSA_FACTOR"6" -#define OSSL_PKEY_PARAM_RSA_FACTOR7 OSSL_PKEY_PARAM_RSA_FACTOR"7" -#define OSSL_PKEY_PARAM_RSA_FACTOR8 OSSL_PKEY_PARAM_RSA_FACTOR"8" -#define OSSL_PKEY_PARAM_RSA_FACTOR9 OSSL_PKEY_PARAM_RSA_FACTOR"9" -#define OSSL_PKEY_PARAM_RSA_FACTOR10 OSSL_PKEY_PARAM_RSA_FACTOR"10" -#define OSSL_PKEY_PARAM_RSA_EXPONENT1 OSSL_PKEY_PARAM_RSA_EXPONENT"1" -#define OSSL_PKEY_PARAM_RSA_EXPONENT2 OSSL_PKEY_PARAM_RSA_EXPONENT"2" -#define OSSL_PKEY_PARAM_RSA_EXPONENT3 OSSL_PKEY_PARAM_RSA_EXPONENT"3" -#define OSSL_PKEY_PARAM_RSA_EXPONENT4 OSSL_PKEY_PARAM_RSA_EXPONENT"4" -#define OSSL_PKEY_PARAM_RSA_EXPONENT5 OSSL_PKEY_PARAM_RSA_EXPONENT"5" -#define OSSL_PKEY_PARAM_RSA_EXPONENT6 OSSL_PKEY_PARAM_RSA_EXPONENT"6" -#define OSSL_PKEY_PARAM_RSA_EXPONENT7 OSSL_PKEY_PARAM_RSA_EXPONENT"7" -#define OSSL_PKEY_PARAM_RSA_EXPONENT8 OSSL_PKEY_PARAM_RSA_EXPONENT"8" -#define OSSL_PKEY_PARAM_RSA_EXPONENT9 OSSL_PKEY_PARAM_RSA_EXPONENT"9" -#define OSSL_PKEY_PARAM_RSA_EXPONENT10 OSSL_PKEY_PARAM_RSA_EXPONENT"10" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT1 OSSL_PKEY_PARAM_RSA_COEFFICIENT"1" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT2 OSSL_PKEY_PARAM_RSA_COEFFICIENT"2" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT3 OSSL_PKEY_PARAM_RSA_COEFFICIENT"3" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT4 OSSL_PKEY_PARAM_RSA_COEFFICIENT"4" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT5 OSSL_PKEY_PARAM_RSA_COEFFICIENT"5" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT6 OSSL_PKEY_PARAM_RSA_COEFFICIENT"6" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT7 OSSL_PKEY_PARAM_RSA_COEFFICIENT"7" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 OSSL_PKEY_PARAM_RSA_COEFFICIENT"8" -#define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 OSSL_PKEY_PARAM_RSA_COEFFICIENT"9" +# define OSSL_KDF_NAME_HKDF "HKDF" +# define OSSL_KDF_NAME_TLS1_3_KDF "TLS13-KDF" +# define OSSL_KDF_NAME_PBKDF1 "PBKDF1" +# define OSSL_KDF_NAME_PBKDF2 "PBKDF2" +# define OSSL_KDF_NAME_SCRYPT "SCRYPT" +# define OSSL_KDF_NAME_SSHKDF "SSHKDF" +# define OSSL_KDF_NAME_SSKDF "SSKDF" +# define OSSL_KDF_NAME_TLS1_PRF "TLS1-PRF" +# define OSSL_KDF_NAME_X942KDF_ASN1 "X942KDF-ASN1" +# define OSSL_KDF_NAME_X942KDF_CONCAT "X942KDF-CONCAT" +# define OSSL_KDF_NAME_X963KDF "X963KDF" +# define OSSL_KDF_NAME_KBKDF "KBKDF" +# define OSSL_KDF_NAME_KRB5KDF "KRB5KDF" +# define OSSL_KDF_NAME_HMACDRBGKDF "HMAC-DRBG-KDF" /* RSA padding modes */ -#define OSSL_PKEY_RSA_PAD_MODE_NONE "none" -#define OSSL_PKEY_RSA_PAD_MODE_PKCSV15 "pkcs1" -#define OSSL_PKEY_RSA_PAD_MODE_OAEP "oaep" -#define OSSL_PKEY_RSA_PAD_MODE_X931 "x931" -#define OSSL_PKEY_RSA_PAD_MODE_PSS "pss" +# define OSSL_PKEY_RSA_PAD_MODE_NONE "none" +# define OSSL_PKEY_RSA_PAD_MODE_PKCSV15 "pkcs1" +# define OSSL_PKEY_RSA_PAD_MODE_OAEP "oaep" +# define OSSL_PKEY_RSA_PAD_MODE_X931 "x931" +# define OSSL_PKEY_RSA_PAD_MODE_PSS "pss" /* RSA pss padding salt length */ -#define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest" -#define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max" -#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto" -#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX "auto-digestmax" - -/* Key generation parameters */ -#define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS -#define OSSL_PKEY_PARAM_RSA_PRIMES "primes" -#define OSSL_PKEY_PARAM_RSA_DIGEST OSSL_PKEY_PARAM_DIGEST -#define OSSL_PKEY_PARAM_RSA_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES -#define OSSL_PKEY_PARAM_RSA_MASKGENFUNC OSSL_PKEY_PARAM_MASKGENFUNC -#define OSSL_PKEY_PARAM_RSA_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST -#define OSSL_PKEY_PARAM_RSA_PSS_SALTLEN "saltlen" - -/* Key generation parameters */ -#define OSSL_PKEY_PARAM_FFC_TYPE "type" -#define OSSL_PKEY_PARAM_FFC_PBITS "pbits" -#define OSSL_PKEY_PARAM_FFC_QBITS "qbits" -#define OSSL_PKEY_PARAM_FFC_DIGEST OSSL_PKEY_PARAM_DIGEST -#define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES - -#define OSSL_PKEY_PARAM_EC_ENCODING "encoding" /* utf8_string */ -#define OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT "point-format" -#define OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE "group-check" -#define OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC "include-public" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX "auto-digestmax" /* OSSL_PKEY_PARAM_EC_ENCODING values */ -#define OSSL_PKEY_EC_ENCODING_EXPLICIT "explicit" -#define OSSL_PKEY_EC_ENCODING_GROUP "named_curve" - -#define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED "uncompressed" -#define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED "compressed" -#define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID "hybrid" - -#define OSSL_PKEY_EC_GROUP_CHECK_DEFAULT "default" -#define OSSL_PKEY_EC_GROUP_CHECK_NAMED "named" -#define OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST "named-nist" - -/* Key Exchange parameters */ -#define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */ -#define OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE "ecdh-cofactor-mode" /* int */ -#define OSSL_EXCHANGE_PARAM_KDF_TYPE "kdf-type" /* utf8_string */ -#define OSSL_EXCHANGE_PARAM_KDF_DIGEST "kdf-digest" /* utf8_string */ -#define OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS "kdf-digest-props" /* utf8_string */ -#define OSSL_EXCHANGE_PARAM_KDF_OUTLEN "kdf-outlen" /* size_t */ -/* The following parameter is an octet_string on set and an octet_ptr on get */ -#define OSSL_EXCHANGE_PARAM_KDF_UKM "kdf-ukm" - -/* Signature parameters */ -#define OSSL_SIGNATURE_PARAM_ALGORITHM_ID "algorithm-id" -#define OSSL_SIGNATURE_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE -#define OSSL_SIGNATURE_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST -#define OSSL_SIGNATURE_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES -#define OSSL_SIGNATURE_PARAM_PSS_SALTLEN "saltlen" -#define OSSL_SIGNATURE_PARAM_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST -#define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES \ - OSSL_PKEY_PARAM_MGF1_PROPERTIES -#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE OSSL_PKEY_PARAM_DIGEST_SIZE - -/* Asym cipher parameters */ -#define OSSL_ASYM_CIPHER_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST -#define OSSL_ASYM_CIPHER_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES -#define OSSL_ASYM_CIPHER_PARAM_ENGINE OSSL_PKEY_PARAM_ENGINE -#define OSSL_ASYM_CIPHER_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE -#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST \ - OSSL_PKEY_PARAM_MGF1_DIGEST -#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS \ - OSSL_PKEY_PARAM_MGF1_PROPERTIES -#define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST OSSL_ALG_PARAM_DIGEST -#define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS "digest-props" -/* The following parameter is an octet_string on set and an octet_ptr on get */ -#define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL "oaep-label" -#define OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION "tls-client-version" -#define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION "tls-negotiated-version" - -/* - * Encoder / decoder parameters - */ -#define OSSL_ENCODER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER -#define OSSL_ENCODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -/* Currently PVK only, but reusable for others as needed */ -#define OSSL_ENCODER_PARAM_ENCRYPT_LEVEL "encrypt-level" -#define OSSL_ENCODER_PARAM_SAVE_PARAMETERS "save-parameters" /* integer */ - -#define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES - -/* Passphrase callback parameters */ -#define OSSL_PASSPHRASE_PARAM_INFO "info" - -/* Keygen callback parameters, from provider to libcrypto */ -#define OSSL_GEN_PARAM_POTENTIAL "potential" /* integer */ -#define OSSL_GEN_PARAM_ITERATION "iteration" /* integer */ +# define OSSL_PKEY_EC_ENCODING_EXPLICIT "explicit" +# define OSSL_PKEY_EC_ENCODING_GROUP "named_curve" -/* ACVP Test parameters : These should not be used normally */ -#define OSSL_PKEY_PARAM_RSA_TEST_XP1 "xp1" -#define OSSL_PKEY_PARAM_RSA_TEST_XP2 "xp2" -#define OSSL_PKEY_PARAM_RSA_TEST_XP "xp" -#define OSSL_PKEY_PARAM_RSA_TEST_XQ1 "xq1" -#define OSSL_PKEY_PARAM_RSA_TEST_XQ2 "xq2" -#define OSSL_PKEY_PARAM_RSA_TEST_XQ "xq" -#define OSSL_PKEY_PARAM_RSA_TEST_P1 "p1" -#define OSSL_PKEY_PARAM_RSA_TEST_P2 "p2" -#define OSSL_PKEY_PARAM_RSA_TEST_Q1 "q1" -#define OSSL_PKEY_PARAM_RSA_TEST_Q2 "q2" -#define OSSL_SIGNATURE_PARAM_KAT "kat" +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED "uncompressed" +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED "compressed" +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID "hybrid" -/* KEM parameters */ -#define OSSL_KEM_PARAM_OPERATION "operation" +# define OSSL_PKEY_EC_GROUP_CHECK_DEFAULT "default" +# define OSSL_PKEY_EC_GROUP_CHECK_NAMED "named" +# define OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST "named-nist" /* OSSL_KEM_PARAM_OPERATION values */ #define OSSL_KEM_PARAM_OPERATION_RSASVE "RSASVE" - -/* Capabilities */ - -/* TLS-GROUP Capability */ -#define OSSL_CAPABILITY_TLS_GROUP_NAME "tls-group-name" -#define OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL "tls-group-name-internal" -#define OSSL_CAPABILITY_TLS_GROUP_ID "tls-group-id" -#define OSSL_CAPABILITY_TLS_GROUP_ALG "tls-group-alg" -#define OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS "tls-group-sec-bits" -#define OSSL_CAPABILITY_TLS_GROUP_IS_KEM "tls-group-is-kem" -#define OSSL_CAPABILITY_TLS_GROUP_MIN_TLS "tls-min-tls" -#define OSSL_CAPABILITY_TLS_GROUP_MAX_TLS "tls-max-tls" -#define OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS "tls-min-dtls" -#define OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS "tls-max-dtls" - -/*- - * storemgmt parameters - */ - -/* - * Used by storemgmt_ctx_set_params(): - * - * - OSSL_STORE_PARAM_EXPECT is an INTEGER, and the value is any of the - * OSSL_STORE_INFO numbers. This is used to set the expected type of - * object loaded. - * - * - OSSL_STORE_PARAM_SUBJECT, OSSL_STORE_PARAM_ISSUER, - * OSSL_STORE_PARAM_SERIAL, OSSL_STORE_PARAM_FINGERPRINT, - * OSSL_STORE_PARAM_DIGEST, OSSL_STORE_PARAM_ALIAS - * are used as search criteria. - * (OSSL_STORE_PARAM_DIGEST is used with OSSL_STORE_PARAM_FINGERPRINT) - */ -#define OSSL_STORE_PARAM_EXPECT "expect" /* INTEGER */ -#define OSSL_STORE_PARAM_SUBJECT "subject" /* DER blob => OCTET_STRING */ -#define OSSL_STORE_PARAM_ISSUER "name" /* DER blob => OCTET_STRING */ -#define OSSL_STORE_PARAM_SERIAL "serial" /* INTEGER */ -#define OSSL_STORE_PARAM_DIGEST "digest" /* UTF8_STRING */ -#define OSSL_STORE_PARAM_FINGERPRINT "fingerprint" /* OCTET_STRING */ -#define OSSL_STORE_PARAM_ALIAS "alias" /* UTF8_STRING */ - -/* You may want to pass properties for the provider implementation to use */ -#define OSSL_STORE_PARAM_PROPERTIES "properties" /* utf8_string */ -/* OSSL_DECODER input type if a decoder is used by the store */ -#define OSSL_STORE_PARAM_INPUT_TYPE "input-type" /* UTF8_STRING */ +#define OSSL_KEM_PARAM_OPERATION_DHKEM "DHKEM" + +/* Parameter name definitions - generated by util/perl/OpenSSL/paramnames.pm */ +# define OSSL_ALG_PARAM_CIPHER "cipher" +# define OSSL_ALG_PARAM_DIGEST "digest" +# define OSSL_ALG_PARAM_ENGINE "engine" +# define OSSL_ALG_PARAM_MAC "mac" +# define OSSL_ALG_PARAM_PROPERTIES "properties" +# define OSSL_ASYM_CIPHER_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST +# define OSSL_ASYM_CIPHER_PARAM_ENGINE OSSL_PKEY_PARAM_ENGINE +# define OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION "implicit-rejection" +# define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST +# define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS OSSL_PKEY_PARAM_MGF1_PROPERTIES +# define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST OSSL_ALG_PARAM_DIGEST +# define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS "digest-props" +# define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL "oaep-label" +# define OSSL_ASYM_CIPHER_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE +# define OSSL_ASYM_CIPHER_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES +# define OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION "tls-client-version" +# define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION "tls-negotiated-version" +# define OSSL_CAPABILITY_TLS_GROUP_ALG "tls-group-alg" +# define OSSL_CAPABILITY_TLS_GROUP_ID "tls-group-id" +# define OSSL_CAPABILITY_TLS_GROUP_IS_KEM "tls-group-is-kem" +# define OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS "tls-max-dtls" +# define OSSL_CAPABILITY_TLS_GROUP_MAX_TLS "tls-max-tls" +# define OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS "tls-min-dtls" +# define OSSL_CAPABILITY_TLS_GROUP_MIN_TLS "tls-min-tls" +# define OSSL_CAPABILITY_TLS_GROUP_NAME "tls-group-name" +# define OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL "tls-group-name-internal" +# define OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS "tls-group-sec-bits" +# define OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT "tls-sigalg-code-point" +# define OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME "tls-sigalg-hash-name" +# define OSSL_CAPABILITY_TLS_SIGALG_HASH_OID "tls-sigalg-hash-oid" +# define OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME "tls-sigalg-iana-name" +# define OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE "tls-sigalg-keytype" +# define OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID "tls-sigalg-keytype-oid" +# define OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS "tls-max-tls" +# define OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS "tls-min-tls" +# define OSSL_CAPABILITY_TLS_SIGALG_NAME "tls-sigalg-name" +# define OSSL_CAPABILITY_TLS_SIGALG_OID "tls-sigalg-oid" +# define OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS "tls-sigalg-sec-bits" +# define OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME "tls-sigalg-sig-name" +# define OSSL_CAPABILITY_TLS_SIGALG_SIG_OID "tls-sigalg-sig-oid" +# define OSSL_CIPHER_PARAM_AEAD "aead" +# define OSSL_CIPHER_PARAM_AEAD_IVLEN OSSL_CIPHER_PARAM_IVLEN +# define OSSL_CIPHER_PARAM_AEAD_MAC_KEY "mackey" +# define OSSL_CIPHER_PARAM_AEAD_TAG "tag" +# define OSSL_CIPHER_PARAM_AEAD_TAGLEN "taglen" +# define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD "tlsaad" +# define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD "tlsaadpad" +# define OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN "tlsivgen" +# define OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED "tlsivfixed" +# define OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV "tlsivinv" +# define OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS "alg_id_param" +# define OSSL_CIPHER_PARAM_BLOCK_SIZE "blocksize" +# define OSSL_CIPHER_PARAM_CTS "cts" +# define OSSL_CIPHER_PARAM_CTS_MODE "cts_mode" +# define OSSL_CIPHER_PARAM_CUSTOM_IV "custom-iv" +# define OSSL_CIPHER_PARAM_HAS_RAND_KEY "has-randkey" +# define OSSL_CIPHER_PARAM_IV "iv" +# define OSSL_CIPHER_PARAM_IVLEN "ivlen" +# define OSSL_CIPHER_PARAM_KEYLEN "keylen" +# define OSSL_CIPHER_PARAM_MODE "mode" +# define OSSL_CIPHER_PARAM_NUM "num" +# define OSSL_CIPHER_PARAM_PADDING "padding" +# define OSSL_CIPHER_PARAM_RANDOM_KEY "randkey" +# define OSSL_CIPHER_PARAM_RC2_KEYBITS "keybits" +# define OSSL_CIPHER_PARAM_ROUNDS "rounds" +# define OSSL_CIPHER_PARAM_SPEED "speed" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK "tls-multi" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD "tls1multi_aad" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN "tls1multi_aadpacklen" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC "tls1multi_enc" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN "tls1multi_encin" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN "tls1multi_enclen" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE "tls1multi_interleave" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE "tls1multi_maxbufsz" +# define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT "tls1multi_maxsndfrag" +# define OSSL_CIPHER_PARAM_TLS_MAC "tls-mac" +# define OSSL_CIPHER_PARAM_TLS_MAC_SIZE "tls-mac-size" +# define OSSL_CIPHER_PARAM_TLS_VERSION "tls-version" +# define OSSL_CIPHER_PARAM_UPDATED_IV "updated-iv" +# define OSSL_CIPHER_PARAM_USE_BITS "use-bits" +# define OSSL_CIPHER_PARAM_XTS_STANDARD "xts_standard" +# define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_DIGEST_PARAM_ALGID_ABSENT "algid-absent" +# define OSSL_DIGEST_PARAM_BLOCK_SIZE "blocksize" +# define OSSL_DIGEST_PARAM_MICALG "micalg" +# define OSSL_DIGEST_PARAM_PAD_TYPE "pad-type" +# define OSSL_DIGEST_PARAM_SIZE "size" +# define OSSL_DIGEST_PARAM_SSL3_MS "ssl3-ms" +# define OSSL_DIGEST_PARAM_XOF "xof" +# define OSSL_DIGEST_PARAM_XOFLEN "xoflen" +# define OSSL_DRBG_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +# define OSSL_DRBG_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +# define OSSL_DRBG_PARAM_ENTROPY_REQUIRED "entropy_required" +# define OSSL_DRBG_PARAM_MAC OSSL_ALG_PARAM_MAC +# define OSSL_DRBG_PARAM_MAX_ADINLEN "max_adinlen" +# define OSSL_DRBG_PARAM_MAX_ENTROPYLEN "max_entropylen" +# define OSSL_DRBG_PARAM_MAX_LENGTH "maxium_length" +# define OSSL_DRBG_PARAM_MAX_NONCELEN "max_noncelen" +# define OSSL_DRBG_PARAM_MAX_PERSLEN "max_perslen" +# define OSSL_DRBG_PARAM_MIN_ENTROPYLEN "min_entropylen" +# define OSSL_DRBG_PARAM_MIN_LENGTH "minium_length" +# define OSSL_DRBG_PARAM_MIN_NONCELEN "min_noncelen" +# define OSSL_DRBG_PARAM_PREDICTION_RESISTANCE "prediction_resistance" +# define OSSL_DRBG_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_DRBG_PARAM_RANDOM_DATA "random_data" +# define OSSL_DRBG_PARAM_RESEED_COUNTER "reseed_counter" +# define OSSL_DRBG_PARAM_RESEED_REQUESTS "reseed_requests" +# define OSSL_DRBG_PARAM_RESEED_TIME "reseed_time" +# define OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL "reseed_time_interval" +# define OSSL_DRBG_PARAM_SIZE "size" +# define OSSL_DRBG_PARAM_USE_DF "use_derivation_function" +# define OSSL_ENCODER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +# define OSSL_ENCODER_PARAM_ENCRYPT_LEVEL "encrypt-level" +# define OSSL_ENCODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_ENCODER_PARAM_SAVE_PARAMETERS "save-parameters" +# define OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE "ecdh-cofactor-mode" +# define OSSL_EXCHANGE_PARAM_KDF_DIGEST "kdf-digest" +# define OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS "kdf-digest-props" +# define OSSL_EXCHANGE_PARAM_KDF_OUTLEN "kdf-outlen" +# define OSSL_EXCHANGE_PARAM_KDF_TYPE "kdf-type" +# define OSSL_EXCHANGE_PARAM_KDF_UKM "kdf-ukm" +# define OSSL_EXCHANGE_PARAM_PAD "pad" +# define OSSL_GEN_PARAM_ITERATION "iteration" +# define OSSL_GEN_PARAM_POTENTIAL "potential" +# define OSSL_KDF_PARAM_ARGON2_AD "ad" +# define OSSL_KDF_PARAM_ARGON2_LANES "lanes" +# define OSSL_KDF_PARAM_ARGON2_MEMCOST "memcost" +# define OSSL_KDF_PARAM_ARGON2_VERSION "version" +# define OSSL_KDF_PARAM_CEK_ALG "cekalg" +# define OSSL_KDF_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +# define OSSL_KDF_PARAM_CONSTANT "constant" +# define OSSL_KDF_PARAM_DATA "data" +# define OSSL_KDF_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +# define OSSL_KDF_PARAM_EARLY_CLEAN "early_clean" +# define OSSL_KDF_PARAM_HMACDRBG_ENTROPY "entropy" +# define OSSL_KDF_PARAM_HMACDRBG_NONCE "nonce" +# define OSSL_KDF_PARAM_INFO "info" +# define OSSL_KDF_PARAM_ITER "iter" +# define OSSL_KDF_PARAM_KBKDF_R "r" +# define OSSL_KDF_PARAM_KBKDF_USE_L "use-l" +# define OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR "use-separator" +# define OSSL_KDF_PARAM_KEY "key" +# define OSSL_KDF_PARAM_LABEL "label" +# define OSSL_KDF_PARAM_MAC OSSL_ALG_PARAM_MAC +# define OSSL_KDF_PARAM_MAC_SIZE "maclen" +# define OSSL_KDF_PARAM_MODE "mode" +# define OSSL_KDF_PARAM_PASSWORD "pass" +# define OSSL_KDF_PARAM_PKCS12_ID "id" +# define OSSL_KDF_PARAM_PKCS5 "pkcs5" +# define OSSL_KDF_PARAM_PREFIX "prefix" +# define OSSL_KDF_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_KDF_PARAM_SALT "salt" +# define OSSL_KDF_PARAM_SCRYPT_MAXMEM "maxmem_bytes" +# define OSSL_KDF_PARAM_SCRYPT_N "n" +# define OSSL_KDF_PARAM_SCRYPT_P "p" +# define OSSL_KDF_PARAM_SCRYPT_R "r" +# define OSSL_KDF_PARAM_SECRET "secret" +# define OSSL_KDF_PARAM_SEED "seed" +# define OSSL_KDF_PARAM_SIZE "size" +# define OSSL_KDF_PARAM_SSHKDF_SESSION_ID "session_id" +# define OSSL_KDF_PARAM_SSHKDF_TYPE "type" +# define OSSL_KDF_PARAM_SSHKDF_XCGHASH "xcghash" +# define OSSL_KDF_PARAM_THREADS "threads" +# define OSSL_KDF_PARAM_UKM "ukm" +# define OSSL_KDF_PARAM_X942_ACVPINFO "acvp-info" +# define OSSL_KDF_PARAM_X942_PARTYUINFO "partyu-info" +# define OSSL_KDF_PARAM_X942_PARTYVINFO "partyv-info" +# define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO "supp-privinfo" +# define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo" +# define OSSL_KDF_PARAM_X942_USE_KEYBITS "use-keybits" +# define OSSL_KEM_PARAM_IKME "ikme" +# define OSSL_KEM_PARAM_OPERATION "operation" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_BLOCK_PADDING "block_padding" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_EARLY_DATA "max_early_data" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN "max_frag_len" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE "mode" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS "options" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD "read_ahead" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_STREAM_MAC "stream_mac" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE "tlstree" +# define OSSL_LIBSSL_RECORD_LAYER_PARAM_USE_ETM "use_etm" +# define OSSL_LIBSSL_RECORD_LAYER_READ_BUFFER_LEN "read_buffer_len" +# define OSSL_MAC_PARAM_BLOCK_SIZE "block-size" +# define OSSL_MAC_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +# define OSSL_MAC_PARAM_CUSTOM "custom" +# define OSSL_MAC_PARAM_C_ROUNDS "c-rounds" +# define OSSL_MAC_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +# define OSSL_MAC_PARAM_DIGEST_NOINIT "digest-noinit" +# define OSSL_MAC_PARAM_DIGEST_ONESHOT "digest-oneshot" +# define OSSL_MAC_PARAM_D_ROUNDS "d-rounds" +# define OSSL_MAC_PARAM_IV "iv" +# define OSSL_MAC_PARAM_KEY "key" +# define OSSL_MAC_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_MAC_PARAM_SALT "salt" +# define OSSL_MAC_PARAM_SIZE "size" +# define OSSL_MAC_PARAM_TLS_DATA_SIZE "tls-data-size" +# define OSSL_MAC_PARAM_XOF "xof" +# define OSSL_OBJECT_PARAM_DATA "data" +# define OSSL_OBJECT_PARAM_DATA_STRUCTURE "data-structure" +# define OSSL_OBJECT_PARAM_DATA_TYPE "data-type" +# define OSSL_OBJECT_PARAM_DESC "desc" +# define OSSL_OBJECT_PARAM_REFERENCE "reference" +# define OSSL_OBJECT_PARAM_TYPE "type" +# define OSSL_PASSPHRASE_PARAM_INFO "info" +# define OSSL_PKEY_PARAM_BITS "bits" +# define OSSL_PKEY_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +# define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" +# define OSSL_PKEY_PARAM_DHKEM_IKM "dhkem-ikm" +# define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator" +# define OSSL_PKEY_PARAM_DH_PRIV_LEN "priv_len" +# define OSSL_PKEY_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +# define OSSL_PKEY_PARAM_DIGEST_SIZE "digest-size" +# define OSSL_PKEY_PARAM_DIST_ID "distid" +# define OSSL_PKEY_PARAM_EC_A "a" +# define OSSL_PKEY_PARAM_EC_B "b" +# define OSSL_PKEY_PARAM_EC_CHAR2_M "m" +# define OSSL_PKEY_PARAM_EC_CHAR2_PP_K1 "k1" +# define OSSL_PKEY_PARAM_EC_CHAR2_PP_K2 "k2" +# define OSSL_PKEY_PARAM_EC_CHAR2_PP_K3 "k3" +# define OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS "tp" +# define OSSL_PKEY_PARAM_EC_CHAR2_TYPE "basis-type" +# define OSSL_PKEY_PARAM_EC_COFACTOR "cofactor" +# define OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS "decoded-from-explicit" +# define OSSL_PKEY_PARAM_EC_ENCODING "encoding" +# define OSSL_PKEY_PARAM_EC_FIELD_TYPE "field-type" +# define OSSL_PKEY_PARAM_EC_GENERATOR "generator" +# define OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE "group-check" +# define OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC "include-public" +# define OSSL_PKEY_PARAM_EC_ORDER "order" +# define OSSL_PKEY_PARAM_EC_P "p" +# define OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT "point-format" +# define OSSL_PKEY_PARAM_EC_PUB_X "qx" +# define OSSL_PKEY_PARAM_EC_PUB_Y "qy" +# define OSSL_PKEY_PARAM_EC_SEED "seed" +# define OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY "encoded-pub-key" +# define OSSL_PKEY_PARAM_ENGINE OSSL_ALG_PARAM_ENGINE +# define OSSL_PKEY_PARAM_FFC_COFACTOR "j" +# define OSSL_PKEY_PARAM_FFC_DIGEST OSSL_PKEY_PARAM_DIGEST +# define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES +# define OSSL_PKEY_PARAM_FFC_G "g" +# define OSSL_PKEY_PARAM_FFC_GINDEX "gindex" +# define OSSL_PKEY_PARAM_FFC_H "hindex" +# define OSSL_PKEY_PARAM_FFC_P "p" +# define OSSL_PKEY_PARAM_FFC_PBITS "pbits" +# define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter" +# define OSSL_PKEY_PARAM_FFC_Q "q" +# define OSSL_PKEY_PARAM_FFC_QBITS "qbits" +# define OSSL_PKEY_PARAM_FFC_SEED "seed" +# define OSSL_PKEY_PARAM_FFC_TYPE "type" +# define OSSL_PKEY_PARAM_FFC_VALIDATE_G "validate-g" +# define OSSL_PKEY_PARAM_FFC_VALIDATE_LEGACY "validate-legacy" +# define OSSL_PKEY_PARAM_FFC_VALIDATE_PQ "validate-pq" +# define OSSL_PKEY_PARAM_GROUP_NAME "group" +# define OSSL_PKEY_PARAM_IMPLICIT_REJECTION "implicit-rejection" +# define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" +# define OSSL_PKEY_PARAM_MASKGENFUNC "mgf" +# define OSSL_PKEY_PARAM_MAX_SIZE "max-size" +# define OSSL_PKEY_PARAM_MGF1_DIGEST "mgf1-digest" +# define OSSL_PKEY_PARAM_MGF1_PROPERTIES "mgf1-properties" +# define OSSL_PKEY_PARAM_PAD_MODE "pad-mode" +# define OSSL_PKEY_PARAM_PRIV_KEY "priv" +# define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +# define OSSL_PKEY_PARAM_PUB_KEY "pub" +# define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT1 "rsa-coefficient1" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT2 "rsa-coefficient2" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT3 "rsa-coefficient3" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT4 "rsa-coefficient4" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT5 "rsa-coefficient5" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT6 "rsa-coefficient6" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT7 "rsa-coefficient7" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 "rsa-coefficient8" +# define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 "rsa-coefficient9" +# define OSSL_PKEY_PARAM_RSA_D "d" +# define OSSL_PKEY_PARAM_RSA_DIGEST OSSL_PKEY_PARAM_DIGEST +# define OSSL_PKEY_PARAM_RSA_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES +# define OSSL_PKEY_PARAM_RSA_E "e" +# define OSSL_PKEY_PARAM_RSA_EXPONENT "rsa-exponent" +# define OSSL_PKEY_PARAM_RSA_EXPONENT1 "rsa-exponent1" +# define OSSL_PKEY_PARAM_RSA_EXPONENT10 "rsa-exponent10" +# define OSSL_PKEY_PARAM_RSA_EXPONENT2 "rsa-exponent2" +# define OSSL_PKEY_PARAM_RSA_EXPONENT3 "rsa-exponent3" +# define OSSL_PKEY_PARAM_RSA_EXPONENT4 "rsa-exponent4" +# define OSSL_PKEY_PARAM_RSA_EXPONENT5 "rsa-exponent5" +# define OSSL_PKEY_PARAM_RSA_EXPONENT6 "rsa-exponent6" +# define OSSL_PKEY_PARAM_RSA_EXPONENT7 "rsa-exponent7" +# define OSSL_PKEY_PARAM_RSA_EXPONENT8 "rsa-exponent8" +# define OSSL_PKEY_PARAM_RSA_EXPONENT9 "rsa-exponent9" +# define OSSL_PKEY_PARAM_RSA_FACTOR "rsa-factor" +# define OSSL_PKEY_PARAM_RSA_FACTOR1 "rsa-factor1" +# define OSSL_PKEY_PARAM_RSA_FACTOR10 "rsa-factor10" +# define OSSL_PKEY_PARAM_RSA_FACTOR2 "rsa-factor2" +# define OSSL_PKEY_PARAM_RSA_FACTOR3 "rsa-factor3" +# define OSSL_PKEY_PARAM_RSA_FACTOR4 "rsa-factor4" +# define OSSL_PKEY_PARAM_RSA_FACTOR5 "rsa-factor5" +# define OSSL_PKEY_PARAM_RSA_FACTOR6 "rsa-factor6" +# define OSSL_PKEY_PARAM_RSA_FACTOR7 "rsa-factor7" +# define OSSL_PKEY_PARAM_RSA_FACTOR8 "rsa-factor8" +# define OSSL_PKEY_PARAM_RSA_FACTOR9 "rsa-factor9" +# define OSSL_PKEY_PARAM_RSA_MASKGENFUNC OSSL_PKEY_PARAM_MASKGENFUNC +# define OSSL_PKEY_PARAM_RSA_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST +# define OSSL_PKEY_PARAM_RSA_N "n" +# define OSSL_PKEY_PARAM_RSA_PRIMES "primes" +# define OSSL_PKEY_PARAM_RSA_PSS_SALTLEN "saltlen" +# define OSSL_PKEY_PARAM_RSA_TEST_P1 "p1" +# define OSSL_PKEY_PARAM_RSA_TEST_P2 "p2" +# define OSSL_PKEY_PARAM_RSA_TEST_Q1 "q1" +# define OSSL_PKEY_PARAM_RSA_TEST_Q2 "q2" +# define OSSL_PKEY_PARAM_RSA_TEST_XP "xp" +# define OSSL_PKEY_PARAM_RSA_TEST_XP1 "xp1" +# define OSSL_PKEY_PARAM_RSA_TEST_XP2 "xp2" +# define OSSL_PKEY_PARAM_RSA_TEST_XQ "xq" +# define OSSL_PKEY_PARAM_RSA_TEST_XQ1 "xq1" +# define OSSL_PKEY_PARAM_RSA_TEST_XQ2 "xq2" +# define OSSL_PKEY_PARAM_SECURITY_BITS "security-bits" +# define OSSL_PKEY_PARAM_USE_COFACTOR_ECDH OSSL_PKEY_PARAM_USE_COFACTOR_FLAG +# define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag" +# define OSSL_PROV_PARAM_BUILDINFO "buildinfo" +# define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" +# define OSSL_PROV_PARAM_CORE_PROV_NAME "provider-name" +# define OSSL_PROV_PARAM_CORE_VERSION "openssl-version" +# define OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md" +# define OSSL_PROV_PARAM_NAME "name" +# define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" +# define OSSL_PROV_PARAM_SELF_TEST_DESC "st-desc" +# define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" +# define OSSL_PROV_PARAM_SELF_TEST_TYPE "st-type" +# define OSSL_PROV_PARAM_STATUS "status" +# define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" +# define OSSL_PROV_PARAM_VERSION "version" +# define OSSL_RAND_PARAM_GENERATE "generate" +# define OSSL_RAND_PARAM_MAX_REQUEST "max_request" +# define OSSL_RAND_PARAM_STATE "state" +# define OSSL_RAND_PARAM_STRENGTH "strength" +# define OSSL_RAND_PARAM_TEST_ENTROPY "test_entropy" +# define OSSL_RAND_PARAM_TEST_NONCE "test_nonce" +# define OSSL_SIGNATURE_PARAM_ALGORITHM_ID "algorithm-id" +# define OSSL_SIGNATURE_PARAM_CONTEXT_STRING "context-string" +# define OSSL_SIGNATURE_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST +# define OSSL_SIGNATURE_PARAM_DIGEST_SIZE OSSL_PKEY_PARAM_DIGEST_SIZE +# define OSSL_SIGNATURE_PARAM_INSTANCE "instance" +# define OSSL_SIGNATURE_PARAM_KAT "kat" +# define OSSL_SIGNATURE_PARAM_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST +# define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES OSSL_PKEY_PARAM_MGF1_PROPERTIES +# define OSSL_SIGNATURE_PARAM_NONCE_TYPE "nonce-type" +# define OSSL_SIGNATURE_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE +# define OSSL_SIGNATURE_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES +# define OSSL_SIGNATURE_PARAM_PSS_SALTLEN "saltlen" +# define OSSL_STORE_PARAM_ALIAS "alias" +# define OSSL_STORE_PARAM_DIGEST "digest" +# define OSSL_STORE_PARAM_EXPECT "expect" +# define OSSL_STORE_PARAM_FINGERPRINT "fingerprint" +# define OSSL_STORE_PARAM_INPUT_TYPE "input-type" +# define OSSL_STORE_PARAM_ISSUER "name" +# define OSSL_STORE_PARAM_PROPERTIES "properties" +# define OSSL_STORE_PARAM_SERIAL "serial" +# define OSSL_STORE_PARAM_SUBJECT "subject" # ifdef __cplusplus } diff --git a/include/openssl/core_names.h.in b/include/openssl/core_names.h.in new file mode 100644 index 0000000000..c14520fe28 --- /dev/null +++ b/include/openssl/core_names.h.in @@ -0,0 +1,119 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +{- +use OpenSSL::paramnames qw(generate_public_macros); +-} + +#ifndef OPENSSL_CORE_NAMES_H +# define OPENSSL_CORE_NAMES_H +# pragma once + +# ifdef __cplusplus +extern "C" { +# endif + +/* OSSL_CIPHER_PARAM_CTS_MODE Values */ +# define OSSL_CIPHER_CTS_MODE_CS1 "CS1" +# define OSSL_CIPHER_CTS_MODE_CS2 "CS2" +# define OSSL_CIPHER_CTS_MODE_CS3 "CS3" + +/* Known CIPHER names (not a complete list) */ +# define OSSL_CIPHER_NAME_AES_128_GCM_SIV "AES-128-GCM-SIV" +# define OSSL_CIPHER_NAME_AES_192_GCM_SIV "AES-192-GCM-SIV" +# define OSSL_CIPHER_NAME_AES_256_GCM_SIV "AES-256-GCM-SIV" + +/* Known DIGEST names (not a complete list) */ +# define OSSL_DIGEST_NAME_MD5 "MD5" +# define OSSL_DIGEST_NAME_MD5_SHA1 "MD5-SHA1" +# define OSSL_DIGEST_NAME_SHA1 "SHA1" +# define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224" +# define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256" +# define OSSL_DIGEST_NAME_SHA2_256_192 "SHA2-256/192" +# define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384" +# define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512" +# define OSSL_DIGEST_NAME_SHA2_512_224 "SHA2-512/224" +# define OSSL_DIGEST_NAME_SHA2_512_256 "SHA2-512/256" +# define OSSL_DIGEST_NAME_MD2 "MD2" +# define OSSL_DIGEST_NAME_MD4 "MD4" +# define OSSL_DIGEST_NAME_MDC2 "MDC2" +# define OSSL_DIGEST_NAME_RIPEMD160 "RIPEMD160" +# define OSSL_DIGEST_NAME_SHA3_224 "SHA3-224" +# define OSSL_DIGEST_NAME_SHA3_256 "SHA3-256" +# define OSSL_DIGEST_NAME_SHA3_384 "SHA3-384" +# define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512" +# define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128" +# define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256" +# define OSSL_DIGEST_NAME_SM3 "SM3" + +/* Known MAC names */ +# define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC" +# define OSSL_MAC_NAME_BLAKE2SMAC "BLAKE2SMAC" +# define OSSL_MAC_NAME_CMAC "CMAC" +# define OSSL_MAC_NAME_GMAC "GMAC" +# define OSSL_MAC_NAME_HMAC "HMAC" +# define OSSL_MAC_NAME_KMAC128 "KMAC128" +# define OSSL_MAC_NAME_KMAC256 "KMAC256" +# define OSSL_MAC_NAME_POLY1305 "POLY1305" +# define OSSL_MAC_NAME_SIPHASH "SIPHASH" + +/* Known KDF names */ +# define OSSL_KDF_NAME_HKDF "HKDF" +# define OSSL_KDF_NAME_TLS1_3_KDF "TLS13-KDF" +# define OSSL_KDF_NAME_PBKDF1 "PBKDF1" +# define OSSL_KDF_NAME_PBKDF2 "PBKDF2" +# define OSSL_KDF_NAME_SCRYPT "SCRYPT" +# define OSSL_KDF_NAME_SSHKDF "SSHKDF" +# define OSSL_KDF_NAME_SSKDF "SSKDF" +# define OSSL_KDF_NAME_TLS1_PRF "TLS1-PRF" +# define OSSL_KDF_NAME_X942KDF_ASN1 "X942KDF-ASN1" +# define OSSL_KDF_NAME_X942KDF_CONCAT "X942KDF-CONCAT" +# define OSSL_KDF_NAME_X963KDF "X963KDF" +# define OSSL_KDF_NAME_KBKDF "KBKDF" +# define OSSL_KDF_NAME_KRB5KDF "KRB5KDF" +# define OSSL_KDF_NAME_HMACDRBGKDF "HMAC-DRBG-KDF" + +/* RSA padding modes */ +# define OSSL_PKEY_RSA_PAD_MODE_NONE "none" +# define OSSL_PKEY_RSA_PAD_MODE_PKCSV15 "pkcs1" +# define OSSL_PKEY_RSA_PAD_MODE_OAEP "oaep" +# define OSSL_PKEY_RSA_PAD_MODE_X931 "x931" +# define OSSL_PKEY_RSA_PAD_MODE_PSS "pss" + +/* RSA pss padding salt length */ +# define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto" +# define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX "auto-digestmax" + +/* OSSL_PKEY_PARAM_EC_ENCODING values */ +# define OSSL_PKEY_EC_ENCODING_EXPLICIT "explicit" +# define OSSL_PKEY_EC_ENCODING_GROUP "named_curve" + +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED "uncompressed" +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED "compressed" +# define OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID "hybrid" + +# define OSSL_PKEY_EC_GROUP_CHECK_DEFAULT "default" +# define OSSL_PKEY_EC_GROUP_CHECK_NAMED "named" +# define OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST "named-nist" + +/* OSSL_KEM_PARAM_OPERATION values */ +#define OSSL_KEM_PARAM_OPERATION_RSASVE "RSASVE" +#define OSSL_KEM_PARAM_OPERATION_DHKEM "DHKEM" + +/* Parameter name definitions - generated by util/perl/OpenSSL/paramnames.pm */ +{- generate_public_macros(); -} + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/crmf.h b/include/openssl/crmf.h index 71b747ed33..1f901f35f8 100644 --- a/include/openssl/crmf.h +++ b/include/openssl/crmf.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/crmf.h.in * - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -43,8 +43,8 @@ extern "C" { # define OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT 0 # define OSSL_CRMF_SUBSEQUENTMESSAGE_CHALLENGERESP 1 - typedef struct ossl_crmf_encryptedvalue_st OSSL_CRMF_ENCRYPTEDVALUE; + DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG) @@ -198,12 +198,14 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, int rid, int acceptRAVerified, OSSL_LIB_CTX *libctx, const char *propq); OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm); -const ASN1_INTEGER -*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); +X509_PUBKEY +*OSSL_CRMF_CERTTEMPLATE_get0_publicKey(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl); +const ASN1_INTEGER +*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); X509_EXTENSIONS *OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME diff --git a/include/openssl/crmf.h.in b/include/openssl/crmf.h.in index 4d37ea6d94..43411fa42f 100644 --- a/include/openssl/crmf.h.in +++ b/include/openssl/crmf.h.in @@ -1,7 +1,7 @@ /*- * {- join("\n * ", @autowarntext) -} * - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -44,8 +44,8 @@ extern "C" { # define OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT 0 # define OSSL_CRMF_SUBSEQUENTMESSAGE_CHALLENGERESP 1 - typedef struct ossl_crmf_encryptedvalue_st OSSL_CRMF_ENCRYPTEDVALUE; + DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG) @@ -151,12 +151,14 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, int rid, int acceptRAVerified, OSSL_LIB_CTX *libctx, const char *propq); OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm); -const ASN1_INTEGER -*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); +X509_PUBKEY +*OSSL_CRMF_CERTTEMPLATE_get0_publicKey(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl); +const ASN1_INTEGER +*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); X509_EXTENSIONS *OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl); const X509_NAME diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index ab01aae8a4..55e00dccdc 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/crypto.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -88,6 +88,7 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock); +int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock); /* No longer needed, so this is a no-op */ #define OPENSSL_malloc_init() while(0) continue @@ -552,6 +553,8 @@ void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); +void OSSL_sleep(uint64_t millis); + # ifdef __cplusplus } # endif diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in index fb0c7cbb87..b2d691b90f 100644 --- a/include/openssl/crypto.h.in +++ b/include/openssl/crypto.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -89,6 +89,7 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, CRYPTO_RWLOCK *lock); int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock); +int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock); /* No longer needed, so this is a no-op */ #define OPENSSL_malloc_init() while(0) continue @@ -529,6 +530,8 @@ void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); +void OSSL_sleep(uint64_t millis); + # ifdef __cplusplus } # endif diff --git a/include/openssl/ct.h b/include/openssl/ct.h index b6dd8c3547..e6dd1192a4 100644 --- a/include/openssl/ct.h +++ b/include/openssl/ct.h @@ -133,7 +133,7 @@ typedef enum { */ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); - + /* * The same as CT_POLICY_EVAL_CTX_new_ex() but the default library * context and property query string is used. diff --git a/include/openssl/ct.h.in b/include/openssl/ct.h.in index 16086b33bd..3fc2aaa942 100644 --- a/include/openssl/ct.h.in +++ b/include/openssl/ct.h.in @@ -85,7 +85,7 @@ typedef enum { */ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); - + /* * The same as CT_POLICY_EVAL_CTX_new_ex() but the default library * context and property query string is used. diff --git a/include/openssl/dh.h b/include/openssl/dh.h index 8bc17448a0..f1c0ed06b3 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -144,7 +144,7 @@ DECLARE_ASN1_ITEM(DHparams) # define DH_GENERATOR_3 3 # define DH_GENERATOR_5 5 -/* DH_check error codes */ +/* DH_check error codes, some of them shared with DH_check_pub_key */ /* * NB: These values must align with the equivalently named macros in * internal/ffc.h. @@ -154,10 +154,10 @@ DECLARE_ASN1_ITEM(DHparams) # define DH_UNABLE_TO_CHECK_GENERATOR 0x04 # define DH_NOT_SUITABLE_GENERATOR 0x08 # define DH_CHECK_Q_NOT_PRIME 0x10 -# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */ # define DH_CHECK_INVALID_J_VALUE 0x40 # define DH_MODULUS_TOO_SMALL 0x80 -# define DH_MODULUS_TOO_LARGE 0x100 +# define DH_MODULUS_TOO_LARGE 0x100 /* +DH_check_pub_key */ /* DH_check_pub_key error codes */ # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h index 5d2a762a96..2997d7d4c2 100644 --- a/include/openssl/dherr.h +++ b/include/openssl/dherr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,7 @@ # define DH_R_INVALID_PARAMETER_NID 114 # define DH_R_INVALID_PUBKEY 102 # define DH_R_INVALID_SECRET 128 +# define DH_R_INVALID_SIZE 129 # define DH_R_KDF_PARAMETER_ERROR 112 # define DH_R_KEYS_NOT_SET 108 # define DH_R_MISSING_PUBKEY 125 @@ -50,6 +51,7 @@ # define DH_R_NO_PRIVATE_VALUE 100 # define DH_R_PARAMETER_ENCODING_ERROR 105 # define DH_R_PEER_KEY_ERROR 111 +# define DH_R_Q_TOO_LARGE 130 # define DH_R_SHARED_INFO_ERROR 113 # define DH_R_UNABLE_TO_CHECK_GENERATOR 121 diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h index 160404cc70..109878e688 100644 --- a/include/openssl/dsa.h +++ b/include/openssl/dsa.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h index 32e142a97d..e01f62751d 100644 --- a/include/openssl/e_os2.h +++ b/include/openssl/e_os2.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -89,7 +89,7 @@ extern "C" { /* * DLL settings. This part is a bit tough, because it's up to the - * application implementor how he or she will link the application, so it + * application implementer how he or she will link the application, so it * requires some macro to be used. */ # ifdef OPENSSL_SYS_WINDOWS diff --git a/include/openssl/e_ostime.h b/include/openssl/e_ostime.h new file mode 100644 index 0000000000..8a7cc9880f --- /dev/null +++ b/include/openssl/e_ostime.h @@ -0,0 +1,30 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_E_OSTIME_H +# define OPENSSL_E_OSTIME_H +# pragma once + +# include +# include +# include + +/* + * This header guarantees that 'struct timeval' will be available. It includes + * the minimum headers needed to facilitate this. This may still be a + * substantial set of headers on some platforms (e.g. on Win32). + */ + +# if defined(OPENSSL_SYS_WINDOWS) +# include +# else +# include +# endif + +#endif diff --git a/include/openssl/ec.h b/include/openssl/ec.h index be9fb2f089..e1cbe98228 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -460,6 +460,22 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], OSSL_LIB_CTX *libctx, const char *propq); +/** + * Creates an OSSL_PARAM array with the parameters describing the given + * EC_GROUP. + * The resulting parameters may contain an explicit or a named curve depending + * on the EC_GROUP. + * \param group pointer to the EC_GROUP object + * \param libctx The associated library context or NULL for the default + * context + * \param propq A property query string + * \param bnctx BN_CTX object (optional) + * \return newly created OSSL_PARAM array with the parameters + * describing the given EC_GROUP or NULL if an error occurred + */ +OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx, + const char *propq, BN_CTX *bnctx); + /** * Creates a EC_GROUP object with a curve specified by a NID * \param libctx The associated library context or NULL for the default @@ -1111,7 +1127,7 @@ OSSL_DEPRECATEDIN_3_0 int EC_KEY_check_key(const EC_KEY *key); /** Indicates if an EC_KEY can be used for signing. * \param eckey the EC_KEY object - * \return 1 if can can sign and 0 otherwise. + * \return 1 if can sign and 0 otherwise. */ OSSL_DEPRECATEDIN_3_0 int EC_KEY_can_sign(const EC_KEY *eckey); @@ -1287,7 +1303,7 @@ OSSL_DEPRECATEDIN_3_0 int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *me OSSL_DEPRECATEDIN_3_0 EC_KEY *EC_KEY_new_method(ENGINE *engine); /** The old name for ecdh_KDF_X9_63 - * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * The ECDH KDF specification has been mistakenly attributed to ANSI X9.62, * it is actually specified in ANSI X9.63. * This identifier is retained for backwards compatibility */ diff --git a/include/openssl/err.h b/include/openssl/err.h index 2abf248348..b987e31f8c 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -496,6 +496,13 @@ int ERR_get_next_error_library(void); int ERR_set_mark(void); int ERR_pop_to_mark(void); int ERR_clear_last_mark(void); +int ERR_count_to_mark(void); + +ERR_STATE *OSSL_ERR_STATE_new(void); +void OSSL_ERR_STATE_save(ERR_STATE *es); +void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es); +void OSSL_ERR_STATE_restore(const ERR_STATE *es); +void OSSL_ERR_STATE_free(ERR_STATE *es); #ifdef __cplusplus } diff --git a/include/openssl/err.h.in b/include/openssl/err.h.in index 11dc21637f..1ef09de02e 100644 --- a/include/openssl/err.h.in +++ b/include/openssl/err.h.in @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -485,6 +485,13 @@ int ERR_get_next_error_library(void); int ERR_set_mark(void); int ERR_pop_to_mark(void); int ERR_clear_last_mark(void); +int ERR_count_to_mark(void); + +ERR_STATE *OSSL_ERR_STATE_new(void); +void OSSL_ERR_STATE_save(ERR_STATE *es); +void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es); +void OSSL_ERR_STATE_restore(const ERR_STATE *es); +void OSSL_ERR_STATE_free(ERR_STATE *es); #ifdef __cplusplus } diff --git a/include/openssl/evp.h b/include/openssl/evp.h index d0fce0c5d5..ea7620d631 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -35,6 +35,7 @@ # define EVP_MAX_KEY_LENGTH 64 # define EVP_MAX_IV_LENGTH 16 # define EVP_MAX_BLOCK_LENGTH 32 +# define EVP_MAX_AEAD_TAG_LENGTH 16 # define PKCS5_SALT_LEN 8 /* Default PKCS#5 iteration count */ @@ -228,7 +229,8 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, * if the following flag is set. */ # define EVP_MD_CTX_FLAG_FINALISE 0x0200 -/* NOTE: 0x0400 is reserved for internal usage */ +/* NOTE: 0x0400 and 0x0800 are reserved for internal usage */ + # ifndef OPENSSL_NO_DEPRECATED_3_0 OSSL_DEPRECATEDIN_3_0 EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); @@ -308,6 +310,7 @@ OSSL_DEPRECATEDIN_3_0 int # define EVP_CIPH_WRAP_MODE 0x10002 # define EVP_CIPH_OCB_MODE 0x10003 # define EVP_CIPH_SIV_MODE 0x10004 +# define EVP_CIPH_GCM_SIV_MODE 0x10005 # define EVP_CIPH_MODE 0xF0007 /* Set if variable length cipher */ # define EVP_CIPH_VARIABLE_LENGTH 0x8 @@ -674,7 +677,7 @@ void BIO_set_md(BIO *, const EVP_MD *md); # define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) # define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(c_pp)) -/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c, +__owur int EVP_Cipher(EVP_CIPHER_CTX *c, unsigned char *out, const unsigned char *in, unsigned int inl); @@ -752,7 +755,7 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); __owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv); -/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, +__owur int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv); @@ -760,16 +763,16 @@ __owur int EVP_EncryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, const OSSL_PARAM params[]); -/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, +__owur int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); -/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, +__owur int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); -/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, +__owur int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); __owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv); -/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, +__owur int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv); @@ -777,17 +780,17 @@ __owur int EVP_DecryptInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, const OSSL_PARAM params[]); -/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, +__owur int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); __owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); -/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, +__owur int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); __owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc); -/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, +__owur int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); @@ -821,18 +824,18 @@ __owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); -int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, +__owur int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, OSSL_LIB_CTX *libctx, const char *props, EVP_PKEY *pkey, const OSSL_PARAM params[]); -/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, +__owur int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); -int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize); +__owur int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize); __owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); -int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, +__owur int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const char *mdname, OSSL_LIB_CTX *libctx, const char *props, EVP_PKEY *pkey, const OSSL_PARAM params[]); @@ -1927,14 +1930,17 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); +int EVP_PKEY_auth_encapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpriv, + const OSSL_PARAM params[]); int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, unsigned char *wrappedkey, size_t *wrappedkeylen, unsigned char *genkey, size_t *genkeylen); int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); +int EVP_PKEY_auth_decapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpub, + const OSSL_PARAM params[]); int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, unsigned char *unwrapped, size_t *unwrappedlen, const unsigned char *wrapped, size_t wrappedlen); - typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); int EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx); diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index a5053f6cd2..11f3faa459 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -110,11 +110,14 @@ # define EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH 216 # define EVP_R_UNABLE_TO_LOCK_CONTEXT 211 # define EVP_R_UNABLE_TO_SET_CALLBACKS 217 +# define EVP_R_UNKNOWN_BITS 166 # define EVP_R_UNKNOWN_CIPHER 160 # define EVP_R_UNKNOWN_DIGEST 161 # define EVP_R_UNKNOWN_KEY_TYPE 207 +# define EVP_R_UNKNOWN_MAX_SIZE 167 # define EVP_R_UNKNOWN_OPTION 169 # define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNKNOWN_SECURITY_BITS 168 # define EVP_R_UNSUPPORTED_ALGORITHM 156 # define EVP_R_UNSUPPORTED_CIPHER 107 # define EVP_R_UNSUPPORTED_KEYLENGTH 123 diff --git a/include/openssl/hpke.h b/include/openssl/hpke.h new file mode 100644 index 0000000000..af637ac61a --- /dev/null +++ b/include/openssl/hpke.h @@ -0,0 +1,169 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* APIs and data structures for HPKE (RFC9180) */ +#ifndef OSSL_HPKE_H +# define OSSL_HPKE_H +# pragma once + +# include + +/* HPKE modes */ +# define OSSL_HPKE_MODE_BASE 0 /* Base mode */ +# define OSSL_HPKE_MODE_PSK 1 /* Pre-shared key mode */ +# define OSSL_HPKE_MODE_AUTH 2 /* Authenticated mode */ +# define OSSL_HPKE_MODE_PSKAUTH 3 /* PSK+authenticated mode */ + +/* + * Max for ikm, psk, pskid, info and exporter contexts. + * RFC9180, section 7.2.1 RECOMMENDS 64 octets but we have test vectors from + * Appendix A.6.1 with a 66 octet IKM so we'll allow that. + */ +# define OSSL_HPKE_MAX_PARMLEN 66 +# define OSSL_HPKE_MIN_PSKLEN 32 +# define OSSL_HPKE_MAX_INFOLEN 1024 + +/* + * The (16bit) HPKE algorithm ID IANA codepoints + * If/when new IANA codepoints are added there are tables in + * crypto/hpke/hpke_util.c that must also be updated. + */ +# define OSSL_HPKE_KEM_ID_RESERVED 0x0000 /* not used */ +# define OSSL_HPKE_KEM_ID_P256 0x0010 /* NIST P-256 */ +# define OSSL_HPKE_KEM_ID_P384 0x0011 /* NIST P-384 */ +# define OSSL_HPKE_KEM_ID_P521 0x0012 /* NIST P-521 */ +# define OSSL_HPKE_KEM_ID_X25519 0x0020 /* Curve25519 */ +# define OSSL_HPKE_KEM_ID_X448 0x0021 /* Curve448 */ + +# define OSSL_HPKE_KDF_ID_RESERVED 0x0000 /* not used */ +# define OSSL_HPKE_KDF_ID_HKDF_SHA256 0x0001 /* HKDF-SHA256 */ +# define OSSL_HPKE_KDF_ID_HKDF_SHA384 0x0002 /* HKDF-SHA384 */ +# define OSSL_HPKE_KDF_ID_HKDF_SHA512 0x0003 /* HKDF-SHA512 */ + +# define OSSL_HPKE_AEAD_ID_RESERVED 0x0000 /* not used */ +# define OSSL_HPKE_AEAD_ID_AES_GCM_128 0x0001 /* AES-GCM-128 */ +# define OSSL_HPKE_AEAD_ID_AES_GCM_256 0x0002 /* AES-GCM-256 */ +# define OSSL_HPKE_AEAD_ID_CHACHA_POLY1305 0x0003 /* Chacha20-Poly1305 */ +# define OSSL_HPKE_AEAD_ID_EXPORTONLY 0xFFFF /* export-only fake ID */ + +/* strings for suite components */ +# define OSSL_HPKE_KEMSTR_P256 "P-256" /* KEM id 0x10 */ +# define OSSL_HPKE_KEMSTR_P384 "P-384" /* KEM id 0x11 */ +# define OSSL_HPKE_KEMSTR_P521 "P-521" /* KEM id 0x12 */ +# define OSSL_HPKE_KEMSTR_X25519 "X25519" /* KEM id 0x20 */ +# define OSSL_HPKE_KEMSTR_X448 "X448" /* KEM id 0x21 */ +# define OSSL_HPKE_KDFSTR_256 "hkdf-sha256" /* KDF id 1 */ +# define OSSL_HPKE_KDFSTR_384 "hkdf-sha384" /* KDF id 2 */ +# define OSSL_HPKE_KDFSTR_512 "hkdf-sha512" /* KDF id 3 */ +# define OSSL_HPKE_AEADSTR_AES128GCM "aes-128-gcm" /* AEAD id 1 */ +# define OSSL_HPKE_AEADSTR_AES256GCM "aes-256-gcm" /* AEAD id 2 */ +# define OSSL_HPKE_AEADSTR_CP "chacha20-poly1305" /* AEAD id 3 */ +# define OSSL_HPKE_AEADSTR_EXP "exporter" /* AEAD id 0xff */ + +/* + * Roles for use in creating an OSSL_HPKE_CTX, most + * important use of this is to control nonce re-use. + */ +# define OSSL_HPKE_ROLE_SENDER 0 +# define OSSL_HPKE_ROLE_RECEIVER 1 + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct { + uint16_t kem_id; /* Key Encapsulation Method id */ + uint16_t kdf_id; /* Key Derivation Function id */ + uint16_t aead_id; /* AEAD alg id */ +} OSSL_HPKE_SUITE; + +/** + * Suite constants, use this like: + * OSSL_HPKE_SUITE myvar = OSSL_HPKE_SUITE_DEFAULT; + */ +# ifndef OPENSSL_NO_ECX +# define OSSL_HPKE_SUITE_DEFAULT \ + {\ + OSSL_HPKE_KEM_ID_X25519, \ + OSSL_HPKE_KDF_ID_HKDF_SHA256, \ + OSSL_HPKE_AEAD_ID_AES_GCM_128 \ + } +# else +# define OSSL_HPKE_SUITE_DEFAULT \ + {\ + OSSL_HPKE_KEM_ID_P256, \ + OSSL_HPKE_KDF_ID_HKDF_SHA256, \ + OSSL_HPKE_AEAD_ID_AES_GCM_128 \ + } +#endif + +typedef struct ossl_hpke_ctx_st OSSL_HPKE_CTX; + +OSSL_HPKE_CTX *OSSL_HPKE_CTX_new(int mode, OSSL_HPKE_SUITE suite, int role, + OSSL_LIB_CTX *libctx, const char *propq); +void OSSL_HPKE_CTX_free(OSSL_HPKE_CTX *ctx); + +int OSSL_HPKE_encap(OSSL_HPKE_CTX *ctx, + unsigned char *enc, size_t *enclen, + const unsigned char *pub, size_t publen, + const unsigned char *info, size_t infolen); +int OSSL_HPKE_seal(OSSL_HPKE_CTX *ctx, + unsigned char *ct, size_t *ctlen, + const unsigned char *aad, size_t aadlen, + const unsigned char *pt, size_t ptlen); + +int OSSL_HPKE_keygen(OSSL_HPKE_SUITE suite, + unsigned char *pub, size_t *publen, EVP_PKEY **priv, + const unsigned char *ikm, size_t ikmlen, + OSSL_LIB_CTX *libctx, const char *propq); +int OSSL_HPKE_decap(OSSL_HPKE_CTX *ctx, + const unsigned char *enc, size_t enclen, + EVP_PKEY *recippriv, + const unsigned char *info, size_t infolen); +int OSSL_HPKE_open(OSSL_HPKE_CTX *ctx, + unsigned char *pt, size_t *ptlen, + const unsigned char *aad, size_t aadlen, + const unsigned char *ct, size_t ctlen); + +int OSSL_HPKE_export(OSSL_HPKE_CTX *ctx, + unsigned char *secret, + size_t secretlen, + const unsigned char *label, + size_t labellen); + +int OSSL_HPKE_CTX_set1_authpriv(OSSL_HPKE_CTX *ctx, EVP_PKEY *priv); +int OSSL_HPKE_CTX_set1_authpub(OSSL_HPKE_CTX *ctx, + const unsigned char *pub, + size_t publen); +int OSSL_HPKE_CTX_set1_psk(OSSL_HPKE_CTX *ctx, + const char *pskid, + const unsigned char *psk, size_t psklen); + +int OSSL_HPKE_CTX_set1_ikme(OSSL_HPKE_CTX *ctx, + const unsigned char *ikme, size_t ikmelen); + +int OSSL_HPKE_CTX_set_seq(OSSL_HPKE_CTX *ctx, uint64_t seq); +int OSSL_HPKE_CTX_get_seq(OSSL_HPKE_CTX *ctx, uint64_t *seq); + +int OSSL_HPKE_suite_check(OSSL_HPKE_SUITE suite); +int OSSL_HPKE_get_grease_value(const OSSL_HPKE_SUITE *suite_in, + OSSL_HPKE_SUITE *suite, + unsigned char *enc, size_t *enclen, + unsigned char *ct, size_t ctlen, + OSSL_LIB_CTX *libctx, const char *propq); +int OSSL_HPKE_str2suite(const char *str, OSSL_HPKE_SUITE *suite); +size_t OSSL_HPKE_get_ciphertext_size(OSSL_HPKE_SUITE suite, size_t clearlen); +size_t OSSL_HPKE_get_public_encap_size(OSSL_HPKE_SUITE suite); +size_t OSSL_HPKE_get_recommended_ikmelen(OSSL_HPKE_SUITE suite); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/http.h b/include/openssl/http.h index f7ab214265..a3cbf15f5a 100644 --- a/include/openssl/http.h +++ b/include/openssl/http.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2018-2020 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -33,6 +33,8 @@ extern "C" { # define OPENSSL_HTTP_PROXY "HTTP_PROXY" # define OPENSSL_HTTPS_PROXY "HTTPS_PROXY" +# ifndef OPENSSL_NO_HTTP + #define OSSL_HTTP_DEFAULT_MAX_LINE_LEN (4 * 1024) #define OSSL_HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024) @@ -103,6 +105,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, const char *OSSL_HTTP_adapt_proxy(const char *proxy, const char *no_proxy, const char *server, int use_ssl); + +# endif /* !defined(OPENSSL_NO_HTTP) */ # ifdef __cplusplus } # endif diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h index f4155df18a..8af9edd24a 100644 --- a/include/openssl/lhash.h +++ b/include/openssl/lhash.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/lhash.h.in b/include/openssl/lhash.h.in index dc344a5480..c9dbd1f3fc 100644 --- a/include/openssl/lhash.h.in +++ b/include/openssl/lhash.h.in @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/macros.h b/include/openssl/macros.h index a614cd66e3..e9ef938747 100644 --- a/include/openssl/macros.h +++ b/include/openssl/macros.h @@ -158,7 +158,7 @@ /* * Define macros for deprecation and simulated removal purposes. * - * The macros OSSL_DEPRECATED_{major}_{minor} are always defined for + * The macros OSSL_DEPRECATEDIN_{major}_{minor} are always defined for * all OpenSSL versions we care for. They can be used as attributes * in function declarations where appropriate. * @@ -169,6 +169,7 @@ * 'no-deprecated'. */ +# undef OPENSSL_NO_DEPRECATED_3_1 # undef OPENSSL_NO_DEPRECATED_3_0 # undef OPENSSL_NO_DEPRECATED_1_1_1 # undef OPENSSL_NO_DEPRECATED_1_1_0 diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 0e86027667..e1b441b313 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/objects.pl * - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at @@ -886,6 +886,14 @@ #define NID_id_ct_signedChecklist 1247 #define OBJ_id_ct_signedChecklist OBJ_id_smime_ct,48L +#define SN_id_ct_ASPA "id-ct-ASPA" +#define NID_id_ct_ASPA 1250 +#define OBJ_id_ct_ASPA OBJ_id_smime_ct,49L + +#define SN_id_ct_signedTAL "id-ct-signedTAL" +#define NID_id_ct_signedTAL 1284 +#define OBJ_id_ct_signedTAL OBJ_id_smime_ct,50L + #define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" #define NID_id_smime_aa_receiptRequest 212 #define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L @@ -1002,10 +1010,22 @@ #define NID_id_smime_aa_dvcs_dvc 240 #define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L +#define SN_id_aa_ets_attrCertificateRefs "id-aa-ets-attrCertificateRefs" +#define NID_id_aa_ets_attrCertificateRefs 1261 +#define OBJ_id_aa_ets_attrCertificateRefs OBJ_id_smime_aa,44L + +#define SN_id_aa_ets_attrRevocationRefs "id-aa-ets-attrRevocationRefs" +#define NID_id_aa_ets_attrRevocationRefs 1262 +#define OBJ_id_aa_ets_attrRevocationRefs OBJ_id_smime_aa,45L + #define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" #define NID_id_smime_aa_signingCertificateV2 1086 #define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L +#define SN_id_aa_ets_archiveTimestampV2 "id-aa-ets-archiveTimestampV2" +#define NID_id_aa_ets_archiveTimestampV2 1280 +#define OBJ_id_aa_ets_archiveTimestampV2 OBJ_id_smime_aa,48L + #define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" #define NID_id_smime_alg_ESDHwith3DES 241 #define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L @@ -1082,15 +1102,17 @@ #define NID_localKeyID 157 #define OBJ_localKeyID OBJ_pkcs9,21L +#define OBJ_ms_corp 1L,3L,6L,1L,4L,1L,311L + #define SN_ms_csp_name "CSPName" #define LN_ms_csp_name "Microsoft CSP Name" #define NID_ms_csp_name 417 -#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L +#define OBJ_ms_csp_name OBJ_ms_corp,17L,1L #define SN_LocalKeySet "LocalKeySet" #define LN_LocalKeySet "Microsoft Local Key set" #define NID_LocalKeySet 856 -#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L +#define OBJ_LocalKeySet OBJ_ms_corp,17L,2L #define OBJ_certTypes OBJ_pkcs9,22L @@ -1108,6 +1130,10 @@ #define NID_x509Crl 160 #define OBJ_x509Crl OBJ_crlTypes,1L +#define SN_id_aa_CMSAlgorithmProtection "id-aa-CMSAlgorithmProtection" +#define NID_id_aa_CMSAlgorithmProtection 1263 +#define OBJ_id_aa_CMSAlgorithmProtection OBJ_pkcs9,52L + #define OBJ_pkcs12 OBJ_pkcs,12L #define OBJ_pkcs12_pbeids OBJ_pkcs12,1L @@ -1217,6 +1243,10 @@ #define NID_SM2_with_SM3 1204 #define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L +#define LN_hmacWithSM3 "hmacWithSM3" +#define NID_hmacWithSM3 1281 +#define OBJ_hmacWithSM3 OBJ_sm3,3L,1L + #define LN_hmacWithSHA224 "hmacWithSHA224" #define NID_hmacWithSHA224 798 #define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L @@ -1300,42 +1330,62 @@ #define SN_ms_ext_req "msExtReq" #define LN_ms_ext_req "Microsoft Extension Request" #define NID_ms_ext_req 171 -#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L +#define OBJ_ms_ext_req OBJ_ms_corp,2L,1L,14L #define SN_ms_code_ind "msCodeInd" #define LN_ms_code_ind "Microsoft Individual Code Signing" #define NID_ms_code_ind 134 -#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L +#define OBJ_ms_code_ind OBJ_ms_corp,2L,1L,21L #define SN_ms_code_com "msCodeCom" #define LN_ms_code_com "Microsoft Commercial Code Signing" #define NID_ms_code_com 135 -#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L +#define OBJ_ms_code_com OBJ_ms_corp,2L,1L,22L #define SN_ms_ctl_sign "msCTLSign" #define LN_ms_ctl_sign "Microsoft Trust List Signing" #define NID_ms_ctl_sign 136 -#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L +#define OBJ_ms_ctl_sign OBJ_ms_corp,10L,3L,1L #define SN_ms_sgc "msSGC" #define LN_ms_sgc "Microsoft Server Gated Crypto" #define NID_ms_sgc 137 -#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L +#define OBJ_ms_sgc OBJ_ms_corp,10L,3L,3L #define SN_ms_efs "msEFS" #define LN_ms_efs "Microsoft Encrypted File System" #define NID_ms_efs 138 -#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L +#define OBJ_ms_efs OBJ_ms_corp,10L,3L,4L #define SN_ms_smartcard_login "msSmartcardLogin" #define LN_ms_smartcard_login "Microsoft Smartcard Login" #define NID_ms_smartcard_login 648 -#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L +#define OBJ_ms_smartcard_login OBJ_ms_corp,20L,2L,2L #define SN_ms_upn "msUPN" #define LN_ms_upn "Microsoft User Principal Name" #define NID_ms_upn 649 -#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L +#define OBJ_ms_upn OBJ_ms_corp,20L,2L,3L + +#define SN_ms_ntds_sec_ext "ms-ntds-sec-ext" +#define LN_ms_ntds_sec_ext "Microsoft NTDS CA Extension" +#define NID_ms_ntds_sec_ext 1292 +#define OBJ_ms_ntds_sec_ext OBJ_ms_corp,25L,2L + +#define SN_ms_ntds_obj_sid "ms-ntds-obj-sid" +#define LN_ms_ntds_obj_sid "Microsoft NTDS AD objectSid" +#define NID_ms_ntds_obj_sid 1291 +#define OBJ_ms_ntds_obj_sid OBJ_ms_corp,25L,2L,1L + +#define SN_ms_cert_templ "ms-cert-templ" +#define LN_ms_cert_templ "Microsoft certificate template" +#define NID_ms_cert_templ 1293 +#define OBJ_ms_cert_templ OBJ_ms_corp,21L,7L + +#define SN_ms_app_policies "ms-app-policies" +#define LN_ms_app_policies "Microsoft Application Policies Extension" +#define NID_ms_app_policies 1294 +#define OBJ_ms_app_policies OBJ_ms_corp,21L,10L #define SN_idea_cbc "IDEA-CBC" #define LN_idea_cbc "idea-cbc" @@ -1503,6 +1553,18 @@ #define NID_id_mod_cmp2000 284 #define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L +#define SN_id_mod_cmp2000_02 "id-mod-cmp2000-02" +#define NID_id_mod_cmp2000_02 1251 +#define OBJ_id_mod_cmp2000_02 OBJ_id_pkix_mod,50L + +#define SN_id_mod_cmp2021_88 "id-mod-cmp2021-88" +#define NID_id_mod_cmp2021_88 1252 +#define OBJ_id_mod_cmp2021_88 OBJ_id_pkix_mod,99L + +#define SN_id_mod_cmp2021_02 "id-mod-cmp2021-02" +#define NID_id_mod_cmp2021_02 1253 +#define OBJ_id_mod_cmp2021_02 OBJ_id_pkix_mod,100L + #define SN_info_access "authorityInfoAccess" #define LN_info_access "Authority Information Access" #define NID_info_access 177 @@ -1783,6 +1845,22 @@ #define NID_id_it_certReqTemplate 1225 #define OBJ_id_it_certReqTemplate OBJ_id_it,19L +#define SN_id_it_rootCaCert "id-it-rootCaCert" +#define NID_id_it_rootCaCert 1254 +#define OBJ_id_it_rootCaCert OBJ_id_it,20L + +#define SN_id_it_certProfile "id-it-certProfile" +#define NID_id_it_certProfile 1255 +#define OBJ_id_it_certProfile OBJ_id_it,21L + +#define SN_id_it_crlStatusList "id-it-crlStatusList" +#define NID_id_it_crlStatusList 1256 +#define OBJ_id_it_crlStatusList OBJ_id_it,22L + +#define SN_id_it_crls "id-it-crls" +#define NID_id_it_crls 1257 +#define OBJ_id_it_crls OBJ_id_it,23L + #define SN_id_regCtrl "id-regCtrl" #define NID_id_regCtrl 313 #define OBJ_id_regCtrl OBJ_id_pkip,1L @@ -1815,6 +1893,18 @@ #define NID_id_regCtrl_protocolEncrKey 320 #define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L +#define SN_id_regCtrl_altCertTemplate "id-regCtrl-altCertTemplate" +#define NID_id_regCtrl_altCertTemplate 1258 +#define OBJ_id_regCtrl_altCertTemplate OBJ_id_regCtrl,7L + +#define SN_id_regCtrl_algId "id-regCtrl-algId" +#define NID_id_regCtrl_algId 1259 +#define OBJ_id_regCtrl_algId OBJ_id_regCtrl,11L + +#define SN_id_regCtrl_rsaKeyLen "id-regCtrl-rsaKeyLen" +#define NID_id_regCtrl_rsaKeyLen 1260 +#define OBJ_id_regCtrl_rsaKeyLen OBJ_id_regCtrl,12L + #define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" #define NID_id_regInfo_utf8Pairs 321 #define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L @@ -2649,11 +2739,56 @@ #define NID_ext_key_usage 126 #define OBJ_ext_key_usage OBJ_id_ce,37L +#define SN_authority_attribute_identifier "authorityAttributeIdentifier" +#define LN_authority_attribute_identifier "X509v3 Authority Attribute Identifier" +#define NID_authority_attribute_identifier 1295 +#define OBJ_authority_attribute_identifier OBJ_id_ce,38L + +#define SN_role_spec_cert_identifier "roleSpecCertIdentifier" +#define LN_role_spec_cert_identifier "X509v3 Role Specification Certificate Identifier" +#define NID_role_spec_cert_identifier 1296 +#define OBJ_role_spec_cert_identifier OBJ_id_ce,39L + +#define SN_basic_att_constraints "basicAttConstraints" +#define LN_basic_att_constraints "X509v3 Basic Attribute Certificate Constraints" +#define NID_basic_att_constraints 1297 +#define OBJ_basic_att_constraints OBJ_id_ce,41L + +#define SN_delegated_name_constraints "delegatedNameConstraints" +#define LN_delegated_name_constraints "X509v3 Delegated Name Constraints" +#define NID_delegated_name_constraints 1298 +#define OBJ_delegated_name_constraints OBJ_id_ce,42L + +#define SN_time_specification "timeSpecification" +#define LN_time_specification "X509v3 Time Specification" +#define NID_time_specification 1299 +#define OBJ_time_specification OBJ_id_ce,43L + #define SN_freshest_crl "freshestCRL" #define LN_freshest_crl "X509v3 Freshest CRL" #define NID_freshest_crl 857 #define OBJ_freshest_crl OBJ_id_ce,46L +#define SN_attribute_descriptor "attributeDescriptor" +#define LN_attribute_descriptor "X509v3 Attribute Descriptor" +#define NID_attribute_descriptor 1300 +#define OBJ_attribute_descriptor OBJ_id_ce,48L + +#define SN_user_notice "userNotice" +#define LN_user_notice "X509v3 User Notice" +#define NID_user_notice 1301 +#define OBJ_user_notice OBJ_id_ce,49L + +#define SN_soa_identifier "sOAIdentifier" +#define LN_soa_identifier "X509v3 Source of Authority Identifier" +#define NID_soa_identifier 1302 +#define OBJ_soa_identifier OBJ_id_ce,50L + +#define SN_acceptable_cert_policies "acceptableCertPolicies" +#define LN_acceptable_cert_policies "X509v3 Acceptable Certification Policies" +#define NID_acceptable_cert_policies 1303 +#define OBJ_acceptable_cert_policies OBJ_id_ce,52L + #define SN_inhibit_any_policy "inhibitAnyPolicy" #define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" #define NID_inhibit_any_policy 748 @@ -2669,6 +2804,86 @@ #define NID_no_rev_avail 403 #define OBJ_no_rev_avail OBJ_id_ce,56L +#define SN_acceptable_privilege_policies "acceptablePrivPolicies" +#define LN_acceptable_privilege_policies "X509v3 Acceptable Privilege Policies" +#define NID_acceptable_privilege_policies 1304 +#define OBJ_acceptable_privilege_policies OBJ_id_ce,57L + +#define SN_indirect_issuer "indirectIssuer" +#define LN_indirect_issuer "X509v3 Indirect Issuer" +#define NID_indirect_issuer 1305 +#define OBJ_indirect_issuer OBJ_id_ce,61L + +#define SN_no_assertion "noAssertion" +#define LN_no_assertion "X509v3 No Assertion" +#define NID_no_assertion 1306 +#define OBJ_no_assertion OBJ_id_ce,62L + +#define SN_id_aa_issuing_distribution_point "aAissuingDistributionPoint" +#define LN_id_aa_issuing_distribution_point "X509v3 Attribute Authority Issuing Distribution Point" +#define NID_id_aa_issuing_distribution_point 1307 +#define OBJ_id_aa_issuing_distribution_point OBJ_id_ce,63L + +#define SN_issued_on_behalf_of "issuedOnBehalfOf" +#define LN_issued_on_behalf_of "X509v3 Issued On Behalf Of" +#define NID_issued_on_behalf_of 1308 +#define OBJ_issued_on_behalf_of OBJ_id_ce,64L + +#define SN_single_use "singleUse" +#define LN_single_use "X509v3 Single Use" +#define NID_single_use 1309 +#define OBJ_single_use OBJ_id_ce,65L + +#define SN_group_ac "groupAC" +#define LN_group_ac "X509v3 Group Attribute Certificate" +#define NID_group_ac 1310 +#define OBJ_group_ac OBJ_id_ce,66L + +#define SN_allowed_attribute_assignments "allowedAttributeAssignments" +#define LN_allowed_attribute_assignments "X509v3 Allowed Attribute Assignments" +#define NID_allowed_attribute_assignments 1311 +#define OBJ_allowed_attribute_assignments OBJ_id_ce,67L + +#define SN_attribute_mappings "attributeMappings" +#define LN_attribute_mappings "X509v3 Attribute Mappings" +#define NID_attribute_mappings 1312 +#define OBJ_attribute_mappings OBJ_id_ce,68L + +#define SN_holder_name_constraints "holderNameConstraints" +#define LN_holder_name_constraints "X509v3 Holder Name Constraints" +#define NID_holder_name_constraints 1313 +#define OBJ_holder_name_constraints OBJ_id_ce,69L + +#define SN_authorization_validation "authorizationValidation" +#define LN_authorization_validation "X509v3 Authorization Validation" +#define NID_authorization_validation 1314 +#define OBJ_authorization_validation OBJ_id_ce,70L + +#define SN_prot_restrict "protRestrict" +#define LN_prot_restrict "X509v3 Protocol Restriction" +#define NID_prot_restrict 1315 +#define OBJ_prot_restrict OBJ_id_ce,71L + +#define SN_subject_alt_public_key_info "subjectAltPublicKeyInfo" +#define LN_subject_alt_public_key_info "X509v3 Subject Alternative Public Key Info" +#define NID_subject_alt_public_key_info 1316 +#define OBJ_subject_alt_public_key_info OBJ_id_ce,72L + +#define SN_alt_signature_algorithm "altSignatureAlgorithm" +#define LN_alt_signature_algorithm "X509v3 Alternative Signature Algorithm" +#define NID_alt_signature_algorithm 1317 +#define OBJ_alt_signature_algorithm OBJ_id_ce,73L + +#define SN_alt_signature_value "altSignatureValue" +#define LN_alt_signature_value "X509v3 Alternative Signature Value" +#define NID_alt_signature_value 1318 +#define OBJ_alt_signature_value OBJ_id_ce,74L + +#define SN_associated_information "associatedInformation" +#define LN_associated_information "X509v3 Associated Information" +#define NID_associated_information 1319 +#define OBJ_associated_information OBJ_id_ce,75L + #define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" #define LN_anyExtendedKeyUsage "Any Extended Key Usage" #define NID_anyExtendedKeyUsage 910 @@ -3220,6 +3435,70 @@ #define NID_hold_instruction_reject 433 #define OBJ_hold_instruction_reject OBJ_holdInstruction,3L +#define SN_itu_t_identified_organization "itu-t-identified-organization" +#define NID_itu_t_identified_organization 1264 +#define OBJ_itu_t_identified_organization OBJ_itu_t,4L + +#define SN_etsi "etsi" +#define NID_etsi 1265 +#define OBJ_etsi OBJ_itu_t_identified_organization,0L + +#define SN_electronic_signature_standard "electronic-signature-standard" +#define NID_electronic_signature_standard 1266 +#define OBJ_electronic_signature_standard OBJ_etsi,1733L + +#define SN_ess_attributes "ess-attributes" +#define NID_ess_attributes 1267 +#define OBJ_ess_attributes OBJ_electronic_signature_standard,2L + +#define SN_id_aa_ets_mimeType "id-aa-ets-mimeType" +#define NID_id_aa_ets_mimeType 1268 +#define OBJ_id_aa_ets_mimeType OBJ_ess_attributes,1L + +#define SN_id_aa_ets_longTermValidation "id-aa-ets-longTermValidation" +#define NID_id_aa_ets_longTermValidation 1269 +#define OBJ_id_aa_ets_longTermValidation OBJ_ess_attributes,2L + +#define SN_id_aa_ets_SignaturePolicyDocument "id-aa-ets-SignaturePolicyDocument" +#define NID_id_aa_ets_SignaturePolicyDocument 1270 +#define OBJ_id_aa_ets_SignaturePolicyDocument OBJ_ess_attributes,3L + +#define SN_id_aa_ets_archiveTimestampV3 "id-aa-ets-archiveTimestampV3" +#define NID_id_aa_ets_archiveTimestampV3 1271 +#define OBJ_id_aa_ets_archiveTimestampV3 OBJ_ess_attributes,4L + +#define SN_id_aa_ATSHashIndex "id-aa-ATSHashIndex" +#define NID_id_aa_ATSHashIndex 1272 +#define OBJ_id_aa_ATSHashIndex OBJ_ess_attributes,5L + +#define SN_cades "cades" +#define NID_cades 1273 +#define OBJ_cades OBJ_etsi,19122L + +#define SN_cades_attributes "cades-attributes" +#define NID_cades_attributes 1274 +#define OBJ_cades_attributes OBJ_cades,1L + +#define SN_id_aa_ets_signerAttrV2 "id-aa-ets-signerAttrV2" +#define NID_id_aa_ets_signerAttrV2 1275 +#define OBJ_id_aa_ets_signerAttrV2 OBJ_cades_attributes,1L + +#define SN_id_aa_ets_sigPolicyStore "id-aa-ets-sigPolicyStore" +#define NID_id_aa_ets_sigPolicyStore 1276 +#define OBJ_id_aa_ets_sigPolicyStore OBJ_cades_attributes,3L + +#define SN_id_aa_ATSHashIndex_v2 "id-aa-ATSHashIndex-v2" +#define NID_id_aa_ATSHashIndex_v2 1277 +#define OBJ_id_aa_ATSHashIndex_v2 OBJ_cades_attributes,4L + +#define SN_id_aa_ATSHashIndex_v3 "id-aa-ATSHashIndex-v3" +#define NID_id_aa_ATSHashIndex_v3 1278 +#define OBJ_id_aa_ATSHashIndex_v3 OBJ_cades_attributes,5L + +#define SN_signedAssertion "signedAssertion" +#define NID_signedAssertion 1279 +#define OBJ_signedAssertion OBJ_cades_attributes,6L + #define SN_data "data" #define NID_data 434 #define OBJ_data OBJ_itu_t,9L @@ -4952,6 +5231,21 @@ #define NID_sm4_ctr 1139 #define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L +#define SN_sm4_gcm "SM4-GCM" +#define LN_sm4_gcm "sm4-gcm" +#define NID_sm4_gcm 1248 +#define OBJ_sm4_gcm OBJ_sm_scheme,104L,8L + +#define SN_sm4_ccm "SM4-CCM" +#define LN_sm4_ccm "sm4-ccm" +#define NID_sm4_ccm 1249 +#define OBJ_sm4_ccm OBJ_sm_scheme,104L,9L + +#define SN_sm4_xts "SM4-XTS" +#define LN_sm4_xts "sm4-xts" +#define NID_sm4_xts 1290 +#define OBJ_sm4_xts OBJ_sm_scheme,104L,10L + #define SN_hmac "HMAC" #define LN_hmac "hmac" #define NID_hmac 855 @@ -5029,6 +5323,9 @@ #define NID_brainpoolP256r1 927 #define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L +#define SN_brainpoolP256r1tls13 "brainpoolP256r1tls13" +#define NID_brainpoolP256r1tls13 1285 + #define SN_brainpoolP256t1 "brainpoolP256t1" #define NID_brainpoolP256t1 928 #define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L @@ -5045,6 +5342,9 @@ #define NID_brainpoolP384r1 931 #define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L +#define SN_brainpoolP384r1tls13 "brainpoolP384r1tls13" +#define NID_brainpoolP384r1tls13 1286 + #define SN_brainpoolP384t1 "brainpoolP384t1" #define NID_brainpoolP384t1 932 #define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L @@ -5053,6 +5353,9 @@ #define NID_brainpoolP512r1 933 #define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L +#define SN_brainpoolP512r1tls13 "brainpoolP512r1tls13" +#define NID_brainpoolP512r1tls13 1287 + #define SN_brainpoolP512t1 "brainpoolP512t1" #define NID_brainpoolP512t1 934 #define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L @@ -5130,17 +5433,17 @@ #define SN_jurisdictionLocalityName "jurisdictionL" #define LN_jurisdictionLocalityName "jurisdictionLocalityName" #define NID_jurisdictionLocalityName 955 -#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L +#define OBJ_jurisdictionLocalityName OBJ_ms_corp,60L,2L,1L,1L #define SN_jurisdictionStateOrProvinceName "jurisdictionST" #define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" #define NID_jurisdictionStateOrProvinceName 956 -#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L +#define OBJ_jurisdictionStateOrProvinceName OBJ_ms_corp,60L,2L,1L,2L #define SN_jurisdictionCountryName "jurisdictionC" #define LN_jurisdictionCountryName "jurisdictionCountryName" #define NID_jurisdictionCountryName 957 -#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L +#define OBJ_jurisdictionCountryName OBJ_ms_corp,60L,2L,1L,3L #define SN_id_scrypt "id-scrypt" #define LN_id_scrypt "scrypt" @@ -5432,6 +5735,24 @@ #define LN_aes_256_siv "aes-256-siv" #define NID_aes_256_siv 1200 +#define SN_oracle "oracle-organization" +#define LN_oracle "Oracle organization" +#define NID_oracle 1282 +#define OBJ_oracle OBJ_joint_iso_itu_t,16L,840L,1L,113894L + +#define SN_oracle_jdk_trustedkeyusage "oracle-jdk-trustedkeyusage" +#define LN_oracle_jdk_trustedkeyusage "Trusted key usage (Oracle)" +#define NID_oracle_jdk_trustedkeyusage 1283 +#define OBJ_oracle_jdk_trustedkeyusage OBJ_oracle,746875L,1L,1L + +#define SN_brotli "brotli" +#define LN_brotli "Brotli compression" +#define NID_brotli 1288 + +#define SN_zstd "zstd" +#define LN_zstd "Zstandard compression" +#define NID_zstd 1289 + #endif /* OPENSSL_OBJ_MAC_H */ #ifndef OPENSSL_NO_DEPRECATED_3_0 diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index b87a4aa1e3..7f1ecf6689 100644 --- a/include/openssl/opensslv.h +++ b/include/openssl/opensslv.h @@ -28,8 +28,8 @@ extern "C" { * These macros express version number MAJOR.MINOR.PATCH exactly */ # define OPENSSL_VERSION_MAJOR 3 -# define OPENSSL_VERSION_MINOR 1 -# define OPENSSL_VERSION_PATCH 4 +# define OPENSSL_VERSION_MINOR 2 +# define OPENSSL_VERSION_PATCH 0 /* * Additional version information @@ -74,21 +74,21 @@ extern "C" { * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and * OPENSSL_VERSION_BUILD_METADATA_STR appended. */ -# define OPENSSL_VERSION_STR "3.1.4" -# define OPENSSL_FULL_VERSION_STR "3.1.4" +# define OPENSSL_VERSION_STR "3.2.0" +# define OPENSSL_FULL_VERSION_STR "3.2.0" /* * SECTION 3: ADDITIONAL METADATA * * These strings are defined separately to allow them to be parsable. */ -# define OPENSSL_RELEASE_DATE "24 Oct 2023" +# define OPENSSL_RELEASE_DATE "23 Nov 2023" /* * SECTION 4: BACKWARD COMPATIBILITY */ -# define OPENSSL_VERSION_TEXT "OpenSSL 3.1.4 24 Oct 2023" +# define OPENSSL_VERSION_TEXT "OpenSSL 3.2.0 23 Nov 2023" /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */ # ifdef OPENSSL_VERSION_PRE_RELEASE diff --git a/include/openssl/pem.h b/include/openssl/pem.h index 000d9c89c3..0446c77019 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -57,6 +57,7 @@ extern "C" { # define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" # define PEM_STRING_PARAMETERS "PARAMETERS" # define PEM_STRING_CMS "CMS" +# define PEM_STRING_SM2PARAMETERS "SM2 PARAMETERS" # define PEM_TYPE_ENCRYPTED 10 # define PEM_TYPE_MIC_ONLY 20 diff --git a/include/openssl/pkcs12.h b/include/openssl/pkcs12.h index 9e20fc1aef..b08b0bc214 100644 --- a/include/openssl/pkcs12.h +++ b/include/openssl/pkcs12.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/pkcs12.h.in * - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -44,6 +44,7 @@ extern "C" { # define PKCS12_MAC_KEY_LENGTH 20 +/* The macro is expected to be used only internally. Kept for backwards compatibility. */ # define PKCS12_SALT_LEN 8 /* It's not clear if these are actually needed... */ @@ -133,7 +134,9 @@ int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag); const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag); +X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libctx, const char *propq); X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libctx, const char *propq); X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); const STACK_OF(PKCS12_SAFEBAG) * PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); @@ -221,6 +224,7 @@ ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); const STACK_OF(X509_ATTRIBUTE) * PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, STACK_OF(X509_ATTRIBUTE) *attrs); unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, int passlen, const unsigned char *in, int inlen, @@ -308,6 +312,7 @@ DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) void PKCS12_PBE_add(void); int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); +typedef int PKCS12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg); PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype); @@ -315,6 +320,11 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype, OSSL_LIB_CTX *ctx, const char *propq); +PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg); PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, diff --git a/include/openssl/pkcs12.h.in b/include/openssl/pkcs12.h.in index cf956b418a..35759d4dea 100644 --- a/include/openssl/pkcs12.h.in +++ b/include/openssl/pkcs12.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,6 +45,7 @@ extern "C" { # define PKCS12_MAC_KEY_LENGTH 20 +/* The macro is expected to be used only internally. Kept for backwards compatibility. */ # define PKCS12_SALT_LEN 8 /* It's not clear if these are actually needed... */ @@ -110,7 +111,9 @@ int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag); const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag); +X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libctx, const char *propq); X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libctx, const char *propq); X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); const STACK_OF(PKCS12_SAFEBAG) * PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); @@ -198,6 +201,7 @@ ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); const STACK_OF(X509_ATTRIBUTE) * PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +void PKCS12_SAFEBAG_set0_attrs(PKCS12_SAFEBAG *bag, STACK_OF(X509_ATTRIBUTE) *attrs); unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, int passlen, const unsigned char *in, int inlen, @@ -285,6 +289,7 @@ DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) void PKCS12_PBE_add(void); int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); +typedef int PKCS12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg); PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype); @@ -292,6 +297,11 @@ PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter, int keytype, OSSL_LIB_CTX *ctx, const char *propq); +PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype, + OSSL_LIB_CTX *ctx, const char *propq, + PKCS12_create_cb *cb, void *cbarg); PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, diff --git a/include/openssl/pkcs12err.h b/include/openssl/pkcs12err.h index 933c83299a..abce373628 100644 --- a/include/openssl/pkcs12err.h +++ b/include/openssl/pkcs12err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,6 +21,7 @@ /* * PKCS12 reason codes. */ +# define PKCS12_R_CALLBACK_FAILED 115 # define PKCS12_R_CANT_PACK_STRUCTURE 100 # define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 # define PKCS12_R_DECODE_ERROR 101 diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index f824546c96..dc46c51118 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h @@ -134,8 +134,8 @@ SKM_DEFINE_STACK_OF_INTERNAL(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO, PKCS7_RECIP_INF typedef struct pkcs7_signed_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; struct pkcs7_st *contents; } PKCS7_SIGNED; @@ -161,8 +161,8 @@ typedef struct pkcs7_enveloped_st { typedef struct pkcs7_signedandenveloped_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; PKCS7_ENC_CONTENT *enc_data; STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; @@ -203,7 +203,7 @@ typedef struct pkcs7_st { /* NID_pkcs7_data */ ASN1_OCTET_STRING *data; /* NID_pkcs7_signed */ - PKCS7_SIGNED *sign; + PKCS7_SIGNED *sign; /* field name 'signed' would clash with C keyword */ /* NID_pkcs7_enveloped */ PKCS7_ENVELOPE *enveloped; /* NID_pkcs7_signedAndEnveloped */ @@ -344,13 +344,13 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst); int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); -int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); -int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_add_certificate(PKCS7 *p7, X509 *cert); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl); int PKCS7_content_new(PKCS7 *p7, int nid); int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509); + X509 *signer); BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); diff --git a/include/openssl/pkcs7.h.in b/include/openssl/pkcs7.h.in index a346bc74a8..11a636e1ec 100644 --- a/include/openssl/pkcs7.h.in +++ b/include/openssl/pkcs7.h.in @@ -87,8 +87,8 @@ typedef struct pkcs7_recip_info_st { typedef struct pkcs7_signed_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; struct pkcs7_st *contents; } PKCS7_SIGNED; @@ -114,8 +114,8 @@ typedef struct pkcs7_enveloped_st { typedef struct pkcs7_signedandenveloped_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; PKCS7_ENC_CONTENT *enc_data; STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; @@ -156,7 +156,7 @@ typedef struct pkcs7_st { /* NID_pkcs7_data */ ASN1_OCTET_STRING *data; /* NID_pkcs7_signed */ - PKCS7_SIGNED *sign; + PKCS7_SIGNED *sign; /* field name 'signed' would clash with C keyword */ /* NID_pkcs7_enveloped */ PKCS7_ENVELOPE *enveloped; /* NID_pkcs7_signedAndEnveloped */ @@ -273,13 +273,13 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst); int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); -int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); -int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_add_certificate(PKCS7 *p7, X509 *cert); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl); int PKCS7_content_new(PKCS7 *p7, int nid); int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509); + X509 *signer); BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); diff --git a/include/openssl/prov_ssl.h b/include/openssl/prov_ssl.h index d3e0896c8e..76d01e1eb8 100644 --- a/include/openssl/prov_ssl.h +++ b/include/openssl/prov_ssl.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,6 +19,7 @@ extern "C" { # define SSL_MAX_MASTER_KEY_LENGTH 48 +/* SSL/TLS uses a 2 byte unsigned version number */ # define SSL3_VERSION 0x0300 # define TLS1_VERSION 0x0301 # define TLS1_1_VERSION 0x0302 @@ -28,6 +29,9 @@ extern "C" { # define DTLS1_2_VERSION 0xFEFD # define DTLS1_BAD_VER 0x0100 +/* QUIC uses a 4 byte unsigned version number */ +# define OSSL_QUIC1_VERSION 0x0000001 + # ifdef __cplusplus } # endif diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h index 5d5c16d9dc..d9ef56815c 100644 --- a/include/openssl/proverr.h +++ b/include/openssl/proverr.h @@ -52,6 +52,7 @@ # define PROV_R_INDICATOR_INTEGRITY_FAILURE 210 # define PROV_R_INSUFFICIENT_DRBG_STRENGTH 181 # define PROV_R_INVALID_AAD 108 +# define PROV_R_INVALID_AEAD 231 # define PROV_R_INVALID_CONFIG_DATA 211 # define PROV_R_INVALID_CONSTANT_LENGTH 157 # define PROV_R_INVALID_CURVE 176 @@ -63,9 +64,11 @@ # define PROV_R_INVALID_INPUT_LENGTH 230 # define PROV_R_INVALID_ITERATION_COUNT 123 # define PROV_R_INVALID_IV_LENGTH 109 +# define PROV_R_INVALID_KDF 232 # define PROV_R_INVALID_KEY 158 # define PROV_R_INVALID_KEY_LENGTH 105 # define PROV_R_INVALID_MAC 151 +# define PROV_R_INVALID_MEMORY_SIZE 235 # define PROV_R_INVALID_MGF1_MD 167 # define PROV_R_INVALID_MODE 125 # define PROV_R_INVALID_OUTPUT_LENGTH 217 @@ -77,6 +80,7 @@ # define PROV_R_INVALID_STATE 212 # define PROV_R_INVALID_TAG 110 # define PROV_R_INVALID_TAG_LENGTH 118 +# define PROV_R_INVALID_THREAD_POOL_SIZE 234 # define PROV_R_INVALID_UKM_LENGTH 200 # define PROV_R_INVALID_X931_DIGEST 170 # define PROV_R_IN_ERROR_STATE 192 diff --git a/include/openssl/provider.h b/include/openssl/provider.h index dc86ff5878..24ec0827bd 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,13 +17,19 @@ extern "C" { # endif -/* Set the default provider search path */ +/* Set and Get a library context search path */ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *, const char *path); +const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx); /* Load and unload a provider */ OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params); OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *, const char *name, int retain_fallbacks); +OSSL_PROVIDER *OSSL_PROVIDER_try_load_ex(OSSL_LIB_CTX *, const char *name, + OSSL_PARAM *params, + int retain_fallbacks); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OSSL_LIB_CTX *, const char *name); int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, diff --git a/include/openssl/quic.h b/include/openssl/quic.h new file mode 100644 index 0000000000..74a6345d5d --- /dev/null +++ b/include/openssl/quic.h @@ -0,0 +1,37 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_QUIC_H +# define OPENSSL_QUIC_H +# pragma once + +# include +# include + +# ifndef OPENSSL_NO_QUIC + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * Method used for non-thread-assisted QUIC client operation. + */ +__owur const SSL_METHOD *OSSL_QUIC_client_method(void); +/* + * Method used for thread-assisted QUIC client operation. + */ +__owur const SSL_METHOD *OSSL_QUIC_client_thread_method(void); + +# ifdef __cplusplus +} +# endif + +# endif /* OPENSSL_NO_QUIC */ +#endif diff --git a/include/openssl/rand.h b/include/openssl/rand.h index 90e0f0a031..1fa1129e3c 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index d0c9599274..167427d3c4 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -189,6 +189,8 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label); # define EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_RSA_IMPLICIT_REJECTION (EVP_PKEY_ALG_CTRL + 14) + # define RSA_PKCS1_PADDING 1 # define RSA_NO_PADDING 3 # define RSA_PKCS1_OAEP_PADDING 4 @@ -198,6 +200,9 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label); # define RSA_PKCS1_PSS_PADDING 6 # define RSA_PKCS1_WITH_TLS_PADDING 7 +/* internal RSA_ only */ +# define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8 + # define RSA_PKCS1_PADDING_SIZE 11 # define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) diff --git a/include/openssl/sha.h b/include/openssl/sha.h index 6e65a04089..163a7d588a 100644 --- a/include/openssl/sha.h +++ b/include/openssl/sha.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -81,6 +81,7 @@ OSSL_DEPRECATEDIN_3_0 void SHA256_Transform(SHA256_CTX *c, unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +# define SHA256_192_DIGEST_LENGTH 24 # define SHA224_DIGEST_LENGTH 28 # define SHA256_DIGEST_LENGTH 32 # define SHA384_DIGEST_LENGTH 48 diff --git a/include/openssl/srtp.h b/include/openssl/srtp.h index d64606e5d9..2c2c334443 100644 --- a/include/openssl/srtp.h +++ b/include/openssl/srtp.h @@ -28,16 +28,28 @@ extern "C" { #endif -# define SRTP_AES128_CM_SHA1_80 0x0001 -# define SRTP_AES128_CM_SHA1_32 0x0002 -# define SRTP_AES128_F8_SHA1_80 0x0003 -# define SRTP_AES128_F8_SHA1_32 0x0004 -# define SRTP_NULL_SHA1_80 0x0005 -# define SRTP_NULL_SHA1_32 0x0006 +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 /* AEAD SRTP protection profiles from RFC 7714 */ -# define SRTP_AEAD_AES_128_GCM 0x0007 -# define SRTP_AEAD_AES_256_GCM 0x0008 +# define SRTP_AEAD_AES_128_GCM 0x0007 +# define SRTP_AEAD_AES_256_GCM 0x0008 + +/* DOUBLE AEAD SRTP protection profiles from RFC 8723 */ +# define SRTP_DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM 0x0009 +# define SRTP_DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM 0x000A + +/* ARIA SRTP protection profiles from RFC 8269 */ +# define SRTP_ARIA_128_CTR_HMAC_SHA1_80 0x000B +# define SRTP_ARIA_128_CTR_HMAC_SHA1_32 0x000C +# define SRTP_ARIA_256_CTR_HMAC_SHA1_80 0x000D +# define SRTP_ARIA_256_CTR_HMAC_SHA1_32 0x000E +# define SRTP_AEAD_ARIA_128_GCM 0x000F +# define SRTP_AEAD_ARIA_256_GCM 0x0010 # ifndef OPENSSL_NO_SRTP diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 942f20e61c..2b43485f72 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/ssl.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -24,6 +24,7 @@ # endif # include +# include # include # include # include @@ -281,28 +282,31 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, /* Extension context codes */ /* This extension is only allowed in TLS */ -#define SSL_EXT_TLS_ONLY 0x0001 +#define SSL_EXT_TLS_ONLY 0x00001 /* This extension is only allowed in DTLS */ -#define SSL_EXT_DTLS_ONLY 0x0002 +#define SSL_EXT_DTLS_ONLY 0x00002 /* Some extensions may be allowed in DTLS but we don't implement them for it */ -#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x00004 /* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ -#define SSL_EXT_SSL3_ALLOWED 0x0008 +#define SSL_EXT_SSL3_ALLOWED 0x00008 /* Extension is only defined for TLS1.2 and below */ -#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x00010 /* Extension is only defined for TLS1.3 and above */ -#define SSL_EXT_TLS1_3_ONLY 0x0020 +#define SSL_EXT_TLS1_3_ONLY 0x00020 /* Ignore this extension during parsing if we are resuming */ -#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 -#define SSL_EXT_CLIENT_HELLO 0x0080 +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x00040 +#define SSL_EXT_CLIENT_HELLO 0x00080 /* Really means TLS1.2 or below */ -#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 -#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 -#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 -#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 -#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 -#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 -#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x00100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x00200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x00400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x00800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x01000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x02000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x04000 +#define SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION 0x08000 +/* When sending a raw public key in a certificate message */ +#define SSL_EXT_TLS1_3_RAW_PUBLIC_KEY 0x10000 /* Typedefs for handling custom extensions */ @@ -433,6 +437,17 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); * interoperability with CryptoPro CSP 3.x */ # define SSL_OP_CRYPTOPRO_TLSEXT_BUG SSL_OP_BIT(31) +/* + * Disable RFC8879 certificate compression + * SSL_OP_NO_TX_CERTIFICATE_COMPRESSION: don't send compressed certificates, + * and ignore the extension when received. + * SSL_OP_NO_RX_CERTIFICATE_COMPRESSION: don't send the extension, and + * subsequently indicating that receiving is not supported + */ +# define SSL_OP_NO_TX_CERTIFICATE_COMPRESSION SSL_OP_BIT(32) +# define SSL_OP_NO_RX_CERTIFICATE_COMPRESSION SSL_OP_BIT(33) + /* Enable KTLS TX zerocopy on Linux */ +# define SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE SSL_OP_BIT(34) /* * Option "collections." @@ -577,6 +592,8 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); # define CERT_PKEY_CERT_TYPE 0x400 /* Cert chain suitable to Suite B */ # define CERT_PKEY_SUITEB 0x800 +/* Cert pkey valid for raw public key use */ +# define CERT_PKEY_RPK 0x1000 # define SSL_CONF_FLAG_CMDLINE 0x1 # define SSL_CONF_FLAG_FILE 0x2 @@ -968,6 +985,7 @@ uint32_t SSL_get_recv_max_early_data(const SSL *s); # include /* This is mostly sslv3 with a few tweaks */ # include /* Datagram TLS */ # include /* Support for the use_srtp extension */ +# include #ifdef __cplusplus extern "C" { @@ -1069,6 +1087,7 @@ typedef enum { DTLS_ST_CR_HELLO_VERIFY_REQUEST, TLS_ST_CR_SRVR_HELLO, TLS_ST_CR_CERT, + TLS_ST_CR_COMP_CERT, TLS_ST_CR_CERT_STATUS, TLS_ST_CR_KEY_EXCH, TLS_ST_CR_CERT_REQ, @@ -1078,6 +1097,7 @@ typedef enum { TLS_ST_CR_FINISHED, TLS_ST_CW_CLNT_HELLO, TLS_ST_CW_CERT, + TLS_ST_CW_COMP_CERT, TLS_ST_CW_KEY_EXCH, TLS_ST_CW_CERT_VRFY, TLS_ST_CW_CHANGE, @@ -1088,10 +1108,12 @@ typedef enum { DTLS_ST_SW_HELLO_VERIFY_REQUEST, TLS_ST_SW_SRVR_HELLO, TLS_ST_SW_CERT, + TLS_ST_SW_COMP_CERT, TLS_ST_SW_KEY_EXCH, TLS_ST_SW_CERT_REQ, TLS_ST_SW_SRVR_DONE, TLS_ST_SR_CERT, + TLS_ST_SR_COMP_CERT, TLS_ST_SR_KEY_EXCH, TLS_ST_SR_CERT_VRFY, TLS_ST_SR_NEXT_PROTO, @@ -1383,6 +1405,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_CTRL_GET_SIGNATURE_NID 132 # define SSL_CTRL_GET_TMP_KEY 133 # define SSL_CTRL_GET_NEGOTIATED_GROUP 134 +# define SSL_CTRL_GET_IANA_GROUPS 135 # define SSL_CTRL_SET_RETRY_VERIFY 136 # define SSL_CTRL_GET_VERIFY_CERT_STORE 137 # define SSL_CTRL_GET_CHAIN_CERT_STORE 138 @@ -1488,6 +1511,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_get1_groups(s, glist) \ SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_get0_iana_groups(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_IANA_GROUPS,0,(uint16_t **)(plst)) # define SSL_CTX_set1_groups(ctx, glist, glistlen) \ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(int *)(glist)) # define SSL_CTX_set1_groups_list(ctx, s) \ @@ -1552,6 +1577,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_get_max_proto_version(s) \ SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +const char *SSL_get0_group_name(SSL *s); const char *SSL_group_to_name(SSL *s, int id); /* Backwards compatibility, original 1.1.0 names */ @@ -1786,6 +1812,9 @@ __owur int SSL_has_matching_session_id(const SSL *s, unsigned int id_len); SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length); +SSL_SESSION *d2i_SSL_SESSION_ex(SSL_SESSION **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, + const char *propq); # ifdef OPENSSL_X509_H __owur X509 *SSL_get0_peer_certificate(const SSL *s); @@ -1843,6 +1872,8 @@ __owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, SSL *SSL_new(SSL_CTX *ctx); int SSL_up_ref(SSL *s); int SSL_is_dtls(const SSL *s); +int SSL_is_tls(const SSL *s); +int SSL_is_quic(const SSL *s); __owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len); @@ -1935,6 +1966,8 @@ size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); size_t SSL_client_hello_get0_compression_methods(SSL *s, const unsigned char **out); int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, + size_t *num_exts); int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out, size_t *outlen); @@ -1989,6 +2022,7 @@ __owur int SSL_get_early_data_status(const SSL *s); __owur int SSL_get_error(const SSL *s, int ret_code); __owur const char *SSL_get_version(const SSL *s); +__owur int SSL_get_handshake_rtt(const SSL *s, uint64_t *rtt); /* This sets the 'default' SSL version that SSL_new() will create */ # ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -2297,6 +2331,105 @@ size_t SSL_get_num_tickets(const SSL *s); int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); +/* QUIC support */ +int SSL_handle_events(SSL *s); +__owur int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite); +__owur int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc); +__owur int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc); +__owur int SSL_net_read_desired(SSL *s); +__owur int SSL_net_write_desired(SSL *s); +__owur int SSL_set_blocking_mode(SSL *s, int blocking); +__owur int SSL_get_blocking_mode(SSL *s); +__owur int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr); +__owur SSL *SSL_get0_connection(SSL *s); +__owur int SSL_is_connection(SSL *s); + +#define SSL_STREAM_TYPE_NONE 0 +#define SSL_STREAM_TYPE_READ (1U << 0) +#define SSL_STREAM_TYPE_WRITE (1U << 1) +#define SSL_STREAM_TYPE_BIDI (SSL_STREAM_TYPE_READ | SSL_STREAM_TYPE_WRITE) +__owur int SSL_get_stream_type(SSL *s); + +__owur uint64_t SSL_get_stream_id(SSL *s); +__owur int SSL_is_stream_local(SSL *s); + +#define SSL_DEFAULT_STREAM_MODE_NONE 0 +#define SSL_DEFAULT_STREAM_MODE_AUTO_BIDI 1 +#define SSL_DEFAULT_STREAM_MODE_AUTO_UNI 2 +__owur int SSL_set_default_stream_mode(SSL *s, uint32_t mode); + +#define SSL_STREAM_FLAG_UNI (1U << 0) +#define SSL_STREAM_FLAG_NO_BLOCK (1U << 1) +#define SSL_STREAM_FLAG_ADVANCE (1U << 2) +__owur SSL *SSL_new_stream(SSL *s, uint64_t flags); + +#define SSL_INCOMING_STREAM_POLICY_AUTO 0 +#define SSL_INCOMING_STREAM_POLICY_ACCEPT 1 +#define SSL_INCOMING_STREAM_POLICY_REJECT 2 +__owur int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec); + +#define SSL_ACCEPT_STREAM_NO_BLOCK (1U << 0) +__owur SSL *SSL_accept_stream(SSL *s, uint64_t flags); +__owur size_t SSL_get_accept_stream_queue_len(SSL *s); + +# ifndef OPENSSL_NO_QUIC +__owur int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); +# endif + +typedef struct ssl_shutdown_ex_args_st { + uint64_t quic_error_code; + const char *quic_reason; +} SSL_SHUTDOWN_EX_ARGS; + +#define SSL_SHUTDOWN_FLAG_RAPID (1U << 0) +#define SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH (1U << 1) +#define SSL_SHUTDOWN_FLAG_NO_BLOCK (1U << 2) +#define SSL_SHUTDOWN_FLAG_WAIT_PEER (1U << 3) + +__owur int SSL_shutdown_ex(SSL *ssl, uint64_t flags, + const SSL_SHUTDOWN_EX_ARGS *args, + size_t args_len); + +__owur int SSL_stream_conclude(SSL *ssl, uint64_t flags); + +typedef struct ssl_stream_reset_args_st { + uint64_t quic_error_code; +} SSL_STREAM_RESET_ARGS; + +__owur int SSL_stream_reset(SSL *ssl, + const SSL_STREAM_RESET_ARGS *args, + size_t args_len); + +#define SSL_STREAM_STATE_NONE 0 +#define SSL_STREAM_STATE_OK 1 +#define SSL_STREAM_STATE_WRONG_DIR 2 +#define SSL_STREAM_STATE_FINISHED 3 +#define SSL_STREAM_STATE_RESET_LOCAL 4 +#define SSL_STREAM_STATE_RESET_REMOTE 5 +#define SSL_STREAM_STATE_CONN_CLOSED 6 +__owur int SSL_get_stream_read_state(SSL *ssl); +__owur int SSL_get_stream_write_state(SSL *ssl); + +__owur int SSL_get_stream_read_error_code(SSL *ssl, uint64_t *app_error_code); +__owur int SSL_get_stream_write_error_code(SSL *ssl, uint64_t *app_error_code); + +#define SSL_CONN_CLOSE_FLAG_LOCAL (1U << 0) +#define SSL_CONN_CLOSE_FLAG_TRANSPORT (1U << 1) + +typedef struct ssl_conn_close_info_st { + uint64_t error_code, frame_type; + const char *reason; + size_t reason_len; + uint32_t flags; +} SSL_CONN_CLOSE_INFO; + +__owur int SSL_get_conn_close_info(SSL *ssl, + SSL_CONN_CLOSE_INFO *info, + size_t info_len); + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define SSL_cache_hit(s) SSL_session_reused(s) # endif @@ -2596,6 +2729,36 @@ void SSL_set_allow_early_data_cb(SSL *s, const char *OSSL_default_cipher_list(void); const char *OSSL_default_ciphersuites(void); +/* RFC8879 Certificate compression APIs */ + +int SSL_CTX_compress_certs(SSL_CTX *ctx, int alg); +int SSL_compress_certs(SSL *ssl, int alg); + +int SSL_CTX_set1_cert_comp_preference(SSL_CTX *ctx, int *algs, size_t len); +int SSL_set1_cert_comp_preference(SSL *ssl, int *algs, size_t len); + +int SSL_CTX_set1_compressed_cert(SSL_CTX *ctx, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length); +int SSL_set1_compressed_cert(SSL *ssl, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length); +size_t SSL_CTX_get1_compressed_cert(SSL_CTX *ctx, int alg, unsigned char **data, size_t *orig_len); +size_t SSL_get1_compressed_cert(SSL *ssl, int alg, unsigned char **data, size_t *orig_len); + +__owur int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk); +__owur EVP_PKEY *SSL_get0_peer_rpk(const SSL *s); +__owur EVP_PKEY *SSL_SESSION_get0_peer_rpk(SSL_SESSION *s); +__owur int SSL_get_negotiated_client_cert_type(const SSL *s); +__owur int SSL_get_negotiated_server_cert_type(const SSL *s); + +__owur int SSL_set1_client_cert_type(SSL *s, const unsigned char *val, size_t len); +__owur int SSL_set1_server_cert_type(SSL *s, const unsigned char *val, size_t len); +__owur int SSL_CTX_set1_client_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len); +__owur int SSL_CTX_set1_server_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len); +__owur int SSL_get0_client_cert_type(const SSL *s, unsigned char **t, size_t *len); +__owur int SSL_get0_server_cert_type(const SSL *s, unsigned char **t, size_t *len); +__owur int SSL_CTX_get0_client_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len); +__owur int SSL_CTX_get0_server_cert_type(const SSL_CTX *s, unsigned char **t, size_t *len); + # ifdef __cplusplus } # endif diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index f03f52fbd8..9f91039f8a 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -25,6 +25,7 @@ use OpenSSL::stackhash qw(generate_stack_macros generate_const_stack_macros); # endif # include +# include # include # include # include @@ -258,28 +259,31 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, /* Extension context codes */ /* This extension is only allowed in TLS */ -#define SSL_EXT_TLS_ONLY 0x0001 +#define SSL_EXT_TLS_ONLY 0x00001 /* This extension is only allowed in DTLS */ -#define SSL_EXT_DTLS_ONLY 0x0002 +#define SSL_EXT_DTLS_ONLY 0x00002 /* Some extensions may be allowed in DTLS but we don't implement them for it */ -#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x00004 /* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ -#define SSL_EXT_SSL3_ALLOWED 0x0008 +#define SSL_EXT_SSL3_ALLOWED 0x00008 /* Extension is only defined for TLS1.2 and below */ -#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x00010 /* Extension is only defined for TLS1.3 and above */ -#define SSL_EXT_TLS1_3_ONLY 0x0020 +#define SSL_EXT_TLS1_3_ONLY 0x00020 /* Ignore this extension during parsing if we are resuming */ -#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 -#define SSL_EXT_CLIENT_HELLO 0x0080 +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x00040 +#define SSL_EXT_CLIENT_HELLO 0x00080 /* Really means TLS1.2 or below */ -#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 -#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 -#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 -#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 -#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 -#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 -#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x00100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x00200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x00400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x00800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x01000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x02000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x04000 +#define SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION 0x08000 +/* When sending a raw public key in a certificate message */ +#define SSL_EXT_TLS1_3_RAW_PUBLIC_KEY 0x10000 /* Typedefs for handling custom extensions */ @@ -410,6 +414,17 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); * interoperability with CryptoPro CSP 3.x */ # define SSL_OP_CRYPTOPRO_TLSEXT_BUG SSL_OP_BIT(31) +/* + * Disable RFC8879 certificate compression + * SSL_OP_NO_TX_CERTIFICATE_COMPRESSION: don't send compressed certificates, + * and ignore the extension when received. + * SSL_OP_NO_RX_CERTIFICATE_COMPRESSION: don't send the extension, and + * subsequently indicating that receiving is not supported + */ +# define SSL_OP_NO_TX_CERTIFICATE_COMPRESSION SSL_OP_BIT(32) +# define SSL_OP_NO_RX_CERTIFICATE_COMPRESSION SSL_OP_BIT(33) + /* Enable KTLS TX zerocopy on Linux */ +# define SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE SSL_OP_BIT(34) /* * Option "collections." @@ -554,6 +569,8 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); # define CERT_PKEY_CERT_TYPE 0x400 /* Cert chain suitable to Suite B */ # define CERT_PKEY_SUITEB 0x800 +/* Cert pkey valid for raw public key use */ +# define CERT_PKEY_RPK 0x1000 # define SSL_CONF_FLAG_CMDLINE 0x1 # define SSL_CONF_FLAG_FILE 0x2 @@ -945,6 +962,7 @@ uint32_t SSL_get_recv_max_early_data(const SSL *s); # include /* This is mostly sslv3 with a few tweaks */ # include /* Datagram TLS */ # include /* Support for the use_srtp extension */ +# include #ifdef __cplusplus extern "C" { @@ -997,6 +1015,7 @@ typedef enum { DTLS_ST_CR_HELLO_VERIFY_REQUEST, TLS_ST_CR_SRVR_HELLO, TLS_ST_CR_CERT, + TLS_ST_CR_COMP_CERT, TLS_ST_CR_CERT_STATUS, TLS_ST_CR_KEY_EXCH, TLS_ST_CR_CERT_REQ, @@ -1006,6 +1025,7 @@ typedef enum { TLS_ST_CR_FINISHED, TLS_ST_CW_CLNT_HELLO, TLS_ST_CW_CERT, + TLS_ST_CW_COMP_CERT, TLS_ST_CW_KEY_EXCH, TLS_ST_CW_CERT_VRFY, TLS_ST_CW_CHANGE, @@ -1016,10 +1036,12 @@ typedef enum { DTLS_ST_SW_HELLO_VERIFY_REQUEST, TLS_ST_SW_SRVR_HELLO, TLS_ST_SW_CERT, + TLS_ST_SW_COMP_CERT, TLS_ST_SW_KEY_EXCH, TLS_ST_SW_CERT_REQ, TLS_ST_SW_SRVR_DONE, TLS_ST_SR_CERT, + TLS_ST_SR_COMP_CERT, TLS_ST_SR_KEY_EXCH, TLS_ST_SR_CERT_VRFY, TLS_ST_SR_NEXT_PROTO, @@ -1311,6 +1333,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_CTRL_GET_SIGNATURE_NID 132 # define SSL_CTRL_GET_TMP_KEY 133 # define SSL_CTRL_GET_NEGOTIATED_GROUP 134 +# define SSL_CTRL_GET_IANA_GROUPS 135 # define SSL_CTRL_SET_RETRY_VERIFY 136 # define SSL_CTRL_GET_VERIFY_CERT_STORE 137 # define SSL_CTRL_GET_CHAIN_CERT_STORE 138 @@ -1416,6 +1439,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_get1_groups(s, glist) \ SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_get0_iana_groups(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_IANA_GROUPS,0,(uint16_t **)(plst)) # define SSL_CTX_set1_groups(ctx, glist, glistlen) \ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(int *)(glist)) # define SSL_CTX_set1_groups_list(ctx, s) \ @@ -1480,6 +1505,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # define SSL_get_max_proto_version(s) \ SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +const char *SSL_get0_group_name(SSL *s); const char *SSL_group_to_name(SSL *s, int id); /* Backwards compatibility, original 1.1.0 names */ @@ -1714,6 +1740,9 @@ __owur int SSL_has_matching_session_id(const SSL *s, unsigned int id_len); SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length); +SSL_SESSION *d2i_SSL_SESSION_ex(SSL_SESSION **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, + const char *propq); # ifdef OPENSSL_X509_H __owur X509 *SSL_get0_peer_certificate(const SSL *s); @@ -1771,6 +1800,8 @@ __owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, SSL *SSL_new(SSL_CTX *ctx); int SSL_up_ref(SSL *s); int SSL_is_dtls(const SSL *s); +int SSL_is_tls(const SSL *s); +int SSL_is_quic(const SSL *s); __owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len); @@ -1863,6 +1894,8 @@ size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); size_t SSL_client_hello_get0_compression_methods(SSL *s, const unsigned char **out); int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, + size_t *num_exts); int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out, size_t *outlen); @@ -1917,6 +1950,7 @@ __owur int SSL_get_early_data_status(const SSL *s); __owur int SSL_get_error(const SSL *s, int ret_code); __owur const char *SSL_get_version(const SSL *s); +__owur int SSL_get_handshake_rtt(const SSL *s, uint64_t *rtt); /* This sets the 'default' SSL version that SSL_new() will create */ # ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -2225,6 +2259,105 @@ size_t SSL_get_num_tickets(const SSL *s); int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); +/* QUIC support */ +int SSL_handle_events(SSL *s); +__owur int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite); +__owur int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc); +__owur int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc); +__owur int SSL_net_read_desired(SSL *s); +__owur int SSL_net_write_desired(SSL *s); +__owur int SSL_set_blocking_mode(SSL *s, int blocking); +__owur int SSL_get_blocking_mode(SSL *s); +__owur int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr); +__owur SSL *SSL_get0_connection(SSL *s); +__owur int SSL_is_connection(SSL *s); + +#define SSL_STREAM_TYPE_NONE 0 +#define SSL_STREAM_TYPE_READ (1U << 0) +#define SSL_STREAM_TYPE_WRITE (1U << 1) +#define SSL_STREAM_TYPE_BIDI (SSL_STREAM_TYPE_READ | SSL_STREAM_TYPE_WRITE) +__owur int SSL_get_stream_type(SSL *s); + +__owur uint64_t SSL_get_stream_id(SSL *s); +__owur int SSL_is_stream_local(SSL *s); + +#define SSL_DEFAULT_STREAM_MODE_NONE 0 +#define SSL_DEFAULT_STREAM_MODE_AUTO_BIDI 1 +#define SSL_DEFAULT_STREAM_MODE_AUTO_UNI 2 +__owur int SSL_set_default_stream_mode(SSL *s, uint32_t mode); + +#define SSL_STREAM_FLAG_UNI (1U << 0) +#define SSL_STREAM_FLAG_NO_BLOCK (1U << 1) +#define SSL_STREAM_FLAG_ADVANCE (1U << 2) +__owur SSL *SSL_new_stream(SSL *s, uint64_t flags); + +#define SSL_INCOMING_STREAM_POLICY_AUTO 0 +#define SSL_INCOMING_STREAM_POLICY_ACCEPT 1 +#define SSL_INCOMING_STREAM_POLICY_REJECT 2 +__owur int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec); + +#define SSL_ACCEPT_STREAM_NO_BLOCK (1U << 0) +__owur SSL *SSL_accept_stream(SSL *s, uint64_t flags); +__owur size_t SSL_get_accept_stream_queue_len(SSL *s); + +# ifndef OPENSSL_NO_QUIC +__owur int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); +# endif + +typedef struct ssl_shutdown_ex_args_st { + uint64_t quic_error_code; + const char *quic_reason; +} SSL_SHUTDOWN_EX_ARGS; + +#define SSL_SHUTDOWN_FLAG_RAPID (1U << 0) +#define SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH (1U << 1) +#define SSL_SHUTDOWN_FLAG_NO_BLOCK (1U << 2) +#define SSL_SHUTDOWN_FLAG_WAIT_PEER (1U << 3) + +__owur int SSL_shutdown_ex(SSL *ssl, uint64_t flags, + const SSL_SHUTDOWN_EX_ARGS *args, + size_t args_len); + +__owur int SSL_stream_conclude(SSL *ssl, uint64_t flags); + +typedef struct ssl_stream_reset_args_st { + uint64_t quic_error_code; +} SSL_STREAM_RESET_ARGS; + +__owur int SSL_stream_reset(SSL *ssl, + const SSL_STREAM_RESET_ARGS *args, + size_t args_len); + +#define SSL_STREAM_STATE_NONE 0 +#define SSL_STREAM_STATE_OK 1 +#define SSL_STREAM_STATE_WRONG_DIR 2 +#define SSL_STREAM_STATE_FINISHED 3 +#define SSL_STREAM_STATE_RESET_LOCAL 4 +#define SSL_STREAM_STATE_RESET_REMOTE 5 +#define SSL_STREAM_STATE_CONN_CLOSED 6 +__owur int SSL_get_stream_read_state(SSL *ssl); +__owur int SSL_get_stream_write_state(SSL *ssl); + +__owur int SSL_get_stream_read_error_code(SSL *ssl, uint64_t *app_error_code); +__owur int SSL_get_stream_write_error_code(SSL *ssl, uint64_t *app_error_code); + +#define SSL_CONN_CLOSE_FLAG_LOCAL (1U << 0) +#define SSL_CONN_CLOSE_FLAG_TRANSPORT (1U << 1) + +typedef struct ssl_conn_close_info_st { + uint64_t error_code, frame_type; + const char *reason; + size_t reason_len; + uint32_t flags; +} SSL_CONN_CLOSE_INFO; + +__owur int SSL_get_conn_close_info(SSL *ssl, + SSL_CONN_CLOSE_INFO *info, + size_t info_len); + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define SSL_cache_hit(s) SSL_session_reused(s) # endif @@ -2524,6 +2657,36 @@ void SSL_set_allow_early_data_cb(SSL *s, const char *OSSL_default_cipher_list(void); const char *OSSL_default_ciphersuites(void); +/* RFC8879 Certificate compression APIs */ + +int SSL_CTX_compress_certs(SSL_CTX *ctx, int alg); +int SSL_compress_certs(SSL *ssl, int alg); + +int SSL_CTX_set1_cert_comp_preference(SSL_CTX *ctx, int *algs, size_t len); +int SSL_set1_cert_comp_preference(SSL *ssl, int *algs, size_t len); + +int SSL_CTX_set1_compressed_cert(SSL_CTX *ctx, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length); +int SSL_set1_compressed_cert(SSL *ssl, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length); +size_t SSL_CTX_get1_compressed_cert(SSL_CTX *ctx, int alg, unsigned char **data, size_t *orig_len); +size_t SSL_get1_compressed_cert(SSL *ssl, int alg, unsigned char **data, size_t *orig_len); + +__owur int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk); +__owur EVP_PKEY *SSL_get0_peer_rpk(const SSL *s); +__owur EVP_PKEY *SSL_SESSION_get0_peer_rpk(SSL_SESSION *s); +__owur int SSL_get_negotiated_client_cert_type(const SSL *s); +__owur int SSL_get_negotiated_server_cert_type(const SSL *s); + +__owur int SSL_set1_client_cert_type(SSL *s, const unsigned char *val, size_t len); +__owur int SSL_set1_server_cert_type(SSL *s, const unsigned char *val, size_t len); +__owur int SSL_CTX_set1_client_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len); +__owur int SSL_CTX_set1_server_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len); +__owur int SSL_get0_client_cert_type(const SSL *s, unsigned char **t, size_t *len); +__owur int SSL_get0_server_cert_type(const SSL *s, unsigned char **t, size_t *len); +__owur int SSL_CTX_get0_client_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len); +__owur int SSL_CTX_get0_server_cert_type(const SSL_CTX *s, unsigned char **t, size_t *len); + # ifdef __cplusplus } # endif diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index 49bd51f24e..4f076c6c9d 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -239,6 +239,13 @@ extern "C" { # define SSL3_RT_HEADER 0x100 # define SSL3_RT_INNER_CONTENT_TYPE 0x101 +/* Pseudo content types for QUIC */ +# define SSL3_RT_QUIC_DATAGRAM 0x200 +# define SSL3_RT_QUIC_PACKET 0x201 +# define SSL3_RT_QUIC_FRAME_FULL 0x202 +# define SSL3_RT_QUIC_FRAME_HEADER 0x203 +# define SSL3_RT_QUIC_FRAME_PADDING 0x204 + # define SSL3_AL_WARNING 1 # define SSL3_AL_FATAL 2 @@ -300,6 +307,8 @@ extern "C" { /* Set if extended master secret extension required on renegotiation */ # define TLS1_FLAGS_REQUIRED_EXTMS 0x1000 +/* 0x2000 is reserved for TLS1_FLAGS_QUIC (internal) */ + # define SSL3_MT_HELLO_REQUEST 0 # define SSL3_MT_CLIENT_HELLO 1 # define SSL3_MT_SERVER_HELLO 2 @@ -317,6 +326,7 @@ extern "C" { # define SSL3_MT_CERTIFICATE_STATUS 22 # define SSL3_MT_SUPPLEMENTAL_DATA 23 # define SSL3_MT_KEY_UPDATE 24 +# define SSL3_MT_COMPRESSED_CERTIFICATE 25 # ifndef OPENSSL_NO_NEXTPROTONEG # define SSL3_MT_NEXT_PROTO 67 # endif diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index f1882558ba..e1eb9a5692 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,8 +25,10 @@ # define SSL_R_APP_DATA_IN_HANDSHAKE 100 # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 # define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 +# define SSL_R_BAD_CERTIFICATE 348 # define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 # define SSL_R_BAD_CIPHER 186 +# define SSL_R_BAD_COMPRESSION_ALGORITHM 326 # define SSL_R_BAD_DATA 390 # define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 # define SSL_R_BAD_DECOMPRESSION 107 @@ -82,6 +84,7 @@ # define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 # define SSL_R_COMPRESSION_LIBRARY_ERROR 142 # define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_CONN_USE_ONLY 356 # define SSL_R_CONTEXT_NOT_DANE_ENABLED 167 # define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400 # define SSL_R_COOKIE_MISMATCH 308 @@ -110,6 +113,7 @@ # define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 # define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 # define SSL_R_EE_KEY_TOO_SMALL 399 +# define SSL_R_EMPTY_RAW_PUBLIC_KEY 349 # define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 # define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 # define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 @@ -119,6 +123,7 @@ # define SSL_R_EXTENSION_NOT_RECEIVED 279 # define SSL_R_EXTRA_DATA_IN_MESSAGE 153 # define SSL_R_EXT_LENGTH_MISMATCH 163 +# define SSL_R_FAILED_TO_GET_PARAMETER 316 # define SSL_R_FAILED_TO_INIT_ASYNC 405 # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 @@ -144,6 +149,8 @@ # define SSL_R_INVALID_KEY_UPDATE_TYPE 120 # define SSL_R_INVALID_MAX_EARLY_DATA 174 # define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_RAW_PUBLIC_KEY 350 +# define SSL_R_INVALID_RECORD 317 # define SSL_R_INVALID_SEQUENCE_NUMBER 402 # define SSL_R_INVALID_SERVERINFO_DATA 388 # define SSL_R_INVALID_SESSION_ID 999 @@ -156,6 +163,7 @@ # define SSL_R_LENGTH_TOO_SHORT 160 # define SSL_R_LIBRARY_BUG 274 # define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED 395 # define SSL_R_MISSING_DSA_SIGNING_CERT 165 # define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 # define SSL_R_MISSING_FATAL 256 @@ -196,9 +204,11 @@ # define SSL_R_NO_SHARED_GROUPS 410 # define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 # define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_STREAM 355 # define SSL_R_NO_SUITABLE_DIGEST_ALGORITHM 297 # define SSL_R_NO_SUITABLE_GROUPS 295 # define SSL_R_NO_SUITABLE_KEY_SHARE 101 +# define SSL_R_NO_SUITABLE_RECORD_LAYER 322 # define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 # define SSL_R_NO_VALID_SCTS 216 # define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 @@ -221,10 +231,16 @@ # define SSL_R_PSK_IDENTITY_NOT_FOUND 223 # define SSL_R_PSK_NO_CLIENT_CB 224 # define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_QUIC_HANDSHAKE_LAYER_ERROR 393 +# define SSL_R_QUIC_NETWORK_ERROR 387 +# define SSL_R_QUIC_PROTOCOL_ERROR 382 # define SSL_R_READ_BIO_NOT_SET 211 # define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_RECORDS_NOT_RELEASED 321 +# define SSL_R_RECORD_LAYER_FAILURE 313 # define SSL_R_RECORD_LENGTH_MISMATCH 213 # define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_REMOTE_PEER_ADDRESS_NOT_SET 346 # define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 # define SSL_R_RENEGOTIATION_ENCODING_ERR 336 # define SSL_R_RENEGOTIATION_MISMATCH 337 @@ -234,6 +250,7 @@ # define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342 # define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 # define SSL_R_SCT_VERIFICATION_FAILED 208 +# define SSL_R_SEQUENCE_CTR_WRAPPED 327 # define SSL_R_SERVERHELLO_TLSEXT 275 # define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 # define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 @@ -273,6 +290,11 @@ # define SSL_R_SSL_SESSION_ID_TOO_LONG 408 # define SSL_R_SSL_SESSION_VERSION_MISMATCH 210 # define SSL_R_STILL_IN_INIT 121 +# define SSL_R_STREAM_COUNT_LIMITED 411 +# define SSL_R_STREAM_FINISHED 365 +# define SSL_R_STREAM_RECV_ONLY 366 +# define SSL_R_STREAM_RESET 375 +# define SSL_R_STREAM_SEND_ONLY 379 # define SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 # define SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109 # define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 @@ -316,6 +338,7 @@ # define SSL_R_UNKNOWN_COMMAND 139 # define SSL_R_UNKNOWN_DIGEST 368 # define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_MANDATORY_PARAMETER 323 # define SSL_R_UNKNOWN_PKEY_TYPE 251 # define SSL_R_UNKNOWN_PROTOCOL 252 # define SSL_R_UNKNOWN_SSL_VERSION 254 @@ -333,6 +356,7 @@ # define SSL_R_WRONG_CERTIFICATE_TYPE 383 # define SSL_R_WRONG_CIPHER_RETURNED 261 # define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_RPK_TYPE 351 # define SSL_R_WRONG_SIGNATURE_LENGTH 264 # define SSL_R_WRONG_SIGNATURE_SIZE 265 # define SSL_R_WRONG_SIGNATURE_TYPE 370 diff --git a/include/openssl/store.h b/include/openssl/store.h index 3c1445e0e6..e6ea3cf878 100644 --- a/include/openssl/store.h +++ b/include/openssl/store.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -98,6 +98,14 @@ OSSL_DEPRECATEDIN_3_0 int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, */ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); +/* + * Deletes the object in the store by URI. + * Returns 1 on success, 0 otherwise. + */ +int OSSL_STORE_delete(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + const OSSL_PARAM params[]); + /* * Check if end of data (end of file) is reached * Returns 1 on end, 0 otherwise. @@ -345,7 +353,7 @@ int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, OSSL_DEPRECATEDIN_3_0 const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); OSSL_DEPRECATEDIN_3_0 -const char * OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); +const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); OSSL_DEPRECATEDIN_3_0 int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); OSSL_DEPRECATEDIN_3_0 diff --git a/include/openssl/thread.h b/include/openssl/thread.h new file mode 100644 index 0000000000..3926ce54d7 --- /dev/null +++ b/include/openssl/thread.h @@ -0,0 +1,31 @@ +/* + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_THREAD_H +# define OPENSSL_THREAD_H + +# define OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL (1U<<0) +# define OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN (1U<<1) + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +uint32_t OSSL_get_thread_support_flags(void); +int OSSL_set_max_threads(OSSL_LIB_CTX *ctx, uint64_t max_threads); +uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx); + +# ifdef __cplusplus +} +# endif + +#endif /* OPENSSL_THREAD_H */ diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 793155e186..7e3d1a725b 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -28,7 +28,7 @@ extern "C" { /* Default security level if not overridden at config time */ # ifndef OPENSSL_TLS_SECURITY_LEVEL -# define OPENSSL_TLS_SECURITY_LEVEL 1 +# define OPENSSL_TLS_SECURITY_LEVEL 2 # endif /* TLS*_VERSION constants are defined in prov_ssl.h */ @@ -122,6 +122,14 @@ extern "C" { */ # define TLSEXT_TYPE_signed_certificate_timestamp 18 +/* + * Extension type for Raw Public Keys + * https://tools.ietf.org/html/rfc7250 + * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml + */ +# define TLSEXT_TYPE_client_cert_type 19 +# define TLSEXT_TYPE_server_cert_type 20 + /* * ExtensionType value for TLS padding extension. * http://tools.ietf.org/html/draft-agl-tls-padding @@ -134,6 +142,9 @@ extern "C" { /* ExtensionType value from RFC7627 */ # define TLSEXT_TYPE_extended_master_secret 23 +/* ExtensionType value from RFC8879 */ +# define TLSEXT_TYPE_compress_certificate 27 + /* ExtensionType value from RFC4507 */ # define TLSEXT_TYPE_session_ticket 35 @@ -147,6 +158,7 @@ extern "C" { # define TLSEXT_TYPE_post_handshake_auth 49 # define TLSEXT_TYPE_signature_algorithms_cert 50 # define TLSEXT_TYPE_key_share 51 +# define TLSEXT_TYPE_quic_transport_parameters 57 /* Temporary extension type */ # define TLSEXT_TYPE_renegotiate 0xff01 @@ -195,6 +207,15 @@ extern "C" { # define TLSEXT_hash_num 10 +/* Possible compression values from RFC8879 */ +/* Not defined in RFC8879, but used internally for no-compression */ +# define TLSEXT_comp_cert_none 0 +# define TLSEXT_comp_cert_zlib 1 +# define TLSEXT_comp_cert_brotli 2 +# define TLSEXT_comp_cert_zstd 3 +/* one more than the number of defined values - used as size of 0-terminated array */ +# define TLSEXT_comp_cert_limit 4 + /* Flag set for unrecognised algorithms */ # define TLSEXT_nid_unknown 0x1000000 @@ -211,6 +232,15 @@ extern "C" { # define TLSEXT_max_fragment_length_2048 3 # define TLSEXT_max_fragment_length_4096 4 +/* + * TLS Certificate Type (for RFC7250) + * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-3 + */ +# define TLSEXT_cert_type_x509 0 +# define TLSEXT_cert_type_pgp 1 /* recognized, but not supported */ +# define TLSEXT_cert_type_rpk 2 +# define TLSEXT_cert_type_1609dot2 3 /* recognized, but not supported */ + int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode); int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode); diff --git a/include/openssl/trace.h b/include/openssl/trace.h index 97e138576a..9a5b56ea5f 100644 --- a/include/openssl/trace.h +++ b/include/openssl/trace.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -305,6 +305,14 @@ void OSSL_trace_end(int category, BIO *channel); # define OSSL_TRACE9(category, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ OSSL_TRACEV(category, (trc_out, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)) +#define OSSL_TRACE_STRING_MAX 80 +int OSSL_trace_string(BIO *out, int text, int full, + const unsigned char *data, size_t size); +#define OSSL_TRACE_STRING(category, text, full, data, len) \ + OSSL_TRACE_BEGIN(category) { \ + OSSL_trace_string(trc_out, text, full, data, len); \ + } OSSL_TRACE_END(category) + # ifdef __cplusplus } # endif diff --git a/include/openssl/ts.h b/include/openssl/ts.h index 8ff6733233..b09b646dff 100644 --- a/include/openssl/ts.h +++ b/include/openssl/ts.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/types.h b/include/openssl/types.h index 5f9d8c23ea..c28028681f 100644 --- a/include/openssl/types.h +++ b/include/openssl/types.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 483cb9d5e6..ac1326330b 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/x509.h.in * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -606,6 +606,8 @@ EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); # endif @@ -654,6 +656,8 @@ EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); DECLARE_ASN1_DUP_FUNCTION(X509) @@ -887,7 +891,7 @@ int X509_REQ_get_signature_nid(const X509_REQ *req); int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); -EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req); X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); int X509_REQ_extension_nid(int nid); int *X509_REQ_get_extension_nids(void); @@ -953,13 +957,14 @@ X509_REVOKED_get0_extensions(const X509_REVOKED *r); X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); -int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); +int X509_REQ_check_private_key(const X509_REQ *req, EVP_PKEY *pkey); -int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_check_private_key(const X509 *cert, const EVP_PKEY *pkey); int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags); int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +void OSSL_STACK_OF_X509_free(STACK_OF(X509) *certs); STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); @@ -1265,6 +1270,8 @@ int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); +void X509_PUBKEY_set0_public_key(X509_PUBKEY *pub, + unsigned char *penc, int penclen); int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype, void *pval, unsigned char *penc, int penclen); diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in index d4df2adc57..7210391305 100644 --- a/include/openssl/x509.h.in +++ b/include/openssl/x509.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -412,6 +412,8 @@ EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); # endif @@ -460,6 +462,8 @@ EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); DECLARE_ASN1_DUP_FUNCTION(X509) @@ -693,7 +697,7 @@ int X509_REQ_get_signature_nid(const X509_REQ *req); int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); -EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req); X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); int X509_REQ_extension_nid(int nid); int *X509_REQ_get_extension_nids(void); @@ -759,13 +763,14 @@ X509_REVOKED_get0_extensions(const X509_REVOKED *r); X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); -int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); +int X509_REQ_check_private_key(const X509_REQ *req, EVP_PKEY *pkey); -int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_check_private_key(const X509 *cert, const EVP_PKEY *pkey); int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, unsigned long flags); int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +void OSSL_STACK_OF_X509_free(STACK_OF(X509) *certs); STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); @@ -1071,6 +1076,8 @@ int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len); +void X509_PUBKEY_set0_public_key(X509_PUBKEY *pub, + unsigned char *penc, int penclen); int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype, void *pval, unsigned char *penc, int penclen); diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 29b0e147ad..d3dfff8c0d 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by Makefile from include/openssl/x509_vfy.h.in * - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -411,6 +411,7 @@ X509_LOOKUP_ctrl_ex((x), X509_L_ADD_STORE, (name), 0, NULL, \ # define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92 # define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93 # define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94 +# define X509_V_ERR_RPK_UNTRUSTED 95 /* Certificate verify flags */ # ifndef OPENSSL_NO_DEPRECATED_1_1_0 @@ -491,71 +492,71 @@ int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a); int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); X509_STORE *X509_STORE_new(void); -void X509_STORE_free(X509_STORE *v); -int X509_STORE_lock(X509_STORE *ctx); -int X509_STORE_unlock(X509_STORE *ctx); -int X509_STORE_up_ref(X509_STORE *v); -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v); -STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *st); -STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, +void X509_STORE_free(X509_STORE *xs); +int X509_STORE_lock(X509_STORE *xs); +int X509_STORE_unlock(X509_STORE *xs); +int X509_STORE_up_ref(X509_STORE *xs); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs); +STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *xs); +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *xs, const X509_NAME *nm); STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *st, const X509_NAME *nm); -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); -int X509_STORE_set_trust(X509_STORE *ctx, int trust); -int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *pm); -X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx); +int X509_STORE_set_flags(X509_STORE *xs, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *xs, int purpose); +int X509_STORE_set_trust(X509_STORE *xs, int trust); +int X509_STORE_set1_param(X509_STORE *xs, const X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *xs); -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +void X509_STORE_set_verify(X509_STORE *xs, X509_STORE_CTX_verify_fn verify); #define X509_STORE_set_verify_func(ctx, func) \ X509_STORE_set_verify((ctx),(func)) void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, X509_STORE_CTX_verify_fn verify); -X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx); -void X509_STORE_set_verify_cb(X509_STORE *ctx, +X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *xs); +void X509_STORE_set_verify_cb(X509_STORE *xs, X509_STORE_CTX_verify_cb verify_cb); # define X509_STORE_set_verify_cb_func(ctx,func) \ X509_STORE_set_verify_cb((ctx),(func)) -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx); -void X509_STORE_set_get_issuer(X509_STORE *ctx, +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *xs); +void X509_STORE_set_get_issuer(X509_STORE *xs, X509_STORE_CTX_get_issuer_fn get_issuer); -X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx); -void X509_STORE_set_check_issued(X509_STORE *ctx, +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *xs); +void X509_STORE_set_check_issued(X509_STORE *xs, X509_STORE_CTX_check_issued_fn check_issued); -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx); -void X509_STORE_set_check_revocation(X509_STORE *ctx, +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *s); +void X509_STORE_set_check_revocation(X509_STORE *xs, X509_STORE_CTX_check_revocation_fn check_revocation); X509_STORE_CTX_check_revocation_fn - X509_STORE_get_check_revocation(const X509_STORE *ctx); -void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_get_check_revocation(const X509_STORE *xs); +void X509_STORE_set_get_crl(X509_STORE *xs, X509_STORE_CTX_get_crl_fn get_crl); -X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx); -void X509_STORE_set_check_crl(X509_STORE *ctx, +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *xs); +void X509_STORE_set_check_crl(X509_STORE *xs, X509_STORE_CTX_check_crl_fn check_crl); -X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx); -void X509_STORE_set_cert_crl(X509_STORE *ctx, +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *xs); +void X509_STORE_set_cert_crl(X509_STORE *xs, X509_STORE_CTX_cert_crl_fn cert_crl); -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx); -void X509_STORE_set_check_policy(X509_STORE *ctx, +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *xs); +void X509_STORE_set_check_policy(X509_STORE *xs, X509_STORE_CTX_check_policy_fn check_policy); -X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx); -void X509_STORE_set_lookup_certs(X509_STORE *ctx, +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *s); +void X509_STORE_set_lookup_certs(X509_STORE *xs, X509_STORE_CTX_lookup_certs_fn lookup_certs); -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx); -void X509_STORE_set_lookup_crls(X509_STORE *ctx, +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *s); +void X509_STORE_set_lookup_crls(X509_STORE *xs, X509_STORE_CTX_lookup_crls_fn lookup_crls); #define X509_STORE_set_lookup_crls_cb(ctx, func) \ X509_STORE_set_lookup_crls((ctx), (func)) -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx); -void X509_STORE_set_cleanup(X509_STORE *ctx, +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *xs); +void X509_STORE_set_cleanup(X509_STORE *xs, X509_STORE_CTX_cleanup_fn cleanup); -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *xs); #define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) -int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); -void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx); +int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data); +void *X509_STORE_get_ex_data(const X509_STORE *xs, int idx); X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); X509_STORE_CTX *X509_STORE_CTX_new(void); @@ -565,11 +566,14 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); void X509_STORE_CTX_free(X509_STORE_CTX *ctx); int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *trust_store, X509 *target, STACK_OF(X509) *untrusted); +int X509_STORE_CTX_init_rpk(X509_STORE_CTX *ctx, X509_STORE *trust_store, + EVP_PKEY* rpk); void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx); X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx); +EVP_PKEY *X509_STORE_CTX_get0_rpk(const X509_STORE_CTX *ctx); STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx); void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, @@ -579,6 +583,8 @@ X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(const X509_STORE_CTX *ctx); X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_get_crl(X509_STORE_CTX *ctx, + X509_STORE_CTX_get_crl_fn get_crl); X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(const X509_STORE_CTX *ctx); X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(const X509_STORE_CTX *ctx); @@ -600,7 +606,7 @@ X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(const X509_STORE_CTX *ctx); # define X509_STORE_get1_crl X509_STORE_CTX_get1_crls #endif -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *xs, X509_LOOKUP_METHOD *m); X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); X509_LOOKUP_METHOD *X509_LOOKUP_file(void); X509_LOOKUP_METHOD *X509_LOOKUP_store(void); @@ -685,8 +691,8 @@ X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( const X509_LOOKUP_METHOD *method); -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); +int X509_STORE_add_cert(X509_STORE *xs, X509 *x); +int X509_STORE_add_crl(X509_STORE *xs, X509_CRL *x); int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, @@ -730,23 +736,21 @@ void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); -int X509_STORE_load_file(X509_STORE *ctx, const char *file); -int X509_STORE_load_path(X509_STORE *ctx, const char *path); -int X509_STORE_load_store(X509_STORE *ctx, const char *store); -int X509_STORE_load_locations(X509_STORE *ctx, - const char *file, - const char *dir); -int X509_STORE_set_default_paths(X509_STORE *ctx); +int X509_STORE_load_file(X509_STORE *xs, const char *file); +int X509_STORE_load_path(X509_STORE *xs, const char *path); +int X509_STORE_load_store(X509_STORE *xs, const char *store); +int X509_STORE_load_locations(X509_STORE *s, const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *xs); -int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, +int X509_STORE_load_file_ex(X509_STORE *xs, const char *file, OSSL_LIB_CTX *libctx, const char *propq); -int X509_STORE_load_store_ex(X509_STORE *ctx, const char *store, +int X509_STORE_load_store_ex(X509_STORE *xs, const char *store, OSSL_LIB_CTX *libctx, const char *propq); -int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, - const char *dir, OSSL_LIB_CTX *libctx, - const char *propq); -int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, - const char *propq); +int X509_STORE_load_locations_ex(X509_STORE *xs, + const char *file, const char *dir, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_set_default_paths_ex(X509_STORE *xs, + OSSL_LIB_CTX *libctx, const char *propq); #define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) @@ -764,6 +768,7 @@ X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(const X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get0_chain(const X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get1_chain(const X509_STORE_CTX *ctx); void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *target); +void X509_STORE_CTX_set0_rpk(X509_STORE_CTX *ctx, EVP_PKEY *target); void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); @@ -773,6 +778,8 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t); +void X509_STORE_CTX_set_current_reasons(X509_STORE_CTX *ctx, + unsigned int current_reasons); X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(const X509_STORE_CTX *ctx); int X509_STORE_CTX_get_explicit_policy(const X509_STORE_CTX *ctx); diff --git a/include/openssl/x509_vfy.h.in b/include/openssl/x509_vfy.h.in index 80f18bd787..7a478d117a 100644 --- a/include/openssl/x509_vfy.h.in +++ b/include/openssl/x509_vfy.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -314,6 +314,7 @@ X509_LOOKUP_ctrl_ex((x), X509_L_ADD_STORE, (name), 0, NULL, \ # define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92 # define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93 # define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94 +# define X509_V_ERR_RPK_UNTRUSTED 95 /* Certificate verify flags */ # ifndef OPENSSL_NO_DEPRECATED_1_1_0 @@ -394,71 +395,71 @@ int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a); int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); X509_STORE *X509_STORE_new(void); -void X509_STORE_free(X509_STORE *v); -int X509_STORE_lock(X509_STORE *ctx); -int X509_STORE_unlock(X509_STORE *ctx); -int X509_STORE_up_ref(X509_STORE *v); -STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v); -STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *st); -STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, +void X509_STORE_free(X509_STORE *xs); +int X509_STORE_lock(X509_STORE *xs); +int X509_STORE_unlock(X509_STORE *xs); +int X509_STORE_up_ref(X509_STORE *xs); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs); +STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *xs); +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *xs, const X509_NAME *nm); STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *st, const X509_NAME *nm); -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); -int X509_STORE_set_trust(X509_STORE *ctx, int trust); -int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *pm); -X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx); +int X509_STORE_set_flags(X509_STORE *xs, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *xs, int purpose); +int X509_STORE_set_trust(X509_STORE *xs, int trust); +int X509_STORE_set1_param(X509_STORE *xs, const X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *xs); -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +void X509_STORE_set_verify(X509_STORE *xs, X509_STORE_CTX_verify_fn verify); #define X509_STORE_set_verify_func(ctx, func) \ X509_STORE_set_verify((ctx),(func)) void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, X509_STORE_CTX_verify_fn verify); -X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx); -void X509_STORE_set_verify_cb(X509_STORE *ctx, +X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *xs); +void X509_STORE_set_verify_cb(X509_STORE *xs, X509_STORE_CTX_verify_cb verify_cb); # define X509_STORE_set_verify_cb_func(ctx,func) \ X509_STORE_set_verify_cb((ctx),(func)) -X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx); -void X509_STORE_set_get_issuer(X509_STORE *ctx, +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *xs); +void X509_STORE_set_get_issuer(X509_STORE *xs, X509_STORE_CTX_get_issuer_fn get_issuer); -X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx); -void X509_STORE_set_check_issued(X509_STORE *ctx, +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *xs); +void X509_STORE_set_check_issued(X509_STORE *xs, X509_STORE_CTX_check_issued_fn check_issued); -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx); -void X509_STORE_set_check_revocation(X509_STORE *ctx, +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *s); +void X509_STORE_set_check_revocation(X509_STORE *xs, X509_STORE_CTX_check_revocation_fn check_revocation); X509_STORE_CTX_check_revocation_fn - X509_STORE_get_check_revocation(const X509_STORE *ctx); -void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_get_check_revocation(const X509_STORE *xs); +void X509_STORE_set_get_crl(X509_STORE *xs, X509_STORE_CTX_get_crl_fn get_crl); -X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx); -void X509_STORE_set_check_crl(X509_STORE *ctx, +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *xs); +void X509_STORE_set_check_crl(X509_STORE *xs, X509_STORE_CTX_check_crl_fn check_crl); -X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx); -void X509_STORE_set_cert_crl(X509_STORE *ctx, +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *xs); +void X509_STORE_set_cert_crl(X509_STORE *xs, X509_STORE_CTX_cert_crl_fn cert_crl); -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx); -void X509_STORE_set_check_policy(X509_STORE *ctx, +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *xs); +void X509_STORE_set_check_policy(X509_STORE *xs, X509_STORE_CTX_check_policy_fn check_policy); -X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx); -void X509_STORE_set_lookup_certs(X509_STORE *ctx, +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *s); +void X509_STORE_set_lookup_certs(X509_STORE *xs, X509_STORE_CTX_lookup_certs_fn lookup_certs); -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx); -void X509_STORE_set_lookup_crls(X509_STORE *ctx, +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *s); +void X509_STORE_set_lookup_crls(X509_STORE *xs, X509_STORE_CTX_lookup_crls_fn lookup_crls); #define X509_STORE_set_lookup_crls_cb(ctx, func) \ X509_STORE_set_lookup_crls((ctx), (func)) -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx); -void X509_STORE_set_cleanup(X509_STORE *ctx, +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *xs); +void X509_STORE_set_cleanup(X509_STORE *xs, X509_STORE_CTX_cleanup_fn cleanup); -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *xs); #define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) -int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); -void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx); +int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data); +void *X509_STORE_get_ex_data(const X509_STORE *xs, int idx); X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); X509_STORE_CTX *X509_STORE_CTX_new(void); @@ -468,11 +469,14 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); void X509_STORE_CTX_free(X509_STORE_CTX *ctx); int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *trust_store, X509 *target, STACK_OF(X509) *untrusted); +int X509_STORE_CTX_init_rpk(X509_STORE_CTX *ctx, X509_STORE *trust_store, + EVP_PKEY* rpk); void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx); X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx); +EVP_PKEY *X509_STORE_CTX_get0_rpk(const X509_STORE_CTX *ctx); STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx); void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, @@ -482,6 +486,8 @@ X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(const X509_STORE_CTX *ctx); X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_get_crl(X509_STORE_CTX *ctx, + X509_STORE_CTX_get_crl_fn get_crl); X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(const X509_STORE_CTX *ctx); X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(const X509_STORE_CTX *ctx); X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(const X509_STORE_CTX *ctx); @@ -503,7 +509,7 @@ X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(const X509_STORE_CTX *ctx); # define X509_STORE_get1_crl X509_STORE_CTX_get1_crls #endif -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *xs, X509_LOOKUP_METHOD *m); X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); X509_LOOKUP_METHOD *X509_LOOKUP_file(void); X509_LOOKUP_METHOD *X509_LOOKUP_store(void); @@ -588,8 +594,8 @@ X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( const X509_LOOKUP_METHOD *method); -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); +int X509_STORE_add_cert(X509_STORE *xs, X509 *x); +int X509_STORE_add_crl(X509_STORE *xs, X509_CRL *x); int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, @@ -633,23 +639,21 @@ void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); -int X509_STORE_load_file(X509_STORE *ctx, const char *file); -int X509_STORE_load_path(X509_STORE *ctx, const char *path); -int X509_STORE_load_store(X509_STORE *ctx, const char *store); -int X509_STORE_load_locations(X509_STORE *ctx, - const char *file, - const char *dir); -int X509_STORE_set_default_paths(X509_STORE *ctx); +int X509_STORE_load_file(X509_STORE *xs, const char *file); +int X509_STORE_load_path(X509_STORE *xs, const char *path); +int X509_STORE_load_store(X509_STORE *xs, const char *store); +int X509_STORE_load_locations(X509_STORE *s, const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *xs); -int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, +int X509_STORE_load_file_ex(X509_STORE *xs, const char *file, OSSL_LIB_CTX *libctx, const char *propq); -int X509_STORE_load_store_ex(X509_STORE *ctx, const char *store, +int X509_STORE_load_store_ex(X509_STORE *xs, const char *store, OSSL_LIB_CTX *libctx, const char *propq); -int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, - const char *dir, OSSL_LIB_CTX *libctx, - const char *propq); -int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, - const char *propq); +int X509_STORE_load_locations_ex(X509_STORE *xs, + const char *file, const char *dir, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_set_default_paths_ex(X509_STORE *xs, + OSSL_LIB_CTX *libctx, const char *propq); #define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) @@ -667,6 +671,7 @@ X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(const X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get0_chain(const X509_STORE_CTX *ctx); STACK_OF(X509) *X509_STORE_CTX_get1_chain(const X509_STORE_CTX *ctx); void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *target); +void X509_STORE_CTX_set0_rpk(X509_STORE_CTX *ctx, EVP_PKEY *target); void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk); int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); @@ -676,6 +681,8 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t); +void X509_STORE_CTX_set_current_reasons(X509_STORE_CTX *ctx, + unsigned int current_reasons); X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(const X509_STORE_CTX *ctx); int X509_STORE_CTX_get_explicit_policy(const X509_STORE_CTX *ctx); diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h index 34ead4b81a..71b557a3e6 100644 --- a/include/openssl/x509err.h +++ b/include/openssl/x509err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 750163549f..e64da7e0c5 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -742,9 +742,10 @@ SKM_DEFINE_STACK_OF_INTERNAL(X509_PURPOSE, X509_PURPOSE, X509_PURPOSE) # define X509_PURPOSE_ANY 7 # define X509_PURPOSE_OCSP_HELPER 8 # define X509_PURPOSE_TIMESTAMP_SIGN 9 +# define X509_PURPOSE_CODE_SIGN 10 # define X509_PURPOSE_MIN 1 -# define X509_PURPOSE_MAX 9 +# define X509_PURPOSE_MAX 10 /* Flags for X509V3_EXT_print() */ diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in index e33c9d3055..569680378d 100644 --- a/include/openssl/x509v3.h.in +++ b/include/openssl/x509v3.h.in @@ -478,9 +478,10 @@ typedef struct x509_purpose_st { # define X509_PURPOSE_ANY 7 # define X509_PURPOSE_OCSP_HELPER 8 # define X509_PURPOSE_TIMESTAMP_SIGN 9 +# define X509_PURPOSE_CODE_SIGN 10 # define X509_PURPOSE_MIN 1 -# define X509_PURPOSE_MAX 9 +# define X509_PURPOSE_MAX 10 /* Flags for X509V3_EXT_print() */ diff --git a/include/openssl/x509v3err.h b/include/openssl/x509v3err.h index 1ae3a56209..deede27952 100644 --- a/include/openssl/x509v3err.h +++ b/include/openssl/x509v3err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,6 +23,8 @@ */ # define X509V3_R_BAD_IP_ADDRESS 118 # define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BAD_OPTION 170 +# define X509V3_R_BAD_VALUE 171 # define X509V3_R_BN_DEC2BN_ERROR 100 # define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 # define X509V3_R_DIRNAME_ERROR 149 @@ -86,6 +88,7 @@ # define X509V3_R_UNKNOWN_EXTENSION 129 # define X509V3_R_UNKNOWN_EXTENSION_NAME 130 # define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNKNOWN_VALUE 172 # define X509V3_R_UNSUPPORTED_OPTION 117 # define X509V3_R_UNSUPPORTED_TYPE 167 # define X509V3_R_USER_TOO_LONG 132 diff --git a/openssl.cmake b/openssl.cmake index c0e237bdc4..36a559f355 100644 --- a/openssl.cmake +++ b/openssl.cmake @@ -104,6 +104,7 @@ set(crypto_srcs crypto/bio/bss_conn.c crypto/bio/bss_core.c crypto/bio/bss_dgram.c + crypto/bio/bss_dgram_pair.c crypto/bio/bss_fd.c crypto/bio/bss_file.c crypto/bio/bss_log.c @@ -162,7 +163,9 @@ set(crypto_srcs crypto/cms/cms_pwri.c crypto/cms/cms_sd.c crypto/cms/cms_smime.c + crypto/comp/c_brotli.c crypto/comp/c_zlib.c + crypto/comp/c_zstd.c crypto/comp/comp_err.c crypto/comp/comp_lib.c crypto/cmp/cmp_util.c @@ -247,6 +250,7 @@ set(crypto_srcs crypto/dsa/dsa_sign.c crypto/dsa/dsa_vrf.c crypto/der_writer.c + crypto/deterministic_nonce.c crypto/dso/dso_dl.c crypto/dso/dso_dlfcn.c crypto/dso/dso_err.c @@ -288,6 +292,7 @@ set(crypto_srcs crypto/ec/ecp_nistz256.c crypto/ec/ecp_oct.c crypto/ec/ecp_smpl.c + crypto/ec/ecp_sm2p256.c crypto/ec/ecx_backend.c crypto/ec/ecx_meth.c crypto/ec/ecx_key.c @@ -320,10 +325,17 @@ set(crypto_srcs crypto/engine/tb_pkmeth.c crypto/engine/tb_rand.c crypto/engine/tb_rsa.c + crypto/err/err_save.c + crypto/err/openssl.ec + crypto/err/err_mark.c + crypto/err/err_prn.c + crypto/err/err_blocks.c crypto/err/err.c + crypto/err/openssl.txt + crypto/err/err_all_legacy.c + crypto/err/build.info + crypto/err/err_local.h crypto/err/err_all.c - crypto/err/err_blocks.c - crypto/err/err_prn.c crypto/ess/ess_asn1.c crypto/ess/ess_err.c crypto/ess/ess_lib.c @@ -410,6 +422,8 @@ set(crypto_srcs crypto/ffc/ffc_params_validate.c crypto/getenv.c crypto/hmac/hmac.c + crypto/hpke/hpke.c + crypto/hpke/hpke_util.c crypto/http/http_client.c crypto/http/http_err.c crypto/http/http_lib.c @@ -435,6 +449,7 @@ set(crypto_srcs crypto/modes/ofb128.c crypto/modes/siv128.c crypto/modes/xts128.c + crypto/modes/xts128gb.c crypto/modes/wrap128.c crypto/o_dir.c crypto/o_fopen.c @@ -461,6 +476,7 @@ set(crypto_srcs crypto/param_build.c crypto/param_build_set.c crypto/params_from_text.c + crypto/params_idx.c crypto/passphrase.c crypto/pem/pem_all.c crypto/pem/pem_err.c @@ -509,12 +525,14 @@ set(crypto_srcs crypto/property/property_string.c crypto/provider_child.c crypto/punycode.c + crypto/quic_vlint.c crypto/rand/prov_seed.c crypto/rand/rand_egd.c crypto/rand/rand_err.c crypto/rand/rand_lib.c crypto/rand/rand_meth.c crypto/rand/rand_pool.c + crypto/rand/rand_uniform.c crypto/rand/randfile.c crypto/rc2/rc2_cbc.c crypto/rc2/rc2_ecb.c @@ -555,6 +573,7 @@ set(crypto_srcs crypto/sha/sha3.c crypto/sha/sha512.c crypto/siphash/siphash.c + crypto/sleep.c crypto/sm2/sm2_err.c crypto/sm2/sm2_crypt.c crypto/sm2/sm2_key.c @@ -577,6 +596,12 @@ set(crypto_srcs crypto/threads_pthread.c crypto/threads_win.c crypto/threads_lib.c + crypto/thread/arch/thread_posix.c + crypto/thread/api.c + crypto/thread/arch.c + crypto/thread/build.info + crypto/thread/internal.c + crypto/time.c crypto/trace.c crypto/ts/ts_err.c crypto/txt_db/txt_db.c @@ -592,6 +617,12 @@ set(crypto_srcs crypto/x509/t_crl.c crypto/x509/t_req.c crypto/x509/t_x509.c + crypto/x509/v3_group_ac.c + crypto/x509/v3_ind_iss.c + crypto/x509/v3_no_ass.c + crypto/x509/v3_no_rev_avail.c + crypto/x509/v3_single_use.c + crypto/x509/v3_soa_id.c crypto/x509/x509_att.c crypto/x509/x509_cmp.c crypto/x509/x509_d2.c @@ -689,6 +720,7 @@ elseif (${ANDROID_ABI} STREQUAL "arm64-v8a") crypto/bn/asm/armv8-mont.S crypto/chacha/asm/chacha-armv8-sve.S crypto/ec/asm/ecp_nistz256-armv8.S + crypto/ec/asm/ecp_sm2p256-armv8.S crypto/md5/asm/md5-aarch64.S crypto/modes/asm/ghashv8-armx-64.S crypto/modes/asm/aes-gcm-armv8_64.S @@ -701,6 +733,7 @@ elseif (${ANDROID_ABI} STREQUAL "arm64-v8a") crypto/sm3/asm/sm3-armv8.S crypto/sm4/asm/sm4-armv8.S crypto/sm4/asm/vpsm4-armv8.S + crypto/sm4/asm/vpsm4_ex-armv8.S ) elseif (${ANDROID_ABI} STREQUAL "x86") set(crypto_srcs ${crypto_srcs} @@ -818,6 +851,7 @@ set(provider_srcs providers/implementations/ciphers/cipher_aes_wrp.c providers/implementations/ciphers/cipher_des.c providers/implementations/ciphers/ciphercommon_gcm_hw.c + providers/implementations/ciphers/ciphercommon_gcm.c providers/implementations/ciphers/cipher_aria.c providers/implementations/ciphers/cipher_aes_ocb.c providers/implementations/ciphers/cipher_desx_hw.c @@ -835,6 +869,9 @@ set(provider_srcs providers/implementations/ciphers/cipher_null.c providers/implementations/ciphers/cipher_rc2_hw.c providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c + providers/implementations/ciphers/cipher_sm4_xts.c + providers/implementations/ciphers/cipher_sm4_xts_hw.c + providers/implementations/ciphers/cipher_sm4_ccm_hw.c providers/implementations/ciphers/cipher_tdes.c providers/implementations/ciphers/cipher_aes_ccm_hw.c providers/implementations/ciphers/ciphercommon_ccm.c @@ -842,19 +879,22 @@ set(provider_srcs providers/implementations/ciphers/ciphercommon.c providers/implementations/ciphers/ciphercommon_block.c providers/implementations/ciphers/cipher_tdes_default_hw.c - providers/implementations/ciphers/ciphercommon_gcm.c providers/implementations/ciphers/cipher_tdes_wrap_hw.c providers/implementations/ciphers/cipher_desx.c providers/implementations/ciphers/ciphercommon_hw.c - providers/implementations/ciphers/cipher_rc2.c + providers/implementations/ciphers/cipher_aes_gcm_siv.c + providers/implementations/ciphers/cipher_aes_gcm_siv.h + providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c + providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c providers/implementations/ciphers/cipher_aes_xts_hw.c - providers/implementations/ciphers/cipher_chacha20_hw.c providers/implementations/ciphers/cipher_aria_ccm_hw.c - providers/implementations/ciphers/cipher_blowfish.c providers/implementations/ciphers/cipher_aria_gcm.c providers/implementations/ciphers/cipher_aria_gcm_hw.c - providers/implementations/ciphers/cipher_rc4_hw.c + providers/implementations/ciphers/cipher_blowfish.c + providers/implementations/ciphers/cipher_chacha20_hw.c providers/implementations/ciphers/cipher_chacha20_poly1305.c + providers/implementations/ciphers/cipher_rc2.c + providers/implementations/ciphers/cipher_rc4_hw.c providers/implementations/ciphers/cipher_rc4_hmac_md5.c providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c providers/implementations/ciphers/cipher_aria_ccm.c @@ -868,6 +908,9 @@ set(provider_srcs providers/implementations/ciphers/cipher_sm4_gcm.c providers/implementations/ciphers/cipher_sm4_gcm_hw.c providers/implementations/ciphers/cipher_sm4_hw.c + providers/implementations/ciphers/cipher_sm4_xts.c + providers/implementations/ciphers/cipher_sm4_xts.h + providers/implementations/ciphers/cipher_sm4_xts_hw.c providers/implementations/digests/blake2_prov.c providers/implementations/digests/blake2s_prov.c providers/implementations/digests/blake2b_prov.c @@ -902,6 +945,8 @@ set(provider_srcs providers/implementations/keymgmt/kdf_legacy_kmgmt.c providers/implementations/keymgmt/mac_legacy_kmgmt.c providers/implementations/keymgmt/rsa_kmgmt.c + providers/implementations/kdfs/argon2.c + providers/implementations/kdfs/hmacdrbg_kdf.c providers/implementations/kdfs/x942kdf.c providers/implementations/kdfs/sskdf.c providers/implementations/kdfs/tls1_prf.c @@ -913,6 +958,11 @@ set(provider_srcs providers/implementations/kdfs/kbkdf.c providers/implementations/kdfs/pbkdf2.c providers/implementations/kdfs/pkcs12kdf.c + providers/implementations/kdfs/pvkkdf.c + providers/implementations/kem/ec_kem.c + providers/implementations/kem/eckem.h + providers/implementations/kem/ecx_kem.c + providers/implementations/kem/kem_util.c providers/implementations/macs/blake2b_mac.c providers/implementations/macs/blake2s_mac.c providers/implementations/macs/cmac_prov.c @@ -938,6 +988,7 @@ set(provider_srcs providers/implementations/storemgmt/file_store.c providers/implementations/storemgmt/file_store_any2obj.c providers/prov_running.c + ) set(legacy_srcs @@ -982,6 +1033,7 @@ target_compile_options(crypto PRIVATE -Wno-missing-field-initializers -Wno-unuse -DOPENSSL_CPUID_OBJ -DL_ENDIAN -DSTATIC_LEGACY + -DOPENSSL_NO_SM2_PRECOMP ) if (${ANDROID_ABI} STREQUAL "armeabi-v7a") @@ -1001,6 +1053,7 @@ elseif (${ANDROID_ABI} STREQUAL "arm64-v8a") -DVPSM4_ASM -DOPENSSL_SM3_ASM -DSM4_ASM + -DECP_SM2P256_ASM ) elseif (${ANDROID_ABI} STREQUAL "x86") target_compile_definitions(crypto PRIVATE @@ -1053,16 +1106,53 @@ set(ssl_srcs ssl/d1_lib.c ssl/d1_msg.c ssl/d1_srtp.c + ssl/event_queue.c ssl/methods.c ssl/pqueue.c - ssl/record/dtls1_bitmap.c + ssl/priority_queue.c + ssl/quic/quic_impl.c + ssl/quic/quic_fifd.c + ssl/quic/quic_channel_local.h + ssl/quic/quic_ackm.c + ssl/quic/quic_fc.c + ssl/quic/quic_thread_assist.c + ssl/quic/uint_set.c + ssl/quic/quic_trace.c + ssl/quic/quic_stream_map.c + ssl/quic/quic_record_rx.c + ssl/quic/quic_demux.c + ssl/quic/quic_tls.c + ssl/quic/quic_record_util.c + ssl/quic/quic_record_shared.c + ssl/quic/quic_sf_list.c + ssl/quic/quic_method.c + ssl/quic/quic_rstream.c + ssl/quic/cc_newreno.c + ssl/quic/quic_sstream.c + ssl/quic/quic_statm.c + ssl/quic/quic_channel.c + ssl/quic/quic_record_tx.c + ssl/quic/quic_cfq.c + ssl/quic/quic_tserver.c + ssl/quic/quic_txp.c + ssl/quic/quic_local.h + ssl/quic/quic_txpim.c + ssl/quic/quic_wire.c + ssl/quic/quic_reactor.c + ssl/quic/quic_rx_depack.c + ssl/quic/quic_record_shared.h + ssl/quic/quic_wire_pkt.c ssl/record/rec_layer_d1.c + ssl/record/methods/tlsany_meth.c + ssl/record/methods/tls_multib.c + ssl/record/methods/tls_pad.c + ssl/record/methods/tls1_meth.c + ssl/record/methods/ssl3_meth.c + ssl/record/methods/tls13_meth.c + ssl/record/methods/dtls_meth.c + ssl/record/methods/ssl3_cbc.c + ssl/record/methods/tls_common.c ssl/record/rec_layer_s3.c - ssl/record/ssl3_buffer.c - ssl/record/ssl3_record.c - ssl/record/ssl3_record_tls13.c - ssl/record/tls_pad.c - ssl/s3_cbc.c ssl/s3_enc.c ssl/s3_lib.c ssl/s3_msg.c diff --git a/openssl.config b/openssl.config index 17e8bb1ccc..200ecc88a0 100644 --- a/openssl.config +++ b/openssl.config @@ -119,6 +119,7 @@ OPENSSL_CRYPTO_CLANG_ASFLAGS_arm64="\ OPENSSL_CRYPTO_DEFINES_arm64="\ BSAES_ASM \ ECP_NISTZ256_ASM \ +ECP_SM2P256_ASM \ KECCAK1600_ASM \ MD5_ASM \ OPENSSL_BN_ASM_MONT \ diff --git a/openssl.version b/openssl.version index 047b885219..097d4b217e 100644 --- a/openssl.version +++ b/openssl.version @@ -1 +1 @@ -OPENSSL_VERSION=3.1.4 +OPENSSL_VERSION=3.2.0 diff --git a/providers/baseprov.c b/providers/baseprov.c index 1dbb0ffb83..6b8de7cb36 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -126,7 +126,7 @@ static const OSSL_DISPATCH base_dispatch_table[] = { (void (*)(void))base_gettable_params }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))base_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))base_query }, - { 0, NULL } + OSSL_DISPATCH_END }; OSSL_provider_init_fn ossl_base_provider_init; diff --git a/providers/common/capabilities.c b/providers/common/capabilities.c index ed37e76969..f7234615e4 100644 --- a/providers/common/capabilities.c +++ b/providers/common/capabilities.c @@ -30,7 +30,7 @@ typedef struct tls_group_constants_st { int maxdtls; /* Maximum DTLS version (or 0 for undefined) */ } TLS_GROUP_CONSTANTS; -static const TLS_GROUP_CONSTANTS group_list[35] = { +static const TLS_GROUP_CONSTANTS group_list[] = { { OSSL_TLS_GROUP_ID_sect163k1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect163r1, 80, TLS1_VERSION, TLS1_2_VERSION, @@ -86,6 +86,9 @@ static const TLS_GROUP_CONSTANTS group_list[35] = { DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, + { OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, -1, -1 }, + { OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, -1, -1 }, + { OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, -1, -1 }, /* Security bit values as given by BN_security_bits() */ { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1 }, @@ -189,14 +192,19 @@ static const OSSL_PARAM param_group_list[][10] = { # endif TLS_GROUP_ENTRY("x25519", "X25519", "X25519", 28), TLS_GROUP_ENTRY("x448", "X448", "X448", 29), +# ifndef FIPS_MODULE + TLS_GROUP_ENTRY("brainpoolP256r1tls13", "brainpoolP256r1", "EC", 30), + TLS_GROUP_ENTRY("brainpoolP384r1tls13", "brainpoolP384r1", "EC", 31), + TLS_GROUP_ENTRY("brainpoolP512r1tls13", "brainpoolP512r1", "EC", 32), +# endif # endif /* OPENSSL_NO_EC */ # ifndef OPENSSL_NO_DH /* Security bit values for FFDHE groups are as per RFC 7919 */ - TLS_GROUP_ENTRY("ffdhe2048", "ffdhe2048", "DH", 30), - TLS_GROUP_ENTRY("ffdhe3072", "ffdhe3072", "DH", 31), - TLS_GROUP_ENTRY("ffdhe4096", "ffdhe4096", "DH", 32), - TLS_GROUP_ENTRY("ffdhe6144", "ffdhe6144", "DH", 33), - TLS_GROUP_ENTRY("ffdhe8192", "ffdhe8192", "DH", 34), + TLS_GROUP_ENTRY("ffdhe2048", "ffdhe2048", "DH", 33), + TLS_GROUP_ENTRY("ffdhe3072", "ffdhe3072", "DH", 34), + TLS_GROUP_ENTRY("ffdhe4096", "ffdhe4096", "DH", 35), + TLS_GROUP_ENTRY("ffdhe6144", "ffdhe6144", "DH", 36), + TLS_GROUP_ENTRY("ffdhe8192", "ffdhe8192", "DH", 37), # endif }; #endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ diff --git a/providers/common/der/build.info b/providers/common/der/build.info index b81413e11b..764bff539e 100644 --- a/providers/common/der/build.info +++ b/providers/common/der/build.info @@ -57,7 +57,7 @@ IF[{- !$disabled{ec} -}] ENDIF #----- ECX -IF[{- !$disabled{ec} -}] +IF[{- !$disabled{ecx} -}] $DER_ECX_H=$INCDIR/der_ecx.h $DER_ECX_GEN=der_ecx_gen.c $DER_ECX_AUX=der_ecx_key.c @@ -107,7 +107,9 @@ ENDIF IF[{- !$disabled{ec} -}] $COMMON = $COMMON $DER_EC_GEN $DER_EC_AUX - $COMMON = $COMMON $DER_ECX_GEN $DER_ECX_AUX + IF[{- !$disabled{ecx} -}] + $COMMON = $COMMON $DER_ECX_GEN $DER_ECX_AUX + ENDIF ENDIF IF[{- !$disabled{sm2} -}] diff --git a/providers/common/der/der_rsa_key.c b/providers/common/der/der_rsa_key.c index 771150d893..893970575f 100644 --- a/providers/common/der/der_rsa_key.c +++ b/providers/common/der/der_rsa_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/der/oids_to_c.pm b/providers/common/der/oids_to_c.pm index a6b0930f9b..6f57df09b9 100644 --- a/providers/common/der/oids_to_c.pm +++ b/providers/common/der/oids_to_c.pm @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index f21c500078..611ec847cb 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -68,6 +68,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INSUFFICIENT_DRBG_STRENGTH), "insufficient drbg strength"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AEAD), "invalid aead"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONFIG_DATA), "invalid config data"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH), @@ -86,10 +87,13 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT), "invalid iteration count"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IV_LENGTH), "invalid iv length"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KDF), "invalid kdf"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY), "invalid key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MAC), "invalid mac"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MEMORY_SIZE), + "invalid memory size"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MGF1_MD), "invalid mgf1 md"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_OUTPUT_LENGTH), @@ -107,6 +111,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG_LENGTH), "invalid tag length"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_THREAD_POOL_SIZE), + "invalid thread pool size"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_UKM_LENGTH), "invalid ukm length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST), diff --git a/providers/common/provider_seeding.c b/providers/common/provider_seeding.c index eb7bb4e6a1..544344f30a 100644 --- a/providers/common/provider_seeding.c +++ b/providers/common/provider_seeding.c @@ -104,7 +104,7 @@ void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf, size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout, size_t min_len, size_t max_len, - const void *salt,size_t salt_len) + const void *salt, size_t salt_len) { const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx); diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c index 48dc41c39c..2473754d26 100644 --- a/providers/common/provider_util.c +++ b/providers/common/provider_util.c @@ -356,10 +356,8 @@ int ossl_prov_memdup(const void *src, size_t src_len, unsigned char **dest, size_t *dest_len) { if (src != NULL) { - if ((*dest = OPENSSL_memdup(src, src_len)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((*dest = OPENSSL_memdup(src, src_len)) == NULL) return 0; - } *dest_len = src_len; } else { *dest = NULL; diff --git a/providers/decoders.inc b/providers/decoders.inc index 2772aad05d..0191aa771e 100644 --- a/providers/decoders.inc +++ b/providers/decoders.inc @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -58,6 +58,7 @@ DECODER_w_structure("EC", der, PrivateKeyInfo, ec, yes), DECODER_w_structure("EC", der, SubjectPublicKeyInfo, ec, yes), DECODER_w_structure("EC", der, type_specific_no_pub, ec, yes), DECODER_w_structure("EC", der, EC, ec, yes), +# ifndef OPENSSL_NO_ECX DECODER_w_structure("ED25519", der, PrivateKeyInfo, ed25519, yes), DECODER_w_structure("ED25519", der, SubjectPublicKeyInfo, ed25519, yes), DECODER_w_structure("ED448", der, PrivateKeyInfo, ed448, yes), @@ -66,9 +67,11 @@ DECODER_w_structure("X25519", der, PrivateKeyInfo, x25519, yes), DECODER_w_structure("X25519", der, SubjectPublicKeyInfo, x25519, yes), DECODER_w_structure("X448", der, PrivateKeyInfo, x448, yes), DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes), +# endif # ifndef OPENSSL_NO_SM2 DECODER_w_structure("SM2", der, PrivateKeyInfo, sm2, no), DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, no), +DECODER_w_structure("SM2", der, type_specific_no_pub, sm2, no), # endif #endif DECODER_w_structure("RSA", der, PrivateKeyInfo, rsa, yes), diff --git a/providers/defltprov.c b/providers/defltprov.c index cc0b0c3b62..f02e04835d 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -103,6 +103,7 @@ static const OSSL_ALGORITHM deflt_digests[] = { { PROV_NAMES_SHA1, "provider=default", ossl_sha1_functions }, { PROV_NAMES_SHA2_224, "provider=default", ossl_sha224_functions }, { PROV_NAMES_SHA2_256, "provider=default", ossl_sha256_functions }, + { PROV_NAMES_SHA2_256_192, "provider=default", ossl_sha256_192_functions }, { PROV_NAMES_SHA2_384, "provider=default", ossl_sha384_functions }, { PROV_NAMES_SHA2_512, "provider=default", ossl_sha512_functions }, { PROV_NAMES_SHA2_512_224, "provider=default", ossl_sha512_224_functions }, @@ -114,6 +115,11 @@ static const OSSL_ALGORITHM deflt_digests[] = { { PROV_NAMES_SHA3_384, "provider=default", ossl_sha3_384_functions }, { PROV_NAMES_SHA3_512, "provider=default", ossl_sha3_512_functions }, + { PROV_NAMES_KECCAK_224, "provider=default", ossl_keccak_224_functions }, + { PROV_NAMES_KECCAK_256, "provider=default", ossl_keccak_256_functions }, + { PROV_NAMES_KECCAK_384, "provider=default", ossl_keccak_384_functions }, + { PROV_NAMES_KECCAK_512, "provider=default", ossl_keccak_512_functions }, + /* * KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for * the KMAC-128 and KMAC-256. @@ -193,6 +199,9 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = { ALG(PROV_NAMES_AES_128_SIV, ossl_aes128siv_functions), ALG(PROV_NAMES_AES_192_SIV, ossl_aes192siv_functions), ALG(PROV_NAMES_AES_256_SIV, ossl_aes256siv_functions), + ALG(PROV_NAMES_AES_128_GCM_SIV, ossl_aes128gcm_siv_functions), + ALG(PROV_NAMES_AES_192_GCM_SIV, ossl_aes192gcm_siv_functions), + ALG(PROV_NAMES_AES_256_GCM_SIV, ossl_aes256gcm_siv_functions), #endif /* OPENSSL_NO_SIV */ ALG(PROV_NAMES_AES_256_GCM, ossl_aes256gcm_functions), ALG(PROV_NAMES_AES_192_GCM, ossl_aes192gcm_functions), @@ -296,6 +305,7 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = { ALG(PROV_NAMES_SM4_CTR, ossl_sm4128ctr_functions), ALG(PROV_NAMES_SM4_OFB, ossl_sm4128ofb128_functions), ALG(PROV_NAMES_SM4_CFB, ossl_sm4128cfb128_functions), + ALG(PROV_NAMES_SM4_XTS, ossl_sm4128xts_functions), #endif /* OPENSSL_NO_SM4 */ #ifndef OPENSSL_NO_CHACHA ALG(PROV_NAMES_ChaCha20, ossl_chacha20_functions), @@ -344,6 +354,13 @@ static const OSSL_ALGORITHM deflt_kdfs[] = { { PROV_NAMES_SCRYPT, "provider=default", ossl_kdf_scrypt_functions }, #endif { PROV_NAMES_KRB5KDF, "provider=default", ossl_kdf_krb5kdf_functions }, + { PROV_NAMES_HMAC_DRBG_KDF, "provider=default", + ossl_kdf_hmac_drbg_functions }, +#ifndef OPENSSL_NO_ARGON2 + { PROV_NAMES_ARGON2I, "provider=default", ossl_kdf_argon2i_functions }, + { PROV_NAMES_ARGON2D, "provider=default", ossl_kdf_argon2d_functions }, + { PROV_NAMES_ARGON2ID, "provider=default", ossl_kdf_argon2id_functions }, +#endif { NULL, NULL, NULL } }; @@ -353,8 +370,10 @@ static const OSSL_ALGORITHM deflt_keyexch[] = { #endif #ifndef OPENSSL_NO_EC { PROV_NAMES_ECDH, "provider=default", ossl_ecdh_keyexch_functions }, +# ifndef OPENSSL_NO_ECX { PROV_NAMES_X25519, "provider=default", ossl_x25519_keyexch_functions }, { PROV_NAMES_X448, "provider=default", ossl_x448_keyexch_functions }, +# endif #endif { PROV_NAMES_TLS1_PRF, "provider=default", ossl_kdf_tls1_prf_keyexch_functions }, { PROV_NAMES_HKDF, "provider=default", ossl_kdf_hkdf_keyexch_functions }, @@ -378,8 +397,10 @@ static const OSSL_ALGORITHM deflt_signature[] = { #endif { PROV_NAMES_RSA, "provider=default", ossl_rsa_signature_functions }, #ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX { PROV_NAMES_ED25519, "provider=default", ossl_ed25519_signature_functions }, { PROV_NAMES_ED448, "provider=default", ossl_ed448_signature_functions }, +# endif { PROV_NAMES_ECDSA, "provider=default", ossl_ecdsa_signature_functions }, # ifndef OPENSSL_NO_SM2 { PROV_NAMES_SM2, "provider=default", ossl_sm2_signature_functions }, @@ -408,6 +429,13 @@ static const OSSL_ALGORITHM deflt_asym_cipher[] = { static const OSSL_ALGORITHM deflt_asym_kem[] = { { PROV_NAMES_RSA, "provider=default", ossl_rsa_asym_kem_functions }, +#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX + { PROV_NAMES_X25519, "provider=default", ossl_ecx_asym_kem_functions }, + { PROV_NAMES_X448, "provider=default", ossl_ecx_asym_kem_functions }, +# endif + { PROV_NAMES_EC, "provider=default", ossl_ec_asym_kem_functions }, +#endif { NULL, NULL, NULL } }; @@ -429,6 +457,7 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = { #ifndef OPENSSL_NO_EC { PROV_NAMES_EC, "provider=default", ossl_ec_keymgmt_functions, PROV_DESCS_EC }, +# ifndef OPENSSL_NO_ECX { PROV_NAMES_X25519, "provider=default", ossl_x25519_keymgmt_functions, PROV_DESCS_X25519 }, { PROV_NAMES_X448, "provider=default", ossl_x448_keymgmt_functions, @@ -437,6 +466,7 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = { PROV_DESCS_ED25519 }, { PROV_NAMES_ED448, "provider=default", ossl_ed448_keymgmt_functions, PROV_DESCS_ED448 }, +# endif #endif { PROV_NAMES_TLS1_PRF, "provider=default", ossl_kdf_keymgmt_functions, PROV_DESCS_TLS1_PRF_SIGN }, @@ -536,7 +566,7 @@ static const OSSL_DISPATCH deflt_dispatch_table[] = { { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))deflt_query }, { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))ossl_prov_get_capabilities }, - { 0, NULL } + OSSL_DISPATCH_END }; OSSL_provider_init_fn ossl_default_provider_init; diff --git a/providers/encoders.inc b/providers/encoders.inc index 95e287c8b9..cd0d1137bb 100644 --- a/providers/encoders.inc +++ b/providers/encoders.inc @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -57,10 +57,12 @@ ENCODER_TEXT("DSA", dsa, yes), #endif #ifndef OPENSSL_NO_EC ENCODER_TEXT("EC", ec, yes), +# ifndef OPENSSL_NO_ECX ENCODER_TEXT("ED25519", ed25519, yes), ENCODER_TEXT("ED448", ed448, yes), ENCODER_TEXT("X25519", x25519, yes), ENCODER_TEXT("X448", x448, yes), +# endif # ifndef OPENSSL_NO_SM2 ENCODER_TEXT("SM2", sm2, no), # endif @@ -181,6 +183,7 @@ ENCODER_w_structure("EC", ec, yes, pem, PrivateKeyInfo), ENCODER_w_structure("EC", ec, yes, der, SubjectPublicKeyInfo), ENCODER_w_structure("EC", ec, yes, pem, SubjectPublicKeyInfo), +#ifndef OPENSSL_NO_ECX ENCODER_w_structure("X25519", x25519, yes, der, EncryptedPrivateKeyInfo), ENCODER_w_structure("X25519", x25519, yes, pem, EncryptedPrivateKeyInfo), ENCODER_w_structure("X25519", x25519, yes, der, PrivateKeyInfo), @@ -208,6 +211,7 @@ ENCODER_w_structure("ED448", ed448, yes, der, PrivateKeyInfo), ENCODER_w_structure("ED448", ed448, yes, pem, PrivateKeyInfo), ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo), ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo), +# endif # ifndef OPENSSL_NO_SM2 ENCODER_w_structure("SM2", sm2, no, der, EncryptedPrivateKeyInfo), diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums index 0dc0803b10..d242295dfc 100644 --- a/providers/fips-sources.checksums +++ b/providers/fips-sources.checksums @@ -11,7 +11,7 @@ a2466f18da5847c7d9fbced17524633c10ce024671a72f53f9c9c55b9b9923dd crypto/aes/aes 7ff9c96ef3d591d45d776fa4b244601ea0d9328e289aeab1e1b92436ce7d02ad crypto/aes/asm/aes-parisc.pl f1244cdeadcb4e48f35bc5df19d4cfaf07e0086ad951b84f07ff6966501faa5b crypto/aes/asm/aes-ppc.pl 538ce0e80698d773c9419a9ca8892d61bc5b3cd1b071c5fc5f315d7f5573e96d crypto/aes/asm/aes-riscv32-zkn.pl -063ab365d4dfebe248e45b328009210cdcc1a63f90eaae8870eaa06a4f8923d9 crypto/aes/asm/aes-riscv64-zkn.pl +b5cdd6858b1eff7d17b29b78ac8c4a7642c0a74710f8b50821a6265328845aaf crypto/aes/asm/aes-riscv64-zkn.pl f0388e17ba4268ed0b562da60e0780072180a824a379b79fafb60e25b8da3b52 crypto/aes/asm/aes-riscv64.pl ecbfe826f4c514810c3ee20e265f4f621149694c298554b2682e5de4f029f14f crypto/aes/asm/aes-s390x.pl ee4e8cacef972942d2a89c1a83c984df9cad87c61a54383403c5c4864c403ba1 crypto/aes/asm/aes-sparcv9.pl @@ -22,11 +22,11 @@ c56c324667b67d726e040d70379efba5b270e2937f403c1b5979018b836903c7 crypto/aes/asm 1d3acabadedb88d1327eeb76201ea9b3f4814f44898018ffae6c73e3f400b89b crypto/aes/asm/aesni-sha256-x86_64.pl 4ff74d4e629a88ef5a9e3d3f5b340fc0a4793d16d7cc7f1b70da62512a856248 crypto/aes/asm/aesni-x86.pl c7c6694480bb5319690f94826139a93f5c460ebea6dba101b520a76cb956ec93 crypto/aes/asm/aesni-x86_64.pl -f3a8f3c960c0f47aaa8fc2633d18b14e7c7feeccc536b0115a08bc58333122b6 crypto/aes/asm/aesp8-ppc.pl +0489a10fbb1a8ca3652848d5c1e14e519501e189bad3e5827a573c26df359691 crypto/aes/asm/aesp8-ppc.pl e397a5781893e97dd90a5a52049633be12a43f379ec5751bca2a6350c39444c8 crypto/aes/asm/aest4-sparcv9.pl 030dd54699b6ab0d71db5a436489ef3265d358337259798ef9d0ee690c182386 crypto/aes/asm/aesv8-armx.pl 5e8005fdb6641df465bdda20c3476f7176e6bcd63d5073044a0c02a327c7f172 crypto/aes/asm/bsaes-armv7.pl -5ee643fd833120756300d92722fa9c8fe2ab58764d64b11350f86c41687b8d7a crypto/aes/asm/bsaes-armv8.pl +9b9c9d7541edb49dcb9fe331f91fca1b6a1e14cc204c07b8cc2b530da8719279 crypto/aes/asm/bsaes-armv8.pl 0726a2c4c15c27a12b2f7d5e16863df4a1b1daa7b7d9b728f621b2b224d290e6 crypto/aes/asm/bsaes-x86_64.pl 762cadf988080f45d1a2f1232058688ac3f5afe76767649d15513a7a5eedcf38 crypto/aes/asm/vpaes-armv8.pl 14146589f53dc898fa86aeffd0e0ba36737b04da26ab0b14c1da09a28836c8f8 crypto/aes/asm/vpaes-loongarch64.pl @@ -35,7 +35,7 @@ c3541865cd02d81101cdbab4877ed82772e6980d2c677b9008b38fa1b26d36d4 crypto/aes/asm 060bb6620f50af9afecdf97df051b45b9a50be9daf343dfec1cbb29693ce00a4 crypto/aes/asm/vpaes-x86_64.pl 2bc67270155e2d6c7da87d9070e005ee79cea18311004907edfd6a078003532a crypto/alphacpuid.pl 269e52f8867c13ca75d2f88ec1f89b692cb8c6c3ee89abe2fd3c1821925191d8 crypto/arm64cpuid.pl -7144d95f74d8f84b5c32fe5b343c1d6d958a96ffcf9d0374a343cd82e599d753 crypto/armcap.c +5d8595338d4ae8bbaba81dab36c00b325abccf5c4a51b7d1b6c622ac893792de crypto/armcap.c b0f528db5658d7c98657eb322bf78e326202f43da88f7c56ada053a494be9977 crypto/armv4cpuid.pl 16739d54200fb81ca7835b5814f965022a2ab41589c7787e2697e3ea72d4fafa crypto/asn1_dsa.c 819c9fd2b0cae9aab81c3cbd1815c2e22949d75f132f649b5883812d0bbaa39a crypto/bn/asm/alpha-mont.pl @@ -54,7 +54,7 @@ b27ec5181e387e812925bb26823b830f49d7a6e4971b6d11ea583f5632a1504b crypto/bn/asm/ 59cd27e1e10c4984b7fb684b27f491e7634473b1bcff197a07e0ca653124aa9a crypto/bn/asm/ppc.pl 0b3350f56d423a4df918a08e90c7c66227c4449a9f9c44096eacc254ebc65f9f crypto/bn/asm/ppc64-mont-fixed.pl a25be64867ab837d93855af232e2bfa71b85b2c6f00e35e620fdc5618187fb6f crypto/bn/asm/ppc64-mont.pl -69d1f8b0e5358b01bcb5ba947e30dd9995f92b8f80dfb41e7c7ea62cea2cd896 crypto/bn/asm/rsaz-2k-avx512.pl +b9fb8777f7e688946c59455eac28e21d6fae8fb2805bcb75c1db17349b623524 crypto/bn/asm/rsaz-2k-avx512.pl 3b9fffe3434c48a3e8e01dac8c33741d7d232b1a45112330d493796eaf06b006 crypto/bn/asm/rsaz-3k-avx512.pl 5abf40162204c8f1900ce7ab48943d1158c26d756c013334c68bd0b0830a035c crypto/bn/asm/rsaz-4k-avx512.pl 231579e532443665020d4d522d9f11713d9c5d5c814b95b434b0f65452e16de4 crypto/bn/asm/rsaz-avx2.pl @@ -78,73 +78,74 @@ da7f7780d27eed164797e5334cd45b35d9c113e86afaca051463aef9a8fd787c crypto/bn/asm/ 259fb8d7f40c0dba46920b1f169d5b37de03b0fda645463d19e3ae2b56de851d crypto/bn/asm/x86_64-mont5.pl 0ea8185a037a2951bb3d1e590bbbdeac305176d5e618f3e43a04c09733a9de34 crypto/bn/bn_add.c 964c7eecef99ef56997cbb90b6560d41e0e90bb1f87dcc5e2a1bf177851c005f crypto/bn/bn_asm.c -14bd5a35c05fcf454854b92fb30b356d7ac618c1eb699dd798f6ad2936d1f5ee crypto/bn/bn_blind.c +22269bec400abc2d4b38f250134070680075aa320a1a8a2e0c4dcd33fd66cd8c crypto/bn/bn_blind.c 7b761d541e3b7f6a3f2b14a09b2b3836a079a845cf67a54db4853e3fd38277c6 crypto/bn/bn_const.c -58b587e20404efa408b31a88ba9c357059ced709bea78c07deb91df7b687db81 crypto/bn/bn_conv.c -2893b6d03d4850d09c15959941b0759bbb50d8c20e873bed088e7cde4e15a65a crypto/bn/bn_ctx.c +7567a675d2b275637209ccced0fd8b47e85bb763065da87809cfc07ce3805124 crypto/bn/bn_conv.c +f53d3804456b787be45ace2b33b7a323e5e4fb6cfbe3aa3b6696e3ce0a640baa crypto/bn/bn_ctx.c d94295953ab91469fe2b9da2a542b8ea11ac38551ecde8f8202b7f645c2dea16 crypto/bn/bn_dh.c 74b63a4515894592b7241fb30b91b21510beaa3d397809e3d74bc9a73e879d18 crypto/bn/bn_div.c -98f5d5ac4bb7cc9ba4326ff48eca6830763c72efe13c97f523714aed082be860 crypto/bn/bn_exp.c +0b5da41b6e2d705898b949568d06920509bf16a9a74dd4de39c406b378cd61b2 crypto/bn/bn_exp.c ec2b6e3af6df473a23e7f1a8522f2554cb0eb5d34e3282458c4a66d242278434 crypto/bn/bn_exp2.c -5d7ece58f63fbf2f3e685b815e6c71c380ec3b09a78d97863b0687bec5010433 crypto/bn/bn_gcd.c -4d6cc7ed36978247a191df1eea0120f8ee97b639ba228793dabe5a8355a1a609 crypto/bn/bn_gf2m.c -081e8a6abc23599307dab3b1a92113a65e0bf8717cbc40c970c7469350bc4581 crypto/bn/bn_intern.c +c9f09aff5b6ba70ca966ca0a0f8f07db980487dd53abf04f52b61f37d8dcd2fb crypto/bn/bn_gcd.c +e37be15f771ab0b1da741266b0081190436edc9b7eb5298be4a0aca0d4c47ada crypto/bn/bn_gf2m.c +73ee247467879d4ec984c9900dfe7761233c5b889b8762be37c7e8fdd6d1d210 crypto/bn/bn_intern.c 602ed46fbfe12c899dfb7d9d99ff0dbfff96b454fce3cd02817f3e2488dd9192 crypto/bn/bn_kron.c -6e07a7bf53d2cc86bd931e89263bbabb8f05ac9c9ce35482b629b4bf889bdaf4 crypto/bn/bn_lib.c +18840c8a7996b619a871efdc834d28556e210b8bddddef606a901f094c45fe81 crypto/bn/bn_lib.c d5beb9fbac2ff5dc3ccbdfa4d1aabca7225c778cff4e3b05b6d6c63e182637f5 crypto/bn/bn_local.h -07247dc2ccc55f3be525baed92fd20031bbaa80fd0bc56155e80ee0da3fc943d crypto/bn/bn_mod.c -f60f3d49b183b04bcdf9b82f7c961b8c1bcb00e68a2c1166fe9edd95a783356e crypto/bn/bn_mont.c +23c47b51cbdab1a8a8e3f3504fae2ceb36c7c227e264d7f4d4fc11c1e0ecdbaf crypto/bn/bn_mod.c +7ddcb7b9b2b008d6f31783c7697d77dd3188d9f643ca948cf49a805d770c3a14 crypto/bn/bn_mont.c 2da73a76b746a47d8cf8ec8b3e0708c2a34e810abde4b4f1241a49e7f5bb2b60 crypto/bn/bn_mpi.c 76982b18b0803d59b33168b260677e7412970757d3b9513de5c80025290f211d crypto/bn/bn_mul.c 1f65ad369352d51af1a75eccf598cb497b400ebd86252f5ca8aac54bbb3cc7bd crypto/bn/bn_nist.c -b93ce358e1cdffcf36466bc6a1e4e050bd35841bb9afbbf5c77158240710ce7d crypto/bn/bn_prime.c +5377e9596c3b9a3153ce75004599dce1f0fef23612d4e086cc936a87d4d5fa99 crypto/bn/bn_prime.c c56ad3073108a0de21c5820a48beae2bccdbf5aa8075ec21738878222eb9adc3 crypto/bn/bn_prime.h -628419eabdb88b265823e43a7a1c88fdfecef79771180836f6089050dc9eadb1 crypto/bn/bn_rand.c -4df8f204c8a06de2b4395be613ca0b9943613c523586e2005876d5c7bb891c75 crypto/bn/bn_recp.c -569cebbb1644d1a4f0df888f17e9f0f474c1066b439e2633dcad415d04932509 crypto/bn/bn_rsa_fips186_4.c +3dd5ce6ddea13d04a9470625af35328319d1a5f3a963183095edf3add314b7e0 crypto/bn/bn_rand.c +b5cc902624b3af2149c9ea91f9d18bea56302144e87dfe49105ec6789b73764b crypto/bn/bn_recp.c +669a157968afe07588507a2e9e35c1c4df9c2b0a95cd9c21404b0bfa21be0d37 crypto/bn/bn_rsa_fips186_4.c 704b0b4723e5c9e9bae5f3e35f9ae8ae8dca3383929e954de9e5169845abfdb2 crypto/bn/bn_shift.c 622e90766b29e0d25f46474429aebda8eba2246835b9e85dc26da7cdbd49334f crypto/bn/bn_sqr.c 42c8ce944c889abcfcf089d0ad2744b7587696d8d7785efa91b3f7ec53dc062a crypto/bn/bn_sqrt.c 24e62baa56e02f2db6454e10168b7c7fa7638db9221b9acda1803d43f38f36e0 crypto/bn/bn_word.c -be27115efd36f0077a3ec26b1ff1f586b0b8969ba05d8ffa34b2ff4badf227bf crypto/bn/rsaz_exp.c +ec684bfc01a74492150e930fe6d6cc5586be48b9674bbd7a492efa517d04c340 crypto/bn/rsaz_exp.c c4d64da1cdc732ea918fccd6a7bb2746b03365dd26f7ba1e74e08c307ca4c58e crypto/bn/rsaz_exp.h -9ec2b47477e22d8ddb708df5ab507a4a5ada49284c1ecdd91ad5e582cf8d4c6e crypto/bn/rsaz_exp_x2.c +55266c387202fd4f90bebfe7bb93c550b23b78dc3a90edcc668e5dbf480f916c crypto/bn/rsaz_exp_x2.c 834db8ff36006e5cb53e09ca6c44290124bd23692f4341ea6563b66fcade4cea crypto/bsearch.c -c39334b70e1394e43f378ae8d31b6e6dc125e4d9181e6536d38e649c4eaadb75 crypto/buffer/buffer.c +82117f6a7cfc31fc86ecd9629bd3bf614126b8e8b2c23717a03ff5c1db7c3c5c crypto/buffer/buffer.c 5f43844b5d8665de9ab895f93599150a327d73ec2674bbf7d7c512d30163022d crypto/c64xpluscpuid.pl -0e1a41a2d81b5765bca3df448f60bf1fad91e485fe89dd65a7300ffc419e316d crypto/cmac/cmac.c -cff758f936cade38b1e41f4d5debd7263b5ef6afe2fe40e6cecfb5533e0ec518 crypto/context.c -c309d81ea991ddf5be4337afad2fd132169f7443c76f863349d3f3c82f3374e4 crypto/core_algorithm.c +40bd11fbe3de4c0fcf16639a3dcfe0f26e3bf447c79f59ec59d7dfc77350a956 crypto/cmac/cmac.c +a6e8cf30340ffaec8aec41dfbef7341afe21e7b13e48899403c529368c0ec6fa crypto/context.c +67c2367871b9350a7f7af5be903d6bcca9ebdbff0e9a9bd9f61b56bef5b76696 crypto/core_algorithm.c f0fd9eb38bf7f196bbb4d26ce8fdf86d0a4f9db219157e66b2c0ffefb4f42005 crypto/core_fetch.c 2f03908edadddc55a61e4cfb4d76751a342f61aad564971df37a6b90c7b2a26f crypto/core_namemap.c -97dfe8dd6278dc0f94f2ea3845b03a8d78cb31ee03c802c4b5822d9bfb28c1c6 crypto/cpuid.c -14ffbee223d679dcc2b365999f7fa5be259582ec53609399c74e2ff09df80899 crypto/cryptlib.c +a7f86c1495a140e5dc2acb737c5ff835691ead833842e0a37bbfc2116530b246 crypto/cpuid.c +a6732e22ccb49cf51fc9dbf23f6059774b70ecc3d7e848c5df112a2d3c179027 crypto/cryptlib.c 66dbfc58916709d5a6913777346083247942a8d9458ee9b2bf443f0ea4988d64 crypto/ctype.c 51e56541daea6d4a26d5bae2ea458414063bf08b045bab8df370f6695903e0a5 crypto/der_writer.c fea3ba4225df97aee90690adf387625b746d8edfdc5af2357ee65151a3d236ac crypto/des/des_enc.c -9da9a319d4391b6d20b646f0de9dc79489f230621b983c4088fef146c79cacea crypto/des/des_local.h +3c5e1c156ebc771701f0adbcfcd099d700796255991c1bf79bd2ca78fc009c87 crypto/des/des_local.h eeef5722ad56bf1af2ff71681bcc8b8525bc7077e973c98cee920ce9bcc66c81 crypto/des/ecb3_enc.c 04d4cc355200b57f1e7d265a2cebdf094df1eb6e96621b533adddc3d60d31fbe crypto/des/fcrypt_b.c 499513b3ad386fe694c4e04b3c8a9fd4c4e18fc44bb6c4f94d6bf2d9362a3a5a crypto/des/ncbc_enc.c 61926e30dd940616e80936d1c94c5f522daf0d475fb3a40a9e589e78f322901e crypto/des/set_key.c 8344811b14d151f6cd40a7bc45c8f4a1106252b119c1d5e6a589a023f39b107d crypto/des/spr.h -816472a54c273906d0a2b58650e0b9d28cc2c8023d120f0d77160f1fe34c4ca3 crypto/dh/dh_backend.c -fcbfe5acb73e1b4094efec56a754b803d2c1a53644c78cf6a73ae868e3f3886d crypto/dh/dh_check.c +a54b1b60cf48ca89dfb3f71d299794dd6c2e462c576b0fe583d1448f819c80ea crypto/dh/dh_backend.c +24cf9462da6632c52b726041271f8a43dfb3f74414abe460d9cc9c7fd2fd2d7d crypto/dh/dh_check.c c117ac4fd24369c7813ac9dc9685640700a82bb32b0f7e038e85afd6c8db75c7 crypto/dh/dh_gen.c 6b17861887b2535159b9e6ca4f927767dad3e71b6e8be50055bc784f78e92d64 crypto/dh/dh_group_params.c a539a8930035fee3b723d74a1d13e931ff69a2b523c83d4a2d0d9db6c78ba902 crypto/dh/dh_kdf.c -9e61a0b5017d835b348b15e93760c42d8d899ffae4251455c7b3085cfd25294c crypto/dh/dh_key.c -92345c259ea2a8c09e6d6b069d0942bd6ca4642231580f3e8148ae7a832a1115 crypto/dh/dh_lib.c +af27b02f3fc5c176bc9f61bc9a67475c5a2a81bce4999f2676311a96059b8dbd crypto/dh/dh_key.c +f7b5a90c76d2bcbea7ed9d8dc340cf3949035eee98f708277edf048d216f58eb crypto/dh/dh_lib.c 8300775d88db0a1aa26a77eb49d6c4f7252e7fee69e1440de4c40edadc9da044 crypto/dh/dh_local.h bbcf4fc3067ac462a27d7277973180b7dc140df9262a686c7fbe4318ca01f7b8 crypto/dsa/dsa_backend.c d7e0d87494e3b3f0898a56785a219e87a2ce14416393ec32d8c0b5f539c7bdbf crypto/dsa/dsa_check.c ae727bf6319eb57e682de35d75ea357921987953b3688365c710e7fba51c7c58 crypto/dsa/dsa_gen.c -100889e879ffba26b3f2cf0a118943e7cf04076e632d76cfacf96c133949791a crypto/dsa/dsa_key.c -9f4837c5abe53613a2dc1c5db81d073d4f42bd28b6a2d1e93a2b350d8e25d52a crypto/dsa/dsa_lib.c -f4d52d3897219786c6046bf76abb2f174655c584caa50272bf5d281720df5022 crypto/dsa/dsa_local.h -c5c252f205482a71efeabe226d51a1c541a6ba2dfa9b8b8a70901087a9dc1667 crypto/dsa/dsa_ossl.c -d612fd05ff98816ba6cf37f84c0e31443ad9d840ed587a7ab2066027da390325 crypto/dsa/dsa_sign.c +9978d27e9fc8ff152830ebb781f71338e56a5e116f29c1c2d59a5a112d86362a crypto/dsa/dsa_key.c +9895a43136d2f68ca0d76d2e47e28f44a1c5061daeb721bd2ca31b6b4dace61f crypto/dsa/dsa_lib.c +f261f9d4f83ecc51ab58de89083e9af4ba4a4c922ccd06b0d628f4b60fc104ec crypto/dsa/dsa_local.h +0b78c4b90b76137c5b2b0dbe286655d0e88b1b4b0bed88730f554d33d2832d9b crypto/dsa/dsa_ossl.c +9776be9ac89d4ea1ed33c2055166a12bff474bc6669660b24da61a63a137cc1b crypto/dsa/dsa_sign.c 53fa10cc87ac63e35df661882852dc46ae68e6fee83b842f1aeefe00b8900ee1 crypto/dsa/dsa_vrf.c +62fbc4465a5b37dc794bee277dd216d77917e715c2bb5d37a7e1735e80ad0f8d crypto/ec/asm/ecp_nistp384-ppc64.pl d9722ad8c6b6e209865a921f3cda831d09bf54a55cacd1edd9802edb6559190a crypto/ec/asm/ecp_nistp521-ppc64.pl 78ad06b88fcc8689a3a846b82f9ee01546e5734acd1bccf2494e523b71dc74d1 crypto/ec/asm/ecp_nistz256-armv4.pl 598da295053253578d5461892098b74ec9dcd02c1eb99d537e14e0c5e958c7b9 crypto/ec/asm/ecp_nistz256-armv8.pl @@ -154,92 +155,92 @@ cfe7e75a2fddc87a7251684469a8808b9da82b2f5725eafad5806920f89932bd crypto/ec/asm/ ac327475c7ec828d11aa05628b4e3b81ec3b1400f30fe7bec01daf3cf71f2dc9 crypto/ec/asm/ecp_nistz256-x86_64.pl cc727533130f5f1a29229929b3d4e8454585d647be25d6344f3c6a0240998368 crypto/ec/asm/x25519-ppc64.pl ee897e230964511baa0d1bf95fb938312407a40a88ebe01476879c2763e5f732 crypto/ec/asm/x25519-x86_64.pl -c0bcde09fd6f1d4682438a6e61365b377a288ce53d1ec81b354d76832bf308fa crypto/ec/curve25519.c -ebd47dd501b147a53ea3c0a0cca18789ac14e2ee4b94e2eed54248992763d454 crypto/ec/curve448/arch_32/f_impl32.c +5fe1cfb5bb13a1aa838453101f5a9783cd6cdd0c5f904d5372a74750ac43c302 crypto/ec/curve25519.c +5daf9f524cd63dd95a2136535b27f2b3d90966562ea5766f4b2d1cd4fccf2502 crypto/ec/curve448/arch_32/f_impl32.c 063dac1e4a9573c47532123e9e03e3532a7473cc3e146521ba9ec6f486ddf3b1 crypto/ec/curve448/arch_64/arch_intrinsics.h 43423b7ee85a5c740c1d81499ee06f4a17732c7731a598e7429d5e402ee77cf4 crypto/ec/curve448/arch_64/f_impl.h -6b01b404354822a5d9cee5ab26f015c362b8ea64be373236e6526bfa67380b51 crypto/ec/curve448/arch_64/f_impl64.c -9b408ec0d43f3b6d714ef5963147e2c2abaddc88633db7dd759193d3c56ed727 crypto/ec/curve448/curve448.c -3c12d90e3fdd59b5d32d63186f1a6f15c75eb73f5035b844a2054356a9459780 crypto/ec/curve448/curve448_local.h +c3146bb6777776d39b89647e3dd3e8afc3d19338c75ff294d6986289cef59c40 crypto/ec/curve448/arch_64/f_impl64.c +cba11345e742cd4eedead0505f92062916ece6fa688cdbdf6466fbea12a7b16c crypto/ec/curve448/curve448.c +a6c70707c520234ccd111562f012e1abf83c43b20b3b36c339ef1ea0369a9e5f crypto/ec/curve448/curve448_local.h 178fb9863c33174b633c2e7607160b1bedb506d66cc06d53382d87431441f306 crypto/ec/curve448/curve448_tables.c f30e13bba5a136ab9ba5225c98b9b94c2cd73fb3aef60f9dcde3cd471cfa1ca4 crypto/ec/curve448/curve448utils.h 4a45e7828831fbe9f282f933cda54b12cd393ec9bffe5c0ace8e4d1c4d5d6358 crypto/ec/curve448/ed448.h -a1211ed3991af967c728b9f6d0774b9ea098d43cef0631ff88984a2580d2ac4f crypto/ec/curve448/eddsa.c -450946e1cccb81e45e5601b6154e2311666b06e294aab926369995af06d1a328 crypto/ec/curve448/f_generic.c -f6447921a0031fa5beddedd298e82096fb3fdb189b712fab328b61f6beae0c23 crypto/ec/curve448/field.h -2ad8331e893b5db33198e27603891587686c0dfdab29706dc52a7097c5d6f219 crypto/ec/curve448/point_448.h +498fda3e0f2d261ab9729ae4de05ff1b496af4582aa019f507570f852d5a2726 crypto/ec/curve448/eddsa.c +9f712e7397b10f1dc88a6d18ff38dcda13d09c02775f3682f2b8698715b1095a crypto/ec/curve448/f_generic.c +070daafb9a532ebb8bc0af8b1341254f0cd3e8932a8c8a2dca7baeef6678768b crypto/ec/curve448/field.h +514014f9fa7835056aab1e6df5511fd7de8ecef3cfcada8e0eadec9b727b419c crypto/ec/curve448/point_448.h 1ff6e467d72530c71d21c310180d04a24f0a9cb41168fba94b43309ecdda3888 crypto/ec/curve448/scalar.c 3052a044afae2e91b677542fc8b34b3ec9d033e0c6562b0d43098cfb34ab3c9d crypto/ec/curve448/word.h ae1637d89287c9d22a34bdc0d67f6e01262a2f8dcef9b61369dba8c334f5a80d crypto/ec/ec2_oct.c -6bbbf570ce31f5b579f7e03ec9f8a774663c7c1eb5e475bd31f8fee94a021ffc crypto/ec/ec2_smpl.c -2a71bd8dbe4f427c117d990581709a4ddce07fa8e530794b5a9574fef7c48a0c crypto/ec/ec_asn1.c -73318950cad070cf883f2883d73ca85adae4125cde85d7feb98a220e6044dc6a crypto/ec/ec_backend.c -86e2becf9b3870979e2abefa1bd318e1a31820d275e2b50e03b17fc287abb20a crypto/ec/ec_check.c -265f911b9d4aada326a2d52cd8a589b556935c8b641598dcd36c6f85d29ce655 crypto/ec/ec_curve.c +9965a95c878438eb94bb0c21876b5a971f47b91f9d22f9c93cf7209a184cd1d1 crypto/ec/ec2_smpl.c +a1f22814f501780591da20de5e724895438094824fce440fd026850c46ad8149 crypto/ec/ec_asn1.c +29783240b377e98006d21b13e984545aa296b26070fd74e77f7d75c01d2616f3 crypto/ec/ec_backend.c +7f19cebad4a94db291464b0d93006a87d15ccec93b94f725052a1037107a96be crypto/ec/ec_check.c +c85f4885f2892dcf074451b137efe0828e486ff5ceadae1fac9b2543fa2114a1 crypto/ec/ec_curve.c 8cfd0dcfb5acbf6105691a2d5e2826dba1ff3906707bc9dd6ff9bffcc306468f crypto/ec/ec_cvt.c -0139b6fc533a885b4a8c2929c3b9c61c676d53e32ddda05c57618714724fa9f7 crypto/ec/ec_key.c -7e40fc646863e0675bbb90f075b809f61bdf0600d8095c8366858d9533ab7700 crypto/ec/ec_kmeth.c -57c6107e235ace603498eadde6bcb03ede2e2e828c0041ed2084a42aa5eb7144 crypto/ec/ec_lib.c -a8a4690e42b4af60aad822aa8b16196df337906af53ea4db926707f7b596ff27 crypto/ec/ec_local.h -fa901b996eb0e460359cd470843bdb03af7a77a2f1136c5e1d30daef70f3e4d2 crypto/ec/ec_mult.c -129c6b42417bfcf582f4a959cfd65433e6f85b158274f4fa38f9c62615ac9166 crypto/ec/ec_oct.c +f4b1f679ca6da3e54121109d4f40b0c46a2366ef48bbf17d8e769f8baaa35f5f crypto/ec/ec_key.c +93f35d2e21d49bb6780d200fda8486edd4a7123956337ba535720bb547a47c4a crypto/ec/ec_kmeth.c +1829428993aa5c51c6322d7d800cb13ccd566bf1f9e38d271f618f1a2315c3c5 crypto/ec/ec_lib.c +eb2f08624819f5d5d865b954a1123a833bc18e9024980f5701125f230e6406b1 crypto/ec/ec_local.h +7417037d376a99498b3044982d72fbe07bcd2cc5b78f73c3665e87c9202af418 crypto/ec/ec_mult.c +5ad8b7c52f91416c5e93b96e1d19f6c0ba1bb8f99d1e382ac43025e8d060a278 crypto/ec/ec_oct.c c7fba2f2c33f67dafa23caef8c3abd12f5336274a9a07d412b83be0366969ee6 crypto/ec/ecdh_kdf.c -b2cf8f052a5716137da7b0e857ed7a5df5fb513b6d14534199a05e32f2b5a866 crypto/ec/ecdh_ossl.c -099f7836a31643c58bda3829090ea81fe3d5acaa4c6f7b145d8355a4293d0ccc crypto/ec/ecdsa_ossl.c +b86a943ae62145438a7214539ceb3e0de5a30e17a6e59742c6e30991db730ab6 crypto/ec/ecdh_ossl.c +e4ac26197ee79f3eed0a08be652bd6a363349e9798f4419a982850e3ba89c8c1 crypto/ec/ecdsa_ossl.c b6baa42b16e8df69a12e0ab101033100cddc808ec2682ba1574373e6ec86ae93 crypto/ec/ecdsa_sign.c f686cea8c8a3259d95c1e6142813d9da47b6d624c62f26c7e4a16d5607cddb35 crypto/ec/ecdsa_vrf.c 141cfc1459214555b623517a054a9e8d5e4065a11301237b7247be2c6f397a0a crypto/ec/ecp_mont.c 13b30f34aeeb0c98747239bfe91b5f0f14e91b2c1f11db62ebb5950c7219daa0 crypto/ec/ecp_nist.c -f288c23b6f83740956886b2303c64d5a3098c98b530859c3bb4b698c01c1643b crypto/ec/ecp_nistz256.c +b19d2ffc6a21405c125e7831a9c1385acad8eea283f52c6b57ac6c8728233ccf crypto/ec/ecp_nistz256.c 51cb98e7e9c241e33261589f0d74103238baaa850e333c61ff1da360e127518a crypto/ec/ecp_oct.c -19f227a48a24d34a1db31f1c4b925ac01a709ba1916a1d3aefec1da4d834d065 crypto/ec/ecp_smpl.c -2096e13aa2fbcb0d4b10faca3e3f5359cf66098b0397a6d74c6fca14f5dee659 crypto/ec/ecx_backend.c +9cf3bacc8a990f6dffe369c28f2f47b192c8d17178185acec601e3fee5b05fac crypto/ec/ecp_smpl.c +aeb2c57685fd610dd1a9d176b70b42cd8d91a252a1e54d3b90b07406d9570883 crypto/ec/ecx_backend.c 5ee19c357c318b2948ff5d9118a626a6207af2b2eade7d8536051d4a522668d3 crypto/ec/ecx_backend.h -22c44f561ab42d1bd7fd3a3c538ebaba375a704f98056b035e7949d73963c580 crypto/ec/ecx_key.c -28abc295dad8888b5482eb61d31cd78dd80545ecb67dc6f9446a36deb8c40a5e crypto/evp/asymcipher.c +72caa2b7d2a54165fb35fea5ec7f5f230a3e9746fa71d56cb345e809bfdaf0a0 crypto/ec/ecx_key.c +64d0ed4018f874f6f88f60eea7b8cc093ebd2495172132603f759445d0bf0edc crypto/evp/asymcipher.c 0e75a058dcbbb62cfe39fec6c4a85385dc1a8fce794e4278ce6cebb29763b82b crypto/evp/dh_support.c -f83e7c6bcc4d0e868eabc9e746c875c40e6df58e839a483449f81e92df314b7c crypto/evp/digest.c +1de49e1fea1892941ce23d6f81c43a9bb29cb006a278321bdbc89b65bf3313eb crypto/evp/digest.c 838277f228cd3025cf95a9cd435e5606ad1fb5d207bbb057aa29892e6a657c55 crypto/evp/ec_support.c -5cc8225a5a4df7a0feeeb5a7fd07bd826072f1c212772094c02ca26024d33b62 crypto/evp/evp_enc.c -4b15287d3ce9cb75cb5ac68003c0deddc2688ffd4abb065eaa04d0998efcbcf9 crypto/evp/evp_fetch.c -ce982249442688249f7c53d0824ae6affb1cf89281f35fbd68c1e0c4c57217d3 crypto/evp/evp_lib.c -5afebfcf415079974ab3b8b70eac93b618fd264135cd68fee5834edffc60ce22 crypto/evp/evp_local.h -958c32605960fff7a56ddbf2708a9b74f0e30d00c9e415e1fd111fefd3feb0b5 crypto/evp/evp_rand.c +1dc7f3a30b9c68d53023cdfb7313908248bc339e173ba60c9fa38a2c11194962 crypto/evp/evp_enc.c +2531ea569aeb8805180a963373ed7eac52acc5eb45d12bda03316bb8a1a8ed47 crypto/evp/evp_fetch.c +f70344599d39e667978e939c553abd3a3dd6660541378d44e1c438f31f5d71a6 crypto/evp/evp_lib.c +33c1282761af93b4a17565dd30f8f031729ef09fc3d643b2a812f8c4ef0df570 crypto/evp/evp_local.h +eaaf795148c5dd99c4194d076c029c843f3aee0c37afeb0dac43a86fd931ac68 crypto/evp/evp_rand.c 2a128617ec0178e9eeacbe41d75a5530755f41ea524cd124607543cf73456a0c crypto/evp/evp_utils.c -ca8c6cfd30efd53f2e5d1f19bcf09a3a3d0dff6d8947c3943d07a3f4b354aa86 crypto/evp/exchange.c -9e25042581b73e295c059c6217f3ecf809134d518eb79b1b67f34e3ca9145677 crypto/evp/kdf_lib.c -1d72f5506984df1df8606e8c7045f041cf517223e2e1b50c4da8ba8bf1c6c186 crypto/evp/kdf_meth.c -5179624b8e03615dc9caedc9ec16d094fa081495613dd552d71c2c39475bcd83 crypto/evp/kem.c -5016dd7ef8b4cf7e9ea8465c18d1daa4c8808cb589261cf236058ee75bc868d7 crypto/evp/keymgmt_lib.c -4c4f49b0305fe3977e04a4315f24470f6e190a3e25735d5dd512d430e2140290 crypto/evp/keymgmt_meth.c -e1a052839b8b70dca20dbac1282d61abd1c415bf4fb6afb56b811e8770d8a2e1 crypto/evp/m_sigver.c -4290c95f63b43688a8da57690d122add5161a6811f9753da1444d28f46739961 crypto/evp/mac_lib.c -e7e8eb5683cd3fbd409df888020dc353b65ac291361829cc4131d5bc86c9fcb3 crypto/evp/mac_meth.c -546d83abecf8973e2d872102a03bde5a46552909fa9e7d1402e1464a27453801 crypto/evp/p_lib.c +a9e940b29f3064e771eeafe9d4d0e6d1f7258cd61a57258faabdbe8121764986 crypto/evp/exchange.c +294284ad040fe4b74845f91b1903c961c757e1ef3fcc2ffa35f43f37f1655e64 crypto/evp/kdf_lib.c +9328c7ea06e0719aaff2d59c959d1b7907b9e6a337f784680e2e289e8c3e4328 crypto/evp/kdf_meth.c +c67d90f42c4d2294ecd103bdb02296a13248ead4aebadc3aead0cb964e171d81 crypto/evp/kem.c +c4c8a30541a51d50872f03994829419a72d52c8207f9047fdc6fd28dfd43c057 crypto/evp/keymgmt_lib.c +43a8d931d2abceea1c009b62f93bd720fa33e261491d395ec6857462db4bef77 crypto/evp/keymgmt_meth.c +41f2e8d9fca78dfce6116e659fdefbdeb590cee567d5f9681eb2c028c0b5c424 crypto/evp/m_sigver.c +2a1207fc3108d1aef4fc10f5d450dc344214f3cfff7a6e9688468c12846d4b64 crypto/evp/mac_lib.c +036307223518ec03a93c9e519cbad9903341bf105642b6b694a791d31a1f232c crypto/evp/mac_meth.c +a93bf4ee0562235dab615562e1780c704bdf58aa62457511ae206ab1d0e2c760 crypto/evp/p_lib.c 3b4228b92eebd04616ecc3ee58684095313dd5ffd1b43cf698a7d6c202cb4622 crypto/evp/pmeth_check.c -1f0e9e94e9b0ad322956521b438b78d44cfcd8eb974e8921d05f9e21ba1c05cf crypto/evp/pmeth_gn.c -76511fba789089a50ef87774817a5482c33633a76a94ecf7b6e8eb915585575d crypto/evp/pmeth_lib.c -4b2dbddf0f9ceed34c3822347138be754fb194febca1c21c46bcc3a5cce33674 crypto/evp/signature.c -600a90728cea180e3c9f6ac5269fa86fef82494f9cde3d8914df3387c80afbfd crypto/ex_data.c -1c8389c5d49616d491978f0f2b2a54ba82d805ec41c8f75c67853216953cf46a crypto/ffc/ffc_backend.c +759573aea2a4cc7b6f763b440e6868bfcfcb7ca94d812fa61ab24a194be2cb36 crypto/evp/pmeth_gn.c +7d9dfc974d15a2b7e2c1c6c54a594f0a14ccdfe5e2e1afe84a3a52130ac8097b crypto/evp/pmeth_lib.c +76d005962440945c127571ca3b3ece7c55944828b41d48c0bd1b819bd40408ab crypto/evp/signature.c +64f7e366e681930ba10267272b87dba223b9744a01c27ba0504a4941802a580d crypto/ex_data.c +d986ec74995b05ff65a68df320ab45894ba35d7be4906f8d78ca5fca294a4e6c crypto/ffc/ffc_backend.c a12af33e605315cdddd6d759e70cd9632f0f33682b9aa7103ed1ecd354fc7e55 crypto/ffc/ffc_dh.c 854378f57707e31ad02cca6eec94369f91f327288d3665713e249c12f7b13211 crypto/ffc/ffc_key_generate.c 4e973d956d4ec2087994de8e963be1a512da1441f22e6e7b9cd7ee536e3ff834 crypto/ffc/ffc_key_validate.c -8b72d5a7452b2c15aec6d20027053a83f7df89d49a3b6cfedd77e2b1a29e9fc1 crypto/ffc/ffc_params.c -1a1d227f9a0f427d2ec93bc646c726c9cd49a84a343b4aff0c9c744fa6df05a9 crypto/ffc/ffc_params_generate.c +b6bc7a9c2887b459d2a4e202e3ca5d637ad169e023d7353be3d4ef6082fda96b crypto/ffc/ffc_params.c +c9c635805b26d85e8c0c7720592fb04b674cde4339fcd94712a4403e8677cb41 crypto/ffc/ffc_params_generate.c 73dac805abab36cd9df53a421221c71d06a366a4ce479fa788be777f11b47159 crypto/ffc/ffc_params_validate.c 0a4fc92e408b0562cf95c480df93a9907a318a2c92356642903a5d50ed04fd88 crypto/hmac/hmac.c 0395c1b0834f2f4a0ca1756385f4dc1a4ef6fb925b2db3743df7f57256c5166f crypto/hmac/hmac_local.h 0e2d6129504d15ffaf5baa63158ccec0e4b6193a8275333956d8f868ef35127e crypto/ia64cpuid.S 3f123f7de496711fa60c47aeaef96640571dbcb1657b23901307e04c3d712579 crypto/initthread.c -f91d8ca9ac5e7f6ba3282ab53700acf7dc477972d2effd239518043eb1a59a96 crypto/lhash/lhash.c +ee895c071ffb217e0f223d5546ae84cadde6701af67e718e9af7f06af531fa42 crypto/lhash/lhash.c 5d49ce00fc06df1b64cbc139ef45c71e0faf08a33f966bc608c82d574521a49e crypto/lhash/lhash_local.h a4f8f200ca749db91da97735c107836dfb2b623424b15c020ec6e48d874f4564 crypto/loongarch64cpuid.pl 460a7af09cde89a820b091522ada1310cfcec99c60aee505f94c48c35e9a29e8 crypto/loongarchcap.c f866aafae928db1b439ac950dc90744a2397dfe222672fe68b3798396190c8b0 crypto/mem_clr.c -6351926545a33d221103a727837ef3810764c3b0c8f735150e82d85f86f5bd7a crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl +36e24eae5d38cc9666ae40e4e8a2dc12328e1159fea68447cb19dab174d25adf crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl 580b90b1a2b4324afbe680c3ff59d58d0eff0b59511e5cf56fb119d2634c9a3b crypto/modes/asm/aes-gcm-armv8_64.pl -4fc1e83482ecc5c6cd01f1e1ccb7b84aa39993f1445e529062b7d4041a7eb190 crypto/modes/asm/aes-gcm-avx512.pl +4872c6bc2988f5307b4d8ce7ed87c98e7fb7e03503fe7144bc590ee234eb60f7 crypto/modes/asm/aes-gcm-avx512.pl 400a202abf66c6a3430965c38f7164ac297c856e8585862f59e3ff188bb35a6b crypto/modes/asm/aes-gcm-ppc.pl 1d686af304f94743038f916125effcb51790c025f3165d8d37b526bbeee781f0 crypto/modes/asm/aesni-gcm-x86_64.pl c2e874a8deb418b5d8c935b2e256370566a5150e040c9fa008cdb5b463c26904 crypto/modes/asm/ghash-alpha.pl @@ -247,7 +248,7 @@ c2e874a8deb418b5d8c935b2e256370566a5150e040c9fa008cdb5b463c26904 crypto/modes/a 097975df63370de7ebea012d17de14fc1f361fb83acf03b432a99ae7d5bceb24 crypto/modes/asm/ghash-c64xplus.pl fdde3bc48b37790c6e0006014da71e7a831bbb4fdbfcda2d01dbe0ceb0ba88fa crypto/modes/asm/ghash-ia64.pl e472d73d06933667a51a0af973479993eed333c71b43af03095450acb36dbeb4 crypto/modes/asm/ghash-parisc.pl -b7e66337683b00148796478563d985f727fddf7f433896046c4ab1f9f24b7624 crypto/modes/asm/ghash-riscv64.pl +494b4b36fd7c7d0e464be76f723c46ae7ad173593ff0556525edfdc974e66c32 crypto/modes/asm/ghash-riscv64.pl 92071f9c046f312c4eb7df483f385bc71ade863392e1acf3e821912bcc5cfaa7 crypto/modes/asm/ghash-s390x.pl 6af1a05981e1d41e4dea51e58938360e3abc4a4f58e179908242466d032b1a8a crypto/modes/asm/ghash-sparcv9.pl 26f55a57e77f774d17dfba93d757f78edfa3a03f68a71ffa37ccf3bfc468b1e2 crypto/modes/asm/ghash-x86.pl @@ -258,52 +259,54 @@ a4e9f2e496bd9362b17a1b5989aa4682647cefcff6117f0607122a9e11a9dfd9 crypto/modes/a 1611e73dc1e01b5c2201f51756a7405b7673aa0bb872e2957d1ec80c3530486f crypto/modes/ccm128.c d8c2f256532a4b94db6d03aea5cb609cccc938069f644b2fc77c5015648d148d crypto/modes/cfb128.c af1c034152d82b29cb7c938c8516cfd136b62bac0908c1d40eb50790d23b288c crypto/modes/ctr128.c -df064432bdd596550920b7a5807811116d24bb11d17729f8d49033418964bed1 crypto/modes/gcm128.c +130d41dd729fae0ce75ea0c1e0f27091b6239a31c5a94d24759cc1b0504ea6ad crypto/modes/gcm128.c bdf25257b15eca206be4d950d2dd807ca5f058f91f54edbd7a0d312ed83eef8e crypto/modes/ofb128.c e55a816c356b2d526bc6e40c8b81afa02576e4d44c7d7b6bbe444fb8b01aad41 crypto/modes/wrap128.c 608a04f387be2a509b4d4ad414b7015ab833e56b85020e692e193160f36883a2 crypto/modes/xts128.c -dc2a6064c95ec84e8f73181123cad0721ca3931b922e2872d77bde1704f0cea4 crypto/o_str.c -8ddbbdf43131c10dcd4428aef0eff2b1e98b0410accada0fad41a4925868beef crypto/packet.c -f86fbec8357ef5bbc6442d11717db88a57a7f453fac4b082282b1370abace9e2 crypto/param_build.c +fb874ea18e9754dde11ef1c2993818074ff7cd8a74a981598745f7e11317bb91 crypto/modes/xts128gb.c +f89e6864ebbff6321e360a6543d45b5f30773a86217ef37c7dfc146b7aa49d4b crypto/o_str.c +b0decda3aae1d3e07cf3cbe9153cdde9deafe65fae346cd208951b4d7dec512e crypto/packet.c +fb60966da0d636a59921c7eeadebedb79caa9667eb1622330ab7e1f31a8d24eb crypto/param_build.c cae7bd4973d36edbdc3bdd8d2c8d157f2c4fcfae00fdf821b67aebb789bc8aa6 crypto/param_build_set.c -ce0e3fb4f466947b58d19a6fbc6c909ba0767b752ec8f563bfa7a8497b9a67d7 crypto/params.c -5aed5133eac67516866a8187ec875ff2f8abac4272f80264b52fa225b732dc4a crypto/params_dup.c -a0097ff2da8955fe15ba204cb54f3fd48a06f846e2b9826f507b26acf65715c3 crypto/params_from_text.c -98eb56498937aca2d4fca8670760485f8b342b7dcd84442f8e114d47310eacbf crypto/ppccap.c +a267f41a7dead2b1f7ea35ad7d2d04db50cb75d0fb20fbc2fa72ba7ea4dc34a0 crypto/params.c +bb7b79b5a070050f5e7dfc66b5635f0891bc278e3e24eec3583b769b33bef657 crypto/params_dup.c +b2bd2b5cf3de2fe130223470da22fe4c1b08e75f0c10fcb7d0c089c9f9851f78 crypto/params_from_text.c +d8c11b10fad7c291f1c31f4639761995941760cdf964a1a24b6800a56c77ffcf crypto/params_idx.c +c27b8c1659274be74e2d6e9fd76980df499d1331c0c2d51f41b3ad547ba88d59 crypto/ppccap.c 46fa4994a6234a98a2845d9337475913f6bc229f1928abc82224de7edf2784b8 crypto/ppccpuid.pl 467c416422ecf61e3b713c5eb259fdbcb4aa73ae8dee61804d0b85cfd3fff4f7 crypto/property/defn_cache.c -0d6df2dfb9896ed00c27e97f190ccd9d581e54e16fb1cbaba587ad1b34c5f1b2 crypto/property/property.c +289f8d0569123201d700934663fabf7215079731a4ea2f5db7944a6cb80d9868 crypto/property/property.c 66da4f28d408133fb544b14aeb9ad4913e7c5c67e2826e53f0dc5bf4d8fada26 crypto/property/property_local.h 79011789ce1c74d41cbd611d11eecccb0355b9318a53917f362bb8ccec67e417 crypto/property/property_parse.c a7cefda6a117550e2c76e0f307565ce1e11640b11ba10c80e469a837fd1212a3 crypto/property/property_query.c 20e69b9d594dfc443075eddbb0e6bcc0ed36ca51993cd50cc5a4f86eb31127f8 crypto/property/property_string.c -8bf2a635dbd2977f8e52506fc23392c9be78d1928114c1754c8d577916645082 crypto/provider_core.c +bf5e9f8e49672afc09f4130ba300844d4412f9e3467985f693da70e34f1a4f3a crypto/provider_core.c d0af10d4091b2032aac1b7db80f8c2e14fa7176592716b25b9437ab6b53c0a89 crypto/provider_local.h 5ba2e1c74ddcd0453d02e32612299d1eef18eff8493a7606c15d0dc3738ad1d9 crypto/provider_predefined.c -aec47f5e7ec054226692df055a90305fd0dbaf0fbf20b56df353c04a2c2725e0 crypto/rand/rand_lib.c +d2851ce0930b36e6f1fbc593a756d9a7c8097eb6b0ace163cecd917c8e9637dd crypto/rand/rand_lib.c fd03b9bb2c23470fa40880ed3bf9847bb17d50592101a78c0ad7a0f121209788 crypto/rand/rand_local.h f67fcf8351b046a00cf1baea29aefab3b4fc9521e0ba508abdd1a9ca44de40c3 crypto/riscv32cpuid.pl c0ff6a8ca7f52f759a945c4d475d00168b12386324e8177f301127b405ca793e crypto/riscv64cpuid.pl a0870a2d4189788a4500227e7142f2fd9805357ecf083699273ef94b1f455ae3 crypto/riscvcap.c f0c8792a99132e0b9c027cfa7370f45594a115934cdc9e8f23bdd64abecaf7fd crypto/rsa/rsa_acvp_test_params.c -5834d7c518ad53ea0dd3db811c0e51568c81cc6c117012030101d29003d0725c crypto/rsa/rsa_backend.c +d7b0bf9184e8221df848fed283aa3c81722a1057890c15444a850017eaaa7757 crypto/rsa/rsa_backend.c 38a102cd1da1f6ca5a46e6a22f018237964336274385f5c70cbedcaa6997647e crypto/rsa/rsa_chk.c -e32cfa04221a2a3ea33f7bcb93ee51b84cbeba97e94c1fbf6e420b24f97fc9ce crypto/rsa/rsa_crpt.c +e762c599b17d5c89f4b1c9eb7d0ca1f04a95d815c86a3e72c30b231ce57fb199 crypto/rsa/rsa_crpt.c e995da1c2e5007bd7f5907f369fe45ed15f4e657143a85078c755bd5e6863d0b crypto/rsa/rsa_gen.c -f2222f270e57559537d3da8abbeb1390bc5376b73dae59d536af6e73eb48bba0 crypto/rsa/rsa_lib.c +1ef5f7b08d8b932b87d945931d8e2f557d53c291055a85319b21711fc572ecf7 crypto/rsa/rsa_lib.c a65e85be5269d8cb88e86b3413c978fa8994419a671092cbf104ff1a08fda23b crypto/rsa/rsa_local.h cf0b75cd54b61b9b9a290ef18d0ddce9fb26a029a54eb3f720d9b25188440f00 crypto/rsa/rsa_mp_names.c 5c60f6e05db82e13178d805deb1947b8eee4a905e6e77523d3b288da70a46bb5 crypto/rsa/rsa_none.c -33de2accc3af530fd0a4758eb83d5e1d994bf49bac4512b01387dbae656e1a7d crypto/rsa/rsa_oaep.c -e05fcad237b7e4e7842ad6e142789fe25d060247283c337c78703be6ecc31ed9 crypto/rsa/rsa_ossl.c -be3f39c1fcb777d6c0122061f9ef735d10a6bee95d67fcc1ca6ae2a664022d2b crypto/rsa/rsa_pk1.c -04b3d6145d36262d7b8f625a2595a48ea8cbf2190b2760762c1eef3cdb8566c0 crypto/rsa/rsa_pss.c +d0538475c5ebd2b2c585dc33fdcfb9a7a2f59f623b7ab0f8a09344a439082dfc crypto/rsa/rsa_oaep.c +6adc9202558e531f4d78c75920882e916be27395dca386044a91adae5b331c64 crypto/rsa/rsa_ossl.c +54446a41065d85d22ed521285196bf285427a071d32d00d070b2248723c2a914 crypto/rsa/rsa_pk1.c +cdf66a4964152e16b7da5b6631f31bd2d90bf730b5a46c2622d5279abdecabe1 crypto/rsa/rsa_pss.c bf6d300b7e7e9e512a47c5bd1f8713806ae3033a140d83dfae4a16ad58d11170 crypto/rsa/rsa_schemes.c -f01af62704dbf9457e2669c3e7c1d4d740f0388faa49df93611b987a8aa2bf11 crypto/rsa/rsa_sign.c -740c022caff3b2487c5838b581cdddcc7de2ceabb504aad72dc0dd70a67bf7cf crypto/rsa/rsa_sp800_56b_check.c -3aba73dacebb046faf8d09dc279149b52c629004b524ec33e6d81c8ad0bc31a8 crypto/rsa/rsa_sp800_56b_gen.c +58db0509f34d970a2f206d468f718c17513970315d5d5ec92822fe6f4b6523fa crypto/rsa/rsa_sign.c +8deac6380d86a43bb81c0ee9ffde642931bdc98a4f120653cb14ceb33c5c39a3 crypto/rsa/rsa_sp800_56b_check.c +8eee673d98a640e30a245556ea046080d4272d20832f0c29157ec9a23cc43d3a crypto/rsa/rsa_sp800_56b_gen.c 1c1c2aeeb18bf1d69e8f134315b7e50d8f43d30eb1aa5bf42983eec9136a2fdc crypto/rsa/rsa_x931.c -630b267c189964f2d1ffbf50e6588e8409cbf87e1e49edaec81b57b6f845df34 crypto/s390xcap.c +4bf7f5cbbf7bf0e6c904b8c4988d077842cdd6aed0ad184cbfa4d4b3bfee79af crypto/s390xcap.c 22205848cfb55116ebf999dced8331b575886a609ce29e6886e6267b2310c337 crypto/s390xcpuid.pl 465f850c3d6f2e9410f2e1ee9604b1b5b80f99bae1f6c581161c2f7ebc2c6e41 crypto/self_test_core.c 05c533fde7fdba0c76103e97d881b7224c8427451b453e2f6413552996063e31 crypto/sha/asm/keccak1600-armv4.pl @@ -348,137 +351,158 @@ fb06844e7c3b014a58dccc8ec6020c71843cfdc5be08288bc7d204f0a840c474 crypto/sha/asm 0611845c52091b0208dd41f22ddef9dd1e68d3d92fa4c4360738b840a6314de6 crypto/sha/asm/sha512-sparcv9.pl f64d16c1e5c3fa4a7969de494a8372127502171a517c14be7a1e3a43a7308699 crypto/sha/asm/sha512-x86_64.pl 8725cabb8d695c576619f19283b034074a3fa0f1c0be952a9dbe9793be15b907 crypto/sha/asm/sha512p8-ppc.pl -57f6cf54b1b5d2cac7a8f622b7b6bd1878f360fff3fa0f02352061c24162ebbb crypto/sha/keccak1600.c +83d52563e8b85ebf9e3448392c0b535a8564b7aaafc595e7a6653035a4511155 crypto/sha/keccak1600.c 306cacd3f86e5cacaca74c58ef862516515e5c0cafaff48636d537fd84f1c2fb crypto/sha/sha1dgst.c -58f6bacfa26273c9cf1b7b11dd2456253f44f20958905f7cb9d0f8eaf40f9591 crypto/sha/sha256.c +af4756bfeeabca490834f51e45e3fd726b5bbb35bb682b73d857a8c2e080c64f crypto/sha/sha256.c 3d972a11be18bfbfcd45790028635d63548bfe0a2e45d2fc56b6051b759d22f0 crypto/sha/sha3.c dc89d6740cfb58729e3276e03d290ae8319c6b081bfeaf21a0aa15ffb9839e17 crypto/sha/sha512.c 6c6f0e6069ac98e407a5810b84deace2d1396d252c584703bcd154d1a015c3ea crypto/sha/sha_local.h 9ef5a01caccc2eb15f72e367d0424737040ac8018479bbbbce3d216c655765c2 crypto/sparccpuid.S 5056b14a55665ffa342a9a1bb32c1c36886add5d0819869193427f33cee028f7 crypto/sparcv9cap.c c50c584c55e56347bb43aca4b796b5344d70daece3061f586b79c871c21f5d1a crypto/sparse_array.c -8da78169fa8c09dc3c29c9bf1602b22e88c5eac4815e274ba1864c166e31584b crypto/stack/stack.c +cd677fd62171621d5e6b142df164aa847149ef4a01f6e3cea4516dcb137824e7 crypto/stack/stack.c +c0c4fd0f112465c6766072e25268c2f9019430e2c08c3c0a4271603d24d79f04 crypto/thread/api.c +e298c753be277ad9a2ac0132d9897cb4c85607dbb2d11cfefd0c98e0f6a723d9 crypto/thread/arch.c +5c02ff77d290ca0deb19672c1ed6fc0f47a0d630f61398a204a2684a7d418f0a crypto/thread/arch/thread_none.c +1506ddf108b99cd192b70dbb00154fbb5e632527fa0ef56796bda4c68f833464 crypto/thread/arch/thread_posix.c +a00e16963e1e2a0126c6a8e62da8a14f98de9736027654c925925dadd0ca3cc1 crypto/thread/arch/thread_win.c +27ec0090f4243c96e4fbe1babfd4320c2a16615ffa368275433217d50a1ef76c crypto/thread/internal.c 67ba8d87fbbb7c9a9e438018e7ecfd1cedd4d00224be05755580d044f5f1317a crypto/threads_lib.c -a41ae93a755e2ec89b3cb5b4932e2b508fdda92ace2e025a2650a6da0e9e972c crypto/threads_none.c -3729e2bd36f945808b578e0d89fac0fcb3114e4fc9381614bcbd8a9869991716 crypto/threads_pthread.c -88423960f0414f6fd41fba4f4c67f9f7260c2741e4788adcd52493e895ec8027 crypto/threads_win.c +5128f6ff98a37b6f9266c6b776020a62e536d8e9e05212c600f42150f32d3d23 crypto/threads_none.c +e29e0fc64feaa71c68da6e5f2fa8a00853f9b2d6a8b516eb474bde51e23065f6 crypto/threads_pthread.c +88b1a6c282ea8e6d3eff5c0808894b49e4b4883847ed45ed448e99249dacf499 crypto/threads_win.c +8b45f948303045d8f753858b1b892e3da13bebe1bdac500db91fbb54a0ac07da crypto/time.c fd6c27cf7c6b5449b17f2b725f4203c4c10207f1973db09fd41571efe5de08fd crypto/x86_64cpuid.pl bbec287bb9bf35379885f8f8998b7fd9e8fc22efee9e1b299109af0f33a7ee16 crypto/x86cpuid.pl -38dd75fe46a8ead29d4593488cfed0d2806e77b0572117549e7b0498296d501f include/crypto/aes_platform.h +77f42b25acf539a55fa9edc3bf4db21247da5d118c4a0ca212c32a7151652344 include/crypto/aes_platform.h +68f6c521b1dbfacb99d75cb1ffdbcd1795d6e0157df69c6c6a7c04f85ea715ec include/crypto/asn1.h 8c6f308c1ca774e6127e325c3b80511dbcdc99631f032694d8db53a5c02364ee include/crypto/asn1_dsa.h -feec318e3875def5c5b6cf9ade636e1bc2f3f200d2390f39152eb9ef7d8e7ce7 include/crypto/bn.h +d95af0a278bc2edef9c3e1129fc6e7b1577b1ea95249b05ef39c4a4847e9ddac include/crypto/bn.h 1c46818354d42bd1b1c4e5fdae9e019814936e775fd8c918ca49959c2a6416df include/crypto/bn_conf.h.in 7a43a4898fcc8446065e6c99249bcc14e475716e8c1d40d50408c0ab179520e6 include/crypto/bn_dh.h -04efb7f98705423b2a63a697a174d37c66d12edf349770e8433b2da5301be390 include/crypto/context.h +a6957475e4c7ae80c06537c3fd3b63f2368b664da54a96befd0a6fa38de27b4a include/crypto/context.h e69b2b20fb415e24b970941c84a62b752b5d0175bc68126e467f7cc970495504 include/crypto/cryptlib.h 6c72cfa9e59d276c1debcfd36a0aff277539b43d2272267147fad4165d72747c include/crypto/ctype.h +09a27585de4638577b482ec9102a0e70d843dee6297a2d45e27d888f6de5e27f include/crypto/decoder.h 89693e0a7528a9574e1d2f80644b29e3b895d3684111dd07c18cc5bed28b45b7 include/crypto/des_platform.h daf508bb7ed5783f1c8c622f0c230e179244dd3f584e1223a19ab95930fbcb4f include/crypto/dh.h -20d99c9a740e4d7d67e23fa4ae4c6a39d114e486c66ad41b65d91a8244cd1dea include/crypto/dsa.h -2ea47c059e84ce9d14cc31f4faf45f64d631de9e2937aa1d7a83de5571c63574 include/crypto/ec.h -edbfae8720502a4708983b60eac72aa04f031059f197ada31627cb5e72812858 include/crypto/ecx.h -596d8efb42a05d3d11fa81d38193828b46e812f7b2553f2bfaf398b35b7b1da8 include/crypto/evp.h +679f6e52d9becdf51fde1649478083d18fa4f5a6ece21eeb1decf70f739f49d5 include/crypto/dsa.h +c7aafee54cc3ace0c563f15aa5af2cdce13e2cfc4f9a9a133952825fb7c8faf5 include/crypto/ec.h +2d8cba492193c170d1f759508556188a568cabe5960020b9a889b69838adbfa4 include/crypto/ecx.h +57c3e27c5aa599c961292a86d82137234385084faa559798968465ff9e300fac include/crypto/evp.h bbe5e52d84e65449a13e42cd2d6adce59b8ed6e73d6950917aa77dc1f3f5dff6 include/crypto/lhash.h -9190c0b67ead73be80c0b9e53a492bbbc7f22641e6abed82e105fd80198595c4 include/crypto/md32_common.h -cf90ee889f93092e260ae6d7a01bbefbf3ad8651153729206e45db671bac3dab include/crypto/modes.h -b194efe362380fe989e1f6cbd96c0899496949f17676f3a1ee541731511ce672 include/crypto/rand.h +906bc2316e4f4651e5db7a8273ec3bb4bcbfb55f0f484bebdae4f6d0ce033bdf include/crypto/md32_common.h +6e7762e7fb63f56d25b24f70209f4dc834c59a87f74467531ec81646f565dbe3 include/crypto/modes.h +920bc48a4dad3712bdcef188c0ce8e8a8304e0ce332b54843bab366fc5eab472 include/crypto/rand.h 90930fc8788d6e04e57829346e0405293ac7a678c3cef23d0692c742e9586d09 include/crypto/rand_pool.h -306abf9d327a9e63fff2cdef730275abc4d2781254a032b1f370f3428eb5a2ef include/crypto/rsa.h +2f502340909e531a9a7c71451400eb68a53bf62015c17b0169b1efffb0703882 include/crypto/rsa.h 32f0149ab1d82fddbdfbbc44e3078b4a4cc6936d35187e0f8d02cc0bc19f2401 include/crypto/security_bits.h -0f743762f646656b5480648c05632575fe8acc7506460c63e0fcdf42cf20c08a include/crypto/sha.h +80338f3865b7c74aab343879432a6399507b834e2f55dd0e9ee7a5eeba11242a include/crypto/sha.h 7676b02824b2d68df6bddeb251e9b8a8fa2e35a95dad9a7ebeca53f9ab8d2dad include/crypto/sparse_array.h 7ad02c7de77304c3b298deeb038ab2550cf8b2bce03021994477c6c43dbcf86e include/crypto/types.h -782a83d4e489fd865e2768a20bfa31e78c2071fd0ceeb9eb077276ae2bcc6590 include/internal/bio.h +27d13538d9303b1c2f0b2ce9b6d376097ce7661354fbefbde24b7ef07206ea45 include/internal/bio.h +92c4187dc051dbab777271e6976eb10bc90197abfd9b0d6f20bc17503f54564d include/internal/common.h 92aacb3e49288f91b44f97e41933e88fe455706e1dd21a365683c2ab545db131 include/internal/constant_time.h c5bb97f654984130c8b44c09a52395bce0b22985d5dbc9c4d9377d86283f11f8 include/internal/core.h -7b5b7c98d783cc5ae769f59c1973f0f46117116abf766e72b6837228412bb030 include/internal/cryptlib.h +424b502d52e7b12877be283628001bc699d221ab4da7007d5123f7e2f3eac9de include/internal/cryptlib.h 9571cfd3d5666749084b354a6d65adee443deeb5713a58c098c7b03bc69dbc63 include/internal/deprecated.h -3325b895d15c0a6341f456a8d866a0f83e80fc8a31a01c34fcfd717715b33075 include/internal/der.h +dc5afb955d810feb5af9f8d25cd8a92118abef320fee95c07b04f301c4e0d96c include/internal/der.h +8059e715f981fbe02b5731610ed24bb6ae617a55e90b03f4260cbb6ccd71e8de include/internal/deterministic_nonce.h fd1722d6b79520ee4ac477280d5131eb1b744c3b422fd15f5e737ef966a97c3b include/internal/dso.h f144daebef828a5bd4416466257a50f06b894e0ce0adf1601aa381f34f25a9e7 include/internal/dsoerr.h -f73c8f38f60fb6c15f59b53167f2591f3253c7afef9cec7ba5b53ecde11d466d include/internal/e_os.h +99276e4650bfdcddac06eaa70dd2e255b30b61ebd8ef948384e28b1dd17ddb61 include/internal/e_os.h 70d3e0d5a1bd8db58dcc57bea4d1c3ed816c735fe0e6b2f4b07073712d2dc5ef include/internal/endian.h -094b69aeb8f349cafa8865b577e253132088c25eabb61b910fab141e6f7d2929 include/internal/ffc.h +4838a68ff626825c261df6a1fd21e156e25d8365af45552f29054d7038a7db3d include/internal/ffc.h 55c4102496ed5ab16de11afe38c328a1396c3b6e2c7e44add4a38855103c19da include/internal/namemap.h b02701592960eb4608bb83b297eed90184004828c7fc03ea81568062f347623d include/internal/nelem.h -ae41a2fb41bf592bbb47e4855cf4efd9ef85fc11f910a7e195ceef78fb4321dc include/internal/numbers.h -b89cca3b727d4526b459246de11e768a20333555bf3a9ed9a9b8beb2b565dc7f include/internal/packet.h -dd7ddecf30bef3002313e6b776ce34d660931e783b2f6edacf64c7c6e729e688 include/internal/param_build_set.h +3363405b2d6afab68f7e13921385ccb648fe7f77522bd0aa5fdf2d7af0b87660 include/internal/numbers.h +66f7c420e531383e8a93c1daccbdc4ab64d11e0ed167af1b7f7be54bd61329aa include/internal/packet.h +f42d4a6108a18ade3eb99682c072adf83889b6ba3fc80ee3e20929ed8d0f7137 include/internal/param_build_set.h +5c6c98b1a642b999c909c7cfb91e7925422fbd0b9eca56210ea745bc20668783 include/internal/param_names.h.in +46d7980258a8d11353af3e3dab87c368eec054e46ac8a0facec68b23ba94d91b include/internal/params.h d4ac19b28ea61f03383364cfad1e941cac44fc36787d80882c5b76ecc9d34e29 include/internal/property.h 727326afb3d33fdffdf26471e313f27892708318c0934089369e4b28267e2635 include/internal/propertyerr.h -9a73c9ac02eb93a8399381862397bc27fbf8abb7523b07e9f1da9f2e66a913ae include/internal/provider.h -80d7d12b8b3d9945bde3991cb0d1413d120a58a04b17ac673549789e3f37b18a include/internal/refcount.h +811eff73f789e535530cf23ea6037d4da6cde53398e0e7063e60c68b8923a9b5 include/internal/provider.h +9b7d51e4bcf7375dff3ef2d815443c36f19b4a48bcf89a5805a55dfac30505f8 include/internal/refcount.h +5f48b2caa1986f85fc31d1f96621684736c27964291b3718dd35f3a15534fa99 include/internal/safe_math.h 11ee9893f7774c83fcfdee6e0ca593af3d28b779107883553facdbfdae3a68f5 include/internal/sha3.h 494ab5c802716bf38032986674fb094dde927a21752fe395d82e6044d81801d1 include/internal/sizes.h +abf03dc8635f2925bdc2299feabe115f8d5d6eaa450b421172ded222872386ba include/internal/ssl3_cbc.h 24f41a1985fa305833c3f58030c494d2563d15fc922cdf3eeb6a7ea8c135a880 include/internal/symhacks.h +6b186bc71a3a41681c94b5bf0a201741f15ee5e6e6a3973d5e878ea3de22e6db include/internal/thread.h +40e15986cb4821472db9b4c8a87ec93405fcb5d2b9eb91eb9bf9991ff71fda30 include/internal/thread_arch.h 640cc6a2aae208073a7f495c08b4c5006a69e8ac1c2d9aaaafd56b0e74d5f859 include/internal/thread_once.h -415b725d7f949a6191ab7bb30b48931bafc01c7aa93607e529fabbc853a4ddc5 include/internal/tlsgroups.h -7c8d8dfb769cd88c23033e86a2b2cf945391d33c6df1dce86c8d2fc5112636e2 include/internal/tsan_assist.h +300fd75e47ace860d006db0050683553417701ead2106c4b5bc6a31745099155 include/internal/time.h +ef96b731db0e0998c11a297d601f5b37c02525774d532fb4f92160e9069c7dfc include/internal/tlsgroups.h +7d97636320f6ce993ff6ff15741b90323a32fbeea4960fa64be2eb147063a149 include/internal/tsan_assist.h 2b38fb6e65d549aca3b2c76907daf67124f395251c0261dec26faa54da8d6d73 include/openssl/aes.h -3157a0e4fba3df5db17e7843ef614d46dd4b6bcdebcb2c3667b777f20a092f2c include/openssl/asn1.h.in +47fd81a330f042baf3675f4154c6276ab7a8cf76efaf01288abe41f119ec5588 include/openssl/asn1.h.in d4733dcd490b3a2554eaf859d1ea964fe76f7d24f78e42be1094bdad6dee7429 include/openssl/asn1err.h 1550474ee05423896ec4abfb6346f1bc44c7be22329efac9ea25de10e81d549c include/openssl/asn1t.h.in -2cd8163cdc6c93386bc05e8ed983e5ca604d0bf9da65500cab736cfa8bc2b048 include/openssl/bio.h.in -0a26138aaded05cafe2326e11fdc19b28408e054cfe3dda40d45ef95ce8136b0 include/openssl/bioerr.h -82171a089d3dc93249ea59ae4900d78197eef1040cd658117be67f3b0b318d03 include/openssl/bn.h +d5543a6b57ab638a4ef62018776a0c4d5e6fa9b60b830cd2850ebbc5d5b38e9a include/openssl/bio.h.in +fe5ab4bc904b7c77e5411c4b7dda6d29595eb60a87f00e30ab32f48391f98b44 include/openssl/bioerr.h +9caa80699882befcce556446a45e5ffde5aa938aa2aae0e8ecd46c9c6a3fe419 include/openssl/bn.h 9ad8b04764797f5138f01f549ba18b44cf698ffc7fe795fef42c1822d84a6ff4 include/openssl/bnerr.h 93954e6c450716e158948d67f64736a451ea9473d02f3a908f3bc8a96cf049a5 include/openssl/buffer.h 9d48e6cab2ee98ae94d7113e4c65f000d97e125fdb3445642865ace3f34d06ac include/openssl/buffererr.h 8e772c24b051e59d2f65339f54584e3e44165a3eaf997d497faea764990130f5 include/openssl/cmac.h 1342636127f3d365ac538115e706ea1aea43ab8fa79e86756e818b30a72789c7 include/openssl/conf.h.in f20c3c845129a129f5e0b1dae970d86a5c96ab49f2e3f6f364734521e9e1abe3 include/openssl/conferr.h -02a1baff7b71a298419c6c5dcb43eaa9cc13e9beeb88c03fb14854b4e84e8862 include/openssl/configuration.h.in +69d98c5230b1c2a1b70c3e6b244fcfd8460a80ebf548542ea43bb1a57fe6cf57 include/openssl/configuration.h.in 6b3810dac6c9d6f5ee36a10ad6d895a5e4553afdfb9641ce9b7dc5db7eef30b7 include/openssl/conftypes.h -df5e60af861665675e4a00d40d15e36884f940e3379c7b45c9f717eaf1942697 include/openssl/core.h -c5e821b6e8191fa6a8377df741f746dbdad84803a111e3675e945662fe3d5cd5 include/openssl/core_dispatch.h -206559e1af84fd1ff4144cf63133559ee814ad6684656a5d69346f395eddc995 include/openssl/core_names.h -80e6806ba08aaafb45fefc6fec015f93bf3b717ff61f83f33dfd54f5ff3bd00e include/openssl/crypto.h.in +28c6f0ede39c821dcf4abeeb4e41972038ebb3e3c9d0a43ffdf28edb559470e1 include/openssl/core.h +103829e44499eafa29da9ff6b5dfc91cf8d121997397ccfdfc5834c0478f4627 include/openssl/core_dispatch.h +8b4027cf19ce2a7cbad506cde61552123818b6eae62d5fbdae34e9f68660e6f8 include/openssl/core_names.h.in +371413ef13841f1245a225c8ec1cec463629c42bfc33254f979d2a8672112f9a include/openssl/crypto.h.in 2f9570c2514b4d1b2a86fbdf30ced879e5c52e62f1d3691cb3da37ce4f6a98dd include/openssl/cryptoerr.h bbc82260cbcadd406091f39b9e3b5ea63146d9a4822623ead16fa12c43ab9fc6 include/openssl/cryptoerr_legacy.h +83af275af84cf88c4e420030a9ea07c38d1887009c8f471874ed1458a4b1cda7 include/openssl/decoder.h +503b45367b035ddf6e54587125c2100ceec324d646e6f3df92c12513185e977c include/openssl/decodererr.h fa3e6b6c2e6222424b9cd7005e3c5499a2334c831cd5d6a29256ce945be8cb1d include/openssl/des.h 0837b1ec7074b37d2e1d5ac46d6003c3fc4f1ff10f2e44c64b5709b0bacec4e8 include/openssl/dh.h -836130f5a32bbdce51b97b34758ed1b03a9d06065c187418eaf323dca6adfc6d include/openssl/dherr.h +b74a54335bb2f55caacd5c3fd10db3575166fc35077dc5740059243f70e0b179 include/openssl/dherr.h 3cfb7211419c5dcc98b9a20713e2245befa0182a10615edb89a5ce0a0725a787 include/openssl/dsa.h 276d1f6e111ba933bc708e6a0670047cbe0d0b67aabe31807abbbc231de4d8cf include/openssl/dsaerr.h 46921241755eec0c0fe1a0a5b32c51ac7a3ecd33b9aa05a7489ad4f67d5454be include/openssl/e_os2.h bc9ec2be442a4f49980ba2c63c8f0da701de1f6e23d7db35d781658f833dd7b9 include/openssl/ebcdic.h -b6a11924ed95072f4af0a895ee6b93d17aa06104619fb79c9cd0a7bfd5c9164c include/openssl/ec.h +49e8a9d226d543ac482cecdc01c83b7ccdfbfca6ad92d690aad75a245148e2ab include/openssl/ec.h 7aa8c5bee779af59d4733f6a50f7f6be39f1eb43409e5b3357440f9a7d0ca115 include/openssl/ecerr.h 61c76ee3f12ed0e42503a56421ca00f1cb9a0f4caa5f9c4421c374bcd45917d7 include/openssl/encoder.h 69dd983f45b8ccd551f084796519446552963a18c52b70470d978b597c81b2dc include/openssl/encodererr.h -c6ee8f17d7252bdd0807a124dc6d50a95c32c04e17688b7c2e061998570b7028 include/openssl/err.h.in -87451ed43c9cacf86e76bc974e0832cc9600001cef7d4b8a6acd6ddc6ab3d565 include/openssl/evp.h -5bd1b5dcd14067a1fe490d49df911002793c0b4f0bd4492cd8f71cfed7bf9f2a include/openssl/evperr.h +d4d376d2251df847f8c8aaf164834787332802ff3ce0c9263be3de952cf00ea4 include/openssl/err.h.in +90b4729d85b1777f0524c1c54a8197fd578c96804aa84a925cad6ae093d37eba include/openssl/evp.h +a5e2027d1154dfae857c34e846a79aa99576bcb261341ec3c2ced73ac28c2aba include/openssl/evperr.h 3085bc5a77ea3776619bf9c748632a3a23f1d8dcad5239ba0f48939f375fb0e8 include/openssl/fips_names.h b1d41beba560a41383f899a361b786e04f889106fb5960ec831b0af7996c9783 include/openssl/fipskey.h.in 47a088c98ad536ea99f2c6a9333e372507cb61b9bdffb930c586ed52f8f261eb include/openssl/hmac.h faab8accc9520269dd874126ae164a43526d5784e6280521c7ab3772c02b0a0c include/openssl/kdf.h 2dc06275ed23fbea883b1126e69c5344ef64fbc81036478fba0c3c9f2d20839f include/openssl/lhash.h.in -a07beaeeffecf72afa66a5a01e01c0bbd75a926987e146f5fd92d1fd012e8fbd include/openssl/macros.h +1d0727322274c34d622a9955a5c50a6537f872f2740286068758fde24bf607b1 include/openssl/macros.h 9184207c562fd1fa7bd3a4f1fadcb984130561279818f0cdfcf3e9c55be8a7d1 include/openssl/modes.h -7c71200e35f4cc1b4011a4bc14e521e4dc037b9b2d640a74bc30ef334b813de3 include/openssl/obj_mac.h +290ff74354553fc9746e4725bc5cfd9de59dad691fda3f3f5880cb0d767b08df include/openssl/obj_mac.h 157797b450215f973eb10be96a04e58048ab9c131ad29427e80d0e37e230ed98 include/openssl/objects.h d25537af264684dff033dd8ae62b0348f868fcfec4aa51fa8f07bcfa4bd807ad include/openssl/objectserr.h fe6acd42c3e90db31aaafc2236a7d30ebfa53c4c07ea4d8265064c7fcb951970 include/openssl/opensslconf.h 1bf52d136e94f727a96651c1f48ad040482f35dae152519ccd585efd410b92f0 include/openssl/opensslv.h.in 767d9d7d5051c937a3ce8a268c702902fda93eeaa210a94dfde1f45c23277d20 include/openssl/param_build.h 30085f4d1b4934bb25ffe7aa9a30859966318a1b4d4dcea937c426e90e6e1984 include/openssl/params.h -097615b849375e2903967521f76c570512e5be47b8159fdbcd31e433f8a4cca7 include/openssl/prov_ssl.h -033c0dd117bbd44af2af9ab2eddb16552bd46ce1ce7435736a187ef82357ee92 include/openssl/proverr.h -b97e8ad49b38683817387596aefec0abd5f4d572643beef48be4f7acba26768d include/openssl/provider.h +ed785c451189aa5f7299f9f32a841e7f25b67c4ee937c8de8491a39240f5bd9d include/openssl/prov_ssl.h +08980b1dbc01e2926fc59707d867030fc7a3d37dc625c0e1edf2d31bdf71b2fb include/openssl/proverr.h +03bda8974476f0f038a7cfa0cb30f0b8210d55c74c6e7e853fd1564dca3e2b14 include/openssl/provider.h e512ab2e492d968a9bf8b2b048f79ac5dfe11bddf3c00f2eec6e9c6ecc57d330 include/openssl/rand.h 5be9d723cf368b48ab35bda5db1a3e83bda6e9e38218dd0b020be1a5427e7488 include/openssl/randerr.h -140340d4735a8bac1be0a07f5446ce316619ebacde0f8a8a942ab03ddc4f3da3 include/openssl/rsa.h +2f4f0106e9b2db6636491dbe3ef81b80dbf01aefe6f73d19663423b7fcd54466 include/openssl/rsa.h 2f339ba2f22b8faa406692289a6e51fdbbb04b03f85cf3ca849835e58211ad23 include/openssl/rsaerr.h 6586f2187991731835353de0ffad0b6b57609b495e53d0f32644491ece629eb2 include/openssl/safestack.h.in 676015d7541e7929c8ecbea648665f869d7edf50f9e7292a401b18c63a7ffe05 include/openssl/self_test.h -2964274ab32b1ba8578a06b06663db2eda4317ae806369271d889176bb5a7d04 include/openssl/sha.h +a435cb5d87a37c05921afb2d68f581018ec9f62fd9b3194ab651139b24f616d2 include/openssl/sha.h c169a015d7be52b7b99dd41c418a48d97e52ad21687c39c512a83a7c3f3ddb70 include/openssl/stack.h 22d7584ad609e30e818b54dca1dfae8dea38913fffedd25cd540c550372fb9a6 include/openssl/symhacks.h -c2a80f226bf916c1fd9067f2d9f37d78a48a9377d14bb554ef013b6ee3ca4a24 include/openssl/trace.h +8acd8147402a816c835b4240e18972072bab41d3fb6ee364fc17e543d6a854f6 include/openssl/thread.h +a99dcb756a27eb019c9e3f5c49bd55ca39def82684aea891bac011e9e99f9b8d include/openssl/trace.h a22bb862d4e1e7bb41b4199f81fc6737dc0a277534b17f9e22b102ea297532c1 include/openssl/types.h c0a9551efccf43f3dd748d4fd8ec897ddaabbc629c00ec1ad76ce983e1195a13 providers/common/bio_prov.c -e086f0f9c4a22bdada5e2f7ba34124d8cdc52d12d2f156e49ea7a5cf1ec85dac providers/common/capabilities.c +9da3f65c020cc14b99bfb732b015841b02a25f2d5022f8c0ef0e0d71c3b9f9f8 providers/common/capabilities.c f94b7435d4ec888ec30df1c611afa8b9eedbb59e905a2c7cb17cfc8c4b9b85b8 providers/common/der/der_digests_gen.c.in 424d7b2ece984a0904b80c73e541400c6e2d50a285c397dd323b440a4f2a8d8e providers/common/der/der_dsa_gen.c.in 27ff361a5fbfc97cd41690ab26639708961d0507b60912f55f5919649842c6ae providers/common/der/der_dsa_key.c @@ -507,108 +531,110 @@ f533a548eee6ec1863ca4afc4eb27766596fdf74c5eaed81817a92d26bbf26f0 providers/comm e1ef8b2be828a54312d6561b37751a5b6e9d5ebdb6c3e63589728c3d8adca7dc providers/common/include/prov/providercommon.h c2b4301a9f835c0b3776ad3afba7121d00cd7ae6387fe11c96269a37da08027c providers/common/include/prov/securitycheck.h 737cc1228106e555e9bab24e3c2438982e04e05b0d5b9ee6995d71df16c49143 providers/common/provider_ctx.c -34d0b6d119167d18770ac47e6cee0ad169ec9318e9a33747341a1a75beb20175 providers/common/provider_err.c -18fe559e6634615caaee95c70c6fdcbc0327df8f787290d1a2272904f41bd8ab providers/common/provider_seeding.c -8008cc352afcc74177ae3c61dd997097395bddcec4461871c0f52ffed6b7e50c providers/common/provider_util.c +3f5656c405ec57a261df7af940c1512990555361f69488a28d65e16f6b865a1d providers/common/provider_err.c +c4032b7cb033b588c6eb0585b8dfbed029d5b112a74ddd134dbcb1d78b0f9684 providers/common/provider_seeding.c +6e833d259d04cdedc007e6cda52fd706527edcf4b4432dbd88cbf45c3f7a4442 providers/common/provider_util.c 5b94312727ca33e4f5c038f4caaae8417bf584cfde22df83d91f3c55c30c81ee providers/common/securitycheck.c bc4370324c4c8791ea6de8641d255073c6745ee984e18912d535e155d9815244 providers/common/securitycheck_fips.c abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101 providers/fips/fips_entry.c -503691dec27f35f02348a4144632c5a9d80400140c2386096e47ac4d708e13bb providers/fips/fipsprov.c +42cd9a91e687784eb44be472075f3ed5f6ec60a47fc1db7ef5b577949cbbee85 providers/fips/fipsprov.c 029fad3c27617c725e516621c2f6c3a0e1dca0fa22f4e89a1a6b9a977c8d935d providers/fips/self_test.c f822a03138e8b83ccaa910b89d72f31691da6778bf6638181f993ec7ae1167e3 providers/fips/self_test.h 551631b909f8d173eafcccac782a44c8aed92bb8463bfccdb936b7f3aee2a48b providers/fips/self_test_data.inc 5b6d8dbc1365974eb9a5d417b2276d40fa7b9e733bb224200d20a61b4b025973 providers/fips/self_test_kats.c -cd784a44a01a8a30a6be63381344a7f5432e74d40b02ea471c5b0dc943a7ac9d providers/implementations/asymciphers/rsa_enc.c -4db1826ecce8b60cb641bcd7a61430ec8cef73d2fe3cbc06aa33526afe1c954a providers/implementations/ciphers/cipher_aes.c +4428a56f5d195547348c743df0c14ac9c97cd7b60ce09b76cffe5e7c9296daec providers/implementations/asymciphers/rsa_enc.c +c2f1b12c64fc369dfc3b9bc9e76a76de7280e6429adaee55d332eb1971ad1879 providers/implementations/ciphers/cipher_aes.c f9d4b30e7110c90064b990c07430bb79061f4436b06ccaa981b25c306cfbfaa2 providers/implementations/ciphers/cipher_aes.h -89378cce6d31e8c2f221f9f29d0b17622624eb83e4ecec8465f7641f68352917 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +20494fb9eb9f0578a3a574e0c6406108cfb28d7895a1891d57b3238420ec4f7b providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c 7668e5c1cac474ad7b0f28aa78ca885edf44815fe4a606a6cd328b3c02fac25a providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h 26e0f28523b416ba4067e471061f5a11fd76f5dc8bfe57ce37a137cf5667630b providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c 6d2ab2e059ef38fad342d4c65eebd533c08a2092bb174ff3566c6604e175c5a4 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c -6d6bf36329af3b77f457898294be05fea3940a61cdaf0ed60cfb8d091a94186e providers/implementations/ciphers/cipher_aes_ccm.c +f37c3cf9e2e6fcfcbed941f3670b790fe09990349db72eb065bef51705d46e96 providers/implementations/ciphers/cipher_aes_ccm.c 00f36bf48e522dbb5ec71df0ec13e387955fa3672e6ff90e8a412ae95c4a642f providers/implementations/ciphers/cipher_aes_ccm.h -b18ca62d4962990bd29bc9531493d61bcb74ba6d8d3ae6c3d6c7b39ba5189b2b providers/implementations/ciphers/cipher_aes_ccm_hw.c +17b9d63357824c24b48c889e27f74e8882bfce740f4c755ae5843def46abe650 providers/implementations/ciphers/cipher_aes_ccm_hw.c 302b3819ff9fdfed750185421616b248b0e1233d75b45a065490fe4762b42f55 providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc a8eaca99a71521ff8ac4ffcf08315e59220f7e0b7f505ecddad04fadd021ec14 providers/implementations/ciphers/cipher_aes_cts.inc -710ee60704dd9dffa2a11e2e96596af1f7f84f915cedcedeec7292e0d978317a providers/implementations/ciphers/cipher_aes_gcm.c +7e886ecc088b5903aa082eac72a4c46f9064392bdf5723a592368ecebfeb71c0 providers/implementations/ciphers/cipher_aes_gcm.c 79f5a732820d2512a7f4fc2a99ece7e6e2523a51e62561eb67a4b70d5538b0c4 providers/implementations/ciphers/cipher_aes_gcm.h -559e65d698d0d854022f69644422b66677ee980ecddb91c8ca5e0c0efd2083b7 providers/implementations/ciphers/cipher_aes_gcm_hw.c +986450da9f87b3cea00880c5bb5b0908b201ba27f68942b9f8bfff393610b3bb providers/implementations/ciphers/cipher_aes_gcm_hw.c be18c20e0197f25fe7b9e0268657a2271a69d216b89cb100f082fa5fcaad1e07 providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc -26b55801b80128e60fa4cd4fb2b7a81a8741fc78142b0b670b09483ada592f0d providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc -73e27d146a51c59abb0999889de5054dcec7d3ad9b47be70c9ef03f50ef527a6 providers/implementations/ciphers/cipher_aes_hw.c +60c4f604cf9b5457be48f31cc24ca21729660381081b2dbf99f362a013a09684 providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc +4dea01dde337e6416db6217ae4a64a0681187c38325a27bc449160f8de7580bb providers/implementations/ciphers/cipher_aes_hw.c 89de794c090192459d99d95bc4a422e7782e62192cd0fdb3bdef4128cfedee68 providers/implementations/ciphers/cipher_aes_hw_aesni.inc -0264d1ea3ece6f730b342586fb1fe00e3f0ff01e47d53f552864df986bf35573 providers/implementations/ciphers/cipher_aes_ocb.c +d280d7ecd1da16248faf38f81059a7d76920bd54a8f551dda137c005acaeb01e providers/implementations/ciphers/cipher_aes_ocb.c 88138a1aff9705e608c0557653be92eb4de65b152555a2b79ec8b2a8fae73e8f providers/implementations/ciphers/cipher_aes_ocb.h -06a116e0d790b6618c1403efb0f08af13d8f62e7ffd2be777251a49079d4a610 providers/implementations/ciphers/cipher_aes_ocb_hw.c -a872195161ac6c3a2cb59c3d15b212e34bb7596a41712258f5d0b5e771e25239 providers/implementations/ciphers/cipher_aes_wrp.c -527ff9277b92606517ee7af13225a9d5fcffbbc36eb18bce39f59d594cbe4931 providers/implementations/ciphers/cipher_aes_xts.c +5840571376d5e32681644224ef25e70ca771357f9e8ce152eada6a15df113731 providers/implementations/ciphers/cipher_aes_ocb_hw.c +110f14e06311883d5e312b37e9d87c51f809592d3092ecd8eb449ea4bc7cac38 providers/implementations/ciphers/cipher_aes_wrp.c +a79fde91348c9df6bb359e5353a442800ca514a1ffcb68e5cc5f7afe7d57d5ec providers/implementations/ciphers/cipher_aes_xts.c c4a2499b214d7cf786dafaaee5c8c6963b3d5d1c27c144eec4b460f839074a3b providers/implementations/ciphers/cipher_aes_xts.h 281157d1da4d7285d878978e6d42d0d33b3a6bc16e3bc5b6879e39093a7d70da providers/implementations/ciphers/cipher_aes_xts_fips.c -c05b9144577565675244ba2e795356797dec38fd480150131985e5e6f4d42e42 providers/implementations/ciphers/cipher_aes_xts_hw.c +ea3b4a90f24b2feeee3f6e34805150bb7100a5b7fe0c0e9983c6b7566cacfc56 providers/implementations/ciphers/cipher_aes_xts_hw.c 46ba8271917b53fd8fdf77aee19cc326a219c950b94e043d6d118dcac25ad7ad providers/implementations/ciphers/cipher_cts.c -74640ce402acc704af72e055fb7f27e6aa8efd417babc56f710478e571d8631c providers/implementations/ciphers/cipher_cts.h +57ee5e4d0af6d6006b04e60c5727b43a71ed37b67aa2410e03ec8932ad4a69e4 providers/implementations/ciphers/cipher_cts.h fcc3bb0637864252402aaa9d543209909df9a39611127f777b168bc888498dc0 providers/implementations/ciphers/cipher_tdes.c -77709f7fc3f7c08986cd4f0ebf2ef6e44bacb975c1483ef444b3cf5e5071f9d6 providers/implementations/ciphers/cipher_tdes.h -6fc41326c5f464f27b7d31c16d5ad7116d6244b99e242893f6c96d0c61f3639a providers/implementations/ciphers/cipher_tdes_common.c +d4cd3672d769b38d5346c9b76fa3902b8bb2daee2aa5e1c1e70b75a54c2f43cd providers/implementations/ciphers/cipher_tdes.h +e5739a8201637f76f8daee987a535f1f278d6c2ad292dddd0a6a397108c65588 providers/implementations/ciphers/cipher_tdes_common.c 50645122f08ef4891cd96cace833bd550be7f5278ab785515fd61fe8993c8c25 providers/implementations/ciphers/cipher_tdes_hw.c -6bb3c24bfd872e3b4c779b29e9f962348f6ae3effeb4f243c8ea66abefe8a4fa providers/implementations/ciphers/ciphercommon.c -dd72ea861edf70b94197821ceb00e07165d550934a2e851d62afa5034b79f468 providers/implementations/ciphers/ciphercommon_block.c -4b4106f85e36eb2c07acc5a3ca5ccd77b736b3ac46cc4af786cf57405ecd54b2 providers/implementations/ciphers/ciphercommon_ccm.c +1f44963b1ac450cb77d75df9fbf956b04742e38d236d316c7eb8021bdf0573a4 providers/implementations/ciphers/ciphercommon.c +ab9a2edb23aa61cf31da6addd8674a6028f93399eceeeee35a56ee770338fd6c providers/implementations/ciphers/ciphercommon_block.c +8af515e63a0c16ff35dcedcc43c7b4735a10943f1e937eeeb73eb1af3dc92782 providers/implementations/ciphers/ciphercommon_ccm.c 8b6828f188c2590c7d9c6cac13fa0eb6d38a522b0f2859e7c8a766580fa9b66e providers/implementations/ciphers/ciphercommon_ccm_hw.c -3b83f58d6ff1ae77de1ae8bee8a44ea2e5e4491c802b156fa77783ddebd44598 providers/implementations/ciphers/ciphercommon_gcm.c +425384b22ca7b7265e163e5768da4a60773a6d88a0a96df7c990759063560cba providers/implementations/ciphers/ciphercommon_gcm.c bb67eaa7a98494ca938726f9218213870fc97dd87b56bda950626cc794baf20b providers/implementations/ciphers/ciphercommon_gcm_hw.c 23fd89e3239e596c325a8c5d23eb1fe157a8d23aa4d90ed2c574bf06dfabd693 providers/implementations/ciphers/ciphercommon_hw.c c4b1cb143de15acc396ce2e03fdd165defd25ebc831de9cdfacf408ea883c666 providers/implementations/ciphers/ciphercommon_local.h 39b47b6ef9d71852964c26e07ef0e9b23f04c7493b1b16ba7c3dba7074b6b70d providers/implementations/digests/digestcommon.c 5f41dd1bf77bd08d287a875f9d6e5a423bf286524694ae7ee133cdd03ee763c0 providers/implementations/digests/sha2_prov.c -d06fd84c0771176e847ad5ea546a1d77f7d9575cd8ce53c9913c7b422dab1b88 providers/implementations/digests/sha3_prov.c -966496fb90dc7506d518c9e5198e0eb89cdd8fd6f6dd27ef8707d1cd405e3f8c providers/implementations/exchange/dh_exch.c -f8692118f4b6c89258c62864b273ebdfce302662dfe4b7647701a4cd7c5419b5 providers/implementations/exchange/ecdh_exch.c -9bf87b8429398a6465c7e9f749a33b84974303a458736b56f3359b30726d3969 providers/implementations/exchange/ecx_exch.c -0cc02005660c5c340660123decac838c59b7460ef1003d9d50edc604cfd8e375 providers/implementations/exchange/kdf_exch.c -a6f269ec18344e0d50fcd29dcc7304ca1548dc7d833739f39fcdb34b2300a8c3 providers/implementations/include/prov/ciphercommon.h -6dc876a1a785420e84210f085be6e4c7aca407ffb5433dbca4cd3f1c11bb7f06 providers/implementations/include/prov/ciphercommon_aead.h -dd07797d61988fd4124cfb920616df672938da80649fac5977bfd061c981edc5 providers/implementations/include/prov/ciphercommon_ccm.h -0c1e99d70155402a790e4de65923228c8df8ad970741caccfe8b513837457d7f providers/implementations/include/prov/ciphercommon_gcm.h +66a8eef0ecb12df2d38111735a7cb3257b85039c34fda6fc0e41db96e2d328cb providers/implementations/digests/sha3_prov.c +4b774bf9267ebe05bf90076bc18e19a21e03ee2716bdb8fc4e6458774e9a820c providers/implementations/exchange/dh_exch.c +b2d80c38dd62b46f2dd71e81a5684f54f43200d3ddbb86178081760ecc93525c providers/implementations/exchange/ecdh_exch.c +4994df237719649b086a032bd64c1cf38ceb4e67dd8ec98da20edf5bc3eadb0b providers/implementations/exchange/ecx_exch.c +2c8421ca27626472fd263172c76188b8b3eeda996dc925d052a8809543a33c11 providers/implementations/exchange/kdf_exch.c +1f248e220109ead708d4e1189be85299b4d11a935ad6bf2e8e6fd020e680c879 providers/implementations/include/prov/ciphercommon.h +a5ea831a23c0f52a37660437f6c61f129c3f8428daf6f8cd8dd458f358c56937 providers/implementations/include/prov/ciphercommon_aead.h +a07b9c86346100feef15c9abb57e48a6099bc9fa782724a2283f17910ef192fb providers/implementations/include/prov/ciphercommon_ccm.h +0da2601354752c1d7085d1aee30ccc45a4066db9ec042fcd7a9da1644cac2330 providers/implementations/include/prov/ciphercommon_gcm.h b9a61ce951c1904d8315b1bb26c0ab0aaadb47e71d4ead5df0a891608c728c4b providers/implementations/include/prov/digestcommon.h -82087efa8777dc5417d934873ae4ef5feeca73dca12ad937fa4e437b2ea29de2 providers/implementations/include/prov/implementations.h -5f09fc71874b00419d71646714f21ebbdcceda277463b6f77d3d3ea6946914e8 providers/implementations/include/prov/kdfexchange.h -c95ce5498e724b9b3d58e3c2f4723e7e3e4beb07f9bea9422e43182cbadb43af providers/implementations/include/prov/macsignature.h -0eaab474a7e8464cd22adb886295ee5afc46137c687b02af3d2ba5dd69a8da9c providers/implementations/include/prov/names.h +1baf1c06b20a0eb8ec271452544922d67c1cc168dbe9853b259191de4bd99918 providers/implementations/include/prov/ecx.h +062b49fc5cfa405fbcb184b1b48c9141db22531493bf828ba8543d24b0b72692 providers/implementations/include/prov/hmac_drbg.h +a6879c2e107597c49efa07fae48f0554ffbea9814c31d186bf0ce9f83e1ec9d2 providers/implementations/include/prov/implementations.h +05eedab6b16c80025f72281fa619d9480c437b800cb821b761fe4c05bc9d3af0 providers/implementations/include/prov/kdfexchange.h +4014246d44fa3f34aad5372c75d3f7eea528f1cf1798e30d5627e7620a356631 providers/implementations/include/prov/macsignature.h +27e57358e8ad201e382b50d5760f010badd9d6253deb34e6fb93a2af35450d9a providers/implementations/include/prov/names.h b9f8781167f274ccd8b643b3bb6c4e1108fb27b2aae588518261af9415228dae providers/implementations/include/prov/seeding.h -086ba2b99e78cd52808e6798d3af6d11bce2a3b6c6c60b9c7f24eb97e0097596 providers/implementations/kdfs/hkdf.c -0b45ad30687ead5f6b2d712f154b560483fd136d496e82c36570468550eedb57 providers/implementations/kdfs/kbkdf.c -5cb7cf8c6387a73ea779aedd133ed14b7642f02569f414dde5aa973e2a38d5c9 providers/implementations/kdfs/pbkdf2.c +976a18396364387b36b83d1cb723b530dce37ffc57fa066567fe730853f84444 providers/implementations/kdfs/hkdf.c +0d0c153bbb7234a98cd95fb802bed6bfc00a6002dd61a7fe77a44433a3cd9181 providers/implementations/kdfs/kbkdf.c +03b3dffd32a2b8f94e7d39b97f3d7b36f00cd0177ee5e7329a39aeca20ed4baf providers/implementations/kdfs/pbkdf2.c c0778565abff112c0c5257329a7750ec4605e62f26cc36851fa1fbee6e03c70c providers/implementations/kdfs/pbkdf2.h abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc providers/implementations/kdfs/pbkdf2_fips.c -13717d4f921787ab2b994ffb86d56aede9b3109bdf00c2a17baf6f53e11c4434 providers/implementations/kdfs/sshkdf.c -6a798e505555baa96ef302dc84f26aeb6920d355b0ad138eb3d17c63e7687234 providers/implementations/kdfs/sskdf.c -a66987548504bbe5bb81b80e7c1e190ab68abd852fb04f59ae40fd4e93160841 providers/implementations/kdfs/tls1_prf.c -1e5aaa6dc3bb52b0b5a07e662386b71e0e3ee7c83b9f15a4144ab24264c7431c providers/implementations/kdfs/x942kdf.c -8e8b9094c757c78638f60d7bde822a035adeecde11f9565cbd24c1322ec7e06b providers/implementations/kem/rsa_kem.c -11a0d0fb88ed88e965f10b3a0ef6c880f60341df995128f57ad943053aaf15b2 providers/implementations/keymgmt/dh_kmgmt.c -a329f57cb041cd03907e9d996fbc2f378ee116c7f8d7fbf1ea08b7a5df7e0304 providers/implementations/keymgmt/dsa_kmgmt.c -9bc88451d3ae110c7a108ee73d3b3b6bda801ec3494d2dfb9c9970b85c2d34fe providers/implementations/keymgmt/ec_kmgmt.c +c3502c75dfb8c97c907eb478be84cc9e09dc0c17ede2c739b433145abfef7202 providers/implementations/kdfs/sshkdf.c +da5fa36d4fbb2816221560f5cd1c1710b59b8f948c1b9d2a37ee8e30a07b04f2 providers/implementations/kdfs/sskdf.c +7aab45293d8cb6d6a778f6d8fb243a679d98a73a26ac7c681ff280a8d5e06664 providers/implementations/kdfs/tls1_prf.c +1664cb4137073e9c0e202b82ca251e8620dbc83aa3d3d6b85de440183288ea61 providers/implementations/kdfs/x942kdf.c +bb7ad10481d496f3227897c00b2a9d516ce8e0a6627f4addeabd9c72d9cf825f providers/implementations/kem/rsa_kem.c +94fbefb22d31920da76dd821117e96fa7745114d35b8a38d7ee67d4609126ff2 providers/implementations/keymgmt/dh_kmgmt.c +2d229f89413d3a3c945f5862145258cadf24bfdde37b637a1bf51d683308873d providers/implementations/keymgmt/dsa_kmgmt.c +3964a23ac071b0d6e54ea12c382e98abe1becfd9890194d94804715002b2b5b8 providers/implementations/keymgmt/ec_kmgmt.c 258ae17bb2dd87ed1511a8eb3fe99eed9b77f5c2f757215ff6b3d0e8791fc251 providers/implementations/keymgmt/ec_kmgmt_imexport.inc -011c36aad6834729043f23eacab417732541ee23916d9afa5bb9164862be00bb providers/implementations/keymgmt/ecx_kmgmt.c -053a2be39a87f50b877ebdbbf799cf5faf8b2de33b04311d819d212ee1ea329b providers/implementations/keymgmt/kdf_legacy_kmgmt.c -1646b477fa231dd0f6c22444c99098f9b447cab0d39ff69b811262469d4dbe09 providers/implementations/keymgmt/mac_legacy_kmgmt.c -19f22fc70a6321441e56d5bd4aab3d01d52d17069d4e4b5cefce0f411ecece75 providers/implementations/keymgmt/rsa_kmgmt.c -d0eff68c72e177c3fe0c77bc8c38eded7e3ce41f72042e2c034c706a12284dd5 providers/implementations/macs/cmac_prov.c -e69aa06f8f3c6f5a26702b9f44a844b8589b99dc0ee590953a29e8b9ef10acbe providers/implementations/macs/gmac_prov.c -895c8dc7235b9ad5ff893be0293cbc245a5455e8850195ac7d446646e4ea71d0 providers/implementations/macs/hmac_prov.c -8640b63fd8325aaf8f7128d6cc448d9af448a65bf51a8978075467d33a67944e providers/implementations/macs/kmac_prov.c +02bcd47c626b65ef7eba3be418bd6c77b1949f1feb3fe99869fad33ebb6ca475 providers/implementations/keymgmt/ecx_kmgmt.c +daf35a7ab961ef70aefca981d80407935904c5da39dca6692432d6e6bc98759d providers/implementations/keymgmt/kdf_legacy_kmgmt.c +91832fb65cc8ee591989fcf0f039ad04ba463008b5be9549a2b0ae6882b257ab providers/implementations/keymgmt/mac_legacy_kmgmt.c +9034a66a4bae1a15e127a5eca94bcec2ecaa971b205e945fcf7fba6b6bb8e47d providers/implementations/keymgmt/rsa_kmgmt.c +7a94dfdf6c0ea272b49a52191f1aaaa74b88cc9d08efa7789c1984be22a2052f providers/implementations/macs/cmac_prov.c +f29f282463f5bc432129850619edc427fe1d6cc8aa107b5703b11858b48790da providers/implementations/macs/gmac_prov.c +47065d5f3460bedc344376754debec56d0e83b8cab94018db77f899c403115bd providers/implementations/macs/hmac_prov.c +16f3dc42faceb235d7c4a495b9be7e8476094482de6ff421ab514390898154fd providers/implementations/macs/kmac_prov.c 3034074f99b02db045f2ccecc8782322e876dad07a3c169bdb24168b6b1f8cbd providers/implementations/rands/crngt.c -4430964416b0d7b77fdb6c0c2e5707b6ed775d956f991d703a5566183e53f6f8 providers/implementations/rands/drbg.c -bb5f8161a80d0d1a7ee919af2b167972b00afd62e326252ca6aa93101f315f19 providers/implementations/rands/drbg_ctr.c -56bf1ac85ed6d593e2360f30daf3b6a6a0067eb069db24bbbee07e37fcb75eba providers/implementations/rands/drbg_hash.c -8ed3b26de4186cc7ef883e20125ffa729275a9d4ae06ddc6294af74f170e3e43 providers/implementations/rands/drbg_hmac.c -e1c1c2554adb92d29b035015c1114512e6b8a6781ed31861d812a8a5bb9b34ec providers/implementations/rands/drbg_local.h -a3072e7516b603f3ab9586a5bc4dce18d23b6300108e6e3514a2da09d73b8021 providers/implementations/rands/test_rng.c -6bb8ae1a0608746d42c7162a51e8245c5b9868be4c6e51bef30ae39ef06b60f3 providers/implementations/signature/dsa_sig.c -a30dc6308de0ca33406e7ce909f3bcf7580fb84d863b0976b275839f866258df providers/implementations/signature/ecdsa_sig.c -9a752462904fc50748c15cdab54262b0bf5e2a8220fbd718d93ccb60aa551fee providers/implementations/signature/eddsa_sig.c -3bb0f342b4cc1b4594ed0986adc47791c0a7b5c1ae7b1888c1fb5edb268a78d9 providers/implementations/signature/mac_legacy_sig.c -7e726080d5c9e08a037799125e209b438defb9fcde40dd83a89e2f13628415d9 providers/implementations/signature/rsa_sig.c -a14e901b02fe095713624db4080b3aa3ca685d43f9ebec03041f992240973346 ssl/record/tls_pad.c -3f2e01a98d9e3fda6cc5cb4b44dd43f6cae4ec34994e8f734d11b1e643e58636 ssl/s3_cbc.c +51688b34a8ba14234cf91c318ce9f97b8a54dbb501d6f56aa53d472f877d3660 providers/implementations/rands/drbg.c +c18ec061bfb908dadebd47ee49fd4aa3fd0d320a0ed85a0f8ae841be4be787d6 providers/implementations/rands/drbg_ctr.c +52df0b9fa3d9357364a27773418aba82def6ac3a3bf027f0e14398cf4e10a247 providers/implementations/rands/drbg_hash.c +989aae213883f4d21480a09273cc21b0ca5d482f4e2ebf6e513ce8853a7c727f providers/implementations/rands/drbg_hmac.c +df266cab55613a7515fa1eed7212bd07281d1d36bffcab436d2cb01cf514dd3d providers/implementations/rands/drbg_local.h +e5fb82137f8afea68a67c1ea2d652831207961c53f14ab33ac0d879c9d0e8448 providers/implementations/rands/test_rng.c +a9aa31d091df5b8f6710dd36761dfe7d32b6da1881f8581bed85ad4e171b0969 providers/implementations/signature/dsa_sig.c +6c8b5f325c997014bd71331c9eb6c185838cd81c10c3ad74dd65289ae923d629 providers/implementations/signature/ecdsa_sig.c +d9d4bbbb0af0d1db6f586a36fd63236e4becdd52468a1e6510994e80988400aa providers/implementations/signature/eddsa_sig.c +e0e67e402ff19b0d2eb5228d7ebd70b9477c12595ac34d6f201373d7c8a516f4 providers/implementations/signature/mac_legacy_sig.c +638c23176fba0fbb324df2d1a52a13048b0f3aad7ddb0552f35b906cfdd7bb02 providers/implementations/signature/rsa_sig.c +0b73a04f8a03106e2a0fea10978f9888158046c29c3993ca6557f5a6403d5580 ssl/record/methods/ssl3_cbc.c +a8914c1661c53bcb0f435ec280c35c5a135e6c71296554c7322186847e194683 ssl/record/methods/tls_pad.c diff --git a/providers/fips.checksum b/providers/fips.checksum index dd2575764d..9a3b991e66 100644 --- a/providers/fips.checksum +++ b/providers/fips.checksum @@ -1 +1 @@ -99cfe3d94b8231ef68881031b05156f7e52b2b595211248f09775610bb2b2480 providers/fips-sources.checksums +b5adc190c5af51bd6bf5a37fd37a31448c345e3b4c98269d134fd8f36417443b providers/fips-sources.checksums diff --git a/providers/fips.module.sources b/providers/fips.module.sources index e0ce4e1eaa..1c0594e2ca 100644 --- a/providers/fips.module.sources +++ b/providers/fips.module.sources @@ -145,6 +145,7 @@ crypto/dsa/dsa_local.h crypto/dsa/dsa_ossl.c crypto/dsa/dsa_sign.c crypto/dsa/dsa_vrf.c +crypto/ec/asm/ecp_nistp384-ppc64.pl crypto/ec/asm/ecp_nistp521-ppc64.pl crypto/ec/asm/ecp_nistz256-armv4.pl crypto/ec/asm/ecp_nistz256-armv8.pl @@ -262,6 +263,7 @@ crypto/modes/gcm128.c crypto/modes/ofb128.c crypto/modes/wrap128.c crypto/modes/xts128.c +crypto/modes/xts128gb.c crypto/o_str.c crypto/packet.c crypto/param_build.c @@ -269,6 +271,7 @@ crypto/param_build_set.c crypto/params.c crypto/params_dup.c crypto/params_from_text.c +crypto/params_idx.c crypto/ppccap.c crypto/ppccpuid.pl crypto/property/defn_cache.c @@ -358,13 +361,21 @@ crypto/sparccpuid.S crypto/sparcv9cap.c crypto/sparse_array.c crypto/stack/stack.c +crypto/thread/api.c +crypto/thread/arch.c +crypto/thread/arch/thread_none.c +crypto/thread/arch/thread_posix.c +crypto/thread/arch/thread_win.c +crypto/thread/internal.c crypto/threads_lib.c crypto/threads_none.c crypto/threads_pthread.c crypto/threads_win.c +crypto/time.c crypto/x86_64cpuid.pl crypto/x86cpuid.pl include/crypto/aes_platform.h +include/crypto/asn1.h include/crypto/asn1_dsa.h include/crypto/bn.h include/crypto/bn_conf.h.in @@ -372,6 +383,7 @@ include/crypto/bn_dh.h include/crypto/context.h include/crypto/cryptlib.h include/crypto/ctype.h +include/crypto/decoder.h include/crypto/des_platform.h include/crypto/dh.h include/crypto/dsa.h @@ -389,11 +401,13 @@ include/crypto/sha.h include/crypto/sparse_array.h include/crypto/types.h include/internal/bio.h +include/internal/common.h include/internal/constant_time.h include/internal/core.h include/internal/cryptlib.h include/internal/deprecated.h include/internal/der.h +include/internal/deterministic_nonce.h include/internal/dso.h include/internal/dsoerr.h include/internal/e_os.h @@ -404,14 +418,21 @@ include/internal/nelem.h include/internal/numbers.h include/internal/packet.h include/internal/param_build_set.h +include/internal/param_names.h.in +include/internal/params.h include/internal/property.h include/internal/propertyerr.h include/internal/provider.h include/internal/refcount.h +include/internal/safe_math.h include/internal/sha3.h include/internal/sizes.h +include/internal/ssl3_cbc.h include/internal/symhacks.h +include/internal/thread.h +include/internal/thread_arch.h include/internal/thread_once.h +include/internal/time.h include/internal/tlsgroups.h include/internal/tsan_assist.h include/openssl/aes.h @@ -431,10 +452,12 @@ include/openssl/configuration.h.in include/openssl/conftypes.h include/openssl/core.h include/openssl/core_dispatch.h -include/openssl/core_names.h +include/openssl/core_names.h.in include/openssl/crypto.h.in include/openssl/cryptoerr.h include/openssl/cryptoerr_legacy.h +include/openssl/decoder.h +include/openssl/decodererr.h include/openssl/des.h include/openssl/dh.h include/openssl/dherr.h @@ -475,6 +498,7 @@ include/openssl/self_test.h include/openssl/sha.h include/openssl/stack.h include/openssl/symhacks.h +include/openssl/thread.h include/openssl/trace.h include/openssl/types.h providers/common/bio_prov.c @@ -571,6 +595,8 @@ providers/implementations/include/prov/ciphercommon_aead.h providers/implementations/include/prov/ciphercommon_ccm.h providers/implementations/include/prov/ciphercommon_gcm.h providers/implementations/include/prov/digestcommon.h +providers/implementations/include/prov/ecx.h +providers/implementations/include/prov/hmac_drbg.h providers/implementations/include/prov/implementations.h providers/implementations/include/prov/kdfexchange.h providers/implementations/include/prov/macsignature.h @@ -610,5 +636,5 @@ providers/implementations/signature/ecdsa_sig.c providers/implementations/signature/eddsa_sig.c providers/implementations/signature/mac_legacy_sig.c providers/implementations/signature/rsa_sig.c -ssl/record/tls_pad.c -ssl/s3_cbc.c +ssl/record/methods/ssl3_cbc.c +ssl/record/methods/tls_pad.c diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index bf22e907bc..7ec409710b 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -409,8 +409,10 @@ static const OSSL_ALGORITHM fips_keyexch[] = { #endif #ifndef OPENSSL_NO_EC { PROV_NAMES_ECDH, FIPS_DEFAULT_PROPERTIES, ossl_ecdh_keyexch_functions }, +# ifndef OPENSSL_NO_ECX { PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keyexch_functions }, { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keyexch_functions }, +# endif #endif { PROV_NAMES_TLS1_PRF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_tls1_prf_keyexch_functions }, @@ -424,9 +426,11 @@ static const OSSL_ALGORITHM fips_signature[] = { #endif { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_signature_functions }, #ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECX { PROV_NAMES_ED25519, FIPS_UNAPPROVED_PROPERTIES, ossl_ed25519_signature_functions }, { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_signature_functions }, +# endif { PROV_NAMES_ECDSA, FIPS_DEFAULT_PROPERTIES, ossl_ecdsa_signature_functions }, #endif { PROV_NAMES_HMAC, FIPS_DEFAULT_PROPERTIES, @@ -466,6 +470,7 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { #ifndef OPENSSL_NO_EC { PROV_NAMES_EC, FIPS_DEFAULT_PROPERTIES, ossl_ec_keymgmt_functions, PROV_DESCS_EC }, +# ifndef OPENSSL_NO_ECX { PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keymgmt_functions, PROV_DESCS_X25519 }, { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keymgmt_functions, @@ -474,6 +479,7 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { PROV_DESCS_ED25519 }, { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_keymgmt_functions, PROV_DESCS_ED448 }, +# endif #endif { PROV_NAMES_TLS1_PRF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions, PROV_DESCS_TLS1_PRF_SIGN }, @@ -545,14 +551,14 @@ static const OSSL_DISPATCH fips_dispatch_table[] = { { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))ossl_prov_get_capabilities }, { OSSL_FUNC_PROVIDER_SELF_TEST, (void (*)(void))fips_self_test }, - { 0, NULL } + OSSL_DISPATCH_END }; /* Functions we provide to ourself */ static const OSSL_DISPATCH intern_dispatch_table[] = { { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_intern_teardown }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query }, - { 0, NULL } + OSSL_DISPATCH_END }; /* diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index d865968058..497d69edd4 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -75,6 +75,8 @@ typedef struct { /* TLS padding */ unsigned int client_version; unsigned int alt_version; + /* PKCS#1 v1.5 decryption mode */ + unsigned int implicit_rejection; } PROV_RSA_CTX; static void *rsa_newctx(void *provctx) @@ -107,6 +109,7 @@ static int rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], RSA_free(prsactx->rsa); prsactx->rsa = vrsa; prsactx->operation = operation; + prsactx->implicit_rejection = 1; switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: @@ -156,10 +159,8 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, int rsasize = RSA_size(prsactx->rsa); unsigned char *tbuf; - if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) return 0; - } if (prsactx->oaep_md == NULL) { prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); if (prsactx->oaep_md == NULL) { @@ -199,6 +200,7 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; + int pad_mode; size_t len = RSA_size(prsactx->rsa); if (!ossl_prov_is_running()) @@ -233,10 +235,8 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { unsigned char *tbuf; - if ((tbuf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((tbuf = OPENSSL_malloc(len)) == NULL) return 0; - } ret = RSA_private_decrypt(inlen, in, tbuf, prsactx->rsa, RSA_NO_PADDING); /* @@ -276,8 +276,12 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, } OPENSSL_free(tbuf); } else { - ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa, - prsactx->pad_mode); + if ((prsactx->implicit_rejection == 0) && + (prsactx->pad_mode == RSA_PKCS1_PADDING)) + pad_mode = RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING; + else + pad_mode = prsactx->pad_mode; + ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa, pad_mode); } *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); ret = constant_time_select_int(constant_time_msb(ret), 0, 1); @@ -401,6 +405,10 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->alt_version)) return 0; + p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION); + if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->implicit_rejection)) + return 0; + return 1; } @@ -412,6 +420,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { NULL, 0), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), + OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL), OSSL_PARAM_END }; @@ -549,6 +558,14 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) return 0; prsactx->alt_version = alt_version; } + p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION); + if (p != NULL) { + unsigned int implicit_rejection; + + if (!OSSL_PARAM_get_uint(p, &implicit_rejection)) + return 0; + prsactx->implicit_rejection = implicit_rejection; + } return 1; } @@ -561,6 +578,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), + OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL), OSSL_PARAM_END }; @@ -586,5 +604,5 @@ const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = { (void (*)(void))rsa_set_ctx_params }, { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))rsa_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/asymciphers/sm2_enc.c b/providers/implementations/asymciphers/sm2_enc.c index a7c9156087..a9d652be30 100644 --- a/providers/implementations/asymciphers/sm2_enc.c +++ b/providers/implementations/asymciphers/sm2_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -229,5 +229,5 @@ const OSSL_DISPATCH ossl_sm2_asym_cipher_functions[] = { (void (*)(void))sm2_set_ctx_params }, { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))sm2_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info index b5d9d4f6c1..5eb705969f 100644 --- a/providers/implementations/ciphers/build.info +++ b/providers/implementations/ciphers/build.info @@ -25,6 +25,51 @@ $SM4_GOAL=../../libdefault.a $CHACHA_GOAL=../../libdefault.a $CHACHAPOLY_GOAL=../../libdefault.a $SIV_GOAL=../../libdefault.a +$SIV_GCM_GOAL=../../libdefault.a + +IF[{- !$disabled{asm} -}] + $GHASHDEF_x86=GHASH_ASM + $GHASHDEF_x86_sse2=OPENSSL_IA32_SSE2 + + $GHASHDEF_x86_64=GHASH_ASM + $GHASHDEF_x86_64_sse2=OPENSSL_IA32_SSE2 + + # ghash-ia64.s doesn't work on VMS + IF[{- $config{target} !~ /^vms-/ -}] + $GHASHDEF_ia64=GHASH_ASM + ENDIF + + $GHASHDEF_sparcv9=GHASH_ASM + + $GHASHDEF_alpha=GHASH_ASM + + $GHASHDEF_s390x=GHASH_ASM + + $GHASHDEF_armv4=GHASH_ASM + $GHASHDEF_aarch64= + + $GHASHDEF_parisc11=GHASH_ASM + $GHASHDEF_parisc20_64=$GHASHDEF_parisc11 + + $GHASHDEF_ppc32= + $GHASHDEF_ppc64=$GHASHDEF_ppc32 + + $GHASHDEF_c64xplus=GHASH_ASM + + $GHASHDEF_riscv64=GHASH_ASM + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + + IF[$GHASHDEF_{- $target{asm_arch} -}] + $GHASHDEF=$GHASHDEF_{- $target{asm_arch} -} + IF[{- !$disabled{sse2} -}] + IF[$GHASHDEF_{- $target{asm_arch} -}_sse2] + $GHASHDEF=$GHASHDEF_{- $target{asm_arch} -}_sse2 + ENDIF + ENDIF + ENDIF +ENDIF # This source is common building blocks for all ciphers in all our providers. SOURCE[$COMMON_GOAL]=\ @@ -54,8 +99,11 @@ SOURCE[$AES_GOAL]=\ SOURCE[$AES_GOAL]=cipher_aes_xts_fips.c IF[{- !$disabled{siv} -}] - SOURCE[$SIV_GOAL]=\ - cipher_aes_siv.c cipher_aes_siv_hw.c + DEFINE[$SIV_GCM_GOAL]=$GHASHDEF + SOURCE[$SIV_GCM_GOAL]=\ + cipher_aes_gcm_siv.c cipher_aes_gcm_siv_hw.c \ + cipher_aes_gcm_siv_polyval.c + SOURCE[$SIV_GOAL]=cipher_aes_siv.c cipher_aes_siv_hw.c ENDIF IF[{- !$disabled{des} -}] @@ -107,7 +155,9 @@ IF[{- !$disabled{sm4} -}] SOURCE[$SM4_GOAL]=\ cipher_sm4.c cipher_sm4_hw.c \ cipher_sm4_gcm.c cipher_sm4_gcm_hw.c \ - cipher_sm4_ccm.c cipher_sm4_ccm_hw.c + cipher_sm4_ccm.c cipher_sm4_ccm_hw.c \ + cipher_sm4_xts.c cipher_sm4_xts_hw.c + ENDIF IF[{- !$disabled{ocb} -}] diff --git a/providers/implementations/ciphers/cipher_aes.c b/providers/implementations/ciphers/cipher_aes.c index 2f469c131a..280be2dddc 100644 --- a/providers/implementations/ciphers/cipher_aes.c +++ b/providers/implementations/ciphers/cipher_aes.c @@ -40,10 +40,8 @@ static void *aes_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c index f9a8a58041..28d3909c4d 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,7 +26,7 @@ #ifndef AES_CBC_HMAC_SHA_CAPABLE # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags) \ const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; #else @@ -334,6 +334,16 @@ static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits, return ctx; } +static void *aes_cbc_hmac_sha1_dupctx(void *provctx) +{ + PROV_AES_HMAC_SHA1_CTX *ctx = provctx; + + if (ctx == NULL) + return NULL; + + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void aes_cbc_hmac_sha1_freectx(void *vctx) { PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx; @@ -361,6 +371,13 @@ static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits, return ctx; } +static void *aes_cbc_hmac_sha256_dupctx(void *provctx) +{ + PROV_AES_HMAC_SHA256_CTX *ctx = provctx; + + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static void aes_cbc_hmac_sha256_freectx(void *vctx) { PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx; @@ -386,6 +403,7 @@ static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[]) \ const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))nm##_##sub##_dupctx}, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))nm##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))nm##_update }, \ @@ -403,7 +421,7 @@ const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ (void (*)(void))nm##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))nm##_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; #endif /* AES_CBC_HMAC_SHA_CAPABLE */ diff --git a/providers/implementations/ciphers/cipher_aes_ccm.c b/providers/implementations/ciphers/cipher_aes_ccm.c index bb4b1e1e64..8c96328096 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm.c +++ b/providers/implementations/ciphers/cipher_aes_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,6 +33,26 @@ static void *aes_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aes_ccm_dupctx(void *provctx) +{ + PROV_AES_CCM_CTX *ctx = provctx; + PROV_AES_CCM_CTX *dupctx = NULL; + + if (ctx == NULL) + return NULL; + dupctx = OPENSSL_memdup(provctx, sizeof(*ctx)); + if (dupctx == NULL) + return NULL; + /* + * ossl_cm_initctx, via the ossl_prov_aes_hw_ccm functions assign a + * provctx->ccm.ks.ks to the ccm context key so we need to point it to + * the memduped copy + */ + dupctx->base.ccm_ctx.key = &dupctx->ccm.ks.ks; + + return dupctx; +} + static OSSL_FUNC_cipher_freectx_fn aes_ccm_freectx; static void aes_ccm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw.c b/providers/implementations/ciphers/cipher_aes_ccm_hw.c index 5dbb74bdcc..575a8ba88d 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,10 +61,10 @@ static const PROV_CCM_HW aes_ccm = { # include "cipher_aes_ccm_hw_aesni.inc" #elif defined(SPARC_AES_CAPABLE) # include "cipher_aes_ccm_hw_t4.inc" -#elif defined(RV64I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_ccm_hw_rv64i_zknd_zkne.inc" -#elif defined(RV32I_ZBKB_ZKND_ZKNE_CAPABLE) && defined(RV32I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_ccm_hw_rv32i_zknd_zkne.inc" +#elif defined(__riscv) && __riscv_xlen == 64 +# include "cipher_aes_ccm_hw_rv64i.inc" +#elif defined(__riscv) && __riscv_xlen == 32 +# include "cipher_aes_ccm_hw_rv32i.inc" #else const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i.inc similarity index 91% rename from providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i.inc index 345bc2faae..7cfe0fc4ce 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw_rv32i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -52,9 +52,9 @@ static const PROV_CCM_HW rv32i_zbkb_zknd_zkne_ccm = { const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { - if (RV32I_ZBKB_ZKND_ZKNE_CAPABLE) + if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) return &rv32i_zbkb_zknd_zkne_ccm; - if (RV32I_ZKND_ZKNE_CAPABLE) + if (RISCV_HAS_ZKND_AND_ZKNE()) return &rv32i_zknd_zkne_ccm; return &aes_ccm; } diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc similarity index 87% rename from providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc index 2f23209d03..203664e62e 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw_rv64i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,5 +33,5 @@ static const PROV_CCM_HW rv64i_zknd_zkne_ccm = { const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { - return RV64I_ZKND_ZKNE_CAPABLE ? &rv64i_zknd_zkne_ccm : &aes_ccm; + return RISCV_HAS_ZKND_AND_ZKNE() ? &rv64i_zknd_zkne_ccm : &aes_ccm; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm.c b/providers/implementations/ciphers/cipher_aes_gcm.c index 0081ca6cd7..1114bd8740 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.c +++ b/providers/implementations/ciphers/cipher_aes_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,6 +34,21 @@ static void *aes_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aes_gcm_dupctx(void *provctx) +{ + PROV_AES_GCM_CTX *ctx = provctx; + PROV_AES_GCM_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; +} + static OSSL_FUNC_cipher_freectx_fn aes_gcm_freectx; static void aes_gcm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c index 6dc0c083bb..4830cdc1b2 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c @@ -55,7 +55,6 @@ static int aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL); # endif /* AES_CTR_ASM */ } - ctx->key_set = 1; return 1; } @@ -143,10 +142,10 @@ static const PROV_GCM_HW aes_gcm = { # include "cipher_aes_gcm_hw_armv8.inc" #elif defined(PPC_AES_GCM_CAPABLE) && defined(_ARCH_PPC64) # include "cipher_aes_gcm_hw_ppc.inc" -#elif defined(RV64I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_gcm_hw_rv64i_zknd_zkne.inc" -#elif defined(RV32I_ZBKB_ZKND_ZKNE_CAPABLE) && defined(RV32I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_gcm_hw_rv32i_zknd_zkne.inc" +#elif defined(__riscv) && __riscv_xlen == 64 +# include "cipher_aes_gcm_hw_rv64i.inc" +#elif defined(__riscv) && __riscv_xlen == 32 +# include "cipher_aes_gcm_hw_rv32i.inc" #else const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i.inc similarity index 91% rename from providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i.inc index dd5878736e..bf3f98df16 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -55,9 +55,9 @@ static const PROV_GCM_HW rv32i_zbkb_zknd_zkne_gcm = { const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { - if (RV32I_ZBKB_ZKND_ZKNE_CAPABLE) + if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) return &rv32i_zbkb_zknd_zkne_gcm; - if (RV32I_ZKND_ZKNE_CAPABLE) + if (RISCV_HAS_ZKND_AND_ZKNE()) return &rv32i_zknd_zkne_gcm; return &aes_gcm; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc similarity index 90% rename from providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc index 44325d8469..7387adfded 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,7 +33,7 @@ static const PROV_GCM_HW rv64i_zknd_zkne_gcm = { const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { - if (RV64I_ZKND_ZKNE_CAPABLE) + if (RISCV_HAS_ZKND_AND_ZKNE()) return &rv64i_zknd_zkne_gcm; else return &aes_gcm; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc index ef18677979..94cf07df14 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2021, Intel Corporation. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -48,7 +48,6 @@ static int vaes_gcm_setkey(PROV_GCM_CTX *ctx, const unsigned char *key, PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; AES_KEY *ks = &actx->ks.ks; - ctx->ks = ks; aesni_set_encrypt_key(key, keylen * 8, ks); memset(gcmctx, 0, sizeof(*gcmctx)); gcmctx->key = ks; @@ -77,7 +76,7 @@ static int vaes_gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, if (ivlen > (U64(1) << 61)) return 0; - ossl_aes_gcm_setiv_avx512(ctx->ks, gcmctx, iv, ivlen); + ossl_aes_gcm_setiv_avx512(gcmctx->key, gcmctx, iv, ivlen); return 1; } @@ -162,9 +161,9 @@ static int vaes_gcm_cipherupdate(PROV_GCM_CTX *ctx, const unsigned char *in, } if (ctx->enc) - ossl_aes_gcm_encrypt_avx512(ctx->ks, gcmctx, &gcmctx->mres, in, len, out); + ossl_aes_gcm_encrypt_avx512(gcmctx->key, gcmctx, &gcmctx->mres, in, len, out); else - ossl_aes_gcm_decrypt_avx512(ctx->ks, gcmctx, &gcmctx->mres, in, len, out); + ossl_aes_gcm_decrypt_avx512(gcmctx->key, gcmctx, &gcmctx->mres, in, len, out); return 1; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.c b/providers/implementations/ciphers/cipher_aes_gcm_siv.c new file mode 100644 index 0000000000..2d4fd88658 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.c @@ -0,0 +1,323 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Dispatch functions for AES SIV mode */ + +/* + * This file uses the low level AES functions (which are deprecated for + * non-internal use) in order to implement provider AES ciphers. + */ +#include "internal/deprecated.h" + +#include +#include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/ciphercommon_aead.h" +#include "prov/provider_ctx.h" +#include "cipher_aes_gcm_siv.h" + +static int ossl_aes_gcm_siv_set_ctx_params(void *vctx, const OSSL_PARAM params[]); + +static void *ossl_aes_gcm_siv_newctx(void *provctx, size_t keybits) +{ + PROV_AES_GCM_SIV_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx != NULL) { + ctx->key_len = keybits / 8; + ctx->hw = ossl_prov_cipher_hw_aes_gcm_siv(keybits); + ctx->libctx = PROV_LIBCTX_OF(provctx); + ctx->provctx = provctx; + } + return ctx; +} + +static void ossl_aes_gcm_siv_freectx(void *vctx) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + + if (ctx == NULL) + return; + + OPENSSL_clear_free(ctx->aad, ctx->aad_len); + ctx->hw->clean_ctx(ctx); + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static void *ossl_aes_gcm_siv_dupctx(void *vctx) +{ + PROV_AES_GCM_SIV_CTX *in = (PROV_AES_GCM_SIV_CTX *)vctx; + PROV_AES_GCM_SIV_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + + if (in->hw == NULL) + return NULL; + + ret = OPENSSL_memdup(in, sizeof(*in)); + if (ret == NULL) + return NULL; + /* NULL-out these things we create later */ + ret->aad = NULL; + ret->ecb_ctx = NULL; + + if (in->aad != NULL) { + if ((ret->aad = OPENSSL_memdup(in->aad, UP16(ret->aad_len))) == NULL) + goto err; + } + + if (!in->hw->dup_ctx(ret, in)) + goto err; + + return ret; + err: + if (ret != NULL) { + OPENSSL_clear_free(ret->aad, ret->aad_len); + OPENSSL_free(ret); + } + return NULL; +} + +static int ossl_aes_gcm_siv_init(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[], int enc) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + + if (!ossl_prov_is_running()) + return 0; + + ctx->enc = enc; + + if (key != NULL) { + if (keylen != ctx->key_len) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + memcpy(ctx->key_gen_key, key, ctx->key_len); + } + if (iv != NULL) { + if (ivlen != sizeof(ctx->nonce)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + memcpy(ctx->nonce, iv, sizeof(ctx->nonce)); + } + + if (!ctx->hw->initkey(ctx)) + return 0; + + return ossl_aes_gcm_siv_set_ctx_params(ctx, params); +} + +static int ossl_aes_gcm_siv_einit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + return ossl_aes_gcm_siv_init(vctx, key, keylen, iv, ivlen, params, 1); +} + +static int ossl_aes_gcm_siv_dinit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + return ossl_aes_gcm_siv_init(vctx, key, keylen, iv, ivlen, params, 0); +} + +#define ossl_aes_gcm_siv_stream_update ossl_aes_gcm_siv_cipher +static int ossl_aes_gcm_siv_cipher(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + int error = 0; + + if (!ossl_prov_is_running()) + return 0; + + /* The RFC has a test case for this, but we don't try to do anything */ + if (inl == 0) { + if (outl != NULL) + *outl = 0; + return 1; + } + + if (outsize < inl) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + error |= !ctx->hw->cipher(ctx, out, in, inl); + + if (outl != NULL && !error) + *outl = inl; + return !error; +} + +static int ossl_aes_gcm_siv_stream_final(void *vctx, unsigned char *out, size_t *outl, + size_t outsize) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + int error = 0; + + if (!ossl_prov_is_running()) + return 0; + + error |= !ctx->hw->cipher(vctx, out, NULL, 0); + + if (outl != NULL && !error) + *outl = 0; + return !error; +} + +static int ossl_aes_gcm_siv_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); + if (p != NULL && p->data_type == OSSL_PARAM_OCTET_STRING) { + if (!ctx->enc || !ctx->generated_tag + || p->data_size != sizeof(ctx->tag) + || !OSSL_PARAM_set_octet_string(p, ctx->tag, sizeof(ctx->tag))) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, sizeof(ctx->tag))) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_len)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + return 1; +} + +static const OSSL_PARAM aes_gcm_siv_known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *ossl_aes_gcm_siv_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return aes_gcm_siv_known_gettable_ctx_params; +} + +static int ossl_aes_gcm_siv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + const OSSL_PARAM *p; + unsigned int speed = 0; + + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING + || p->data_size != sizeof(ctx->user_tag)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (!ctx->enc) { + memcpy(ctx->user_tag, p->data, sizeof(ctx->tag)); + ctx->have_user_tag = 1; + } + } + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_SPEED); + if (p != NULL) { + if (!OSSL_PARAM_get_uint(p, &speed)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + ctx->speed = !!speed; + } + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL) { + size_t key_len; + + if (!OSSL_PARAM_get_size_t(p, &key_len)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + /* The key length can not be modified */ + if (key_len != ctx->key_len) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + } + return 1; +} + +static const OSSL_PARAM aes_gcm_siv_known_settable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_SPEED, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_END +}; +static const OSSL_PARAM *ossl_aes_gcm_siv_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return aes_gcm_siv_known_settable_ctx_params; +} + +#define IMPLEMENT_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ +static OSSL_FUNC_cipher_newctx_fn ossl_##alg##kbits##_##lc##_newctx; \ +static OSSL_FUNC_cipher_freectx_fn ossl_##alg##_##lc##_freectx; \ +static OSSL_FUNC_cipher_dupctx_fn ossl_##alg##_##lc##_dupctx; \ +static OSSL_FUNC_cipher_encrypt_init_fn ossl_##alg##_##lc##_einit; \ +static OSSL_FUNC_cipher_decrypt_init_fn ossl_##alg##_##lc##_dinit; \ +static OSSL_FUNC_cipher_update_fn ossl_##alg##_##lc##_stream_update; \ +static OSSL_FUNC_cipher_final_fn ossl_##alg##_##lc##_stream_final; \ +static OSSL_FUNC_cipher_cipher_fn ossl_##alg##_##lc##_cipher; \ +static OSSL_FUNC_cipher_get_params_fn ossl_##alg##_##kbits##_##lc##_get_params; \ +static OSSL_FUNC_cipher_get_ctx_params_fn ossl_##alg##_##lc##_get_ctx_params; \ +static OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_##alg##_##lc##_gettable_ctx_params; \ +static OSSL_FUNC_cipher_set_ctx_params_fn ossl_##alg##_##lc##_set_ctx_params; \ +static OSSL_FUNC_cipher_settable_ctx_params_fn ossl_##alg##_##lc##_settable_ctx_params; \ +static int ossl_##alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ +{ \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ +} \ +static void *ossl_##alg##kbits##_##lc##_newctx(void *provctx) \ +{ \ + return ossl_##alg##_##lc##_newctx(provctx, kbits); \ +} \ +const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))ossl_##alg##kbits##_##lc##_newctx }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))ossl_##alg##_##lc##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))ossl_##alg##_##lc##_dupctx }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_##alg##_##lc##_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_##alg##_##lc##_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_##alg##_##lc##_stream_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_##alg##_##lc##_stream_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_##alg##_##lc##_cipher }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))ossl_##alg##_##kbits##_##lc##_get_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))ossl_cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))ossl_##alg##_##lc##_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))ossl_##alg##_##lc##_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))ossl_##alg##_##lc##_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))ossl_##alg##_##lc##_settable_ctx_params }, \ + OSSL_DISPATCH_END \ +} + +IMPLEMENT_cipher(aes, gcm_siv, GCM_SIV, AEAD_FLAGS, 128, 8, 96); +IMPLEMENT_cipher(aes, gcm_siv, GCM_SIV, AEAD_FLAGS, 192, 8, 96); +IMPLEMENT_cipher(aes, gcm_siv, GCM_SIV, AEAD_FLAGS, 256, 8, 96); diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.h b/providers/implementations/ciphers/cipher_aes_gcm_siv.h new file mode 100644 index 0000000000..37d1e3326b --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.h @@ -0,0 +1,76 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "prov/ciphercommon.h" +#include "crypto/aes_platform.h" + +#define BLOCK_SIZE 16 +#define NONCE_SIZE 12 +#define TAG_SIZE 16 + +/* AAD manipulation macros */ +#define UP16(x) (((x) + 15) & ~0x0F) +#define DOWN16(x) ((x) & ~0x0F) +#define REMAINDER16(x) ((x) & 0x0F) +#define IS16(x) (((x) & 0x0F) == 0) + +typedef struct prov_cipher_hw_aes_gcm_siv_st { + int (*initkey)(void *vctx); + int (*cipher)(void *vctx, unsigned char *out, const unsigned char *in, + size_t len); + int (*dup_ctx)(void *vdst, void *vsrc); + void (*clean_ctx)(void *vctx); +} PROV_CIPHER_HW_AES_GCM_SIV; + +/* Arranged for alignment purposes */ +typedef struct prov_aes_gcm_siv_ctx_st { + EVP_CIPHER_CTX *ecb_ctx; + const PROV_CIPHER_HW_AES_GCM_SIV *hw; /* maybe not used, yet? */ + uint8_t *aad; /* Allocated, rounded up to 16 bytes, from user */ + OSSL_LIB_CTX *libctx; + OSSL_PROVIDER *provctx; + size_t aad_len; /* actual AAD length */ + size_t key_len; + uint8_t key_gen_key[32]; /* from user */ + uint8_t msg_enc_key[32]; /* depends on key size */ + uint8_t msg_auth_key[BLOCK_SIZE]; + uint8_t tag[TAG_SIZE]; /* generated tag, given to user or compared to user */ + uint8_t user_tag[TAG_SIZE]; /* from user */ + uint8_t nonce[NONCE_SIZE]; /* from user */ + u128 Htable[16]; /* Polyval calculations via ghash */ + unsigned int enc : 1; /* Set to 1 if we are encrypting or 0 otherwise */ + unsigned int have_user_tag : 1; + unsigned int generated_tag : 1; + unsigned int used_enc : 1; + unsigned int used_dec : 1; + unsigned int speed : 1; +} PROV_AES_GCM_SIV_CTX; + +const PROV_CIPHER_HW_AES_GCM_SIV *ossl_prov_cipher_hw_aes_gcm_siv(size_t keybits); + +void ossl_polyval_ghash_init(u128 Htable[16], const uint64_t H[2]); +void ossl_polyval_ghash_hash(const u128 Htable[16], uint8_t *tag, const uint8_t *inp, size_t len); + +/* Define GSWAP8/GSWAP4 - used for BOTH little and big endian architectures */ +static ossl_inline uint32_t GSWAP4(uint32_t n) +{ + return (((n & 0x000000FF) << 24) + | ((n & 0x0000FF00) << 8) + | ((n & 0x00FF0000) >> 8) + | ((n & 0xFF000000) >> 24)); +} +static ossl_inline uint64_t GSWAP8(uint64_t n) +{ + uint64_t result; + + result = GSWAP4(n & 0x0FFFFFFFF); + result <<= 32; + return result | GSWAP4(n >> 32); +} diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c new file mode 100644 index 0000000000..9887e1c3a4 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c @@ -0,0 +1,373 @@ +/* + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include "cipher_aes_gcm_siv.h" + +static int aes_gcm_siv_ctr32(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *init_counter, + unsigned char *out, const unsigned char *in, size_t len); + +static int aes_gcm_siv_initkey(void *vctx) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + uint8_t output[BLOCK_SIZE]; + uint32_t counter = 0x0; + size_t i; + union { + uint32_t counter; + uint8_t block[BLOCK_SIZE]; + } data; + int out_len; + EVP_CIPHER *ecb = NULL; + DECLARE_IS_ENDIAN; + + switch (ctx->key_len) { + case 16: + ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-128-ECB", NULL); + break; + case 24: + ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-192-ECB", NULL); + break; + case 32: + ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-256-ECB", NULL); + break; + default: + goto err; + } + + if (ctx->ecb_ctx == NULL && (ctx->ecb_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if (!EVP_EncryptInit_ex2(ctx->ecb_ctx, ecb, ctx->key_gen_key, NULL, NULL)) + goto err; + + memset(&data, 0, sizeof(data)); + memcpy(&data.block[sizeof(data.counter)], ctx->nonce, NONCE_SIZE); + + /* msg_auth_key is always 16 bytes in size, regardless of AES128/AES256 */ + /* counter is stored little-endian */ + for (i = 0; i < BLOCK_SIZE; i += 8) { + if (IS_LITTLE_ENDIAN) { + data.counter = counter; + } else { + data.counter = GSWAP4(counter); + } + /* Block size is 16 (128 bits), but only 8 bytes are used */ + out_len = BLOCK_SIZE; + if (!EVP_EncryptUpdate(ctx->ecb_ctx, output, &out_len, data.block, BLOCK_SIZE)) + goto err; + memcpy(&ctx->msg_auth_key[i], output, 8); + counter++; + } + + /* msg_enc_key length is directly tied to key length AES128/AES256 */ + for (i = 0; i < ctx->key_len; i += 8) { + if (IS_LITTLE_ENDIAN) { + data.counter = counter; + } else { + data.counter = GSWAP4(counter); + } + /* Block size is 16 bytes (128 bits), but only 8 bytes are used */ + out_len = BLOCK_SIZE; + if (!EVP_EncryptUpdate(ctx->ecb_ctx, output, &out_len, data.block, BLOCK_SIZE)) + goto err; + memcpy(&ctx->msg_enc_key[i], output, 8); + counter++; + } + + if (!EVP_EncryptInit_ex2(ctx->ecb_ctx, ecb, ctx->msg_enc_key, NULL, NULL)) + goto err; + + /* Freshen up the state */ + ctx->used_enc = 0; + ctx->used_dec = 0; + EVP_CIPHER_free(ecb); + return 1; + err: + EVP_CIPHER_CTX_free(ctx->ecb_ctx); + EVP_CIPHER_free(ecb); + ctx->ecb_ctx = NULL; + return 0; +} + +static int aes_gcm_siv_aad(PROV_AES_GCM_SIV_CTX *ctx, + const unsigned char *aad, size_t len) +{ + size_t to_alloc; + uint8_t *ptr; + uint64_t len64; + + /* length of 0 resets the AAD */ + if (len == 0) { + OPENSSL_free(ctx->aad); + ctx->aad = NULL; + ctx->aad_len = 0; + return 1; + } + to_alloc = UP16(ctx->aad_len + len); + /* need to check the size of the AAD per RFC8452 */ + len64 = to_alloc; + if (len64 > ((uint64_t)1 << 36)) + return 0; + ptr = OPENSSL_realloc(ctx->aad, to_alloc); + if (ptr == NULL) + return 0; + ctx->aad = ptr; + memcpy(&ctx->aad[ctx->aad_len], aad, len); + ctx->aad_len += len; + if (to_alloc > ctx->aad_len) + memset(&ctx->aad[ctx->aad_len], 0, to_alloc - ctx->aad_len); + return 1; +} + +static int aes_gcm_siv_finish(PROV_AES_GCM_SIV_CTX *ctx) +{ + int ret = 0; + + if (ctx->enc) + return ctx->generated_tag; + ret = !CRYPTO_memcmp(ctx->tag, ctx->user_tag, sizeof(ctx->tag)); + ret &= ctx->have_user_tag; + return ret; +} + +static int aes_gcm_siv_encrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len) +{ + uint64_t len_blk[2]; + uint8_t S_s[TAG_SIZE]; + uint8_t counter_block[TAG_SIZE]; + uint8_t padding[BLOCK_SIZE]; + size_t i; + int64_t len64 = len; + int out_len; + int error = 0; + DECLARE_IS_ENDIAN; + + ctx->generated_tag = 0; + if (!ctx->speed && ctx->used_enc) + return 0; + /* need to check the size of the input! */ + if (len64 > ((int64_t)1 << 36) || len == 0) + return 0; + + if (IS_LITTLE_ENDIAN) { + len_blk[0] = (uint64_t)ctx->aad_len * 8; + len_blk[1] = (uint64_t)len * 8; + } else { + len_blk[0] = GSWAP8((uint64_t)ctx->aad_len * 8); + len_blk[1] = GSWAP8((uint64_t)len * 8); + } + memset(S_s, 0, TAG_SIZE); + ossl_polyval_ghash_init(ctx->Htable, (const uint64_t*)ctx->msg_auth_key); + + if (ctx->aad != NULL) { + /* AAD is allocated with padding, but need to adjust length */ + ossl_polyval_ghash_hash(ctx->Htable, S_s, ctx->aad, UP16(ctx->aad_len)); + } + if (DOWN16(len) > 0) + ossl_polyval_ghash_hash(ctx->Htable, S_s, (uint8_t *) in, DOWN16(len)); + if (!IS16(len)) { + /* deal with padding - probably easier to memset the padding first rather than calculate */ + memset(padding, 0, sizeof(padding)); + memcpy(padding, &in[DOWN16(len)], REMAINDER16(len)); + ossl_polyval_ghash_hash(ctx->Htable, S_s, padding, sizeof(padding)); + } + ossl_polyval_ghash_hash(ctx->Htable, S_s, (uint8_t *) len_blk, sizeof(len_blk)); + + for (i = 0; i < NONCE_SIZE; i++) + S_s[i] ^= ctx->nonce[i]; + + S_s[TAG_SIZE - 1] &= 0x7f; + out_len = sizeof(ctx->tag); + error |= !EVP_EncryptUpdate(ctx->ecb_ctx, ctx->tag, &out_len, S_s, sizeof(S_s)); + memcpy(counter_block, ctx->tag, TAG_SIZE); + counter_block[TAG_SIZE - 1] |= 0x80; + + error |= !aes_gcm_siv_ctr32(ctx, counter_block, out, in, len); + + ctx->generated_tag = !error; + /* Regardless of error */ + ctx->used_enc = 1; + return !error; +} + +static int aes_gcm_siv_decrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *in, + unsigned char *out, size_t len) +{ + uint8_t counter_block[TAG_SIZE]; + uint64_t len_blk[2]; + uint8_t S_s[TAG_SIZE]; + size_t i; + uint64_t padding[2]; + int64_t len64 = len; + int out_len; + int error = 0; + DECLARE_IS_ENDIAN; + + ctx->generated_tag = 0; + if (!ctx->speed && ctx->used_dec) + return 0; + /* need to check the size of the input! */ + if (len64 > ((int64_t)1 << 36) || len == 0) + return 0; + + memcpy(counter_block, ctx->user_tag, sizeof(counter_block)); + counter_block[TAG_SIZE - 1] |= 0x80; + + error |= !aes_gcm_siv_ctr32(ctx, counter_block, out, in, len); + + if (IS_LITTLE_ENDIAN) { + len_blk[0] = (uint64_t)ctx->aad_len * 8; + len_blk[1] = (uint64_t)len * 8; + } else { + len_blk[0] = GSWAP8((uint64_t)ctx->aad_len * 8); + len_blk[1] = GSWAP8((uint64_t)len * 8); + } + memset(S_s, 0, TAG_SIZE); + ossl_polyval_ghash_init(ctx->Htable, (const uint64_t*)ctx->msg_auth_key); + if (ctx->aad != NULL) { + /* AAD allocated with padding, but need to adjust length */ + ossl_polyval_ghash_hash(ctx->Htable, S_s, ctx->aad, UP16(ctx->aad_len)); + } + if (DOWN16(len) > 0) + ossl_polyval_ghash_hash(ctx->Htable, S_s, out, DOWN16(len)); + if (!IS16(len)) { + /* deal with padding - probably easier to "memset" the padding first rather than calculate */ + padding[0] = padding[1] = 0; + memcpy(padding, &out[DOWN16(len)], REMAINDER16(len)); + ossl_polyval_ghash_hash(ctx->Htable, S_s, (uint8_t *)padding, sizeof(padding)); + } + ossl_polyval_ghash_hash(ctx->Htable, S_s, (uint8_t *)len_blk, TAG_SIZE); + + for (i = 0; i < NONCE_SIZE; i++) + S_s[i] ^= ctx->nonce[i]; + + S_s[TAG_SIZE - 1] &= 0x7f; + + /* + * In the ctx, user_tag is the one received/set by the user, + * and tag is generated from the input + */ + out_len = sizeof(ctx->tag); + error |= !EVP_EncryptUpdate(ctx->ecb_ctx, ctx->tag, &out_len, S_s, sizeof(S_s)); + ctx->generated_tag = !error; + /* Regardless of error */ + ctx->used_dec = 1; + return !error; +} + +static int aes_gcm_siv_cipher(void *vctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + + /* EncryptFinal or DecryptFinal */ + if (in == NULL) + return aes_gcm_siv_finish(ctx); + + /* Deal with associated data */ + if (out == NULL) + return aes_gcm_siv_aad(ctx, in, len); + + if (ctx->enc) + return aes_gcm_siv_encrypt(ctx, in, out, len); + + return aes_gcm_siv_decrypt(ctx, in, out, len); +} + +static void aes_gcm_siv_clean_ctx(void *vctx) +{ + PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; + + EVP_CIPHER_CTX_free(ctx->ecb_ctx); + ctx->ecb_ctx = NULL; +} + +static int aes_gcm_siv_dup_ctx(void *vdst, void *vsrc) +{ + PROV_AES_GCM_SIV_CTX *dst = (PROV_AES_GCM_SIV_CTX *)vdst; + PROV_AES_GCM_SIV_CTX *src = (PROV_AES_GCM_SIV_CTX *)vsrc; + + dst->ecb_ctx = NULL; + if (src->ecb_ctx != NULL) { + if ((dst->ecb_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if (!EVP_CIPHER_CTX_copy(dst->ecb_ctx, src->ecb_ctx)) + goto err; + } + return 1; + + err: + EVP_CIPHER_CTX_free(dst->ecb_ctx); + dst->ecb_ctx = NULL; + return 0; +} + +static const PROV_CIPHER_HW_AES_GCM_SIV aes_gcm_siv_hw = +{ + aes_gcm_siv_initkey, + aes_gcm_siv_cipher, + aes_gcm_siv_dup_ctx, + aes_gcm_siv_clean_ctx, +}; + +const PROV_CIPHER_HW_AES_GCM_SIV *ossl_prov_cipher_hw_aes_gcm_siv(size_t keybits) +{ + return &aes_gcm_siv_hw; +} + +/* AES-GCM-SIV needs AES-CTR32, which is different than the AES-CTR implementation */ +static int aes_gcm_siv_ctr32(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *init_counter, + unsigned char *out, const unsigned char *in, size_t len) +{ + uint8_t keystream[BLOCK_SIZE]; + int out_len; + size_t i; + size_t j; + size_t todo; + uint32_t counter; + int error = 0; + union { + uint32_t x32[BLOCK_SIZE / sizeof(uint32_t)]; + uint8_t x8[BLOCK_SIZE]; + } block; + DECLARE_IS_ENDIAN; + + memcpy(&block, init_counter, sizeof(block)); + if (IS_BIG_ENDIAN) { + counter = GSWAP4(block.x32[0]); + } + + for (i = 0; i < len; i += sizeof(block)) { + out_len = BLOCK_SIZE; + error |= !EVP_EncryptUpdate(ctx->ecb_ctx, keystream, &out_len, (uint8_t*)&block, sizeof(block)); + if (IS_LITTLE_ENDIAN) { + block.x32[0]++; + } else { + counter++; + block.x32[0] = GSWAP4(counter); + } + todo = len - i; + if (todo > sizeof(keystream)) + todo = sizeof(keystream); + /* Non optimal, but avoids alignment issues */ + for (j = 0; j < todo; j++) + out[i + j] = in[i + j] ^ keystream[j]; + } + return !error; +} diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c new file mode 100644 index 0000000000..fead51dd36 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * AES low level APIs are deprecated for public use, but still ok for internal + * use where we're using them to implement the higher level EVP interface, as is + * the case here. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include "cipher_aes_gcm_siv.h" + +static ossl_inline void mulx_ghash(uint64_t *a) +{ + uint64_t t[2], mask; + DECLARE_IS_ENDIAN; + + if (IS_LITTLE_ENDIAN) { + t[0] = GSWAP8(a[0]); + t[1] = GSWAP8(a[1]); + } else { + t[0] = a[0]; + t[1] = a[1]; + } + mask = -(int64_t)(t[1] & 1) & 0xe1; + mask <<= 56; + + if (IS_LITTLE_ENDIAN) { + a[1] = GSWAP8((t[1] >> 1) ^ (t[0] << 63)); + a[0] = GSWAP8((t[0] >> 1) ^ mask); + } else { + a[1] = (t[1] >> 1) ^ (t[0] << 63); + a[0] = (t[0] >> 1) ^ mask; + } +} + +#define aligned64(p) (((uintptr_t)p & 0x07) == 0) +static ossl_inline void byte_reverse16(uint8_t *out, const uint8_t *in) +{ + if (aligned64(out) && aligned64(in)) { + ((uint64_t *)out)[0] = GSWAP8(((uint64_t *)in)[1]); + ((uint64_t *)out)[1] = GSWAP8(((uint64_t *)in)[0]); + } else { + int i; + + for (i = 0; i < 16; i++) + out[i] = in[15 - i]; + } +} + +/* Initialization of POLYVAL via existing GHASH implementation */ +void ossl_polyval_ghash_init(u128 Htable[16], const uint64_t H[2]) +{ + uint64_t tmp[2]; + DECLARE_IS_ENDIAN; + + byte_reverse16((uint8_t *)tmp, (const uint8_t *)H); + mulx_ghash(tmp); + if (IS_LITTLE_ENDIAN) { + /* "H is stored in host byte order" */ + tmp[0] = GSWAP8(tmp[0]); + tmp[1] = GSWAP8(tmp[1]); + } + + ossl_gcm_init_4bit(Htable, (u64*)tmp); +} + +/* Implementation of POLYVAL via existing GHASH implementation */ +void ossl_polyval_ghash_hash(const u128 Htable[16], uint8_t *tag, const uint8_t *inp, size_t len) +{ + uint64_t out[2]; + uint64_t tmp[2]; + size_t i; + + byte_reverse16((uint8_t *)out, (uint8_t *)tag); + + /* + * This implementation doesn't deal with partials, callers do, + * so, len is a multiple of 16 + */ + for (i = 0; i < len; i += 16) { + byte_reverse16((uint8_t *)tmp, &inp[i]); + ossl_gcm_ghash_4bit((u64*)out, Htable, (uint8_t *)tmp, 16); + } + byte_reverse16(tag, (uint8_t *)out); +} diff --git a/providers/implementations/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c index 074d04d878..0a1243a5fc 100644 --- a/providers/implementations/ciphers/cipher_aes_hw.c +++ b/providers/implementations/ciphers/cipher_aes_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -142,10 +142,10 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ # include "cipher_aes_hw_t4.inc" #elif defined(S390X_aes_128_CAPABLE) # include "cipher_aes_hw_s390x.inc" -#elif defined(RV64I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_hw_rv64i_zknd_zkne.inc" -#elif defined(RV32I_ZBKB_ZKND_ZKNE_CAPABLE) && defined(RV32I_ZKND_ZKNE_CAPABLE) -# include "cipher_aes_hw_rv32i_zknd_zkne.inc" +#elif defined(__riscv) && __riscv_xlen == 64 +# include "cipher_aes_hw_rv64i.inc" +#elif defined(__riscv) && __riscv_xlen == 32 +# include "cipher_aes_hw_rv32i.inc" #else /* The generic case */ # define PROV_CIPHER_HW_declare(mode) diff --git a/providers/implementations/ciphers/cipher_aes_hw_rv32i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_hw_rv32i.inc similarity index 95% rename from providers/implementations/ciphers/cipher_aes_hw_rv32i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_hw_rv32i.inc index d3173fa401..f6c652c32d 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_rv32i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_rv32i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -96,7 +96,7 @@ static const PROV_CIPHER_HW rv32i_zbkb_zknd_zkne_##mode = { \ cipher_hw_aes_copyctx \ }; #define PROV_CIPHER_HW_select(mode) \ -if (RV32I_ZBKB_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \ return &rv32i_zbkb_zknd_zkne_##mode; \ -if (RV32I_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &rv32i_zknd_zkne_##mode; diff --git a/providers/implementations/ciphers/cipher_aes_hw_rv64i_zknd_zkne.inc b/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc similarity index 94% rename from providers/implementations/ciphers/cipher_aes_hw_rv64i_zknd_zkne.inc rename to providers/implementations/ciphers/cipher_aes_hw_rv64i.inc index 762d211ef8..7ebf52f971 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_rv64i_zknd_zkne.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -55,5 +55,5 @@ static const PROV_CIPHER_HW rv64i_zknd_zkne_##mode = { \ cipher_hw_aes_copyctx \ }; #define PROV_CIPHER_HW_select(mode) \ -if (RV64I_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &rv64i_zknd_zkne_##mode; diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index ce377ad574..aec988e44e 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -340,10 +340,8 @@ static void *aes_ocb_dupctx(void *vctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; if (!aes_generic_ocb_copy_ctx(ret, in)) { OPENSSL_free(ret); @@ -387,7 +385,10 @@ static int aes_ocb_set_ctx_params(void *vctx, const OSSL_PARAM params[]) /* IV len must be 1 to 15 */ if (sz < OCB_MIN_IV_LEN || sz > OCB_MAX_IV_LEN) return 0; - ctx->base.ivlen = sz; + if (ctx->base.ivlen != sz) { + ctx->base.ivlen = sz; + ctx->iv_state = IV_STATE_UNINITIALISED; + } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL) { @@ -551,7 +552,7 @@ const OSSL_DISPATCH ossl_##aes##kbits##mode##_functions[] = { \ (void (*)(void))cipher_ocb_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))cipher_ocb_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 256, 128, OCB_DEFAULT_IV_LEN * 8); diff --git a/providers/implementations/ciphers/cipher_aes_ocb_hw.c b/providers/implementations/ciphers/cipher_aes_ocb_hw.c index 5b93d2b717..2672b92ec4 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb_hw.c +++ b/providers/implementations/ciphers/cipher_aes_ocb_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -103,7 +103,8 @@ static const PROV_CIPHER_HW aes_t4_ocb = { \ # define PROV_CIPHER_HW_select() \ if (SPARC_AES_CAPABLE) \ return &aes_t4_ocb; -#elif defined(RV64I_ZKND_ZKNE_CAPABLE) + +#elif defined(__riscv) && __riscv_xlen == 64 static int cipher_hw_aes_ocb_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *vctx, const unsigned char *key, @@ -122,9 +123,10 @@ static const PROV_CIPHER_HW aes_rv64i_zknd_zkne_ocb = { \ NULL \ }; # define PROV_CIPHER_HW_select() \ - if (RV64I_ZKND_ZKNE_CAPABLE) \ + if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &aes_rv64i_zknd_zkne_ocb; -#elif defined(RV32I_ZBKB_ZKND_ZKNE_CAPABLE) && defined(RV32I_ZKND_ZKNE_CAPABLE) + +#elif defined(__riscv) && __riscv_xlen == 32 static int cipher_hw_aes_ocb_rv32i_zknd_zkne_initkey(PROV_CIPHER_CTX *vctx, const unsigned char *key, @@ -158,9 +160,9 @@ static const PROV_CIPHER_HW aes_rv32i_zbkb_zknd_zkne_ocb = { \ NULL \ }; # define PROV_CIPHER_HW_select() \ - if (RV32I_ZBKB_ZKND_ZKNE_CAPABLE) \ + if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \ return &aes_rv32i_zbkb_zknd_zkne_ocb; \ - if (RV32I_ZKND_ZKNE_CAPABLE) \ + if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &aes_rv32i_zknd_zkne_ocb; #else # define PROV_CIPHER_HW_declare() diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c index bdc896e8f7..bcbc17a48a 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.c +++ b/providers/implementations/ciphers/cipher_aes_siv.c @@ -65,10 +65,8 @@ static void *siv_dupctx(void *vctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } if (!in->hw->dupctx(in, ret)) { OPENSSL_free(ret); ret = NULL; @@ -273,7 +271,7 @@ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, 2*kbits, blkbits, ivbits); \ } \ -static void * alg##kbits##lc##_newctx(void *provctx) \ +static void *alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, 2*kbits, EVP_CIPH_##UCMODE##_MODE, \ flags); \ @@ -299,7 +297,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ (void (*)(void)) alg##_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 128, 8, 0) diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index 8bddf475e2..912a47e3fe 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -66,6 +66,26 @@ static void *aes_wrap_newctx(size_t kbits, size_t blkbits, return wctx; } +static void *aes_wrap_dupctx(void *wctx) +{ + PROV_AES_WRAP_CTX *ctx = wctx; + PROV_AES_WRAP_CTX *dctx = wctx; + + if (ctx == NULL) + return NULL; + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + + if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { + dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, + dctx->base.tlsmacsize); + if (dctx->base.tlsmac == NULL) { + OPENSSL_free(dctx); + dctx = NULL; + } + } + return dctx; +} + static void aes_wrap_freectx(void *vctx) { PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx; @@ -281,6 +301,7 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_##mode##_cipher }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_##mode##_final }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_##mode##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_##mode##_dupctx }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))aes_##kbits##_##fname##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ @@ -293,7 +314,7 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } IMPLEMENT_cipher(wrap, wrap, WRAP, WRAP_FLAGS, 256, 64, AES_WRAP_NOPAD_IVLEN * 8); diff --git a/providers/implementations/ciphers/cipher_aes_xts.c b/providers/implementations/ciphers/cipher_aes_xts.c index dce2032986..cce2537ea7 100644 --- a/providers/implementations/ciphers/cipher_aes_xts.c +++ b/providers/implementations/ciphers/cipher_aes_xts.c @@ -1,6 +1,6 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -146,10 +146,8 @@ static void *aes_xts_dupctx(void *vctx) return NULL; } ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; } @@ -287,7 +285,7 @@ const OSSL_DISPATCH ossl_aes##kbits##xts_functions[] = { \ (void (*)(void))aes_xts_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))aes_xts_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } IMPLEMENT_cipher(xts, XTS, 256, AES_XTS_FLAGS); diff --git a/providers/implementations/ciphers/cipher_aes_xts_hw.c b/providers/implementations/ciphers/cipher_aes_xts_hw.c index c8c9cbf19e..564d6d6764 100644 --- a/providers/implementations/ciphers/cipher_aes_xts_hw.c +++ b/providers/implementations/ciphers/cipher_aes_xts_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -158,7 +158,8 @@ static const PROV_CIPHER_HW aes_xts_t4 = { \ # define PROV_CIPHER_HW_select_xts() \ if (SPARC_AES_CAPABLE) \ return &aes_xts_t4; -#elif defined(RV64I_ZKND_ZKNE_CAPABLE) + +#elif defined(__riscv) && __riscv_xlen == 64 static int cipher_hw_aes_xts_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, @@ -181,9 +182,10 @@ static const PROV_CIPHER_HW aes_xts_rv64i_zknd_zkne = { \ cipher_hw_aes_xts_copyctx \ }; # define PROV_CIPHER_HW_select_xts() \ -if (RV64I_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZKND_AND_ZKNE()) \ return &aes_xts_rv64i_zknd_zkne; -#elif defined(RV32I_ZBKB_ZKND_ZKNE_CAPABLE) && defined(RV32I_ZKND_ZKNE_CAPABLE) + +#elif defined(__riscv) && __riscv_xlen == 32 static int cipher_hw_aes_xts_rv32i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, @@ -221,9 +223,9 @@ static const PROV_CIPHER_HW aes_xts_rv32i_zbkb_zknd_zkne = { \ cipher_hw_aes_xts_copyctx \ }; # define PROV_CIPHER_HW_select_xts() \ -if (RV32I_ZBKB_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \ return &aes_xts_rv32i_zbkb_zknd_zkne; \ -if (RV32I_ZKND_ZKNE_CAPABLE) \ +if (RISCV_HAS_ZKND_ZKNE()) \ return &aes_xts_rv32i_zknd_zkne; # else /* The generic case */ diff --git a/providers/implementations/ciphers/cipher_aria.c b/providers/implementations/ciphers/cipher_aria.c index be69c39bab..ce4938d44a 100644 --- a/providers/implementations/ciphers/cipher_aria.c +++ b/providers/implementations/ciphers/cipher_aria.c @@ -33,10 +33,8 @@ static void *aria_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; diff --git a/providers/implementations/ciphers/cipher_aria_ccm.c b/providers/implementations/ciphers/cipher_aria_ccm.c index d6b5517ee0..0a0f52cdcc 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.c +++ b/providers/implementations/ciphers/cipher_aria_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,6 +28,21 @@ static void *aria_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aria_ccm_dupctx(void *provctx) +{ + PROV_ARIA_CCM_CTX *ctx = provctx; + PROV_ARIA_CCM_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.ccm_ctx.key != NULL) + dctx->base.ccm_ctx.key = &dctx->ks.ks; + + return dctx; +} + static void aria_ccm_freectx(void *vctx) { PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx; diff --git a/providers/implementations/ciphers/cipher_aria_gcm.c b/providers/implementations/ciphers/cipher_aria_gcm.c index b412bd3202..e794a80a00 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.c +++ b/providers/implementations/ciphers/cipher_aria_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,6 +27,21 @@ static void *aria_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *aria_gcm_dupctx(void *provctx) +{ + PROV_ARIA_GCM_CTX *ctx = provctx; + PROV_ARIA_GCM_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; +} + static OSSL_FUNC_cipher_freectx_fn aria_gcm_freectx; static void aria_gcm_freectx(void *vctx) { diff --git a/providers/implementations/ciphers/cipher_blowfish.c b/providers/implementations/ciphers/cipher_blowfish.c index 748028d3f3..9f17f1200d 100644 --- a/providers/implementations/ciphers/cipher_blowfish.c +++ b/providers/implementations/ciphers/cipher_blowfish.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,10 +41,8 @@ static void *blowfish_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; diff --git a/providers/implementations/ciphers/cipher_camellia.c b/providers/implementations/ciphers/cipher_camellia.c index b119666aa8..c550af3f83 100644 --- a/providers/implementations/ciphers/cipher_camellia.c +++ b/providers/implementations/ciphers/cipher_camellia.c @@ -39,10 +39,8 @@ static void *camellia_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; diff --git a/providers/implementations/ciphers/cipher_cast5.c b/providers/implementations/ciphers/cipher_cast5.c index 55081ccbe9..84c88793b0 100644 --- a/providers/implementations/ciphers/cipher_cast5.c +++ b/providers/implementations/ciphers/cipher_cast5.c @@ -42,10 +42,8 @@ static void *cast5_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; diff --git a/providers/implementations/ciphers/cipher_chacha20.c b/providers/implementations/ciphers/cipher_chacha20.c index ef80a515d7..5e2ad91445 100644 --- a/providers/implementations/ciphers/cipher_chacha20.c +++ b/providers/implementations/ciphers/cipher_chacha20.c @@ -214,13 +214,13 @@ const OSSL_DISPATCH ossl_chacha20_functions[] = { { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))chacha20_final }, { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))chacha20_cipher}, { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))chacha20_get_params }, - { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,(void (*)(void))chacha20_gettable_params }, + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))chacha20_gettable_params }, { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))chacha20_get_ctx_params }, { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))chacha20_gettable_ctx_params }, { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))chacha20_set_ctx_params }, { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))chacha20_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index abe670add7..d5d4e1a251 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -23,6 +23,7 @@ static OSSL_FUNC_cipher_newctx_fn chacha20_poly1305_newctx; static OSSL_FUNC_cipher_freectx_fn chacha20_poly1305_freectx; +static OSSL_FUNC_cipher_dupctx_fn chacha20_poly1305_dupctx; static OSSL_FUNC_cipher_encrypt_init_fn chacha20_poly1305_einit; static OSSL_FUNC_cipher_decrypt_init_fn chacha20_poly1305_dinit; static OSSL_FUNC_cipher_get_params_fn chacha20_poly1305_get_params; @@ -58,6 +59,25 @@ static void *chacha20_poly1305_newctx(void *provctx) return ctx; } +static void *chacha20_poly1305_dupctx(void *provctx) +{ + PROV_CHACHA20_POLY1305_CTX *ctx = provctx; + PROV_CHACHA20_POLY1305_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { + dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, + dctx->base.tlsmacsize); + if (dctx->base.tlsmac == NULL) { + OPENSSL_free(dctx); + dctx = NULL; + } + } + return dctx; +} + static void chacha20_poly1305_freectx(void *vctx) { PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; @@ -310,6 +330,7 @@ static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl, const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))chacha20_poly1305_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))chacha20_poly1305_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))chacha20_poly1305_dupctx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))chacha20_poly1305_einit }, { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))chacha20_poly1305_dinit }, { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))chacha20_poly1305_update }, @@ -327,6 +348,6 @@ const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[] = { (void (*)(void))chacha20_poly1305_set_ctx_params }, { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))chacha20_poly1305_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/ciphers/cipher_cts.h b/providers/implementations/ciphers/cipher_cts.h index 9473fbde88..a26e5a9e07 100644 --- a/providers/implementations/ciphers/cipher_cts.h +++ b/providers/implementations/ciphers/cipher_cts.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -42,7 +42,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_cts_functions[] = { \ (void (*)(void)) alg##_cbc_cts_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void)) alg##_cbc_cts_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; OSSL_FUNC_cipher_update_fn ossl_cipher_cbc_cts_block_update; diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c index c6d13466f7..e2c890979e 100644 --- a/providers/implementations/ciphers/cipher_des.c +++ b/providers/implementations/ciphers/cipher_des.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -53,10 +53,8 @@ static void *des_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; @@ -98,6 +96,7 @@ static int des_init(void *vctx, const unsigned char *key, size_t keylen, } if (!ctx->hw->init(ctx, key, keylen)) return 0; + ctx->key_set = 1; } return ossl_cipher_generic_set_ctx_params(ctx, params); } @@ -185,7 +184,7 @@ const OSSL_DISPATCH ossl_##des_##lcmode##_functions[] = { \ (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } /* ossl_des_ecb_functions */ diff --git a/providers/implementations/ciphers/cipher_des_hw.c b/providers/implementations/ciphers/cipher_des_hw.c index a77fcc681a..a2d54b46ba 100644 --- a/providers/implementations/ciphers/cipher_des_hw.c +++ b/providers/implementations/ciphers/cipher_des_hw.c @@ -136,7 +136,8 @@ static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, { size_t n, chunk = MAXCHUNK / 8; DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (inl < chunk) chunk = inl; diff --git a/providers/implementations/ciphers/cipher_idea.c b/providers/implementations/ciphers/cipher_idea.c index bc716290a4..c69c6ac092 100644 --- a/providers/implementations/ciphers/cipher_idea.c +++ b/providers/implementations/ciphers/cipher_idea.c @@ -40,10 +40,8 @@ static void *idea_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; diff --git a/providers/implementations/ciphers/cipher_null.c b/providers/implementations/ciphers/cipher_null.c index 0df97a7f8b..c911049e2d 100644 --- a/providers/implementations/ciphers/cipher_null.c +++ b/providers/implementations/ciphers/cipher_null.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -193,5 +193,5 @@ const OSSL_DISPATCH ossl_null_functions[] = { { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))null_set_ctx_params }, { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))null_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/ciphers/cipher_rc2.c b/providers/implementations/ciphers/cipher_rc2.c index 106f47e866..a4cd6bd533 100644 --- a/providers/implementations/ciphers/cipher_rc2.c +++ b/providers/implementations/ciphers/cipher_rc2.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -50,10 +50,8 @@ static void *rc2_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; @@ -130,7 +128,7 @@ static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) return 0; } if ((type = ASN1_TYPE_new()) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } @@ -139,7 +137,7 @@ static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) if (!ASN1_TYPE_set_int_octetstring(type, num, ctx->base.iv, ctx->base.ivlen)) { ASN1_TYPE_free(type); - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } /* @@ -228,7 +226,7 @@ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ -static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ +static void *alg##_##kbits##_##lcmode##_newctx(void *provctx) \ { \ PROV_##UCALG##_CTX *ctx; \ if (!ossl_prov_is_running()) \ @@ -265,7 +263,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ (void (*)(void))rc2_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))rc2_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; /* ossl_rc2128ecb_functions */ diff --git a/providers/implementations/ciphers/cipher_rc4.c b/providers/implementations/ciphers/cipher_rc4.c index a548beafaf..733524d36f 100644 --- a/providers/implementations/ciphers/cipher_rc4.c +++ b/providers/implementations/ciphers/cipher_rc4.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -43,10 +43,8 @@ static void *rc4_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; @@ -78,7 +76,7 @@ static int alg##_##kbits##_get_params(OSSL_PARAM params[]) \ kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_newctx; \ -static void * alg##_##kbits##_newctx(void *provctx) \ +static void *alg##_##kbits##_newctx(void *provctx) \ { \ PROV_##UCALG##_CTX *ctx; \ if (!ossl_prov_is_running()) \ @@ -112,7 +110,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##_functions[] = { \ (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; /* ossl_rc440_functions */ diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c index c46c6eab63..82ef7890b5 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,6 +34,7 @@ static OSSL_FUNC_cipher_encrypt_init_fn rc4_hmac_md5_einit; static OSSL_FUNC_cipher_decrypt_init_fn rc4_hmac_md5_dinit; static OSSL_FUNC_cipher_newctx_fn rc4_hmac_md5_newctx; static OSSL_FUNC_cipher_freectx_fn rc4_hmac_md5_freectx; +static OSSL_FUNC_cipher_dupctx_fn rc4_hmac_md5_dupctx; static OSSL_FUNC_cipher_get_ctx_params_fn rc4_hmac_md5_get_ctx_params; static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params; @@ -71,6 +72,15 @@ static void rc4_hmac_md5_freectx(void *vctx) OPENSSL_clear_free(ctx, sizeof(*ctx)); } +static void *rc4_hmac_md5_dupctx(void *vctx) +{ + PROV_RC4_HMAC_MD5_CTX *ctx = vctx; + + if (ctx == NULL) + return NULL; + return OPENSSL_memdup(ctx, sizeof(*ctx)); +} + static int rc4_hmac_md5_einit(void *ctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) @@ -214,6 +224,7 @@ static int rc4_hmac_md5_get_params(OSSL_PARAM params[]) const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))rc4_hmac_md5_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))rc4_hmac_md5_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))rc4_hmac_md5_dupctx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc4_hmac_md5_einit }, { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc4_hmac_md5_dinit }, { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))rc4_hmac_md5_update }, @@ -230,5 +241,5 @@ const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = { (void (*)(void))rc4_hmac_md5_set_ctx_params }, { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))rc4_hmac_md5_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/ciphers/cipher_rc5.c b/providers/implementations/ciphers/cipher_rc5.c index 5c7d2b1721..090b0488e5 100644 --- a/providers/implementations/ciphers/cipher_rc5.c +++ b/providers/implementations/ciphers/cipher_rc5.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -47,10 +47,8 @@ static void *rc5_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; @@ -138,7 +136,7 @@ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ -static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ +static void *alg##_##kbits##_##lcmode##_newctx(void *provctx) \ { \ PROV_##UCALG##_CTX *ctx; \ if (!ossl_prov_is_running()) \ @@ -175,7 +173,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ (void (*)(void))rc5_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))rc5_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; /* ossl_rc5128ecb_functions */ diff --git a/providers/implementations/ciphers/cipher_rc5.h b/providers/implementations/ciphers/cipher_rc5.h index ab3da8d73f..421632f2ea 100644 --- a/providers/implementations/ciphers/cipher_rc5.h +++ b/providers/implementations/ciphers/cipher_rc5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_seed.c b/providers/implementations/ciphers/cipher_seed.c index bae6a8e530..3644cb5e22 100644 --- a/providers/implementations/ciphers/cipher_seed.c +++ b/providers/implementations/ciphers/cipher_seed.c @@ -39,10 +39,8 @@ static void *seed_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } *ret = *in; return ret; diff --git a/providers/implementations/ciphers/cipher_sm4.c b/providers/implementations/ciphers/cipher_sm4.c index 6cf2731c6d..863c9997f5 100644 --- a/providers/implementations/ciphers/cipher_sm4.c +++ b/providers/implementations/ciphers/cipher_sm4.c @@ -33,10 +33,8 @@ static void *sm4_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; diff --git a/providers/implementations/ciphers/cipher_sm4_ccm.c b/providers/implementations/ciphers/cipher_sm4_ccm.c index 38e75016e9..3af84d85b7 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm.c +++ b/providers/implementations/ciphers/cipher_sm4_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,6 +28,21 @@ static void *sm4_ccm_newctx(void *provctx, size_t keybits) return ctx; } +static void *sm4_ccm_dupctx(void *provctx) +{ + PROV_SM4_CCM_CTX *ctx = provctx; + PROV_SM4_CCM_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.ccm_ctx.key != NULL) + dctx->base.ccm_ctx.key = &dctx->ks.ks; + + return dctx; +} + static void sm4_ccm_freectx(void *vctx) { PROV_SM4_CCM_CTX *ctx = (PROV_SM4_CCM_CTX *)vctx; diff --git a/providers/implementations/ciphers/cipher_sm4_ccm.h b/providers/implementations/ciphers/cipher_sm4_ccm.h index fbfb46a6d0..189e71e9e4 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm.h +++ b/providers/implementations/ciphers/cipher_sm4_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_ccm_hw.c b/providers/implementations/ciphers/cipher_sm4_ccm_hw.c index 426ebe963d..537024b09c 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm_hw.c +++ b/providers/implementations/ciphers/cipher_sm4_ccm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,18 +12,42 @@ */ #include "cipher_sm4_ccm.h" +#include "crypto/sm4_platform.h" + +#define SM4_HW_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec) \ + fn_set_enc_key(key, &actx->ks.ks); \ + CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ks.ks, \ + (block128_f)fn_blk); \ + ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec; \ + ctx->key_set = 1; static int ccm_sm4_initkey(PROV_CCM_CTX *ctx, const unsigned char *key, size_t keylen) { PROV_SM4_CCM_CTX *actx = (PROV_SM4_CCM_CTX *)ctx; - ossl_sm4_set_key(key, &actx->ks.ks); - CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ks.ks, - (block128_f)ossl_sm4_encrypt); - ctx->str = NULL; - ctx->key_set = 1; - return 1; +#ifdef HWSM4_CAPABLE + if (HWSM4_CAPABLE) { + SM4_HW_CCM_SET_KEY_FN(HWSM4_set_encrypt_key, HWSM4_encrypt, NULL, NULL); + } else +#endif /* HWSM4_CAPABLE */ + +#ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + SM4_HW_CCM_SET_KEY_FN(vpsm4_ex_set_encrypt_key, vpsm4_ex_encrypt, NULL, + NULL); + } else +#endif /* VPSM4_EX_CAPABLE */ + +#ifdef VPSM4_CAPABLE + if (VPSM4_CAPABLE) { + SM4_HW_CCM_SET_KEY_FN(vpsm4_set_encrypt_key, vpsm4_encrypt, NULL, NULL); + } else +#endif /* VPSM4_CAPABLE */ + { + SM4_HW_CCM_SET_KEY_FN(ossl_sm4_set_key, ossl_sm4_encrypt, NULL, NULL); + } + return 1; } static const PROV_CCM_HW ccm_sm4 = { diff --git a/providers/implementations/ciphers/cipher_sm4_gcm.c b/providers/implementations/ciphers/cipher_sm4_gcm.c index ce1aa2b07d..1128f65939 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm.c +++ b/providers/implementations/ciphers/cipher_sm4_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,6 +29,21 @@ static void *sm4_gcm_newctx(void *provctx, size_t keybits) return ctx; } +static void *sm4_gcm_dupctx(void *provctx) +{ + PROV_SM4_GCM_CTX *ctx = provctx; + PROV_SM4_GCM_CTX *dctx = NULL; + + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL && dctx->base.gcm.key != NULL) + dctx->base.gcm.key = &dctx->ks.ks; + + return dctx; +} + static void sm4_gcm_freectx(void *vctx) { PROV_SM4_GCM_CTX *ctx = (PROV_SM4_GCM_CTX *)vctx; diff --git a/providers/implementations/ciphers/cipher_sm4_gcm.h b/providers/implementations/ciphers/cipher_sm4_gcm.h index abd5ce75f1..2b6b5f3ece 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm.h +++ b/providers/implementations/ciphers/cipher_sm4_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_gcm_hw.c b/providers/implementations/ciphers/cipher_sm4_gcm_hw.c index 268d47f65d..630d8a3218 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_sm4_gcm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,37 +14,45 @@ #include "cipher_sm4_gcm.h" #include "crypto/sm4_platform.h" +# define SM4_GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ + fn_set_enc_key(key, ks); \ + CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ + ctx->ctr = (ctr128_f)fn_ctr; \ + ctx->key_set = 1; + static int sm4_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, size_t keylen) { PROV_SM4_GCM_CTX *actx = (PROV_SM4_GCM_CTX *)ctx; SM4_KEY *ks = &actx->ks.ks; - ctx->ks = ks; # ifdef HWSM4_CAPABLE if (HWSM4_CAPABLE) { - HWSM4_set_encrypt_key(key, ks); - CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f) HWSM4_encrypt); # ifdef HWSM4_ctr32_encrypt_blocks - ctx->ctr = (ctr128_f) HWSM4_ctr32_encrypt_blocks; + SM4_GCM_HW_SET_KEY_CTR_FN(ks, HWSM4_set_encrypt_key, HWSM4_encrypt, + HWSM4_ctr32_encrypt_blocks); # else /* HWSM4_ctr32_encrypt_blocks */ - ctx->ctr = (ctr128_f)NULL; + SM4_GCM_HW_SET_KEY_CTR_FN(ks, HWSM4_set_encrypt_key, HWSM4_encrypt, NULL); # endif } else # endif /* HWSM4_CAPABLE */ + +#ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + SM4_GCM_HW_SET_KEY_CTR_FN(ks, vpsm4_ex_set_encrypt_key, vpsm4_ex_encrypt, + vpsm4_ex_ctr32_encrypt_blocks); + } else +#endif /* VPSM4_EX_CAPABLE */ + # ifdef VPSM4_CAPABLE if (VPSM4_CAPABLE) { - vpsm4_set_encrypt_key(key, ks); - CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f) vpsm4_encrypt); - ctx->ctr = (ctr128_f) vpsm4_ctr32_encrypt_blocks; + SM4_GCM_HW_SET_KEY_CTR_FN(ks, vpsm4_set_encrypt_key, vpsm4_encrypt, + vpsm4_ctr32_encrypt_blocks); } else # endif /* VPSM4_CAPABLE */ { - ossl_sm4_set_key(key, ks); - CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)ossl_sm4_encrypt); - ctx->ctr = (ctr128_f)NULL; + SM4_GCM_HW_SET_KEY_CTR_FN(ks, ossl_sm4_set_key, ossl_sm4_encrypt, NULL); } - ctx->key_set = 1; return 1; } diff --git a/providers/implementations/ciphers/cipher_sm4_hw.c b/providers/implementations/ciphers/cipher_sm4_hw.c index 1fd916a565..7419744a46 100644 --- a/providers/implementations/ciphers/cipher_sm4_hw.c +++ b/providers/implementations/ciphers/cipher_sm4_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -42,6 +42,19 @@ static int cipher_hw_sm4_initkey(PROV_CIPHER_CTX *ctx, (void)0; /* terminate potentially open 'else' */ } else #endif +#ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + vpsm4_ex_set_encrypt_key(key, ks); + ctx->block = (block128_f)vpsm4_ex_encrypt; + ctx->stream.cbc = NULL; + if (ctx->mode == EVP_CIPH_CBC_MODE) + ctx->stream.cbc = (cbc128_f)vpsm4_ex_cbc_encrypt; + else if (ctx->mode == EVP_CIPH_ECB_MODE) + ctx->stream.ecb = (ecb128_f)vpsm4_ex_ecb_encrypt; + else if (ctx->mode == EVP_CIPH_CTR_MODE) + ctx->stream.ctr = (ctr128_f)vpsm4_ex_ctr32_encrypt_blocks; + } else +#endif #ifdef VPSM4_CAPABLE if (VPSM4_CAPABLE) { vpsm4_set_encrypt_key(key, ks); @@ -75,6 +88,17 @@ static int cipher_hw_sm4_initkey(PROV_CIPHER_CTX *ctx, #endif } else #endif +#ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + vpsm4_ex_set_decrypt_key(key, ks); + ctx->block = (block128_f)vpsm4_ex_decrypt; + ctx->stream.cbc = NULL; + if (ctx->mode == EVP_CIPH_CBC_MODE) + ctx->stream.cbc = (cbc128_f)vpsm4_ex_cbc_encrypt; + else if (ctx->mode == EVP_CIPH_ECB_MODE) + ctx->stream.ecb = (ecb128_f)vpsm4_ex_ecb_encrypt; + } else +#endif #ifdef VPSM4_CAPABLE if (VPSM4_CAPABLE) { vpsm4_set_decrypt_key(key, ks); @@ -82,7 +106,7 @@ static int cipher_hw_sm4_initkey(PROV_CIPHER_CTX *ctx, ctx->stream.cbc = NULL; if (ctx->mode == EVP_CIPH_CBC_MODE) ctx->stream.cbc = (cbc128_f)vpsm4_cbc_encrypt; - else if (ctx->mode == EVP_CIPH_ECB_MODE) + else if (ctx->mode == EVP_CIPH_ECB_MODE) ctx->stream.ecb = (ecb128_f)vpsm4_ecb_encrypt; } else #endif diff --git a/providers/implementations/ciphers/cipher_sm4_xts.c b/providers/implementations/ciphers/cipher_sm4_xts.c new file mode 100644 index 0000000000..e8c28e2660 --- /dev/null +++ b/providers/implementations/ciphers/cipher_sm4_xts.c @@ -0,0 +1,281 @@ + +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Dispatch functions for SM4 XTS mode */ + +#include +#include "cipher_sm4_xts.h" +#include "prov/implementations.h" +#include "prov/providercommon.h" + +#define SM4_XTS_FLAGS PROV_CIPHER_FLAG_CUSTOM_IV +#define SM4_XTS_IV_BITS 128 +#define SM4_XTS_BLOCK_BITS 8 + +/* forward declarations */ +static OSSL_FUNC_cipher_encrypt_init_fn sm4_xts_einit; +static OSSL_FUNC_cipher_decrypt_init_fn sm4_xts_dinit; +static OSSL_FUNC_cipher_update_fn sm4_xts_stream_update; +static OSSL_FUNC_cipher_final_fn sm4_xts_stream_final; +static OSSL_FUNC_cipher_cipher_fn sm4_xts_cipher; +static OSSL_FUNC_cipher_freectx_fn sm4_xts_freectx; +static OSSL_FUNC_cipher_dupctx_fn sm4_xts_dupctx; +static OSSL_FUNC_cipher_set_ctx_params_fn sm4_xts_set_ctx_params; +static OSSL_FUNC_cipher_settable_ctx_params_fn sm4_xts_settable_ctx_params; + +/*- + * Provider dispatch functions + */ +static int sm4_xts_init(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[], int enc) +{ + PROV_SM4_XTS_CTX *xctx = (PROV_SM4_XTS_CTX *)vctx; + PROV_CIPHER_CTX *ctx = &xctx->base; + + if (!ossl_prov_is_running()) + return 0; + + ctx->enc = enc; + + if (iv != NULL) { + if (!ossl_cipher_generic_initiv(vctx, iv, ivlen)) + return 0; + } + if (key != NULL) { + if (keylen != ctx->keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + if (!ctx->hw->init(ctx, key, keylen)) + return 0; + } + return sm4_xts_set_ctx_params(xctx, params); +} + +static int sm4_xts_einit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + return sm4_xts_init(vctx, key, keylen, iv, ivlen, params, 1); +} + +static int sm4_xts_dinit(void *vctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + return sm4_xts_init(vctx, key, keylen, iv, ivlen, params, 0); +} + +static void *sm4_xts_newctx(void *provctx, unsigned int mode, uint64_t flags, + size_t kbits, size_t blkbits, size_t ivbits) +{ + PROV_SM4_XTS_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) { + ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, + flags, ossl_prov_cipher_hw_sm4_xts(kbits), + NULL); + } + return ctx; +} + +static void sm4_xts_freectx(void *vctx) +{ + PROV_SM4_XTS_CTX *ctx = (PROV_SM4_XTS_CTX *)vctx; + + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static void *sm4_xts_dupctx(void *vctx) +{ + PROV_SM4_XTS_CTX *in = (PROV_SM4_XTS_CTX *)vctx; + PROV_SM4_XTS_CTX *ret = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + if (in->xts.key1 != NULL) { + if (in->xts.key1 != &in->ks1) + return NULL; + } + if (in->xts.key2 != NULL) { + if (in->xts.key2 != &in->ks2) + return NULL; + } + ret = OPENSSL_malloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + in->base.hw->copyctx(&ret->base, &in->base); + return ret; +} + +static int sm4_xts_cipher(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl) +{ + PROV_SM4_XTS_CTX *ctx = (PROV_SM4_XTS_CTX *)vctx; + + if (!ossl_prov_is_running() + || ctx->xts.key1 == NULL + || ctx->xts.key2 == NULL + || !ctx->base.iv_set + || out == NULL + || in == NULL + || inl < SM4_BLOCK_SIZE) + return 0; + + /* + * Impose a limit of 2^20 blocks per data unit as specified by + * IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007 + * indicated that this was a SHOULD NOT rather than a MUST NOT. + * NIST SP 800-38E mandates the same limit. + */ + if (inl > XTS_MAX_BLOCKS_PER_DATA_UNIT * SM4_BLOCK_SIZE) { + ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE); + return 0; + } + if (ctx->xts_standard) { + if (ctx->stream != NULL) + (*ctx->stream)(in, out, inl, ctx->xts.key1, ctx->xts.key2, + ctx->base.iv, ctx->base.enc); + else if (CRYPTO_xts128_encrypt(&ctx->xts, ctx->base.iv, in, out, inl, + ctx->base.enc)) + return 0; + } else { + if (ctx->stream_gb != NULL) + (*ctx->stream_gb)(in, out, inl, ctx->xts.key1, ctx->xts.key2, + ctx->base.iv, ctx->base.enc); + else if (ossl_crypto_xts128gb_encrypt(&ctx->xts, ctx->base.iv, in, out, + inl, ctx->base.enc)) + return 0; + } + *outl = inl; + return 1; +} + +static int sm4_xts_stream_update(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, + size_t inl) +{ + PROV_SM4_XTS_CTX *ctx = (PROV_SM4_XTS_CTX *)vctx; + + if (outsize < inl) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (!sm4_xts_cipher(ctx, out, outl, outsize, in, inl)) { + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); + return 0; + } + + return 1; +} + +static int sm4_xts_stream_final(void *vctx, unsigned char *out, size_t *outl, + size_t outsize) +{ + if (!ossl_prov_is_running()) + return 0; + *outl = 0; + return 1; +} + +static const OSSL_PARAM sm4_xts_known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_XTS_STANDARD, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *sm4_xts_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return sm4_xts_known_settable_ctx_params; +} + +static int sm4_xts_set_ctx_params(void *vxctx, const OSSL_PARAM params[]) +{ + PROV_SM4_XTS_CTX *xctx = (PROV_SM4_XTS_CTX *)vxctx; + const OSSL_PARAM *p; + + if (params == NULL) + return 1; + + /*- + * Sets the XTS standard to use with SM4-XTS algorithm. + * + * Must be utf8 string "GB" or "IEEE", + * "GB" means the GB/T 17964-2021 standard + * "IEEE" means the IEEE Std 1619-2007 standard + */ + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_XTS_STANDARD); + + if (p != NULL) { + const char *xts_standard = NULL; + + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + + if (!OSSL_PARAM_get_utf8_string_ptr(p, &xts_standard)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (OPENSSL_strcasecmp(xts_standard, "GB") == 0) { + xctx->xts_standard = 0; + } else if (OPENSSL_strcasecmp(xts_standard, "IEEE") == 0) { + xctx->xts_standard = 1; + } else { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + + return 1; +} + +#define IMPLEMENT_cipher(lcmode, UCMODE, kbits, flags) \ +static OSSL_FUNC_cipher_get_params_fn sm4_##kbits##_##lcmode##_get_params; \ +static int sm4_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ +{ \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, 2 * kbits, SM4_XTS_BLOCK_BITS,\ + SM4_XTS_IV_BITS); \ +} \ +static OSSL_FUNC_cipher_newctx_fn sm4_##kbits##_xts_newctx; \ +static void *sm4_##kbits##_xts_newctx(void *provctx) \ +{ \ + return sm4_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \ + SM4_XTS_BLOCK_BITS, SM4_XTS_IV_BITS); \ +} \ +const OSSL_DISPATCH ossl_sm4##kbits##xts_functions[] = { \ + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))sm4_##kbits##_xts_newctx }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))sm4_xts_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))sm4_xts_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))sm4_xts_stream_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))sm4_xts_stream_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))sm4_xts_cipher }, \ + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))sm4_xts_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))sm4_xts_dupctx }, \ + { OSSL_FUNC_CIPHER_GET_PARAMS, \ + (void (*)(void))sm4_##kbits##_##lcmode##_get_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ + (void (*)(void))sm4_xts_set_ctx_params }, \ + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))sm4_xts_settable_ctx_params }, \ + OSSL_DISPATCH_END \ +} +/* ossl_sm4128xts_functions */ +IMPLEMENT_cipher(xts, XTS, 128, SM4_XTS_FLAGS); diff --git a/providers/implementations/ciphers/cipher_sm4_xts.h b/providers/implementations/ciphers/cipher_sm4_xts.h new file mode 100644 index 0000000000..43d9a212e5 --- /dev/null +++ b/providers/implementations/ciphers/cipher_sm4_xts.h @@ -0,0 +1,46 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "prov/ciphercommon.h" +#include "crypto/sm4_platform.h" + +PROV_CIPHER_FUNC(void, xts_stream, + (const unsigned char *in, unsigned char *out, size_t len, + const SM4_KEY *key1, const SM4_KEY *key2, + const unsigned char iv[16], const int enc)); + +typedef struct prov_sm4_xts_ctx_st { + /* Must be first */ + PROV_CIPHER_CTX base; + + /* SM4 key schedules to use */ + union { + OSSL_UNION_ALIGN; + SM4_KEY ks; + } ks1, ks2; + + /*- + * XTS standard to use with SM4-XTS algorithm + * + * Must be 0 or 1, + * 0 for XTS mode specified by GB/T 17964-2021 + * 1 for XTS mode specified by IEEE Std 1619-2007 + */ + int xts_standard; + + XTS128_CONTEXT xts; + + /* Stream function for XTS mode specified by GB/T 17964-2021 */ + OSSL_xts_stream_fn stream_gb; + /* Stream function for XTS mode specified by IEEE Std 1619-2007 */ + OSSL_xts_stream_fn stream; +} PROV_SM4_XTS_CTX; + +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_xts(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_sm4_xts_hw.c b/providers/implementations/ciphers/cipher_sm4_xts_hw.c new file mode 100644 index 0000000000..44af243a69 --- /dev/null +++ b/providers/implementations/ciphers/cipher_sm4_xts_hw.c @@ -0,0 +1,94 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_sm4_xts.h" + +#define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key, \ + fn_block_enc, fn_block_dec, \ + fn_stream, fn_stream_gb) { \ + size_t bytes = keylen / 2; \ + \ + if (ctx->enc) { \ + fn_set_enc_key(key, &xctx->ks1.ks); \ + xctx->xts.block1 = (block128_f)fn_block_enc; \ + } else { \ + fn_set_dec_key(key, &xctx->ks1.ks); \ + xctx->xts.block1 = (block128_f)fn_block_dec; \ + } \ + fn_set_enc_key(key + bytes, &xctx->ks2.ks); \ + xctx->xts.block2 = (block128_f)fn_block_enc; \ + xctx->xts.key1 = &xctx->ks1; \ + xctx->xts.key2 = &xctx->ks2; \ + xctx->stream = fn_stream; \ + xctx->stream_gb = fn_stream_gb; \ +} + +static int cipher_hw_sm4_xts_generic_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, + size_t keylen) +{ + PROV_SM4_XTS_CTX *xctx = (PROV_SM4_XTS_CTX *)ctx; + OSSL_xts_stream_fn stream = NULL; + OSSL_xts_stream_fn stream_gb = NULL; +#ifdef HWSM4_CAPABLE + if (HWSM4_CAPABLE) { + XTS_SET_KEY_FN(HWSM4_set_encrypt_key, HWSM4_set_decrypt_key, + HWSM4_encrypt, HWSM4_decrypt, stream, stream_gb); + return 1; + } else +#endif /* HWSM4_CAPABLE */ +#ifdef VPSM4_EX_CAPABLE + if (VPSM4_EX_CAPABLE) { + stream = vpsm4_ex_xts_encrypt; + stream_gb = vpsm4_ex_xts_encrypt_gb; + XTS_SET_KEY_FN(vpsm4_ex_set_encrypt_key, vpsm4_ex_set_decrypt_key, + vpsm4_ex_encrypt, vpsm4_ex_decrypt, stream, stream_gb); + return 1; + } else +#endif /* VPSM4_EX_CAPABLE */ +#ifdef VPSM4_CAPABLE + if (VPSM4_CAPABLE) { + stream = vpsm4_xts_encrypt; + stream_gb = vpsm4_xts_encrypt_gb; + XTS_SET_KEY_FN(vpsm4_set_encrypt_key, vpsm4_set_decrypt_key, + vpsm4_encrypt, vpsm4_decrypt, stream, stream_gb); + return 1; + } else +#endif /* VPSM4_CAPABLE */ + { + (void)0; + } + { + XTS_SET_KEY_FN(ossl_sm4_set_key, ossl_sm4_set_key, ossl_sm4_encrypt, + ossl_sm4_decrypt, stream, stream_gb); + } + return 1; +} + +static void cipher_hw_sm4_xts_copyctx(PROV_CIPHER_CTX *dst, + const PROV_CIPHER_CTX *src) +{ + PROV_SM4_XTS_CTX *sctx = (PROV_SM4_XTS_CTX *)src; + PROV_SM4_XTS_CTX *dctx = (PROV_SM4_XTS_CTX *)dst; + + *dctx = *sctx; + dctx->xts.key1 = &dctx->ks1.ks; + dctx->xts.key2 = &dctx->ks2.ks; +} + + +static const PROV_CIPHER_HW sm4_generic_xts = { + cipher_hw_sm4_xts_generic_initkey, + NULL, + cipher_hw_sm4_xts_copyctx +}; +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_xts(size_t keybits) +{ + return &sm4_generic_xts; +} diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h index 93f9d1744d..3c98ed241d 100644 --- a/providers/implementations/ciphers/cipher_tdes.h +++ b/providers/implementations/ciphers/cipher_tdes.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -67,7 +67,7 @@ const OSSL_DISPATCH ossl_tdes_##type##_##lcmode##_functions[] = { \ (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c index af2f5b9841..c80d9f16b1 100644 --- a/providers/implementations/ciphers/cipher_tdes_common.c +++ b/providers/implementations/ciphers/cipher_tdes_common.c @@ -44,10 +44,8 @@ void *ossl_tdes_dupctx(void *ctx) return NULL; ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ret == NULL) return NULL; - } in->base.hw->copyctx(&ret->base, &in->base); return ret; @@ -92,6 +90,7 @@ static int tdes_init(void *vctx, const unsigned char *key, size_t keylen, } if (!ctx->hw->init(ctx, key, ctx->keylen)) return 0; + ctx->key_set = 1; } return ossl_cipher_generic_set_ctx_params(ctx, params); } diff --git a/providers/implementations/ciphers/cipher_tdes_default_hw.c b/providers/implementations/ciphers/cipher_tdes_default_hw.c index 53cbbad571..ccdf3941c8 100644 --- a/providers/implementations/ciphers/cipher_tdes_default_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_default_hw.c @@ -99,7 +99,8 @@ static int ossl_cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; size_t n; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (ctx->use_bits == 0) inl *= 8; diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c index 1b4539a64c..391383b550 100644 --- a/providers/implementations/ciphers/cipher_tdes_wrap.c +++ b/providers/implementations/ciphers/cipher_tdes_wrap.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -203,7 +203,7 @@ const OSSL_DISPATCH ossl_tdes_wrap_cbc_functions[] = \ (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } /* ossl_tdes_wrap_cbc_functions */ diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index fa383165d8..db81af5401 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -128,7 +128,10 @@ int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } - ctx->keylen = keylen; + if (ctx->keylen != keylen) { + ctx->keylen = keylen; + ctx->key_set = 0; + } } return 1; } @@ -217,6 +220,7 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, } if (!ctx->hw->init(ctx, key, ctx->keylen)) return 0; + ctx->key_set = 1; } return ossl_cipher_generic_set_ctx_params(ctx, params); } @@ -249,6 +253,11 @@ int ossl_cipher_generic_block_update(void *vctx, unsigned char *out, size_t blksz = ctx->blocksize; size_t nextblocks; + if (!ctx->key_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + if (ctx->tlsversion > 0) { /* * Each update call corresponds to a TLS record and is individually @@ -390,6 +399,11 @@ int ossl_cipher_generic_block_final(void *vctx, unsigned char *out, if (!ossl_prov_is_running()) return 0; + if (!ctx->key_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + if (ctx->tlsversion > 0) { /* We never finalize TLS, so this is an error */ ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); @@ -456,6 +470,11 @@ int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out, { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + if (!ctx->key_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + if (inl == 0) { *outl = 0; return 1; @@ -510,9 +529,16 @@ int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out, int ossl_cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + if (!ossl_prov_is_running()) return 0; + if (!ctx->key_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + *outl = 0; return 1; } @@ -526,6 +552,11 @@ int ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl, if (!ossl_prov_is_running()) return 0; + if (!ctx->key_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; diff --git a/providers/implementations/ciphers/ciphercommon_block.c b/providers/implementations/ciphers/ciphercommon_block.c index 6e6bb091e7..cfc78e0770 100644 --- a/providers/implementations/ciphers/ciphercommon_block.c +++ b/providers/implementations/ciphers/ciphercommon_block.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,26 +13,9 @@ #include #include #include "internal/constant_time.h" +#include "internal/ssl3_cbc.h" #include "ciphercommon_local.h" -/* Functions defined in ssl/tls_pad.c */ -int ssl3_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - OSSL_LIB_CTX *libctx); - -int tls1_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - int aead, - OSSL_LIB_CTX *libctx); - /* * Fills a single block of buffered data from the input, and returns the amount * of data remaining in the input that is a multiple of the blocksize. The buffer @@ -110,7 +93,7 @@ int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) size_t pad, i; size_t len = *buflen; - if(len != blocksize) { + if (len != blocksize) { ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } diff --git a/providers/implementations/ciphers/ciphercommon_ccm.c b/providers/implementations/ciphers/ciphercommon_ccm.c index ce3f7527f3..e638eb1631 100644 --- a/providers/implementations/ciphers/ciphercommon_ccm.c +++ b/providers/implementations/ciphers/ciphercommon_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -109,7 +109,10 @@ int ossl_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } - ctx->l = ivlen; + if (ctx->l != ivlen) { + ctx->l = ivlen; + ctx->iv_set = 0; + } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c index ed95c97ff4..fe24b450a5 100644 --- a/providers/implementations/ciphers/ciphercommon_gcm.c +++ b/providers/implementations/ciphers/ciphercommon_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,7 @@ #include "prov/ciphercommon_gcm.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" +#include "internal/param_names.h" static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len); static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv, @@ -145,84 +146,97 @@ int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; OSSL_PARAM *p; size_t sz; - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); - if (p != NULL) { - size_t taglen = (ctx->taglen != UNINITIALISED_SIZET) ? ctx->taglen : - GCM_TAG_MAX_SIZE; - - if (!OSSL_PARAM_set_size_t(p, taglen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); - if (p != NULL) { - if (ctx->iv_state == IV_STATE_UNINITIALISED) - return 0; - if (ctx->ivlen > p->data_size) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); - return 0; - } - if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen) - && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); - if (p != NULL) { - if (ctx->iv_state == IV_STATE_UNINITIALISED) - return 0; - if (ctx->ivlen > p->data_size) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); - return 0; - } - if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen) - && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); - if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); - if (p != NULL) { - sz = p->data_size; - if (sz == 0 - || sz > EVP_GCM_TLS_TAG_LEN - || !ctx->enc - || ctx->taglen == UNINITIALISED_SIZET) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); - return 0; + int type; + + for (p = params; p->key != NULL; p++) { + type = ossl_param_find_pidx(p->key); + switch (type) { + default: + break; + + case PIDX_CIPHER_PARAM_IVLEN: + if (!OSSL_PARAM_set_size_t(p, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_KEYLEN: + if (!OSSL_PARAM_set_size_t(p, ctx->keylen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TAGLEN: + { + size_t taglen = (ctx->taglen != UNINITIALISED_SIZET) ? ctx->taglen : + GCM_TAG_MAX_SIZE; + + if (!OSSL_PARAM_set_size_t(p, taglen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + break; + + case PIDX_CIPHER_PARAM_IV: + if (ctx->iv_state == IV_STATE_UNINITIALISED) + return 0; + if (ctx->ivlen > p->data_size) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_UPDATED_IV: + if (ctx->iv_state == IV_STATE_UNINITIALISED) + return 0; + if (ctx->ivlen > p->data_size) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TLS1_AAD_PAD: + if (!OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TAG: + sz = p->data_size; + if (sz == 0 + || sz > EVP_GCM_TLS_TAG_LEN + || !ctx->enc + || ctx->taglen == UNINITIALISED_SIZET) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN: + if (p->data == NULL + || p->data_type != OSSL_PARAM_OCTET_STRING + || !getivgen(ctx, p->data, p->data_size)) + return 0; + break; } - if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN); - if (p != NULL) { - if (p->data == NULL - || p->data_type != OSSL_PARAM_OCTET_STRING - || !getivgen(ctx, p->data, p->data_size)) - return 0; } return 1; } @@ -233,71 +247,80 @@ int ossl_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) const OSSL_PARAM *p; size_t sz; void *vp; + int type; if (params == NULL) return 1; - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); - if (p != NULL) { - vp = ctx->buf; - if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - if (sz == 0 || ctx->enc) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); - return 0; + for (p = params; p->key != NULL; p++) { + type = ossl_param_find_pidx(p->key); + switch (type) { + default: + break; + + case PIDX_CIPHER_PARAM_AEAD_TAG: + vp = ctx->buf; + if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (sz == 0 || ctx->enc) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); + return 0; + } + ctx->taglen = sz; + break; + + case PIDX_CIPHER_PARAM_AEAD_IVLEN: + if (!OSSL_PARAM_get_size_t(p, &sz)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (sz == 0 || sz > sizeof(ctx->iv)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + if (ctx->ivlen != sz) { + /* If the iv was already set or autogenerated, it is invalid. */ + if (ctx->iv_state != IV_STATE_UNINITIALISED) + ctx->iv_state = IV_STATE_FINISHED; + ctx->ivlen = sz; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TLS1_AAD: + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + sz = gcm_tls_init(ctx, p->data, p->data_size); + if (sz == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD); + return 0; + } + ctx->tls_aad_pad_sz = sz; + break; + + case PIDX_CIPHER_PARAM_AEAD_TLS1_IV_FIXED: + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (gcm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + break; + + case PIDX_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV: + if (p->data == NULL + || p->data_type != OSSL_PARAM_OCTET_STRING + || !setivinv(ctx, p->data, p->data_size)) + return 0; + break; } - ctx->taglen = sz; } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); - if (p != NULL) { - if (!OSSL_PARAM_get_size_t(p, &sz)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - if (sz == 0 || sz > sizeof(ctx->iv)) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); - return 0; - } - ctx->ivlen = sz; - } - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_OCTET_STRING) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - sz = gcm_tls_init(ctx, p->data, p->data_size); - if (sz == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD); - return 0; - } - ctx->tls_aad_pad_sz = sz; - } - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_OCTET_STRING) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - if (gcm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV); - if (p != NULL) { - if (p->data == NULL - || p->data_type != OSSL_PARAM_OCTET_STRING - || !setivinv(ctx, p->data, p->data_size)) - return 0; - } - - return 1; } diff --git a/providers/implementations/digests/blake2_prov.c b/providers/implementations/digests/blake2_prov.c index 25342eedb8..d31627b92e 100644 --- a/providers/implementations/digests/blake2_prov.c +++ b/providers/implementations/digests/blake2_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,11 +8,12 @@ */ #include +#include #include "prov/blake2.h" #include "prov/digestcommon.h" #include "prov/implementations.h" -int ossl_blake2s256_init(void *ctx) +static int ossl_blake2s256_init(void *ctx) { BLAKE2S_PARAM P; @@ -20,12 +21,15 @@ int ossl_blake2s256_init(void *ctx) return ossl_blake2s_init((BLAKE2S_CTX *)ctx, &P); } -int ossl_blake2b512_init(void *ctx) +static int ossl_blake2b512_init(void *ctx) { - BLAKE2B_PARAM P; + struct blake2b_md_data_st *mdctx = ctx; + uint8_t digest_length = mdctx->params.digest_length; - ossl_blake2b_param_init(&P); - return ossl_blake2b_init((BLAKE2B_CTX *)ctx, &P); + ossl_blake2b_param_init(&mdctx->params); + if (digest_length != 0) + mdctx->params.digest_length = digest_length; + return ossl_blake2b_init(&mdctx->ctx, &mdctx->params); } /* ossl_blake2s256_functions */ @@ -35,7 +39,92 @@ IMPLEMENT_digest_functions(blake2s256, BLAKE2S_CTX, ossl_blake2s_final) /* ossl_blake2b512_functions */ -IMPLEMENT_digest_functions(blake2b512, BLAKE2B_CTX, - BLAKE2B_BLOCKBYTES, BLAKE2B_DIGEST_LENGTH, 0, - ossl_blake2b512_init, ossl_blake2b_update, - ossl_blake2b_final) + +static OSSL_FUNC_digest_init_fn blake2b512_internal_init; +static OSSL_FUNC_digest_newctx_fn blake2b512_newctx; +static OSSL_FUNC_digest_freectx_fn blake2b512_freectx; +static OSSL_FUNC_digest_dupctx_fn blake2b512_dupctx; +static OSSL_FUNC_digest_final_fn blake2b512_internal_final; +static OSSL_FUNC_digest_get_params_fn blake2b512_get_params; + +static int blake2b512_internal_init(void *ctx, const OSSL_PARAM params[]) +{ + return ossl_prov_is_running() && ossl_blake2b_set_ctx_params(ctx, params) + && ossl_blake2b512_init(ctx); +} + +static void *blake2b512_newctx(void *prov_ctx) +{ + struct blake2b_md_data_st *ctx; + + ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; + return ctx; +} + +static void blake2b512_freectx(void *vctx) +{ + struct blake2b_md_data_st *ctx; + + ctx = (struct blake2b_md_data_st *)vctx; + OPENSSL_clear_free(ctx, sizeof(*ctx)); +} + +static void *blake2b512_dupctx(void *ctx) +{ + struct blake2b_md_data_st *in, *ret; + + in = (struct blake2b_md_data_st *)ctx; + ret = ossl_prov_is_running()? OPENSSL_malloc(sizeof(*ret)) : NULL; + if (ret != NULL) + *ret = *in; + return ret; +} + +static int blake2b512_internal_final(void *ctx, unsigned char *out, + size_t *outl, size_t outsz) +{ + struct blake2b_md_data_st *b_ctx; + + b_ctx = (struct blake2b_md_data_st *)ctx; + + if (!ossl_prov_is_running()) + return 0; + + *outl = b_ctx->ctx.outlen; + + if (outsz == 0) + return 1; + + if (outsz < *outl) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); + return 0; + } + + return ossl_blake2b_final(out, ctx); +} + +static int blake2b512_get_params(OSSL_PARAM params[]) +{ + return ossl_digest_default_get_params(params, BLAKE2B_BLOCKBYTES, 64, 0); +} + +const OSSL_DISPATCH ossl_blake2b512_functions[] = { + {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake2b512_newctx}, + {OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake2b_update}, + {OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake2b512_internal_final}, + {OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake2b512_freectx}, + {OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))blake2b512_dupctx}, + {OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))blake2b512_get_params}, + {OSSL_FUNC_DIGEST_GETTABLE_PARAMS, + (void (*)(void))ossl_digest_default_gettable_params}, + {OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake2b512_internal_init}, + {OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, + (void (*)(void))ossl_blake2b_gettable_ctx_params}, + {OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, + (void (*)(void))ossl_blake2b_settable_ctx_params}, + {OSSL_FUNC_DIGEST_GET_CTX_PARAMS, + (void (*)(void))ossl_blake2b_get_ctx_params}, + {OSSL_FUNC_DIGEST_SET_CTX_PARAMS, + (void (*)(void))ossl_blake2b_set_ctx_params}, + {0, NULL} +}; diff --git a/providers/implementations/digests/blake2b_prov.c b/providers/implementations/digests/blake2b_prov.c index 11271e1b59..1917990c44 100644 --- a/providers/implementations/digests/blake2b_prov.c +++ b/providers/implementations/digests/blake2b_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,9 +17,81 @@ #include #include #include +#include +#include +#include +#include "internal/numbers.h" #include "blake2_impl.h" #include "prov/blake2.h" +static const OSSL_PARAM known_blake2b_ctx_params[] = { + {OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, + OSSL_PARAM_END +}; + +const OSSL_PARAM *ossl_blake2b_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *pctx) +{ + return known_blake2b_ctx_params; +} + +const OSSL_PARAM *ossl_blake2b_settable_ctx_params(ossl_unused void *ctx, + ossl_unused void *pctx) +{ + return known_blake2b_ctx_params; +} + +int ossl_blake2b_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + struct blake2b_md_data_st *mdctx = vctx; + OSSL_PARAM *p; + + BLAKE2B_CTX *ctx = &mdctx->ctx; + + if (ctx == NULL) + return 0; + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); + if (p != NULL + && !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + + return 1; +} + +int ossl_blake2b_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + size_t size; + struct blake2b_md_data_st *mdctx = vctx; + const OSSL_PARAM *p; + + BLAKE2B_CTX *ctx = &mdctx->ctx; + + if (ctx == NULL) + return 0; + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE); + if (p != NULL) { + if (!OSSL_PARAM_get_size_t(p, &size)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (size < 1 || size > BLAKE2B_OUTBYTES) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); + return 0; + } + ossl_blake2b_param_set_digest_length(&mdctx->params, (uint8_t)size); + } + + return 1; +} + static const uint64_t blake2b_IV[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, diff --git a/providers/implementations/digests/sha2_prov.c b/providers/implementations/digests/sha2_prov.c index b239adbb47..60f1912cc4 100644 --- a/providers/implementations/digests/sha2_prov.c +++ b/providers/implementations/digests/sha2_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -71,7 +71,12 @@ IMPLEMENT_digest_functions(sha224, SHA256_CTX, IMPLEMENT_digest_functions(sha256, SHA256_CTX, SHA256_CBLOCK, SHA256_DIGEST_LENGTH, SHA2_FLAGS, SHA256_Init, SHA256_Update, SHA256_Final) - +#ifndef FIPS_MODULE +/* ossl_sha256_192_functions */ +IMPLEMENT_digest_functions(sha256_192, SHA256_CTX, + SHA256_CBLOCK, SHA256_192_DIGEST_LENGTH, SHA2_FLAGS, + ossl_sha256_192_init, SHA256_Update, SHA256_Final) +#endif /* ossl_sha384_functions */ IMPLEMENT_digest_functions(sha384, SHA512_CTX, SHA512_CBLOCK, SHA384_DIGEST_LENGTH, SHA2_FLAGS, diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c index 3690dc93d6..423bed7983 100644 --- a/providers/implementations/digests/sha3_prov.c +++ b/providers/implementations/digests/sha3_prov.c @@ -183,7 +183,6 @@ static int s390x_keccakc_final(unsigned char *md, void *vctx, int padding) size_t bsz = ctx->block_size; size_t num = ctx->bufsz; size_t needed = ctx->md_size; - static const unsigned char empty[KECCAK1600_WIDTH / 8] = {0}; if (!ossl_prov_is_running()) return 0; @@ -193,17 +192,20 @@ static int s390x_keccakc_final(unsigned char *md, void *vctx, int padding) ctx->buf[num] = padding; ctx->buf[bsz - 1] |= 0x80; s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A); - while (needed > bsz) { - memcpy(md, ctx->A, bsz); - needed -= bsz; - md += bsz; - s390x_kimd(empty, bsz, ctx->pad, ctx->A); - } - memcpy(md, ctx->A, needed); + num = needed > bsz ? bsz : needed; + memcpy(md, ctx->A, num); + needed -= num; + if (needed > 0) + s390x_klmd(NULL, 0, md + bsz, needed, ctx->pad | S390X_KLMD_PS, ctx->A); return 1; } +static int s390x_keccak_final(unsigned char *md, void *vctx) +{ + return s390x_keccakc_final(md, vctx, 0x01); +} + static int s390x_kmac_final(unsigned char *md, void *vctx) { return s390x_keccakc_final(md, vctx, 0x04); @@ -215,6 +217,12 @@ static PROV_SHA3_METHOD sha3_s390x_md = s390x_sha3_final }; +static PROV_SHA3_METHOD keccak_s390x_md = +{ + s390x_sha3_absorb, + s390x_keccak_final +}; + static PROV_SHA3_METHOD shake_s390x_md = { s390x_sha3_absorb, @@ -241,6 +249,40 @@ static PROV_SHA3_METHOD kmac_s390x_md = } else { \ ctx->meth = sha3_generic_md; \ } +#elif defined(__aarch64__) && defined(KECCAK1600_ASM) +# include "arm_arch.h" + +static sha3_absorb_fn armsha3_sha3_absorb; + +size_t SHA3_absorb_cext(uint64_t A[5][5], const unsigned char *inp, size_t len, + size_t r); +/*- + * Hardware-assisted ARMv8.2 SHA3 extension version of the absorb() + */ +static size_t armsha3_sha3_absorb(void *vctx, const void *inp, size_t len) +{ + KECCAK1600_CTX *ctx = vctx; + + return SHA3_absorb_cext(ctx->A, inp, len, ctx->block_size); +} + +static PROV_SHA3_METHOD sha3_ARMSHA3_md = +{ + armsha3_sha3_absorb, + generic_sha3_final +}; +# define SHA3_SET_MD(uname, typ) \ + if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ + ctx->meth = sha3_ARMSHA3_md; \ + } else { \ + ctx->meth = sha3_generic_md; \ + } +# define KMAC_SET_MD(bitlen) \ + if (OPENSSL_armcap_P & ARMV8_HAVE_SHA3_AND_WORTH_USING) { \ + ctx->meth = sha3_ARMSHA3_md; \ + } else { \ + ctx->meth = sha3_generic_md; \ + } #else # define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md; # define KMAC_SET_MD(bitlen) ctx->meth = sha3_generic_md; @@ -349,6 +391,12 @@ static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[]) SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ SHA3_FLAGS) +#define IMPLEMENT_KECCAK_functions(bitlen) \ + SHA3_newctx(keccak, KECCAK_##bitlen, keccak_##bitlen, bitlen, '\x01') \ + PROV_FUNC_SHA3_DIGEST(keccak_##bitlen, bitlen, \ + SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ + SHA3_FLAGS) + #define IMPLEMENT_SHAKE_functions(bitlen) \ SHA3_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \ PROV_FUNC_SHAKE_DIGEST(shake_##bitlen, bitlen, \ @@ -368,6 +416,14 @@ IMPLEMENT_SHA3_functions(256) IMPLEMENT_SHA3_functions(384) /* ossl_sha3_512_functions */ IMPLEMENT_SHA3_functions(512) +/* ossl_keccak_224_functions */ +IMPLEMENT_KECCAK_functions(224) +/* ossl_keccak_256_functions */ +IMPLEMENT_KECCAK_functions(256) +/* ossl_keccak_384_functions */ +IMPLEMENT_KECCAK_functions(384) +/* ossl_keccak_512_functions */ +IMPLEMENT_KECCAK_functions(512) /* ossl_shake_128_functions */ IMPLEMENT_SHAKE_functions(128) /* ossl_shake_256_functions */ diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index 72f73b69dc..b0d4e0ecf6 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -89,6 +89,7 @@ struct keytype_desc_st { */ struct der2key_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; const struct keytype_desc_st *desc; /* The selection that is passed to der2key_decode() */ int selection; @@ -109,7 +110,7 @@ static void *der2key_decode_p8(const unsigned char **input_der, if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf) && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type) - key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), NULL); + key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), ctx->propq); PKCS8_PRIV_KEY_INFO_free(p8inf); return key; @@ -120,6 +121,8 @@ static void *der2key_decode_p8(const unsigned char **input_der, static OSSL_FUNC_decoder_freectx_fn der2key_freectx; static OSSL_FUNC_decoder_decode_fn der2key_decode; static OSSL_FUNC_decoder_export_object_fn der2key_export_object; +static OSSL_FUNC_decoder_settable_ctx_params_fn der2key_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn der2key_set_ctx_params; static struct der2key_ctx_st * der2key_newctx(void *provctx, const struct keytype_desc_st *desc) @@ -133,6 +136,28 @@ der2key_newctx(void *provctx, const struct keytype_desc_st *desc) return ctx; } +static const OSSL_PARAM *der2key_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int der2key_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct der2key_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static void der2key_freectx(void *vctx) { struct der2key_ctx_st *ctx = vctx; @@ -421,6 +446,7 @@ static void ec_adjust(void *key, struct der2key_ctx_st *ctx) ossl_ec_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); } +# ifndef OPENSSL_NO_ECX /* * ED25519, ED448, X25519, X448 only implement PKCS#8 and SubjectPublicKeyInfo, * so no d2i functions to be had. @@ -438,45 +464,46 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) ossl_ecx_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); } -# define ed25519_evp_type EVP_PKEY_ED25519 -# define ed25519_d2i_private_key NULL -# define ed25519_d2i_public_key NULL -# define ed25519_d2i_key_params NULL -# define ed25519_d2i_PKCS8 ecx_d2i_PKCS8 -# define ed25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED25519_PUBKEY -# define ed25519_free (free_key_fn *)ossl_ecx_key_free -# define ed25519_check NULL -# define ed25519_adjust ecx_key_adjust - -# define ed448_evp_type EVP_PKEY_ED448 -# define ed448_d2i_private_key NULL -# define ed448_d2i_public_key NULL -# define ed448_d2i_key_params NULL -# define ed448_d2i_PKCS8 ecx_d2i_PKCS8 -# define ed448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED448_PUBKEY -# define ed448_free (free_key_fn *)ossl_ecx_key_free -# define ed448_check NULL -# define ed448_adjust ecx_key_adjust - -# define x25519_evp_type EVP_PKEY_X25519 -# define x25519_d2i_private_key NULL -# define x25519_d2i_public_key NULL -# define x25519_d2i_key_params NULL -# define x25519_d2i_PKCS8 ecx_d2i_PKCS8 -# define x25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X25519_PUBKEY -# define x25519_free (free_key_fn *)ossl_ecx_key_free -# define x25519_check NULL -# define x25519_adjust ecx_key_adjust - -# define x448_evp_type EVP_PKEY_X448 -# define x448_d2i_private_key NULL -# define x448_d2i_public_key NULL -# define x448_d2i_key_params NULL -# define x448_d2i_PKCS8 ecx_d2i_PKCS8 -# define x448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X448_PUBKEY -# define x448_free (free_key_fn *)ossl_ecx_key_free -# define x448_check NULL -# define x448_adjust ecx_key_adjust +# define ed25519_evp_type EVP_PKEY_ED25519 +# define ed25519_d2i_private_key NULL +# define ed25519_d2i_public_key NULL +# define ed25519_d2i_key_params NULL +# define ed25519_d2i_PKCS8 ecx_d2i_PKCS8 +# define ed25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED25519_PUBKEY +# define ed25519_free (free_key_fn *)ossl_ecx_key_free +# define ed25519_check NULL +# define ed25519_adjust ecx_key_adjust + +# define ed448_evp_type EVP_PKEY_ED448 +# define ed448_d2i_private_key NULL +# define ed448_d2i_public_key NULL +# define ed448_d2i_key_params NULL +# define ed448_d2i_PKCS8 ecx_d2i_PKCS8 +# define ed448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED448_PUBKEY +# define ed448_free (free_key_fn *)ossl_ecx_key_free +# define ed448_check NULL +# define ed448_adjust ecx_key_adjust + +# define x25519_evp_type EVP_PKEY_X25519 +# define x25519_d2i_private_key NULL +# define x25519_d2i_public_key NULL +# define x25519_d2i_key_params NULL +# define x25519_d2i_PKCS8 ecx_d2i_PKCS8 +# define x25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X25519_PUBKEY +# define x25519_free (free_key_fn *)ossl_ecx_key_free +# define x25519_check NULL +# define x25519_adjust ecx_key_adjust + +# define x448_evp_type EVP_PKEY_X448 +# define x448_d2i_private_key NULL +# define x448_d2i_public_key NULL +# define x448_d2i_key_params NULL +# define x448_d2i_PKCS8 ecx_d2i_PKCS8 +# define x448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X448_PUBKEY +# define x448_free (free_key_fn *)ossl_ecx_key_free +# define x448_check NULL +# define x448_adjust ecx_key_adjust +# endif /* OPENSSL_NO_ECX */ # ifndef OPENSSL_NO_SM2 # define sm2_evp_type EVP_PKEY_SM2 @@ -753,7 +780,11 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) (void (*)(void))der2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))der2key_export_object }, \ - { 0, NULL } \ + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))der2key_settable_ctx_params }, \ + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, \ + (void (*)(void))der2key_set_ctx_params }, \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DH @@ -777,6 +808,7 @@ MAKE_DECODER("EC", ec, ec, PrivateKeyInfo); MAKE_DECODER("EC", ec, ec, SubjectPublicKeyInfo); MAKE_DECODER("EC", ec, ec, type_specific_no_pub); MAKE_DECODER("EC", ec, ec, EC); +# ifndef OPENSSL_NO_ECX MAKE_DECODER("X25519", x25519, ecx, PrivateKeyInfo); MAKE_DECODER("X25519", x25519, ecx, SubjectPublicKeyInfo); MAKE_DECODER("X448", x448, ecx, PrivateKeyInfo); @@ -785,9 +817,11 @@ MAKE_DECODER("ED25519", ed25519, ecx, PrivateKeyInfo); MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo); MAKE_DECODER("ED448", ed448, ecx, PrivateKeyInfo); MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo); +# endif # ifndef OPENSSL_NO_SM2 MAKE_DECODER("SM2", sm2, ec, PrivateKeyInfo); MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo); +MAKE_DECODER("SM2", sm2, sm2, type_specific_no_pub); # endif #endif MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo); diff --git a/providers/implementations/encode_decode/decode_epki2pki.c b/providers/implementations/encode_decode/decode_epki2pki.c index 9cea80b616..37d9bd1858 100644 --- a/providers/implementations/encode_decode/decode_epki2pki.c +++ b/providers/implementations/encode_decode/decode_epki2pki.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,12 +26,15 @@ static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx; static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx; static OSSL_FUNC_decoder_decode_fn epki2pki_decode; +static OSSL_FUNC_decoder_settable_ctx_params_fn epki2pki_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn epki2pki_set_ctx_params; /* * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding. */ struct epki2pki_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *epki2pki_newctx(void *provctx) @@ -50,6 +53,28 @@ static void epki2pki_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *epki2pki_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int epki2pki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct epki2pki_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + /* * The selection parameter in epki2pki_decode() is not used by this function * because it's not relevant just to decode EncryptedPrivateKeyInfo to @@ -104,7 +129,8 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if (!PKCS12_pbe_crypt_ex(alg, pbuf, plen, oct->data, oct->length, &new_der, &new_der_len, 0, - PROV_LIBCTX_OF(ctx->provctx), NULL)) { + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq)) { ok = 0; } else { OPENSSL_free(der); @@ -154,5 +180,9 @@ const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[] { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))epki2pki_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))epki2pki_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))epki2pki_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))epki2pki_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))epki2pki_set_ctx_params }, + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/decode_msblob2key.c b/providers/implementations/encode_decode/decode_msblob2key.c index b9d0cabada..df327210f1 100644 --- a/providers/implementations/encode_decode/decode_msblob2key.c +++ b/providers/implementations/encode_decode/decode_msblob2key.c @@ -132,10 +132,8 @@ static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, goto next; } buf = OPENSSL_malloc(length); - if (buf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto end; - } p = buf; if (BIO_read(in, buf, length) != (int)length) { ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); @@ -282,7 +280,7 @@ static void rsa_adjust(void *key, struct msblob2key_ctx_st *ctx) (void (*)(void))msblob2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))msblob2key_export_object }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c index bc937ffb9d..ea6eb7f961 100644 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -119,6 +119,7 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, { PEM_STRING_DSAPARAMS, OSSL_OBJECT_PKEY, "DSA", "type-specific" }, { PEM_STRING_ECPRIVATEKEY, OSSL_OBJECT_PKEY, "EC", "type-specific" }, { PEM_STRING_ECPARAMETERS, OSSL_OBJECT_PKEY, "EC", "type-specific" }, + { PEM_STRING_SM2PARAMETERS, OSSL_OBJECT_PKEY, "SM2", "type-specific" }, { PEM_STRING_RSA, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, { PEM_STRING_RSA_PUBLIC, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, @@ -215,5 +216,5 @@ const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[] = { { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))pem2der_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))pem2der_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2der_decode }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/decode_pvk2key.c b/providers/implementations/encode_decode/decode_pvk2key.c index 2d7cb15e53..ea4585d93c 100644 --- a/providers/implementations/encode_decode/decode_pvk2key.c +++ b/providers/implementations/encode_decode/decode_pvk2key.c @@ -24,6 +24,7 @@ #include /* For public PVK functions */ #include #include "internal/passphrase.h" +#include "internal/sizes.h" #include "crypto/pem.h" /* For internal PVK and "blob" headers */ #include "crypto/rsa.h" #include "prov/bio.h" @@ -49,12 +50,15 @@ struct keytype_desc_st { static OSSL_FUNC_decoder_freectx_fn pvk2key_freectx; static OSSL_FUNC_decoder_decode_fn pvk2key_decode; static OSSL_FUNC_decoder_export_object_fn pvk2key_export_object; +static OSSL_FUNC_decoder_settable_ctx_params_fn pvk2key_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn pvk2key_set_ctx_params; /* * Context used for DER to key decoding. */ struct pvk2key_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; const struct keytype_desc_st *desc; /* The selection that is passed to der2key_decode() */ int selection; @@ -79,6 +83,28 @@ static void pvk2key_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *pvk2key_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END, + }; + return settables; +} + +static int pvk2key_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct pvk2key_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static int pvk2key_does_selection(void *provctx, int selection) { if (selection == 0) @@ -115,7 +141,8 @@ static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, goto end; key = ctx->desc->read_private_key(in, ossl_pw_pvk_password, &pwdata, - PROV_LIBCTX_OF(ctx->provctx), NULL); + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); /* * Because the PVK API doesn't have a separate decrypt call, we need @@ -247,7 +274,11 @@ static void rsa_adjust(void *key, struct pvk2key_ctx_st *ctx) (void (*)(void))pvk2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))pvk2key_export_object }, \ - { 0, NULL } \ + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))pvk2key_settable_ctx_params }, \ + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, \ + (void (*)(void))pvk2key_set_ctx_params }, \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/decode_spki2typespki.c b/providers/implementations/encode_decode/decode_spki2typespki.c index a5dbbb31ad..7074be93d6 100644 --- a/providers/implementations/encode_decode/decode_spki2typespki.c +++ b/providers/implementations/encode_decode/decode_spki2typespki.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,6 +23,8 @@ static OSSL_FUNC_decoder_newctx_fn spki2typespki_newctx; static OSSL_FUNC_decoder_freectx_fn spki2typespki_freectx; static OSSL_FUNC_decoder_decode_fn spki2typespki_decode; +static OSSL_FUNC_decoder_settable_ctx_params_fn spki2typespki_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn spki2typespki_set_ctx_params; /* * Context used for SubjectPublicKeyInfo to Type specific SubjectPublicKeyInfo @@ -30,6 +32,7 @@ static OSSL_FUNC_decoder_decode_fn spki2typespki_decode; */ struct spki2typespki_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *spki2typespki_newctx(void *provctx) @@ -48,6 +51,28 @@ static void spki2typespki_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *spki2typespki_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int spki2typespki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct spki2typespki_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *data_cb, void *data_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) @@ -67,8 +92,8 @@ static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, return 1; derp = der; xpub = ossl_d2i_X509_PUBKEY_INTERNAL((const unsigned char **)&derp, len, - PROV_LIBCTX_OF(ctx->provctx)); - + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); if (xpub == NULL) { /* We return "empty handed". This is not an error. */ @@ -120,5 +145,9 @@ const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_der_decoder_functions[] = { { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))spki2typespki_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))spki2typespki_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))spki2typespki_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))spki2typespki_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))spki2typespki_set_ctx_params }, + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index 03d8b26ec6..ae6d7d0a68 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -67,7 +67,7 @@ typedef int write_bio_of_void_fn(BIO *bp, const void *x); /* Free the blob allocated during key_to_paramstring_fn */ static void free_asn1_data(int type, void *data) { - switch(type) { + switch (type) { case V_ASN1_OBJECT: ASN1_OBJECT_free(data); break; @@ -91,7 +91,7 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, || (derlen = k2d(key, &der)) <= 0 || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); PKCS8_PRIV_KEY_INFO_free(p8info); OPENSSL_free(der); p8info = NULL; @@ -154,7 +154,7 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, || (derlen = k2d(key, &der)) <= 0 || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_X509_LIB); X509_PUBKEY_free(xpk); OPENSSL_free(der); xpk = NULL; @@ -380,7 +380,7 @@ static int key_to_type_specific_der_bio(BIO *out, const void *key, int ret; if ((derlen = k2d(key, &der)) <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return 0; } @@ -446,7 +446,7 @@ static int prepare_dh_params(const void *dh, int nid, int save, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } @@ -456,7 +456,7 @@ static int prepare_dh_params(const void *dh, int nid, int save, params->length = i2d_DHparams(dh, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -550,14 +550,14 @@ static int encode_dsa_params(const void *dsa, int nid, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } params->length = i2d_DSAparams(dsa, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -645,13 +645,13 @@ static int prepare_ec_explicit_params(const void *eckey, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } params->length = i2d_ECParameters(eckey, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -748,7 +748,7 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) /* ---------------------------------------------------------------------- */ -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECX # define prepare_ecx_params NULL static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) @@ -762,10 +762,8 @@ static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) } keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen); - if (keyblob == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (keyblob == NULL) return 0; - } *pder = keyblob; return ecxkey->keylen; @@ -788,7 +786,7 @@ static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); if (keybloblen < 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } @@ -1298,7 +1296,7 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, (void (*)(void))impl##_to_##kind##_##output##_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##_to_##kind##_##output##_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } /* @@ -1396,6 +1394,7 @@ MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, pem); MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); # endif +# ifndef OPENSSL_NO_ECX MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, der); MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, pem); MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, der); @@ -1420,6 +1419,7 @@ MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der); MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem); MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der); MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); +# endif #endif /* diff --git a/providers/implementations/encode_decode/encode_key2blob.c b/providers/implementations/encode_decode/encode_key2blob.c index 550bceb09f..29e72faa63 100644 --- a/providers/implementations/encode_decode/encode_key2blob.c +++ b/providers/implementations/encode_decode/encode_key2blob.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -168,7 +168,7 @@ static int key2blob_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2blob_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2blob_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_EC diff --git a/providers/implementations/encode_decode/encode_key2ms.c b/providers/implementations/encode_decode/encode_key2ms.c index fe8c2dce43..1f21a51296 100644 --- a/providers/implementations/encode_decode/encode_key2ms.c +++ b/providers/implementations/encode_decode/encode_key2ms.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -222,7 +222,7 @@ static int key2pvk_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2##output##_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2##output##_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 3e75a9afb3..c0c2923285 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -109,7 +109,7 @@ static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) if ((bytes % 15) == 0 && bytes > 0) { if (BIO_printf(out, ":\n%s", spaces) <= 0) goto err; - use_sep = 0; /* The first byte on the next line doesnt have a : */ + use_sep = 0; /* The first byte on the next line doesn't have a : */ } if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", tolower(p[0]), tolower(p[1])) <= 0) @@ -512,7 +512,8 @@ static int ec_to_text(BIO *out, const void *key, int selection) else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) type_label = "Public-Key"; else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) - type_label = "EC-Parameters"; + if (EC_GROUP_get_curve_name(group) != NID_sm2) + type_label = "EC-Parameters"; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); @@ -538,8 +539,9 @@ static int ec_to_text(BIO *out, const void *key, int selection) goto err; } - if (BIO_printf(out, "%s: (%d bit)\n", type_label, - EC_GROUP_order_bits(group)) <= 0) + if (type_label != NULL + && BIO_printf(out, "%s: (%d bit)\n", type_label, + EC_GROUP_order_bits(group)) <= 0) goto err; if (priv != NULL && !print_labeled_buf(out, "priv:", priv, priv_len)) @@ -564,7 +566,7 @@ static int ec_to_text(BIO *out, const void *key, int selection) /* ---------------------------------------------------------------------- */ -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECX static int ecx_to_text(BIO *out, const void *key, int selection) { const ECX_KEY *ecx = key; @@ -649,7 +651,7 @@ static int rsa_to_text(BIO *out, const void *key, int selection) coeffs = sk_BIGNUM_const_new_null(); if (factors == NULL || exps == NULL || coeffs == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB); goto err; } @@ -852,7 +854,7 @@ static int key2text_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2text_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2text_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DH @@ -867,10 +869,12 @@ MAKE_TEXT_ENCODER(ec, ec); # ifndef OPENSSL_NO_SM2 MAKE_TEXT_ENCODER(sm2, ec); # endif +# ifndef OPENSSL_NO_ECX MAKE_TEXT_ENCODER(ed25519, ecx); MAKE_TEXT_ENCODER(ed448, ecx); MAKE_TEXT_ENCODER(x25519, ecx); MAKE_TEXT_ENCODER(x448, ecx); +# endif #endif MAKE_TEXT_ENCODER(rsa, rsa); MAKE_TEXT_ENCODER(rsapss, rsa); diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info index 3c1e5c58f1..0333c9f49c 100644 --- a/providers/implementations/exchange/build.info +++ b/providers/implementations/exchange/build.info @@ -21,8 +21,10 @@ IF[{- !$disabled{asm} -}] ENDIF IF[{- !$disabled{ec} -}] - SOURCE[$ECX_GOAL]=ecx_exch.c - DEFINE[$ECX_GOAL]=$ECDEF + IF[{- !$disabled{ecx} -}] + SOURCE[$ECX_GOAL]=ecx_exch.c + DEFINE[$ECX_GOAL]=$ECDEF + ENDIF SOURCE[$ECDH_GOAL]=ecdh_exch.c ENDIF diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c index dd5254fef3..20b8fa0078 100644 --- a/providers/implementations/exchange/dh_exch.c +++ b/providers/implementations/exchange/dh_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -194,10 +194,8 @@ static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret, } if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1)) return 0; - if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) return 0; - } if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, 1)) goto err; @@ -474,7 +472,7 @@ static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL ? "" - : EVP_MD_get0_name(pdhctx->kdf_md))){ + : EVP_MD_get0_name(pdhctx->kdf_md))) { return 0; } @@ -509,5 +507,5 @@ const OSSL_DISPATCH ossl_dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params }, { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))dh_gettable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/exchange/ecdh_exch.c b/providers/implementations/exchange/ecdh_exch.c index 43caedb6df..5b8412aba1 100644 --- a/providers/implementations/exchange/ecdh_exch.c +++ b/providers/implementations/exchange/ecdh_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -126,7 +126,7 @@ int ecdh_match_params(const EC_KEY *priv, const EC_KEY *peer) ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(priv)); if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_BN_LIB); return 0; } ret = group_priv != NULL @@ -378,7 +378,7 @@ int ecdh_get_ctx_params(void *vpecdhctx, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pectx->kdf_md == NULL ? "" - : EVP_MD_get0_name(pectx->kdf_md))){ + : EVP_MD_get0_name(pectx->kdf_md))) { return 0; } @@ -451,7 +451,7 @@ int ecdh_plain_derive(void *vpecdhctx, unsigned char *secret, } if ((group = EC_KEY_get0_group(pecdhctx->k)) == NULL - || (cofactor = EC_GROUP_get0_cofactor(group)) == NULL ) + || (cofactor = EC_GROUP_get0_cofactor(group)) == NULL) return 0; /* @@ -524,10 +524,8 @@ int ecdh_X9_63_kdf_derive(void *vpecdhctx, unsigned char *secret, } if (!ecdh_plain_derive(vpecdhctx, NULL, &stmplen, 0)) return 0; - if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) return 0; - } if (!ecdh_plain_derive(vpecdhctx, stmp, &stmplen, stmplen)) goto err; @@ -577,5 +575,5 @@ const OSSL_DISPATCH ossl_ecdh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))ecdh_get_ctx_params }, { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))ecdh_gettable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/exchange/ecx_exch.c b/providers/implementations/exchange/ecx_exch.c index 2ba9090c8b..ccf39462ed 100644 --- a/providers/implementations/exchange/ecx_exch.c +++ b/providers/implementations/exchange/ecx_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,9 +17,6 @@ #include "crypto/ecx.h" #include "prov/implementations.h" #include "prov/providercommon.h" -#ifdef S390X_EC_ASM -# include "s390x_arch.h" -#endif static OSSL_FUNC_keyexch_newctx_fn x25519_newctx; static OSSL_FUNC_keyexch_newctx_fn x448_newctx; @@ -49,10 +46,8 @@ static void *ecx_newctx(void *provctx, size_t keylen) return NULL; ctx = OPENSSL_zalloc(sizeof(PROV_ECX_CTX)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->keylen = keylen; @@ -120,65 +115,8 @@ static int ecx_derive(void *vecxctx, unsigned char *secret, size_t *secretlen, if (!ossl_prov_is_running()) return 0; - - if (ecxctx->key == NULL - || ecxctx->key->privkey == NULL - || ecxctx->peerkey == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); - return 0; - } - - if (!ossl_assert(ecxctx->keylen == X25519_KEYLEN - || ecxctx->keylen == X448_KEYLEN)) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); - return 0; - } - - if (secret == NULL) { - *secretlen = ecxctx->keylen; - return 1; - } - if (outlen < ecxctx->keylen) { - ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } - - if (ecxctx->keylen == X25519_KEYLEN) { -#ifdef S390X_EC_ASM - if (OPENSSL_s390xcap_P.pcc[1] - & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) { - if (s390x_x25519_mul(secret, ecxctx->peerkey->pubkey, - ecxctx->key->privkey) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); - return 0; - } - } else -#endif - if (ossl_x25519(secret, ecxctx->key->privkey, - ecxctx->peerkey->pubkey) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); - return 0; - } - } else { -#ifdef S390X_EC_ASM - if (OPENSSL_s390xcap_P.pcc[1] - & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) { - if (s390x_x448_mul(secret, ecxctx->peerkey->pubkey, - ecxctx->key->privkey) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); - return 0; - } - } else -#endif - if (ossl_x448(secret, ecxctx->key->privkey, - ecxctx->peerkey->pubkey) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); - return 0; - } - } - - *secretlen = ecxctx->keylen; - return 1; + return ossl_ecx_compute_key(ecxctx->peerkey, ecxctx->key, ecxctx->keylen, + secret, secretlen, outlen); } static void ecx_freectx(void *vecxctx) @@ -200,10 +138,8 @@ static void *ecx_dupctx(void *vecxctx) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); - if (dstctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (dstctx == NULL) return NULL; - } *dstctx = *srcctx; if (dstctx->key != NULL && !ossl_ecx_key_up_ref(dstctx->key)) { @@ -229,7 +165,7 @@ const OSSL_DISPATCH ossl_x25519_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))ecx_set_peer }, { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))ecx_freectx }, { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))ecx_dupctx }, - { 0, NULL } + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_x448_keyexch_functions[] = { @@ -239,5 +175,5 @@ const OSSL_DISPATCH ossl_x448_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))ecx_set_peer }, { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))ecx_freectx }, { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))ecx_dupctx }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/exchange/kdf_exch.c b/providers/implementations/exchange/kdf_exch.c index 527a866c3d..4aaf673398 100644 --- a/providers/implementations/exchange/kdf_exch.c +++ b/providers/implementations/exchange/kdf_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -207,7 +207,7 @@ KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT") { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \ { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ (void (*)(void))kdf_##funcname##_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; KDF_KEYEXCH_FUNCTIONS(tls1_prf) diff --git a/providers/implementations/include/prov/blake2.h b/providers/implementations/include/prov/blake2.h index d18cbc708c..445fd89aa2 100644 --- a/providers/implementations/include/prov/blake2.h +++ b/providers/implementations/include/prov/blake2.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,7 @@ # include # include +# include # define BLAKE2S_BLOCKBYTES 64 # define BLAKE2S_OUTBYTES 32 @@ -82,8 +83,10 @@ struct blake2b_ctx_st { typedef struct blake2s_ctx_st BLAKE2S_CTX; typedef struct blake2b_ctx_st BLAKE2B_CTX; -int ossl_blake2s256_init(void *ctx); -int ossl_blake2b512_init(void *ctx); +struct blake2b_md_data_st { + BLAKE2B_CTX ctx; + BLAKE2B_PARAM params; +}; int ossl_blake2b_init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P); int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, @@ -91,6 +94,11 @@ int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, int ossl_blake2b_update(BLAKE2B_CTX *c, const void *data, size_t datalen); int ossl_blake2b_final(unsigned char *md, BLAKE2B_CTX *c); +OSSL_FUNC_digest_get_ctx_params_fn ossl_blake2b_get_ctx_params; +OSSL_FUNC_digest_set_ctx_params_fn ossl_blake2b_set_ctx_params; +OSSL_FUNC_digest_gettable_ctx_params_fn ossl_blake2b_gettable_ctx_params; +OSSL_FUNC_digest_settable_ctx_params_fn ossl_blake2b_settable_ctx_params; + /* * These setters are internal and do not check the validity of their parameters. * See blake2b_mac_ctrl for validation logic. diff --git a/providers/implementations/include/prov/ciphercommon.h b/providers/implementations/include/prov/ciphercommon.h index 94f485f9b1..45002ad594 100644 --- a/providers/implementations/include/prov/ciphercommon.h +++ b/providers/implementations/include/prov/ciphercommon.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,23 +7,27 @@ * https://www.openssl.org/source/license.html */ -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "crypto/modes.h" +#ifndef OSSL_PROV_CIPHERCOMMON_H +# define OSSL_PROV_CIPHERCOMMON_H +# pragma once + +# include +# include +# include +# include +# include "internal/cryptlib.h" +# include "crypto/modes.h" # define MAXCHUNK ((size_t)1 << 30) # define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) -#define GENERIC_BLOCK_SIZE 16 -#define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ -#define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ -#define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ -#define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ +# define GENERIC_BLOCK_SIZE 16 +# define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ +# define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ +# define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ +# define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ -#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args +# define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args typedef struct prov_cipher_hw_st PROV_CIPHER_HW; typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; @@ -32,14 +36,14 @@ typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len); /* Internal flags that can be queried */ -#define PROV_CIPHER_FLAG_AEAD 0x0001 -#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 -#define PROV_CIPHER_FLAG_CTS 0x0004 -#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 -#define PROV_CIPHER_FLAG_RAND_KEY 0x0010 +# define PROV_CIPHER_FLAG_AEAD 0x0001 +# define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 +# define PROV_CIPHER_FLAG_CTS 0x0004 +# define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 +# define PROV_CIPHER_FLAG_RAND_KEY 0x0010 /* Internal flags that are only used within the provider */ -#define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 -#define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 +# define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 +# define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 struct prov_cipher_ctx_st { /* place buffer at the beginning for memory alignment */ @@ -65,6 +69,7 @@ struct prov_cipher_ctx_st { unsigned int pad : 1; /* Whether padding should be used or not */ unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */ unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */ + unsigned int key_set : 1; /* Set when key is set on the context */ unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */ unsigned int variable_keylength : 1; unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */ @@ -126,7 +131,7 @@ void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, uint64_t flags, const PROV_CIPHER_HW *hw, void *provctx); -#define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\ +# define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\ blkbits, ivbits, typ) \ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ @@ -150,10 +155,10 @@ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; -#define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \ +# define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \ kbits, blkbits, ivbits, typ) \ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ @@ -177,11 +182,11 @@ const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; -#define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \ +# define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \ kbits, blkbits, ivbits, typ) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ @@ -203,14 +208,14 @@ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ return ctx; \ } \ -#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ +# define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) \ IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) \ IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) -#define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ +# define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) \ IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) \ @@ -228,11 +233,11 @@ PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc; PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8; PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128; PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128; -#define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb -#define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr -#define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1 +# define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb +# define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr +# define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1 -#define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ +# define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ unsigned char *out, \ const unsigned char *in, size_t len) \ @@ -253,7 +258,7 @@ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ return 1; \ } -#define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ +# define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ unsigned char *out, \ const unsigned char *in, size_t len) \ @@ -268,7 +273,7 @@ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ return 1; \ } -#define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ +# define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ unsigned char *out, \ const unsigned char *in, size_t len) \ @@ -286,7 +291,7 @@ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ return 1; \ } -#define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ +# define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ unsigned char *out, \ const unsigned char *in, size_t len) \ @@ -310,7 +315,7 @@ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ return 1; \ } -#define IMPLEMENT_CIPHER_HW_COPYCTX(name, CTX_TYPE) \ +# define IMPLEMENT_CIPHER_HW_COPYCTX(name, CTX_TYPE) \ static void name(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) \ { \ CTX_TYPE *sctx = (CTX_TYPE *)src; \ @@ -320,7 +325,7 @@ static void name(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) \ dst->ks = &dctx->ks.ks; \ } -#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \ +# define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \ static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \ @@ -329,7 +334,7 @@ static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), -#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ +# define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ OSSL_PARAM_END \ }; \ const OSSL_PARAM * name##_gettable_ctx_params(ossl_unused void *cctx, \ @@ -338,11 +343,11 @@ const OSSL_PARAM * name##_gettable_ctx_params(ossl_unused void *cctx, \ return name##_known_gettable_ctx_params; \ } -#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \ +# define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \ static const OSSL_PARAM name##_known_settable_ctx_params[] = { \ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), -#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \ +# define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \ OSSL_PARAM_END \ }; \ const OSSL_PARAM * name##_settable_ctx_params(ossl_unused void *cctx, \ @@ -360,3 +365,5 @@ size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen); + +#endif diff --git a/providers/implementations/include/prov/ciphercommon_aead.h b/providers/implementations/include/prov/ciphercommon_aead.h index 1d017175d3..8d709f10ea 100644 --- a/providers/implementations/include/prov/ciphercommon_aead.h +++ b/providers/implementations/include/prov/ciphercommon_aead.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,11 +7,15 @@ * https://www.openssl.org/source/license.html */ -#define UNINITIALISED_SIZET ((size_t)-1) +#ifndef OSSL_PROV_CIPHERCOMMON_AEAD_H +# define OSSL_PROV_CIPHERCOMMON_AEAD_H +# pragma once -#define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) +# define UNINITIALISED_SIZET ((size_t)-1) -#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ +# define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) + +# define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ @@ -23,9 +27,14 @@ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits); \ } \ +static void * alg##kbits##lc##_dupctx(void *src) \ +{ \ + return alg##_##lc##_dupctx(src); \ +} \ const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))alg##kbits##lc##_dupctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_##lc##_stream_update }, \ @@ -43,5 +52,7 @@ const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ (void (*)(void))ossl_cipher_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))ossl_cipher_aead_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } + +#endif diff --git a/providers/implementations/include/prov/ciphercommon_ccm.h b/providers/implementations/include/prov/ciphercommon_ccm.h index 4c184b395f..ce1a2aa0e7 100644 --- a/providers/implementations/include/prov/ciphercommon_ccm.h +++ b/providers/implementations/include/prov/ciphercommon_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,11 +7,15 @@ * https://www.openssl.org/source/license.html */ -#include "ciphercommon_aead.h" +#ifndef OSSL_PROV_CIPHERCOMMON_CCM_H +# define OSSL_PROV_CIPHERCOMMON_CCM_H +# pragma once + +# include "ciphercommon_aead.h" typedef struct prov_ccm_hw_st PROV_CCM_HW; -#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) +# if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) /*- * KMAC-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-08) @@ -24,7 +28,7 @@ typedef struct S390X_kmac_params_st { unsigned char k[32]; } S390X_KMAC_PARAMS; /* KMAC-AES parameter block - end */ -#endif +# endif /* Base structure that is shared by AES & ARIA for CCM MODE */ typedef struct prov_ccm_st { @@ -98,3 +102,5 @@ int ossl_ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in, int ossl_ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in, unsigned char *out, size_t len, unsigned char *expected_tag, size_t taglen); + +#endif diff --git a/providers/implementations/include/prov/ciphercommon_gcm.h b/providers/implementations/include/prov/ciphercommon_gcm.h index 7c4a548f9d..cd07c239bf 100644 --- a/providers/implementations/include/prov/ciphercommon_gcm.h +++ b/providers/implementations/include/prov/ciphercommon_gcm.h @@ -1,6 +1,6 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,16 +8,20 @@ * https://www.openssl.org/source/license.html */ -#include -#include "ciphercommon_aead.h" +#ifndef OSSL_PROV_CIPHERCOMMON_GCM_H +# define OSSL_PROV_CIPHERCOMMON_GCM_H +# pragma once + +# include +# include "ciphercommon_aead.h" typedef struct prov_gcm_hw_st PROV_GCM_HW; -#define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */ -#define GCM_IV_MAX_SIZE (1024 / 8) -#define GCM_TAG_MAX_SIZE 16 +# define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */ +# define GCM_IV_MAX_SIZE (1024 / 8) +# define GCM_TAG_MAX_SIZE 16 -#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) +# if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) /*- * KMA-GCM-AES parameter block - begin * (see z/Architecture Principles of Operation >= SA22-7832-11) @@ -42,7 +46,7 @@ typedef struct S390X_kma_params_st { unsigned char k[32]; /* key */ } S390X_KMA_PARAMS; -#endif +# endif typedef struct prov_gcm_ctx_st { unsigned int mode; /* The mode that we are using */ @@ -75,7 +79,6 @@ typedef struct prov_gcm_ctx_st { const PROV_GCM_HW *hw; /* hardware specific methods */ GCM128_CONTEXT gcm; ctr128_f ctr; - const void *ks; } PROV_GCM_CTX; PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key, @@ -121,9 +124,10 @@ int ossl_gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, int ossl_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, size_t len, unsigned char *out); -#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ - ctx->ks = ks; \ +# define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \ fn_set_enc_key(key, keylen * 8, ks); \ CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \ ctx->ctr = (ctr128_f)fn_ctr; \ ctx->key_set = 1; + +#endif diff --git a/providers/implementations/include/prov/ecx.h b/providers/implementations/include/prov/ecx.h new file mode 100644 index 0000000000..3427d154aa --- /dev/null +++ b/providers/implementations/include/prov/ecx.h @@ -0,0 +1,31 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "crypto/types.h" + +#ifndef OPENSSL_NO_EC + +/* RFC 9180 Labels used for Extract and Expand operations */ + +/* ASCII: "eae_prk", in hex for EBCDIC compatibility */ +#define OSSL_DHKEM_LABEL_EAE_PRK "\x65\x61\x65\x5F\x70\x72\x6B" +/* ASCII: "shared_secret", in hex for EBCDIC compatibility */ +#define OSSL_DHKEM_LABEL_SHARED_SECRET "\x73\x68\x61\x72\x65\x64\x5F\x73\x65\x63\x72\x65\x74" +/* ASCII: "dkp_prk", in hex for EBCDIC compatibility */ +#define OSSL_DHKEM_LABEL_DKP_PRK "\x64\x6B\x70\x5F\x70\x72\x6B" +/* ASCII: "candidate", in hex for EBCDIC compatibility */ +#define OSSL_DHKEM_LABEL_CANDIDATE "\x63\x61\x6E\x64\x69\x64\x61\x74\x65" +/* ASCII: "sk", in hex for EBCDIC compatibility */ +#define OSSL_DHKEM_LABEL_SK "\x73\x6B" + +int ossl_ecx_dhkem_derive_private(ECX_KEY *ecx, unsigned char *privout, + const unsigned char *ikm, size_t ikmlen); +int ossl_ec_dhkem_derive_private(EC_KEY *ec, BIGNUM *privout, + const unsigned char *ikm, size_t ikmlen); +#endif diff --git a/providers/implementations/include/prov/hmac_drbg.h b/providers/implementations/include/prov/hmac_drbg.h new file mode 100644 index 0000000000..28aa5bc1ad --- /dev/null +++ b/providers/implementations/include/prov/hmac_drbg.h @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_PROV_HMAC_DRBG_H +# define OSSL_PROV_HMAC_DRBG_H +# pragma once + +#include +#include "prov/provider_util.h" + +typedef struct drbg_hmac_st { + EVP_MAC_CTX *ctx; /* H(x) = HMAC_hash OR H(x) = KMAC */ + PROV_DIGEST digest; /* H(x) = hash(x) */ + size_t blocklen; + unsigned char K[EVP_MAX_MD_SIZE]; + unsigned char V[EVP_MAX_MD_SIZE]; +} PROV_DRBG_HMAC; + +int ossl_drbg_hmac_init(PROV_DRBG_HMAC *drbg, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len); +int ossl_drbg_hmac_generate(PROV_DRBG_HMAC *hmac, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len); + +#endif /* OSSL_PROV_HMAC_DRBG_H */ diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 498eab4ad4..80b544c429 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,7 @@ extern const OSSL_DISPATCH ossl_sha1_functions[]; extern const OSSL_DISPATCH ossl_sha224_functions[]; extern const OSSL_DISPATCH ossl_sha256_functions[]; +extern const OSSL_DISPATCH ossl_sha256_192_functions[]; extern const OSSL_DISPATCH ossl_sha384_functions[]; extern const OSSL_DISPATCH ossl_sha512_functions[]; extern const OSSL_DISPATCH ossl_sha512_224_functions[]; @@ -22,6 +23,10 @@ extern const OSSL_DISPATCH ossl_sha3_224_functions[]; extern const OSSL_DISPATCH ossl_sha3_256_functions[]; extern const OSSL_DISPATCH ossl_sha3_384_functions[]; extern const OSSL_DISPATCH ossl_sha3_512_functions[]; +extern const OSSL_DISPATCH ossl_keccak_224_functions[]; +extern const OSSL_DISPATCH ossl_keccak_256_functions[]; +extern const OSSL_DISPATCH ossl_keccak_384_functions[]; +extern const OSSL_DISPATCH ossl_keccak_512_functions[]; extern const OSSL_DISPATCH ossl_keccak_kmac_128_functions[]; extern const OSSL_DISPATCH ossl_keccak_kmac_256_functions[]; extern const OSSL_DISPATCH ossl_shake_128_functions[]; @@ -181,6 +186,7 @@ extern const OSSL_DISPATCH ossl_sm4128cbc_functions[]; extern const OSSL_DISPATCH ossl_sm4128ctr_functions[]; extern const OSSL_DISPATCH ossl_sm4128ofb128_functions[]; extern const OSSL_DISPATCH ossl_sm4128cfb128_functions[]; +extern const OSSL_DISPATCH ossl_sm4128xts_functions[]; #endif /* OPENSSL_NO_SM4 */ #ifndef OPENSSL_NO_RC5 extern const OSSL_DISPATCH ossl_rc5128ecb_functions[]; @@ -241,6 +247,9 @@ extern const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[]; extern const OSSL_DISPATCH ossl_aes128siv_functions[]; extern const OSSL_DISPATCH ossl_aes192siv_functions[]; extern const OSSL_DISPATCH ossl_aes256siv_functions[]; +extern const OSSL_DISPATCH ossl_aes128gcm_siv_functions[]; +extern const OSSL_DISPATCH ossl_aes192gcm_siv_functions[]; +extern const OSSL_DISPATCH ossl_aes256gcm_siv_functions[]; #endif /* OPENSSL_NO_SIV */ /* MACs */ @@ -257,6 +266,7 @@ extern const OSSL_DISPATCH ossl_poly1305_functions[]; /* KDFs / PRFs */ extern const OSSL_DISPATCH ossl_kdf_pbkdf1_functions[]; extern const OSSL_DISPATCH ossl_kdf_pbkdf2_functions[]; +extern const OSSL_DISPATCH ossl_kdf_pvk_functions[]; extern const OSSL_DISPATCH ossl_kdf_pkcs12_functions[]; #ifndef OPENSSL_NO_SCRYPT extern const OSSL_DISPATCH ossl_kdf_scrypt_functions[]; @@ -270,6 +280,12 @@ extern const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_kbkdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_krb5kdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_hmac_drbg_functions[]; +#ifndef OPENSSL_NO_ARGON2 +extern const OSSL_DISPATCH ossl_kdf_argon2i_functions[]; +extern const OSSL_DISPATCH ossl_kdf_argon2d_functions[]; +extern const OSSL_DISPATCH ossl_kdf_argon2id_functions[]; +#endif /* RNGs */ extern const OSSL_DISPATCH ossl_test_rng_functions[]; @@ -285,10 +301,12 @@ extern const OSSL_DISPATCH ossl_dhx_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_dsa_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_rsa_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[]; +#ifndef OPENSSL_NO_ECX extern const OSSL_DISPATCH ossl_x25519_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_x448_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_ed25519_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_ed448_keymgmt_functions[]; +#endif extern const OSSL_DISPATCH ossl_ec_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_kdf_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[]; @@ -326,6 +344,8 @@ extern const OSSL_DISPATCH ossl_sm2_asym_cipher_functions[]; /* Asym Key encapsulation */ extern const OSSL_DISPATCH ossl_rsa_asym_kem_functions[]; +extern const OSSL_DISPATCH ossl_ecx_asym_kem_functions[]; +extern const OSSL_DISPATCH ossl_ec_asym_kem_functions[]; /* Encoders */ extern const OSSL_DISPATCH ossl_rsa_to_PKCS1_der_encoder_functions[]; @@ -500,6 +520,7 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed448_decoder_functi #ifndef OPENSSL_NO_SM2 extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_sm2_decoder_functions[]; extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_sm2_decoder_functions[]; +extern const OSSL_DISPATCH ossl_type_specific_no_pub_der_to_sm2_decoder_functions[]; #endif extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_rsa_decoder_functions[]; @@ -517,3 +538,4 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_der_decoder_function extern const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[]; extern const OSSL_DISPATCH ossl_file_store_functions[]; +extern const OSSL_DISPATCH ossl_winstore_store_functions[]; diff --git a/providers/implementations/include/prov/kdfexchange.h b/providers/implementations/include/prov/kdfexchange.h index bfedd3afd3..cf08f785ee 100644 --- a/providers/implementations/include/prov/kdfexchange.h +++ b/providers/implementations/include/prov/kdfexchange.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,7 +14,6 @@ struct kdf_data_st { OSSL_LIB_CTX *libctx; CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; }; typedef struct kdf_data_st KDF_DATA; diff --git a/providers/implementations/include/prov/macsignature.h b/providers/implementations/include/prov/macsignature.h index 9bfaaf9b6e..e13ff362ce 100644 --- a/providers/implementations/include/prov/macsignature.h +++ b/providers/implementations/include/prov/macsignature.h @@ -1,5 +1,5 @@ /* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,7 +13,6 @@ #include "prov/provider_util.h" struct mac_key_st { - CRYPTO_RWLOCK *lock; OSSL_LIB_CTX *libctx; CRYPTO_REF_COUNT refcnt; unsigned char *priv_key; diff --git a/providers/implementations/include/prov/names.h b/providers/implementations/include/prov/names.h index 025d25ab04..f0ad435346 100644 --- a/providers/implementations/include/prov/names.h +++ b/providers/implementations/include/prov/names.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -97,6 +97,9 @@ #define PROV_NAMES_AES_128_SIV "AES-128-SIV" #define PROV_NAMES_AES_192_SIV "AES-192-SIV" #define PROV_NAMES_AES_256_SIV "AES-256-SIV" +#define PROV_NAMES_AES_128_GCM_SIV "AES-128-GCM-SIV" +#define PROV_NAMES_AES_192_GCM_SIV "AES-192-GCM-SIV" +#define PROV_NAMES_AES_256_GCM_SIV "AES-256-GCM-SIV" #define PROV_NAMES_ARIA_256_GCM "ARIA-256-GCM:1.2.410.200046.1.1.36" #define PROV_NAMES_ARIA_192_GCM "ARIA-192-GCM:1.2.410.200046.1.1.35" #define PROV_NAMES_ARIA_128_GCM "ARIA-128-GCM:1.2.410.200046.1.1.34" @@ -164,6 +167,7 @@ #define PROV_NAMES_SM4_CFB "SM4-CFB:SM4-CFB128:1.2.156.10197.1.104.4" #define PROV_NAMES_SM4_GCM "SM4-GCM:1.2.156.10197.1.104.8" #define PROV_NAMES_SM4_CCM "SM4-CCM:1.2.156.10197.1.104.9" +#define PROV_NAMES_SM4_XTS "SM4-XTS:1.2.156.10197.1.104.10" #define PROV_NAMES_ChaCha20 "ChaCha20" #define PROV_NAMES_ChaCha20_Poly1305 "ChaCha20-Poly1305" #define PROV_NAMES_CAST5_ECB "CAST5-ECB" @@ -210,6 +214,7 @@ #define PROV_NAMES_SHA1 "SHA1:SHA-1:SSL3-SHA1:1.3.14.3.2.26" #define PROV_NAMES_SHA2_224 "SHA2-224:SHA-224:SHA224:2.16.840.1.101.3.4.2.4" #define PROV_NAMES_SHA2_256 "SHA2-256:SHA-256:SHA256:2.16.840.1.101.3.4.2.1" +#define PROV_NAMES_SHA2_256_192 "SHA2-256/192:SHA-256/192:SHA256-192" #define PROV_NAMES_SHA2_384 "SHA2-384:SHA-384:SHA384:2.16.840.1.101.3.4.2.2" #define PROV_NAMES_SHA2_512 "SHA2-512:SHA-512:SHA512:2.16.840.1.101.3.4.2.3" #define PROV_NAMES_SHA2_512_224 "SHA2-512/224:SHA-512/224:SHA512-224:2.16.840.1.101.3.4.2.5" @@ -221,6 +226,11 @@ #define PROV_NAMES_SHA3_384 "SHA3-384:2.16.840.1.101.3.4.2.9" #define PROV_NAMES_SHA3_512 "SHA3-512:2.16.840.1.101.3.4.2.10" +#define PROV_NAMES_KECCAK_224 "KECCAK-224" +#define PROV_NAMES_KECCAK_256 "KECCAK-256" +#define PROV_NAMES_KECCAK_384 "KECCAK-384" +#define PROV_NAMES_KECCAK_512 "KECCAK-512" + #define PROV_NAMES_SHAKE_128 "SHAKE-128:SHAKE128:2.16.840.1.101.3.4.2.11" #define PROV_NAMES_SHAKE_256 "SHAKE-256:SHAKE256:2.16.840.1.101.3.4.2.12" @@ -258,6 +268,7 @@ #define PROV_NAMES_SSKDF "SSKDF" #define PROV_NAMES_PBKDF1 "PBKDF1" #define PROV_NAMES_PBKDF2 "PBKDF2:1.2.840.113549.1.5.12" +#define PROV_NAMES_PVKKDF "PVKKDF" #define PROV_NAMES_SSHKDF "SSHKDF" #define PROV_NAMES_X963KDF "X963KDF:X942KDF-CONCAT" #define PROV_NAMES_X942KDF_ASN1 "X942KDF-ASN1:X942KDF" @@ -268,6 +279,10 @@ #define PROV_NAMES_SCRYPT "SCRYPT:id-scrypt:1.3.6.1.4.1.11591.4.11" #define PROV_DESCS_SCRYPT_SIGN "OpenSSL SCRYPT via EVP_PKEY implementation" #define PROV_NAMES_KRB5KDF "KRB5KDF" +#define PROV_NAMES_HMAC_DRBG_KDF "HMAC-DRBG-KDF" +#define PROV_NAMES_ARGON2I "ARGON2I" +#define PROV_NAMES_ARGON2D "ARGON2D" +#define PROV_NAMES_ARGON2ID "ARGON2ID" /*- * MACs diff --git a/providers/implementations/include/prov/seeding.h b/providers/implementations/include/prov/seeding.h index 2a12039268..af6cb79fb2 100644 --- a/providers/implementations/include/prov/seeding.h +++ b/providers/implementations/include/prov/seeding.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/kdfs/argon2.c b/providers/implementations/kdfs/argon2.c new file mode 100644 index 0000000000..fe84ab54ca --- /dev/null +++ b/providers/implementations/kdfs/argon2.c @@ -0,0 +1,1560 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * RFC 9106 Argon2 (see https://www.rfc-editor.org/rfc/rfc9106.txt) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/thread.h" +#include "internal/numbers.h" +#include "internal/endian.h" +#include "crypto/evp.h" +#include "prov/implementations.h" +#include "prov/provider_ctx.h" +#include "prov/providercommon.h" +#include "prov/blake2.h" + +#if defined(OPENSSL_NO_DEFAULT_THREAD_POOL) && defined(OPENSSL_NO_THREAD_POOL) +# define ARGON2_NO_THREADS +#endif + +#if !defined(OPENSSL_THREADS) +# define ARGON2_NO_THREADS +#endif + +#ifndef OPENSSL_NO_ARGON2 + +# define ARGON2_MIN_LANES 1u +# define ARGON2_MAX_LANES 0xFFFFFFu +# define ARGON2_MIN_THREADS 1u +# define ARGON2_MAX_THREADS 0xFFFFFFu +# define ARGON2_SYNC_POINTS 4u +# define ARGON2_MIN_OUT_LENGTH 4u +# define ARGON2_MAX_OUT_LENGTH 0xFFFFFFFFu +# define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) +# define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +# define ARGON2_MAX_MEMORY 0xFFFFFFFFu +# define ARGON2_MIN_TIME 1u +# define ARGON2_MAX_TIME 0xFFFFFFFFu +# define ARGON2_MIN_PWD_LENGTH 0u +# define ARGON2_MAX_PWD_LENGTH 0xFFFFFFFFu +# define ARGON2_MIN_AD_LENGTH 0u +# define ARGON2_MAX_AD_LENGTH 0xFFFFFFFFu +# define ARGON2_MIN_SALT_LENGTH 8u +# define ARGON2_MAX_SALT_LENGTH 0xFFFFFFFFu +# define ARGON2_MIN_SECRET 0u +# define ARGON2_MAX_SECRET 0xFFFFFFFFu +# define ARGON2_BLOCK_SIZE 1024 +# define ARGON2_QWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 8) +# define ARGON2_OWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 16) +# define ARGON2_HWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 32) +# define ARGON2_512BIT_WORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 64) +# define ARGON2_ADDRESSES_IN_BLOCK 128 +# define ARGON2_PREHASH_DIGEST_LENGTH 64 +# define ARGON2_PREHASH_SEED_LENGTH \ + (ARGON2_PREHASH_DIGEST_LENGTH + (2 * sizeof(uint32_t))) + +# define ARGON2_DEFAULT_OUTLEN 64u +# define ARGON2_DEFAULT_T_COST 3u +# define ARGON2_DEFAULT_M_COST ARGON2_MIN_MEMORY +# define ARGON2_DEFAULT_LANES 1u +# define ARGON2_DEFAULT_THREADS 1u +# define ARGON2_DEFAULT_VERSION ARGON2_VERSION_NUMBER + +# undef G +# define G(a, b, c, d) \ + do { \ + a = a + b + 2 * mul_lower(a, b); \ + d = rotr64(d ^ a, 32); \ + c = c + d + 2 * mul_lower(c, d); \ + b = rotr64(b ^ c, 24); \ + a = a + b + 2 * mul_lower(a, b); \ + d = rotr64(d ^ a, 16); \ + c = c + d + 2 * mul_lower(c, d); \ + b = rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +# undef PERMUTATION_P +# define PERMUTATION_P(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + G(v0, v4, v8, v12); \ + G(v1, v5, v9, v13); \ + G(v2, v6, v10, v14); \ + G(v3, v7, v11, v15); \ + G(v0, v5, v10, v15); \ + G(v1, v6, v11, v12); \ + G(v2, v7, v8, v13); \ + G(v3, v4, v9, v14); \ + } while ((void)0, 0) + +# undef PERMUTATION_P_COLUMN +# define PERMUTATION_P_COLUMN(x, i) \ + do { \ + uint64_t *base = &x[16 * i]; \ + PERMUTATION_P( \ + *base, *(base + 1), *(base + 2), *(base + 3), \ + *(base + 4), *(base + 5), *(base + 6), *(base + 7), \ + *(base + 8), *(base + 9), *(base + 10), *(base + 11), \ + *(base + 12), *(base + 13), *(base + 14), *(base + 15) \ + ); \ + } while ((void)0, 0) + +# undef PERMUTATION_P_ROW +# define PERMUTATION_P_ROW(x, i) \ + do { \ + uint64_t *base = &x[2 * i]; \ + PERMUTATION_P( \ + *base, *(base + 1), *(base + 16), *(base + 17), \ + *(base + 32), *(base + 33), *(base + 48), *(base + 49), \ + *(base + 64), *(base + 65), *(base + 80), *(base + 81), \ + *(base + 96), *(base + 97), *(base + 112), *(base + 113) \ + ); \ + } while ((void)0, 0) + +typedef struct { + uint64_t v[ARGON2_QWORDS_IN_BLOCK]; +} BLOCK; + +typedef enum { + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 +} ARGON2_VERSION; + +typedef enum { + ARGON2_D = 0, + ARGON2_I = 1, + ARGON2_ID = 2 +} ARGON2_TYPE; + +typedef struct { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} ARGON2_POS; + +typedef struct { + void *provctx; + uint32_t outlen; + uint8_t *pwd; + uint32_t pwdlen; + uint8_t *salt; + uint32_t saltlen; + uint8_t *secret; + uint32_t secretlen; + uint8_t *ad; + uint32_t adlen; + uint32_t t_cost; + uint32_t m_cost; + uint32_t lanes; + uint32_t threads; + uint32_t version; + uint32_t early_clean; + ARGON2_TYPE type; + BLOCK *memory; + uint32_t passes; + uint32_t memory_blocks; + uint32_t segment_length; + uint32_t lane_length; + OSSL_LIB_CTX *libctx; + EVP_MD *md; + EVP_MAC *mac; + char *propq; +} KDF_ARGON2; + +typedef struct { + ARGON2_POS pos; + KDF_ARGON2 *ctx; +} ARGON2_THREAD_DATA; + +static OSSL_FUNC_kdf_newctx_fn kdf_argon2i_new; +static OSSL_FUNC_kdf_newctx_fn kdf_argon2d_new; +static OSSL_FUNC_kdf_newctx_fn kdf_argon2id_new; +static OSSL_FUNC_kdf_freectx_fn kdf_argon2_free; +static OSSL_FUNC_kdf_reset_fn kdf_argon2_reset; +static OSSL_FUNC_kdf_derive_fn kdf_argon2_derive; +static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_argon2_settable_ctx_params; +static OSSL_FUNC_kdf_set_ctx_params_fn kdf_argon2_set_ctx_params; + +static void kdf_argon2_init(KDF_ARGON2 *ctx, ARGON2_TYPE t); +static void *kdf_argon2d_new(void *provctx); +static void *kdf_argon2i_new(void *provctx); +static void *kdf_argon2id_new(void *provctx); +static void kdf_argon2_free(void *vctx); +static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen, + const OSSL_PARAM params[]); +static void kdf_argon2_reset(void *vctx); +static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads); +static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes); +static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost); +static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost); +static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen); +static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p); +static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p); +static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p); +static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p); +static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[]); +static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[]); +static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version); +static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx); +static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx); + +static ossl_inline uint64_t load64(const uint8_t *src); +static ossl_inline void store32(uint8_t *dst, uint32_t w); +static ossl_inline void store64(uint8_t *dst, uint64_t w); +static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c); +static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y); + +static void init_block_value(BLOCK *b, uint8_t in); +static void copy_block(BLOCK *dst, const BLOCK *src); +static void xor_block(BLOCK *dst, const BLOCK *src); +static void load_block(BLOCK *dst, const void *input); +static void store_block(void *output, const BLOCK *src); +static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx); +static void fill_block(const BLOCK *prev, const BLOCK *ref, BLOCK *next, + int with_xor); + +static void next_addresses(BLOCK *address_block, BLOCK *input_block, + const BLOCK *zero_block); +static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass, + uint8_t slice); +static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass, + uint8_t slice, uint32_t index, + uint32_t pseudo_rand, int same_lane); + +static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane, + uint8_t slice); + +# if !defined(ARGON2_NO_THREADS) +static uint32_t fill_segment_thr(void *thread_data); +static int fill_mem_blocks_mt(KDF_ARGON2 *ctx); +# endif + +static int fill_mem_blocks_st(KDF_ARGON2 *ctx); +static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx); + +static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx); +static int initialize(KDF_ARGON2 *ctx); +static void finalize(const KDF_ARGON2 *ctx, void *out); + +static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen, + const void *in, size_t inlen, const void *key, + size_t keylen); +static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out, + size_t outlen, const void *in, size_t inlen); + +static ossl_inline uint64_t load64(const uint8_t *src) +{ + return + (((uint64_t)src[0]) << 0) + | (((uint64_t)src[1]) << 8) + | (((uint64_t)src[2]) << 16) + | (((uint64_t)src[3]) << 24) + | (((uint64_t)src[4]) << 32) + | (((uint64_t)src[5]) << 40) + | (((uint64_t)src[6]) << 48) + | (((uint64_t)src[7]) << 56); +} + +static ossl_inline void store32(uint8_t *dst, uint32_t w) +{ + dst[0] = (uint8_t)(w >> 0); + dst[1] = (uint8_t)(w >> 8); + dst[2] = (uint8_t)(w >> 16); + dst[3] = (uint8_t)(w >> 24); +} + +static ossl_inline void store64(uint8_t *dst, uint64_t w) +{ + dst[0] = (uint8_t)(w >> 0); + dst[1] = (uint8_t)(w >> 8); + dst[2] = (uint8_t)(w >> 16); + dst[3] = (uint8_t)(w >> 24); + dst[4] = (uint8_t)(w >> 32); + dst[5] = (uint8_t)(w >> 40); + dst[6] = (uint8_t)(w >> 48); + dst[7] = (uint8_t)(w >> 56); +} + +static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c) +{ + return (w >> c) | (w << (64 - c)); +} + +static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y) +{ + const uint64_t m = 0xFFFFFFFFUL; + return (x & m) * (y & m); +} + +static void init_block_value(BLOCK *b, uint8_t in) +{ + memset(b->v, in, sizeof(b->v)); +} + +static void copy_block(BLOCK *dst, const BLOCK *src) +{ + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +static void xor_block(BLOCK *dst, const BLOCK *src) +{ + int i; + + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) + dst->v[i] ^= src->v[i]; +} + +static void load_block(BLOCK *dst, const void *input) +{ + unsigned i; + + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) + dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i])); +} + +static void store_block(void *output, const BLOCK *src) +{ + unsigned i; + + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) + store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); +} + +static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx) +{ + uint32_t l; + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + + /* + * Make the first and second block in each lane as G(H0||0||i) + * or G(H0||1||i). + */ + for (l = 0; l < ctx->lanes; ++l) { + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE, + blockhash, ARGON2_PREHASH_SEED_LENGTH); + load_block(&ctx->memory[l * ctx->lane_length + 0], + blockhash_bytes); + store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE, + blockhash, ARGON2_PREHASH_SEED_LENGTH); + load_block(&ctx->memory[l * ctx->lane_length + 1], + blockhash_bytes); + } + OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +static void fill_block(const BLOCK *prev, const BLOCK *ref, + BLOCK *next, int with_xor) +{ + BLOCK blockR, tmp; + unsigned i; + + copy_block(&blockR, ref); + xor_block(&blockR, prev); + copy_block(&tmp, &blockR); + + if (with_xor) + xor_block(&tmp, next); + + for (i = 0; i < 8; ++i) + PERMUTATION_P_COLUMN(blockR.v, i); + + for (i = 0; i < 8; ++i) + PERMUTATION_P_ROW(blockR.v, i); + + copy_block(next, &tmp); + xor_block(next, &blockR); +} + +static void next_addresses(BLOCK *address_block, BLOCK *input_block, + const BLOCK *zero_block) +{ + input_block->v[6]++; + fill_block(zero_block, input_block, address_block, 0); + fill_block(zero_block, address_block, address_block, 0); +} + +static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass, + uint8_t slice) +{ + switch (ctx->type) { + case ARGON2_I: + return 1; + case ARGON2_ID: + return (pass == 0) && (slice < ARGON2_SYNC_POINTS / 2); + case ARGON2_D: + default: + return 0; + } +} + +/* + * Pass 0 (pass = 0): + * This lane: all already finished segments plus already constructed blocks + * in this segment + * Other lanes: all already finished segments + * + * Pass 1+: + * This lane: (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes: (SYNC_POINTS - 1) last segments + */ +static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass, + uint8_t slice, uint32_t index, + uint32_t pseudo_rand, int same_lane) +{ + uint32_t ref_area_sz; + uint64_t rel_pos; + uint32_t start_pos, abs_pos; + + start_pos = 0; + switch (pass) { + case 0: + if (slice == 0) + ref_area_sz = index - 1; + else if (same_lane) + ref_area_sz = slice * ctx->segment_length + index - 1; + else + ref_area_sz = slice * ctx->segment_length + + ((index == 0) ? (-1) : 0); + break; + default: + if (same_lane) + ref_area_sz = ctx->lane_length - ctx->segment_length + index - 1; + else + ref_area_sz = ctx->lane_length - ctx->segment_length + + ((index == 0) ? (-1) : 0); + if (slice != ARGON2_SYNC_POINTS - 1) + start_pos = (slice + 1) * ctx->segment_length; + break; + } + + rel_pos = pseudo_rand; + rel_pos = rel_pos * rel_pos >> 32; + rel_pos = ref_area_sz - 1 - (ref_area_sz * rel_pos >> 32); + abs_pos = (start_pos + rel_pos) % ctx->lane_length; + + return abs_pos; +} + +static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane, + uint8_t slice) +{ + BLOCK *ref_block = NULL, *curr_block = NULL; + BLOCK address_block, input_block, zero_block; + uint64_t rnd, ref_index, ref_lane; + uint32_t prev_offset; + uint32_t start_idx; + uint32_t j; + uint32_t curr_offset; /* Offset of the current block */ + + memset(&input_block, 0, sizeof(BLOCK)); + + if (ctx == NULL) + return; + + if (data_indep_addressing(ctx, pass, slice)) { + init_block_value(&zero_block, 0); + init_block_value(&input_block, 0); + + input_block.v[0] = pass; + input_block.v[1] = lane; + input_block.v[2] = slice; + input_block.v[3] = ctx->memory_blocks; + input_block.v[4] = ctx->passes; + input_block.v[5] = ctx->type; + } + + start_idx = 0; + + /* We've generated the first two blocks. Generate the 1st block of addrs. */ + if ((pass == 0) && (slice == 0)) { + start_idx = 2; + if (data_indep_addressing(ctx, pass, slice)) + next_addresses(&address_block, &input_block, &zero_block); + } + + curr_offset = lane * ctx->lane_length + slice * ctx->segment_length + + start_idx; + + if ((curr_offset % ctx->lane_length) == 0) + prev_offset = curr_offset + ctx->lane_length - 1; + else + prev_offset = curr_offset - 1; + + for (j = start_idx; j < ctx->segment_length; ++j, ++curr_offset, ++prev_offset) { + if (curr_offset % ctx->lane_length == 1) + prev_offset = curr_offset - 1; + + /* Taking pseudo-random value from the previous block. */ + if (data_indep_addressing(ctx, pass, slice)) { + if (j % ARGON2_ADDRESSES_IN_BLOCK == 0) + next_addresses(&address_block, &input_block, &zero_block); + rnd = address_block.v[j % ARGON2_ADDRESSES_IN_BLOCK]; + } else { + rnd = ctx->memory[prev_offset].v[0]; + } + + /* Computing the lane of the reference block */ + ref_lane = ((rnd >> 32)) % ctx->lanes; + /* Can not reference other lanes yet */ + if ((pass == 0) && (slice == 0)) + ref_lane = lane; + + /* Computing the number of possible reference block within the lane. */ + ref_index = index_alpha(ctx, pass, slice, j, rnd & 0xFFFFFFFF, + ref_lane == lane); + + /* Creating a new block */ + ref_block = ctx->memory + ctx->lane_length * ref_lane + ref_index; + curr_block = ctx->memory + curr_offset; + if (ARGON2_VERSION_10 == ctx->version) { + /* Version 1.2.1 and earlier: overwrite, not XOR */ + fill_block(ctx->memory + prev_offset, ref_block, curr_block, 0); + continue; + } + + fill_block(ctx->memory + prev_offset, ref_block, curr_block, + pass == 0 ? 0 : 1); + } +} + +# if !defined(ARGON2_NO_THREADS) + +static uint32_t fill_segment_thr(void *thread_data) +{ + ARGON2_THREAD_DATA *my_data; + + my_data = (ARGON2_THREAD_DATA *) thread_data; + fill_segment(my_data->ctx, my_data->pos.pass, my_data->pos.lane, + my_data->pos.slice); + + return 0; +} + +static int fill_mem_blocks_mt(KDF_ARGON2 *ctx) +{ + uint32_t r, s, l, ll; + void **t; + ARGON2_THREAD_DATA *t_data; + + t = OPENSSL_zalloc(sizeof(void *)*ctx->lanes); + t_data = OPENSSL_zalloc(ctx->lanes * sizeof(ARGON2_THREAD_DATA)); + + if (t == NULL || t_data == NULL) + goto fail; + + for (r = 0; r < ctx->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + for (l = 0; l < ctx->lanes; ++l) { + ARGON2_POS p; + if (l >= ctx->threads) { + if (ossl_crypto_thread_join(t[l - ctx->threads], NULL) == 0) + goto fail; + if (ossl_crypto_thread_clean(t[l - ctx->threads]) == 0) + goto fail; + t[l] = NULL; + } + + p.pass = r; + p.lane = l; + p.slice = (uint8_t)s; + p.index = 0; + + t_data[l].ctx = ctx; + memcpy(&(t_data[l].pos), &p, sizeof(ARGON2_POS)); + t[l] = ossl_crypto_thread_start(ctx->libctx, &fill_segment_thr, + (void *) &t_data[l]); + if (t[l] == NULL) { + for (ll = 0; ll < l; ++ll) { + if (ossl_crypto_thread_join(t[ll], NULL) == 0) + goto fail; + if (ossl_crypto_thread_clean(t[ll]) == 0) + goto fail; + t[ll] = NULL; + } + goto fail; + } + } + for (l = ctx->lanes - ctx->threads; l < ctx->lanes; ++l) { + if (ossl_crypto_thread_join(t[l], NULL) == 0) + goto fail; + if (ossl_crypto_thread_clean(t[l]) == 0) + goto fail; + t[l] = NULL; + } + } + } + + OPENSSL_free(t_data); + OPENSSL_free(t); + + return 1; + +fail: + if (t_data != NULL) + OPENSSL_free(t_data); + if (t != NULL) + OPENSSL_free(t); + return 0; +} + +# endif /* !defined(ARGON2_NO_THREADS) */ + +static int fill_mem_blocks_st(KDF_ARGON2 *ctx) +{ + uint32_t r, s, l; + + for (r = 0; r < ctx->passes; ++r) + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) + for (l = 0; l < ctx->lanes; ++l) + fill_segment(ctx, r, l, s); + return 1; +} + +static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx) +{ +# if !defined(ARGON2_NO_THREADS) + return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : fill_mem_blocks_mt(ctx); +# else + return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : 0; +# endif +} + +static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx) +{ + EVP_MD_CTX *mdctx; + uint8_t value[sizeof(uint32_t)]; + unsigned int tmp; + uint32_t args[7]; + + if (ctx == NULL || blockhash == NULL) + return; + + args[0] = ctx->lanes; + args[1] = ctx->outlen; + args[2] = ctx->m_cost; + args[3] = ctx->t_cost; + args[4] = ctx->version; + args[5] = (uint32_t) ctx->type; + args[6] = ctx->pwdlen; + + mdctx = EVP_MD_CTX_create(); + if (mdctx == NULL || EVP_DigestInit_ex(mdctx, ctx->md, NULL) != 1) + goto fail; + + for (tmp = 0; tmp < sizeof(args) / sizeof(uint32_t); ++tmp) { + store32((uint8_t *) &value, args[tmp]); + if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1) + goto fail; + } + + if (ctx->pwd != NULL) { + if (EVP_DigestUpdate(mdctx, ctx->pwd, ctx->pwdlen) != 1) + goto fail; + if (ctx->early_clean) { + OPENSSL_cleanse(ctx->pwd, ctx->pwdlen); + ctx->pwdlen = 0; + } + } + + store32((uint8_t *) &value, ctx->saltlen); + + if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1) + goto fail; + + if (ctx->salt != NULL) + if (EVP_DigestUpdate(mdctx, ctx->salt, ctx->saltlen) != 1) + goto fail; + + store32((uint8_t *) &value, ctx->secretlen); + if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1) + goto fail; + + if (ctx->secret != NULL) { + if (EVP_DigestUpdate(mdctx, ctx->secret, ctx->secretlen) != 1) + goto fail; + if (ctx->early_clean) { + OPENSSL_cleanse(ctx->secret, ctx->secretlen); + ctx->secretlen = 0; + } + } + + store32((uint8_t *) &value, ctx->adlen); + if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1) + goto fail; + + if (ctx->ad != NULL) + if (EVP_DigestUpdate(mdctx, ctx->ad, ctx->adlen) != 1) + goto fail; + + tmp = ARGON2_PREHASH_DIGEST_LENGTH; + if (EVP_DigestFinal_ex(mdctx, blockhash, &tmp) != 1) + goto fail; + +fail: + EVP_MD_CTX_destroy(mdctx); +} + +static int initialize(KDF_ARGON2 *ctx) +{ + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + + if (ctx == NULL) + return 0; + + if (ctx->memory_blocks * sizeof(BLOCK) / sizeof(BLOCK) != ctx->memory_blocks) + return 0; + + if (ctx->type != ARGON2_D) + ctx->memory = OPENSSL_secure_zalloc(ctx->memory_blocks * + sizeof(BLOCK)); + else + ctx->memory = OPENSSL_zalloc(ctx->memory_blocks * + sizeof(BLOCK)); + + if (ctx->memory == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, + "cannot allocate required memory"); + return 0; + } + + initial_hash(blockhash, ctx); + OPENSSL_cleanse(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH); + fill_first_blocks(blockhash, ctx); + OPENSSL_cleanse(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return 1; +} + +static void finalize(const KDF_ARGON2 *ctx, void *out) +{ + BLOCK blockhash; + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + uint32_t last_block_in_lane; + uint32_t l; + + if (ctx == NULL) + return; + + copy_block(&blockhash, ctx->memory + ctx->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < ctx->lanes; ++l) { + last_block_in_lane = l * ctx->lane_length + (ctx->lane_length - 1); + xor_block(&blockhash, ctx->memory + last_block_in_lane); + } + + /* Hash the result */ + store_block(blockhash_bytes, &blockhash); + blake2b_long(ctx->md, ctx->mac, out, ctx->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + OPENSSL_cleanse(blockhash.v, ARGON2_BLOCK_SIZE); + OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE); + + if (ctx->type != ARGON2_D) + OPENSSL_secure_clear_free(ctx->memory, + ctx->memory_blocks * sizeof(BLOCK)); + else + OPENSSL_clear_free(ctx->memory, + ctx->memory_blocks * sizeof(BLOCK)); +} + +static int blake2b_mac(EVP_MAC *mac, void *out, size_t outlen, const void *in, + size_t inlen, const void *key, size_t keylen) +{ + int ret = 0; + size_t par_n = 0, out_written; + EVP_MAC_CTX *ctx = NULL; + OSSL_PARAM par[3]; + + if ((ctx = EVP_MAC_CTX_new(mac)) == NULL) + goto fail; + + par[par_n++] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *) key, keylen); + par[par_n++] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &outlen); + par[par_n++] = OSSL_PARAM_construct_end(); + + ret = EVP_MAC_CTX_set_params(ctx, par) == 1 + && EVP_MAC_init(ctx, NULL, 0, NULL) == 1 + && EVP_MAC_update(ctx, in, inlen) == 1 + && EVP_MAC_final(ctx, out, (size_t *) &out_written, outlen) == 1; + +fail: + EVP_MAC_CTX_free(ctx); + return ret; +} + +static int blake2b_md(EVP_MD *md, void *out, size_t outlen, const void *in, + size_t inlen) +{ + int ret = 0; + EVP_MD_CTX *ctx = NULL; + OSSL_PARAM par[2]; + + if ((ctx = EVP_MD_CTX_create()) == NULL) + return 0; + + par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen); + par[1] = OSSL_PARAM_construct_end(); + + ret = EVP_DigestInit_ex2(ctx, md, par) == 1 + && EVP_DigestUpdate(ctx, in, inlen) == 1 + && EVP_DigestFinal_ex(ctx, out, NULL) == 1; + + EVP_MD_CTX_free(ctx); + return ret; +} + +static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen, + const void *in, size_t inlen, const void *key, size_t keylen) +{ + if (out == NULL || outlen == 0) + return 0; + + if (key == NULL || keylen == 0) + return blake2b_md(md, out, outlen, in, inlen); + + return blake2b_mac(mac, out, outlen, in, inlen, key, keylen); +} + +static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out, + size_t outlen, const void *in, size_t inlen) +{ + int ret = 0; + EVP_MD_CTX *ctx = NULL; + uint32_t outlen_curr; + uint8_t outbuf[BLAKE2B_OUTBYTES]; + uint8_t inbuf[BLAKE2B_OUTBYTES]; + uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; + OSSL_PARAM par[2]; + size_t outlen_md; + + if (out == NULL || outlen == 0) + return 0; + + /* Ensure little-endian byte order */ + store32(outlen_bytes, (uint32_t)outlen); + + if ((ctx = EVP_MD_CTX_create()) == NULL) + return 0; + + outlen_md = (outlen <= BLAKE2B_OUTBYTES) ? outlen : BLAKE2B_OUTBYTES; + par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &outlen_md); + par[1] = OSSL_PARAM_construct_end(); + + ret = EVP_DigestInit_ex2(ctx, md, par) == 1 + && EVP_DigestUpdate(ctx, outlen_bytes, sizeof(outlen_bytes)) == 1 + && EVP_DigestUpdate(ctx, in, inlen) == 1 + && EVP_DigestFinal_ex(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out, + NULL) == 1; + + if (ret == 0) + goto fail; + + if (outlen > BLAKE2B_OUTBYTES) { + memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + outlen_curr = (uint32_t) outlen - BLAKE2B_OUTBYTES / 2; + + while (outlen_curr > BLAKE2B_OUTBYTES) { + memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES); + if (blake2b(md, mac, outbuf, BLAKE2B_OUTBYTES, inbuf, + BLAKE2B_OUTBYTES, NULL, 0) != 1) + goto fail; + memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + outlen_curr -= BLAKE2B_OUTBYTES / 2; + } + + memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES); + if (blake2b(md, mac, outbuf, outlen_curr, inbuf, BLAKE2B_OUTBYTES, + NULL, 0) != 1) + goto fail; + memcpy(out, outbuf, outlen_curr); + } + ret = 1; + +fail: + EVP_MD_CTX_free(ctx); + return ret; +} + +static void kdf_argon2_init(KDF_ARGON2 *c, ARGON2_TYPE type) +{ + OSSL_LIB_CTX *libctx; + + libctx = c->libctx; + memset(c, 0, sizeof(*c)); + + c->libctx = libctx; + c->outlen = ARGON2_DEFAULT_OUTLEN; + c->t_cost = ARGON2_DEFAULT_T_COST; + c->m_cost = ARGON2_DEFAULT_M_COST; + c->lanes = ARGON2_DEFAULT_LANES; + c->threads = ARGON2_DEFAULT_THREADS; + c->version = ARGON2_DEFAULT_VERSION; + c->type = type; +} + +static void *kdf_argon2d_new(void *provctx) +{ + KDF_ARGON2 *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ctx->libctx = PROV_LIBCTX_OF(provctx); + + kdf_argon2_init(ctx, ARGON2_D); + return ctx; +} + +static void *kdf_argon2i_new(void *provctx) +{ + KDF_ARGON2 *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ctx->libctx = PROV_LIBCTX_OF(provctx); + + kdf_argon2_init(ctx, ARGON2_I); + return ctx; +} + +static void *kdf_argon2id_new(void *provctx) +{ + KDF_ARGON2 *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ctx->libctx = PROV_LIBCTX_OF(provctx); + + kdf_argon2_init(ctx, ARGON2_ID); + return ctx; +} + +static void kdf_argon2_free(void *vctx) +{ + KDF_ARGON2 *ctx = (KDF_ARGON2 *)vctx; + + if (ctx == NULL) + return; + + if (ctx->pwd != NULL) + OPENSSL_clear_free(ctx->pwd, ctx->pwdlen); + + if (ctx->salt != NULL) + OPENSSL_clear_free(ctx->salt, ctx->saltlen); + + if (ctx->secret != NULL) + OPENSSL_clear_free(ctx->secret, ctx->secretlen); + + if (ctx->ad != NULL) + OPENSSL_clear_free(ctx->ad, ctx->adlen); + + EVP_MD_free(ctx->md); + EVP_MAC_free(ctx->mac); + + OPENSSL_free(ctx->propq); + + memset(ctx, 0, sizeof(*ctx)); + + OPENSSL_free(ctx); +} + +static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen, + const OSSL_PARAM params[]) +{ + KDF_ARGON2 *ctx; + uint32_t memory_blocks, segment_length; + + ctx = (KDF_ARGON2 *)vctx; + + if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx, params)) + return 0; + + if (ctx->mac == NULL) + ctx->mac = EVP_MAC_fetch(ctx->libctx, "blake2bmac", ctx->propq); + if (ctx->mac == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MAC, + "cannot fetch blake2bmac"); + return 0; + } + + if (ctx->md == NULL) + ctx->md = EVP_MD_fetch(ctx->libctx, "blake2b512", ctx->propq); + if (ctx->md == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST, + "cannot fetch blake2b512"); + return 0; + } + + if (ctx->salt == NULL || ctx->saltlen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT); + return 0; + } + + if (outlen != ctx->outlen) { + if (OSSL_PARAM_locate((OSSL_PARAM *)params, "size") != NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + if (!kdf_argon2_ctx_set_out_length(ctx, (uint32_t) outlen)) + return 0; + } + + switch (ctx->type) { + case ARGON2_D: + case ARGON2_I: + case ARGON2_ID: + break; + default: + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE, "invalid Argon2 type"); + return 0; + } + + if (ctx->threads > 1) { +# ifdef ARGON2_NO_THREADS + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE, + "requested %u threads, single-threaded mode supported only", + ctx->threads); + return 0; +# else + if (ctx->threads > ossl_get_avail_threads(ctx->libctx)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE, + "requested %u threads, available: 1", + ossl_get_avail_threads(ctx->libctx)); + return 0; + } +# endif + if (ctx->threads > ctx->lanes) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE, + "requested more threads (%u) than lanes (%u)", + ctx->threads, ctx->lanes); + return 0; + } + } + + if (ctx->m_cost < 8 * ctx->lanes) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, + "m_cost must be greater or equal than 8 times the number of lanes"); + return 0; + } + + memory_blocks = ctx->m_cost; + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * ctx->lanes) + memory_blocks = 2 * ARGON2_SYNC_POINTS * ctx->lanes; + + /* Ensure that all segments have equal length */ + segment_length = memory_blocks / (ctx->lanes * ARGON2_SYNC_POINTS); + memory_blocks = segment_length * (ctx->lanes * ARGON2_SYNC_POINTS); + + ctx->memory = NULL; + ctx->memory_blocks = memory_blocks; + ctx->segment_length = segment_length; + ctx->passes = ctx->t_cost; + ctx->lane_length = segment_length * ARGON2_SYNC_POINTS; + + if (initialize(ctx) != 1) + return 0; + + if (fill_memory_blocks(ctx) != 1) + return 0; + + finalize(ctx, out); + + return 1; +} + +static void kdf_argon2_reset(void *vctx) +{ + OSSL_LIB_CTX *libctx; + KDF_ARGON2 *ctx; + ARGON2_TYPE type; + + ctx = (KDF_ARGON2 *) vctx; + type = ctx->type; + libctx = ctx->libctx; + + EVP_MD_free(ctx->md); + EVP_MAC_free(ctx->mac); + + OPENSSL_free(ctx->propq); + + if (ctx->pwd != NULL) + OPENSSL_clear_free(ctx->pwd, ctx->pwdlen); + + if (ctx->salt != NULL) + OPENSSL_clear_free(ctx->salt, ctx->saltlen); + + if (ctx->secret != NULL) + OPENSSL_clear_free(ctx->secret, ctx->secretlen); + + if (ctx->ad != NULL) + OPENSSL_clear_free(ctx->ad, ctx->adlen); + + memset(ctx, 0, sizeof(*ctx)); + ctx->libctx = libctx; + kdf_argon2_init(ctx, type); +} + +static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads) +{ + if (threads < ARGON2_MIN_THREADS) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE, + "min threads: %u", ARGON2_MIN_THREADS); + return 0; + } + + if (threads > ARGON2_MAX_THREADS) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE, + "max threads: %u", ARGON2_MAX_THREADS); + return 0; + } + + ctx->threads = threads; + return 1; +} + +static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes) +{ + if (lanes > ARGON2_MAX_LANES) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER, + "max lanes: %u", ARGON2_MAX_LANES); + return 0; + } + + if (lanes < ARGON2_MIN_LANES) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER, + "min lanes: %u", ARGON2_MIN_LANES); + return 0; + } + + ctx->lanes = lanes; + return 1; +} + +static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost) +{ + /* ARGON2_MAX_MEMORY == max m_cost value, so skip check */ + + if (t_cost < ARGON2_MIN_TIME) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT, + "min: %u", ARGON2_MIN_TIME); + return 0; + } + + ctx->t_cost = t_cost; + return 1; +} + +static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost) +{ + /* ARGON2_MAX_MEMORY == max m_cost value, so skip check */ + + if (m_cost < ARGON2_MIN_MEMORY) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, "min: %u", + ARGON2_MIN_MEMORY); + return 0; + } + + ctx->m_cost = m_cost; + return 1; +} + +static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen) +{ + /* + * ARGON2_MAX_OUT_LENGTH == max outlen value, so upper bounds checks + * are always satisfied; to suppress compiler if statement tautology + * warnings, these checks are skipped. + */ + + if (outlen < ARGON2_MIN_OUT_LENGTH) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH, "min: %u", + ARGON2_MIN_OUT_LENGTH); + return 0; + } + + ctx->outlen = outlen; + return 1; +} + +static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p) +{ + size_t buflen; + + if (p->data == NULL) + return 0; + + if (ctx->secret != NULL) { + OPENSSL_clear_free(ctx->secret, ctx->secretlen); + ctx->secret = NULL; + ctx->secretlen = 0U; + } + + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->secret, 0, &buflen)) + return 0; + + if (buflen > ARGON2_MAX_SECRET) { + OPENSSL_free(ctx->secret); + ctx->secret = NULL; + ctx->secretlen = 0U; + return 0; + } + + ctx->secretlen = (uint32_t) buflen; + return 1; +} + +static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p) +{ + size_t buflen; + + if (p->data == NULL) + return 0; + + if (ctx->pwd != NULL) { + OPENSSL_clear_free(ctx->pwd, ctx->pwdlen); + ctx->pwd = NULL; + ctx->pwdlen = 0U; + } + + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->pwd, 0, &buflen)) + return 0; + + if (buflen > ARGON2_MAX_PWD_LENGTH) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u", + ARGON2_MAX_PWD_LENGTH); + goto fail; + } + + ctx->pwdlen = (uint32_t) buflen; + return 1; + +fail: + OPENSSL_free(ctx->pwd); + ctx->pwd = NULL; + ctx->pwdlen = 0U; + return 0; +} + +static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p) +{ + size_t buflen; + + if (p->data == NULL) + return 0; + + if (ctx->salt != NULL) { + OPENSSL_clear_free(ctx->salt, ctx->saltlen); + ctx->salt = NULL; + ctx->saltlen = 0U; + } + + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, &buflen)) + return 0; + + if (buflen < ARGON2_MIN_SALT_LENGTH) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "min: %u", + ARGON2_MIN_SALT_LENGTH); + goto fail; + } + + if (buflen > ARGON2_MAX_SALT_LENGTH) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u", + ARGON2_MAX_SALT_LENGTH); + goto fail; + } + + ctx->saltlen = (uint32_t) buflen; + return 1; + +fail: + OPENSSL_free(ctx->salt); + ctx->salt = NULL; + ctx->saltlen = 0U; + return 0; +} + +static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p) +{ + size_t buflen; + + if (p->data == NULL) + return 0; + + if (ctx->ad != NULL) { + OPENSSL_clear_free(ctx->ad, ctx->adlen); + ctx->ad = NULL; + ctx->adlen = 0U; + } + + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->ad, 0, &buflen)) + return 0; + + if (buflen > ARGON2_MAX_AD_LENGTH) { + OPENSSL_free(ctx->ad); + ctx->ad = NULL; + ctx->adlen = 0U; + return 0; + } + + ctx->adlen = (uint32_t) buflen; + return 1; +} + +static void kdf_argon2_ctx_set_flag_early_clean(KDF_ARGON2 *ctx, uint32_t f) +{ + ctx->early_clean = !!(f); +} + +static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version) +{ + switch (version) { + case ARGON2_VERSION_10: + case ARGON2_VERSION_13: + ctx->version = version; + return 1; + default: + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE, + "invalid Argon2 version"); + return 0; + } +} + +static int set_property_query(KDF_ARGON2 *ctx, const char *propq) +{ + OPENSSL_free(ctx->propq); + ctx->propq = NULL; + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) + return 0; + } + EVP_MD_free(ctx->md); + ctx->md = NULL; + EVP_MAC_free(ctx->mac); + ctx->mac = NULL; + return 1; +} + +static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + KDF_ARGON2 *ctx; + uint32_t u32_value; + + if (params == NULL) + return 1; + + ctx = (KDF_ARGON2 *) vctx; + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) + if (!kdf_argon2_ctx_set_pwd(ctx, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) + if (!kdf_argon2_ctx_set_salt(ctx, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) + if (!kdf_argon2_ctx_set_secret(ctx, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_AD)) != NULL) + if (!kdf_argon2_ctx_set_ad(ctx, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SIZE)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_out_length(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_t_cost(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_THREADS)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_threads(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_LANES)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_lanes(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_MEMCOST)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_m_cost(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_EARLY_CLEAN)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + kdf_argon2_ctx_set_flag_early_clean(ctx, u32_value); + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_VERSION)) != NULL) { + if (!OSSL_PARAM_get_uint32(p, &u32_value)) + return 0; + if (!kdf_argon2_ctx_set_version(ctx, u32_value)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING + || !set_property_query(ctx, p->data)) + return 0; + } + + return 1; +} + +static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_ARGON2_AD, NULL, 0), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_THREADS, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_LANES, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_EARLY_CLEAN, NULL), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_VERSION, NULL), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + + return known_settable_ctx_params; +} + +static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + (void) vctx; + if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) + return OSSL_PARAM_set_size_t(p, SIZE_MAX); + + return -2; +} + +static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_PARAM_END + }; + + return known_gettable_ctx_params; +} + +const OSSL_DISPATCH ossl_kdf_argon2i_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2i_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params }, + OSSL_DISPATCH_END +}; + +const OSSL_DISPATCH ossl_kdf_argon2d_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2d_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params }, + OSSL_DISPATCH_END +}; + +const OSSL_DISPATCH ossl_kdf_argon2id_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2id_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_argon2_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params }, + OSSL_DISPATCH_END +}; + +#endif diff --git a/providers/implementations/kdfs/build.info b/providers/implementations/kdfs/build.info index f4620adce2..3b7687b8f3 100644 --- a/providers/implementations/kdfs/build.info +++ b/providers/implementations/kdfs/build.info @@ -7,11 +7,14 @@ $KBKDF_GOAL=../../libdefault.a ../../libfips.a $KRB5KDF_GOAL=../../libdefault.a $PBKDF1_GOAL=../../liblegacy.a $PBKDF2_GOAL=../../libdefault.a ../../libfips.a +$PVKKDF_GOAL=../../liblegacy.a $PKCS12KDF_GOAL=../../libdefault.a $SSKDF_GOAL=../../libdefault.a ../../libfips.a $SCRYPT_GOAL=../../libdefault.a $SSHKDF_GOAL=../../libdefault.a ../../libfips.a $X942KDF_GOAL=../../libdefault.a ../../libfips.a +$HMAC_DRBG_KDF_GOAL=../../libdefault.a +$ARGON2_GOAL=../../libdefault.a SOURCE[$TLS1_PRF_GOAL]=tls1_prf.c @@ -28,6 +31,8 @@ SOURCE[$PBKDF2_GOAL]=pbkdf2.c # When the PBKDF2 moves to legacy, this can be removed. SOURCE[$PBKDF2_GOAL]=pbkdf2_fips.c +SOURCE[$PBKDF1_GOAL]=pvkkdf.c + SOURCE[$PKCS12KDF_GOAL]=pkcs12kdf.c SOURCE[$SSKDF_GOAL]=sskdf.c @@ -36,3 +41,6 @@ SOURCE[$SCRYPT_GOAL]=scrypt.c SOURCE[$SSHKDF_GOAL]=sshkdf.c SOURCE[$X942KDF_GOAL]=x942kdf.c DEPEND[x942kdf.o]=../../common/include/prov/der_wrap.h + +SOURCE[$HMAC_DRBG_KDF_GOAL]=hmacdrbg_kdf.c +SOURCE[$ARGON2_GOAL]=argon2.c diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c index daa619b8af..a83e298227 100644 --- a/providers/implementations/kdfs/hkdf.c +++ b/providers/implementations/kdfs/hkdf.c @@ -30,6 +30,7 @@ #include "prov/implementations.h" #include "prov/provider_util.h" #include "internal/e_os.h" +#include "internal/params.h" #define HKDF_MAXBUF 2048 #define HKDF_MAXINFO (32*1024) @@ -95,9 +96,7 @@ static void *kdf_hkdf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - else + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) ctx->provctx = provctx; return ctx; } @@ -276,44 +275,8 @@ static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[]) return 1; } -/* - * Use WPACKET to concat one or more OSSL_KDF_PARAM_INFO fields into a fixed - * out buffer of size *outlen. - * If out is NULL then outlen is used to return the required buffer size. - */ -static int setinfo_fromparams(const OSSL_PARAM *p, unsigned char *out, size_t *outlen) -{ - int ret = 0; - WPACKET pkt; - - if (out == NULL) { - if (!WPACKET_init_null(&pkt, 0)) - return 0; - } else { - if (!WPACKET_init_static_len(&pkt, out, *outlen, 0)) - return 0; - } - - for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_INFO)) { - if (p->data_type != OSSL_PARAM_OCTET_STRING) - goto err; - if (p->data != NULL - && p->data_size != 0 - && !WPACKET_memcpy(&pkt, p->data, p->data_size)) - goto err; - } - if (!WPACKET_get_total_written(&pkt, outlen) - || !WPACKET_finish(&pkt)) - goto err; - ret = 1; -err: - WPACKET_cleanup(&pkt); - return ret; -} - static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { - const OSSL_PARAM *p; KDF_HKDF *ctx = vctx; if (params == NULL) @@ -322,29 +285,11 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (!hkdf_common_set_ctx_params(ctx, params)) return 0; - /* The info fields concatenate, so process them all */ - if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) { - size_t sz = 0; - - /* calculate the total size */ - if (!setinfo_fromparams(p, NULL, &sz)) - return 0; - if (sz > HKDF_MAXINFO) - return 0; + if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO, + &ctx->info, &ctx->info_len, + HKDF_MAXINFO) == 0) + return 0; - OPENSSL_clear_free(ctx->info, ctx->info_len); - ctx->info = NULL; - if (sz == 0) - return 1; - /* Alloc the buffer */ - ctx->info = OPENSSL_malloc(sz); - if (ctx->info == NULL) - return 0; - ctx->info_len = sz; - /* Concat one or more OSSL_KDF_PARAM_INFO fields */ - if (!setinfo_fromparams(p, ctx->info, &sz)) - return 0; - } return 1; } @@ -396,7 +341,7 @@ const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_hkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; /* @@ -812,5 +757,5 @@ const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_hkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/kdfs/hmacdrbg_kdf.c b/providers/implementations/kdfs/hmacdrbg_kdf.c new file mode 100644 index 0000000000..30f1dfbd24 --- /dev/null +++ b/providers/implementations/kdfs/hmacdrbg_kdf.c @@ -0,0 +1,259 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "prov/providercommon.h" +#include "prov/implementations.h" +#include "prov/hmac_drbg.h" +#include "prov/provider_ctx.h" + +static OSSL_FUNC_kdf_newctx_fn hmac_drbg_kdf_new; +static OSSL_FUNC_kdf_dupctx_fn hmac_drbg_kdf_dup; +static OSSL_FUNC_kdf_freectx_fn hmac_drbg_kdf_free; +static OSSL_FUNC_kdf_reset_fn hmac_drbg_kdf_reset; +static OSSL_FUNC_kdf_derive_fn hmac_drbg_kdf_derive; +static OSSL_FUNC_kdf_settable_ctx_params_fn hmac_drbg_kdf_settable_ctx_params; +static OSSL_FUNC_kdf_set_ctx_params_fn hmac_drbg_kdf_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn hmac_drbg_kdf_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn hmac_drbg_kdf_get_ctx_params; + +typedef struct { + PROV_DRBG_HMAC base; + void *provctx; + unsigned char *entropy, *nonce; + size_t entropylen, noncelen; + int init; +} KDF_HMAC_DRBG; + +static void *hmac_drbg_kdf_new(void *provctx) +{ + KDF_HMAC_DRBG *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + ctx->provctx = provctx; + return ctx; +} + +static void hmac_drbg_kdf_reset(void *vctx) +{ + KDF_HMAC_DRBG *ctx = (KDF_HMAC_DRBG *)vctx; + PROV_DRBG_HMAC *drbg = &ctx->base; + void *provctx = ctx->provctx; + + EVP_MAC_CTX_free(drbg->ctx); + ossl_prov_digest_reset(&drbg->digest); + OPENSSL_clear_free(ctx->entropy, ctx->entropylen); + OPENSSL_clear_free(ctx->nonce, ctx->noncelen); + OPENSSL_cleanse(ctx, sizeof(*ctx)); + ctx->provctx = provctx; +} + +static void hmac_drbg_kdf_free(void *vctx) +{ + KDF_HMAC_DRBG *ctx = (KDF_HMAC_DRBG *)vctx; + + if (ctx != NULL) { + hmac_drbg_kdf_reset(ctx); + OPENSSL_free(ctx); + } +} + +static int ossl_drbg_hmac_dup(PROV_DRBG_HMAC *dst, const PROV_DRBG_HMAC *src) { + if (src->ctx != NULL) { + dst->ctx = EVP_MAC_CTX_dup(src->ctx); + if (dst->ctx == NULL) + return 0; + } + if (!ossl_prov_digest_copy(&dst->digest, &src->digest)) + return 0; + memcpy(dst->K, src->K, sizeof(dst->K)); + memcpy(dst->V, src->V, sizeof(dst->V)); + dst->blocklen = src->blocklen; + return 1; +} + +static void *hmac_drbg_kdf_dup(void *vctx) +{ + const KDF_HMAC_DRBG *src = (const KDF_HMAC_DRBG *)vctx; + KDF_HMAC_DRBG *dst; + + dst = hmac_drbg_kdf_new(src->provctx); + if (dst != NULL) { + if (!ossl_drbg_hmac_dup(&dst->base, &src->base) + || !ossl_prov_memdup(src->entropy, src->entropylen, + &dst->entropy , &dst->entropylen) + || !ossl_prov_memdup(src->nonce, src->noncelen, + &dst->nonce, &dst->noncelen)) + goto err; + dst->init = src->init; + } + return dst; + + err: + hmac_drbg_kdf_free(dst); + return NULL; +} + +static int hmac_drbg_kdf_derive(void *vctx, unsigned char *out, size_t outlen, + const OSSL_PARAM params[]) +{ + KDF_HMAC_DRBG *ctx = (KDF_HMAC_DRBG *)vctx; + PROV_DRBG_HMAC *drbg = &ctx->base; + + if (!ossl_prov_is_running() + || !hmac_drbg_kdf_set_ctx_params(vctx, params)) + return 0; + if (!ctx->init) { + if (ctx->entropy == NULL + || ctx->entropylen == 0 + || ctx->nonce == NULL + || ctx->noncelen == 0 + || !ossl_drbg_hmac_init(drbg, ctx->entropy, ctx->entropylen, + ctx->nonce, ctx->noncelen, NULL, 0)) + return 0; + ctx->init = 1; + } + + return ossl_drbg_hmac_generate(drbg, out, outlen, NULL, 0); +} + +static int hmac_drbg_kdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + KDF_HMAC_DRBG *hmac = (KDF_HMAC_DRBG *)vctx; + PROV_DRBG_HMAC *drbg = &hmac->base; + const char *name; + const EVP_MD *md; + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_MAC); + if (p != NULL) { + if (drbg->ctx == NULL) + return 0; + name = EVP_MAC_get0_name(EVP_MAC_CTX_get0_mac(drbg->ctx)); + if (!OSSL_PARAM_set_utf8_string(p, name)) + return 0; + } + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_DIGEST); + if (p != NULL) { + md = ossl_prov_digest_md(&drbg->digest); + if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md))) + return 0; + } + return 1; +} + +static const OSSL_PARAM *hmac_drbg_kdf_gettable_ctx_params( + ossl_unused void *vctx, ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +} + +static int hmac_drbg_kdf_set_ctx_params(void *vctx, + const OSSL_PARAM params[]) +{ + KDF_HMAC_DRBG *hmac = (KDF_HMAC_DRBG *)vctx; + PROV_DRBG_HMAC *drbg = &hmac->base; + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(hmac->provctx); + const EVP_MD *md; + const OSSL_PARAM *p; + void *ptr = NULL; + size_t size = 0; + + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_HMACDRBG_ENTROPY); + if (p != NULL) { + if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size)) + return 0; + OPENSSL_free(hmac->entropy); + hmac->entropy = ptr; + hmac->entropylen = size; + hmac->init = 0; + ptr = NULL; + } + + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_HMACDRBG_NONCE); + if (p != NULL) { + if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size)) + return 0; + OPENSSL_free(hmac->nonce); + hmac->nonce = ptr; + hmac->noncelen = size; + hmac->init = 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST); + if (p != NULL) { + if (!ossl_prov_digest_load_from_params(&drbg->digest, params, libctx)) + return 0; + + /* Confirm digest is allowed. Allow all digests that are not XOF */ + md = ossl_prov_digest_md(&drbg->digest); + if (md != NULL) { + if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); + return 0; + } + drbg->blocklen = EVP_MD_get_size(md); + } + return ossl_prov_macctx_load_from_params(&drbg->ctx, params, + "HMAC", NULL, NULL, libctx); + } + return 1; +} + +static const OSSL_PARAM *hmac_drbg_kdf_settable_ctx_params( + ossl_unused void *vctx, ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_HMACDRBG_ENTROPY, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_HMACDRBG_NONCE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +const OSSL_DISPATCH ossl_kdf_hmac_drbg_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))hmac_drbg_kdf_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))hmac_drbg_kdf_free }, + { OSSL_FUNC_KDF_DUPCTX, (void(*)(void))hmac_drbg_kdf_dup }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))hmac_drbg_kdf_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))hmac_drbg_kdf_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))hmac_drbg_kdf_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, + (void(*)(void))hmac_drbg_kdf_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))hmac_drbg_kdf_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, + (void(*)(void))hmac_drbg_kdf_get_ctx_params }, + OSSL_DISPATCH_END +}; diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c index aa3df15bc7..e6855d5732 100644 --- a/providers/implementations/kdfs/kbkdf.c +++ b/providers/implementations/kdfs/kbkdf.c @@ -45,6 +45,7 @@ #include "prov/providercommon.h" #include "internal/e_os.h" +#include "internal/params.h" #define ossl_min(a, b) ((a) < (b)) ? (a) : (b) @@ -117,10 +118,8 @@ static void *kbkdf_new(void *provctx) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->provctx = provctx; init(ctx); @@ -343,17 +342,6 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen, return ret; } -static int kbkdf_set_buffer(unsigned char **out, size_t *out_len, - const OSSL_PARAM *p) -{ - if (p->data == NULL || p->data_size == 0) - return 1; - - OPENSSL_clear_free(*out, *out_len); - *out = NULL; - return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len); -} - static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { KBKDF *ctx = (KBKDF *)vctx; @@ -393,21 +381,22 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } - p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY); - if (p != NULL && !kbkdf_set_buffer(&ctx->ki, &ctx->ki_len, p)) - return 0; + if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_KEY, + &ctx->ki, &ctx->ki_len) == 0) + return 0; - p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT); - if (p != NULL && !kbkdf_set_buffer(&ctx->label, &ctx->label_len, p)) - return 0; + if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SALT, + &ctx->label, &ctx->label_len) == 0) + return 0; - p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO); - if (p != NULL && !kbkdf_set_buffer(&ctx->context, &ctx->context_len, p)) + if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO, + &ctx->context, &ctx->context_len, + 0) == 0) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED); - if (p != NULL && !kbkdf_set_buffer(&ctx->iv, &ctx->iv_len, p)) - return 0; + if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SEED, + &ctx->iv, &ctx->iv_len) == 0) + return 0; p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KBKDF_USE_L); if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->use_l)) @@ -490,5 +479,5 @@ const OSSL_DISPATCH ossl_kdf_kbkdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kbkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kbkdf_get_ctx_params }, - { 0, NULL }, + OSSL_DISPATCH_END, }; diff --git a/providers/implementations/kdfs/krb5kdf.c b/providers/implementations/kdfs/krb5kdf.c index 0ad59734f8..b6cf0e3a2b 100644 --- a/providers/implementations/kdfs/krb5kdf.c +++ b/providers/implementations/kdfs/krb5kdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,10 +64,8 @@ static void *krb5kdf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) return NULL; - } ctx->provctx = provctx; return ctx; } @@ -232,7 +230,7 @@ const OSSL_DISPATCH ossl_kdf_krb5kdf_functions[] = { (void(*)(void))krb5kdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))krb5kdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; #ifndef OPENSSL_NO_DES diff --git a/providers/implementations/kdfs/pbkdf1.c b/providers/implementations/kdfs/pbkdf1.c index ff51074c48..6f95df071b 100644 --- a/providers/implementations/kdfs/pbkdf1.c +++ b/providers/implementations/kdfs/pbkdf1.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,7 +60,7 @@ static int kdf_pbkdf1_do_derive(const unsigned char *pass, size_t passlen, ctx = EVP_MD_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); goto err; } @@ -96,10 +96,8 @@ static void *kdf_pbkdf1_new(void *provctx) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->provctx = provctx; return ctx; } @@ -161,10 +159,8 @@ static int kdf_pbkdf1_set_membuf(unsigned char **buffer, size_t *buflen, *buflen = 0; if (p->data_size == 0) { - if ((*buffer = OPENSSL_malloc(1)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((*buffer = OPENSSL_malloc(1)) == NULL) return 0; - } } else if (p->data != NULL) { if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) return 0; @@ -210,7 +206,7 @@ static int kdf_pbkdf1_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) - if (!kdf_pbkdf1_set_membuf(&ctx->salt, &ctx->salt_len,p)) + if (!kdf_pbkdf1_set_membuf(&ctx->salt, &ctx->salt_len, p)) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) @@ -264,5 +260,5 @@ const OSSL_DISPATCH ossl_kdf_pbkdf1_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_pbkdf1_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pbkdf1_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c index 5c3e7b95ce..f2d190c308 100644 --- a/providers/implementations/kdfs/pbkdf2.c +++ b/providers/implementations/kdfs/pbkdf2.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -72,10 +72,8 @@ static void *kdf_pbkdf2_new_no_init(void *provctx) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->provctx = provctx; return ctx; } @@ -163,10 +161,8 @@ static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen, *buflen = 0; if (p->data_size == 0) { - if ((*buffer = OPENSSL_malloc(1)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((*buffer = OPENSSL_malloc(1)) == NULL) return 0; - } } else if (p->data != NULL) { if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) return 0; @@ -229,7 +225,7 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return 0; } - if (!pbkdf2_set_membuf(&ctx->salt, &ctx->salt_len,p)) + if (!pbkdf2_set_membuf(&ctx->salt, &ctx->salt_len, p)) return 0; } @@ -292,7 +288,7 @@ const OSSL_DISPATCH ossl_kdf_pbkdf2_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pbkdf2_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; /* diff --git a/providers/implementations/kdfs/pkcs12kdf.c b/providers/implementations/kdfs/pkcs12kdf.c index 5e0e0614da..0679c05f93 100644 --- a/providers/implementations/kdfs/pkcs12kdf.c +++ b/providers/implementations/kdfs/pkcs12kdf.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,7 +60,7 @@ static int pkcs12kdf_derive(const unsigned char *pass, size_t passlen, ctx = EVP_MD_CTX_new(); if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); goto end; } vi = EVP_MD_get_block_size(md_type); @@ -81,10 +81,8 @@ static int pkcs12kdf_derive(const unsigned char *pass, size_t passlen, Plen = 0; Ilen = Slen + Plen; I = OPENSSL_malloc(Ilen); - if (D == NULL || Ai == NULL || B == NULL || I == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (D == NULL || Ai == NULL || B == NULL || I == NULL) goto end; - } for (i = 0; i < v; i++) D[i] = id; p = I; @@ -144,10 +142,8 @@ static void *kdf_pkcs12_new(void *provctx) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->provctx = provctx; return ctx; } @@ -210,10 +206,8 @@ static int pkcs12kdf_set_membuf(unsigned char **buffer, size_t *buflen, *buflen = 0; if (p->data_size == 0) { - if ((*buffer = OPENSSL_malloc(1)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((*buffer = OPENSSL_malloc(1)) == NULL) return 0; - } } else if (p->data != NULL) { if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) return 0; @@ -262,7 +256,7 @@ static int kdf_pkcs12_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) - if (!pkcs12kdf_set_membuf(&ctx->salt, &ctx->salt_len,p)) + if (!pkcs12kdf_set_membuf(&ctx->salt, &ctx->salt_len, p)) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PKCS12_ID)) != NULL) @@ -321,5 +315,5 @@ const OSSL_DISPATCH ossl_kdf_pkcs12_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_pkcs12_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pkcs12_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/kdfs/pvkkdf.c b/providers/implementations/kdfs/pvkkdf.c new file mode 100644 index 0000000000..85a250ff7c --- /dev/null +++ b/providers/implementations/kdfs/pvkkdf.c @@ -0,0 +1,248 @@ +/* + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/numbers.h" /* SIZE_MAX */ +#include "prov/provider_ctx.h" +#include "prov/providercommon.h" +#include "prov/implementations.h" +#include "prov/provider_util.h" + +static OSSL_FUNC_kdf_newctx_fn kdf_pvk_new; +static OSSL_FUNC_kdf_dupctx_fn kdf_pvk_dup; +static OSSL_FUNC_kdf_freectx_fn kdf_pvk_free; +static OSSL_FUNC_kdf_reset_fn kdf_pvk_reset; +static OSSL_FUNC_kdf_derive_fn kdf_pvk_derive; +static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_pvk_settable_ctx_params; +static OSSL_FUNC_kdf_set_ctx_params_fn kdf_pvk_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_pvk_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kdf_pvk_get_ctx_params; + +typedef struct { + void *provctx; + unsigned char *pass; + size_t pass_len; + unsigned char *salt; + size_t salt_len; + PROV_DIGEST digest; +} KDF_PVK; + +static void kdf_pvk_init(KDF_PVK *ctx); + +static void *kdf_pvk_new(void *provctx) +{ + KDF_PVK *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + ctx->provctx = provctx; + kdf_pvk_init(ctx); + return ctx; +} + +static void kdf_pvk_cleanup(KDF_PVK *ctx) +{ + ossl_prov_digest_reset(&ctx->digest); + OPENSSL_free(ctx->salt); + OPENSSL_clear_free(ctx->pass, ctx->pass_len); + OPENSSL_cleanse(ctx, sizeof(*ctx)); +} + +static void kdf_pvk_free(void *vctx) +{ + KDF_PVK *ctx = (KDF_PVK *)vctx; + + if (ctx != NULL) { + kdf_pvk_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +static void *kdf_pvk_dup(void *vctx) +{ + const KDF_PVK *src = (const KDF_PVK *)vctx; + KDF_PVK *dest; + + dest = kdf_pvk_new(src->provctx); + if (dest != NULL) + if (!ossl_prov_memdup(src->salt, src->salt_len, + &dest->salt, &dest->salt_len) + || !ossl_prov_memdup(src->pass, src->pass_len, + &dest->pass , &dest->pass_len) + || !ossl_prov_digest_copy(&dest->digest, &src->digest)) + goto err; + return dest; + + err: + kdf_pvk_free(dest); + return NULL; +} + +static void kdf_pvk_reset(void *vctx) +{ + KDF_PVK *ctx = (KDF_PVK *)vctx; + void *provctx = ctx->provctx; + + kdf_pvk_cleanup(ctx); + ctx->provctx = provctx; + kdf_pvk_init(ctx); +} + +static void kdf_pvk_init(KDF_PVK *ctx) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + SN_sha1, 0); + if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) + /* This is an error, but there is no way to indicate such directly */ + ossl_prov_digest_reset(&ctx->digest); +} + +static int pvk_set_membuf(unsigned char **buffer, size_t *buflen, + const OSSL_PARAM *p) +{ + OPENSSL_clear_free(*buffer, *buflen); + *buffer = NULL; + *buflen = 0; + + if (p->data_size == 0) { + if ((*buffer = OPENSSL_malloc(1)) == NULL) + return 0; + } else if (p->data != NULL) { + if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) + return 0; + } + return 1; +} + +static int kdf_pvk_derive(void *vctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) +{ + KDF_PVK *ctx = (KDF_PVK *)vctx; + const EVP_MD *md; + EVP_MD_CTX *mctx; + int res; + + if (!ossl_prov_is_running() || !kdf_pvk_set_ctx_params(ctx, params)) + return 0; + + if (ctx->pass == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS); + return 0; + } + + if (ctx->salt == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT); + return 0; + } + + md = ossl_prov_digest_md(&ctx->digest); + if (md == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return 0; + } + res = EVP_MD_get_size(md); + if (res <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); + return 0; + } + if ((size_t)res > keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE); + return 0; + } + + mctx = EVP_MD_CTX_new(); + res = mctx != NULL + && EVP_DigestInit_ex(mctx, md, NULL) + && EVP_DigestUpdate(mctx, ctx->salt, ctx->salt_len) + && EVP_DigestUpdate(mctx, ctx->pass, ctx->pass_len) + && EVP_DigestFinal_ex(mctx, key, NULL); + EVP_MD_CTX_free(mctx); + return res; +} + +static int kdf_pvk_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + KDF_PVK *ctx = vctx; + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); + + if (params == NULL) + return 1; + + if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) + if (!pvk_set_membuf(&ctx->pass, &ctx->pass_len, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) { + if (!pvk_set_membuf(&ctx->salt, &ctx->salt_len, p)) + return 0; + } + + return 1; +} + +static const OSSL_PARAM *kdf_pvk_settable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +static int kdf_pvk_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) + return OSSL_PARAM_set_size_t(p, SIZE_MAX); + return -2; +} + +static const OSSL_PARAM *kdf_pvk_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *p_ctx) +{ + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +} + +const OSSL_DISPATCH ossl_kdf_pvk_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_pvk_new }, + { OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_pvk_dup }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_pvk_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_pvk_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_pvk_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_pvk_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_pvk_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_pvk_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pvk_get_ctx_params }, + OSSL_DISPATCH_END +}; diff --git a/providers/implementations/kdfs/scrypt.c b/providers/implementations/kdfs/scrypt.c index e914eef992..ee2d4a7d32 100644 --- a/providers/implementations/kdfs/scrypt.c +++ b/providers/implementations/kdfs/scrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -63,10 +63,8 @@ static void *kdf_scrypt_new_inner(OSSL_LIB_CTX *libctx) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) return NULL; - } ctx->libctx = libctx; kdf_scrypt_init(ctx); return ctx; @@ -150,10 +148,8 @@ static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen, *buflen = 0; if (p->data_size == 0) { - if ((*buffer = OPENSSL_malloc(1)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((*buffer = OPENSSL_malloc(1)) == NULL) return 0; - } } else if (p->data != NULL) { if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) return 0; @@ -179,10 +175,8 @@ static int set_property_query(KDF_SCRYPT *ctx, const char *propq) ctx->propq = NULL; if (propq != NULL) { ctx->propq = OPENSSL_strdup(propq); - if (ctx->propq == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx->propq == NULL) return 0; - } } return 1; } @@ -323,7 +317,7 @@ const OSSL_DISPATCH ossl_kdf_scrypt_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_scrypt_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_scrypt_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) @@ -527,10 +521,8 @@ static int scrypt_alg(const char *pass, size_t passlen, return 1; B = OPENSSL_malloc((size_t)(Blen + Vlen)); - if (B == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (B == NULL) return 0; - } X = (uint32_t *)(B + Blen); T = X + 32 * r; V = T + 32 * r; diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c index 1afac4e477..90986bc762 100644 --- a/providers/implementations/kdfs/sshkdf.c +++ b/providers/implementations/kdfs/sshkdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -58,9 +58,7 @@ static void *kdf_sshkdf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - else + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) ctx->provctx = provctx; return ctx; } @@ -247,7 +245,7 @@ const OSSL_DISPATCH ossl_kdf_sshkdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))kdf_sshkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_sshkdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; static int SSHKDF(const EVP_MD *evp_md, diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c index ecb98de6fd..db750a4f23 100644 --- a/providers/implementations/kdfs/sskdf.c +++ b/providers/implementations/kdfs/sskdf.c @@ -50,6 +50,7 @@ #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_util.h" +#include "internal/params.h" typedef struct { void *provctx; @@ -291,9 +292,8 @@ static void *sskdf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - ctx->provctx = provctx; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) + ctx->provctx = provctx; return ctx; } @@ -351,16 +351,6 @@ static void *sskdf_dup(void *vctx) return NULL; } -static int sskdf_set_buffer(unsigned char **out, size_t *out_len, - const OSSL_PARAM *p) -{ - if (p->data == NULL || p->data_size == 0) - return 1; - OPENSSL_free(*out); - *out = NULL; - return OSSL_PARAM_get_octet_string(p, (void **)out, 0, out_len); -} - static size_t sskdf_size(KDF_SSKDF *ctx) { int len; @@ -424,10 +414,8 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen, /* If no salt is set then use a default_salt of zeros */ if (ctx->salt == NULL || ctx->salt_len <= 0) { ctx->salt = OPENSSL_zalloc(default_salt_len); - if (ctx->salt == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctx->salt == NULL) return 0; - } ctx->salt_len = default_salt_len; } ret = SSKDF_mac_kdm(ctx->macctx, @@ -483,6 +471,7 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) KDF_SSKDF *ctx = vctx; OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); size_t sz; + int r; if (params == NULL) return 1; @@ -490,29 +479,32 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params, NULL, NULL, NULL, libctx)) return 0; - if (ctx->macctx != NULL) { - if (EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), - OSSL_MAC_NAME_KMAC128) - || EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), - OSSL_MAC_NAME_KMAC256)) { - ctx->is_kmac = 1; - } - } + if (ctx->macctx != NULL) { + if (EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), + OSSL_MAC_NAME_KMAC128) + || EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), + OSSL_MAC_NAME_KMAC256)) { + ctx->is_kmac = 1; + } + } - if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) - return 0; + if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) + return 0; - if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL - || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) - if (!sskdf_set_buffer(&ctx->secret, &ctx->secret_len, p)) - return 0; + r = ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SECRET, + &ctx->secret, &ctx->secret_len); + if (r == -1) + r = ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_KEY, + &ctx->secret, &ctx->secret_len); + if (r == 0) + return 0; - if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) - if (!sskdf_set_buffer(&ctx->info, &ctx->info_len, p)) - return 0; + if (ossl_param_get1_concat_octet_string(params, OSSL_KDF_PARAM_INFO, + &ctx->info, &ctx->info_len, 0) == 0) + return 0; - if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) - if (!sskdf_set_buffer(&ctx->salt, &ctx->salt_len, p)) + if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SALT, + &ctx->salt, &ctx->salt_len) == 0) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MAC_SIZE)) @@ -573,7 +565,7 @@ const OSSL_DISPATCH ossl_kdf_sskdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))sskdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = { @@ -588,5 +580,5 @@ const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))sskdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c index 54124ad4cb..ff305579c3 100644 --- a/providers/implementations/kdfs/tls1_prf.c +++ b/providers/implementations/kdfs/tls1_prf.c @@ -113,11 +113,8 @@ static void *kdf_tls1_prf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return NULL; - } - ctx->provctx = provctx; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) + ctx->provctx = provctx; return ctx; } @@ -314,7 +311,7 @@ const OSSL_DISPATCH ossl_kdf_tls1_prf_functions[] = { (void(*)(void))kdf_tls1_prf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_tls1_prf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; /* @@ -440,10 +437,8 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, seed, seed_len, out, olen)) return 0; - if ((tmp = OPENSSL_malloc(olen)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((tmp = OPENSSL_malloc(olen)) == NULL) return 0; - } if (!tls1_prf_P_hash(sha1ctx, sec + slen - L_S2, L_S2, seed, seed_len, tmp, olen)) { diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c index 4c274fe27a..19b54493ef 100644 --- a/providers/implementations/kdfs/x942kdf.c +++ b/providers/implementations/kdfs/x942kdf.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -239,7 +239,7 @@ x942_encode_otherinfo(size_t keylen, goto err; /* * Since we allocated the exact size required, the buffer should point to the - * start of the alllocated buffer at this point. + * start of the allocated buffer at this point. */ if (WPACKET_get_curr(&pkt) != der_buf) goto err; @@ -336,10 +336,8 @@ static void *x942kdf_new(void *provctx) if (!ossl_prov_is_running()) return NULL; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) return NULL; - } ctx->provctx = provctx; ctx->use_keybits = 1; return ctx; @@ -628,5 +626,5 @@ const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[] = { { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))x942kdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x942kdf_get_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/kem/build.info b/providers/implementations/kem/build.info index dbb1b7d750..d6a6698da1 100644 --- a/providers/implementations/kem/build.info +++ b/providers/implementations/kem/build.info @@ -2,5 +2,13 @@ # switch each to the Legacy provider when needed. $RSA_KEM_GOAL=../../libdefault.a ../../libfips.a +$EC_KEM_GOAL=../../libdefault.a SOURCE[$RSA_KEM_GOAL]=rsa_kem.c + +IF[{- !$disabled{ec} -}] + SOURCE[$EC_KEM_GOAL]=kem_util.c ec_kem.c + IF[{- !$disabled{ecx} -}] + SOURCE[$EC_KEM_GOAL]=ecx_kem.c + ENDIF +ENDIF diff --git a/providers/implementations/kem/ec_kem.c b/providers/implementations/kem/ec_kem.c new file mode 100644 index 0000000000..b82f903662 --- /dev/null +++ b/providers/implementations/kem/ec_kem.c @@ -0,0 +1,814 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * The following implementation is part of RFC 9180 related to DHKEM using + * EC keys (i.e. P-256, P-384 and P-521) + * References to Sections in the comments below refer to RFC 9180. + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "prov/provider_ctx.h" +#include "prov/implementations.h" +#include "prov/securitycheck.h" +#include "prov/providercommon.h" + +#include +#include "internal/hpke_util.h" +#include "crypto/ec.h" +#include "prov/ecx.h" +#include "eckem.h" + +typedef struct { + EC_KEY *recipient_key; + EC_KEY *sender_authkey; + OSSL_LIB_CTX *libctx; + char *propq; + unsigned int mode; + unsigned int op; + unsigned char *ikm; + size_t ikmlen; + const char *kdfname; + const OSSL_HPKE_KEM_INFO *info; +} PROV_EC_CTX; + +static OSSL_FUNC_kem_newctx_fn eckem_newctx; +static OSSL_FUNC_kem_encapsulate_init_fn eckem_encapsulate_init; +static OSSL_FUNC_kem_auth_encapsulate_init_fn eckem_auth_encapsulate_init; +static OSSL_FUNC_kem_encapsulate_fn eckem_encapsulate; +static OSSL_FUNC_kem_decapsulate_init_fn eckem_decapsulate_init; +static OSSL_FUNC_kem_auth_decapsulate_init_fn eckem_auth_decapsulate_init; +static OSSL_FUNC_kem_decapsulate_fn eckem_decapsulate; +static OSSL_FUNC_kem_freectx_fn eckem_freectx; +static OSSL_FUNC_kem_set_ctx_params_fn eckem_set_ctx_params; +static OSSL_FUNC_kem_settable_ctx_params_fn eckem_settable_ctx_params; + +/* ASCII: "KEM", in hex for EBCDIC compatibility */ +static const char LABEL_KEM[] = "\x4b\x45\x4d"; + +static int eckey_check(const EC_KEY *ec, int requires_privatekey) +{ + int rv = 0; + BN_CTX *bnctx = NULL; + BIGNUM *rem = NULL; + const BIGNUM *priv = EC_KEY_get0_private_key(ec); + const EC_POINT *pub = EC_KEY_get0_public_key(ec); + + /* Keys always require a public component */ + if (pub == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + if (priv == NULL) { + return (requires_privatekey == 0); + } else { + /* If there is a private key, check that is non zero (mod order) */ + const EC_GROUP *group = EC_KEY_get0_group(ec); + const BIGNUM *order = EC_GROUP_get0_order(group); + + bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec)); + rem = BN_new(); + + if (order != NULL && rem != NULL && bnctx != NULL) { + rv = BN_mod(rem, priv, order, bnctx) + && !BN_is_zero(rem); + } + } + BN_free(rem); + BN_CTX_free(bnctx); + return rv; +} + +/* Returns NULL if the curve is not supported */ +static const char *ec_curvename_get0(const EC_KEY *ec) +{ + const EC_GROUP *group = EC_KEY_get0_group(ec); + + return EC_curve_nid2nist(EC_GROUP_get_curve_name(group)); +} + +/* + * Set the recipient key, and free any existing key. + * ec can be NULL. + * The ec key may have only a private or public component + * (but it must have a group). + */ +static int recipient_key_set(PROV_EC_CTX *ctx, EC_KEY *ec) +{ + EC_KEY_free(ctx->recipient_key); + ctx->recipient_key = NULL; + + if (ec != NULL) { + const char *curve = ec_curvename_get0(ec); + + if (curve == NULL) + return -2; + ctx->info = ossl_HPKE_KEM_INFO_find_curve(curve); + if (ctx->info == NULL) + return -2; + if (!EC_KEY_up_ref(ec)) + return 0; + ctx->recipient_key = ec; + ctx->kdfname = "HKDF"; + } + return 1; +} + +/* + * Set the senders auth key, and free any existing auth key. + * ec can be NULL. + */ +static int sender_authkey_set(PROV_EC_CTX *ctx, EC_KEY *ec) +{ + EC_KEY_free(ctx->sender_authkey); + ctx->sender_authkey = NULL; + + if (ec != NULL) { + if (!EC_KEY_up_ref(ec)) + return 0; + ctx->sender_authkey = ec; + } + return 1; +} + +/* + * Serializes a encoded public key buffer into a EC public key. + * Params: + * in Contains the group. + * pubbuf The encoded public key buffer + * Returns: The created public EC key, or NULL if there is an error. + */ +static EC_KEY *eckey_frompub(EC_KEY *in, + const unsigned char *pubbuf, size_t pubbuflen) +{ + EC_KEY *key; + + key = EC_KEY_new_ex(ossl_ec_key_get_libctx(in), ossl_ec_key_get0_propq(in)); + if (key == NULL) + goto err; + if (!EC_KEY_set_group(key, EC_KEY_get0_group(in))) + goto err; + if (!EC_KEY_oct2key(key, pubbuf, pubbuflen, NULL)) + goto err; + return key; +err: + EC_KEY_free(key); + return NULL; +} + +/* + * Deserialises a EC public key into a encoded byte array. + * Returns: 1 if successful or 0 otherwise. + */ +static int ecpubkey_todata(const EC_KEY *ec, unsigned char *out, size_t *outlen, + size_t maxoutlen) +{ + const EC_POINT *pub; + const EC_GROUP *group; + + group = EC_KEY_get0_group(ec); + pub = EC_KEY_get0_public_key(ec); + *outlen = EC_POINT_point2oct(group, pub, POINT_CONVERSION_UNCOMPRESSED, + out, maxoutlen, NULL); + return *outlen != 0; +} + +static void *eckem_newctx(void *provctx) +{ + PROV_EC_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_EC_CTX)); + + if (ctx == NULL) + return NULL; + ctx->libctx = PROV_LIBCTX_OF(provctx); + + return ctx; +} + +static void eckem_freectx(void *vectx) +{ + PROV_EC_CTX *ctx = (PROV_EC_CTX *)vectx; + + OPENSSL_clear_free(ctx->ikm, ctx->ikmlen); + recipient_key_set(ctx, NULL); + sender_authkey_set(ctx, NULL); + OPENSSL_free(ctx); +} + +static int ossl_ec_match_params(const EC_KEY *key1, const EC_KEY *key2) +{ + int ret; + BN_CTX *ctx = NULL; + const EC_GROUP *group1 = EC_KEY_get0_group(key1); + const EC_GROUP *group2 = EC_KEY_get0_group(key2); + + ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key1)); + if (ctx == NULL) + return 0; + + ret = group1 != NULL + && group2 != NULL + && EC_GROUP_cmp(group1, group2, ctx) == 0; + if (!ret) + ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); + BN_CTX_free(ctx); + return ret; +} + +static int eckem_init(void *vctx, int operation, void *vec, void *vauth, + const OSSL_PARAM params[]) +{ + int rv; + PROV_EC_CTX *ctx = (PROV_EC_CTX *)vctx; + EC_KEY *ec = vec; + EC_KEY *auth = vauth; + + if (!ossl_prov_is_running()) + return 0; + + if (!eckey_check(ec, operation == EVP_PKEY_OP_DECAPSULATE)) + return 0; + rv = recipient_key_set(ctx, ec); + if (rv <= 0) + return rv; + + if (auth != NULL) { + if (!ossl_ec_match_params(ec, auth) + || !eckey_check(auth, operation == EVP_PKEY_OP_ENCAPSULATE) + || !sender_authkey_set(ctx, auth)) + return 0; + } + + ctx->op = operation; + return eckem_set_ctx_params(vctx, params); +} + +static int eckem_encapsulate_init(void *vctx, void *vec, + const OSSL_PARAM params[]) +{ + return eckem_init(vctx, EVP_PKEY_OP_ENCAPSULATE, vec, NULL, params); +} + +static int eckem_decapsulate_init(void *vctx, void *vec, + const OSSL_PARAM params[]) +{ + return eckem_init(vctx, EVP_PKEY_OP_DECAPSULATE, vec, NULL, params); +} + +static int eckem_auth_encapsulate_init(void *vctx, void *vecx, void *vauthpriv, + const OSSL_PARAM params[]) +{ + return eckem_init(vctx, EVP_PKEY_OP_ENCAPSULATE, vecx, vauthpriv, params); +} + +static int eckem_auth_decapsulate_init(void *vctx, void *vecx, void *vauthpub, + const OSSL_PARAM params[]) +{ + return eckem_init(vctx, EVP_PKEY_OP_DECAPSULATE, vecx, vauthpub, params); +} + +static int eckem_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_EC_CTX *ctx = (PROV_EC_CTX *)vctx; + const OSSL_PARAM *p; + int mode; + + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_IKME); + if (p != NULL) { + void *tmp = NULL; + size_t tmplen = 0; + + if (p->data != NULL && p->data_size != 0) { + if (!OSSL_PARAM_get_octet_string(p, &tmp, 0, &tmplen)) + return 0; + } + OPENSSL_clear_free(ctx->ikm, ctx->ikmlen); + /* Set the ephemeral seed */ + ctx->ikm = tmp; + ctx->ikmlen = tmplen; + } + + p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_OPERATION); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + mode = ossl_eckem_modename2id(p->data); + if (mode == KEM_MODE_UNDEFINED) + return 0; + ctx->mode = mode; + } + return 1; +} + +static const OSSL_PARAM known_settable_eckem_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KEM_PARAM_OPERATION, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KEM_PARAM_IKME, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *eckem_settable_ctx_params(ossl_unused void *vctx, + ossl_unused void *provctx) +{ + return known_settable_eckem_ctx_params; +} + +/* + * See Section 4.1 DH-Based KEM (DHKEM) ExtractAndExpand + */ +static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + uint16_t kemid, + const unsigned char *dhkm, size_t dhkmlen, + const unsigned char *kemctx, + size_t kemctxlen) +{ + uint8_t suiteid[2]; + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prklen = okmlen; + int ret; + + if (prklen > sizeof(prk)) + return 0; + + suiteid[0] = (kemid >> 8) & 0xff; + suiteid[1] = kemid & 0xff; + + ret = ossl_hpke_labeled_extract(kctx, prk, prklen, + NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_EAE_PRK, dhkm, dhkmlen) + && ossl_hpke_labeled_expand(kctx, okm, okmlen, prk, prklen, + LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_SHARED_SECRET, + kemctx, kemctxlen); + OPENSSL_cleanse(prk, prklen); + return ret; +} + +/* + * See Section 7.1.3 DeriveKeyPair. + * + * This function is used by ec keygen. + * (For this reason it does not use any of the state stored in PROV_EC_CTX). + * + * Params: + * ec An initialized ec key. + * priv The buffer to store the generated private key into (it is assumed + * this is of length alg->encodedprivlen). + * ikm buffer containing the input key material (seed). This must be set. + * ikmlen size of the ikm buffer in bytes + * Returns: + * 1 if successful or 0 otherwise. + */ +int ossl_ec_dhkem_derive_private(EC_KEY *ec, BIGNUM *priv, + const unsigned char *ikm, size_t ikmlen) +{ + int ret = 0; + EVP_KDF_CTX *kdfctx = NULL; + uint8_t suiteid[2]; + unsigned char prk[OSSL_HPKE_MAX_SECRET]; + unsigned char privbuf[OSSL_HPKE_MAX_PRIVATE]; + const BIGNUM *order; + unsigned char counter = 0; + const char *curve = ec_curvename_get0(ec); + const OSSL_HPKE_KEM_INFO *info; + + if (curve == NULL) + return -2; + + info = ossl_HPKE_KEM_INFO_find_curve(curve); + if (info == NULL) + return -2; + + kdfctx = ossl_kdf_ctx_create("HKDF", info->mdname, + ossl_ec_key_get_libctx(ec), + ossl_ec_key_get0_propq(ec)); + if (kdfctx == NULL) + return 0; + + /* ikmlen should have a length of at least Nsk */ + if (ikmlen < info->Nsecret) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH, + "ikm length is :%zu, should be at least %zu", + ikmlen, info->Nsecret); + goto err; + } + + suiteid[0] = info->kem_id / 256; + suiteid[1] = info->kem_id % 256; + + if (!ossl_hpke_labeled_extract(kdfctx, prk, info->Nsecret, + NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_DKP_PRK, ikm, ikmlen)) + goto err; + + order = EC_GROUP_get0_order(EC_KEY_get0_group(ec)); + do { + if (!ossl_hpke_labeled_expand(kdfctx, privbuf, info->Nsk, + prk, info->Nsecret, + LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_CANDIDATE, + &counter, 1)) + goto err; + privbuf[0] &= info->bitmask; + if (BN_bin2bn(privbuf, info->Nsk, priv) == NULL) + goto err; + if (counter == 0xFF) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + goto err; + } + counter++; + } while (BN_is_zero(priv) || BN_cmp(priv, order) >= 0); + ret = 1; +err: + OPENSSL_cleanse(prk, sizeof(prk)); + OPENSSL_cleanse(privbuf, sizeof(privbuf)); + EVP_KDF_CTX_free(kdfctx); + return ret; +} + +/* + * Do a keygen operation without having to use EVP_PKEY. + * Params: + * ctx Context object + * ikm The seed material - if this is NULL, then a random seed is used. + * Returns: + * The generated EC key, or NULL on failure. + */ +static EC_KEY *derivekey(PROV_EC_CTX *ctx, + const unsigned char *ikm, size_t ikmlen) +{ + int ret = 0; + EC_KEY *key; + unsigned char *seed = (unsigned char *)ikm; + size_t seedlen = ikmlen; + unsigned char tmpbuf[OSSL_HPKE_MAX_PRIVATE]; + + key = EC_KEY_new_ex(ctx->libctx, ctx->propq); + if (key == NULL) + goto err; + if (!EC_KEY_set_group(key, EC_KEY_get0_group(ctx->recipient_key))) + goto err; + + /* Generate a random seed if there is no input ikm */ + if (seed == NULL || seedlen == 0) { + seedlen = ctx->info->Nsk; + if (seedlen > sizeof(tmpbuf)) + goto err; + if (RAND_priv_bytes_ex(ctx->libctx, tmpbuf, seedlen, 0) <= 0) + goto err; + seed = tmpbuf; + } + ret = ossl_ec_generate_key_dhkem(key, seed, seedlen); +err: + if (seed != ikm) + OPENSSL_cleanse(seed, seedlen); + if (ret <= 0) { + EC_KEY_free(key); + key = NULL; + } + return key; +} + +/* + * Before doing a key exchange the public key of the peer needs to be checked + * Note that the group check is not done here as we have already checked + * that it only uses one of the approved curve names when the key was set. + * + * Returns 1 if the public key is valid, or 0 if it fails. + */ +static int check_publickey(const EC_KEY *pub) +{ + int ret = 0; + BN_CTX *bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(pub)); + + if (bnctx == NULL) + return 0; + ret = ossl_ec_key_public_check(pub, bnctx); + BN_CTX_free(bnctx); + + return ret; +} + +/* + * Do an ecdh key exchange. + * dhkm = DH(sender, peer) + * + * NOTE: Instead of using EVP_PKEY_derive() API's, we use EC_KEY operations + * to avoid messy conversions back to EVP_PKEY. + * + * Returns the size of the secret if successful, or 0 otherwise, + */ +static int generate_ecdhkm(const EC_KEY *sender, const EC_KEY *peer, + unsigned char *out, size_t maxout, + unsigned int secretsz) +{ + const EC_GROUP *group = EC_KEY_get0_group(sender); + size_t secretlen = (EC_GROUP_get_degree(group) + 7) / 8; + + if (secretlen != secretsz || secretlen > maxout) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "secretsz invalid"); + return 0; + } + + if (!check_publickey(peer)) + return 0; + return ECDH_compute_key(out, secretlen, EC_KEY_get0_public_key(peer), + sender, NULL) > 0; +} + +/* + * Derive a secret using ECDH (code is shared by the encap and decap) + * + * dhkm = Concat(ecdh(privkey1, peerkey1), ecdh(privkey2, peerkey2) + * kemctx = Concat(sender_pub, recipient_pub, ctx->sender_authkey) + * secret = dhkem_extract_and_expand(kemid, dhkm, kemctx); + * + * Params: + * ctx Object that contains algorithm state and constants. + * secret The returned secret (with a length ctx->alg->secretlen bytes). + * privkey1 A private key used for ECDH key derivation. + * peerkey1 A public key used for ECDH key derivation with privkey1 + * privkey2 A optional private key used for a second ECDH key derivation. + * It can be NULL. + * peerkey2 A optional public key used for a second ECDH key derivation + * with privkey2,. It can be NULL. + * sender_pub The senders public key in encoded form. + * recipient_pub The recipients public key in encoded form. + * Notes: + * The second ecdh() is only used for the HPKE auth modes when both privkey2 + * and peerkey2 are non NULL (i.e. ctx->sender_authkey is not NULL). + */ +static int derive_secret(PROV_EC_CTX *ctx, unsigned char *secret, + const EC_KEY *privkey1, const EC_KEY *peerkey1, + const EC_KEY *privkey2, const EC_KEY *peerkey2, + const unsigned char *sender_pub, + const unsigned char *recipient_pub) +{ + int ret = 0; + EVP_KDF_CTX *kdfctx = NULL; + unsigned char sender_authpub[OSSL_HPKE_MAX_PUBLIC]; + unsigned char dhkm[OSSL_HPKE_MAX_PRIVATE * 2]; + unsigned char kemctx[OSSL_HPKE_MAX_PUBLIC * 3]; + size_t sender_authpublen; + size_t kemctxlen = 0, dhkmlen = 0; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + size_t encodedpublen = info->Npk; + size_t encodedprivlen = info->Nsk; + int auth = ctx->sender_authkey != NULL; + + if (!generate_ecdhkm(privkey1, peerkey1, dhkm, sizeof(dhkm), encodedprivlen)) + goto err; + dhkmlen = encodedprivlen; + kemctxlen = 2 * encodedpublen; + + /* Concat the optional second ECDH (used for Auth) */ + if (auth) { + /* Get the public key of the auth sender in encoded form */ + if (!ecpubkey_todata(ctx->sender_authkey, sender_authpub, + &sender_authpublen, sizeof(sender_authpub))) + goto err; + if (sender_authpublen != encodedpublen) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, + "Invalid sender auth public key"); + goto err; + } + if (!generate_ecdhkm(privkey2, peerkey2, + dhkm + dhkmlen, sizeof(dhkm) - dhkmlen, + encodedprivlen)) + goto err; + dhkmlen += encodedprivlen; + kemctxlen += encodedpublen; + } + if (kemctxlen > sizeof(kemctx)) + goto err; + + /* kemctx is the concat of both sides encoded public key */ + memcpy(kemctx, sender_pub, info->Npk); + memcpy(kemctx + info->Npk, recipient_pub, info->Npk); + if (auth) + memcpy(kemctx + 2 * encodedpublen, sender_authpub, encodedpublen); + kdfctx = ossl_kdf_ctx_create(ctx->kdfname, info->mdname, + ctx->libctx, ctx->propq); + if (kdfctx == NULL) + goto err; + if (!dhkem_extract_and_expand(kdfctx, secret, info->Nsecret, + info->kem_id, dhkm, dhkmlen, + kemctx, kemctxlen)) + goto err; + ret = 1; +err: + OPENSSL_cleanse(dhkm, dhkmlen); + EVP_KDF_CTX_free(kdfctx); + return ret; +} + +/* + * Do a DHKEM encapsulate operation. + * + * See Section 4.1 Encap() and AuthEncap() + * + * Params: + * ctx A context object holding the recipients public key and the + * optional senders auth private key. + * enc A buffer to return the senders ephemeral public key. + * Setting this to NULL allows the enclen and secretlen to return + * values, without calculating the secret. + * enclen Passes in the max size of the enc buffer and returns the + * encoded public key length. + * secret A buffer to return the calculated shared secret. + * secretlen Passes in the max size of the secret buffer and returns the + * secret length. + * Returns: 1 on success or 0 otherwise. + */ +static int dhkem_encap(PROV_EC_CTX *ctx, + unsigned char *enc, size_t *enclen, + unsigned char *secret, size_t *secretlen) +{ + int ret = 0; + EC_KEY *sender_ephemkey = NULL; + unsigned char sender_pub[OSSL_HPKE_MAX_PUBLIC]; + unsigned char recipient_pub[OSSL_HPKE_MAX_PUBLIC]; + size_t sender_publen, recipient_publen; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + + if (enc == NULL) { + if (enclen == NULL && secretlen == NULL) + return 0; + if (enclen != NULL) + *enclen = info->Nenc; + if (secretlen != NULL) + *secretlen = info->Nsecret; + return 1; + } + + if (*secretlen < info->Nsecret) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small"); + return 0; + } + if (*enclen < info->Nenc) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*enclen too small"); + return 0; + } + + /* Create an ephemeral key */ + sender_ephemkey = derivekey(ctx, ctx->ikm, ctx->ikmlen); + if (sender_ephemkey == NULL) + goto err; + if (!ecpubkey_todata(sender_ephemkey, sender_pub, &sender_publen, + sizeof(sender_pub)) + || !ecpubkey_todata(ctx->recipient_key, recipient_pub, + &recipient_publen, sizeof(recipient_pub))) + goto err; + + if (sender_publen != info->Npk + || recipient_publen != sender_publen) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid public key"); + goto err; + } + + if (!derive_secret(ctx, secret, + sender_ephemkey, ctx->recipient_key, + ctx->sender_authkey, ctx->recipient_key, + sender_pub, recipient_pub)) + goto err; + + /* Return the senders ephemeral public key in encoded form */ + memcpy(enc, sender_pub, sender_publen); + *enclen = sender_publen; + *secretlen = info->Nsecret; + ret = 1; +err: + EC_KEY_free(sender_ephemkey); + return ret; +} + +/* + * Do a DHKEM decapsulate operation. + * See Section 4.1 Decap() and Auth Decap() + * + * Params: + * ctx A context object holding the recipients private key and the + * optional senders auth public key. + * secret A buffer to return the calculated shared secret. Setting this to + * NULL can be used to return the secretlen. + * secretlen Passes in the max size of the secret buffer and returns the + * secret length. + * enc A buffer containing the senders ephemeral public key that was returned + * from dhkem_encap(). + * enclen The length in bytes of enc. + * Returns: 1 If the shared secret is returned or 0 on error. + */ +static int dhkem_decap(PROV_EC_CTX *ctx, + unsigned char *secret, size_t *secretlen, + const unsigned char *enc, size_t enclen) +{ + int ret = 0; + EC_KEY *sender_ephempubkey = NULL; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + unsigned char recipient_pub[OSSL_HPKE_MAX_PUBLIC]; + size_t recipient_publen; + size_t encodedpublen = info->Npk; + + if (secret == NULL) { + *secretlen = info->Nsecret; + return 1; + } + + if (*secretlen < info->Nsecret) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small"); + return 0; + } + if (enclen != encodedpublen) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid enc public key"); + return 0; + } + + sender_ephempubkey = eckey_frompub(ctx->recipient_key, enc, enclen); + if (sender_ephempubkey == NULL) + goto err; + if (!ecpubkey_todata(ctx->recipient_key, recipient_pub, &recipient_publen, + sizeof(recipient_pub))) + goto err; + if (recipient_publen != encodedpublen) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid recipient public key"); + goto err; + } + + if (!derive_secret(ctx, secret, + ctx->recipient_key, sender_ephempubkey, + ctx->recipient_key, ctx->sender_authkey, + enc, recipient_pub)) + goto err; + *secretlen = info->Nsecret; + ret = 1; +err: + EC_KEY_free(sender_ephempubkey); + return ret; +} + +static int eckem_encapsulate(void *vctx, unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + PROV_EC_CTX *ctx = (PROV_EC_CTX *)vctx; + + switch (ctx->mode) { + case KEM_MODE_DHKEM: + return dhkem_encap(ctx, out, outlen, secret, secretlen); + default: + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); + return -2; + } +} + +static int eckem_decapsulate(void *vctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + PROV_EC_CTX *ctx = (PROV_EC_CTX *)vctx; + + switch (ctx->mode) { + case KEM_MODE_DHKEM: + return dhkem_decap(ctx, out, outlen, in, inlen); + default: + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); + return -2; + } +} + +const OSSL_DISPATCH ossl_ec_asym_kem_functions[] = { + { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))eckem_newctx }, + { OSSL_FUNC_KEM_ENCAPSULATE_INIT, + (void (*)(void))eckem_encapsulate_init }, + { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))eckem_encapsulate }, + { OSSL_FUNC_KEM_DECAPSULATE_INIT, + (void (*)(void))eckem_decapsulate_init }, + { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))eckem_decapsulate }, + { OSSL_FUNC_KEM_FREECTX, (void (*)(void))eckem_freectx }, + { OSSL_FUNC_KEM_SET_CTX_PARAMS, + (void (*)(void))eckem_set_ctx_params }, + { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, + (void (*)(void))eckem_settable_ctx_params }, + { OSSL_FUNC_KEM_AUTH_ENCAPSULATE_INIT, + (void (*)(void))eckem_auth_encapsulate_init }, + { OSSL_FUNC_KEM_AUTH_DECAPSULATE_INIT, + (void (*)(void))eckem_auth_decapsulate_init }, + OSSL_DISPATCH_END +}; diff --git a/providers/implementations/kem/eckem.h b/providers/implementations/kem/eckem.h new file mode 100644 index 0000000000..2e46a0f2ff --- /dev/null +++ b/providers/implementations/kem/eckem.h @@ -0,0 +1,13 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define KEM_MODE_UNDEFINED 0 +#define KEM_MODE_DHKEM 1 + +int ossl_eckem_modename2id(const char *name); diff --git a/providers/implementations/kem/ecx_kem.c b/providers/implementations/kem/ecx_kem.c new file mode 100644 index 0000000000..4a762f2153 --- /dev/null +++ b/providers/implementations/kem/ecx_kem.c @@ -0,0 +1,704 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * The following implementation is part of RFC 9180 related to DHKEM using + * ECX keys (i.e. X25519 and X448) + * References to Sections in the comments below refer to RFC 9180. + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "prov/provider_ctx.h" +#include "prov/implementations.h" +#include "prov/securitycheck.h" +#include "prov/providercommon.h" +#include "prov/ecx.h" +#include "crypto/ecx.h" +#include +#include "internal/hpke_util.h" +#include "eckem.h" + +#define MAX_ECX_KEYLEN X448_KEYLEN + +/* KEM identifiers from Section 7.1 "Table 2 KEM IDs" */ +#define KEMID_X25519_HKDF_SHA256 0x20 +#define KEMID_X448_HKDF_SHA512 0x21 + +/* ASCII: "KEM", in hex for EBCDIC compatibility */ +static const char LABEL_KEM[] = "\x4b\x45\x4d"; + +typedef struct { + ECX_KEY *recipient_key; + ECX_KEY *sender_authkey; + OSSL_LIB_CTX *libctx; + char *propq; + unsigned int mode; + unsigned int op; + unsigned char *ikm; + size_t ikmlen; + const char *kdfname; + const OSSL_HPKE_KEM_INFO *info; +} PROV_ECX_CTX; + +static OSSL_FUNC_kem_newctx_fn ecxkem_newctx; +static OSSL_FUNC_kem_encapsulate_init_fn ecxkem_encapsulate_init; +static OSSL_FUNC_kem_encapsulate_fn ecxkem_encapsulate; +static OSSL_FUNC_kem_decapsulate_init_fn ecxkem_decapsulate_init; +static OSSL_FUNC_kem_decapsulate_fn ecxkem_decapsulate; +static OSSL_FUNC_kem_freectx_fn ecxkem_freectx; +static OSSL_FUNC_kem_set_ctx_params_fn ecxkem_set_ctx_params; +static OSSL_FUNC_kem_auth_encapsulate_init_fn ecxkem_auth_encapsulate_init; +static OSSL_FUNC_kem_auth_decapsulate_init_fn ecxkem_auth_decapsulate_init; + +/* + * Set KEM values as specified in Section 7.1 "Table 2 KEM IDs" + * There is only one set of values for X25519 and X448. + * Additional values could be set via set_params if required. + */ +static const OSSL_HPKE_KEM_INFO *get_kem_info(ECX_KEY *ecx) +{ + const char *name = NULL; + + if (ecx->type == ECX_KEY_TYPE_X25519) + name = SN_X25519; + else + name = SN_X448; + return ossl_HPKE_KEM_INFO_find_curve(name); +} + +/* + * Set the recipient key, and free any existing key. + * ecx can be NULL. The ecx key may have only a private or public component. + */ +static int recipient_key_set(PROV_ECX_CTX *ctx, ECX_KEY *ecx) +{ + ossl_ecx_key_free(ctx->recipient_key); + ctx->recipient_key = NULL; + if (ecx != NULL) { + ctx->info = get_kem_info(ecx); + if (ctx->info == NULL) + return -2; + ctx->kdfname = "HKDF"; + if (!ossl_ecx_key_up_ref(ecx)) + return 0; + ctx->recipient_key = ecx; + } + return 1; +} + +/* + * Set the senders auth key, and free any existing auth key. + * ecx can be NULL. + */ +static int sender_authkey_set(PROV_ECX_CTX *ctx, ECX_KEY *ecx) +{ + ossl_ecx_key_free(ctx->sender_authkey); + ctx->sender_authkey = NULL; + + if (ecx != NULL) { + if (!ossl_ecx_key_up_ref(ecx)) + return 0; + ctx->sender_authkey = ecx; + } + return 1; +} + +/* + * Serialize a public key from byte array's for the encoded public keys. + * ctx is used to access the key type. + * Returns: The created ECX_KEY or NULL on error. + */ +static ECX_KEY *ecxkey_pubfromdata(PROV_ECX_CTX *ctx, + const unsigned char *pubbuf, size_t pubbuflen) +{ + ECX_KEY *ecx = NULL; + OSSL_PARAM params[2], *p = params; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, + (char *)pubbuf, pubbuflen); + *p = OSSL_PARAM_construct_end(); + + ecx = ossl_ecx_key_new(ctx->libctx, ctx->recipient_key->type, 1, ctx->propq); + if (ecx == NULL) + return NULL; + if (ossl_ecx_key_fromdata(ecx, params, 0) <= 0) { + ossl_ecx_key_free(ecx); + ecx = NULL; + } + return ecx; +} + +static unsigned char *ecx_pubkey(ECX_KEY *ecx) +{ + if (ecx == NULL || !ecx->haspubkey) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + return ecx->pubkey; +} + +static void *ecxkem_newctx(void *provctx) +{ + PROV_ECX_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_ECX_CTX)); + + if (ctx == NULL) + return NULL; + ctx->libctx = PROV_LIBCTX_OF(provctx); + + return ctx; +} + +static void ecxkem_freectx(void *vectx) +{ + PROV_ECX_CTX *ctx = (PROV_ECX_CTX *)vectx; + + OPENSSL_clear_free(ctx->ikm, ctx->ikmlen); + recipient_key_set(ctx, NULL); + sender_authkey_set(ctx, NULL); + OPENSSL_free(ctx); +} + +static int ecx_match_params(const ECX_KEY *key1, const ECX_KEY *key2) +{ + return (key1->type == key2->type && key1->keylen == key2->keylen); +} + +static int ecx_key_check(const ECX_KEY *ecx, int requires_privatekey) +{ + if (ecx->privkey == NULL) + return (requires_privatekey == 0); + return 1; +} + +static int ecxkem_init(void *vecxctx, int operation, void *vecx, void *vauth, + ossl_unused const OSSL_PARAM params[]) +{ + int rv; + PROV_ECX_CTX *ctx = (PROV_ECX_CTX *)vecxctx; + ECX_KEY *ecx = vecx; + ECX_KEY *auth = vauth; + + if (!ossl_prov_is_running()) + return 0; + + if (!ecx_key_check(ecx, operation == EVP_PKEY_OP_DECAPSULATE)) + return 0; + rv = recipient_key_set(ctx, ecx); + if (rv <= 0) + return rv; + + if (auth != NULL) { + if (!ecx_match_params(auth, ctx->recipient_key) + || !ecx_key_check(auth, operation == EVP_PKEY_OP_ENCAPSULATE) + || !sender_authkey_set(ctx, auth)) + return 0; + } + + ctx->op = operation; + return ecxkem_set_ctx_params(vecxctx, params); +} + +static int ecxkem_encapsulate_init(void *vecxctx, void *vecx, + const OSSL_PARAM params[]) +{ + return ecxkem_init(vecxctx, EVP_PKEY_OP_ENCAPSULATE, vecx, NULL, params); +} + +static int ecxkem_decapsulate_init(void *vecxctx, void *vecx, + const OSSL_PARAM params[]) +{ + return ecxkem_init(vecxctx, EVP_PKEY_OP_DECAPSULATE, vecx, NULL, params); +} + +static int ecxkem_auth_encapsulate_init(void *vctx, void *vecx, void *vauthpriv, + const OSSL_PARAM params[]) +{ + return ecxkem_init(vctx, EVP_PKEY_OP_ENCAPSULATE, vecx, vauthpriv, params); +} + +static int ecxkem_auth_decapsulate_init(void *vctx, void *vecx, void *vauthpub, + const OSSL_PARAM params[]) +{ + return ecxkem_init(vctx, EVP_PKEY_OP_DECAPSULATE, vecx, vauthpub, params); +} + +static int ecxkem_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_ECX_CTX *ctx = (PROV_ECX_CTX *)vctx; + const OSSL_PARAM *p; + int mode; + + if (ctx == NULL) + return 0; + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_IKME); + if (p != NULL) { + void *tmp = NULL; + size_t tmplen = 0; + + if (p->data != NULL && p->data_size != 0) { + if (!OSSL_PARAM_get_octet_string(p, &tmp, 0, &tmplen)) + return 0; + } + OPENSSL_clear_free(ctx->ikm, ctx->ikmlen); + ctx->ikm = tmp; + ctx->ikmlen = tmplen; + } + p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_OPERATION); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + mode = ossl_eckem_modename2id(p->data); + if (mode == KEM_MODE_UNDEFINED) + return 0; + ctx->mode = mode; + } + return 1; +} + +static const OSSL_PARAM known_settable_ecxkem_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KEM_PARAM_OPERATION, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KEM_PARAM_IKME, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *ecxkem_settable_ctx_params(ossl_unused void *vctx, + ossl_unused void *provctx) +{ + return known_settable_ecxkem_ctx_params; +} + +/* + * See Section 4.1 DH-Based KEM (DHKEM) ExtractAndExpand + */ +static int dhkem_extract_and_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + uint16_t kemid, + const unsigned char *dhkm, size_t dhkmlen, + const unsigned char *kemctx, + size_t kemctxlen) +{ + uint8_t suiteid[2]; + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prklen = okmlen; /* Nh */ + int ret; + + if (prklen > sizeof(prk)) + return 0; + + suiteid[0] = (kemid >> 8) &0xff; + suiteid[1] = kemid & 0xff; + + ret = ossl_hpke_labeled_extract(kctx, prk, prklen, + NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_EAE_PRK, dhkm, dhkmlen) + && ossl_hpke_labeled_expand(kctx, okm, okmlen, prk, prklen, + LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_SHARED_SECRET, + kemctx, kemctxlen); + OPENSSL_cleanse(prk, prklen); + return ret; +} + +/* + * See Section 7.1.3 DeriveKeyPair. + * + * This function is used by ecx keygen. + * (For this reason it does not use any of the state stored in PROV_ECX_CTX). + * + * Params: + * ecx An initialized ecx key. + * privout The buffer to store the generated private key into (it is assumed + * this is of length ecx->keylen). + * ikm buffer containing the input key material (seed). This must be non NULL. + * ikmlen size of the ikm buffer in bytes + * Returns: + * 1 if successful or 0 otherwise. + */ +int ossl_ecx_dhkem_derive_private(ECX_KEY *ecx, unsigned char *privout, + const unsigned char *ikm, size_t ikmlen) +{ + int ret = 0; + EVP_KDF_CTX *kdfctx = NULL; + unsigned char prk[EVP_MAX_MD_SIZE]; + uint8_t suiteid[2]; + const OSSL_HPKE_KEM_INFO *info = get_kem_info(ecx); + + /* ikmlen should have a length of at least Nsk */ + if (ikmlen < info->Nsk) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH, + "ikm length is :%zu, should be at least %zu", + ikmlen, info->Nsk); + goto err; + } + + kdfctx = ossl_kdf_ctx_create("HKDF", info->mdname, ecx->libctx, ecx->propq); + if (kdfctx == NULL) + return 0; + + suiteid[0] = info->kem_id / 256; + suiteid[1] = info->kem_id % 256; + + if (!ossl_hpke_labeled_extract(kdfctx, prk, info->Nsecret, + NULL, 0, LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_DKP_PRK, ikm, ikmlen)) + goto err; + + if (!ossl_hpke_labeled_expand(kdfctx, privout, info->Nsk, prk, info->Nsecret, + LABEL_KEM, suiteid, sizeof(suiteid), + OSSL_DHKEM_LABEL_SK, NULL, 0)) + goto err; + ret = 1; +err: + OPENSSL_cleanse(prk, sizeof(prk)); + EVP_KDF_CTX_free(kdfctx); + return ret; +} + +/* + * Do a keygen operation without having to use EVP_PKEY. + * Params: + * ctx Context object + * ikm The seed material - if this is NULL, then a random seed is used. + * Returns: + * The generated ECX key, or NULL on failure. + */ +static ECX_KEY *derivekey(PROV_ECX_CTX *ctx, + const unsigned char *ikm, size_t ikmlen) +{ + int ok = 0; + ECX_KEY *key; + unsigned char *privkey; + unsigned char *seed = (unsigned char *)ikm; + size_t seedlen = ikmlen; + unsigned char tmpbuf[OSSL_HPKE_MAX_PRIVATE]; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + + key = ossl_ecx_key_new(ctx->libctx, ctx->recipient_key->type, 0, ctx->propq); + if (key == NULL) + return NULL; + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) + goto err; + + /* Generate a random seed if there is no input ikm */ + if (seed == NULL || seedlen == 0) { + if (info->Nsk > sizeof(tmpbuf)) + goto err; + if (RAND_priv_bytes_ex(ctx->libctx, tmpbuf, info->Nsk, 0) <= 0) + goto err; + seed = tmpbuf; + seedlen = info->Nsk; + } + if (!ossl_ecx_dhkem_derive_private(key, privkey, seed, seedlen)) + goto err; + if (!ossl_ecx_public_from_private(key)) + goto err; + key->haspubkey = 1; + ok = 1; +err: + if (!ok) { + ossl_ecx_key_free(key); + key = NULL; + } + if (seed != ikm) + OPENSSL_cleanse(seed, seedlen); + return key; +} + +/* + * Do an ecxdh key exchange. + * dhkm = DH(sender, peer) + * + * NOTE: Instead of using EVP_PKEY_derive() API's, we use ECX_KEY operations + * to avoid messy conversions back to EVP_PKEY. + * + * Returns the size of the secret if successful, or 0 otherwise, + */ +static int generate_ecxdhkm(const ECX_KEY *sender, const ECX_KEY *peer, + unsigned char *out, size_t maxout, + unsigned int secretsz) +{ + size_t len = 0; + + /* NOTE: ossl_ecx_compute_key checks for shared secret being all zeros */ + return ossl_ecx_compute_key((ECX_KEY *)peer, (ECX_KEY *)sender, + sender->keylen, out, &len, maxout); +} + +/* + * Derive a secret using ECXDH (code is shared by the encap and decap) + * + * dhkm = Concat(ecxdh(privkey1, peerkey1), ecdh(privkey2, peerkey2) + * kemctx = Concat(sender_pub, recipient_pub, ctx->sender_authkey) + * secret = dhkem_extract_and_expand(kemid, dhkm, kemctx); + * + * Params: + * ctx Object that contains algorithm state and constants. + * secret The returned secret (with a length ctx->alg->secretlen bytes). + * privkey1 A private key used for ECXDH key derivation. + * peerkey1 A public key used for ECXDH key derivation with privkey1 + * privkey2 A optional private key used for a second ECXDH key derivation. + * It can be NULL. + * peerkey2 A optional public key used for a second ECXDH key derivation + * with privkey2,. It can be NULL. + * sender_pub The senders public key in encoded form. + * recipient_pub The recipients public key in encoded form. + * Notes: + * The second ecdh() is only used for the HPKE auth modes when both privkey2 + * and peerkey2 are non NULL (i.e. ctx->sender_authkey is not NULL). + */ +static int derive_secret(PROV_ECX_CTX *ctx, unsigned char *secret, + const ECX_KEY *privkey1, const ECX_KEY *peerkey1, + const ECX_KEY *privkey2, const ECX_KEY *peerkey2, + const unsigned char *sender_pub, + const unsigned char *recipient_pub) +{ + int ret = 0; + EVP_KDF_CTX *kdfctx = NULL; + unsigned char *sender_authpub = NULL; + unsigned char dhkm[MAX_ECX_KEYLEN * 2]; + unsigned char kemctx[MAX_ECX_KEYLEN * 3]; + size_t kemctxlen = 0, dhkmlen = 0; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + int auth = ctx->sender_authkey != NULL; + size_t encodedkeylen = info->Npk; + + if (!generate_ecxdhkm(privkey1, peerkey1, dhkm, sizeof(dhkm), encodedkeylen)) + goto err; + dhkmlen = encodedkeylen; + + /* Concat the optional second ECXDH (used for Auth) */ + if (auth) { + if (!generate_ecxdhkm(privkey2, peerkey2, + dhkm + dhkmlen, sizeof(dhkm) - dhkmlen, + encodedkeylen)) + goto err; + /* Get the public key of the auth sender in encoded form */ + sender_authpub = ecx_pubkey(ctx->sender_authkey); + if (sender_authpub == NULL) + goto err; + dhkmlen += encodedkeylen; + } + kemctxlen = encodedkeylen + dhkmlen; + if (kemctxlen > sizeof(kemctx)) + goto err; + + /* kemctx is the concat of both sides encoded public key */ + memcpy(kemctx, sender_pub, encodedkeylen); + memcpy(kemctx + encodedkeylen, recipient_pub, encodedkeylen); + if (auth) + memcpy(kemctx + 2 * encodedkeylen, sender_authpub, encodedkeylen); + kdfctx = ossl_kdf_ctx_create(ctx->kdfname, info->mdname, + ctx->libctx, ctx->propq); + if (kdfctx == NULL) + goto err; + if (!dhkem_extract_and_expand(kdfctx, secret, info->Nsecret, + info->kem_id, dhkm, dhkmlen, + kemctx, kemctxlen)) + goto err; + ret = 1; +err: + OPENSSL_cleanse(dhkm, dhkmlen); + EVP_KDF_CTX_free(kdfctx); + return ret; +} + +/* + * Do a DHKEM encapsulate operation. + * + * See Section 4.1 Encap() and AuthEncap() + * + * Params: + * ctx A context object holding the recipients public key and the + * optional senders auth private key. + * enc A buffer to return the senders ephemeral public key. + * Setting this to NULL allows the enclen and secretlen to return + * values, without calculating the secret. + * enclen Passes in the max size of the enc buffer and returns the + * encoded public key length. + * secret A buffer to return the calculated shared secret. + * secretlen Passes in the max size of the secret buffer and returns the + * secret length. + * Returns: 1 on success or 0 otherwise. + */ +static int dhkem_encap(PROV_ECX_CTX *ctx, + unsigned char *enc, size_t *enclen, + unsigned char *secret, size_t *secretlen) +{ + int ret = 0; + ECX_KEY *sender_ephemkey = NULL; + unsigned char *sender_ephempub, *recipient_pub; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + + if (enc == NULL) { + if (enclen == NULL && secretlen == NULL) + return 0; + if (enclen != NULL) + *enclen = info->Nenc; + if (secretlen != NULL) + *secretlen = info->Nsecret; + return 1; + } + + if (*secretlen < info->Nsecret) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small"); + return 0; + } + if (*enclen < info->Nenc) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*enclen too small"); + return 0; + } + + /* Create an ephemeral key */ + sender_ephemkey = derivekey(ctx, ctx->ikm, ctx->ikmlen); + + sender_ephempub = ecx_pubkey(sender_ephemkey); + recipient_pub = ecx_pubkey(ctx->recipient_key); + if (sender_ephempub == NULL || recipient_pub == NULL) + goto err; + + if (!derive_secret(ctx, secret, + sender_ephemkey, ctx->recipient_key, + ctx->sender_authkey, ctx->recipient_key, + sender_ephempub, recipient_pub)) + goto err; + + /* Return the public part of the ephemeral key */ + memcpy(enc, sender_ephempub, info->Nenc); + *enclen = info->Nenc; + *secretlen = info->Nsecret; + ret = 1; +err: + ossl_ecx_key_free(sender_ephemkey); + return ret; +} + +/* + * Do a DHKEM decapsulate operation. + * See Section 4.1 Decap() and Auth Decap() + * + * Params: + * ctx A context object holding the recipients private key and the + * optional senders auth public key. + * secret A buffer to return the calculated shared secret. Setting this to + * NULL can be used to return the secretlen. + * secretlen Passes in the max size of the secret buffer and returns the + * secret length. + * enc A buffer containing the senders ephemeral public key that was returned + * from dhkem_encap(). + * enclen The length in bytes of enc. + * Returns: 1 If the shared secret is returned or 0 on error. + */ +static int dhkem_decap(PROV_ECX_CTX *ctx, + unsigned char *secret, size_t *secretlen, + const unsigned char *enc, size_t enclen) +{ + int ret = 0; + ECX_KEY *recipient_privkey = ctx->recipient_key; + ECX_KEY *sender_ephempubkey = NULL; + const OSSL_HPKE_KEM_INFO *info = ctx->info; + unsigned char *recipient_pub; + + if (secret == NULL) { + *secretlen = info->Nsecret; + return 1; + } + if (*secretlen < info->Nsecret) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_LENGTH, "*secretlen too small"); + return 0; + } + if (enclen != info->Nenc) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY, "Invalid enc public key"); + return 0; + } + + /* Get the public part of the ephemeral key created by encap */ + sender_ephempubkey = ecxkey_pubfromdata(ctx, enc, enclen); + if (sender_ephempubkey == NULL) + goto err; + + recipient_pub = ecx_pubkey(recipient_privkey); + if (recipient_pub == NULL) + goto err; + + if (!derive_secret(ctx, secret, + ctx->recipient_key, sender_ephempubkey, + ctx->recipient_key, ctx->sender_authkey, + enc, recipient_pub)) + goto err; + + *secretlen = info->Nsecret; + ret = 1; +err: + ossl_ecx_key_free(sender_ephempubkey); + return ret; +} + +static int ecxkem_encapsulate(void *vctx, unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + PROV_ECX_CTX *ctx = (PROV_ECX_CTX *)vctx; + + switch (ctx->mode) { + case KEM_MODE_DHKEM: + return dhkem_encap(ctx, out, outlen, secret, secretlen); + default: + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); + return -2; + } +} + +static int ecxkem_decapsulate(void *vctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + PROV_ECX_CTX *ctx = (PROV_ECX_CTX *)vctx; + + switch (ctx->mode) { + case KEM_MODE_DHKEM: + return dhkem_decap(vctx, out, outlen, in, inlen); + default: + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); + return -2; + } +} + +const OSSL_DISPATCH ossl_ecx_asym_kem_functions[] = { + { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))ecxkem_newctx }, + { OSSL_FUNC_KEM_ENCAPSULATE_INIT, + (void (*)(void))ecxkem_encapsulate_init }, + { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))ecxkem_encapsulate }, + { OSSL_FUNC_KEM_DECAPSULATE_INIT, + (void (*)(void))ecxkem_decapsulate_init }, + { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))ecxkem_decapsulate }, + { OSSL_FUNC_KEM_FREECTX, (void (*)(void))ecxkem_freectx }, + { OSSL_FUNC_KEM_SET_CTX_PARAMS, + (void (*)(void))ecxkem_set_ctx_params }, + { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, + (void (*)(void))ecxkem_settable_ctx_params }, + { OSSL_FUNC_KEM_AUTH_ENCAPSULATE_INIT, + (void (*)(void))ecxkem_auth_encapsulate_init }, + { OSSL_FUNC_KEM_AUTH_DECAPSULATE_INIT, + (void (*)(void))ecxkem_auth_decapsulate_init }, + OSSL_DISPATCH_END +}; diff --git a/providers/implementations/kem/kem_util.c b/providers/implementations/kem/kem_util.c new file mode 100644 index 0000000000..1fd52e1c2d --- /dev/null +++ b/providers/implementations/kem/kem_util.c @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include /* for memcpy() */ +#include +#include +#include "eckem.h" + +typedef struct { + unsigned int id; + const char *mode; +} KEM_MODE; + +static const KEM_MODE eckem_modename_id_map[] = { + { KEM_MODE_DHKEM, OSSL_KEM_PARAM_OPERATION_DHKEM }, + { 0, NULL } +}; + +int ossl_eckem_modename2id(const char *name) +{ + size_t i; + + if (name == NULL) + return KEM_MODE_UNDEFINED; + + for (i = 0; eckem_modename_id_map[i].mode != NULL; ++i) { + if (OPENSSL_strcasecmp(name, eckem_modename_id_map[i].mode) == 0) + return eckem_modename_id_map[i].id; + } + return KEM_MODE_UNDEFINED; +} diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c index 365ae3d7d6..ff22ddffcf 100644 --- a/providers/implementations/kem/rsa_kem.c +++ b/providers/implementations/kem/rsa_kem.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -361,5 +361,5 @@ const OSSL_DISPATCH ossl_rsa_asym_kem_functions[] = { (void (*)(void))rsakem_set_ctx_params }, { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, (void (*)(void))rsakem_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index 0d86907aed..6fb506b5a9 100644 --- a/providers/implementations/keymgmt/build.info +++ b/providers/implementations/keymgmt/build.info @@ -30,8 +30,10 @@ IF[{- !$disabled{asm} -}] ENDIF IF[{- !$disabled{ec} -}] - SOURCE[$ECX_GOAL]=ecx_kmgmt.c - DEFINE[$ECX_GOAL]=$ECDEF + IF[{- !$disabled{ecx} -}] + SOURCE[$ECX_GOAL]=ecx_kmgmt.c + DEFINE[$ECX_GOAL]=$ECDEF + ENDIF ENDIF SOURCE[$RSA_GOAL]=rsa_kmgmt.c diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index c14b9765d1..795a3f2fab 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -403,7 +403,7 @@ static int dh_validate_private(const DH *dh) DH_get0_key(dh, NULL, &priv_key); if (priv_key == NULL) return 0; - return ossl_dh_check_priv_key(dh, priv_key, &status);; + return ossl_dh_check_priv_key(dh, priv_key, &status); } static int dh_validate(const void *keydata, int selection, int checktype) @@ -699,7 +699,7 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) return NULL; /* - * If a group name is selected then the type is group regardless of what the + * If a group name is selected then the type is group regardless of what * the user selected. This overrides rather than errors for backwards * compatibility. */ @@ -738,10 +738,8 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) } else if (gctx->hindex != 0) { ossl_ffc_params_set_h(ffc, gctx->hindex); } - if (gctx->mdname != NULL) { - if (!ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) - goto end; - } + if (gctx->mdname != NULL) + ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops); gctx->cb = osslcb; gctx->cbarg = cbarg; gencb = BN_GENCB_new(); @@ -846,7 +844,7 @@ const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; /* For any DH key, we use the "DH" algorithms regardless of sub-type. */ @@ -880,5 +878,5 @@ const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))dhx_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index 2f5742cfcc..a89d20822b 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -590,10 +590,9 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) } else if (gctx->hindex != 0) { ossl_ffc_params_set_h(ffc, gctx->hindex); } - if (gctx->mdname != NULL) { - if (!ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) - goto end; - } + if (gctx->mdname != NULL) + ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops); + if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { if (ossl_dsa_generate_ffc_parameters(dsa, gctx->gen_type, @@ -676,5 +675,5 @@ const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index a37cbbdba8..9390935394 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -222,7 +222,7 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, ecbits = EC_GROUP_order_bits(ecg); if (ecbits <= 0) goto err; - sz = (ecbits + 7 ) / 8; + sz = (ecbits + 7) / 8; if (!ossl_param_build_set_bn_pad(tmpl, params, OSSL_PKEY_PARAM_PRIV_KEY, @@ -989,6 +989,8 @@ struct ec_gen_ctx { int selection; int ecdh_mode; EC_GROUP *gen_group; + unsigned char *dhkem_ikm; + size_t dhkem_ikmlen; }; static void *ec_gen_init(void *provctx, int selection, @@ -1024,7 +1026,6 @@ static void *sm2_gen_init(void *provctx, int selection, return gctx; if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL) return gctx; - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ec_gen_cleanup(gctx); } return NULL; @@ -1122,6 +1123,9 @@ static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, gctx->gen_len); + COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm, + gctx->dhkem_ikmlen); + ret = 1; err: EC_GROUP_free(group); @@ -1221,6 +1225,7 @@ static const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx, OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), OSSL_PARAM_END }; @@ -1274,14 +1279,22 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ret = ec_gen_assign_group(ec, gctx->gen_group); /* Whether you want it or not, you get a keypair, not just one half */ - if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - ret = ret && EC_KEY_generate_key(ec); + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { +#ifndef FIPS_MODULE + if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) + ret = ret && ossl_ec_generate_key_dhkem(ec, gctx->dhkem_ikm, + gctx->dhkem_ikmlen); + else +#endif + ret = ret && EC_KEY_generate_key(ec); + } if (gctx->ecdh_mode != -1) ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode); if (gctx->group_check != NULL) - ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check); + ret = ret && ossl_ec_set_check_group_type_from_name(ec, + gctx->group_check); if (ret) return ec; err: @@ -1349,6 +1362,7 @@ static void ec_gen_cleanup(void *genctx) if (gctx == NULL) return; + OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen); EC_GROUP_free(gctx->gen_group); BN_free(gctx->p); BN_free(gctx->a); @@ -1430,7 +1444,7 @@ const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))ec_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; #ifndef FIPS_MODULE @@ -1461,7 +1475,7 @@ const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))sm2_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; # endif #endif diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 987d38456f..8a9fe1b21b 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -22,6 +22,7 @@ #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" +#include "prov/ecx.h" #ifdef S390X_EC_ASM # include "s390x_arch.h" # include /* For SHA512_DIGEST_LENGTH */ @@ -78,6 +79,8 @@ struct ecx_gen_ctx { char *propq; ECX_KEY_TYPE type; int selection; + unsigned char *dhkem_ikm; + size_t dhkem_ikmlen; }; #ifdef S390X_EC_ASM @@ -384,10 +387,8 @@ static int set_property_query(ECX_KEY *ecxkey, const char *propq) ecxkey->propq = NULL; if (propq != NULL) { ecxkey->propq = OPENSSL_strdup(propq); - if (ecxkey->propq == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ecxkey->propq == NULL) return 0; - } } return 1; } @@ -561,6 +562,16 @@ static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) if (gctx->propq == NULL) return 0; } + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM); + if (p != NULL) { + if (p->data_size != 0 && p->data != NULL) { + OPENSSL_free(gctx->dhkem_ikm); + gctx->dhkem_ikm = NULL; + if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0, + &gctx->dhkem_ikmlen)) + return 0; + } + } return 1; } @@ -571,6 +582,7 @@ static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx, static OSSL_PARAM settable[] = { OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), OSSL_PARAM_END }; return settable; @@ -585,7 +597,7 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) return NULL; if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0, gctx->propq)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); return NULL; } @@ -594,11 +606,24 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) return key; if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } - if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0) - goto err; +#ifndef FIPS_MODULE + if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { + if (gctx->type == ECX_KEY_TYPE_ED25519 + || gctx->type == ECX_KEY_TYPE_ED448) + goto err; + if (!ossl_ecx_dhkem_derive_private(key, privkey, + gctx->dhkem_ikm, gctx->dhkem_ikmlen)) + goto err; + } else +#endif + { + if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0) + goto err; + } + switch (gctx->type) { case ECX_KEY_TYPE_X25519: privkey[0] &= 248; @@ -694,6 +719,7 @@ static void ecx_gen_cleanup(void *genctx) { struct ecx_gen_ctx *gctx = genctx; + OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen); OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } @@ -817,7 +843,7 @@ static int ed448_validate(const void *keydata, int selection, int checktype) { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; MAKE_KEYMGMT_FUNCTIONS(x25519) @@ -840,7 +866,7 @@ static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx) unsigned char *privkey = NULL, *pubkey; if (key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } @@ -852,12 +878,23 @@ static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } - if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0) - goto err; +#ifndef FIPS_MODULE + if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { + if (gctx->type != ECX_KEY_TYPE_X25519) + goto err; + if (!ossl_ecx_dhkem_derive_private(key, privkey, + gctx->dhkem_ikm, gctx->dhkem_ikmlen)) + goto err; + } else +#endif + { + if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0) + goto err; + } privkey[0] &= 248; privkey[31] &= 127; @@ -886,7 +923,7 @@ static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx) unsigned char *privkey = NULL, *pubkey; if (key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } @@ -898,12 +935,23 @@ static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } - if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0) - goto err; +#ifndef FIPS_MODULE + if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { + if (gctx->type != ECX_KEY_TYPE_X448) + goto err; + if (!ossl_ecx_dhkem_derive_private(key, privkey, + gctx->dhkem_ikm, gctx->dhkem_ikmlen)) + goto err; + } else +#endif + { + if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0) + goto err; + } privkey[0] &= 252; privkey[55] |= 128; @@ -938,7 +986,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) int j; if (key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } @@ -950,7 +998,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } @@ -1005,7 +1053,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) EVP_MD *shake = NULL; if (key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } @@ -1017,7 +1065,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) privkey = ossl_ecx_key_allocate_privkey(key); if (privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); goto err; } diff --git a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c index 57fc7b5af0..deb4960006 100644 --- a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c +++ b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -37,13 +37,11 @@ KDF_DATA *ossl_kdf_data_new(void *provctx) if (kdfdata == NULL) return NULL; - kdfdata->lock = CRYPTO_THREAD_lock_new(); - if (kdfdata->lock == NULL) { + if (!CRYPTO_NEW_REF(&kdfdata->refcnt, 1)) { OPENSSL_free(kdfdata); return NULL; } kdfdata->libctx = PROV_LIBCTX_OF(provctx); - kdfdata->refcnt = 1; return kdfdata; } @@ -55,11 +53,11 @@ void ossl_kdf_data_free(KDF_DATA *kdfdata) if (kdfdata == NULL) return; - CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref, kdfdata->lock); + CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref); if (ref > 0) return; - CRYPTO_THREAD_lock_free(kdfdata->lock); + CRYPTO_FREE_REF(&kdfdata->refcnt); OPENSSL_free(kdfdata); } @@ -77,7 +75,7 @@ int ossl_kdf_data_up_ref(KDF_DATA *kdfdata) if (!ossl_prov_is_running()) return 0; - CRYPTO_UP_REF(&kdfdata->refcnt, &ref, kdfdata->lock); + CRYPTO_UP_REF(&kdfdata->refcnt, &ref); return 1; } @@ -100,5 +98,5 @@ const OSSL_DISPATCH ossl_kdf_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))kdf_newdata }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))kdf_freedata }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))kdf_has }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c index ba3a46324f..f952ebb227 100644 --- a/providers/implementations/keymgmt/mac_legacy_kmgmt.c +++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c @@ -72,13 +72,11 @@ MAC_KEY *ossl_mac_key_new(OSSL_LIB_CTX *libctx, int cmac) if (mackey == NULL) return NULL; - mackey->lock = CRYPTO_THREAD_lock_new(); - if (mackey->lock == NULL) { + if (!CRYPTO_NEW_REF(&mackey->refcnt, 1)) { OPENSSL_free(mackey); return NULL; } mackey->libctx = libctx; - mackey->refcnt = 1; mackey->cmac = cmac; return mackey; @@ -91,14 +89,14 @@ void ossl_mac_key_free(MAC_KEY *mackey) if (mackey == NULL) return; - CRYPTO_DOWN_REF(&mackey->refcnt, &ref, mackey->lock); + CRYPTO_DOWN_REF(&mackey->refcnt, &ref); if (ref > 0) return; OPENSSL_secure_clear_free(mackey->priv_key, mackey->priv_key_len); OPENSSL_free(mackey->properties); ossl_prov_cipher_reset(&mackey->cipher); - CRYPTO_THREAD_lock_free(mackey->lock); + CRYPTO_FREE_REF(&mackey->refcnt); OPENSSL_free(mackey); } @@ -116,7 +114,7 @@ int ossl_mac_key_up_ref(MAC_KEY *mackey) if (!ossl_prov_is_running()) return 0; - CRYPTO_UP_REF(&mackey->refcnt, &ref, mackey->lock); + CRYPTO_UP_REF(&mackey->refcnt, &ref); return 1; } @@ -194,10 +192,8 @@ static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[]) OPENSSL_secure_clear_free(key->priv_key, key->priv_key_len); /* allocate at least one byte to distinguish empty key from no key set */ key->priv_key = OPENSSL_secure_malloc(p->data_size > 0 ? p->data_size : 1); - if (key->priv_key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (key->priv_key == NULL) return 0; - } memcpy(key->priv_key, p->data, p->data_size); key->priv_key_len = p->data_size; } @@ -210,10 +206,8 @@ static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[]) } OPENSSL_free(key->properties); key->properties = OPENSSL_strdup(p->data); - if (key->properties == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (key->properties == NULL) return 0; - } } if (key->cmac && !ossl_prov_cipher_load_from_params(&key->cipher, params, @@ -432,10 +426,8 @@ static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[]) return 0; } gctx->priv_key = OPENSSL_secure_malloc(p->data_size); - if (gctx->priv_key == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (gctx->priv_key == NULL) return 0; - } memcpy(gctx->priv_key, p->data, p->data_size); gctx->priv_key_len = p->data_size; } @@ -489,7 +481,7 @@ static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg) return NULL; if ((key = ossl_mac_key_new(gctx->libctx, 0)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return NULL; } @@ -551,7 +543,7 @@ const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[] = { (void (*)(void))mac_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup }, - { 0, NULL } + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_cmac_legacy_keymgmt_functions[] = { @@ -573,6 +565,6 @@ const OSSL_DISPATCH ossl_cmac_legacy_keymgmt_functions[] = { (void (*)(void))cmac_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 3ba12c4889..c24cb8da88 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -715,7 +715,7 @@ const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { @@ -740,5 +740,5 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))rsa_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/blake2_mac_impl.c b/providers/implementations/macs/blake2_mac_impl.c index 3c6b0c2c0c..ec22e607a0 100644 --- a/providers/implementations/macs/blake2_mac_impl.c +++ b/providers/implementations/macs/blake2_mac_impl.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -250,5 +250,5 @@ const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))blake2_mac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))blake2_mac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c index fc9f911beb..1b3893598d 100644 --- a/providers/implementations/macs/cmac_prov.c +++ b/providers/implementations/macs/cmac_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -229,5 +229,5 @@ const OSSL_DISPATCH ossl_cmac_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))cmac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))cmac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/gmac_prov.c b/providers/implementations/macs/gmac_prov.c index 3dd38ecd7c..122df5f609 100644 --- a/providers/implementations/macs/gmac_prov.c +++ b/providers/implementations/macs/gmac_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -255,5 +255,5 @@ const OSSL_DISPATCH ossl_gmac_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))gmac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))gmac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c index 52ebb08b8f..a1f3c2db84 100644 --- a/providers/implementations/macs/hmac_prov.c +++ b/providers/implementations/macs/hmac_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,6 +21,8 @@ #include #include +#include "internal/ssl3_cbc.h" + #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" @@ -59,17 +61,6 @@ struct hmac_data_st { size_t tls_mac_out_size; }; -/* Defined in ssl/s3_cbc.c */ -int ssl3_cbc_digest_record(const EVP_MD *md, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char header[13], - const unsigned char *data, - size_t data_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - size_t mac_secret_length, char is_sslv3); - static void *hmac_new(void *provctx) { struct hmac_data_st *macctx; @@ -353,5 +344,5 @@ const OSSL_DISPATCH ossl_hmac_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))hmac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))hmac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c index 99e7c60a74..ddaab4ba86 100644 --- a/providers/implementations/macs/kmac_prov.c +++ b/providers/implementations/macs/kmac_prov.c @@ -310,10 +310,8 @@ static int kmac_init(void *vmacctx, const unsigned char *key, return 0; } out = OPENSSL_malloc(out_len); - if (out == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (out == NULL) return 0; - } res = bytepad(out, NULL, kmac_string, sizeof(kmac_string), kctx->custom, kctx->custom_len, block_len) && EVP_DigestUpdate(ctx, out, out_len) @@ -607,7 +605,7 @@ const OSSL_DISPATCH ossl_kmac128_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))kmac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_kmac256_functions[] = { @@ -623,5 +621,5 @@ const OSSL_DISPATCH ossl_kmac256_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))kmac_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))kmac_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c index f922802ea7..19974f9289 100644 --- a/providers/implementations/macs/poly1305_prov.c +++ b/providers/implementations/macs/poly1305_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -183,5 +183,5 @@ const OSSL_DISPATCH ossl_poly1305_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))poly1305_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))poly1305_set_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/macs/siphash_prov.c b/providers/implementations/macs/siphash_prov.c index a28cdb33ac..a54def3b85 100644 --- a/providers/implementations/macs/siphash_prov.c +++ b/providers/implementations/macs/siphash_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -233,5 +233,5 @@ const OSSL_DISPATCH ossl_siphash_functions[] = { { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))siphash_settable_ctx_params }, { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))siphash_set_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index ea55363bf8..1586288692 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -45,21 +45,20 @@ static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch, static int rand_drbg_restart(PROV_DRBG *drbg); +/* + * We interpret a call to this function as a hint only and ignore it. This + * occurs when the EVP layer thinks we should do some locking. In practice + * however we manage for ourselves when we take a lock or not on the basis + * of whether drbg->lock is present or not. + */ int ossl_drbg_lock(void *vctx) { - PROV_DRBG *drbg = vctx; - - if (drbg == NULL || drbg->lock == NULL) - return 1; - return CRYPTO_THREAD_write_lock(drbg->lock); + return 1; } +/* Interpreted as a hint only and ignored as for ossl_drbg_lock() */ void ossl_drbg_unlock(void *vctx) { - PROV_DRBG *drbg = vctx; - - if (drbg != NULL && drbg->lock != NULL) - CRYPTO_THREAD_unlock(drbg->lock); } static int ossl_drbg_lock_parent(PROV_DRBG *drbg) @@ -161,10 +160,8 @@ size_t ossl_drbg_get_seed(void *vdrbg, unsigned char **pout, /* Allocate storage */ buffer = OPENSSL_secure_malloc(bytes_needed); - if (buffer == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (buffer == NULL) return 0; - } /* * Get random data. Include our DRBG address as @@ -338,8 +335,9 @@ static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, unsigned char **pout, /* Use the built in nonce source plus some of our specifics */ memset(&data, 0, sizeof(data)); data.drbg = drbg; - CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count, - dngbl->rand_nonce_lock); + if (!CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count, + dngbl->rand_nonce_lock)) + return 0; return ossl_prov_get_nonce(drbg->provctx, pout, min_len, max_len, &data, sizeof(data)); } @@ -486,16 +484,12 @@ int ossl_prov_drbg_uninstantiate(PROV_DRBG *drbg) return 1; } -/* - * Reseed |drbg|, mixing in the specified data - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, - const unsigned char *ent, size_t ent_len, - const unsigned char *adin, size_t adinlen) +static int ossl_prov_drbg_reseed_unlocked(PROV_DRBG *drbg, + int prediction_resistance, + const unsigned char *ent, + size_t ent_len, + const unsigned char *adin, + size_t adinlen) { unsigned char *entropy = NULL; size_t entropylen = 0; @@ -597,12 +591,37 @@ int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, return 0; } +/* + * Reseed |drbg|, mixing in the specified data + * + * Acquires the drbg->lock for writing, if non-null. + * + * Returns 1 on success, 0 on failure. + */ +int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adinlen) +{ + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = ossl_prov_drbg_reseed_unlocked(drbg, prediction_resistance, ent, + ent_len, adin, adinlen); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; +} + /* * Generate |outlen| bytes into the buffer at |out|. Reseed if we need * to or if |prediction_resistance| is set. Additional input can be * sent in |adin| and |adinlen|. * - * Requires that drbg->lock is already locked for write, if non-null. + * Acquires the drbg->lock for writing if available * * Returns 1 on success, 0 on failure. * @@ -613,35 +632,39 @@ int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, { int fork_id; int reseed_required = 0; + int ret = 0; if (!ossl_prov_is_running()) return 0; + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + if (drbg->state != EVP_RAND_STATE_READY) { /* try to recover from previous errors */ rand_drbg_restart(drbg); if (drbg->state == EVP_RAND_STATE_ERROR) { ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE); - return 0; + goto err; } if (drbg->state == EVP_RAND_STATE_UNINITIALISED) { ERR_raise(ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED); - return 0; + goto err; } } if (strength > drbg->strength) { ERR_raise(ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH); - return 0; + goto err; } if (outlen > drbg->max_request) { ERR_raise(ERR_LIB_PROV, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG); - return 0; + goto err; } if (adinlen > drbg->max_adinlen) { ERR_raise(ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG); - return 0; + goto err; } fork_id = openssl_get_fork_id(); @@ -666,10 +689,10 @@ int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, reseed_required = 1; if (reseed_required || prediction_resistance) { - if (!ossl_prov_drbg_reseed(drbg, prediction_resistance, NULL, 0, - adin, adinlen)) { + if (!ossl_prov_drbg_reseed_unlocked(drbg, prediction_resistance, NULL, + 0, adin, adinlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_RESEED_ERROR); - return 0; + goto err; } adin = NULL; adinlen = 0; @@ -678,12 +701,17 @@ int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, if (!drbg->generate(drbg, out, outlen, adin, adinlen)) { drbg->state = EVP_RAND_STATE_ERROR; ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR); - return 0; + goto err; } drbg->generate_counter++; - return 1; + ret = 1; + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } /* @@ -778,10 +806,8 @@ PROV_DRBG *ossl_rand_drbg_new return NULL; drbg = OPENSSL_zalloc(sizeof(*drbg)); - if (drbg == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (drbg == NULL) return NULL; - } drbg->provctx = provctx; drbg->instantiate = instantiate; @@ -852,6 +878,10 @@ void ossl_rand_drbg_free(PROV_DRBG *drbg) OPENSSL_free(drbg); } +/* + * Helper function called by internal DRBG implementations. Assumes that at + * least a read lock has been taken on drbg->lock + */ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]) { OSSL_PARAM *p; @@ -864,10 +894,6 @@ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_int(p, drbg->strength)) return 0; - p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); - if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_request)) - return 0; - p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_ENTROPYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_entropylen)) return 0; @@ -904,10 +930,43 @@ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval)) return 0; + return 1; +} + +/* + * Helper function to get certain params that require no lock to obtain. Sets + * *complete to 1 if all the params were processed, or 0 otherwise + */ +int ossl_drbg_get_ctx_params_no_lock(PROV_DRBG *drbg, OSSL_PARAM params[], + int *complete) +{ + size_t cnt = 0; + OSSL_PARAM *p; + + /* This value never changes once set */ + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); + if (p != NULL) { + if (!OSSL_PARAM_set_size_t(p, drbg->max_request)) + return 0; + cnt++; + } + + /* + * Can be changed by multiple threads, but we tolerate inaccuracies in this + * value. + */ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER); - if (p != NULL - && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter))) - return 0; + if (p != NULL) { + if (!OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter))) + return 0; + cnt++; + } + + if (params[cnt].key == NULL) + *complete = 1; + else + *complete = 0; + return 1; } diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c index 451113c4d1..cc4ed25cfd 100644 --- a/providers/implementations/rands/drbg_ctr.c +++ b/providers/implementations/rands/drbg_ctr.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,6 +33,8 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params; static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params; static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization; +static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]); + /* * The state of a DRBG AES-CTR. */ @@ -330,11 +332,20 @@ static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength, const OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret = 0; - if (!ossl_prov_is_running() || !drbg_ctr_set_ctx_params(drbg, params)) + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) return 0; - return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + + if (!ossl_prov_is_running() + || !drbg_ctr_set_ctx_params_locked(drbg, params)) + goto err; + ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } static int drbg_ctr_reseed(PROV_DRBG *drbg, @@ -473,21 +484,41 @@ static int drbg_ctr_uninstantiate(PROV_DRBG *drbg) static int drbg_ctr_uninstantiate_wrapper(void *vdrbg) { - return drbg_ctr_uninstantiate((PROV_DRBG *)vdrbg); + PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_ctr_uninstantiate(drbg); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static int drbg_ctr_verify_zeroization(void *vdrbg) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; + int ret = 0; - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->K); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->V); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->bltmp); - PROV_DRBG_VERYIFY_ZEROIZATION(ctr->KX); - if (ctr->bltmp_pos != 0) + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) return 0; - return 1; + + PROV_DRBG_VERIFY_ZEROIZATION(ctr->K); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->V); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp); + PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX); + if (ctr->bltmp_pos != 0) + goto err; + + ret = 1; + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } static int drbg_ctr_init_lengths(PROV_DRBG *drbg) @@ -538,7 +569,7 @@ static int drbg_ctr_init(PROV_DRBG *drbg) if (ctr->ctx_ctr == NULL) ctr->ctx_ctr = EVP_CIPHER_CTX_new(); if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); goto err; } @@ -565,7 +596,7 @@ static int drbg_ctr_init(PROV_DRBG *drbg) if (ctr->ctx_df == NULL) ctr->ctx_df = EVP_CIPHER_CTX_new(); if (ctr->ctx_df == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); goto err; } /* Set key schedule for df_key */ @@ -589,10 +620,8 @@ static int drbg_ctr_new(PROV_DRBG *drbg) PROV_DRBG_CTR *ctr; ctr = OPENSSL_secure_zalloc(sizeof(*ctr)); - if (ctr == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (ctr == NULL) return 0; - } ctr->use_df = 1; drbg->data = ctr; @@ -629,20 +658,35 @@ static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; OSSL_PARAM *p; + int ret = 0, complete = 0; + + if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete)) + return 0; + + if (complete) + return 1; + + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) + return 0; p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF); if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df)) - return 0; + goto err; p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER); if (p != NULL) { if (ctr->cipher_ctr == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_CIPHER_get0_name(ctr->cipher_ctr))) - return 0; + goto err; } - return ossl_drbg_get_ctx_params(drbg, params); + ret = ossl_drbg_get_ctx_params(drbg, params); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx, @@ -657,7 +701,7 @@ static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx, return known_gettable_ctx_params; } -static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data; @@ -693,10 +737,8 @@ static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER); return 0; } - if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) return 0; - } strcpy(ecb + p->data_size - ecb_str_len, "ECB"); EVP_CIPHER_free(ctr->cipher_ecb); EVP_CIPHER_free(ctr->cipher_ctr); @@ -716,6 +758,22 @@ static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return ossl_drbg_set_ctx_params(ctx, params); } +static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_DRBG *drbg = (PROV_DRBG *)vctx; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_ctr_set_ctx_params_locked(vctx, params); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; +} + static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx, ossl_unused void *provctx) { @@ -751,5 +809,5 @@ const OSSL_DISPATCH ossl_drbg_ctr_functions[] = { (void(*)(void))drbg_ctr_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed }, { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index fb824abfa6..a216910d83 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -35,6 +35,8 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hash_gettable_ctx_params; static OSSL_FUNC_rand_get_ctx_params_fn drbg_hash_get_ctx_params; static OSSL_FUNC_rand_verify_zeroization_fn drbg_hash_verify_zeroization; +static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]); + /* 888 bits from SP800-90Ar1 10.1 table 2 */ #define HASH_PRNG_MAX_SEEDLEN (888/8) @@ -113,7 +115,7 @@ static int hash_df(PROV_DRBG *drbg, unsigned char *out, memcpy(out, vtmp, outlen); OPENSSL_cleanse(vtmp, hash->blocklen); break; - } else if(!EVP_DigestFinal(ctx, out, NULL)) { + } else if (!EVP_DigestFinal(ctx, out, NULL)) { return 0; } @@ -164,7 +166,7 @@ static int add_bytes(PROV_DRBG *drbg, unsigned char *dst, /* Add the carry to the top of the dst if inlen is not the same size */ for (i = drbg->seedlen - inlen; i > 0; --i, d--) { *d += 1; /* Carry can only be 1 */ - if (*d != 0) /* exit if carry doesnt propagate to the next byte */ + if (*d != 0) /* exit if carry doesn't propagate to the next byte */ break; } } @@ -212,7 +214,7 @@ static int hash_gen(PROV_DRBG *drbg, unsigned char *out, size_t outlen) if (outlen == 0) return 1; memcpy(hash->vtmp, hash->V, drbg->seedlen); - for(;;) { + for (;;) { if (!EVP_DigestInit_ex(hash->ctx, ossl_prov_digest_md(&hash->digest), NULL) || !EVP_DigestUpdate(hash->ctx, hash->vtmp, drbg->seedlen)) @@ -270,11 +272,20 @@ static int drbg_hash_instantiate_wrapper(void *vdrbg, unsigned int strength, const OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret = 0; - if (!ossl_prov_is_running() || !drbg_hash_set_ctx_params(drbg, params)) + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) return 0; - return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + + if (!ossl_prov_is_running() + || !drbg_hash_set_ctx_params_locked(drbg, params)) + goto err; + ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } /* @@ -371,18 +382,38 @@ static int drbg_hash_uninstantiate(PROV_DRBG *drbg) static int drbg_hash_uninstantiate_wrapper(void *vdrbg) { - return drbg_hash_uninstantiate((PROV_DRBG *)vdrbg); + PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_hash_uninstantiate(drbg); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static int drbg_hash_verify_zeroization(void *vdrbg) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data; + int ret = 0; - PROV_DRBG_VERYIFY_ZEROIZATION(hash->V); - PROV_DRBG_VERYIFY_ZEROIZATION(hash->C); - PROV_DRBG_VERYIFY_ZEROIZATION(hash->vtmp); - return 1; + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) + return 0; + + PROV_DRBG_VERIFY_ZEROIZATION(hash->V); + PROV_DRBG_VERIFY_ZEROIZATION(hash->C); + PROV_DRBG_VERIFY_ZEROIZATION(hash->vtmp); + + ret = 1; + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } static int drbg_hash_new(PROV_DRBG *ctx) @@ -390,10 +421,8 @@ static int drbg_hash_new(PROV_DRBG *ctx) PROV_DRBG_HASH *hash; hash = OPENSSL_secure_zalloc(sizeof(*hash)); - if (hash == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (hash == NULL) return 0; - } ctx->data = hash; ctx->seedlen = HASH_PRNG_MAX_SEEDLEN; @@ -434,15 +463,30 @@ static int drbg_hash_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data; const EVP_MD *md; OSSL_PARAM *p; + int ret = 0, complete = 0; + + if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete)) + return 0; + + if (complete) + return 1; + + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) + return 0; p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST); if (p != NULL) { md = ossl_prov_digest_md(&hash->digest); if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md))) - return 0; + goto err; } - return ossl_drbg_get_ctx_params(drbg, params); + ret = ossl_drbg_get_ctx_params(drbg, params); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *vctx, @@ -456,7 +500,7 @@ static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *vctx, return known_gettable_ctx_params; } -static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)ctx->data; @@ -489,6 +533,22 @@ static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return ossl_drbg_set_ctx_params(ctx, params); } +static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_DRBG *drbg = (PROV_DRBG *)vctx; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_hash_set_ctx_params_locked(vctx, params); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; +} + static const OSSL_PARAM *drbg_hash_settable_ctx_params(ossl_unused void *vctx, ossl_unused void *p_ctx) { @@ -523,5 +583,5 @@ const OSSL_DISPATCH ossl_drbg_hash_functions[] = { (void(*)(void))drbg_hash_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed }, { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c index 664a074639..74d47886b4 100644 --- a/providers/implementations/rands/drbg_hmac.c +++ b/providers/implementations/rands/drbg_hmac.c @@ -13,11 +13,11 @@ #include #include #include -#include "prov/provider_util.h" #include "internal/thread_once.h" #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "prov/hmac_drbg.h" #include "drbg_local.h" static OSSL_FUNC_rand_newctx_fn drbg_hmac_new_wrapper; @@ -32,13 +32,7 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hmac_gettable_ctx_params; static OSSL_FUNC_rand_get_ctx_params_fn drbg_hmac_get_ctx_params; static OSSL_FUNC_rand_verify_zeroization_fn drbg_hmac_verify_zeroization; -typedef struct rand_drbg_hmac_st { - EVP_MAC_CTX *ctx; /* H(x) = HMAC_hash OR H(x) = KMAC */ - PROV_DIGEST digest; /* H(x) = hash(x) */ - size_t blocklen; - unsigned char K[EVP_MAX_MD_SIZE]; - unsigned char V[EVP_MAX_MD_SIZE]; -} PROV_DRBG_HMAC; +static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]); /* * Called twice by SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process. @@ -91,13 +85,11 @@ static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte, * * Returns zero if an error occurs otherwise it returns 1. */ -static int drbg_hmac_update(PROV_DRBG *drbg, +static int drbg_hmac_update(PROV_DRBG_HMAC *hmac, const unsigned char *in1, size_t in1len, const unsigned char *in2, size_t in2len, const unsigned char *in3, size_t in3len) { - PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; - /* (Steps 1-2) K = HMAC(K, V||0x00||provided_data). V = HMAC(K,V) */ if (!do_hmac(hmac, 0x00, in1, in1len, in2, in2len, in3, in3len)) return 0; @@ -119,13 +111,11 @@ static int drbg_hmac_update(PROV_DRBG *drbg, * * Returns zero if an error occurs otherwise it returns 1. */ -static int drbg_hmac_instantiate(PROV_DRBG *drbg, - const unsigned char *ent, size_t ent_len, - const unsigned char *nonce, size_t nonce_len, - const unsigned char *pstr, size_t pstr_len) +int ossl_drbg_hmac_init(PROV_DRBG_HMAC *hmac, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) { - PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; - if (hmac->ctx == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC); return 0; @@ -136,9 +126,17 @@ static int drbg_hmac_instantiate(PROV_DRBG *drbg, /* (Step 3) V = 0x01 01...01 */ memset(hmac->V, 0x01, hmac->blocklen); /* (Step 4) (K,V) = HMAC_DRBG_Update(entropy||nonce||pers string, K, V) */ - return drbg_hmac_update(drbg, ent, ent_len, nonce, nonce_len, pstr, + return drbg_hmac_update(hmac, ent, ent_len, nonce, nonce_len, pstr, pstr_len); } +static int drbg_hmac_instantiate(PROV_DRBG *drbg, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) +{ + return ossl_drbg_hmac_init((PROV_DRBG_HMAC *)drbg->data, ent, ent_len, + nonce, nonce_len, pstr, pstr_len); +} static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength, int prediction_resistance, @@ -147,13 +145,23 @@ static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength, const OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret = 0; - if (!ossl_prov_is_running() || !drbg_hmac_set_ctx_params(drbg, params)) + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) return 0; - return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + + if (!ossl_prov_is_running() + || !drbg_hmac_set_ctx_params_locked(drbg, params)) + goto err; + ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } + /* * SP800-90Ar1 10.1.2.4 HMAC_DRBG_Reseed_Process: * @@ -168,8 +176,10 @@ static int drbg_hmac_reseed(PROV_DRBG *drbg, const unsigned char *ent, size_t ent_len, const unsigned char *adin, size_t adin_len) { + PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; + /* (Step 2) (K,V) = HMAC_DRBG_Update(entropy||additional_input, K, V) */ - return drbg_hmac_update(drbg, ent, ent_len, adin, adin_len, NULL, 0); + return drbg_hmac_update(hmac, ent, ent_len, adin, adin_len, NULL, 0); } static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance, @@ -191,18 +201,17 @@ static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance, * * Returns zero if an error occurs otherwise it returns 1. */ -static int drbg_hmac_generate(PROV_DRBG *drbg, - unsigned char *out, size_t outlen, - const unsigned char *adin, size_t adin_len) +int ossl_drbg_hmac_generate(PROV_DRBG_HMAC *hmac, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) { - PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; EVP_MAC_CTX *ctx = hmac->ctx; const unsigned char *temp = hmac->V; /* (Step 2) if adin != NULL then (K,V) = HMAC_DRBG_Update(adin, K, V) */ if (adin != NULL && adin_len > 0 - && !drbg_hmac_update(drbg, adin, adin_len, NULL, 0, NULL, 0)) + && !drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0)) return 0; /* @@ -231,14 +240,22 @@ static int drbg_hmac_generate(PROV_DRBG *drbg, outlen -= hmac->blocklen; } /* (Step 6) (K,V) = HMAC_DRBG_Update(adin, K, V) */ - if (!drbg_hmac_update(drbg, adin, adin_len, NULL, 0, NULL, 0)) + if (!drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0)) return 0; return 1; } -static int drbg_hmac_generate_wrapper - (void *vdrbg, unsigned char *out, size_t outlen, unsigned int strength, +static int drbg_hmac_generate(PROV_DRBG *drbg, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) +{ + return ossl_drbg_hmac_generate((PROV_DRBG_HMAC *)drbg->data, out, outlen, + adin, adin_len); +} + +static int drbg_hmac_generate_wrapper(void *vdrbg, + unsigned char *out, size_t outlen, unsigned int strength, int prediction_resistance, const unsigned char *adin, size_t adin_len) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; @@ -258,17 +275,37 @@ static int drbg_hmac_uninstantiate(PROV_DRBG *drbg) static int drbg_hmac_uninstantiate_wrapper(void *vdrbg) { - return drbg_hmac_uninstantiate((PROV_DRBG *)vdrbg); + PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_hmac_uninstantiate(drbg); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static int drbg_hmac_verify_zeroization(void *vdrbg) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; + int ret = 0; - PROV_DRBG_VERYIFY_ZEROIZATION(hmac->K); - PROV_DRBG_VERYIFY_ZEROIZATION(hmac->V); - return 1; + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) + return 0; + + PROV_DRBG_VERIFY_ZEROIZATION(hmac->K); + PROV_DRBG_VERIFY_ZEROIZATION(hmac->V); + + ret = 1; + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + return ret; } static int drbg_hmac_new(PROV_DRBG *drbg) @@ -276,10 +313,8 @@ static int drbg_hmac_new(PROV_DRBG *drbg) PROV_DRBG_HMAC *hmac; hmac = OPENSSL_secure_zalloc(sizeof(*hmac)); - if (hmac == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (hmac == NULL) return 0; - } drbg->data = hmac; /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */ @@ -321,24 +356,39 @@ static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) const char *name; const EVP_MD *md; OSSL_PARAM *p; + int ret = 0, complete = 0; + + if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete)) + return 0; + + if (complete) + return 1; + + if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) + return 0; p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAC); if (p != NULL) { if (hmac->ctx == NULL) - return 0; + goto err; name = EVP_MAC_get0_name(EVP_MAC_CTX_get0_mac(hmac->ctx)); if (!OSSL_PARAM_set_utf8_string(p, name)) - return 0; + goto err; } p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST); if (p != NULL) { md = ossl_prov_digest_md(&hmac->digest); if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md))) - return 0; + goto err; } - return ossl_drbg_get_ctx_params(drbg, params); + ret = ossl_drbg_get_ctx_params(drbg, params); + err: + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; } static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx, @@ -353,7 +403,7 @@ static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx, return known_gettable_ctx_params; } -static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data; @@ -386,6 +436,22 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return ossl_drbg_set_ctx_params(ctx, params); } +static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_DRBG *drbg = (PROV_DRBG *)vctx; + int ret; + + if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) + return 0; + + ret = drbg_hmac_set_ctx_params_locked(vctx, params); + + if (drbg->lock != NULL) + CRYPTO_THREAD_unlock(drbg->lock); + + return ret; +} + static const OSSL_PARAM *drbg_hmac_settable_ctx_params(ossl_unused void *vctx, ossl_unused void *p_ctx) { @@ -421,5 +487,5 @@ const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = { (void(*)(void))drbg_hmac_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed }, { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h index 3b5417b43b..50f98a0b61 100644 --- a/providers/implementations/rands/drbg_local.h +++ b/providers/implementations/rands/drbg_local.h @@ -206,13 +206,13 @@ OSSL_FUNC_rand_get_seed_fn ossl_drbg_get_seed; OSSL_FUNC_rand_clear_seed_fn ossl_drbg_clear_seed; /* Verify that an array of numeric values is all zero */ -#define PROV_DRBG_VERYIFY_ZEROIZATION(v) \ +#define PROV_DRBG_VERIFY_ZEROIZATION(v) \ { \ size_t i; \ \ for (i = 0; i < OSSL_NELEM(v); i++) \ if ((v)[i] != 0) \ - return 0; \ + goto err; \ } /* locking api */ @@ -222,9 +222,11 @@ OSSL_FUNC_rand_unlock_fn ossl_drbg_unlock; /* Common parameters for all of our DRBGs */ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]); +int ossl_drbg_get_ctx_params_no_lock(PROV_DRBG *drbg, OSSL_PARAM params[], + int *complete); int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]); -#define OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON \ +#define OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON \ OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL), \ OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL) diff --git a/providers/implementations/rands/seed_src.c b/providers/implementations/rands/seed_src.c index 5c83a479c0..e8f7ec9efc 100644 --- a/providers/implementations/rands/seed_src.c +++ b/providers/implementations/rands/seed_src.c @@ -53,10 +53,8 @@ static void *seed_src_new(void *provctx, void *parent, } s = OPENSSL_zalloc(sizeof(*s)); - if (s == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (s == NULL) return NULL; - } s->provctx = provctx; s->state = EVP_RAND_STATE_UNINITIALISED; @@ -106,7 +104,7 @@ static int seed_src_generate(void *vseed, unsigned char *out, size_t outlen, pool = ossl_rand_pool_new(strength, 1, outlen, outlen); if (pool == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_RAND_LIB); return 0; } @@ -246,5 +244,5 @@ const OSSL_DISPATCH ossl_seed_src_functions[] = { (void(*)(void))seed_src_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))seed_get_seed }, { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))seed_clear_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/rands/seeding/rand_cpu_arm64.c b/providers/implementations/rands/seeding/rand_cpu_arm64.c index 778ec395ce..a8530e02b5 100644 --- a/providers/implementations/rands/seeding/rand_cpu_arm64.c +++ b/providers/implementations/rands/seeding/rand_cpu_arm64.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index cd02a0236d..9a936d800d 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -175,7 +175,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) /* Get wall clock time, take 8 bits. */ clock_gettime(CLOCK_REALTIME, &ts); v = (unsigned char)(ts.tv_nsec & 0xFF); - ossl_rand_pool_add(pool, arg, &v, sizeof(v) , 2); + ossl_rand_pool_add(pool, arg, &v, sizeof(v), 2); } return ossl_rand_pool_entropy_available(pool); } @@ -319,9 +319,7 @@ static ssize_t sysctl_random(char *buf, size_t buflen) # define __NR_getrandom 352 # elif defined(__cris__) # define __NR_getrandom 356 -# elif defined(__aarch64__) -# define __NR_getrandom 278 -# else /* generic */ +# else /* generic (f.e. aarch64, loongarch, loongarch64) */ # define __NR_getrandom 278 # endif # endif @@ -397,6 +395,10 @@ static ssize_t syscall_random(void *buf, size_t buflen) # elif (defined(__DragonFly__) && __DragonFly_version >= 500700) \ || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000) return getrandom(buf, buflen, 0); +# elif defined(__wasi__) + if (getentropy(buf, buflen) == 0) + return (ssize_t)buflen; + return -1; # else errno = ENOSYS; return -1; @@ -508,7 +510,7 @@ static int wait_random_seeded(void) * So the handle might have been closed or even reused for opening * another file. */ -static int check_random_device(struct random_device * rd) +static int check_random_device(struct random_device *rd) { struct stat st; @@ -526,7 +528,7 @@ static int check_random_device(struct random_device * rd) static int get_random_device(size_t n) { struct stat st; - struct random_device * rd = &random_devices[n]; + struct random_device *rd = &random_devices[n]; /* reuse existing file descriptor if it is (still) valid */ if (check_random_device(rd)) @@ -555,7 +557,7 @@ static int get_random_device(size_t n) */ static void close_random_device(size_t n) { - struct random_device * rd = &random_devices[n]; + struct random_device *rd = &random_devices[n]; if (check_random_device(rd)) close(rd->fd); diff --git a/providers/implementations/rands/seeding/rand_vms.c b/providers/implementations/rands/seeding/rand_vms.c index 713718189d..4ff879491a 100644 --- a/providers/implementations/rands/seeding/rand_vms.c +++ b/providers/implementations/rands/seeding/rand_vms.c @@ -389,7 +389,7 @@ size_t data_collect_method(RAND_POOL *pool) uint32_t status; uint32_t efn; IOSB iosb; - $DESCRIPTOR(SYSDEVICE,"SYS$SYSDEVICE:"); + $DESCRIPTOR(SYSDEVICE, "SYS$SYSDEVICE:"); if ((status = sys$getdviw(EFN$C_ENF, 0, &SYSDEVICE, DVI_items, 0, 0, 0, 0, 0)) != SS$_NORMAL) { diff --git a/providers/implementations/rands/seeding/rand_vxworks.c b/providers/implementations/rands/seeding/rand_vxworks.c index 04e8e39252..a28fbd7997 100644 --- a/providers/implementations/rands/seeding/rand_vxworks.c +++ b/providers/implementations/rands/seeding/rand_vxworks.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -116,7 +116,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) RANDOM_NUM_GEN_STATUS status = randStatus(); if ((status == RANDOM_NUM_GEN_ENOUGH_ENTROPY) - || (status == RANDOM_NUM_GEN_MAX_ENTROPY) ) { + || (status == RANDOM_NUM_GEN_MAX_ENTROPY)) { result = randBytes(buffer, bytes_needed); if (result == OK) ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); diff --git a/providers/implementations/rands/seeding/rand_win.c b/providers/implementations/rands/seeding/rand_win.c index 7a9e971dfb..ee2d3e4d7f 100644 --- a/providers/implementations/rands/seeding/rand_win.c +++ b/providers/implementations/rands/seeding/rand_win.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index d0468437e3..57b36469ca 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -342,5 +342,5 @@ const OSSL_DISPATCH ossl_test_rng_functions[] = { { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, (void(*)(void))test_rng_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))test_rng_get_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index fd3be7f3b9..6987a12250 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -12,7 +12,10 @@ IF[{- !$disabled{dsa} -}] ENDIF IF[{- !$disabled{ec} -}] - SOURCE[$EC_GOAL]=eddsa_sig.c ecdsa_sig.c + SOURCE[$EC_GOAL]=ecdsa_sig.c + IF[{- !$disabled{ecx} -}] + SOURCE[$EC_GOAL]=eddsa_sig.c + ENDIF ENDIF IF[{- !$disabled{sm2} -}] diff --git a/providers/implementations/signature/dsa_sig.c b/providers/implementations/signature/dsa_sig.c index 70d0ea5d24..b89a0f6836 100644 --- a/providers/implementations/signature/dsa_sig.c +++ b/providers/implementations/signature/dsa_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -74,6 +74,9 @@ typedef struct { */ unsigned int flag_allow_md : 1; + /* If this is set to 1 then the generated k is not random */ + unsigned int nonce_type; + char mdname[OSSL_MAX_NAME_SIZE]; /* The Algorithm Identifier of the combined signature algorithm */ @@ -111,7 +114,6 @@ static void *dsa_newctx(void *provctx, const char *propq) if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(pdsactx); pdsactx = NULL; - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } return pdsactx; } @@ -250,7 +252,9 @@ static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, if (mdsize != 0 && tbslen != mdsize) return 0; - ret = ossl_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa); + ret = ossl_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa, + pdsactx->nonce_type, pdsactx->mdname, + pdsactx->libctx, pdsactx->propq); if (ret <= 0) return 0; @@ -457,12 +461,17 @@ static int dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdsactx->mdname)) return 0; + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); + if (p != NULL && !OSSL_PARAM_set_uint(p, pdsactx->nonce_type)) + return 0; + return 1; } static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), OSSL_PARAM_END }; @@ -498,6 +507,10 @@ static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) if (!dsa_setup_md(pdsactx, mdname, mdprops)) return 0; } + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); + if (p != NULL + && !OSSL_PARAM_get_uint(p, &pdsactx->nonce_type)) + return 0; return 1; } @@ -505,6 +518,7 @@ static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), OSSL_PARAM_END }; @@ -596,5 +610,5 @@ const OSSL_DISPATCH ossl_dsa_signature_functions[] = { (void (*)(void))dsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))dsa_settable_ctx_md_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/signature/ecdsa_sig.c b/providers/implementations/signature/ecdsa_sig.c index 865d49d100..fe65ed8dc6 100644 --- a/providers/implementations/signature/ecdsa_sig.c +++ b/providers/implementations/signature/ecdsa_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,6 +25,7 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "internal/cryptlib.h" +#include "internal/deterministic_nonce.h" #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" @@ -102,6 +103,8 @@ typedef struct { */ unsigned int kattest; #endif + /* If this is set then the generated k is not random */ + unsigned int nonce_type; } PROV_ECDSA_CTX; static void *ecdsa_newctx(void *provctx, const char *propq) @@ -120,7 +123,6 @@ static void *ecdsa_newctx(void *provctx, const char *propq) if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(ctx); ctx = NULL; - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } return ctx; } @@ -193,7 +195,15 @@ static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen, if (ctx->mdsize != 0 && tbslen != ctx->mdsize) return 0; - ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r, ctx->ec); + if (ctx->nonce_type != 0) { + ret = ossl_ecdsa_deterministic_sign(tbs, tbslen, sig, &sltmp, + ctx->ec, ctx->nonce_type, + ctx->mdname, + ctx->libctx, ctx->propq); + } else { + ret = ECDSA_sign_ex(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r, + ctx->ec); + } if (ret <= 0) return 0; @@ -457,6 +467,10 @@ static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params) : EVP_MD_get0_name(ctx->md))) return 0; + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); + if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->nonce_type)) + return 0; + return 1; } @@ -464,6 +478,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), OSSL_PARAM_END }; @@ -514,6 +529,10 @@ static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; ctx->mdsize = mdsize; } + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE); + if (p != NULL + && !OSSL_PARAM_get_uint(p, &ctx->nonce_type)) + return 0; return 1; } @@ -523,6 +542,7 @@ static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), + OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_NONCE_TYPE, NULL), OSSL_PARAM_END }; @@ -615,5 +635,5 @@ const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = { (void (*)(void))ecdsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))ecdsa_settable_ctx_md_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/signature/eddsa_sig.c b/providers/implementations/signature/eddsa_sig.c index 3c9b306ea6..8594af39e1 100644 --- a/providers/implementations/signature/eddsa_sig.c +++ b/providers/implementations/signature/eddsa_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -43,6 +43,24 @@ static int s390x_ed448_digestverify(const ECX_KEY *edkey, #endif /* S390X_EC_ASM */ +enum ID_EdDSA_INSTANCE { + ID_NOT_SET = 0, + ID_Ed25519, + ID_Ed25519ctx, + ID_Ed25519ph, + ID_Ed448, + ID_Ed448ph +}; + +#define SN_Ed25519 "Ed25519" +#define SN_Ed25519ph "Ed25519ph" +#define SN_Ed25519ctx "Ed25519ctx" +#define SN_Ed448 "Ed448" +#define SN_Ed448ph "Ed448ph" + +#define EDDSA_MAX_CONTEXT_STRING_LEN 255 +#define EDDSA_PREHASH_OUTPUT_LEN 64 + static OSSL_FUNC_signature_newctx_fn eddsa_newctx; static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init; static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign; @@ -53,6 +71,55 @@ static OSSL_FUNC_signature_freectx_fn eddsa_freectx; static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx; static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params; static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params; +static OSSL_FUNC_signature_set_ctx_params_fn eddsa_set_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_ctx_params; + +/* there are five EdDSA instances: + + Ed25519 + Ed25519ph + Ed25519ctx + Ed448 + Ed448ph + + Quoting from RFC 8032, Section 5.1: + + For Ed25519, dom2(f,c) is the empty string. The phflag value is + irrelevant. The context (if present at all) MUST be empty. This + causes the scheme to be one and the same with the Ed25519 scheme + published earlier. + + For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty. + + For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input + is hashed using SHA-512 before signing with Ed25519. + + Quoting from RFC 8032, Section 5.2: + + Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag + being 1, i.e., the input is hashed before signing with Ed448 with a + hash constant modified. + + Value of context is set by signer and verifier (maximum of 255 + octets; the default is empty string) and has to match octet by octet + for verification to be successful. + + Quoting from RFC 8032, Section 2: + + dom2(x, y) The blank octet string when signing or verifying + Ed25519. Otherwise, the octet string: "SigEd25519 no + Ed25519 collisions" || octet(x) || octet(OLEN(y)) || + y, where x is in range 0-255 and y is an octet string + of at most 255 octets. "SigEd25519 no Ed25519 + collisions" is in ASCII (32 octets). + + dom4(x, y) The octet string "SigEd448" || octet(x) || + octet(OLEN(y)) || y, where x is in range 0-255 and y + is an octet string of at most 255 octets. "SigEd448" + is in ASCII (8 octets). + + Note above that x is the pre-hash flag, and y is the context string. +*/ typedef struct { OSSL_LIB_CTX *libctx; @@ -62,6 +129,19 @@ typedef struct { unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; unsigned char *aid; size_t aid_len; + + /* id indicating the EdDSA instance */ + int instance_id; + + unsigned int dom2_flag : 1; + unsigned int prehash_flag : 1; + + /* indicates that a non-empty context string is required, as in Ed25519ctx */ + unsigned int context_string_flag : 1; + + unsigned char context_string[EDDSA_MAX_CONTEXT_STRING_LEN]; + size_t context_string_len; + } PROV_EDDSA_CTX; static void *eddsa_newctx(void *provctx, const char *propq_unused) @@ -72,10 +152,8 @@ static void *eddsa_newctx(void *provctx, const char *propq_unused) return NULL; peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); - if (peddsactx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (peddsactx == NULL) return NULL; - } peddsactx->libctx = PROV_LIBCTX_OF(provctx); @@ -84,7 +162,7 @@ static void *eddsa_newctx(void *provctx, const char *propq_unused) static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, void *vedkey, - ossl_unused const OSSL_PARAM params[]) + const OSSL_PARAM params[]) { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; ECX_KEY *edkey = (ECX_KEY *)vedkey; @@ -101,8 +179,7 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, if (edkey == NULL) { if (peddsactx->key != NULL) - /* there is nothing to do on reinit */ - return 1; + return eddsa_set_ctx_params(peddsactx, params); ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); return 0; } @@ -112,6 +189,11 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, return 0; } + peddsactx->dom2_flag = 0; + peddsactx->prehash_flag = 0; + peddsactx->context_string_flag = 0; + peddsactx->context_string_len = 0; + /* * We do not care about DER writing errors. * All it really means is that for some reason, there's no @@ -124,9 +206,11 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, switch (edkey->type) { case ECX_KEY_TYPE_ED25519: ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey); + peddsactx->instance_id = ID_Ed25519; break; case ECX_KEY_TYPE_ED448: ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey); + peddsactx->instance_id = ID_Ed448; break; default: /* Should never happen */ @@ -142,6 +226,9 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, peddsactx->key = edkey; + if (!eddsa_set_ctx_params(peddsactx, params)) + return 0; + return 1; } @@ -151,6 +238,8 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + uint8_t md[EVP_MAX_MD_SIZE]; + size_t mdlen; if (!ossl_prov_is_running()) return 0; @@ -168,17 +257,33 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, return 0; } #ifdef S390X_EC_ASM - if (S390X_CAN_SIGN(ED25519)) { - if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); - return 0; - } - *siglen = ED25519_SIGSIZE; - return 1; + /* s390x_ed25519_digestsign() does not yet support dom2 or context-strings. + fall back to non-accelerated sign if those options are set. */ + if (S390X_CAN_SIGN(ED25519) + && !peddsactx->dom2_flag + && !peddsactx->context_string_flag + && peddsactx->context_string_len == 0) { + if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); + return 0; + } + *siglen = ED25519_SIGSIZE; + return 1; } #endif /* S390X_EC_ASM */ + + if (peddsactx->prehash_flag) { + if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen) + || mdlen != EDDSA_PREHASH_OUTPUT_LEN) + return 0; + tbs = md; + tbslen = mdlen; + } + if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey, - peddsactx->libctx, NULL) == 0) { + peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag, + peddsactx->context_string, peddsactx->context_string_len, + peddsactx->libctx, NULL) == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); return 0; } @@ -186,12 +291,41 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, return 1; } +/* EVP_Q_digest() does not allow variable output length for XOFs, + so we use this function */ +static int ed448_shake256(OSSL_LIB_CTX *libctx, + const char *propq, + const uint8_t *in, size_t inlen, + uint8_t *out, size_t outlen) +{ + int ret = 0; + EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new(); + EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq); + + if (hash_ctx == NULL || shake256 == NULL) + goto err; + + if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL) + || !EVP_DigestUpdate(hash_ctx, in, inlen) + || !EVP_DigestFinalXOF(hash_ctx, out, outlen)) + goto err; + + ret = 1; + + err: + EVP_MD_CTX_free(hash_ctx); + EVP_MD_free(shake256); + return ret; +} + int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + uint8_t md[EDDSA_PREHASH_OUTPUT_LEN]; + size_t mdlen = sizeof(md); if (!ossl_prov_is_running()) return 0; @@ -209,17 +343,31 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, return 0; } #ifdef S390X_EC_ASM - if (S390X_CAN_SIGN(ED448)) { + /* s390x_ed448_digestsign() does not yet support context-strings or pre-hashing. + fall back to non-accelerated sign if a context-string or pre-hasing is provided. */ + if (S390X_CAN_SIGN(ED448) + && peddsactx->context_string_len == 0 + && peddsactx->prehash_flag == 0) { if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); - return 0; - } - *siglen = ED448_SIGSIZE; - return 1; + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); + return 0; + } + *siglen = ED448_SIGSIZE; + return 1; } #endif /* S390X_EC_ASM */ - if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey, - edkey->privkey, NULL, 0, edkey->propq) == 0) { + + if (peddsactx->prehash_flag) { + if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen)) + return 0; + tbs = md; + tbslen = mdlen; + } + + if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, + edkey->pubkey, edkey->privkey, + peddsactx->context_string, peddsactx->context_string_len, + peddsactx->prehash_flag, edkey->propq) == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); return 0; } @@ -233,16 +381,34 @@ int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig, { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + uint8_t md[EVP_MAX_MD_SIZE]; + size_t mdlen; if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE) return 0; #ifdef S390X_EC_ASM - if (S390X_CAN_SIGN(ED25519)) + /* s390x_ed25519_digestverify() does not yet support dom2 or context-strings. + fall back to non-accelerated verify if those options are set. */ + if (S390X_CAN_SIGN(ED25519) + && !peddsactx->dom2_flag + && !peddsactx->context_string_flag + && peddsactx->context_string_len == 0) { return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen); + } #endif /* S390X_EC_ASM */ + if (peddsactx->prehash_flag) { + if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen) + || mdlen != EDDSA_PREHASH_OUTPUT_LEN) + return 0; + tbs = md; + tbslen = mdlen; + } + return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, + peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag, + peddsactx->context_string, peddsactx->context_string_len, peddsactx->libctx, edkey->propq); } @@ -252,17 +418,32 @@ int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + uint8_t md[EDDSA_PREHASH_OUTPUT_LEN]; + size_t mdlen = sizeof(md); if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE) return 0; #ifdef S390X_EC_ASM - if (S390X_CAN_SIGN(ED448)) + /* s390x_ed448_digestverify() does not yet support context-strings or pre-hashing. + fall back to non-accelerated verify if a context-string or pre-hasing is provided. */ + if (S390X_CAN_SIGN(ED448) + && peddsactx->context_string_len == 0 + && peddsactx->prehash_flag == 0) { return s390x_ed448_digestverify(edkey, sig, tbs, tbslen); + } #endif /* S390X_EC_ASM */ + if (peddsactx->prehash_flag) { + if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen)) + return 0; + tbs = md; + tbslen = mdlen; + } + return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, - NULL, 0, edkey->propq); + peddsactx->context_string, peddsactx->context_string_len, + peddsactx->prehash_flag, edkey->propq); } static void eddsa_freectx(void *vpeddsactx) @@ -319,6 +500,8 @@ static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params) static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0), + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0), OSSL_PARAM_END }; @@ -328,6 +511,84 @@ static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx, return known_gettable_ctx_params; } +static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[]) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + const OSSL_PARAM *p; + + if (peddsactx == NULL) + return 0; + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE); + if (p != NULL) { + char instance_name[OSSL_MAX_NAME_SIZE] = ""; + char *pinstance_name = instance_name; + + if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name))) + return 0; + + if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) { + peddsactx->instance_id = ID_Ed25519; + if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0; + peddsactx->dom2_flag = 0; + peddsactx->prehash_flag = 0; + peddsactx->context_string_flag = 0; + } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) { + peddsactx->instance_id = ID_Ed25519ctx; + if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0; + peddsactx->dom2_flag = 1; + peddsactx->prehash_flag = 0; + peddsactx->context_string_flag = 1; + } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) { + peddsactx->instance_id = ID_Ed25519ph; + if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0; + peddsactx->dom2_flag = 1; + peddsactx->prehash_flag = 1; + peddsactx->context_string_flag = 0; + } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) { + peddsactx->instance_id = ID_Ed448; + if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0; + peddsactx->prehash_flag = 0; + peddsactx->context_string_flag = 0; + } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) { + peddsactx->instance_id = ID_Ed448ph; + if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0; + peddsactx->prehash_flag = 1; + peddsactx->context_string_flag = 0; + } else { + /* we did not recognize the instance */ + return 0; + } + + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING); + if (p != NULL) { + void *vp_context_string = peddsactx->context_string; + + if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) { + peddsactx->context_string_len = 0; + return 0; + } + } + + return 1; +} + +static const OSSL_PARAM settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0), + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx, + ossl_unused void *provctx) +{ + return settable_ctx_params; +} + const OSSL_DISPATCH ossl_ed25519_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, @@ -343,7 +604,10 @@ const OSSL_DISPATCH ossl_ed25519_signature_functions[] = { { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))eddsa_gettable_ctx_params }, - { 0, NULL } + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, + (void (*)(void))eddsa_settable_ctx_params }, + OSSL_DISPATCH_END }; const OSSL_DISPATCH ossl_ed448_signature_functions[] = { @@ -361,7 +625,10 @@ const OSSL_DISPATCH ossl_ed448_signature_functions[] = { { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))eddsa_gettable_ctx_params }, - { 0, NULL } + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, + (void (*)(void))eddsa_settable_ctx_params }, + OSSL_DISPATCH_END }; #ifdef S390X_EC_ASM diff --git a/providers/implementations/signature/mac_legacy_sig.c b/providers/implementations/signature/mac_legacy_sig.c index 6be605c8c6..b25a74506a 100644 --- a/providers/implementations/signature/mac_legacy_sig.c +++ b/providers/implementations/signature/mac_legacy_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,10 +60,8 @@ static void *mac_newctx(void *provctx, const char *propq, const char *macname) return NULL; pmacctx->libctx = PROV_LIBCTX_OF(provctx); - if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) goto err; - } mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq); if (mac == NULL) @@ -258,7 +256,7 @@ MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC") (void (*)(void))mac_set_ctx_params }, \ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ (void (*)(void))mac_##funcname##_settable_ctx_params }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ }; MAC_SIGNATURE_FUNCTIONS(hmac) diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c index cd5de6bd51..b8648b54bf 100644 --- a/providers/implementations/signature/rsa_sig.c +++ b/providers/implementations/signature/rsa_sig.c @@ -123,7 +123,7 @@ static int rsa_check_padding(const PROV_RSA_CTX *prsactx, const char *mdname, const char *mgf1_mdname, int mdnid) { - switch(prsactx->pad_mode) { + switch (prsactx->pad_mode) { case RSA_NO_PADDING: if (mdname != NULL || mdnid != NID_undef) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); @@ -182,7 +182,6 @@ static void *rsa_newctx(void *provctx, const char *propq) || (propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL)) { OPENSSL_free(prsactx); - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } @@ -244,11 +243,11 @@ static unsigned char *rsa_generate_signature_aid(PROV_RSA_CTX *ctx, int ret; if (!WPACKET_init_der(&pkt, aid_buf, buf_len)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB); return NULL; } - switch(ctx->pad_mode) { + switch (ctx->pad_mode) { case RSA_PKCS1_PADDING: ret = ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, ctx->mdnid); @@ -498,10 +497,8 @@ static int setup_tbuf(PROV_RSA_CTX *ctx) { if (ctx->tbuf != NULL) return 1; - if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) return 0; - } return 1; } @@ -582,7 +579,7 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, return 0; } if (!setup_tbuf(prsactx)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return 0; } memcpy(prsactx->tbuf, tbs, tbslen); @@ -1003,10 +1000,8 @@ static void *rsa_dupctx(void *vprsactx) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); - if (dstctx == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (dstctx == NULL) return NULL; - } *dstctx = *srcctx; dstctx->rsa = NULL; @@ -1493,5 +1488,5 @@ const OSSL_DISPATCH ossl_rsa_signature_functions[] = { (void (*)(void))rsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))rsa_settable_ctx_md_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/signature/sm2_sig.c b/providers/implementations/signature/sm2_sig.c index b3647a9a73..a61fd0864f 100644 --- a/providers/implementations/signature/sm2_sig.c +++ b/providers/implementations/signature/sm2_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -122,7 +122,6 @@ static void *sm2sig_newctx(void *provctx, const char *propq) ctx->libctx = PROV_LIBCTX_OF(provctx); if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(ctx); - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } ctx->mdsize = SM3_DIGEST_LENGTH; @@ -560,5 +559,5 @@ const OSSL_DISPATCH ossl_sm2_signature_functions[] = { (void (*)(void))sm2sig_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))sm2sig_settable_ctx_md_params }, - { 0, NULL } + OSSL_DISPATCH_END }; diff --git a/providers/implementations/storemgmt/build.info b/providers/implementations/storemgmt/build.info index 8e6445a4e7..d0b1174926 100644 --- a/providers/implementations/storemgmt/build.info +++ b/providers/implementations/storemgmt/build.info @@ -4,3 +4,6 @@ $STORE_GOAL=../../libdefault.a SOURCE[$STORE_GOAL]=file_store.c file_store_any2obj.c +IF[{- !$disabled{winstore} -}] + SOURCE[$STORE_GOAL]=winstore_store.c +ENDIF diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c index bb8b2ab862..171c74d581 100644 --- a/providers/implementations/storemgmt/file_store.c +++ b/providers/implementations/storemgmt/file_store.c @@ -55,9 +55,7 @@ static OSSL_FUNC_store_close_fn file_close; * passes that on to the data callback; this decoder is created with * internal OpenSSL functions, thereby bypassing the need for a surrounding * provider. This is ok, since this is a local decoder, not meant for - * public consumption. It also uses the libcrypto internal decoder - * setup function ossl_decoder_ctx_setup_for_pkey(), to allow the - * last resort decoder to be added first (and thereby be executed last). + * public consumption. * Finally, it sets up its own construct and cleanup functions. * * Essentially, that makes this implementation a kind of glorified decoder. @@ -155,7 +153,7 @@ static struct file_ctx_st *file_open_stream(BIO *source, const char *uri, struct file_ctx_st *ctx; if ((ctx = new_file_ctx(IS_FILE, uri, provctx)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); goto err; } @@ -172,7 +170,7 @@ static void *file_open_dir(const char *path, const char *uri, void *provctx) struct file_ctx_st *ctx; if ((ctx = new_file_ctx(IS_DIR, uri, provctx)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return NULL; } @@ -201,7 +199,7 @@ static void *file_open(void *provctx, const char *uri) unsigned int check_absolute:1; } path_data[2]; size_t path_data_n = 0, i; - const char *path; + const char *path, *p = uri, *q; BIO *bio; ERR_set_mark(); @@ -213,20 +211,18 @@ static void *file_open(void *provctx, const char *uri) path_data[path_data_n++].path = uri; /* - * Second step, if the URI appears to start with the 'file' scheme, + * Second step, if the URI appears to start with the "file" scheme, * extract the path and make that the second path to check. * There's a special case if the URI also contains an authority, then * the full URI shouldn't be used as a path anywhere. */ - if (OPENSSL_strncasecmp(uri, "file:", 5) == 0) { - const char *p = &uri[5]; - - if (strncmp(&uri[5], "//", 2) == 0) { + if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) { + q = p; + if (CHECK_AND_SKIP_CASE_PREFIX(q, "//")) { path_data_n--; /* Invalidate using the full URI */ - if (OPENSSL_strncasecmp(&uri[7], "localhost/", 10) == 0) { - p = &uri[16]; - } else if (uri[7] == '/') { - p = &uri[7]; + if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/") + || CHECK_AND_SKIP_CASE_PREFIX(q, "/")) { + p = q - 1; } else { ERR_clear_last_mark(); ERR_raise(ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED); @@ -236,7 +232,7 @@ static void *file_open(void *provctx, const char *uri) path_data[path_data_n].check_absolute = 1; #ifdef _WIN32 - /* Windows file: URIs with a drive letter start with a / */ + /* Windows "file:" URIs with a drive letter start with a '/' */ if (p[0] == '/' && p[2] == ':' && p[3] == '/') { char c = tolower(p[1]); @@ -424,7 +420,7 @@ static int file_setup_decoders(struct file_ctx_st *ctx) /* Setup for this session, so only if not already done */ if (ctx->_.file.decoderctx == NULL) { if ((ctx->_.file.decoderctx = OSSL_DECODER_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); goto err; } @@ -560,10 +556,8 @@ static char *file_name_to_uri(struct file_ctx_st *ctx, const char *name) + strlen(name) + 1 /* \0 */; data = OPENSSL_zalloc(calculated_length); - if (data == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (data == NULL) return NULL; - } OPENSSL_strlcat(data, ctx->uri, calculated_length); OPENSSL_strlcat(data, pathsep, calculated_length); @@ -786,5 +780,5 @@ const OSSL_DISPATCH ossl_file_store_functions[] = { { OSSL_FUNC_STORE_LOAD, (void (*)(void))file_load }, { OSSL_FUNC_STORE_EOF, (void (*)(void))file_eof }, { OSSL_FUNC_STORE_CLOSE, (void (*)(void))file_close }, - { 0, NULL }, + OSSL_DISPATCH_END, }; diff --git a/providers/implementations/storemgmt/file_store_any2obj.c b/providers/implementations/storemgmt/file_store_any2obj.c index 28601683bf..b8fa591085 100644 --- a/providers/implementations/storemgmt/file_store_any2obj.c +++ b/providers/implementations/storemgmt/file_store_any2obj.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -125,7 +125,7 @@ static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection, mem_want = 16; /* The size of the MSBLOB header */ if ((mem = BUF_MEM_new()) == NULL || !BUF_MEM_grow(mem, mem_want)) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); goto err; } @@ -147,7 +147,7 @@ static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection, ok = 0; mem_want = ossl_blob_length(bitlen, isdss, ispub); if (!BUF_MEM_grow(mem, mem_len + mem_want)) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); goto err; } @@ -192,7 +192,7 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection, mem_want = 24; /* The size of the PVK header */ if ((mem = BUF_MEM_new()) == NULL || !BUF_MEM_grow(mem, mem_want)) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); goto err; } @@ -214,7 +214,7 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection, ok = 0; mem_want = saltlen + keylen; if (!BUF_MEM_grow(mem, mem_len + mem_want)) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); goto err; } @@ -246,7 +246,7 @@ static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection, { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))any2obj_newctx }, \ { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))any2obj_freectx }, \ { OSSL_FUNC_DECODER_DECODE, (void (*)(void))fromtype##2obj_decode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } MAKE_DECODER(der, OSSL_OBJECT_UNKNOWN); diff --git a/providers/implementations/storemgmt/winstore_store.c b/providers/implementations/storemgmt/winstore_store.c new file mode 100644 index 0000000000..e230101d73 --- /dev/null +++ b/providers/implementations/storemgmt/winstore_store.c @@ -0,0 +1,329 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* The OSSL_STORE_INFO type numbers */ +#include "internal/cryptlib.h" +#include "internal/o_dir.h" +#include "crypto/decoder.h" +#include "crypto/ctype.h" /* ossl_isdigit() */ +#include "prov/implementations.h" +#include "prov/bio.h" +#include "file_store_local.h" +#ifdef __CYGWIN__ +# include +#endif +#include + +enum { + STATE_IDLE, + STATE_READ, + STATE_EOF, +}; + +struct winstore_ctx_st { + void *provctx; + char *propq; + unsigned char *subject; + size_t subject_len; + + HCERTSTORE win_store; + const CERT_CONTEXT *win_ctx; + int state; + + OSSL_DECODER_CTX *dctx; +}; + +static void winstore_win_reset(struct winstore_ctx_st *ctx) +{ + if (ctx->win_ctx != NULL) { + CertFreeCertificateContext(ctx->win_ctx); + ctx->win_ctx = NULL; + } + + ctx->state = STATE_IDLE; +} + +static void winstore_win_advance(struct winstore_ctx_st *ctx) +{ + CERT_NAME_BLOB name = {0}; + + if (ctx->state == STATE_EOF) + return; + + name.cbData = ctx->subject_len; + name.pbData = ctx->subject; + + ctx->win_ctx = (name.cbData == 0 ? NULL : + CertFindCertificateInStore(ctx->win_store, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, CERT_FIND_SUBJECT_NAME, + &name, ctx->win_ctx)); + + ctx->state = (ctx->win_ctx == NULL) ? STATE_EOF : STATE_READ; +} + +static void *winstore_open(void *provctx, const char *uri) +{ + struct winstore_ctx_st *ctx = NULL; + + if (!HAS_CASE_PREFIX(uri, "org.openssl.winstore:")) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->provctx = provctx; + ctx->win_store = CertOpenSystemStoreW(0, L"ROOT"); + if (ctx->win_store == NULL) { + OPENSSL_free(ctx); + return NULL; + } + + winstore_win_reset(ctx); + return ctx; +} + +static void *winstore_attach(void *provctx, OSSL_CORE_BIO *cin) +{ + return NULL; /* not supported */ +} + +static const OSSL_PARAM *winstore_settable_ctx_params(void *loaderctx, const OSSL_PARAM params[]) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_STORE_PARAM_SUBJECT, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +static int winstore_set_ctx_params(void *loaderctx, const OSSL_PARAM params[]) +{ + struct winstore_ctx_st *ctx = loaderctx; + const OSSL_PARAM *p; + int do_reset = 0; + + if (params == NULL) + return 1; + + p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_PROPERTIES); + if (p != NULL) { + do_reset = 1; + OPENSSL_free(ctx->propq); + ctx->propq = NULL; + if (!OSSL_PARAM_get_utf8_string(p, &ctx->propq, 0)) + return 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); + if (p != NULL) { + const unsigned char *der = NULL; + size_t der_len = 0; + + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&der, &der_len)) + return 0; + + do_reset = 1; + + OPENSSL_free(ctx->subject); + + ctx->subject = OPENSSL_malloc(der_len); + if (ctx->subject == NULL) { + ctx->subject_len = 0; + return 0; + } + + ctx->subject_len = der_len; + memcpy(ctx->subject, der, der_len); + } + + if (do_reset) { + winstore_win_reset(ctx); + winstore_win_advance(ctx); + } + + return 1; +} + +struct load_data_st { + OSSL_CALLBACK *object_cb; + void *object_cbarg; +}; + +static int load_construct(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, void *construct_data) +{ + struct load_data_st *data = construct_data; + return data->object_cb(params, data->object_cbarg); +} + +static void load_cleanup(void *construct_data) +{ + /* No-op. */ +} + +static int setup_decoder(struct winstore_ctx_st *ctx) +{ + OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); + const OSSL_ALGORITHM *to_algo = NULL; + + if (ctx->dctx != NULL) + return 1; + + ctx->dctx = OSSL_DECODER_CTX_new(); + if (ctx->dctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + return 0; + } + + if (!OSSL_DECODER_CTX_set_input_type(ctx->dctx, "DER")) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + if (!OSSL_DECODER_CTX_set_input_structure(ctx->dctx, "Certificate")) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + for (to_algo = ossl_any_to_obj_algorithm; + to_algo->algorithm_names != NULL; + to_algo++) { + OSSL_DECODER *to_obj = NULL; + OSSL_DECODER_INSTANCE *to_obj_inst = NULL; + + /* + * Create the internal last resort decoder implementation + * together with a "decoder instance". + * The decoder doesn't need any identification or to be + * attached to any provider, since it's only used locally. + */ + to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL); + if (to_obj != NULL) + to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx); + + OSSL_DECODER_free(to_obj); + if (to_obj_inst == NULL) + goto err; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx->dctx, + to_obj_inst)) { + ossl_decoder_instance_free(to_obj_inst); + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + } + + if (!OSSL_DECODER_CTX_add_extra(ctx->dctx, libctx, ctx->propq)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + if (!OSSL_DECODER_CTX_set_construct(ctx->dctx, load_construct)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + if (!OSSL_DECODER_CTX_set_cleanup(ctx->dctx, load_cleanup)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + return 1; + +err: + OSSL_DECODER_CTX_free(ctx->dctx); + ctx->dctx = NULL; + return 0; +} + +static int winstore_load_using(struct winstore_ctx_st *ctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, + const void *der, size_t der_len) +{ + struct load_data_st data; + const unsigned char *der_ = der; + size_t der_len_ = der_len; + + if (setup_decoder(ctx) == 0) + return 0; + + data.object_cb = object_cb; + data.object_cbarg = object_cbarg; + + OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data); + OSSL_DECODER_CTX_set_passphrase_cb(ctx->dctx, pw_cb, pw_cbarg); + + if (OSSL_DECODER_from_data(ctx->dctx, &der_, &der_len_) == 0) + return 0; + + return 1; +} + +static int winstore_load(void *loaderctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + int ret = 0; + struct winstore_ctx_st *ctx = loaderctx; + + if (ctx->state != STATE_READ) + return 0; + + ret = winstore_load_using(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg, + ctx->win_ctx->pbCertEncoded, + ctx->win_ctx->cbCertEncoded); + + if (ret == 1) + winstore_win_advance(ctx); + + return ret; +} + +static int winstore_eof(void *loaderctx) +{ + struct winstore_ctx_st *ctx = loaderctx; + + return ctx->state != STATE_READ; +} + +static int winstore_close(void *loaderctx) +{ + struct winstore_ctx_st *ctx = loaderctx; + + winstore_win_reset(ctx); + CertCloseStore(ctx->win_store, 0); + OSSL_DECODER_CTX_free(ctx->dctx); + OPENSSL_free(ctx->propq); + OPENSSL_free(ctx->subject); + OPENSSL_free(ctx); + return 1; +} + +const OSSL_DISPATCH ossl_winstore_store_functions[] = { + { OSSL_FUNC_STORE_OPEN, (void (*)(void))winstore_open }, + { OSSL_FUNC_STORE_ATTACH, (void (*)(void))winstore_attach }, + { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, (void (*)(void))winstore_settable_ctx_params }, + { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))winstore_set_ctx_params }, + { OSSL_FUNC_STORE_LOAD, (void (*)(void))winstore_load }, + { OSSL_FUNC_STORE_EOF, (void (*)(void))winstore_eof }, + { OSSL_FUNC_STORE_CLOSE, (void (*)(void))winstore_close }, + OSSL_DISPATCH_END, +}; diff --git a/providers/legacyprov.c b/providers/legacyprov.c index 38505d86c6..16e3639e76 100644 --- a/providers/legacyprov.c +++ b/providers/legacyprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "prov/provider_ctx.h" #include "prov/implementations.h" @@ -33,6 +34,22 @@ OSSL_provider_init_fn ossl_legacy_provider_init; # define OSSL_provider_init ossl_legacy_provider_init #endif +#ifndef STATIC_LEGACY +/* + * Should these function pointers be stored in the provider side provctx? + * Could they ever be different from one init to the next? We assume not for + * now. + */ + +/* Functions provided by the core */ +static OSSL_FUNC_core_new_error_fn *c_new_error; +static OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug; +static OSSL_FUNC_core_vset_error_fn *c_vset_error; +static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark; +static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark; +static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark; +#endif + /* Parameters we provide to the core */ static const OSSL_PARAM legacy_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), @@ -145,6 +162,7 @@ static const OSSL_ALGORITHM legacy_ciphers[] = { static const OSSL_ALGORITHM legacy_kdfs[] = { ALG(PROV_NAMES_PBKDF1, ossl_kdf_pbkdf1_functions), + ALG(PROV_NAMES_PVKKDF, ossl_kdf_pvk_functions), { NULL, NULL, NULL } }; @@ -175,7 +193,7 @@ static const OSSL_DISPATCH legacy_dispatch_table[] = { { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))legacy_gettable_params }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))legacy_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))legacy_query }, - { 0, NULL } + OSSL_DISPATCH_END }; int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, @@ -184,6 +202,41 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, void **provctx) { OSSL_LIB_CTX *libctx = NULL; +#ifndef STATIC_LEGACY + const OSSL_DISPATCH *tmp; +#endif + +#ifndef STATIC_LEGACY + for (tmp = in; tmp->function_id != 0; tmp++) { + /* + * We do not support the scenario of an application linked against + * multiple versions of libcrypto (e.g. one static and one dynamic), + * but sharing a single legacy.so. We do a simple sanity check here. + */ +#define set_func(c, f) if (c == NULL) c = f; else if (c != f) return 0; + switch (tmp->function_id) { + case OSSL_FUNC_CORE_NEW_ERROR: + set_func(c_new_error, OSSL_FUNC_core_new_error(tmp)); + break; + case OSSL_FUNC_CORE_SET_ERROR_DEBUG: + set_func(c_set_error_debug, OSSL_FUNC_core_set_error_debug(tmp)); + break; + case OSSL_FUNC_CORE_VSET_ERROR: + set_func(c_vset_error, OSSL_FUNC_core_vset_error(tmp)); + break; + case OSSL_FUNC_CORE_SET_ERROR_MARK: + set_func(c_set_error_mark, OSSL_FUNC_core_set_error_mark(tmp)); + break; + case OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK: + set_func(c_clear_last_error_mark, + OSSL_FUNC_core_clear_last_error_mark(tmp)); + break; + case OSSL_FUNC_CORE_POP_ERROR_TO_MARK: + set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(tmp)); + break; + } + } +#endif if ((*provctx = ossl_prov_ctx_new()) == NULL || (libctx = OSSL_LIB_CTX_new_child(handle, in)) == NULL) { @@ -199,3 +252,53 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, return 1; } + +#ifndef STATIC_LEGACY +/* + * Provider specific implementation of libcrypto functions in terms of + * upcalls. + */ + +/* + * For ERR functions, we pass a NULL context. This is valid to do as long + * as only error codes that the calling libcrypto supports are used. + */ +void ERR_new(void) +{ + c_new_error(NULL); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + c_set_error_debug(NULL, file, line, func); +} + +void ERR_set_error(int lib, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args); + va_end(args); +} + +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) +{ + c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args); +} + +int ERR_set_mark(void) +{ + return c_set_error_mark(NULL); +} + +int ERR_clear_last_mark(void) +{ + return c_clear_last_error_mark(NULL); +} + +int ERR_pop_to_mark(void) +{ + return c_pop_error_to_mark(NULL); +} +#endif diff --git a/providers/nullprov.c b/providers/nullprov.c index d5b4c05d93..bace75af15 100644 --- a/providers/nullprov.c +++ b/providers/nullprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,7 +64,7 @@ static const OSSL_DISPATCH null_dispatch_table[] = { { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))null_gettable_params }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))null_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))null_query }, - { 0, NULL } + OSSL_DISPATCH_END }; int ossl_null_provider_init(const OSSL_CORE_HANDLE *handle, diff --git a/providers/stores.inc b/providers/stores.inc index 4c1ec8f287..526532759e 100644 --- a/providers/stores.inc +++ b/providers/stores.inc @@ -12,3 +12,6 @@ #endif STORE("file", "yes", ossl_file_store_functions) +#ifndef OPENSSL_NO_WINSTORE +STORE("org.openssl.winstore", "yes", ossl_winstore_store_functions) +#endif diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index 401178f0c2..68dd48a5ef 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,7 +25,11 @@ static int ssl_free(BIO *data); static long ssl_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); typedef struct bio_ssl_st { SSL *ssl; /* The ssl handle :-) */ - /* re-negotiate every time the total number of bytes is this size */ + /* + * Re-negotiate every time the total number of bytes is this size + * or when timeout expires. + * There is no proper support for TLS-1.3 or QUIC yet. + */ int num_renegotiates; unsigned long renegotiate_count; size_t byte_count; @@ -57,10 +61,8 @@ static int ssl_new(BIO *bi) { BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs)); - if (bs == NULL) { - ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); + if (bs == NULL) return 0; - } BIO_set_init(bi, 0); BIO_set_data(bi, bs); /* Clear all flags */ @@ -227,19 +229,24 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) BIO *dbio, *bio; long ret = 1; BIO *next; + SSL_CONNECTION *sc = NULL; bs = BIO_get_data(b); next = BIO_next(b); ssl = bs->ssl; - if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + if (ssl == NULL && cmd != BIO_C_SET_SSL) return 0; switch (cmd) { case BIO_CTRL_RESET: + /* TODO(QUIC FUTURE): Add support when SSL_clear() is supported */ + if ((sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl)) == NULL) + return 0; + SSL_shutdown(ssl); - if (ssl->handshake_func == ssl->method->ssl_connect) + if (sc->handshake_func == ssl->method->ssl_connect) SSL_set_connect_state(ssl); - else if (ssl->handshake_func == ssl->method->ssl_accept) + else if (sc->handshake_func == ssl->method->ssl_accept) SSL_set_accept_state(ssl); if (!SSL_clear(ssl)) { @@ -249,8 +256,8 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) if (next != NULL) ret = BIO_ctrl(next, cmd, num, ptr); - else if (ssl->rbio != NULL) - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + else if (sc->rbio != NULL) + ret = BIO_ctrl(sc->rbio, cmd, num, ptr); else ret = 1; break; @@ -311,20 +318,20 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_set_shutdown(b, (int)num); break; case BIO_CTRL_WPENDING: - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); break; case BIO_CTRL_PENDING: ret = SSL_pending(ssl); if (ret == 0) - ret = BIO_pending(ssl->rbio); + ret = BIO_pending(SSL_get_rbio(ssl)); break; case BIO_CTRL_FLUSH: BIO_clear_retry_flags(b); - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); BIO_copy_next_retry(b); break; case BIO_CTRL_PUSH: - if ((next != NULL) && (next != ssl->rbio)) { + if ((next != NULL) && (next != SSL_get_rbio(ssl))) { /* * We are going to pass ownership of next to the SSL object...but * we don't own a reference to pass yet - so up ref @@ -378,13 +385,21 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) ret = (dbs->ssl != NULL); break; case BIO_C_GET_FD: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + ret = BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr); break; case BIO_CTRL_SET_CALLBACK: ret = 0; /* use callback ctrl */ break; + case BIO_CTRL_GET_RPOLL_DESCRIPTOR: + if (!SSL_get_rpoll_descriptor(ssl, (BIO_POLL_DESCRIPTOR *)ptr)) + ret = 0; + break; + case BIO_CTRL_GET_WPOLL_DESCRIPTOR: + if (!SSL_get_wpoll_descriptor(ssl, (BIO_POLL_DESCRIPTOR *)ptr)) + ret = 0; + break; default: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + ret = BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr); break; } return ret; @@ -400,7 +415,7 @@ static long ssl_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) ssl = bs->ssl; switch (cmd) { case BIO_CTRL_SET_CALLBACK: - ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); + ret = BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp); break; default: ret = 0; @@ -423,6 +438,12 @@ BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) #ifndef OPENSSL_NO_SOCK BIO *ret = NULL, *buf = NULL, *ssl = NULL; +# ifndef OPENSSL_NO_QUIC + if (ctx != NULL && IS_QUIC_CTX(ctx)) + /* Never use buffering for QUIC. */ + return BIO_new_ssl_connect(ctx); +# endif + if ((buf = BIO_new(BIO_f_buffer())) == NULL) return NULL; if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) @@ -444,6 +465,13 @@ BIO *BIO_new_ssl_connect(SSL_CTX *ctx) if ((con = BIO_new(BIO_s_connect())) == NULL) return NULL; + +# ifndef OPENSSL_NO_QUIC + if (ctx != NULL && IS_QUIC_CTX(ctx)) + if (!BIO_set_sock_type(con, SOCK_DGRAM)) + goto err; +#endif + if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) goto err; if ((ret = BIO_push(ssl, con)) == NULL) diff --git a/ssl/build.info b/ssl/build.info index 0851357f81..00e9e8fd7d 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -1,44 +1,36 @@ -LIBS=../libssl - -#Needed for the multiblock code in rec_layer_s3.c -IF[{- !$disabled{asm} -}] - $AESDEF_x86=AES_ASM - $AESDEF_x86_64=AES_ASM +SUBDIRS=record - IF[$AESDEF_{- $target{asm_arch} -}] - $AESDEF=$AESDEF_{- $target{asm_arch} -} - ENDIF -ENDIF +LIBS=../libssl -$KTLSSRC= -IF[{- !$disabled{ktls} -}] - $KTLSSRC=ktls.c +IF[{- !$disabled{quic} -}] + SUBDIRS=quic ENDIF SOURCE[../libssl]=\ pqueue.c \ - statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \ + statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c \ statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \ statem/extensions_clnt.c statem/extensions_cust.c s3_msg.c \ - methods.c t1_lib.c t1_enc.c tls13_enc.c \ - d1_lib.c record/rec_layer_d1.c d1_msg.c \ + methods.c t1_lib.c t1_enc.c tls13_enc.c \ + d1_lib.c d1_msg.c \ statem/statem_dtls.c d1_srtp.c \ ssl_lib.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \ bio_ssl.c ssl_err.c ssl_err_legacy.c tls_srp.c t1_trce.c ssl_utst.c \ - record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ - statem/statem.c record/ssl3_record_tls13.c \ - tls_depr.c $KTLSSRC -# For shared builds we need to include the libcrypto packet.c and sources -# needed in providers (s3_cbc.c and record/tls_pad.c) in libssl as well. -SHARED_SOURCE[../libssl]=record/tls_pad.c ../crypto/packet.c + statem/statem.c \ + ssl_cert_comp.c \ + tls_depr.c + +# For shared builds we need to include the libcrypto packet.c and quic_vlint.c +# in libssl as well. +SHARED_SOURCE[../libssl]=\ + ../crypto/packet.c ../crypto/quic_vlint.c ../crypto/time.c + IF[{- !$disabled{'deprecated-3.0'} -}] - SHARED_SOURCE[../libssl]=s3_cbc.c SOURCE[../libssl]=ssl_rsa_legacy.c ENDIF -DEFINE[../libssl]=$AESDEF - -SOURCE[../providers/libcommon.a]=record/tls_pad.c -SOURCE[../providers/libdefault.a ../providers/libfips.a]=s3_cbc.c +IF[{- !$disabled{quic} -}] + SOURCE[../libssl]=priority_queue.c event_queue.c +ENDIF diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 871c187a9d..1ac0975d0a 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,17 +12,15 @@ #include #include #include "ssl_local.h" +#include "internal/time.h" -static void get_current_time(struct timeval *t); -static int dtls1_handshake_write(SSL *s); +static int dtls1_handshake_write(SSL_CONNECTION *s); static size_t dtls1_link_min_mtu(void); /* XDTLS: figure out the right values */ static const size_t g_probable_mtu[] = { 1500, 512, 256 }; const SSL3_ENC_METHOD DTLSv1_enc_data = { - tls1_enc, - tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, tls1_change_cipher_state, @@ -38,8 +36,6 @@ const SSL3_ENC_METHOD DTLSv1_enc_data = { }; const SSL3_ENC_METHOD DTLSv1_2_enc_data = { - tls1_enc, - tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, tls1_change_cipher_state, @@ -55,27 +51,31 @@ const SSL3_ENC_METHOD DTLSv1_2_enc_data = { dtls1_handshake_write }; -long dtls1_default_timeout(void) +OSSL_TIME dtls1_default_timeout(void) { /* * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for * http, the cache would over fill */ - return (60 * 60 * 2); + return ossl_seconds2time(60 * 60 * 2); } -int dtls1_new(SSL *s) +int dtls1_new(SSL *ssl) { DTLS1_STATE *d1; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return 0; if (!DTLS_RECORD_LAYER_new(&s->rlayer)) { return 0; } - if (!ssl3_new(s)) + if (!ssl3_new(ssl)) return 0; if ((d1 = OPENSSL_zalloc(sizeof(*d1))) == NULL) { - ssl3_free(s); + ssl3_free(ssl); return 0; } @@ -93,25 +93,25 @@ int dtls1_new(SSL *s) pqueue_free(d1->buffered_messages); pqueue_free(d1->sent_messages); OPENSSL_free(d1); - ssl3_free(s); + ssl3_free(ssl); return 0; } s->d1 = d1; - if (!s->method->ssl_clear(s)) + if (!ssl->method->ssl_clear(ssl)) return 0; return 1; } -static void dtls1_clear_queues(SSL *s) +static void dtls1_clear_queues(SSL_CONNECTION *s) { dtls1_clear_received_buffer(s); dtls1_clear_sent_buffer(s); } -void dtls1_clear_received_buffer(SSL *s) +void dtls1_clear_received_buffer(SSL_CONNECTION *s) { pitem *item = NULL; hm_fragment *frag = NULL; @@ -123,24 +123,36 @@ void dtls1_clear_received_buffer(SSL *s) } } -void dtls1_clear_sent_buffer(SSL *s) +void dtls1_clear_sent_buffer(SSL_CONNECTION *s) { pitem *item = NULL; hm_fragment *frag = NULL; while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { frag = (hm_fragment *)item->data; + + if (frag->msg_header.is_ccs + && frag->msg_header.saved_retransmit_state.wrlmethod != NULL + && s->rlayer.wrl != frag->msg_header.saved_retransmit_state.wrl) { + /* + * If we're freeing the CCS then we're done with the old wrl and it + * can bee freed + */ + frag->msg_header.saved_retransmit_state.wrlmethod->free(frag->msg_header.saved_retransmit_state.wrl); + } + dtls1_hm_fragment_free(frag); pitem_free(item); } } -void dtls1_free(SSL *s) +void dtls1_free(SSL *ssl) { - DTLS_RECORD_LAYER_free(&s->rlayer); + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); - ssl3_free(s); + if (s == NULL) + return; if (s->d1 != NULL) { dtls1_clear_queues(s); @@ -148,17 +160,26 @@ void dtls1_free(SSL *s) pqueue_free(s->d1->sent_messages); } + DTLS_RECORD_LAYER_free(&s->rlayer); + + ssl3_free(ssl); + OPENSSL_free(s->d1); s->d1 = NULL; } -int dtls1_clear(SSL *s) +int dtls1_clear(SSL *ssl) { pqueue *buffered_messages; pqueue *sent_messages; size_t mtu; size_t link_mtu; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return 0; + DTLS_RECORD_LAYER_clear(&s->rlayer); if (s->d1) { @@ -180,7 +201,7 @@ int dtls1_clear(SSL *s) s->d1->cookie_len = sizeof(s->d1->cookie); } - if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { + if (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU) { s->d1->mtu = mtu; s->d1->link_mtu = link_mtu; } @@ -189,28 +210,34 @@ int dtls1_clear(SSL *s) s->d1->sent_messages = sent_messages; } - if (!ssl3_clear(s)) + if (!ssl3_clear(ssl)) return 0; - if (s->method->version == DTLS_ANY_VERSION) + if (ssl->method->version == DTLS_ANY_VERSION) s->version = DTLS_MAX_VERSION_INTERNAL; #ifndef OPENSSL_NO_DTLS1_METHOD else if (s->options & SSL_OP_CISCO_ANYCONNECT) s->client_version = s->version = DTLS1_BAD_VER; #endif else - s->version = s->method->version; + s->version = ssl->method->version; return 1; } -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) +long dtls1_ctrl(SSL *ssl, int cmd, long larg, void *parg) { int ret = 0; + OSSL_TIME t; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return 0; switch (cmd) { case DTLS_CTRL_GET_TIMEOUT: - if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { + if (dtls1_get_timeout(s, &t)) { + *(struct timeval *)parg = ossl_time_to_timeval(t); ret = 1; } break; @@ -234,20 +261,28 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) s->d1->mtu = larg; return larg; default: - ret = ssl3_ctrl(s, cmd, larg, parg); + ret = ssl3_ctrl(ssl, cmd, larg, parg); break; } return ret; } -void dtls1_start_timer(SSL *s) +static void dtls1_bio_set_next_timeout(BIO *bio, const DTLS1_STATE *d1) { - unsigned int sec, usec; + struct timeval tv = ossl_time_to_timeval(d1->next_timeout); + + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &tv); +} + +void dtls1_start_timer(SSL_CONNECTION *s) +{ + OSSL_TIME duration; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); #ifndef OPENSSL_NO_SCTP /* Disable timer for SCTP */ - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); + if (BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { + s->d1->next_timeout = ossl_time_zero(); return; } #endif @@ -256,122 +291,89 @@ void dtls1_start_timer(SSL *s) * If timer is not set, initialize duration with 1 second or * a user-specified value if the timer callback is installed. */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - + if (ossl_time_is_zero(s->d1->next_timeout)) { if (s->d1->timer_cb != NULL) - s->d1->timeout_duration_us = s->d1->timer_cb(s, 0); + s->d1->timeout_duration_us = s->d1->timer_cb(ssl, 0); else s->d1->timeout_duration_us = 1000000; } - /* Set timeout to current time */ - get_current_time(&(s->d1->next_timeout)); - - /* Add duration to current time */ - - sec = s->d1->timeout_duration_us / 1000000; - usec = s->d1->timeout_duration_us - (sec * 1000000); - - s->d1->next_timeout.tv_sec += sec; - s->d1->next_timeout.tv_usec += usec; + /* Set timeout to current time plus duration */ + duration = ossl_us2time(s->d1->timeout_duration_us); + s->d1->next_timeout = ossl_time_add(ossl_time_now(), duration); - if (s->d1->next_timeout.tv_usec >= 1000000) { - s->d1->next_timeout.tv_sec++; - s->d1->next_timeout.tv_usec -= 1000000; - } - - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); + /* set s->d1->next_timeout into ssl->rbio interface */ + dtls1_bio_set_next_timeout(SSL_get_rbio(ssl), s->d1); } -struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) +int dtls1_get_timeout(const SSL_CONNECTION *s, OSSL_TIME *timeleft) { - struct timeval timenow; + OSSL_TIME timenow; /* If no timeout is set, just return NULL */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - return NULL; - } + if (ossl_time_is_zero(s->d1->next_timeout)) + return 0; /* Get current time */ - get_current_time(&timenow); - - /* If timer already expired, set remaining time to 0 */ - if (s->d1->next_timeout.tv_sec < timenow.tv_sec || - (s->d1->next_timeout.tv_sec == timenow.tv_sec && - s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { - memset(timeleft, 0, sizeof(*timeleft)); - return timeleft; - } - - /* Calculate time left until timer expires */ - memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); - timeleft->tv_sec -= timenow.tv_sec; - timeleft->tv_usec -= timenow.tv_usec; - if (timeleft->tv_usec < 0) { - timeleft->tv_sec--; - timeleft->tv_usec += 1000000; - } + timenow = ossl_time_now(); /* - * If remaining time is less than 15 ms, set it to 0 to prevent issues - * because of small divergences with socket timeouts. + * If timer already expired or if remaining time is less than 15 ms, + * set it to 0 to prevent issues because of small divergences with + * socket timeouts. */ - if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { - memset(timeleft, 0, sizeof(*timeleft)); - } - - return timeleft; + *timeleft = ossl_time_subtract(s->d1->next_timeout, timenow); + if (ossl_time_compare(*timeleft, ossl_ms2time(15)) <= 0) + *timeleft = ossl_time_zero(); + return 1; } -int dtls1_is_timer_expired(SSL *s) +int dtls1_is_timer_expired(SSL_CONNECTION *s) { - struct timeval timeleft; + OSSL_TIME timeleft; /* Get time left until timeout, return false if no timer running */ - if (dtls1_get_timeout(s, &timeleft) == NULL) { + if (!dtls1_get_timeout(s, &timeleft)) return 0; - } /* Return false if timer is not expired yet */ - if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + if (!ossl_time_is_zero(timeleft)) return 0; - } /* Timer expired, so return true */ return 1; } -static void dtls1_double_timeout(SSL *s) +static void dtls1_double_timeout(SSL_CONNECTION *s) { s->d1->timeout_duration_us *= 2; if (s->d1->timeout_duration_us > 60000000) s->d1->timeout_duration_us = 60000000; } -void dtls1_stop_timer(SSL *s) +void dtls1_stop_timer(SSL_CONNECTION *s) { /* Reset everything */ s->d1->timeout_num_alerts = 0; - memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); + s->d1->next_timeout = ossl_time_zero(); s->d1->timeout_duration_us = 1000000; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); + dtls1_bio_set_next_timeout(s->rbio, s->d1); /* Clear retransmission buffer */ dtls1_clear_sent_buffer(s); } -int dtls1_check_timeout_num(SSL *s) +int dtls1_check_timeout_num(SSL_CONNECTION *s) { size_t mtu; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); s->d1->timeout_num_alerts++; /* Reduce MTU after 2 unsuccessful retransmissions */ if (s->d1->timeout_num_alerts > 2 - && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + && !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); if (mtu < s->d1->mtu) s->d1->mtu = mtu; } @@ -385,7 +387,7 @@ int dtls1_check_timeout_num(SSL *s) return 0; } -int dtls1_handle_timeout(SSL *s) +int dtls1_handle_timeout(SSL_CONNECTION *s) { /* if no timer is expired, don't do anything */ if (!dtls1_is_timer_expired(s)) { @@ -393,7 +395,8 @@ int dtls1_handle_timeout(SSL *s) } if (s->d1->timer_cb != NULL) - s->d1->timeout_duration_us = s->d1->timer_cb(s, s->d1->timeout_duration_us); + s->d1->timeout_duration_us = s->d1->timer_cb(SSL_CONNECTION_GET_SSL(s), + s->d1->timeout_duration_us); else dtls1_double_timeout(s); @@ -407,62 +410,40 @@ int dtls1_handle_timeout(SSL *s) return dtls1_retransmit_buffered_messages(s); } -static void get_current_time(struct timeval *t) -{ -#if defined(_WIN32) - SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); - /* re-bias to 1/1/1970 */ -# ifdef __MINGW32__ - now.ul -= 116444736000000000ULL; -# else - /* *INDENT-OFF* */ - now.ul -= 116444736000000000UI64; - /* *INDENT-ON* */ -# endif - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; -#else - gettimeofday(t, NULL); -#endif -} - #define LISTEN_SUCCESS 2 #define LISTEN_SEND_VERIFY_REQUEST 1 #ifndef OPENSSL_NO_SOCK -int DTLSv1_listen(SSL *s, BIO_ADDR *client) +int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) { int next, n, ret = 0; unsigned char cookie[DTLS1_COOKIE_LENGTH]; unsigned char seq[SEQ_NUM_SIZE]; const unsigned char *data; - unsigned char *buf, *wbuf; - size_t fragoff, fraglen, msglen, reclen, align = 0; - unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen; + unsigned char *buf = NULL, *wbuf; + size_t fragoff, fraglen, msglen; + unsigned int rectype, versmajor, versminor, msgseq, msgtype, clientvers, cookielen; BIO *rbio, *wbio; BIO_ADDR *tmpclient = NULL; PACKET pkt, msgpkt, msgpayload, session, cookiepkt; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return -1; if (s->handshake_func == NULL) { /* Not properly initialized yet */ - SSL_set_accept_state(s); + SSL_set_accept_state(ssl); } /* Ensure there is no state left over from a previous invocation */ - if (!SSL_clear(s)) + if (!SSL_clear(ssl)) return -1; ERR_clear_error(); - rbio = SSL_get_rbio(s); - wbio = SSL_get_wbio(s); + rbio = SSL_get_rbio(ssl); + wbio = SSL_get_wbio(ssl); if (!rbio || !wbio) { ERR_raise(ERR_LIB_SSL, SSL_R_BIO_NOT_SET); @@ -481,25 +462,14 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) return -1; } - if (!ssl3_setup_buffers(s)) { - /* ERR_raise() already called */ + buf = OPENSSL_malloc(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_PLAIN_LENGTH); + if (buf == NULL) + return -1; + wbuf = OPENSSL_malloc(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_PLAIN_LENGTH); + if (wbuf == NULL) { + OPENSSL_free(buf); return -1; } - buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf; - wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf; -#if defined(SSL3_ALIGN_PAYLOAD) -# if SSL3_ALIGN_PAYLOAD != 0 - /* - * Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for - * consistency with ssl3_read_n. In practice it should make no difference - * for sensible values of SSL3_ALIGN_PAYLOAD because the difference between - * SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8 - */ - align = (size_t)buf + SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); -# endif -#endif - buf += align; do { /* Get a packet */ @@ -512,12 +482,14 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* Non-blocking IO */ goto end; } - return -1; + ret = -1; + goto end; } if (!PACKET_buf_init(&pkt, buf, n)) { ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); - return -1; + ret = -1; + goto end; } /* @@ -535,17 +507,18 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) goto end; } - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, buf, - DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); - /* Get the record header */ if (!PACKET_get_1(&pkt, &rectype) - || !PACKET_get_1(&pkt, &versmajor)) { + || !PACKET_get_1(&pkt, &versmajor) + || !PACKET_get_1(&pkt, &versminor)) { ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } + if (s->msg_callback) + s->msg_callback(0, (versmajor << 8) | versminor, SSL3_RT_HEADER, buf, + DTLS1_RT_HEADER_LENGTH, ssl, s->msg_callback_arg); + if (rectype != SSL3_RT_HANDSHAKE) { ERR_raise(ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE); goto end; @@ -560,14 +533,12 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) goto end; } - if (!PACKET_forward(&pkt, 1) - /* Save the sequence number: 64 bits, with top 2 bytes = epoch */ - || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE) + /* Save the sequence number: 64 bits, with top 2 bytes = epoch */ + if (!PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE) || !PACKET_get_length_prefixed_2(&pkt, &msgpkt)) { ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } - reclen = PACKET_remaining(&msgpkt); /* * We allow data remaining at the end of the packet because there could * be a second record (but we ignore it) @@ -620,7 +591,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, data, - fraglen + DTLS1_HM_HEADER_LENGTH, s, + fraglen + DTLS1_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); if (!PACKET_get_net_2(&msgpayload, &clientvers)) { @@ -631,8 +602,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* * Verify client version is supported */ - if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) && - s->method->version != DTLS_ANY_VERSION) { + if (DTLS_VERSION_LT(clientvers, (unsigned int)ssl->method->version) && + ssl->method->version != DTLS_ANY_VERSION) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_VERSION_NUMBER); goto end; } @@ -658,12 +629,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* * We have a cookie, so lets check it. */ - if (s->ctx->app_verify_cookie_cb == NULL) { + if (ssl->ctx->app_verify_cookie_cb == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK); /* This is fatal */ - return -1; + ret = -1; + goto end; } - if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookiepkt), + if (ssl->ctx->app_verify_cookie_cb(ssl, PACKET_data(&cookiepkt), (unsigned int)PACKET_remaining(&cookiepkt)) == 0) { /* * We treat invalid cookies in the same was as no cookie as @@ -688,12 +660,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) */ /* Generate the cookie */ - if (s->ctx->app_gen_cookie_cb == NULL || - s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || + if (ssl->ctx->app_gen_cookie_cb == NULL || + ssl->ctx->app_gen_cookie_cb(ssl, cookie, &cookielen) == 0 || cookielen > 255) { ERR_raise(ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); /* This is fatal */ - return -1; + ret = -1; + goto end; } /* @@ -701,8 +674,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * haven't decided which version to use yet send back using version * 1.0 header: otherwise some clients will ignore it. */ - version = (s->method->version == DTLS_ANY_VERSION) ? DTLS1_VERSION - : s->version; + version = (ssl->method->version == DTLS_ANY_VERSION) ? DTLS1_VERSION + : s->version; /* Construct the record and message headers */ if (!WPACKET_init_static_len(&wpkt, @@ -757,7 +730,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); WPACKET_cleanup(&wpkt); /* This is fatal */ - return -1; + ret = -1; + goto end; } /* @@ -773,10 +747,11 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) if (s->msg_callback) s->msg_callback(1, 0, SSL3_RT_HEADER, buf, - DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); + DTLS1_RT_HEADER_LENGTH, ssl, + s->msg_callback_arg); if ((tmpclient = BIO_ADDR_new()) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_BIO_LIB); goto end; } @@ -799,7 +774,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) */ goto end; } - return -1; + ret = -1; + goto end; } if (BIO_flush(wbio) <= 0) { @@ -810,7 +786,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) */ goto end; } - return -1; + ret = -1; + goto end; } } } while (next != LISTEN_SUCCESS); @@ -821,13 +798,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) s->d1->handshake_read_seq = 1; s->d1->handshake_write_seq = 1; s->d1->next_handshake_write_seq = 1; - DTLS_RECORD_LAYER_set_write_sequence(&s->rlayer, seq); + s->rlayer.wrlmethod->increment_sequence_ctr(s->rlayer.wrl); /* * We are doing cookie exchange, so make sure we set that option in the * SSL object */ - SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); + SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); /* * Tell the state machine that we've done the initial hello verify @@ -841,18 +818,38 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) if (BIO_dgram_get_peer(rbio, client) <= 0) BIO_ADDR_clear(client); - /* Buffer the record in the processed_rcds queue */ - if (!dtls_buffer_listen_record(s, reclen, seq, align)) - return -1; + /* Buffer the record for use by the record layer */ + if (BIO_write(s->rlayer.rrlnext, buf, n) != n) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + /* + * Reset the record layer - but this time we can use the record we just + * buffered in s->rlayer.rrlnext + */ + if (!ssl_set_new_record_layer(s, + DTLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NID_undef, NULL, NULL, NULL)) { + /* SSLfatal already called */ + ret = -1; + goto end; + } ret = 1; end: BIO_ADDR_free(tmpclient); + OPENSSL_free(buf); + OPENSSL_free(wbuf); return ret; } #endif -static int dtls1_handshake_write(SSL *s) +static int dtls1_handshake_write(SSL_CONNECTION *s) { return dtls1_do_write(s, SSL3_RT_HANDSHAKE); } @@ -862,10 +859,14 @@ int dtls1_shutdown(SSL *s) int ret; #ifndef OPENSSL_NO_SCTP BIO *wbio; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (s == NULL) + return -1; wbio = SSL_get_wbio(s); if (wbio != NULL && BIO_dgram_is_sctp(wbio) && - !(s->shutdown & SSL_SENT_SHUTDOWN)) { + !(sc->shutdown & SSL_SENT_SHUTDOWN)) { ret = BIO_dgram_sctp_wait_for_dry(wbio); if (ret < 0) return -1; @@ -882,19 +883,21 @@ int dtls1_shutdown(SSL *s) return ret; } -int dtls1_query_mtu(SSL *s) +int dtls1_query_mtu(SSL_CONNECTION *s) { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + if (s->d1->link_mtu) { s->d1->mtu = - s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); + s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(ssl)); s->d1->link_mtu = 0; } /* AHA! Figure out the MTU, and stick to the right size */ if (s->d1->mtu < dtls1_min_mtu(s)) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + if (!(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { s->d1->mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); /* * I've seen the kernel return bogus numbers when it doesn't know @@ -903,7 +906,7 @@ int dtls1_query_mtu(SSL *s) if (s->d1->mtu < dtls1_min_mtu(s)) { /* Set to min mtu */ s->d1->mtu = dtls1_min_mtu(s); - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, (long)s->d1->mtu, NULL); } } else @@ -918,16 +921,24 @@ static size_t dtls1_link_min_mtu(void) sizeof(g_probable_mtu[0])) - 1]); } -size_t dtls1_min_mtu(SSL *s) +size_t dtls1_min_mtu(SSL_CONNECTION *s) { - return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(ssl)); } -size_t DTLS_get_data_mtu(const SSL *s) +size_t DTLS_get_data_mtu(const SSL *ssl) { size_t mac_overhead, int_overhead, blocksize, ext_overhead; - const SSL_CIPHER *ciph = SSL_get_current_cipher(s); - size_t mtu = s->d1->mtu; + const SSL_CIPHER *ciph = SSL_get_current_cipher(ssl); + size_t mtu; + const SSL_CONNECTION *s = SSL_CONNECTION_FROM_CONST_SSL_ONLY(ssl); + + if (s == NULL) + return 0; + + mtu = s->d1->mtu; if (ciph == NULL) return 0; @@ -959,7 +970,12 @@ size_t DTLS_get_data_mtu(const SSL *s) return mtu; } -void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb) +void DTLS_set_timer_cb(SSL *ssl, DTLS_timer_cb cb) { + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return; + s->d1->timer_cb = cb; } diff --git a/ssl/d1_msg.c b/ssl/d1_msg.c index 10438a3955..b1e1fad16d 100644 --- a/ssl/d1_msg.c +++ b/ssl/d1_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,13 +9,17 @@ #include "ssl_local.h" -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, - size_t *written) +int dtls1_write_app_data_bytes(SSL *s, uint8_t type, const void *buf_, + size_t len, size_t *written) { int i; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); - if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) { - i = s->handshake_func(s); + if (sc == NULL) + return -1; + + if (SSL_in_init(s) && !ossl_statem_get_in_handshake(sc)) { + i = sc->handshake_func(s); if (i < 0) return i; if (i == 0) { @@ -29,42 +33,46 @@ int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, return -1; } - return dtls1_write_bytes(s, type, buf_, len, written); + return dtls1_write_bytes(sc, type, buf_, len, written); } -int dtls1_dispatch_alert(SSL *s) +int dtls1_dispatch_alert(SSL *ssl) { int i, j; void (*cb) (const SSL *ssl, int type, int val) = NULL; unsigned char buf[DTLS1_AL_HEADER_LENGTH]; unsigned char *ptr = &buf[0]; size_t written; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (s == NULL) + return 0; - s->s3.alert_dispatch = 0; + s->s3.alert_dispatch = SSL_ALERT_DISPATCH_NONE; memset(buf, 0, sizeof(buf)); *ptr++ = s->s3.send_alert[0]; *ptr++ = s->s3.send_alert[1]; - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0, &written); + i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), &written); if (i <= 0) { s->s3.alert_dispatch = 1; - /* fprintf( stderr, "not done with alert\n" ); */ + /* fprintf(stderr, "not done with alert\n"); */ } else { (void)BIO_flush(s->wbio); if (s->msg_callback) s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3.send_alert, - 2, s, s->msg_callback_arg); + 2, ssl, s->msg_callback_arg); if (s->info_callback != NULL) cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; + else if (ssl->ctx->info_callback != NULL) + cb = ssl->ctx->info_callback; if (cb != NULL) { j = (s->s3.send_alert[0] << 8) | s->s3.send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); + cb(ssl, SSL_CB_WRITE_ALERT, j); } } return i; diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c index 2300753382..5ca135d970 100644 --- a/ssl/d1_srtp.c +++ b/ssl/d1_srtp.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,6 +16,7 @@ #include #include #include "ssl_local.h" +#include "quic/quic_local.h" #ifndef OPENSSL_NO_SRTP @@ -36,6 +37,38 @@ static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, }, + { + "SRTP_DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM", + SRTP_DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM, + }, + { + "SRTP_DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM", + SRTP_DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM, + }, + { + "SRTP_ARIA_128_CTR_HMAC_SHA1_80", + SRTP_ARIA_128_CTR_HMAC_SHA1_80, + }, + { + "SRTP_ARIA_128_CTR_HMAC_SHA1_32", + SRTP_ARIA_128_CTR_HMAC_SHA1_32, + }, + { + "SRTP_ARIA_256_CTR_HMAC_SHA1_80", + SRTP_ARIA_256_CTR_HMAC_SHA1_80, + }, + { + "SRTP_ARIA_256_CTR_HMAC_SHA1_32", + SRTP_ARIA_256_CTR_HMAC_SHA1_32, + }, + { + "SRTP_AEAD_ARIA_128_GCM", + SRTP_AEAD_ARIA_128_GCM, + }, + { + "SRTP_AEAD_ARIA_256_GCM", + SRTP_AEAD_ARIA_256_GCM, + }, {0} }; @@ -107,19 +140,29 @@ static int ssl_ctx_make_profiles(const char *profiles_string, int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) { + if (IS_QUIC_METHOD(ctx->method)) + return 1; + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); } int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) { - return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 1; + + return ssl_ctx_make_profiles(profiles, &sc->srtp_profiles); } STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) { - if (s != NULL) { - if (s->srtp_profiles != NULL) { - return s->srtp_profiles; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc != NULL) { + if (sc->srtp_profiles != NULL) { + return sc->srtp_profiles; } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) { return s->ctx->srtp_profiles; } @@ -130,6 +173,11 @@ STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) { - return s->srtp_profile; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + return sc->srtp_profile; } #endif diff --git a/ssl/event_queue.c b/ssl/event_queue.c new file mode 100644 index 0000000000..20f4020db5 --- /dev/null +++ b/ssl/event_queue.c @@ -0,0 +1,196 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/event_queue.h" +#include "ssl_local.h" + +struct ossl_event_queue_st { + PRIORITY_QUEUE_OF(OSSL_EVENT) *timed_events; + PRIORITY_QUEUE_OF(OSSL_EVENT) *now_events; +}; + +static int event_compare_times(const OSSL_EVENT *a, const OSSL_EVENT *b) +{ + return ossl_time_compare(a->when, b->when); +} + +static int event_compare_priority(const OSSL_EVENT *a, const OSSL_EVENT *b) +{ + if (a->priority > b->priority) + return -1; + if (a->priority < b->priority) + return 1; + return 0; +} + +OSSL_EVENT_QUEUE *ossl_event_queue_new(void) +{ + OSSL_EVENT_QUEUE *r = OPENSSL_malloc(sizeof(*r)); + + if (r != NULL) { + r->timed_events = ossl_pqueue_OSSL_EVENT_new(&event_compare_times); + r->now_events = ossl_pqueue_OSSL_EVENT_new(&event_compare_priority); + if (r->timed_events == NULL || r->now_events == NULL) { + ossl_event_queue_free(r); + return NULL; + } + } + return r; +} + +void ossl_event_free(OSSL_EVENT *event) +{ + if (event != NULL) { + if (event->flag_dynamic) + OPENSSL_free(event); + else + event->queue = NULL; + } +} + +static void event_queue_free(PRIORITY_QUEUE_OF(OSSL_EVENT) *queue) +{ + OSSL_EVENT *e; + + if (queue != NULL) { + while ((e = ossl_pqueue_OSSL_EVENT_pop(queue)) != NULL) + ossl_event_free(e); + ossl_pqueue_OSSL_EVENT_free(queue); + } +} + +void ossl_event_queue_free(OSSL_EVENT_QUEUE *queue) +{ + if (queue != NULL) { + event_queue_free(queue->now_events); + event_queue_free(queue->timed_events); + OPENSSL_free(queue); + } +} + +static ossl_inline +int event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event) +{ + PRIORITY_QUEUE_OF(OSSL_EVENT) *pq = + ossl_time_compare(event->when, ossl_time_now()) <= 0 + ? queue->now_events + : queue->timed_events; + + if (ossl_pqueue_OSSL_EVENT_push(pq, event, &event->ref)) { + event->queue = pq; + return 1; + } + return 0; +} + +static ossl_inline +void ossl_event_set(OSSL_EVENT *event, uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size) +{ + event->type = type; + event->priority = priority; + event->when = when; + event->ctx = ctx; + event->payload = payload; + event->payload_size = payload_size; +} + +OSSL_EVENT *ossl_event_queue_add_new(OSSL_EVENT_QUEUE *queue, + uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size) +{ + OSSL_EVENT *e = OPENSSL_malloc(sizeof(*e)); + + if (e == NULL || queue == NULL) { + OPENSSL_free(e); + return NULL; + } + + ossl_event_set(e, type, priority, when, ctx, payload, payload_size); + e->flag_dynamic = 1; + if (event_queue_add(queue, e)) + return e; + OPENSSL_free(e); + return NULL; +} + +int ossl_event_queue_add(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event, + uint32_t type, uint32_t priority, + OSSL_TIME when, void *ctx, + void *payload, size_t payload_size) +{ + if (event == NULL || queue == NULL) + return 0; + ossl_event_set(event, type, priority, when, ctx, payload, payload_size); + event->flag_dynamic = 0; + return event_queue_add(queue, event); +} + +int ossl_event_queue_remove(OSSL_EVENT_QUEUE *queue, OSSL_EVENT *event) +{ + if (event != NULL && event->queue != NULL) { + ossl_pqueue_OSSL_EVENT_remove(event->queue, event->ref); + event->queue = NULL; + } + return 1; +} + +OSSL_TIME ossl_event_time_until(const OSSL_EVENT *event) +{ + if (event == NULL) + return ossl_time_infinite(); + return ossl_time_subtract(event->when, ossl_time_now()); +} + +OSSL_TIME ossl_event_queue_time_until_next(const OSSL_EVENT_QUEUE *queue) +{ + if (queue == NULL) + return ossl_time_infinite(); + if (ossl_pqueue_OSSL_EVENT_num(queue->now_events) > 0) + return ossl_time_zero(); + return ossl_event_time_until(ossl_pqueue_OSSL_EVENT_peek(queue->timed_events)); +} + +int ossl_event_queue_postpone_until(OSSL_EVENT_QUEUE *queue, + OSSL_EVENT *event, + OSSL_TIME when) +{ + if (ossl_event_queue_remove(queue, event)) { + event->when = when; + return event_queue_add(queue, event); + } + return 0; +} + +int ossl_event_queue_get1_next_event(OSSL_EVENT_QUEUE *queue, + OSSL_EVENT **event) +{ + OSSL_TIME now = ossl_time_now(); + OSSL_EVENT *e; + + /* Check for expired timer based events and convert them to now events */ + while ((e = ossl_pqueue_OSSL_EVENT_peek(queue->timed_events)) != NULL + && ossl_time_compare(e->when, now) <= 0) { + e = ossl_pqueue_OSSL_EVENT_pop(queue->timed_events); + if (!ossl_pqueue_OSSL_EVENT_push(queue->now_events, e, &e->ref)) { + e->queue = NULL; + return 0; + } + } + + /* + * Get next event from the now queue. + * The pop returns NULL when there is none. + */ + *event = ossl_pqueue_OSSL_EVENT_pop(queue->now_events); + return 1; +} diff --git a/ssl/ktls.c b/ssl/ktls.c deleted file mode 100644 index ddbfd1447c..0000000000 --- a/ssl/ktls.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "ssl_local.h" -#include "internal/ktls.h" - -#if defined(__FreeBSD__) -# include "crypto/cryptodev.h" - -/*- - * Check if a given cipher is supported by the KTLS interface. - * The kernel might still fail the setsockopt() if no suitable - * provider is found, but this checks if the socket option - * supports the cipher suite used at all. - */ -int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) -{ - - switch (s->version) { - case TLS1_VERSION: - case TLS1_1_VERSION: - case TLS1_2_VERSION: - case TLS1_3_VERSION: - break; - default: - return 0; - } - - switch (s->s3.tmp.new_cipher->algorithm_enc) { - case SSL_AES128GCM: - case SSL_AES256GCM: - return 1; - case SSL_AES128: - case SSL_AES256: - if (s->ext.use_etm) - return 0; - switch (s->s3.tmp.new_cipher->algorithm_mac) { - case SSL_SHA1: - case SSL_SHA256: - case SSL_SHA384: - return 1; - default: - return 0; - } - default: - return 0; - } -} - -/* Function to configure kernel TLS structure */ -int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, - void *rl_sequence, ktls_crypto_info_t *crypto_info, - unsigned char **rec_seq, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, - size_t mac_secret_size) -{ - memset(crypto_info, 0, sizeof(*crypto_info)); - switch (s->s3.tmp.new_cipher->algorithm_enc) { - case SSL_AES128GCM: - case SSL_AES256GCM: - crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; - if (s->version == TLS1_3_VERSION) { - crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd); - if (crypto_info->iv_len < 0) - return 0; - } - else - crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; - break; - case SSL_AES128: - case SSL_AES256: - switch (s->s3.tmp.new_cipher->algorithm_mac) { - case SSL_SHA1: - crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; - break; - case SSL_SHA256: - crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; - break; - case SSL_SHA384: - crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; - break; - default: - return 0; - } - crypto_info->cipher_algorithm = CRYPTO_AES_CBC; - crypto_info->iv_len = EVP_CIPHER_get_iv_length(c); - crypto_info->auth_key = mac_key; - crypto_info->auth_key_len = mac_secret_size; - break; - default: - return 0; - } - crypto_info->cipher_key = key; - crypto_info->cipher_key_len = EVP_CIPHER_get_key_length(c); - crypto_info->iv = iv; - crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; - crypto_info->tls_vminor = (s->version & 0x000000ff); -# ifdef TCP_RXTLS_ENABLE - memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); - if (rec_seq != NULL) - *rec_seq = crypto_info->rec_seq; -# else - if (rec_seq != NULL) - *rec_seq = NULL; -# endif - return 1; -}; - -#endif /* __FreeBSD__ */ - -#if defined(OPENSSL_SYS_LINUX) - -/* Function to check supported ciphers in Linux */ -int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) -{ - switch (s->version) { - case TLS1_2_VERSION: - case TLS1_3_VERSION: - break; - default: - return 0; - } - - /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 - * or Chacha20-Poly1305 - */ -# ifdef OPENSSL_KTLS_AES_CCM_128 - if (EVP_CIPHER_is_a(c, "AES-128-CCM")) { - if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */ - || EVP_CIPHER_CTX_get_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) - return 0; - return 1; - } else -# endif - if (0 -# ifdef OPENSSL_KTLS_AES_GCM_128 - || EVP_CIPHER_is_a(c, "AES-128-GCM") -# endif -# ifdef OPENSSL_KTLS_AES_GCM_256 - || EVP_CIPHER_is_a(c, "AES-256-GCM") -# endif -# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 - || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305") -# endif - ) { - return 1; - } - return 0; -} - -/* Function to configure kernel TLS structure */ -int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, - void *rl_sequence, ktls_crypto_info_t *crypto_info, - unsigned char **rec_seq, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, - size_t mac_secret_size) -{ - unsigned char geniv[12]; - unsigned char *iiv = iv; - - if (s->version == TLS1_2_VERSION && - EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) { - if (!EVP_CIPHER_CTX_get_updated_iv(dd, geniv, - EVP_GCM_TLS_FIXED_IV_LEN - + EVP_GCM_TLS_EXPLICIT_IV_LEN)) - return 0; - iiv = geniv; - } - - memset(crypto_info, 0, sizeof(*crypto_info)); - switch (EVP_CIPHER_get_nid(c)) - { -# ifdef OPENSSL_KTLS_AES_GCM_128 - case NID_aes_128_gcm: - crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; - crypto_info->gcm128.info.version = s->version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); - memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_128_IV_SIZE); - memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); - memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_get_key_length(c)); - memcpy(crypto_info->gcm128.rec_seq, rl_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->gcm128.rec_seq; - return 1; -# endif -# ifdef OPENSSL_KTLS_AES_GCM_256 - case NID_aes_256_gcm: - crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; - crypto_info->gcm256.info.version = s->version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); - memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_256_IV_SIZE); - memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); - memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_get_key_length(c)); - memcpy(crypto_info->gcm256.rec_seq, rl_sequence, - TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->gcm256.rec_seq; - return 1; -# endif -# ifdef OPENSSL_KTLS_AES_CCM_128 - case NID_aes_128_ccm: - crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; - crypto_info->ccm128.info.version = s->version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); - memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_CCM_128_IV_SIZE); - memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); - memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_get_key_length(c)); - memcpy(crypto_info->ccm128.rec_seq, rl_sequence, - TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->ccm128.rec_seq; - return 1; -# endif -# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 - case NID_chacha20_poly1305: - crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; - crypto_info->chacha20poly1305.info.version = s->version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); - memcpy(crypto_info->chacha20poly1305.iv, iiv, - TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); - memcpy(crypto_info->chacha20poly1305.key, key, - EVP_CIPHER_get_key_length(c)); - memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, - TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->chacha20poly1305.rec_seq; - return 1; -# endif - default: - return 0; - } - -} - -#endif /* OPENSSL_SYS_LINUX */ diff --git a/ssl/pqueue.c b/ssl/pqueue.c index 0852aceacf..db161e25da 100644 --- a/ssl/pqueue.c +++ b/ssl/pqueue.c @@ -19,10 +19,8 @@ pitem *pitem_new(unsigned char *prio64be, void *data) { pitem *item = OPENSSL_malloc(sizeof(*item)); - if (item == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (item == NULL) return NULL; - } memcpy(item->priority, prio64be, sizeof(item->priority)); item->data = data; @@ -39,9 +37,6 @@ pqueue *pqueue_new(void) { pqueue *pq = OPENSSL_zalloc(sizeof(*pq)); - if (pq == NULL) - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); - return pq; } diff --git a/ssl/priority_queue.c b/ssl/priority_queue.c new file mode 100644 index 0000000000..5393c532a7 --- /dev/null +++ b/ssl/priority_queue.c @@ -0,0 +1,376 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/priority_queue.h" +#include "internal/safe_math.h" +#include "internal/numbers.h" + +OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) + +/* + * Fundamental operations: + * Binary Heap Fibonacci Heap + * Get smallest O(1) O(1) + * Delete any O(log n) O(log n) average but worst O(n) + * Insert O(log n) O(1) + * + * Not supported: + * Merge two structures O(log n) O(1) + * Decrease key O(log n) O(1) + * Increase key O(log n) ? + * + * The Fibonacci heap is quite a bit more complicated to implement and has + * larger overhead in practice. We favour the binary heap here. A multi-way + * (ternary or quaternary) heap might elicit a performance advantage via better + * cache access patterns. + */ + +struct pq_heap_st { + void *data; /* User supplied data pointer */ + size_t index; /* Constant index in elements[] */ +}; + +struct pq_elem_st { + size_t posn; /* Current index in heap[] or link in free list */ +#ifndef NDEBUG + int used; /* Debug flag indicating that this is in use */ +#endif +}; + +struct ossl_pqueue_st +{ + struct pq_heap_st *heap; + struct pq_elem_st *elements; + int (*compare)(const void *, const void *); + size_t htop; /* Highest used heap element */ + size_t hmax; /* Allocated heap & element space */ + size_t freelist; /* Index into elements[], start of free element list */ +}; + +/* + * The initial and maximum number of elements in the heap. + */ +static const size_t min_nodes = 8; +static const size_t max_nodes = + SIZE_MAX / (sizeof(struct pq_heap_st) > sizeof(struct pq_elem_st) + ? sizeof(struct pq_heap_st) : sizeof(struct pq_elem_st)); + +#ifndef NDEBUG +/* Some basic sanity checking of the data structure */ +# define ASSERT_USED(pq, idx) \ + assert(pq->elements[pq->heap[idx].index].used); \ + assert(pq->elements[pq->heap[idx].index].posn == idx) +# define ASSERT_ELEM_USED(pq, elem) \ + assert(pq->elements[elem].used) +#else +# define ASSERT_USED(pq, idx) +# define ASSERT_ELEM_USED(pq, elem) +#endif + +/* + * Calculate the array growth based on the target size. + * + * The growth factor is a rational number and is defined by a numerator + * and a denominator. According to Andrew Koenig in his paper "Why Are + * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less + * than the golden ratio (1.618...). + * + * We use an expansion factor of 8 / 5 = 1.6 + */ +static ossl_inline size_t compute_pqueue_growth(size_t target, size_t current) +{ + int err = 0; + + while (current < target) { + if (current >= max_nodes) + return 0; + + current = safe_muldiv_size_t(current, 8, 5, &err); + if (err) + return 0; + if (current >= max_nodes) + current = max_nodes; + } + return current; +} + +static ossl_inline void pqueue_swap_elem(OSSL_PQUEUE *pq, size_t i, size_t j) +{ + struct pq_heap_st *h = pq->heap, t_h; + struct pq_elem_st *e = pq->elements; + + ASSERT_USED(pq, i); + ASSERT_USED(pq, j); + + t_h = h[i]; + h[i] = h[j]; + h[j] = t_h; + + e[h[i].index].posn = i; + e[h[j].index].posn = j; +} + +static ossl_inline void pqueue_move_elem(OSSL_PQUEUE *pq, size_t from, size_t to) +{ + struct pq_heap_st *h = pq->heap; + struct pq_elem_st *e = pq->elements; + + ASSERT_USED(pq, from); + + h[to] = h[from]; + e[h[to].index].posn = to; +} + +/* + * Force the specified element to the front of the heap. This breaks + * the heap partial ordering pre-condition. + */ +static ossl_inline void pqueue_force_bottom(OSSL_PQUEUE *pq, size_t n) +{ + ASSERT_USED(pq, n); + while (n > 0) { + const size_t p = (n - 1) / 2; + + ASSERT_USED(pq, p); + pqueue_swap_elem(pq, n, p); + n = p; + } +} + +/* + * Move an element down to its correct position to restore the partial + * order pre-condition. + */ +static ossl_inline void pqueue_move_down(OSSL_PQUEUE *pq, size_t n) +{ + struct pq_heap_st *h = pq->heap; + + ASSERT_USED(pq, n); + while (n > 0) { + const size_t p = (n - 1) / 2; + + ASSERT_USED(pq, p); + if (pq->compare(h[n].data, h[p].data) >= 0) + break; + pqueue_swap_elem(pq, n, p); + n = p; + } +} + +/* + * Move an element up to its correct position to restore the partial + * order pre-condition. + */ +static ossl_inline void pqueue_move_up(OSSL_PQUEUE *pq, size_t n) +{ + struct pq_heap_st *h = pq->heap; + size_t p = n * 2 + 1; + + ASSERT_USED(pq, n); + if (pq->htop > p + 1) { + ASSERT_USED(pq, p); + ASSERT_USED(pq, p + 1); + if (pq->compare(h[p].data, h[p + 1].data) > 0) + p++; + } + while (pq->htop > p && pq->compare(h[p].data, h[n].data) < 0) { + ASSERT_USED(pq, p); + pqueue_swap_elem(pq, n, p); + n = p; + p = n * 2 + 1; + if (pq->htop > p + 1) { + ASSERT_USED(pq, p + 1); + if (pq->compare(h[p].data, h[p + 1].data) > 0) + p++; + } + } +} + +int ossl_pqueue_push(OSSL_PQUEUE *pq, void *data, size_t *elem) +{ + size_t n, m; + + if (!ossl_pqueue_reserve(pq, 1)) + return 0; + + n = pq->htop++; + m = pq->freelist; + pq->freelist = pq->elements[m].posn; + + pq->heap[n].data = data; + pq->heap[n].index = m; + + pq->elements[m].posn = n; +#ifndef NDEBUG + pq->elements[m].used = 1; +#endif + pqueue_move_down(pq, n); + if (elem != NULL) + *elem = m; + return 1; +} + +void *ossl_pqueue_peek(const OSSL_PQUEUE *pq) +{ + if (pq->htop > 0) { + ASSERT_USED(pq, 0); + return pq->heap->data; + } + return NULL; +} + +void *ossl_pqueue_pop(OSSL_PQUEUE *pq) +{ + void *res; + size_t elem; + + if (pq == NULL || pq->htop == 0) + return NULL; + + ASSERT_USED(pq, 0); + res = pq->heap->data; + elem = pq->heap->index; + + if (--pq->htop != 0) { + pqueue_move_elem(pq, pq->htop, 0); + pqueue_move_up(pq, 0); + } + + pq->elements[elem].posn = pq->freelist; + pq->freelist = elem; +#ifndef NDEBUG + pq->elements[elem].used = 0; +#endif + return res; +} + +void *ossl_pqueue_remove(OSSL_PQUEUE *pq, size_t elem) +{ + size_t n; + + if (pq == NULL || elem >= pq->hmax || pq->htop == 0) + return 0; + + ASSERT_ELEM_USED(pq, elem); + n = pq->elements[elem].posn; + + ASSERT_USED(pq, n); + + if (n == pq->htop - 1) { + pq->elements[elem].posn = pq->freelist; + pq->freelist = elem; +#ifndef NDEBUG + pq->elements[elem].used = 0; +#endif + return pq->heap[--pq->htop].data; + } + if (n > 0) + pqueue_force_bottom(pq, n); + return ossl_pqueue_pop(pq); +} + +static void pqueue_add_freelist(OSSL_PQUEUE *pq, size_t from) +{ + struct pq_elem_st *e = pq->elements; + size_t i; + +#ifndef NDEBUG + for (i = from; i < pq->hmax; i++) + e[i].used = 0; +#endif + e[from].posn = pq->freelist; + for (i = from + 1; i < pq->hmax; i++) + e[i].posn = i - 1; + pq->freelist = pq->hmax - 1; +} + +int ossl_pqueue_reserve(OSSL_PQUEUE *pq, size_t n) +{ + size_t new_max, cur_max; + struct pq_heap_st *h; + struct pq_elem_st *e; + + if (pq == NULL) + return 0; + cur_max = pq->hmax; + if (pq->htop + n < cur_max) + return 1; + + new_max = compute_pqueue_growth(n + cur_max, cur_max); + if (new_max == 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + h = OPENSSL_realloc(pq->heap, new_max * sizeof(*pq->heap)); + if (h == NULL) + return 0; + pq->heap = h; + + e = OPENSSL_realloc(pq->elements, new_max * sizeof(*pq->elements)); + if (e == NULL) + return 0; + pq->elements = e; + + pq->hmax = new_max; + pqueue_add_freelist(pq, cur_max); + return 1; +} + +OSSL_PQUEUE *ossl_pqueue_new(int (*compare)(const void *, const void *)) +{ + OSSL_PQUEUE *pq; + + if (compare == NULL) + return NULL; + + pq = OPENSSL_malloc(sizeof(*pq)); + if (pq == NULL) + return NULL; + pq->compare = compare; + pq->hmax = min_nodes; + pq->htop = 0; + pq->freelist = 0; + pq->heap = OPENSSL_malloc(sizeof(*pq->heap) * min_nodes); + pq->elements = OPENSSL_malloc(sizeof(*pq->elements) * min_nodes); + if (pq->heap == NULL || pq->elements == NULL) { + ossl_pqueue_free(pq); + return NULL; + } + pqueue_add_freelist(pq, 0); + return pq; +} + +void ossl_pqueue_free(OSSL_PQUEUE *pq) +{ + if (pq != NULL) { + OPENSSL_free(pq->heap); + OPENSSL_free(pq->elements); + OPENSSL_free(pq); + } +} + +void ossl_pqueue_pop_free(OSSL_PQUEUE *pq, void (*freefunc)(void *)) +{ + size_t i; + + if (pq != NULL) { + for (i = 0; i < pq->htop; i++) + (*freefunc)(pq->heap[i].data); + ossl_pqueue_free(pq); + } +} + +size_t ossl_pqueue_num(const OSSL_PQUEUE *pq) +{ + return pq != NULL ? pq->htop : 0; +} diff --git a/ssl/quic/build.info b/ssl/quic/build.info new file mode 100644 index 0000000000..3a9e2d55af --- /dev/null +++ b/ssl/quic/build.info @@ -0,0 +1,16 @@ +$LIBSSL=../../libssl + +SOURCE[$LIBSSL]=quic_method.c quic_impl.c quic_wire.c quic_ackm.c quic_statm.c +SOURCE[$LIBSSL]=cc_newreno.c quic_demux.c quic_record_rx.c +SOURCE[$LIBSSL]=quic_record_tx.c quic_record_util.c quic_record_shared.c quic_wire_pkt.c +SOURCE[$LIBSSL]=quic_rx_depack.c +SOURCE[$LIBSSL]=quic_fc.c uint_set.c +SOURCE[$LIBSSL]=quic_cfq.c quic_txpim.c quic_fifd.c quic_txp.c +SOURCE[$LIBSSL]=quic_stream_map.c +SOURCE[$LIBSSL]=quic_sf_list.c quic_rstream.c quic_sstream.c +SOURCE[$LIBSSL]=quic_reactor.c +SOURCE[$LIBSSL]=quic_channel.c +SOURCE[$LIBSSL]=quic_tserver.c +SOURCE[$LIBSSL]=quic_tls.c +SOURCE[$LIBSSL]=quic_thread_assist.c +SOURCE[$LIBSSL]=quic_trace.c diff --git a/ssl/quic/cc_newreno.c b/ssl/quic/cc_newreno.c new file mode 100644 index 0000000000..1fe37c276e --- /dev/null +++ b/ssl/quic/cc_newreno.c @@ -0,0 +1,485 @@ +#include "internal/quic_cc.h" +#include "internal/quic_types.h" +#include "internal/safe_math.h" + +OSSL_SAFE_MATH_UNSIGNED(u64, uint64_t) + +typedef struct ossl_cc_newreno_st { + /* Dependencies. */ + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; + + /* 'Constants' (which we allow to be configurable). */ + uint64_t k_init_wnd, k_min_wnd; + uint32_t k_loss_reduction_factor_num, k_loss_reduction_factor_den; + uint32_t persistent_cong_thresh; + + /* State. */ + size_t max_dgram_size; + uint64_t bytes_in_flight, cong_wnd, slow_start_thresh, bytes_acked; + OSSL_TIME cong_recovery_start_time; + + /* Unflushed state during multiple on-loss calls. */ + int processing_loss; /* 1 if not flushed */ + OSSL_TIME tx_time_of_last_loss; + + /* Diagnostic state. */ + int in_congestion_recovery; + + /* Diagnostic output locations. */ + size_t *p_diag_max_dgram_payload_len; + uint64_t *p_diag_cur_cwnd_size; + uint64_t *p_diag_min_cwnd_size; + uint64_t *p_diag_cur_bytes_in_flight; + uint32_t *p_diag_cur_state; +} OSSL_CC_NEWRENO; + +#define MIN_MAX_INIT_WND_SIZE 14720 /* RFC 9002 s. 7.2 */ + +/* TODO(QUIC FUTURE): Pacing support. */ + +static void newreno_set_max_dgram_size(OSSL_CC_NEWRENO *nr, + size_t max_dgram_size); +static void newreno_update_diag(OSSL_CC_NEWRENO *nr); + +static void newreno_reset(OSSL_CC_DATA *cc); + +static OSSL_CC_DATA *newreno_new(OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) +{ + OSSL_CC_NEWRENO *nr; + + if ((nr = OPENSSL_zalloc(sizeof(*nr))) == NULL) + return NULL; + + nr->now_cb = now_cb; + nr->now_cb_arg = now_cb_arg; + + newreno_set_max_dgram_size(nr, QUIC_MIN_INITIAL_DGRAM_LEN); + newreno_reset((OSSL_CC_DATA *)nr); + + return (OSSL_CC_DATA *)nr; +} + +static void newreno_free(OSSL_CC_DATA *cc) +{ + OPENSSL_free(cc); +} + +static void newreno_set_max_dgram_size(OSSL_CC_NEWRENO *nr, + size_t max_dgram_size) +{ + size_t max_init_wnd; + int is_reduced = (max_dgram_size < nr->max_dgram_size); + + nr->max_dgram_size = max_dgram_size; + + max_init_wnd = 2 * max_dgram_size; + if (max_init_wnd < MIN_MAX_INIT_WND_SIZE) + max_init_wnd = MIN_MAX_INIT_WND_SIZE; + + nr->k_init_wnd = 10 * max_dgram_size; + if (nr->k_init_wnd > max_init_wnd) + nr->k_init_wnd = max_init_wnd; + + nr->k_min_wnd = 2 * max_dgram_size; + + if (is_reduced) + nr->cong_wnd = nr->k_init_wnd; + + newreno_update_diag(nr); +} + +static void newreno_reset(OSSL_CC_DATA *cc) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + nr->k_loss_reduction_factor_num = 1; + nr->k_loss_reduction_factor_den = 2; + nr->persistent_cong_thresh = 3; + + nr->cong_wnd = nr->k_init_wnd; + nr->bytes_in_flight = 0; + nr->bytes_acked = 0; + nr->slow_start_thresh = UINT64_MAX; + nr->cong_recovery_start_time = ossl_time_zero(); + + nr->processing_loss = 0; + nr->tx_time_of_last_loss = ossl_time_zero(); + nr->in_congestion_recovery = 0; +} + +static int newreno_set_input_params(OSSL_CC_DATA *cc, const OSSL_PARAM *params) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + const OSSL_PARAM *p; + size_t value; + + p = OSSL_PARAM_locate_const(params, OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN); + if (p != NULL) { + if (!OSSL_PARAM_get_size_t(p, &value)) + return 0; + if (value < QUIC_MIN_INITIAL_DGRAM_LEN) + return 0; + + newreno_set_max_dgram_size(nr, value); + } + + return 1; +} + +static int bind_diag(OSSL_PARAM *params, const char *param_name, size_t len, + void **pp) +{ + const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, param_name); + + *pp = NULL; + + if (p == NULL) + return 1; + + if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER + || p->data_size != len) + return 0; + + *pp = p->data; + return 1; +} + +static int newreno_bind_diagnostic(OSSL_CC_DATA *cc, OSSL_PARAM *params) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + size_t *new_p_max_dgram_payload_len; + uint64_t *new_p_cur_cwnd_size; + uint64_t *new_p_min_cwnd_size; + uint64_t *new_p_cur_bytes_in_flight; + uint32_t *new_p_cur_state; + + if (!bind_diag(params, OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN, + sizeof(size_t), (void **)&new_p_max_dgram_payload_len) + || !bind_diag(params, OSSL_CC_OPTION_CUR_CWND_SIZE, + sizeof(uint64_t), (void **)&new_p_cur_cwnd_size) + || !bind_diag(params, OSSL_CC_OPTION_MIN_CWND_SIZE, + sizeof(uint64_t), (void **)&new_p_min_cwnd_size) + || !bind_diag(params, OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT, + sizeof(uint64_t), (void **)&new_p_cur_bytes_in_flight) + || !bind_diag(params, OSSL_CC_OPTION_CUR_STATE, + sizeof(uint32_t), (void **)&new_p_cur_state)) + return 0; + + if (new_p_max_dgram_payload_len != NULL) + nr->p_diag_max_dgram_payload_len = new_p_max_dgram_payload_len; + + if (new_p_cur_cwnd_size != NULL) + nr->p_diag_cur_cwnd_size = new_p_cur_cwnd_size; + + if (new_p_min_cwnd_size != NULL) + nr->p_diag_min_cwnd_size = new_p_min_cwnd_size; + + if (new_p_cur_bytes_in_flight != NULL) + nr->p_diag_cur_bytes_in_flight = new_p_cur_bytes_in_flight; + + if (new_p_cur_state != NULL) + nr->p_diag_cur_state = new_p_cur_state; + + newreno_update_diag(nr); + return 1; +} + +static void unbind_diag(OSSL_PARAM *params, const char *param_name, + void **pp) +{ + const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, param_name); + + if (p != NULL) + *pp = NULL; +} + +static int newreno_unbind_diagnostic(OSSL_CC_DATA *cc, OSSL_PARAM *params) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + unbind_diag(params, OSSL_CC_OPTION_MAX_DGRAM_PAYLOAD_LEN, + (void **)&nr->p_diag_max_dgram_payload_len); + unbind_diag(params, OSSL_CC_OPTION_CUR_CWND_SIZE, + (void **)&nr->p_diag_cur_cwnd_size); + unbind_diag(params, OSSL_CC_OPTION_MIN_CWND_SIZE, + (void **)&nr->p_diag_min_cwnd_size); + unbind_diag(params, OSSL_CC_OPTION_CUR_BYTES_IN_FLIGHT, + (void **)&nr->p_diag_cur_bytes_in_flight); + unbind_diag(params, OSSL_CC_OPTION_CUR_STATE, + (void **)&nr->p_diag_cur_state); + return 1; +} + +static void newreno_update_diag(OSSL_CC_NEWRENO *nr) +{ + if (nr->p_diag_max_dgram_payload_len != NULL) + *nr->p_diag_max_dgram_payload_len = nr->max_dgram_size; + + if (nr->p_diag_cur_cwnd_size != NULL) + *nr->p_diag_cur_cwnd_size = nr->cong_wnd; + + if (nr->p_diag_min_cwnd_size != NULL) + *nr->p_diag_min_cwnd_size = nr->k_min_wnd; + + if (nr->p_diag_cur_bytes_in_flight != NULL) + *nr->p_diag_cur_bytes_in_flight = nr->bytes_in_flight; + + if (nr->p_diag_cur_state != NULL) { + if (nr->in_congestion_recovery) + *nr->p_diag_cur_state = 'R'; + else if (nr->cong_wnd < nr->slow_start_thresh) + *nr->p_diag_cur_state = 'S'; + else + *nr->p_diag_cur_state = 'A'; + } +} + +static int newreno_in_cong_recovery(OSSL_CC_NEWRENO *nr, OSSL_TIME tx_time) +{ + return ossl_time_compare(tx_time, nr->cong_recovery_start_time) <= 0; +} + +static void newreno_cong(OSSL_CC_NEWRENO *nr, OSSL_TIME tx_time) +{ + int err = 0; + + /* No reaction if already in a recovery period. */ + if (newreno_in_cong_recovery(nr, tx_time)) + return; + + /* Start a new recovery period. */ + nr->in_congestion_recovery = 1; + nr->cong_recovery_start_time = nr->now_cb(nr->now_cb_arg); + + /* slow_start_thresh = cong_wnd * loss_reduction_factor */ + nr->slow_start_thresh + = safe_muldiv_u64(nr->cong_wnd, + nr->k_loss_reduction_factor_num, + nr->k_loss_reduction_factor_den, + &err); + + if (err) + nr->slow_start_thresh = UINT64_MAX; + + nr->cong_wnd = nr->slow_start_thresh; + if (nr->cong_wnd < nr->k_min_wnd) + nr->cong_wnd = nr->k_min_wnd; +} + +static void newreno_flush(OSSL_CC_NEWRENO *nr, uint32_t flags) +{ + if (!nr->processing_loss) + return; + + newreno_cong(nr, nr->tx_time_of_last_loss); + + if ((flags & OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION) != 0) { + nr->cong_wnd = nr->k_min_wnd; + nr->cong_recovery_start_time = ossl_time_zero(); + } + + nr->processing_loss = 0; + newreno_update_diag(nr); +} + +static uint64_t newreno_get_tx_allowance(OSSL_CC_DATA *cc) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + if (nr->bytes_in_flight >= nr->cong_wnd) + return 0; + + return nr->cong_wnd - nr->bytes_in_flight; +} + +static OSSL_TIME newreno_get_wakeup_deadline(OSSL_CC_DATA *cc) +{ + if (newreno_get_tx_allowance(cc) > 0) { + /* We have TX allowance now so wakeup immediately */ + return ossl_time_zero(); + } else { + /* + * The NewReno congestion controller does not vary its state in time, + * only in response to stimulus. + */ + return ossl_time_infinite(); + } +} + +static int newreno_on_data_sent(OSSL_CC_DATA *cc, uint64_t num_bytes) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + nr->bytes_in_flight += num_bytes; + newreno_update_diag(nr); + return 1; +} + +static int newreno_is_cong_limited(OSSL_CC_NEWRENO *nr) +{ + uint64_t wnd_rem; + + /* We are congestion-limited if we are already at the congestion window. */ + if (nr->bytes_in_flight >= nr->cong_wnd) + return 1; + + wnd_rem = nr->cong_wnd - nr->bytes_in_flight; + + /* + * Consider ourselves congestion-limited if less than three datagrams' worth + * of congestion window remains to be spent, or if we are in slow start and + * have consumed half of our window. + */ + return (nr->cong_wnd < nr->slow_start_thresh && wnd_rem <= nr->cong_wnd / 2) + || wnd_rem <= 3 * nr->max_dgram_size; +} + +static int newreno_on_data_acked(OSSL_CC_DATA *cc, + const OSSL_CC_ACK_INFO *info) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + /* + * Packet has been acked. Firstly, remove it from the aggregate count of + * bytes in flight. + */ + nr->bytes_in_flight -= info->tx_size; + + /* + * We use acknowledgement of data as a signal that we are not at channel + * capacity and that it may be reasonable to increase the congestion window. + * However, acknowledgement is not a useful signal that there is further + * capacity if we are not actually saturating the congestion window that we + * already have (for example, if the application is not generating much data + * or we are limited by flow control). Therefore, we only expand the + * congestion window if we are consuming a significant fraction of the + * congestion window. + */ + if (!newreno_is_cong_limited(nr)) + goto out; + + /* + * We can handle acknowledgement of a packet in one of three ways + * depending on our current state: + * + * - Congestion Recovery: Do nothing. We don't start increasing + * the congestion window in response to acknowledgements until + * we are no longer in the Congestion Recovery state. + * + * - Slow Start: Increase the congestion window using the slow + * start scale. + * + * - Congestion Avoidance: Increase the congestion window using + * the congestion avoidance scale. + */ + if (newreno_in_cong_recovery(nr, info->tx_time)) { + /* Congestion recovery, do nothing. */ + } else if (nr->cong_wnd < nr->slow_start_thresh) { + /* When this condition is true we are in the Slow Start state. */ + nr->cong_wnd += info->tx_size; + nr->in_congestion_recovery = 0; + } else { + /* Otherwise, we are in the Congestion Avoidance state. */ + nr->bytes_acked += info->tx_size; + + /* + * Avoid integer division as per RFC 9002 s. B.5. / RFC3465 s. 2.1. + */ + if (nr->bytes_acked >= nr->cong_wnd) { + nr->bytes_acked -= nr->cong_wnd; + nr->cong_wnd += nr->max_dgram_size; + } + + nr->in_congestion_recovery = 0; + } + +out: + newreno_update_diag(nr); + return 1; +} + +static int newreno_on_data_lost(OSSL_CC_DATA *cc, + const OSSL_CC_LOSS_INFO *info) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + if (info->tx_size > nr->bytes_in_flight) + return 0; + + nr->bytes_in_flight -= info->tx_size; + + if (!nr->processing_loss) { + + if (ossl_time_compare(info->tx_time, nr->tx_time_of_last_loss) <= 0) + /* + * After triggering congestion due to a lost packet at time t, don't + * trigger congestion again due to any subsequently detected lost + * packet at a time s < t, as we've effectively already signalled + * congestion on loss of that and subsequent packets. + */ + goto out; + + nr->processing_loss = 1; + + /* + * Cancel any pending window increase in the Congestion Avoidance state. + */ + nr->bytes_acked = 0; + } + + nr->tx_time_of_last_loss + = ossl_time_max(nr->tx_time_of_last_loss, info->tx_time); + +out: + newreno_update_diag(nr); + return 1; +} + +static int newreno_on_data_lost_finished(OSSL_CC_DATA *cc, uint32_t flags) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + newreno_flush(nr, flags); + return 1; +} + +static int newreno_on_data_invalidated(OSSL_CC_DATA *cc, + uint64_t num_bytes) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + nr->bytes_in_flight -= num_bytes; + newreno_update_diag(nr); + return 1; +} + +static int newreno_on_ecn(OSSL_CC_DATA *cc, + const OSSL_CC_ECN_INFO *info) +{ + OSSL_CC_NEWRENO *nr = (OSSL_CC_NEWRENO *)cc; + + nr->processing_loss = 1; + nr->bytes_acked = 0; + nr->tx_time_of_last_loss = info->largest_acked_time; + newreno_flush(nr, 0); + return 1; +} + +const OSSL_CC_METHOD ossl_cc_newreno_method = { + newreno_new, + newreno_free, + newreno_reset, + newreno_set_input_params, + newreno_bind_diagnostic, + newreno_unbind_diagnostic, + newreno_get_tx_allowance, + newreno_get_wakeup_deadline, + newreno_on_data_sent, + newreno_on_data_acked, + newreno_on_data_lost, + newreno_on_data_lost_finished, + newreno_on_data_invalidated, + newreno_on_ecn, +}; diff --git a/ssl/quic/quic_ackm.c b/ssl/quic/quic_ackm.c new file mode 100644 index 0000000000..75a1e5741a --- /dev/null +++ b/ssl/quic/quic_ackm.c @@ -0,0 +1,1725 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_ackm.h" +#include "internal/uint_set.h" +#include "internal/common.h" +#include + +DEFINE_LIST_OF(tx_history, OSSL_ACKM_TX_PKT); + +/* + * TX Packet History + * ***************** + * + * The TX Packet History object tracks information about packets which have been + * sent for which we later expect to receive an ACK. It is essentially a simple + * database keeping a list of packet information structures in packet number + * order which can also be looked up directly by packet number. + * + * We currently only allow packets to be appended to the list (i.e. the packet + * numbers of the packets appended to the list must monotonically increase), as + * we should not currently need more general functionality such as a sorted list + * insert. + */ +struct tx_pkt_history_st { + /* A linked list of all our packets. */ + OSSL_LIST(tx_history) packets; + + /* + * Mapping from packet numbers (uint64_t) to (OSSL_ACKM_TX_PKT *) + * + * Invariant: A packet is in this map if and only if it is in the linked + * list. + */ + LHASH_OF(OSSL_ACKM_TX_PKT) *map; + + /* + * The lowest packet number which may currently be added to the history list + * (inclusive). We do not allow packet numbers to be added to the history + * list non-monotonically, so packet numbers must be greater than or equal + * to this value. + */ + uint64_t watermark; + + /* + * Packet number of the highest packet info structure we have yet appended + * to the list. This is usually one less than watermark, except when we have + * not added any packet yet. + */ + uint64_t highest_sent; +}; + +DEFINE_LHASH_OF_EX(OSSL_ACKM_TX_PKT); + +static unsigned long tx_pkt_info_hash(const OSSL_ACKM_TX_PKT *pkt) +{ + /* Using low bits of the packet number as the hash should be enough */ + return (unsigned long)pkt->pkt_num; +} + +static int tx_pkt_info_compare(const OSSL_ACKM_TX_PKT *a, + const OSSL_ACKM_TX_PKT *b) +{ + if (a->pkt_num < b->pkt_num) + return -1; + if (a->pkt_num > b->pkt_num) + return 1; + return 0; +} + +static int +tx_pkt_history_init(struct tx_pkt_history_st *h) +{ + ossl_list_tx_history_init(&h->packets); + h->watermark = 0; + h->highest_sent = 0; + + h->map = lh_OSSL_ACKM_TX_PKT_new(tx_pkt_info_hash, tx_pkt_info_compare); + if (h->map == NULL) + return 0; + + return 1; +} + +static void +tx_pkt_history_destroy(struct tx_pkt_history_st *h) +{ + lh_OSSL_ACKM_TX_PKT_free(h->map); + h->map = NULL; + ossl_list_tx_history_init(&h->packets); +} + +static int +tx_pkt_history_add_actual(struct tx_pkt_history_st *h, + OSSL_ACKM_TX_PKT *pkt) +{ + OSSL_ACKM_TX_PKT *existing; + + /* + * There should not be any existing packet with this number + * in our mapping. + */ + existing = lh_OSSL_ACKM_TX_PKT_retrieve(h->map, pkt); + if (!ossl_assert(existing == NULL)) + return 0; + + /* Should not already be in a list. */ + if (!ossl_assert(ossl_list_tx_history_next(pkt) == NULL + && ossl_list_tx_history_prev(pkt) == NULL)) + return 0; + + lh_OSSL_ACKM_TX_PKT_insert(h->map, pkt); + + ossl_list_tx_history_insert_tail(&h->packets, pkt); + return 1; +} + +/* Adds a packet information structure to the history list. */ +static int +tx_pkt_history_add(struct tx_pkt_history_st *h, + OSSL_ACKM_TX_PKT *pkt) +{ + if (!ossl_assert(pkt->pkt_num >= h->watermark)) + return 0; + + if (tx_pkt_history_add_actual(h, pkt) < 1) + return 0; + + h->watermark = pkt->pkt_num + 1; + h->highest_sent = pkt->pkt_num; + return 1; +} + +/* Retrieve a packet information structure by packet number. */ +static OSSL_ACKM_TX_PKT * +tx_pkt_history_by_pkt_num(struct tx_pkt_history_st *h, uint64_t pkt_num) +{ + OSSL_ACKM_TX_PKT key; + + key.pkt_num = pkt_num; + + return lh_OSSL_ACKM_TX_PKT_retrieve(h->map, &key); +} + +/* Remove a packet information structure from the history log. */ +static int +tx_pkt_history_remove(struct tx_pkt_history_st *h, uint64_t pkt_num) +{ + OSSL_ACKM_TX_PKT key, *pkt; + key.pkt_num = pkt_num; + + pkt = tx_pkt_history_by_pkt_num(h, pkt_num); + if (pkt == NULL) + return 0; + + ossl_list_tx_history_remove(&h->packets, pkt); + lh_OSSL_ACKM_TX_PKT_delete(h->map, &key); + return 1; +} + +/* + * RX Packet Number Tracking + * ************************* + * + * **Background.** The RX side of the ACK manager must track packets we have + * received for which we have to generate ACK frames. Broadly, this means we + * store a set of packet numbers which we have received but which we do not know + * for a fact that the transmitter knows we have received. + * + * This must handle various situations: + * + * 1. We receive a packet but have not sent an ACK yet, so the transmitter + * does not know whether we have received it or not yet. + * + * 2. We receive a packet and send an ACK which is lost. We do not + * immediately know that the ACK was lost and the transmitter does not know + * that we have received the packet. + * + * 3. We receive a packet and send an ACK which is received by the + * transmitter. The transmitter does not immediately respond with an ACK, + * or responds with an ACK which is lost. The transmitter knows that we + * have received the packet, but we do not know for sure that it knows, + * because the ACK we sent could have been lost. + * + * 4. We receive a packet and send an ACK which is received by the + * transmitter. The transmitter subsequently sends us an ACK which confirms + * its receipt of the ACK we sent, and we successfully receive that ACK, so + * we know that the transmitter knows, that we received the original + * packet. + * + * Only when we reach case (4) are we relieved of any need to track a given + * packet number we have received, because only in this case do we know for sure + * that the peer knows we have received the packet. Having reached case (4) we + * will never again need to generate an ACK containing the PN in question, but + * until we reach that point, we must keep track of the PN as not having been + * provably ACKed, as we may have to keep generating ACKs for the given PN not + * just until the transmitter receives one, but until we know that it has + * received one. This will be referred to herein as "provably ACKed". + * + * **Duplicate handling.** The above discusses the case where we have received a + * packet with a given PN but are at best unsure whether the sender knows we + * have received it or not. However, we must also handle the case where we have + * yet to receive a packet with a given PN in the first place. The reason for + * this is because of the requirement expressed by RFC 9000 s. 12.3: + * + * "A receiver MUST discard a newly unprotected packet unless it is certain + * that it has not processed another packet with the same packet number from + * the same packet number space." + * + * We must ensure we never process a duplicate PN. As such, each possible PN we + * can receive must exist in one of the following logical states: + * + * - We have never processed this PN before + * (so if we receive such a PN, it can be processed) + * + * - We have processed this PN but it has not yet been provably ACKed + * (and should therefore be in any future ACK frame generated; + * if we receive such a PN again, it must be ignored) + * + * - We have processed this PN and it has been provably ACKed + * (if we receive such a PN again, it must be ignored) + * + * However, if we were to track this state for every PN ever used in the history + * of a connection, the amount of state required would increase unboundedly as + * the connection goes on (for example, we would have to store a set of every PN + * ever received.) + * + * RFC 9000 s. 12.3 continues: + * + * "Endpoints that track all individual packets for the purposes of detecting + * duplicates are at risk of accumulating excessive state. The data required + * for detecting duplicates can be limited by maintaining a minimum packet + * number below which all packets are immediately dropped." + * + * Moreover, RFC 9000 s. 13.2.3 states that: + * + * "A receiver MUST retain an ACK Range unless it can ensure that it will not + * subsequently accept packets with numbers in that range. Maintaining a + * minimum packet number that increases as ranges are discarded is one way to + * achieve this with minimal state." + * + * This touches on a subtlety of the original requirement quoted above: the + * receiver MUST discard a packet unless it is certain that it has not processed + * another packet with the same PN. However, this does not forbid the receiver + * from also discarding some PNs even though it has not yet processed them. In + * other words, implementations must be conservative and err in the direction of + * assuming a packet is a duplicate, but it is acceptable for this to come at + * the cost of falsely identifying some packets as duplicates. + * + * This allows us to bound the amount of state we must keep, and we adopt the + * suggested strategy quoted above to do so. We define a watermark PN below + * which all PNs are in the same state. This watermark is only ever increased. + * Thus the PNs the state for which needs to be explicitly tracked is limited to + * only a small number of recent PNs, and all older PNs have an assumed state. + * + * Any given PN thus falls into one of the following states: + * + * - (A) The PN is above the watermark but we have not yet received it. + * + * If we receive such a PN, we should process it and record the PN as + * received. + * + * - (B) The PN is above the watermark and we have received it. + * + * The PN should be included in any future ACK frame we generate. + * If we receive such a PN again, we should ignore it. + * + * - (C) The PN is below the watermark. + * + * We do not know whether a packet with the given PN was received or + * not. To be safe, if we receive such a packet, it is not processed. + * + * Note that state (C) corresponds to both "we have processed this PN and it has + * been provably ACKed" logical state and a subset of the PNs in the "we have + * never processed this PN before" logical state (namely all PNs which were lost + * and never received, but which are not recent enough to be above the + * watermark). The reason we can merge these states and avoid tracking states + * for the PNs in this state is because the provably ACKed and never-received + * states are functionally identical in terms of how we need to handle them: we + * don't need to do anything for PNs in either of these states, so we don't have + * to care about PNs in this state nor do we have to care about distinguishing + * the two states for a given PN. + * + * Note that under this scheme provably ACKed PNs are by definition always below + * the watermark; therefore, it follows that when a PN becomes provably ACKed, + * the watermark must be immediately increased to exceed it (otherwise we would + * keep reporting it in future ACK frames). + * + * This is in line with RFC 9000 s. 13.2.4's suggested strategy on when + * to advance the watermark: + * + * "When a packet containing an ACK frame is sent, the Largest Acknowledged + * field in that frame can be saved. When a packet containing an ACK frame is + * acknowledged, the receiver can stop acknowledging packets less than or + * equal to the Largest Acknowledged field in the sent ACK frame." + * + * This is where our scheme's false positives arise. When a packet containing an + * ACK frame is itself ACK'd, PNs referenced in that ACK frame become provably + * acked, and the watermark is bumped accordingly. However, the Largest + * Acknowledged field does not imply that all lower PNs have been received, + * because there may be gaps expressed in the ranges of PNs expressed by that + * and previous ACK frames. Thus, some unreceived PNs may be moved below the + * watermark, and we may subsequently reject those PNs as possibly being + * duplicates even though we have not actually received those PNs. Since we bump + * the watermark when a PN becomes provably ACKed, it follows that an unreceived + * PN falls below the watermark (and thus becomes a false positive for the + * purposes of duplicate detection) when a higher-numbered PN becomes provably + * ACKed. + * + * Thus, when PN n becomes provably acked, any unreceived PNs in the range [0, + * n) will no longer be processed. Although datagrams may be reordered in the + * network, a PN we receive can only become provably ACKed after our own + * subsequently generated ACK frame is sent in a future TX packet, and then we + * receive another RX PN acknowledging that TX packet. This means that a given RX + * PN can only become provably ACKed at least 1 RTT after it is received; it is + * unlikely that any reordered datagrams will still be "in the network" (and not + * lost) by this time. If this does occur for whatever reason and a late PN is + * received, the packet will be discarded unprocessed and the PN is simply + * handled as though lost (a "written off" PN). + * + * **Data structure.** Our state for the RX handling side of the ACK manager, as + * discussed above, mainly comprises: + * + * a) a logical set of PNs, and + * b) a monotonically increasing PN counter (the watermark). + * + * For (a), we define a data structure which stores a logical set of PNs, which + * we use to keep track of which PNs we have received but which have not yet + * been provably ACKed, and thus will later need to generate an ACK frame for. + * + * The correspondence with the logical states discussed above is as follows. A + * PN is in state (C) if it is below the watermark; otherwise it is in state (B) + * if it is in the logical set of PNs, and in state (A) otherwise. + * + * Note that PNs are only removed from the PN set (when they become provably + * ACKed or written off) by virtue of advancement of the watermark. Removing PNs + * from the PN set any other way would be ambiguous as it would be + * indistinguishable from a PN we have not yet received and risk us processing a + * duplicate packet. In other words, for a given PN: + * + * - State (A) can transition to state (B) or (C) + * - State (B) can transition to state (C) only + * - State (C) is the terminal state + * + * We can query the logical set data structure for PNs which have been received + * but which have not been provably ACKed when we want to generate ACK frames. + * Since ACK frames can be lost and/or we might not know that the peer has + * successfully received them, we might generate multiple ACK frames covering a + * given PN until that PN becomes provably ACKed and we finally remove it from + * our set (by bumping the watermark) as no longer being our concern. + * + * The data structure used is the UINT_SET structure defined in uint_set.h, + * which is used as a PN set. We use the following operations of the structure: + * + * Insert Range: Used when we receive a new PN. + * + * Remove Range: Used when bumping the watermark. + * + * Query: Used to determine if a PN is in the set. + * + * **Possible duplicates.** A PN is considered a possible duplicate when either: + * + * a) its PN is already in the PN set (i.e. has already been received), or + * b) its PN is below the watermark (i.e. was provably ACKed or written off). + * + * A packet with a given PN is considered 'processable' when that PN is not + * considered a possible duplicate (see ossl_ackm_is_rx_pn_processable). + * + * **TX/RX interaction.** The watermark is bumped whenever an RX packet becomes + * provably ACKed. This occurs when an ACK frame is received by the TX side of + * the ACK manager; thus, there is necessary interaction between the TX and RX + * sides of the ACK manager. + * + * This is implemented as follows. When a packet is queued as sent in the TX + * side of the ACK manager, it may optionally have a Largest Acked value set on + * it. The user of the ACK manager should do this if the packet being + * transmitted contains an ACK frame, by setting the field to the Largest Acked + * field of that frame. Otherwise, this field should be set to QUIC_PN_INVALID. + * When a TX packet is eventually acknowledged which has this field set, it is + * used to update the state of the RX side of the ACK manager by bumping the + * watermark accordingly. + */ +struct rx_pkt_history_st { + UINT_SET set; + + /* + * Invariant: PNs below this are not in the set. + * Invariant: This is monotonic and only ever increases. + */ + QUIC_PN watermark; +}; + +static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h, + QUIC_PN watermark); + +static void rx_pkt_history_init(struct rx_pkt_history_st *h) +{ + ossl_uint_set_init(&h->set); + h->watermark = 0; +} + +static void rx_pkt_history_destroy(struct rx_pkt_history_st *h) +{ + ossl_uint_set_destroy(&h->set); +} + +/* + * Limit the number of ACK ranges we store to prevent resource consumption DoS + * attacks. + */ +#define MAX_RX_ACK_RANGES 32 + +static void rx_pkt_history_trim_range_count(struct rx_pkt_history_st *h) +{ + QUIC_PN highest = QUIC_PN_INVALID; + + while (ossl_list_uint_set_num(&h->set) > MAX_RX_ACK_RANGES) { + UINT_RANGE r = ossl_list_uint_set_head(&h->set)->range; + + highest = (highest == QUIC_PN_INVALID) + ? r.end : ossl_quic_pn_max(highest, r.end); + + ossl_uint_set_remove(&h->set, &r); + } + + /* + * Bump watermark to cover all PNs we removed to avoid accidental + * reprocessing of packets. + */ + if (highest != QUIC_PN_INVALID) + rx_pkt_history_bump_watermark(h, highest + 1); +} + +static int rx_pkt_history_add_pn(struct rx_pkt_history_st *h, + QUIC_PN pn) +{ + UINT_RANGE r; + + r.start = pn; + r.end = pn; + + if (pn < h->watermark) + return 1; /* consider this a success case */ + + if (ossl_uint_set_insert(&h->set, &r) != 1) + return 0; + + rx_pkt_history_trim_range_count(h); + return 1; +} + +static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h, + QUIC_PN watermark) +{ + UINT_RANGE r; + + if (watermark <= h->watermark) + return 1; + + /* Remove existing PNs below the watermark. */ + r.start = 0; + r.end = watermark - 1; + if (ossl_uint_set_remove(&h->set, &r) != 1) + return 0; + + h->watermark = watermark; + return 1; +} + +/* + * ACK Manager Implementation + * ************************** + * Implementation of the ACK manager proper. + */ + +/* Constants used by the ACK manager; see RFC 9002. */ +#define K_GRANULARITY (1 * OSSL_TIME_MS) +#define K_PKT_THRESHOLD 3 +#define K_TIME_THRESHOLD_NUM 9 +#define K_TIME_THRESHOLD_DEN 8 + +/* The maximum number of times we allow PTO to be doubled. */ +#define MAX_PTO_COUNT 16 + +/* Default maximum amount of time to leave an ACK-eliciting packet un-ACK'd. */ +#define DEFAULT_TX_MAX_ACK_DELAY ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY) + +struct ossl_ackm_st { + /* Our list of transmitted packets. Corresponds to RFC 9002 sent_packets. */ + struct tx_pkt_history_st tx_history[QUIC_PN_SPACE_NUM]; + + /* Our list of received PNs which are not yet provably acked. */ + struct rx_pkt_history_st rx_history[QUIC_PN_SPACE_NUM]; + + /* Polymorphic dependencies that we consume. */ + OSSL_TIME (*now)(void *arg); + void *now_arg; + OSSL_STATM *statm; + const OSSL_CC_METHOD *cc_method; + OSSL_CC_DATA *cc_data; + + /* RFC 9002 variables. */ + uint32_t pto_count; + QUIC_PN largest_acked_pkt[QUIC_PN_SPACE_NUM]; + OSSL_TIME time_of_last_ack_eliciting_pkt[QUIC_PN_SPACE_NUM]; + OSSL_TIME loss_time[QUIC_PN_SPACE_NUM]; + OSSL_TIME loss_detection_deadline; + + /* Lowest PN which is still not known to be ACKed. */ + QUIC_PN lowest_unacked_pkt[QUIC_PN_SPACE_NUM]; + + /* Time at which we got our first RTT sample, or 0. */ + OSSL_TIME first_rtt_sample; + + /* + * A packet's num_bytes are added to this if it is inflight, + * and removed again once ack'd/lost/discarded. + */ + uint64_t bytes_in_flight; + + /* + * A packet's num_bytes are added to this if it is both inflight and + * ack-eliciting, and removed again once ack'd/lost/discarded. + */ + uint64_t ack_eliciting_bytes_in_flight[QUIC_PN_SPACE_NUM]; + + /* Count of ECN-CE events. */ + uint64_t peer_ecnce[QUIC_PN_SPACE_NUM]; + + /* Set to 1 when the handshake is confirmed. */ + char handshake_confirmed; + + /* Set to 1 when the peer has completed address validation. */ + char peer_completed_addr_validation; + + /* Set to 1 when a PN space has been discarded. */ + char discarded[QUIC_PN_SPACE_NUM]; + + /* Set to 1 when we think an ACK frame should be generated. */ + char rx_ack_desired[QUIC_PN_SPACE_NUM]; + + /* Set to 1 if an ACK frame has ever been generated. */ + char rx_ack_generated[QUIC_PN_SPACE_NUM]; + + /* Probe request counts for reporting to the user. */ + OSSL_ACKM_PROBE_INFO pending_probe; + + /* Generated ACK frames for each PN space. */ + OSSL_QUIC_FRAME_ACK ack[QUIC_PN_SPACE_NUM]; + OSSL_QUIC_ACK_RANGE ack_ranges[QUIC_PN_SPACE_NUM][MAX_RX_ACK_RANGES]; + + /* Other RX state. */ + /* Largest PN we have RX'd. */ + QUIC_PN rx_largest_pn[QUIC_PN_SPACE_NUM]; + + /* Time at which the PN in rx_largest_pn was RX'd. */ + OSSL_TIME rx_largest_time[QUIC_PN_SPACE_NUM]; + + /* + * ECN event counters. Each time we receive a packet with a given ECN label, + * the corresponding ECN counter here is incremented. + */ + uint64_t rx_ect0[QUIC_PN_SPACE_NUM]; + uint64_t rx_ect1[QUIC_PN_SPACE_NUM]; + uint64_t rx_ecnce[QUIC_PN_SPACE_NUM]; + + /* + * Number of ACK-eliciting packets since last ACK. We use this to defer + * emitting ACK frames until a threshold number of ACK-eliciting packets + * have been received. + */ + uint32_t rx_ack_eliciting_pkts_since_last_ack[QUIC_PN_SPACE_NUM]; + + /* + * The ACK frame coalescing deadline at which we should flush any unsent ACK + * frames. + */ + OSSL_TIME rx_ack_flush_deadline[QUIC_PN_SPACE_NUM]; + + /* + * The RX maximum ACK delay (the maximum amount of time our peer might + * wait to send us an ACK after receiving an ACK-eliciting packet). + */ + OSSL_TIME rx_max_ack_delay; + + /* + * The TX maximum ACK delay (the maximum amount of time we allow ourselves + * to wait before generating an ACK after receiving an ACK-eliciting + * packet). + */ + OSSL_TIME tx_max_ack_delay; + + /* Callbacks for deadline updates. */ + void (*loss_detection_deadline_cb)(OSSL_TIME deadline, void *arg); + void *loss_detection_deadline_cb_arg; + + void (*ack_deadline_cb)(OSSL_TIME deadline, int pkt_space, void *arg); + void *ack_deadline_cb_arg; +}; + +static ossl_inline uint32_t min_u32(uint32_t x, uint32_t y) +{ + return x < y ? x : y; +} + +/* + * Get TX history for a given packet number space. Must not have been + * discarded. + */ +static struct tx_pkt_history_st *get_tx_history(OSSL_ACKM *ackm, int pkt_space) +{ + assert(!ackm->discarded[pkt_space]); + + return &ackm->tx_history[pkt_space]; +} + +/* + * Get RX history for a given packet number space. Must not have been + * discarded. + */ +static struct rx_pkt_history_st *get_rx_history(OSSL_ACKM *ackm, int pkt_space) +{ + assert(!ackm->discarded[pkt_space]); + + return &ackm->rx_history[pkt_space]; +} + +/* Does the newly-acknowledged list contain any ack-eliciting packet? */ +static int ack_includes_ack_eliciting(OSSL_ACKM_TX_PKT *pkt) +{ + for (; pkt != NULL; pkt = pkt->anext) + if (pkt->is_ack_eliciting) + return 1; + + return 0; +} + +/* Return number of ACK-eliciting bytes in flight across all PN spaces. */ +static uint64_t ackm_ack_eliciting_bytes_in_flight(OSSL_ACKM *ackm) +{ + int i; + uint64_t total = 0; + + for (i = 0; i < QUIC_PN_SPACE_NUM; ++i) + total += ackm->ack_eliciting_bytes_in_flight[i]; + + return total; +} + +/* Return 1 if the range contains the given PN. */ +static int range_contains(const OSSL_QUIC_ACK_RANGE *range, QUIC_PN pn) +{ + return pn >= range->start && pn <= range->end; +} + +/* + * Given a logical representation of an ACK frame 'ack', create a singly-linked + * list of the newly ACK'd frames; that is, of frames which are matched by the + * list of PN ranges contained in the ACK frame. The packet structures in the + * list returned are removed from the TX history list. Returns a pointer to the + * list head (or NULL) if empty. + */ +static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_newly_acked_pkts(OSSL_ACKM *ackm, + const OSSL_QUIC_FRAME_ACK *ack, + int pkt_space) +{ + OSSL_ACKM_TX_PKT *acked_pkts = NULL, **fixup = &acked_pkts, *pkt, *pprev; + struct tx_pkt_history_st *h; + size_t ridx = 0; + + assert(ack->num_ack_ranges > 0); + + /* + * Our history list is a list of packets sorted in ascending order + * by packet number. + * + * ack->ack_ranges is a list of packet number ranges in descending order. + * + * Walk through our history list from the end in order to efficiently detect + * membership in the specified ack ranges. As an optimization, we use our + * hashtable to try and skip to the first matching packet. This may fail if + * the ACK ranges given include nonexistent packets. + */ + h = get_tx_history(ackm, pkt_space); + + pkt = tx_pkt_history_by_pkt_num(h, ack->ack_ranges[0].end); + if (pkt == NULL) + pkt = ossl_list_tx_history_tail(&h->packets); + + for (; pkt != NULL; pkt = pprev) { + /* + * Save prev value as it will be zeroed if we remove the packet from the + * history list below. + */ + pprev = ossl_list_tx_history_prev(pkt); + + for (;; ++ridx) { + if (ridx >= ack->num_ack_ranges) { + /* + * We have exhausted all ranges so stop here, even if there are + * more packets to look at. + */ + goto stop; + } + + if (range_contains(&ack->ack_ranges[ridx], pkt->pkt_num)) { + /* We have matched this range. */ + tx_pkt_history_remove(h, pkt->pkt_num); + + *fixup = pkt; + fixup = &pkt->anext; + *fixup = NULL; + break; + } else if (pkt->pkt_num > ack->ack_ranges[ridx].end) { + /* + * We have not reached this range yet in our list, so do not + * advance ridx. + */ + break; + } else { + /* + * We have moved beyond this range, so advance to the next range + * and try matching again. + */ + assert(pkt->pkt_num < ack->ack_ranges[ridx].start); + continue; + } + } + } +stop: + + return acked_pkts; +} + +/* + * Create a singly-linked list of newly detected-lost packets in the given + * packet number space. Returns the head of the list or NULL if no packets were + * detected lost. The packets in the list are removed from the TX history list. + */ +static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_lost_pkts(OSSL_ACKM *ackm, + int pkt_space) +{ + OSSL_ACKM_TX_PKT *lost_pkts = NULL, **fixup = &lost_pkts, *pkt, *pnext; + OSSL_TIME loss_delay, lost_send_time, now; + OSSL_RTT_INFO rtt; + struct tx_pkt_history_st *h; + + assert(ackm->largest_acked_pkt[pkt_space] != QUIC_PN_INVALID); + + ossl_statm_get_rtt_info(ackm->statm, &rtt); + + ackm->loss_time[pkt_space] = ossl_time_zero(); + + loss_delay = ossl_time_multiply(ossl_time_max(rtt.latest_rtt, + rtt.smoothed_rtt), + K_TIME_THRESHOLD_NUM); + loss_delay = ossl_time_divide(loss_delay, K_TIME_THRESHOLD_DEN); + + /* Minimum time of K_GRANULARITY before packets are deemed lost. */ + loss_delay = ossl_time_max(loss_delay, ossl_ticks2time(K_GRANULARITY)); + + /* Packets sent before this time are deemed lost. */ + now = ackm->now(ackm->now_arg); + lost_send_time = ossl_time_subtract(now, loss_delay); + + h = get_tx_history(ackm, pkt_space); + pkt = ossl_list_tx_history_head(&h->packets); + + for (; pkt != NULL; pkt = pnext) { + assert(pkt_space == pkt->pkt_space); + + /* + * Save prev value as it will be zeroed if we remove the packet from the + * history list below. + */ + pnext = ossl_list_tx_history_next(pkt); + + if (pkt->pkt_num > ackm->largest_acked_pkt[pkt_space]) + continue; + + /* + * Mark packet as lost, or set time when it should be marked. + */ + if (ossl_time_compare(pkt->time, lost_send_time) <= 0 + || ackm->largest_acked_pkt[pkt_space] + >= pkt->pkt_num + K_PKT_THRESHOLD) { + tx_pkt_history_remove(h, pkt->pkt_num); + + *fixup = pkt; + fixup = &pkt->lnext; + *fixup = NULL; + } else { + if (ossl_time_is_zero(ackm->loss_time[pkt_space])) + ackm->loss_time[pkt_space] = + ossl_time_add(pkt->time, loss_delay); + else + ackm->loss_time[pkt_space] = + ossl_time_min(ackm->loss_time[pkt_space], + ossl_time_add(pkt->time, loss_delay)); + } + } + + return lost_pkts; +} + +static OSSL_TIME ackm_get_loss_time_and_space(OSSL_ACKM *ackm, int *pspace) +{ + OSSL_TIME time = ackm->loss_time[QUIC_PN_SPACE_INITIAL]; + int i, space = QUIC_PN_SPACE_INITIAL; + + for (i = space + 1; i < QUIC_PN_SPACE_NUM; ++i) + if (ossl_time_is_zero(time) + || ossl_time_compare(ackm->loss_time[i], time) == -1) { + time = ackm->loss_time[i]; + space = i; + } + + *pspace = space; + return time; +} + +static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space) +{ + OSSL_RTT_INFO rtt; + OSSL_TIME duration; + OSSL_TIME pto_timeout = ossl_time_infinite(), t; + int pto_space = QUIC_PN_SPACE_INITIAL, i; + + ossl_statm_get_rtt_info(ackm->statm, &rtt); + + duration + = ossl_time_add(rtt.smoothed_rtt, + ossl_time_max(ossl_time_multiply(rtt.rtt_variance, 4), + ossl_ticks2time(K_GRANULARITY))); + + duration + = ossl_time_multiply(duration, + (uint64_t)1 << min_u32(ackm->pto_count, + MAX_PTO_COUNT)); + + /* Anti-deadlock PTO starts from the current time. */ + if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0) { + assert(!ackm->peer_completed_addr_validation); + + *space = ackm->discarded[QUIC_PN_SPACE_INITIAL] + ? QUIC_PN_SPACE_HANDSHAKE + : QUIC_PN_SPACE_INITIAL; + return ossl_time_add(ackm->now(ackm->now_arg), duration); + } + + for (i = QUIC_PN_SPACE_INITIAL; i < QUIC_PN_SPACE_NUM; ++i) { + if (ackm->ack_eliciting_bytes_in_flight[i] == 0) + continue; + + if (i == QUIC_PN_SPACE_APP) { + /* Skip application data until handshake confirmed. */ + if (!ackm->handshake_confirmed) + break; + + /* Include max_ack_delay and backoff for app data. */ + if (!ossl_time_is_infinite(ackm->rx_max_ack_delay)) { + uint64_t factor + = (uint64_t)1 << min_u32(ackm->pto_count, MAX_PTO_COUNT); + + duration + = ossl_time_add(duration, + ossl_time_multiply(ackm->rx_max_ack_delay, + factor)); + } + } + + t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration); + if (ossl_time_compare(t, pto_timeout) < 0) { + pto_timeout = t; + pto_space = i; + } + } + + *space = pto_space; + return pto_timeout; +} + +static void ackm_set_loss_detection_timer_actual(OSSL_ACKM *ackm, + OSSL_TIME deadline) +{ + ackm->loss_detection_deadline = deadline; + + if (ackm->loss_detection_deadline_cb != NULL) + ackm->loss_detection_deadline_cb(deadline, + ackm->loss_detection_deadline_cb_arg); +} + +static int ackm_set_loss_detection_timer(OSSL_ACKM *ackm) +{ + int space; + OSSL_TIME earliest_loss_time, timeout; + + earliest_loss_time = ackm_get_loss_time_and_space(ackm, &space); + if (!ossl_time_is_zero(earliest_loss_time)) { + /* Time threshold loss detection. */ + ackm_set_loss_detection_timer_actual(ackm, earliest_loss_time); + return 1; + } + + if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0 + && ackm->peer_completed_addr_validation) { + /* + * Nothing to detect lost, so no timer is set. However, the client + * needs to arm the timer if the server might be blocked by the + * anti-amplification limit. + */ + ackm_set_loss_detection_timer_actual(ackm, ossl_time_zero()); + return 1; + } + + timeout = ackm_get_pto_time_and_space(ackm, &space); + ackm_set_loss_detection_timer_actual(ackm, timeout); + return 1; +} + +static int ackm_in_persistent_congestion(OSSL_ACKM *ackm, + const OSSL_ACKM_TX_PKT *lpkt) +{ + /* TODO(QUIC FUTURE): Persistent congestion not currently implemented. */ + return 0; +} + +static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space, + const OSSL_ACKM_TX_PKT *lpkt, int pseudo) +{ + const OSSL_ACKM_TX_PKT *p, *pnext; + OSSL_RTT_INFO rtt; + QUIC_PN largest_pn_lost = 0; + OSSL_CC_LOSS_INFO loss_info = {0}; + uint32_t flags = 0; + + for (p = lpkt; p != NULL; p = pnext) { + pnext = p->lnext; + + if (p->is_inflight) { + ackm->bytes_in_flight -= p->num_bytes; + if (p->is_ack_eliciting) + ackm->ack_eliciting_bytes_in_flight[p->pkt_space] + -= p->num_bytes; + + if (p->pkt_num > largest_pn_lost) + largest_pn_lost = p->pkt_num; + + if (!pseudo) { + /* + * If this is pseudo-loss (e.g. during connection retry) we do not + * inform the CC as it is not a real loss and not reflective of + * network conditions. + */ + loss_info.tx_time = p->time; + loss_info.tx_size = p->num_bytes; + + ackm->cc_method->on_data_lost(ackm->cc_data, &loss_info); + } + } + + p->on_lost(p->cb_arg); + } + + /* + * Persistent congestion can only be considered if we have gotten at least + * one RTT sample. + */ + ossl_statm_get_rtt_info(ackm->statm, &rtt); + if (!ossl_time_is_zero(ackm->first_rtt_sample) + && ackm_in_persistent_congestion(ackm, lpkt)) + flags |= OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION; + + ackm->cc_method->on_data_lost_finished(ackm->cc_data, flags); +} + +static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt) +{ + const OSSL_ACKM_TX_PKT *anext; + QUIC_PN last_pn_acked = 0; + OSSL_CC_ACK_INFO ainfo = {0}; + + for (; apkt != NULL; apkt = anext) { + if (apkt->is_inflight) { + ackm->bytes_in_flight -= apkt->num_bytes; + if (apkt->is_ack_eliciting) + ackm->ack_eliciting_bytes_in_flight[apkt->pkt_space] + -= apkt->num_bytes; + + if (apkt->pkt_num > last_pn_acked) + last_pn_acked = apkt->pkt_num; + + if (apkt->largest_acked != QUIC_PN_INVALID) + /* + * This can fail, but it is monotonic; worst case we try again + * next time. + */ + rx_pkt_history_bump_watermark(get_rx_history(ackm, + apkt->pkt_space), + apkt->largest_acked + 1); + } + + ainfo.tx_time = apkt->time; + ainfo.tx_size = apkt->num_bytes; + + anext = apkt->anext; + apkt->on_acked(apkt->cb_arg); /* may free apkt */ + + if (apkt->is_inflight) + ackm->cc_method->on_data_acked(ackm->cc_data, &ainfo); + } +} + +OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg), + void *now_arg, + OSSL_STATM *statm, + const OSSL_CC_METHOD *cc_method, + OSSL_CC_DATA *cc_data) +{ + OSSL_ACKM *ackm; + int i; + + ackm = OPENSSL_zalloc(sizeof(OSSL_ACKM)); + if (ackm == NULL) + return NULL; + + for (i = 0; i < (int)OSSL_NELEM(ackm->tx_history); ++i) { + ackm->largest_acked_pkt[i] = QUIC_PN_INVALID; + ackm->rx_ack_flush_deadline[i] = ossl_time_infinite(); + if (tx_pkt_history_init(&ackm->tx_history[i]) < 1) + goto err; + } + + for (i = 0; i < (int)OSSL_NELEM(ackm->rx_history); ++i) + rx_pkt_history_init(&ackm->rx_history[i]); + + ackm->now = now; + ackm->now_arg = now_arg; + ackm->statm = statm; + ackm->cc_method = cc_method; + ackm->cc_data = cc_data; + + ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY); + ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY; + + return ackm; + +err: + while (--i >= 0) + tx_pkt_history_destroy(&ackm->tx_history[i]); + + OPENSSL_free(ackm); + return NULL; +} + +void ossl_ackm_free(OSSL_ACKM *ackm) +{ + size_t i; + + if (ackm == NULL) + return; + + for (i = 0; i < OSSL_NELEM(ackm->tx_history); ++i) + if (!ackm->discarded[i]) { + tx_pkt_history_destroy(&ackm->tx_history[i]); + rx_pkt_history_destroy(&ackm->rx_history[i]); + } + + OPENSSL_free(ackm); +} + +int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt) +{ + struct tx_pkt_history_st *h = get_tx_history(ackm, pkt->pkt_space); + + /* Time must be set and not move backwards. */ + if (ossl_time_is_zero(pkt->time) + || ossl_time_compare(ackm->time_of_last_ack_eliciting_pkt[pkt->pkt_space], + pkt->time) > 0) + return 0; + + /* Must have non-zero number of bytes. */ + if (pkt->num_bytes == 0) + return 0; + + /* Does not make any sense for a non-in-flight packet to be ACK-eliciting. */ + if (!pkt->is_inflight && pkt->is_ack_eliciting) + return 0; + + if (tx_pkt_history_add(h, pkt) == 0) + return 0; + + if (pkt->is_inflight) { + if (pkt->is_ack_eliciting) { + ackm->time_of_last_ack_eliciting_pkt[pkt->pkt_space] = pkt->time; + ackm->ack_eliciting_bytes_in_flight[pkt->pkt_space] + += pkt->num_bytes; + } + + ackm->bytes_in_flight += pkt->num_bytes; + ackm_set_loss_detection_timer(ackm); + + ackm->cc_method->on_data_sent(ackm->cc_data, pkt->num_bytes); + } + + return 1; +} + +int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes) +{ + /* No-op on the client. */ + return 1; +} + +static void ackm_process_ecn(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack, + int pkt_space) +{ + struct tx_pkt_history_st *h; + OSSL_ACKM_TX_PKT *pkt; + OSSL_CC_ECN_INFO ecn_info = {0}; + + /* + * If the ECN-CE counter reported by the peer has increased, this could + * be a new congestion event. + */ + if (ack->ecnce > ackm->peer_ecnce[pkt_space]) { + ackm->peer_ecnce[pkt_space] = ack->ecnce; + + h = get_tx_history(ackm, pkt_space); + pkt = tx_pkt_history_by_pkt_num(h, ack->ack_ranges[0].end); + if (pkt == NULL) + return; + + ecn_info.largest_acked_time = pkt->time; + ackm->cc_method->on_ecn(ackm->cc_data, &ecn_info); + } +} + +int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack, + int pkt_space, OSSL_TIME rx_time) +{ + OSSL_ACKM_TX_PKT *na_pkts, *lost_pkts; + int must_set_timer = 0; + + if (ackm->largest_acked_pkt[pkt_space] == QUIC_PN_INVALID) + ackm->largest_acked_pkt[pkt_space] = ack->ack_ranges[0].end; + else + ackm->largest_acked_pkt[pkt_space] + = ossl_quic_pn_max(ackm->largest_acked_pkt[pkt_space], + ack->ack_ranges[0].end); + + /* + * If we get an ACK in the handshake space, address validation is completed. + * Make sure we update the timer, even if no packets were ACK'd. + */ + if (!ackm->peer_completed_addr_validation + && pkt_space == QUIC_PN_SPACE_HANDSHAKE) { + ackm->peer_completed_addr_validation = 1; + must_set_timer = 1; + } + + /* + * Find packets that are newly acknowledged and remove them from the list. + */ + na_pkts = ackm_detect_and_remove_newly_acked_pkts(ackm, ack, pkt_space); + if (na_pkts == NULL) { + if (must_set_timer) + ackm_set_loss_detection_timer(ackm); + + return 1; + } + + /* + * Update the RTT if the largest acknowledged is newly acked and at least + * one ACK-eliciting packet was newly acked. + * + * First packet in the list is always the one with the largest PN. + */ + if (na_pkts->pkt_num == ack->ack_ranges[0].end && + ack_includes_ack_eliciting(na_pkts)) { + OSSL_TIME now = ackm->now(ackm->now_arg), ack_delay; + if (ossl_time_is_zero(ackm->first_rtt_sample)) + ackm->first_rtt_sample = now; + + /* Enforce maximum ACK delay. */ + ack_delay = ack->delay_time; + if (ackm->handshake_confirmed) + ack_delay = ossl_time_min(ack_delay, ackm->rx_max_ack_delay); + + ossl_statm_update_rtt(ackm->statm, ack_delay, + ossl_time_subtract(now, na_pkts->time)); + } + + /* + * Process ECN information if present. + * + * We deliberately do most ECN processing in the ACKM rather than the + * congestion controller to avoid having to give the congestion controller + * access to ACKM internal state. + */ + if (ack->ecn_present) + ackm_process_ecn(ackm, ack, pkt_space); + + /* Handle inferred loss. */ + lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space); + if (lost_pkts != NULL) + ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0); + + ackm_on_pkts_acked(ackm, na_pkts); + + /* + * Reset pto_count unless the client is unsure if the server validated the + * client's address. + */ + if (ackm->peer_completed_addr_validation) + ackm->pto_count = 0; + + ackm_set_loss_detection_timer(ackm); + return 1; +} + +int ossl_ackm_on_pkt_space_discarded(OSSL_ACKM *ackm, int pkt_space) +{ + OSSL_ACKM_TX_PKT *pkt, *pnext; + uint64_t num_bytes_invalidated = 0; + + if (ackm->discarded[pkt_space]) + return 0; + + if (pkt_space == QUIC_PN_SPACE_HANDSHAKE) + ackm->peer_completed_addr_validation = 1; + + for (pkt = ossl_list_tx_history_head(&get_tx_history(ackm, pkt_space)->packets); + pkt != NULL; pkt = pnext) { + pnext = ossl_list_tx_history_next(pkt); + if (pkt->is_inflight) { + ackm->bytes_in_flight -= pkt->num_bytes; + num_bytes_invalidated += pkt->num_bytes; + } + + pkt->on_discarded(pkt->cb_arg); /* may free pkt */ + } + + tx_pkt_history_destroy(&ackm->tx_history[pkt_space]); + rx_pkt_history_destroy(&ackm->rx_history[pkt_space]); + + if (num_bytes_invalidated > 0) + ackm->cc_method->on_data_invalidated(ackm->cc_data, + num_bytes_invalidated); + + ackm->time_of_last_ack_eliciting_pkt[pkt_space] = ossl_time_zero(); + ackm->loss_time[pkt_space] = ossl_time_zero(); + ackm->pto_count = 0; + ackm->discarded[pkt_space] = 1; + ackm->ack_eliciting_bytes_in_flight[pkt_space] = 0; + ackm_set_loss_detection_timer(ackm); + return 1; +} + +int ossl_ackm_on_handshake_confirmed(OSSL_ACKM *ackm) +{ + ackm->handshake_confirmed = 1; + ackm->peer_completed_addr_validation = 1; + ackm_set_loss_detection_timer(ackm); + return 1; +} + +static void ackm_queue_probe_anti_deadlock_handshake(OSSL_ACKM *ackm) +{ + ++ackm->pending_probe.anti_deadlock_handshake; +} + +static void ackm_queue_probe_anti_deadlock_initial(OSSL_ACKM *ackm) +{ + ++ackm->pending_probe.anti_deadlock_initial; +} + +static void ackm_queue_probe(OSSL_ACKM *ackm, int pkt_space) +{ + /* + * TODO(QUIC FUTURE): We are allowed to send either one or two probe + * packets here. + * Determine a strategy for when we should send two probe packets. + */ + ++ackm->pending_probe.pto[pkt_space]; +} + +int ossl_ackm_on_timeout(OSSL_ACKM *ackm) +{ + int pkt_space; + OSSL_TIME earliest_loss_time; + OSSL_ACKM_TX_PKT *lost_pkts; + + earliest_loss_time = ackm_get_loss_time_and_space(ackm, &pkt_space); + if (!ossl_time_is_zero(earliest_loss_time)) { + /* Time threshold loss detection. */ + lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space); + if (lost_pkts != NULL) + ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0); + ackm_set_loss_detection_timer(ackm); + return 1; + } + + if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0) { + assert(!ackm->peer_completed_addr_validation); + /* + * Client sends an anti-deadlock packet: Initial is padded to earn more + * anti-amplification credit. A handshake packet proves address + * ownership. + */ + if (ackm->discarded[QUIC_PN_SPACE_INITIAL]) + ackm_queue_probe_anti_deadlock_handshake(ackm); + else + ackm_queue_probe_anti_deadlock_initial(ackm); + } else { + /* + * PTO. The user of the ACKM should send new data if available, else + * retransmit old data, or if neither is available, send a single PING + * frame. + */ + ackm_get_pto_time_and_space(ackm, &pkt_space); + ackm_queue_probe(ackm, pkt_space); + } + + ++ackm->pto_count; + ackm_set_loss_detection_timer(ackm); + return 1; +} + +OSSL_TIME ossl_ackm_get_loss_detection_deadline(OSSL_ACKM *ackm) +{ + return ackm->loss_detection_deadline; +} + +OSSL_ACKM_PROBE_INFO *ossl_ackm_get0_probe_request(OSSL_ACKM *ackm) +{ + return &ackm->pending_probe; +} + +int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn) +{ + struct tx_pkt_history_st *h; + OSSL_ACKM_TX_PKT *p; + + h = get_tx_history(ackm, pkt_space); + p = ossl_list_tx_history_tail(&h->packets); + if (p != NULL) { + *pn = p->pkt_num; + return 1; + } + + return 0; +} + +/* Number of ACK-eliciting packets RX'd before we always emit an ACK. */ +#define PKTS_BEFORE_ACK 2 + +/* + * Return 1 if emission of an ACK frame is currently desired. + * + * This occurs when one or more of the following conditions occurs: + * + * - We have flagged that we want to send an ACK frame + * (for example, due to the packet threshold count being exceeded), or + * + * - We have exceeded the ACK flush deadline, meaning that + * we have received at least one ACK-eliciting packet, but held off on + * sending an ACK frame immediately in the hope that more ACK-eliciting + * packets might come in, but not enough did and we are now requesting + * transmission of an ACK frame anyway. + * + */ +int ossl_ackm_is_ack_desired(OSSL_ACKM *ackm, int pkt_space) +{ + return ackm->rx_ack_desired[pkt_space] + || (!ossl_time_is_infinite(ackm->rx_ack_flush_deadline[pkt_space]) + && ossl_time_compare(ackm->now(ackm->now_arg), + ackm->rx_ack_flush_deadline[pkt_space]) >= 0); +} + +/* + * Returns 1 if an ACK frame matches a given packet number. + */ +static int ack_contains(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pkt_num) +{ + size_t i; + + for (i = 0; i < ack->num_ack_ranges; ++i) + if (range_contains(&ack->ack_ranges[i], pkt_num)) + return 1; + + return 0; +} + +/* + * Returns 1 iff a PN (which we have just received) was previously reported as + * implied missing (by us, in an ACK frame we previously generated). + */ +static int ackm_is_missing(OSSL_ACKM *ackm, int pkt_space, QUIC_PN pkt_num) +{ + /* + * A PN is implied missing if it is not greater than the highest PN in our + * generated ACK frame, but is not matched by the frame. + */ + return ackm->ack[pkt_space].num_ack_ranges > 0 + && pkt_num <= ackm->ack[pkt_space].ack_ranges[0].end + && !ack_contains(&ackm->ack[pkt_space], pkt_num); +} + +/* + * Returns 1 iff our RX of a PN newly establishes the implication of missing + * packets. + */ +static int ackm_has_newly_missing(OSSL_ACKM *ackm, int pkt_space) +{ + struct rx_pkt_history_st *h; + + h = get_rx_history(ackm, pkt_space); + + if (ossl_list_uint_set_is_empty(&h->set)) + return 0; + + /* + * The second condition here establishes that the highest PN range in our RX + * history comprises only a single PN. If there is more than one, then this + * function will have returned 1 during a previous call to + * ossl_ackm_on_rx_packet assuming the third condition below was met. Thus + * we only return 1 when the missing PN condition is newly established. + * + * The third condition here establishes that the highest PN range in our RX + * history is beyond (and does not border) the highest PN we have yet + * reported in any ACK frame. Thus there is a gap of at least one PN between + * the PNs we have ACK'd previously and the PN we have just received. + */ + return ackm->ack[pkt_space].num_ack_ranges > 0 + && ossl_list_uint_set_tail(&h->set)->range.start + == ossl_list_uint_set_tail(&h->set)->range.end + && ossl_list_uint_set_tail(&h->set)->range.start + > ackm->ack[pkt_space].ack_ranges[0].end + 1; +} + +static void ackm_set_flush_deadline(OSSL_ACKM *ackm, int pkt_space, + OSSL_TIME deadline) +{ + ackm->rx_ack_flush_deadline[pkt_space] = deadline; + + if (ackm->ack_deadline_cb != NULL) + ackm->ack_deadline_cb(ossl_ackm_get_ack_deadline(ackm, pkt_space), + pkt_space, ackm->ack_deadline_cb_arg); +} + +/* Explicitly flags that we want to generate an ACK frame. */ +static void ackm_queue_ack(OSSL_ACKM *ackm, int pkt_space) +{ + ackm->rx_ack_desired[pkt_space] = 1; + + /* Cancel deadline. */ + ackm_set_flush_deadline(ackm, pkt_space, ossl_time_infinite()); +} + +static void ackm_on_rx_ack_eliciting(OSSL_ACKM *ackm, + OSSL_TIME rx_time, int pkt_space, + int was_missing) +{ + OSSL_TIME tx_max_ack_delay; + + if (ackm->rx_ack_desired[pkt_space]) + /* ACK generation already requested so nothing to do. */ + return; + + ++ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space]; + + if (!ackm->rx_ack_generated[pkt_space] + || was_missing + || ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space] + >= PKTS_BEFORE_ACK + || ackm_has_newly_missing(ackm, pkt_space)) { + /* + * Either: + * + * - We have never yet generated an ACK frame, meaning that this + * is the first ever packet received, which we should always + * acknowledge immediately, or + * + * - We previously reported the PN that we have just received as + * missing in a previous ACK frame (meaning that we should report + * the fact that we now have it to the peer immediately), or + * + * - We have exceeded the ACK-eliciting packet threshold count + * for the purposes of ACK coalescing, so request transmission + * of an ACK frame, or + * + * - The PN we just received and added to our PN RX history + * newly implies one or more missing PNs, in which case we should + * inform the peer by sending an ACK frame immediately. + * + * We do not test the ACK flush deadline here because it is tested + * separately in ossl_ackm_is_ack_desired. + */ + ackm_queue_ack(ackm, pkt_space); + return; + } + + /* + * Not emitting an ACK yet. + * + * Update the ACK flush deadline. + * + * RFC 9000 s. 13.2.1: "An endpoint MUST acknowledge all ack-eliciting + * Initial and Handshake packets immediately"; don't delay ACK generation if + * we are using the Initial or Handshake PN spaces. + */ + tx_max_ack_delay = ackm->tx_max_ack_delay; + if (pkt_space == QUIC_PN_SPACE_INITIAL + || pkt_space == QUIC_PN_SPACE_HANDSHAKE) + tx_max_ack_delay = ossl_time_zero(); + + if (ossl_time_is_infinite(ackm->rx_ack_flush_deadline[pkt_space])) + ackm_set_flush_deadline(ackm, pkt_space, + ossl_time_add(rx_time, tx_max_ack_delay)); + else + ackm_set_flush_deadline(ackm, pkt_space, + ossl_time_min(ackm->rx_ack_flush_deadline[pkt_space], + ossl_time_add(rx_time, + tx_max_ack_delay))); +} + +int ossl_ackm_on_rx_packet(OSSL_ACKM *ackm, const OSSL_ACKM_RX_PKT *pkt) +{ + struct rx_pkt_history_st *h = get_rx_history(ackm, pkt->pkt_space); + int was_missing; + + if (ossl_ackm_is_rx_pn_processable(ackm, pkt->pkt_num, pkt->pkt_space) != 1) + /* PN has already been processed or written off, no-op. */ + return 1; + + /* + * Record the largest PN we have RX'd and the time we received it. + * We use this to calculate the ACK delay field of ACK frames. + */ + if (pkt->pkt_num > ackm->rx_largest_pn[pkt->pkt_space]) { + ackm->rx_largest_pn[pkt->pkt_space] = pkt->pkt_num; + ackm->rx_largest_time[pkt->pkt_space] = pkt->time; + } + + /* + * If the PN we just received was previously implied missing by virtue of + * being omitted from a previous ACK frame generated, we skip any packet + * count thresholds or coalescing delays and emit a new ACK frame + * immediately. + */ + was_missing = ackm_is_missing(ackm, pkt->pkt_space, pkt->pkt_num); + + /* + * Add the packet number to our history list of PNs we have not yet provably + * acked. + */ + if (rx_pkt_history_add_pn(h, pkt->pkt_num) != 1) + return 0; + + /* + * Receiving this packet may or may not cause us to emit an ACK frame. + * We may not emit an ACK frame yet if we have not yet received a threshold + * number of packets. + */ + if (pkt->is_ack_eliciting) + ackm_on_rx_ack_eliciting(ackm, pkt->time, pkt->pkt_space, was_missing); + + /* Update the ECN counters according to which ECN signal we got, if any. */ + switch (pkt->ecn) { + case OSSL_ACKM_ECN_ECT0: + ++ackm->rx_ect0[pkt->pkt_space]; + break; + case OSSL_ACKM_ECN_ECT1: + ++ackm->rx_ect1[pkt->pkt_space]; + break; + case OSSL_ACKM_ECN_ECNCE: + ++ackm->rx_ecnce[pkt->pkt_space]; + break; + default: + break; + } + + return 1; +} + +static void ackm_fill_rx_ack_ranges(OSSL_ACKM *ackm, int pkt_space, + OSSL_QUIC_FRAME_ACK *ack) +{ + struct rx_pkt_history_st *h = get_rx_history(ackm, pkt_space); + UINT_SET_ITEM *x; + size_t i = 0; + + /* + * Copy out ranges from the PN set, starting at the end, until we reach our + * maximum number of ranges. + */ + for (x = ossl_list_uint_set_tail(&h->set); + x != NULL && i < OSSL_NELEM(ackm->ack_ranges); + x = ossl_list_uint_set_prev(x), ++i) { + ackm->ack_ranges[pkt_space][i].start = x->range.start; + ackm->ack_ranges[pkt_space][i].end = x->range.end; + } + + ack->ack_ranges = ackm->ack_ranges[pkt_space]; + ack->num_ack_ranges = i; +} + +const OSSL_QUIC_FRAME_ACK *ossl_ackm_get_ack_frame(OSSL_ACKM *ackm, + int pkt_space) +{ + OSSL_QUIC_FRAME_ACK *ack = &ackm->ack[pkt_space]; + OSSL_TIME now = ackm->now(ackm->now_arg); + + ackm_fill_rx_ack_ranges(ackm, pkt_space, ack); + + if (!ossl_time_is_zero(ackm->rx_largest_time[pkt_space]) + && ossl_time_compare(now, ackm->rx_largest_time[pkt_space]) > 0 + && pkt_space == QUIC_PN_SPACE_APP) + ack->delay_time = + ossl_time_subtract(now, ackm->rx_largest_time[pkt_space]); + else + ack->delay_time = ossl_time_zero(); + + ack->ect0 = ackm->rx_ect0[pkt_space]; + ack->ect1 = ackm->rx_ect1[pkt_space]; + ack->ecnce = ackm->rx_ecnce[pkt_space]; + ack->ecn_present = 1; + + ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space] = 0; + + ackm->rx_ack_generated[pkt_space] = 1; + ackm->rx_ack_desired[pkt_space] = 0; + ackm_set_flush_deadline(ackm, pkt_space, ossl_time_infinite()); + return ack; +} + + +OSSL_TIME ossl_ackm_get_ack_deadline(OSSL_ACKM *ackm, int pkt_space) +{ + if (ackm->rx_ack_desired[pkt_space]) + /* Already desired, deadline is now. */ + return ossl_time_zero(); + + return ackm->rx_ack_flush_deadline[pkt_space]; +} + +int ossl_ackm_is_rx_pn_processable(OSSL_ACKM *ackm, QUIC_PN pn, int pkt_space) +{ + struct rx_pkt_history_st *h = get_rx_history(ackm, pkt_space); + + return pn >= h->watermark && ossl_uint_set_query(&h->set, pn) == 0; +} + +void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm, + void (*fn)(OSSL_TIME deadline, + void *arg), + void *arg) +{ + ackm->loss_detection_deadline_cb = fn; + ackm->loss_detection_deadline_cb_arg = arg; +} + +void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm, + void (*fn)(OSSL_TIME deadline, + int pkt_space, + void *arg), + void *arg) +{ + ackm->ack_deadline_cb = fn; + ackm->ack_deadline_cb_arg = arg; +} + +int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm, + int pkt_space, QUIC_PN pn) +{ + struct tx_pkt_history_st *h = get_tx_history(ackm, pkt_space); + OSSL_ACKM_TX_PKT *pkt; + + pkt = tx_pkt_history_by_pkt_num(h, pn); + if (pkt == NULL) + return 0; + + tx_pkt_history_remove(h, pkt->pkt_num); + pkt->lnext = NULL; + ackm_on_pkts_lost(ackm, pkt_space, pkt, /*pseudo=*/1); + return 1; +} + +OSSL_TIME ossl_ackm_get_pto_duration(OSSL_ACKM *ackm) +{ + OSSL_TIME duration; + OSSL_RTT_INFO rtt; + + ossl_statm_get_rtt_info(ackm->statm, &rtt); + + duration = ossl_time_add(rtt.smoothed_rtt, + ossl_time_max(ossl_time_multiply(rtt.rtt_variance, 4), + ossl_ticks2time(K_GRANULARITY))); + if (!ossl_time_is_infinite(ackm->rx_max_ack_delay)) + duration = ossl_time_add(duration, ackm->rx_max_ack_delay); + + return duration; +} + +QUIC_PN ossl_ackm_get_largest_acked(OSSL_ACKM *ackm, int pkt_space) +{ + return ackm->largest_acked_pkt[pkt_space]; +} + +void ossl_ackm_set_rx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME rx_max_ack_delay) +{ + ackm->rx_max_ack_delay = rx_max_ack_delay; +} + +void ossl_ackm_set_tx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME tx_max_ack_delay) +{ + ackm->tx_max_ack_delay = tx_max_ack_delay; +} diff --git a/ssl/quic/quic_cfq.c b/ssl/quic/quic_cfq.c new file mode 100644 index 0000000000..9b9999a823 --- /dev/null +++ b/ssl/quic/quic_cfq.c @@ -0,0 +1,363 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_cfq.h" +#include "internal/numbers.h" + +typedef struct quic_cfq_item_ex_st QUIC_CFQ_ITEM_EX; + +struct quic_cfq_item_ex_st { + QUIC_CFQ_ITEM public; + QUIC_CFQ_ITEM_EX *prev, *next; + unsigned char *encoded; + cfq_free_cb *free_cb; + void *free_cb_arg; + uint64_t frame_type; + size_t encoded_len; + uint32_t priority, pn_space, flags; + int state; +}; + +uint64_t ossl_quic_cfq_item_get_frame_type(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return ex->frame_type; +} + +const unsigned char *ossl_quic_cfq_item_get_encoded(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return ex->encoded; +} + +size_t ossl_quic_cfq_item_get_encoded_len(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return ex->encoded_len; +} + +int ossl_quic_cfq_item_get_state(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return ex->state; +} + +uint32_t ossl_quic_cfq_item_get_pn_space(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return ex->pn_space; +} + +int ossl_quic_cfq_item_is_unreliable(const QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + return (ex->flags & QUIC_CFQ_ITEM_FLAG_UNRELIABLE) != 0; +} + +typedef struct quic_cfq_item_list_st { + QUIC_CFQ_ITEM_EX *head, *tail; +} QUIC_CFQ_ITEM_LIST; + +struct quic_cfq_st { + /* + * Invariant: A CFQ item is always in exactly one of these lists, never more + * or less than one. + * + * Invariant: The list the CFQ item is determined exactly by the state field + * of the item. + */ + QUIC_CFQ_ITEM_LIST new_list, tx_list, free_list; +}; + +static int compare(const QUIC_CFQ_ITEM_EX *a, const QUIC_CFQ_ITEM_EX *b) +{ + if (a->pn_space < b->pn_space) + return -1; + else if (a->pn_space > b->pn_space) + return 1; + + if (a->priority > b->priority) + return -1; + else if (a->priority < b->priority) + return 1; + + return 0; +} + +static void list_remove(QUIC_CFQ_ITEM_LIST *l, QUIC_CFQ_ITEM_EX *n) +{ + if (l->head == n) + l->head = n->next; + if (l->tail == n) + l->tail = n->prev; + if (n->prev != NULL) + n->prev->next = n->next; + if (n->next != NULL) + n->next->prev = n->prev; + n->prev = n->next = NULL; +} + +static void list_insert_head(QUIC_CFQ_ITEM_LIST *l, QUIC_CFQ_ITEM_EX *n) +{ + n->next = l->head; + n->prev = NULL; + l->head = n; + if (n->next != NULL) + n->next->prev = n; + if (l->tail == NULL) + l->tail = n; +} + +static void list_insert_tail(QUIC_CFQ_ITEM_LIST *l, QUIC_CFQ_ITEM_EX *n) +{ + n->prev = l->tail; + n->next = NULL; + l->tail = n; + if (n->prev != NULL) + n->prev->next = n; + if (l->head == NULL) + l->head = n; +} + +static void list_insert_after(QUIC_CFQ_ITEM_LIST *l, + QUIC_CFQ_ITEM_EX *ref, + QUIC_CFQ_ITEM_EX *n) +{ + n->prev = ref; + n->next = ref->next; + if (ref->next != NULL) + ref->next->prev = n; + ref->next = n; + if (l->tail == ref) + l->tail = n; +} + +static void list_insert_sorted(QUIC_CFQ_ITEM_LIST *l, QUIC_CFQ_ITEM_EX *n, + int (*cmp)(const QUIC_CFQ_ITEM_EX *a, + const QUIC_CFQ_ITEM_EX *b)) +{ + QUIC_CFQ_ITEM_EX *p = l->head, *pprev = NULL; + + if (p == NULL) { + l->head = l->tail = n; + n->prev = n->next = NULL; + return; + } + + for (; p != NULL && cmp(p, n) < 0; pprev = p, p = p->next); + + if (p == NULL) + list_insert_tail(l, n); + else if (pprev == NULL) + list_insert_head(l, n); + else + list_insert_after(l, pprev, n); +} + +QUIC_CFQ *ossl_quic_cfq_new(void) +{ + QUIC_CFQ *cfq = OPENSSL_zalloc(sizeof(*cfq)); + + if (cfq == NULL) + return NULL; + + return cfq; +} + +static void clear_item(QUIC_CFQ_ITEM_EX *item) +{ + if (item->free_cb != NULL) { + item->free_cb(item->encoded, item->encoded_len, item->free_cb_arg); + + item->free_cb = NULL; + item->encoded = NULL; + item->encoded_len = 0; + } + + item->state = -1; +} + +static void free_list_items(QUIC_CFQ_ITEM_LIST *l) +{ + QUIC_CFQ_ITEM_EX *p, *pnext; + + for (p = l->head; p != NULL; p = pnext) { + pnext = p->next; + clear_item(p); + OPENSSL_free(p); + } +} + +void ossl_quic_cfq_free(QUIC_CFQ *cfq) +{ + if (cfq == NULL) + return; + + free_list_items(&cfq->new_list); + free_list_items(&cfq->tx_list); + free_list_items(&cfq->free_list); + OPENSSL_free(cfq); +} + +static QUIC_CFQ_ITEM_EX *cfq_get_free(QUIC_CFQ *cfq) +{ + QUIC_CFQ_ITEM_EX *item = cfq->free_list.head; + + if (item != NULL) + return item; + + item = OPENSSL_zalloc(sizeof(*item)); + if (item == NULL) + return NULL; + + item->state = -1; + list_insert_tail(&cfq->free_list, item); + return item; +} + +QUIC_CFQ_ITEM *ossl_quic_cfq_add_frame(QUIC_CFQ *cfq, + uint32_t priority, + uint32_t pn_space, + uint64_t frame_type, + uint32_t flags, + const unsigned char *encoded, + size_t encoded_len, + cfq_free_cb *free_cb, + void *free_cb_arg) +{ + QUIC_CFQ_ITEM_EX *item = cfq_get_free(cfq); + + if (item == NULL) + return NULL; + + item->priority = priority; + item->frame_type = frame_type; + item->pn_space = pn_space; + item->encoded = (unsigned char *)encoded; + item->encoded_len = encoded_len; + item->free_cb = free_cb; + item->free_cb_arg = free_cb_arg; + + item->state = QUIC_CFQ_STATE_NEW; + item->flags = flags; + list_remove(&cfq->free_list, item); + list_insert_sorted(&cfq->new_list, item, compare); + return &item->public; +} + +void ossl_quic_cfq_mark_tx(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + switch (ex->state) { + case QUIC_CFQ_STATE_NEW: + list_remove(&cfq->new_list, ex); + list_insert_tail(&cfq->tx_list, ex); + ex->state = QUIC_CFQ_STATE_TX; + break; + case QUIC_CFQ_STATE_TX: + break; /* nothing to do */ + default: + assert(0); /* invalid state (e.g. in free state) */ + break; + } +} + +void ossl_quic_cfq_mark_lost(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item, + uint32_t priority) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + if (ossl_quic_cfq_item_is_unreliable(item)) { + ossl_quic_cfq_release(cfq, item); + return; + } + + switch (ex->state) { + case QUIC_CFQ_STATE_NEW: + if (priority != UINT32_MAX && priority != ex->priority) { + list_remove(&cfq->new_list, ex); + ex->priority = priority; + list_insert_sorted(&cfq->new_list, ex, compare); + } + break; /* nothing to do */ + case QUIC_CFQ_STATE_TX: + if (priority != UINT32_MAX) + ex->priority = priority; + list_remove(&cfq->tx_list, ex); + list_insert_sorted(&cfq->new_list, ex, compare); + ex->state = QUIC_CFQ_STATE_NEW; + break; + default: + assert(0); /* invalid state (e.g. in free state) */ + break; + } +} + +/* + * Releases a CFQ item. The item may be in either state (NEW or TX) prior to the + * call. The QUIC_CFQ_ITEM pointer must not be used following this call. + */ +void ossl_quic_cfq_release(QUIC_CFQ *cfq, QUIC_CFQ_ITEM *item) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + switch (ex->state) { + case QUIC_CFQ_STATE_NEW: + list_remove(&cfq->new_list, ex); + list_insert_tail(&cfq->free_list, ex); + clear_item(ex); + break; + case QUIC_CFQ_STATE_TX: + list_remove(&cfq->tx_list, ex); + list_insert_tail(&cfq->free_list, ex); + clear_item(ex); + break; + default: + assert(0); /* invalid state (e.g. in free state) */ + break; + } +} + +QUIC_CFQ_ITEM *ossl_quic_cfq_get_priority_head(const QUIC_CFQ *cfq, + uint32_t pn_space) +{ + QUIC_CFQ_ITEM_EX *item = cfq->new_list.head; + + for (; item != NULL && item->pn_space != pn_space; item = item->next); + + if (item == NULL) + return NULL; + + return &item->public; +} + +QUIC_CFQ_ITEM *ossl_quic_cfq_item_get_priority_next(const QUIC_CFQ_ITEM *item, + uint32_t pn_space) +{ + QUIC_CFQ_ITEM_EX *ex = (QUIC_CFQ_ITEM_EX *)item; + + if (ex == NULL) + return NULL; + + ex = ex->next; + + for (; ex != NULL && ex->pn_space != pn_space; ex = ex->next); + + if (ex == NULL) + return NULL; /* ubsan */ + + return &ex->public; +} diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c new file mode 100644 index 0000000000..d3b7947fb4 --- /dev/null +++ b/ssl/quic/quic_channel.c @@ -0,0 +1,3803 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/quic_channel.h" +#include "internal/quic_error.h" +#include "internal/quic_rx_depack.h" +#include "../ssl_local.h" +#include "quic_channel_local.h" + +/* + * NOTE: While this channel implementation currently has basic server support, + * this functionality has been implemented for internal testing purposes and is + * not suitable for network use. In particular, it does not implement address + * validation, anti-amplification or retry logic. + * + * TODO(QUIC SERVER): Implement address validation and anti-amplification + * TODO(QUIC SERVER): Implement retry logic + */ + +#define INIT_DCID_LEN 8 +#define INIT_CRYPTO_RECV_BUF_LEN 16384 +#define INIT_CRYPTO_SEND_BUF_LEN 16384 +#define INIT_APP_BUF_LEN 8192 + +/* + * Interval before we force a PING to ensure NATs don't timeout. This is based + * on the lowest commonly seen value of 30 seconds as cited in RFC 9000 s. + * 10.1.2. + */ +#define MAX_NAT_INTERVAL (ossl_ms2time(25000)) + +/* + * Our maximum ACK delay on the TX side. This is up to us to choose. Note that + * this could differ from QUIC_DEFAULT_MAX_DELAY in future as that is a protocol + * value which determines the value of the maximum ACK delay if the + * max_ack_delay transport parameter is not set. + */ +#define DEFAULT_MAX_ACK_DELAY QUIC_DEFAULT_MAX_ACK_DELAY + +static void ch_save_err_state(QUIC_CHANNEL *ch); +static void ch_rx_pre(QUIC_CHANNEL *ch); +static int ch_rx(QUIC_CHANNEL *ch, int channel_only); +static int ch_tx(QUIC_CHANNEL *ch); +static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags); +static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only); +static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only); +static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch); +static int ch_retry(QUIC_CHANNEL *ch, + const unsigned char *retry_token, + size_t retry_token_len, + const QUIC_CONN_ID *retry_scid); +static void ch_cleanup(QUIC_CHANNEL *ch); +static int ch_generate_transport_params(QUIC_CHANNEL *ch); +static int ch_on_transport_params(const unsigned char *params, + size_t params_len, + void *arg); +static int ch_on_handshake_alert(void *arg, unsigned char alert_code); +static int ch_on_handshake_complete(void *arg); +static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction, + uint32_t suite_id, EVP_MD *md, + const unsigned char *secret, + size_t secret_len, + void *arg); +static int ch_on_crypto_recv_record(const unsigned char **buf, + size_t *bytes_read, void *arg); +static int ch_on_crypto_release_record(size_t bytes_read, void *arg); +static int crypto_ensure_empty(QUIC_RSTREAM *rstream); +static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len, + size_t *consumed, void *arg); +static OSSL_TIME get_time(void *arg); +static uint64_t get_stream_limit(int uni, void *arg); +static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg); +static void rxku_detected(QUIC_PN pn, void *arg); +static int ch_retry(QUIC_CHANNEL *ch, + const unsigned char *retry_token, + size_t retry_token_len, + const QUIC_CONN_ID *retry_scid); +static void ch_update_idle(QUIC_CHANNEL *ch); +static int ch_discard_el(QUIC_CHANNEL *ch, + uint32_t enc_level); +static void ch_on_idle_timeout(QUIC_CHANNEL *ch); +static void ch_update_idle(QUIC_CHANNEL *ch); +static void ch_update_ping_deadline(QUIC_CHANNEL *ch); +static void ch_stateless_reset(QUIC_CHANNEL *ch); +static void ch_raise_net_error(QUIC_CHANNEL *ch); +static void ch_on_terminating_timeout(QUIC_CHANNEL *ch); +static void ch_start_terminating(QUIC_CHANNEL *ch, + const QUIC_TERMINATE_CAUSE *tcause, + int force_immediate); +static int ch_stateless_reset_token_handler(const unsigned char *data, size_t datalen, void *arg); +static void ch_default_packet_handler(QUIC_URXE *e, void *arg); +static int ch_server_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer, + const QUIC_CONN_ID *peer_scid, + const QUIC_CONN_ID *peer_dcid); +static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space, + void *arg); +static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt); +static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch); + +DEFINE_LHASH_OF_EX(QUIC_SRT_ELEM); + +static int gen_rand_conn_id(OSSL_LIB_CTX *libctx, size_t len, QUIC_CONN_ID *cid) +{ + if (len > QUIC_MAX_CONN_ID_LEN) + return 0; + + cid->id_len = (unsigned char)len; + + if (RAND_bytes_ex(libctx, cid->id, len, len * 8) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB); + cid->id_len = 0; + return 0; + } + + return 1; +} + +static unsigned long chan_reset_token_hash(const QUIC_SRT_ELEM *a) +{ + unsigned long h; + + assert(sizeof(h) <= sizeof(a->token)); + memcpy(&h, &a->token, sizeof(h)); + return h; +} + +static int chan_reset_token_cmp(const QUIC_SRT_ELEM *a, const QUIC_SRT_ELEM *b) +{ + /* RFC 9000 s. 10.3.1: + * When comparing a datagram to stateless reset token values, + * endpoints MUST perform the comparison without leaking + * information about the value of the token. For example, + * performing this comparison in constant time protects the + * value of individual stateless reset tokens from information + * leakage through timing side channels. + * + * TODO(QUIC FUTURE): make this a memcmp when obfuscation is done and update + * comment above. + */ + return CRYPTO_memcmp(&a->token, &b->token, sizeof(a->token)); +} + +static int reset_token_obfuscate(QUIC_SRT_ELEM *out, const unsigned char *in) +{ + /* + * TODO(QUIC FUTURE): update this to AES encrypt the token in ECB mode with a + * random (per channel) key. + */ + memcpy(&out->token, in, sizeof(out->token)); + return 1; +} + +/* + * Add a stateless reset token to the channel + */ +static int chan_add_reset_token(QUIC_CHANNEL *ch, const unsigned char *new, + uint64_t seq_num) +{ + QUIC_SRT_ELEM *srte; + int err; + + /* Add to list by sequence number (always the tail) */ + if ((srte = OPENSSL_malloc(sizeof(*srte))) == NULL) + return 0; + + ossl_list_stateless_reset_tokens_init_elem(srte); + ossl_list_stateless_reset_tokens_insert_tail(&ch->srt_list_seq, srte); + reset_token_obfuscate(srte, new); + srte->seq_num = seq_num; + + lh_QUIC_SRT_ELEM_insert(ch->srt_hash_tok, srte); + err = lh_QUIC_SRT_ELEM_error(ch->srt_hash_tok); + if (err > 0) { + ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); + OPENSSL_free(srte); + return 0; + } + return 1; +} + +/* + * Remove a stateless reset token from the channel + * If the token isn't known, we just ignore the remove request which is safe. + */ +static void chan_remove_reset_token(QUIC_CHANNEL *ch, uint64_t seq_num) +{ + QUIC_SRT_ELEM *srte; + + /* + * Because the list is ordered and we only ever remove CIDs in order, + * this loop should never iterate, but safer to provide the option. + */ + for (srte = ossl_list_stateless_reset_tokens_head(&ch->srt_list_seq); + srte != NULL; + srte = ossl_list_stateless_reset_tokens_next(srte)) { + if (srte->seq_num > seq_num) + return; + if (srte->seq_num == seq_num) { + ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); + (void)lh_QUIC_SRT_ELEM_delete(ch->srt_hash_tok, srte); + OPENSSL_free(srte); + return; + } + } +} + +/* + * This is called by the demux whenever a new datagram arrives + * + * TODO(QUIC FUTURE): optimise this to only be called for unparsable packets + */ +static int ch_stateless_reset_token_handler(const unsigned char *data, + size_t datalen, void *arg) +{ + QUIC_SRT_ELEM srte; + QUIC_CHANNEL *ch = (QUIC_CHANNEL *)arg; + + /* + * Perform some fast and cheap checks for a packet not being a stateless + * reset token. RFC 9000 s. 10.3 specifies this layout for stateless + * reset packets: + * + * Stateless Reset { + * Fixed Bits (2) = 1, + * Unpredictable Bits (38..), + * Stateless Reset Token (128), + * } + * + * It also specifies: + * However, endpoints MUST treat any packet ending in a valid + * stateless reset token as a Stateless Reset, as other QUIC + * versions might allow the use of a long header. + * + * We can rapidly check for the minimum length and that the first pair + * of bits in the first byte are 01 or 11. + * + * The function returns 1 if it is a stateless reset packet, 0 if it isn't + * and -1 if an error was encountered. + */ + if (datalen < QUIC_STATELESS_RESET_TOKEN_LEN + 5 || (0100 & *data) != 0100) + return 0; + memset(&srte, 0, sizeof(srte)); + if (!reset_token_obfuscate(&srte, data + datalen - sizeof(srte.token))) + return -1; + return lh_QUIC_SRT_ELEM_retrieve(ch->srt_hash_tok, &srte) != NULL; +} + +/* + * QUIC Channel Initialization and Teardown + * ======================================== + */ +#define DEFAULT_INIT_CONN_RXFC_WND (768 * 1024) +#define DEFAULT_CONN_RXFC_MAX_WND_MUL 20 + +#define DEFAULT_INIT_STREAM_RXFC_WND (512 * 1024) +#define DEFAULT_STREAM_RXFC_MAX_WND_MUL 12 + +#define DEFAULT_INIT_CONN_MAX_STREAMS 100 + +static int ch_init(QUIC_CHANNEL *ch) +{ + OSSL_QUIC_TX_PACKETISER_ARGS txp_args = {0}; + OSSL_QTX_ARGS qtx_args = {0}; + OSSL_QRX_ARGS qrx_args = {0}; + QUIC_TLS_ARGS tls_args = {0}; + uint32_t pn_space; + size_t rx_short_cid_len = ch->is_server ? INIT_DCID_LEN : 0; + + ossl_list_stateless_reset_tokens_init(&ch->srt_list_seq); + ch->srt_hash_tok = lh_QUIC_SRT_ELEM_new(&chan_reset_token_hash, + &chan_reset_token_cmp); + if (ch->srt_hash_tok == NULL) + goto err; + + /* For clients, generate our initial DCID. */ + if (!ch->is_server + && !gen_rand_conn_id(ch->libctx, INIT_DCID_LEN, &ch->init_dcid)) + goto err; + + /* We plug in a network write BIO to the QTX later when we get one. */ + qtx_args.libctx = ch->libctx; + qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN; + ch->rx_max_udp_payload_size = qtx_args.mdpl; + + ch->ping_deadline = ossl_time_infinite(); + + ch->qtx = ossl_qtx_new(&qtx_args); + if (ch->qtx == NULL) + goto err; + + ch->txpim = ossl_quic_txpim_new(); + if (ch->txpim == NULL) + goto err; + + ch->cfq = ossl_quic_cfq_new(); + if (ch->cfq == NULL) + goto err; + + if (!ossl_quic_txfc_init(&ch->conn_txfc, NULL)) + goto err; + + /* + * Note: The TP we transmit governs what the peer can transmit and thus + * applies to the RXFC. + */ + ch->tx_init_max_stream_data_bidi_local = DEFAULT_INIT_STREAM_RXFC_WND; + ch->tx_init_max_stream_data_bidi_remote = DEFAULT_INIT_STREAM_RXFC_WND; + ch->tx_init_max_stream_data_uni = DEFAULT_INIT_STREAM_RXFC_WND; + + if (!ossl_quic_rxfc_init(&ch->conn_rxfc, NULL, + DEFAULT_INIT_CONN_RXFC_WND, + DEFAULT_CONN_RXFC_MAX_WND_MUL * + DEFAULT_INIT_CONN_RXFC_WND, + get_time, ch)) + goto err; + + for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) + if (!ossl_quic_rxfc_init_standalone(&ch->crypto_rxfc[pn_space], + INIT_CRYPTO_RECV_BUF_LEN, + get_time, ch)) + goto err; + + if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_bidi_rxfc, + DEFAULT_INIT_CONN_MAX_STREAMS, + get_time, ch)) + goto err; + + if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_uni_rxfc, + DEFAULT_INIT_CONN_MAX_STREAMS, + get_time, ch)) + goto err; + + if (!ossl_statm_init(&ch->statm)) + goto err; + + ch->have_statm = 1; + ch->cc_method = &ossl_cc_newreno_method; + if ((ch->cc_data = ch->cc_method->new(get_time, ch)) == NULL) + goto err; + + if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm, + ch->cc_method, ch->cc_data)) == NULL) + goto err; + + if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch, + &ch->max_streams_bidi_rxfc, + &ch->max_streams_uni_rxfc, + ch->is_server)) + goto err; + + ch->have_qsm = 1; + + /* We use a zero-length SCID. */ + txp_args.cur_dcid = ch->init_dcid; + txp_args.ack_delay_exponent = 3; + txp_args.qtx = ch->qtx; + txp_args.txpim = ch->txpim; + txp_args.cfq = ch->cfq; + txp_args.ackm = ch->ackm; + txp_args.qsm = &ch->qsm; + txp_args.conn_txfc = &ch->conn_txfc; + txp_args.conn_rxfc = &ch->conn_rxfc; + txp_args.max_streams_bidi_rxfc = &ch->max_streams_bidi_rxfc; + txp_args.max_streams_uni_rxfc = &ch->max_streams_uni_rxfc; + txp_args.cc_method = ch->cc_method; + txp_args.cc_data = ch->cc_data; + txp_args.now = get_time; + txp_args.now_arg = ch; + + for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { + ch->crypto_send[pn_space] = ossl_quic_sstream_new(INIT_CRYPTO_SEND_BUF_LEN); + if (ch->crypto_send[pn_space] == NULL) + goto err; + + txp_args.crypto[pn_space] = ch->crypto_send[pn_space]; + } + + ch->txp = ossl_quic_tx_packetiser_new(&txp_args); + if (ch->txp == NULL) + goto err; + + ossl_quic_tx_packetiser_set_ack_tx_cb(ch->txp, ch_on_txp_ack_tx, ch); + + if ((ch->demux = ossl_quic_demux_new(/*BIO=*/NULL, + /*Short CID Len=*/rx_short_cid_len, + get_time, ch)) == NULL) + goto err; + + /* + * Setup a handler to detect stateless reset tokens. + */ + ossl_quic_demux_set_stateless_reset_handler(ch->demux, + &ch_stateless_reset_token_handler, + ch); + + /* + * If we are a server, setup our handler for packets not corresponding to + * any known DCID on our end. This is for handling clients establishing new + * connections. + */ + if (ch->is_server) + ossl_quic_demux_set_default_handler(ch->demux, + ch_default_packet_handler, + ch); + + qrx_args.libctx = ch->libctx; + qrx_args.demux = ch->demux; + qrx_args.short_conn_id_len = rx_short_cid_len; + qrx_args.max_deferred = 32; + + if ((ch->qrx = ossl_qrx_new(&qrx_args)) == NULL) + goto err; + + if (!ossl_qrx_set_late_validation_cb(ch->qrx, + rx_late_validate, + ch)) + goto err; + + if (!ossl_qrx_set_key_update_cb(ch->qrx, + rxku_detected, + ch)) + goto err; + + if (!ch->is_server && !ossl_qrx_add_dst_conn_id(ch->qrx, &txp_args.cur_scid)) + goto err; + + for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { + ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, 0); + if (ch->crypto_recv[pn_space] == NULL) + goto err; + } + + /* Plug in the TLS handshake layer. */ + tls_args.s = ch->tls; + tls_args.crypto_send_cb = ch_on_crypto_send; + tls_args.crypto_send_cb_arg = ch; + tls_args.crypto_recv_rcd_cb = ch_on_crypto_recv_record; + tls_args.crypto_recv_rcd_cb_arg = ch; + tls_args.crypto_release_rcd_cb = ch_on_crypto_release_record; + tls_args.crypto_release_rcd_cb_arg = ch; + tls_args.yield_secret_cb = ch_on_handshake_yield_secret; + tls_args.yield_secret_cb_arg = ch; + tls_args.got_transport_params_cb = ch_on_transport_params; + tls_args.got_transport_params_cb_arg= ch; + tls_args.handshake_complete_cb = ch_on_handshake_complete; + tls_args.handshake_complete_cb_arg = ch; + tls_args.alert_cb = ch_on_handshake_alert; + tls_args.alert_cb_arg = ch; + tls_args.is_server = ch->is_server; + + if ((ch->qtls = ossl_quic_tls_new(&tls_args)) == NULL) + goto err; + + ch->tx_max_ack_delay = DEFAULT_MAX_ACK_DELAY; + ch->rx_max_ack_delay = QUIC_DEFAULT_MAX_ACK_DELAY; + ch->rx_ack_delay_exp = QUIC_DEFAULT_ACK_DELAY_EXP; + ch->rx_active_conn_id_limit = QUIC_MIN_ACTIVE_CONN_ID_LIMIT; + ch->max_idle_timeout = QUIC_DEFAULT_IDLE_TIMEOUT; + ch->tx_enc_level = QUIC_ENC_LEVEL_INITIAL; + ch->rx_enc_level = QUIC_ENC_LEVEL_INITIAL; + ch->txku_threshold_override = UINT64_MAX; + + ossl_ackm_set_tx_max_ack_delay(ch->ackm, ossl_ms2time(ch->tx_max_ack_delay)); + ossl_ackm_set_rx_max_ack_delay(ch->ackm, ossl_ms2time(ch->rx_max_ack_delay)); + + /* + * Determine the QUIC Transport Parameters and serialize the transport + * parameters block. (For servers, we do this later as we must defer + * generation until we have received the client's transport parameters.) + */ + if (!ch->is_server && !ch_generate_transport_params(ch)) + goto err; + + ch_update_idle(ch); + ossl_quic_reactor_init(&ch->rtor, ch_tick, ch, + ch_determine_next_tick_deadline(ch)); + return 1; + +err: + ch_cleanup(ch); + return 0; +} + +static void ch_cleanup(QUIC_CHANNEL *ch) +{ + QUIC_SRT_ELEM *srte, *srte_next; + uint32_t pn_space; + + if (ch->ackm != NULL) + for (pn_space = QUIC_PN_SPACE_INITIAL; + pn_space < QUIC_PN_SPACE_NUM; + ++pn_space) + ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space); + + ossl_quic_tx_packetiser_free(ch->txp); + ossl_quic_txpim_free(ch->txpim); + ossl_quic_cfq_free(ch->cfq); + ossl_qtx_free(ch->qtx); + if (ch->cc_data != NULL) + ch->cc_method->free(ch->cc_data); + if (ch->have_statm) + ossl_statm_destroy(&ch->statm); + ossl_ackm_free(ch->ackm); + + if (ch->have_qsm) + ossl_quic_stream_map_cleanup(&ch->qsm); + + for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { + ossl_quic_sstream_free(ch->crypto_send[pn_space]); + ossl_quic_rstream_free(ch->crypto_recv[pn_space]); + } + + ossl_qrx_pkt_release(ch->qrx_pkt); + ch->qrx_pkt = NULL; + + ossl_quic_tls_free(ch->qtls); + ossl_qrx_free(ch->qrx); + ossl_quic_demux_free(ch->demux); + OPENSSL_free(ch->local_transport_params); + OPENSSL_free((char *)ch->terminate_cause.reason); + OSSL_ERR_STATE_free(ch->err_state); + OPENSSL_free(ch->ack_range_scratch); + + /* Free the stateless reset tokens */ + for (srte = ossl_list_stateless_reset_tokens_head(&ch->srt_list_seq); + srte != NULL; + srte = srte_next) { + srte_next = ossl_list_stateless_reset_tokens_next(srte); + ossl_list_stateless_reset_tokens_remove(&ch->srt_list_seq, srte); + (void)lh_QUIC_SRT_ELEM_delete(ch->srt_hash_tok, srte); + OPENSSL_free(srte); + } + lh_QUIC_SRT_ELEM_free(ch->srt_hash_tok); +} + +QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) +{ + QUIC_CHANNEL *ch = NULL; + + if ((ch = OPENSSL_zalloc(sizeof(*ch))) == NULL) + return NULL; + + ch->libctx = args->libctx; + ch->propq = args->propq; + ch->is_server = args->is_server; + ch->tls = args->tls; + ch->mutex = args->mutex; + ch->now_cb = args->now_cb; + ch->now_cb_arg = args->now_cb_arg; + + if (!ch_init(ch)) { + OPENSSL_free(ch); + return NULL; + } + + return ch; +} + +void ossl_quic_channel_free(QUIC_CHANNEL *ch) +{ + if (ch == NULL) + return; + + ch_cleanup(ch); + OPENSSL_free(ch); +} + +/* Set mutator callbacks for test framework support */ +int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch, + ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, + void *mutatearg) +{ + if (ch->qtx == NULL) + return 0; + + ossl_qtx_set_mutator(ch->qtx, mutatecb, finishmutatecb, mutatearg); + return 1; +} + +int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr) +{ + if (!ch->addressed_mode) + return 0; + + *peer_addr = ch->cur_peer_addr; + return 1; +} + +int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr) +{ + if (ch->state != QUIC_CHANNEL_STATE_IDLE) + return 0; + + if (peer_addr == NULL || BIO_ADDR_family(peer_addr) == AF_UNSPEC) { + BIO_ADDR_clear(&ch->cur_peer_addr); + ch->addressed_mode = 0; + return 1; + } + + ch->cur_peer_addr = *peer_addr; + ch->addressed_mode = 1; + return 1; +} + +QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch) +{ + return &ch->rtor; +} + +QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch) +{ + return &ch->qsm; +} + +OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch) +{ + return &ch->statm; +} + +QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch, + uint64_t stream_id) +{ + return ossl_quic_stream_map_get_by_id(&ch->qsm, stream_id); +} + +int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch) +{ + return ch != NULL && ch->state == QUIC_CHANNEL_STATE_ACTIVE; +} + +int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch) +{ + return ch->state == QUIC_CHANNEL_STATE_TERMINATING_CLOSING; +} + +static int ossl_quic_channel_is_draining(const QUIC_CHANNEL *ch) +{ + return ch->state == QUIC_CHANNEL_STATE_TERMINATING_DRAINING; +} + +static int ossl_quic_channel_is_terminating(const QUIC_CHANNEL *ch) +{ + return ossl_quic_channel_is_closing(ch) + || ossl_quic_channel_is_draining(ch); +} + +int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch) +{ + return ch->state == QUIC_CHANNEL_STATE_TERMINATED; +} + +int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch) +{ + return ossl_quic_channel_is_terminating(ch) + || ossl_quic_channel_is_terminated(ch); +} + +const QUIC_TERMINATE_CAUSE * +ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch) +{ + return ossl_quic_channel_is_term_any(ch) ? &ch->terminate_cause : NULL; +} + +int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch) +{ + return ch->handshake_complete; +} + +int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch) +{ + return ch->handshake_confirmed; +} + +QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch) +{ + return ch->demux; +} + +CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch) +{ + return ch->mutex; +} + +int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch) +{ + return ossl_quic_demux_has_pending(ch->demux) + || ossl_qrx_processed_read_pending(ch->qrx); +} + +/* + * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components + * ================================================================ + */ + +/* Used by various components. */ +static OSSL_TIME get_time(void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (ch->now_cb == NULL) + return ossl_time_now(); + + return ch->now_cb(ch->now_cb_arg); +} + +/* Used by QSM. */ +static uint64_t get_stream_limit(int uni, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + return uni ? ch->max_local_streams_uni : ch->max_local_streams_bidi; +} + +/* + * Called by QRX to determine if a packet is potentially invalid before trying + * to decrypt it. + */ +static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + /* Potential duplicates should not be processed. */ + if (!ossl_ackm_is_rx_pn_processable(ch->ackm, pn, pn_space)) + return 0; + + return 1; +} + +/* + * Triggers a TXKU (whether spontaneous or solicited). Does not check whether + * spontaneous TXKU is currently allowed. + */ +QUIC_NEEDS_LOCK +static void ch_trigger_txku(QUIC_CHANNEL *ch) +{ + uint64_t next_pn + = ossl_quic_tx_packetiser_get_next_pn(ch->txp, QUIC_PN_SPACE_APP); + + if (!ossl_quic_pn_valid(next_pn) + || !ossl_qtx_trigger_key_update(ch->qtx)) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + "key update"); + return; + } + + ch->txku_in_progress = 1; + ch->txku_pn = next_pn; + ch->rxku_expected = ch->ku_locally_initiated; +} + +QUIC_NEEDS_LOCK +static int txku_in_progress(QUIC_CHANNEL *ch) +{ + if (ch->txku_in_progress + && ossl_ackm_get_largest_acked(ch->ackm, QUIC_PN_SPACE_APP) >= ch->txku_pn) { + OSSL_TIME pto = ossl_ackm_get_pto_duration(ch->ackm); + + /* + * RFC 9001 s. 6.5: Endpoints SHOULD wait three times the PTO before + * initiating a key update after receiving an acknowledgment that + * confirms that the previous key update was received. + * + * Note that by the above wording, this period starts from when we get + * the ack for a TXKU-triggering packet, not when the TXKU is initiated. + * So we defer TXKU cooldown deadline calculation to this point. + */ + ch->txku_in_progress = 0; + ch->txku_cooldown_deadline = ossl_time_add(get_time(ch), + ossl_time_multiply(pto, 3)); + } + + return ch->txku_in_progress; +} + +QUIC_NEEDS_LOCK +static int txku_allowed(QUIC_CHANNEL *ch) +{ + return ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT /* Sanity check. */ + /* Strict RFC 9001 criterion for TXKU. */ + && ch->handshake_confirmed + && !txku_in_progress(ch); +} + +QUIC_NEEDS_LOCK +static int txku_recommendable(QUIC_CHANNEL *ch) +{ + if (!txku_allowed(ch)) + return 0; + + return + /* Recommended RFC 9001 criterion for TXKU. */ + ossl_time_compare(get_time(ch), ch->txku_cooldown_deadline) >= 0 + /* Some additional sensible criteria. */ + && !ch->rxku_in_progress + && !ch->rxku_pending_confirm; +} + +QUIC_NEEDS_LOCK +static int txku_desirable(QUIC_CHANNEL *ch) +{ + uint64_t cur_pkt_count, max_pkt_count, thresh_pkt_count; + const uint32_t enc_level = QUIC_ENC_LEVEL_1RTT; + + /* Check AEAD limit to determine if we should perform a spontaneous TXKU. */ + cur_pkt_count = ossl_qtx_get_cur_epoch_pkt_count(ch->qtx, enc_level); + max_pkt_count = ossl_qtx_get_max_epoch_pkt_count(ch->qtx, enc_level); + + thresh_pkt_count = max_pkt_count / 2; + if (ch->txku_threshold_override != UINT64_MAX) + thresh_pkt_count = ch->txku_threshold_override; + + return cur_pkt_count >= thresh_pkt_count; +} + +QUIC_NEEDS_LOCK +static void ch_maybe_trigger_spontaneous_txku(QUIC_CHANNEL *ch) +{ + if (!txku_recommendable(ch) || !txku_desirable(ch)) + return; + + ch->ku_locally_initiated = 1; + ch_trigger_txku(ch); +} + +QUIC_NEEDS_LOCK +static int rxku_allowed(QUIC_CHANNEL *ch) +{ + /* + * RFC 9001 s. 6.1: An endpoint MUST NOT initiate a key update prior to + * having confirmed the handshake (Section 4.1.2). + * + * RFC 9001 s. 6.1: An endpoint MUST NOT initiate a subsequent key update + * unless it has received an acknowledgment for a packet that was sent + * protected with keys from the current key phase. + * + * RFC 9001 s. 6.2: If an endpoint detects a second update before it has + * sent any packets with updated keys containing an acknowledgment for the + * packet that initiated the key update, it indicates that its peer has + * updated keys twice without awaiting confirmation. An endpoint MAY treat + * such consecutive key updates as a connection error of type + * KEY_UPDATE_ERROR. + */ + return ch->handshake_confirmed && !ch->rxku_pending_confirm; +} + +/* + * Called when the QRX detects a new RX key update event. + */ +enum rxku_decision { + DECISION_RXKU_ONLY, + DECISION_PROTOCOL_VIOLATION, + DECISION_SOLICITED_TXKU +}; + +/* Called when the QRX detects a key update has occurred. */ +QUIC_NEEDS_LOCK +static void rxku_detected(QUIC_PN pn, void *arg) +{ + QUIC_CHANNEL *ch = arg; + enum rxku_decision decision; + OSSL_TIME pto; + + /* + * Note: rxku_in_progress is always 0 here as an RXKU cannot be detected + * when we are still in UPDATING or COOLDOWN (see quic_record_rx.h). + */ + assert(!ch->rxku_in_progress); + + if (!rxku_allowed(ch)) + /* Is RXKU even allowed at this time? */ + decision = DECISION_PROTOCOL_VIOLATION; + + else if (ch->ku_locally_initiated) + /* + * If this key update was locally initiated (meaning that this detected + * RXKU event is a result of our own spontaneous TXKU), we do not + * trigger another TXKU; after all, to do so would result in an infinite + * ping-pong of key updates. We still process it as an RXKU. + */ + decision = DECISION_RXKU_ONLY; + + else + /* + * Otherwise, a peer triggering a KU means we have to trigger a KU also. + */ + decision = DECISION_SOLICITED_TXKU; + + if (decision == DECISION_PROTOCOL_VIOLATION) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_KEY_UPDATE_ERROR, + 0, "RX key update again too soon"); + return; + } + + pto = ossl_ackm_get_pto_duration(ch->ackm); + + ch->ku_locally_initiated = 0; + ch->rxku_in_progress = 1; + ch->rxku_pending_confirm = 1; + ch->rxku_trigger_pn = pn; + ch->rxku_update_end_deadline = ossl_time_add(get_time(ch), pto); + ch->rxku_expected = 0; + + if (decision == DECISION_SOLICITED_TXKU) + /* NOT gated by usual txku_allowed() */ + ch_trigger_txku(ch); + + /* + * Ordinarily, we only generate ACK when some ACK-eliciting frame has been + * received. In some cases, this may not occur for a long time, for example + * if transmission of application data is going in only one direction and + * nothing else is happening with the connection. However, since the peer + * cannot initiate a subsequent (spontaneous) TXKU until its prior + * (spontaneous or solicited) TXKU has completed - meaning that prior + * TXKU's trigger packet (or subsequent packet) has been acknowledged, this + * can lead to very long times before a TXKU is considered 'completed'. + * Optimise this by forcing ACK generation after triggering TXKU. + * (Basically, we consider a RXKU event something that is 'ACK-eliciting', + * which it more or less should be; it is necessarily separate from ordinary + * processing of ACK-eliciting frames as key update is not indicated via a + * frame.) + */ + ossl_quic_tx_packetiser_schedule_ack(ch->txp, QUIC_PN_SPACE_APP); +} + +/* Called per tick to handle RXKU timer events. */ +QUIC_NEEDS_LOCK +static void ch_rxku_tick(QUIC_CHANNEL *ch) +{ + if (!ch->rxku_in_progress + || ossl_time_compare(get_time(ch), ch->rxku_update_end_deadline) < 0) + return; + + ch->rxku_update_end_deadline = ossl_time_infinite(); + ch->rxku_in_progress = 0; + + if (!ossl_qrx_key_update_timeout(ch->qrx, /*normal=*/1)) + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + "RXKU cooldown internal error"); +} + +QUIC_NEEDS_LOCK +static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space, + void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (pn_space != QUIC_PN_SPACE_APP || !ch->rxku_pending_confirm + || !ossl_quic_frame_ack_contains_pn(ack, ch->rxku_trigger_pn)) + return; + + /* + * Defer clearing rxku_pending_confirm until TXP generate call returns + * successfully. + */ + ch->rxku_pending_confirm_done = 1; +} + +/* + * QUIC Channel: Handshake Layer Event Handling + * ============================================ + */ +static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len, + size_t *consumed, void *arg) +{ + int ret; + QUIC_CHANNEL *ch = arg; + uint32_t enc_level = ch->tx_enc_level; + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + QUIC_SSTREAM *sstream = ch->crypto_send[pn_space]; + + if (!ossl_assert(sstream != NULL)) + return 0; + + ret = ossl_quic_sstream_append(sstream, buf, buf_len, consumed); + return ret; +} + +static int crypto_ensure_empty(QUIC_RSTREAM *rstream) +{ + size_t avail = 0; + int is_fin = 0; + + if (rstream == NULL) + return 1; + + if (!ossl_quic_rstream_available(rstream, &avail, &is_fin)) + return 0; + + return avail == 0; +} + +static int ch_on_crypto_recv_record(const unsigned char **buf, + size_t *bytes_read, void *arg) +{ + QUIC_CHANNEL *ch = arg; + QUIC_RSTREAM *rstream; + int is_fin = 0; /* crypto stream is never finished, so we don't use this */ + uint32_t i; + + /* + * After we move to a later EL we must not allow our peer to send any new + * bytes in the crypto stream on a previous EL. Retransmissions of old bytes + * are allowed. + * + * In practice we will only move to a new EL when we have consumed all bytes + * which should be sent on the crypto stream at a previous EL. For example, + * the Handshake EL should not be provisioned until we have completely + * consumed a TLS 1.3 ServerHello. Thus when we provision an EL the output + * of ossl_quic_rstream_available() should be 0 for all lower ELs. Thus if a + * given EL is available we simply ensure we have not received any further + * bytes at a lower EL. + */ + for (i = QUIC_ENC_LEVEL_INITIAL; i < ch->rx_enc_level; ++i) + if (i != QUIC_ENC_LEVEL_0RTT && + !crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { + /* Protocol violation (RFC 9001 s. 4.1.3) */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "crypto stream data in wrong EL"); + return 0; + } + + rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->rx_enc_level)]; + if (rstream == NULL) + return 0; + + return ossl_quic_rstream_get_record(rstream, buf, bytes_read, + &is_fin); +} + +static int ch_on_crypto_release_record(size_t bytes_read, void *arg) +{ + QUIC_CHANNEL *ch = arg; + QUIC_RSTREAM *rstream; + OSSL_RTT_INFO rtt_info; + uint32_t rx_pn_space = ossl_quic_enc_level_to_pn_space(ch->rx_enc_level); + + rstream = ch->crypto_recv[rx_pn_space]; + if (rstream == NULL) + return 0; + + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info); + if (!ossl_quic_rxfc_on_retire(&ch->crypto_rxfc[rx_pn_space], bytes_read, + rtt_info.smoothed_rtt)) + return 0; + + return ossl_quic_rstream_release_record(rstream, bytes_read); +} + +static int ch_on_handshake_yield_secret(uint32_t enc_level, int direction, + uint32_t suite_id, EVP_MD *md, + const unsigned char *secret, + size_t secret_len, + void *arg) +{ + QUIC_CHANNEL *ch = arg; + uint32_t i; + + if (enc_level < QUIC_ENC_LEVEL_HANDSHAKE || enc_level >= QUIC_ENC_LEVEL_NUM) + /* Invalid EL. */ + return 0; + + + if (direction) { + /* TX */ + if (enc_level <= ch->tx_enc_level) + /* + * Does not make sense for us to try and provision an EL we have already + * attained. + */ + return 0; + + if (!ossl_qtx_provide_secret(ch->qtx, enc_level, + suite_id, md, + secret, secret_len)) + return 0; + + ch->tx_enc_level = enc_level; + } else { + /* RX */ + if (enc_level <= ch->rx_enc_level) + /* + * Does not make sense for us to try and provision an EL we have already + * attained. + */ + return 0; + + /* + * Ensure all crypto streams for previous ELs are now empty of available + * data. + */ + for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i) + if (!crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { + /* Protocol violation (RFC 9001 s. 4.1.3) */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "crypto stream data in wrong EL"); + return 0; + } + + if (!ossl_qrx_provide_secret(ch->qrx, enc_level, + suite_id, md, + secret, secret_len)) + return 0; + + ch->have_new_rx_secret = 1; + ch->rx_enc_level = enc_level; + } + + return 1; +} + +static int ch_on_handshake_complete(void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (!ossl_assert(!ch->handshake_complete)) + return 0; /* this should not happen twice */ + + if (!ossl_assert(ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT)) + return 0; + + if (!ch->got_remote_transport_params) { + /* + * Was not a valid QUIC handshake if we did not get valid transport + * params. + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_MISSING_EXT, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "no transport parameters received"); + return 0; + } + + /* Don't need transport parameters anymore. */ + OPENSSL_free(ch->local_transport_params); + ch->local_transport_params = NULL; + + /* Tell the QRX it can now process 1-RTT packets. */ + ossl_qrx_allow_1rtt_processing(ch->qrx); + + /* Tell TXP the handshake is complete. */ + ossl_quic_tx_packetiser_notify_handshake_complete(ch->txp); + + ch->handshake_complete = 1; + + if (ch->is_server) { + /* + * On the server, the handshake is confirmed as soon as it is complete. + */ + ossl_quic_channel_on_handshake_confirmed(ch); + + ossl_quic_tx_packetiser_schedule_handshake_done(ch->txp); + } + + return 1; +} + +static int ch_on_handshake_alert(void *arg, unsigned char alert_code) +{ + QUIC_CHANNEL *ch = arg; + + /* + * RFC 9001 s. 4.4: More specifically, servers MUST NOT send post-handshake + * TLS CertificateRequest messages, and clients MUST treat receipt of such + * messages as a connection error of type PROTOCOL_VIOLATION. + */ + if (alert_code == SSL_AD_UNEXPECTED_MESSAGE + && ch->handshake_complete + && ossl_quic_tls_is_cert_request(ch->qtls)) + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + 0, + "Post-handshake TLS " + "CertificateRequest received"); + /* + * RFC 9001 s. 4.6.1: Servers MUST NOT send the early_data extension with a + * max_early_data_size field set to any value other than 0xffffffff. A + * client MUST treat receipt of a NewSessionTicket that contains an + * early_data extension with any other value as a connection error of type + * PROTOCOL_VIOLATION. + */ + else if (alert_code == SSL_AD_ILLEGAL_PARAMETER + && ch->handshake_complete + && ossl_quic_tls_has_bad_max_early_data(ch->qtls)) + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + 0, + "Bad max_early_data received"); + else + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_CRYPTO_ERR_BEGIN + + alert_code, + 0, "handshake alert"); + + return 1; +} + +/* + * QUIC Channel: Transport Parameter Handling + * ========================================== + */ + +/* + * Called by handshake layer when we receive QUIC Transport Parameters from the + * peer. Note that these are not authenticated until the handshake is marked + * as complete. + */ +#define TP_REASON_SERVER_ONLY(x) \ + x " may not be sent by a client" +#define TP_REASON_DUP(x) \ + x " appears multiple times" +#define TP_REASON_MALFORMED(x) \ + x " is malformed" +#define TP_REASON_EXPECTED_VALUE(x) \ + x " does not match expected value" +#define TP_REASON_NOT_RETRY(x) \ + x " sent when not performing a retry" +#define TP_REASON_REQUIRED(x) \ + x " was not sent but is required" +#define TP_REASON_INTERNAL_ERROR(x) \ + x " encountered internal error" + +static void txfc_bump_cwm_bidi(QUIC_STREAM *s, void *arg) +{ + if (!ossl_quic_stream_is_bidi(s) + || ossl_quic_stream_is_server_init(s)) + return; + + ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg); +} + +static void txfc_bump_cwm_uni(QUIC_STREAM *s, void *arg) +{ + if (ossl_quic_stream_is_bidi(s) + || ossl_quic_stream_is_server_init(s)) + return; + + ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg); +} + +static void do_update(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static int ch_on_transport_params(const unsigned char *params, + size_t params_len, + void *arg) +{ + QUIC_CHANNEL *ch = arg; + PACKET pkt; + uint64_t id, v; + size_t len; + const unsigned char *body; + int got_orig_dcid = 0; + int got_initial_scid = 0; + int got_retry_scid = 0; + int got_initial_max_data = 0; + int got_initial_max_stream_data_bidi_local = 0; + int got_initial_max_stream_data_bidi_remote = 0; + int got_initial_max_stream_data_uni = 0; + int got_initial_max_streams_bidi = 0; + int got_initial_max_streams_uni = 0; + int got_stateless_reset_token = 0; + int got_preferred_addr = 0; + int got_ack_delay_exp = 0; + int got_max_ack_delay = 0; + int got_max_udp_payload_size = 0; + int got_max_idle_timeout = 0; + int got_active_conn_id_limit = 0; + int got_disable_active_migration = 0; + QUIC_CONN_ID cid; + const char *reason = "bad transport parameter"; + + if (ch->got_remote_transport_params) { + reason = "multiple transport parameter extensions"; + goto malformed; + } + + if (!PACKET_buf_init(&pkt, params, params_len)) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + "internal error (packet buf init)"); + return 0; + } + + while (PACKET_remaining(&pkt) > 0) { + if (!ossl_quic_wire_peek_transport_param(&pkt, &id)) + goto malformed; + + switch (id) { + case QUIC_TPARAM_ORIG_DCID: + if (got_orig_dcid) { + reason = TP_REASON_DUP("ORIG_DCID"); + goto malformed; + } + + if (ch->is_server) { + reason = TP_REASON_SERVER_ONLY("ORIG_DCID"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { + reason = TP_REASON_MALFORMED("ORIG_DCID"); + goto malformed; + } + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Must match our initial DCID. */ + if (!ossl_quic_conn_id_eq(&ch->init_dcid, &cid)) { + reason = TP_REASON_EXPECTED_VALUE("ORIG_DCID"); + goto malformed; + } +#endif + + got_orig_dcid = 1; + break; + + case QUIC_TPARAM_RETRY_SCID: + if (ch->is_server) { + reason = TP_REASON_SERVER_ONLY("RETRY_SCID"); + goto malformed; + } + + if (got_retry_scid) { + reason = TP_REASON_DUP("RETRY_SCID"); + goto malformed; + } + + if (!ch->doing_retry) { + reason = TP_REASON_NOT_RETRY("RETRY_SCID"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { + reason = TP_REASON_MALFORMED("RETRY_SCID"); + goto malformed; + } + + /* Must match Retry packet SCID. */ + if (!ossl_quic_conn_id_eq(&ch->retry_scid, &cid)) { + reason = TP_REASON_EXPECTED_VALUE("RETRY_SCID"); + goto malformed; + } + + got_retry_scid = 1; + break; + + case QUIC_TPARAM_INITIAL_SCID: + if (got_initial_scid) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_SCID"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { + reason = TP_REASON_MALFORMED("INITIAL_SCID"); + goto malformed; + } + + /* Must match SCID of first Initial packet from server. */ + if (!ossl_quic_conn_id_eq(&ch->init_scid, &cid)) { + reason = TP_REASON_EXPECTED_VALUE("INITIAL_SCID"); + goto malformed; + } + + got_initial_scid = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_DATA: + if (got_initial_max_data) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_DATA"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_DATA"); + goto malformed; + } + + ossl_quic_txfc_bump_cwm(&ch->conn_txfc, v); + got_initial_max_data = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL: + if (got_initial_max_stream_data_bidi_local) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"); + goto malformed; + } + + /* + * This is correct; the BIDI_LOCAL TP governs streams created by + * the endpoint which sends the TP, i.e., our peer. + */ + ch->rx_init_max_stream_data_bidi_remote = v; + got_initial_max_stream_data_bidi_local = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE: + if (got_initial_max_stream_data_bidi_remote) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"); + goto malformed; + } + + /* + * This is correct; the BIDI_REMOTE TP governs streams created + * by the endpoint which receives the TP, i.e., us. + */ + ch->rx_init_max_stream_data_bidi_local = v; + + /* Apply to all existing streams. */ + ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_bidi, &v); + got_initial_max_stream_data_bidi_remote = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI: + if (got_initial_max_stream_data_uni) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_UNI"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_UNI"); + goto malformed; + } + + ch->rx_init_max_stream_data_uni = v; + + /* Apply to all existing streams. */ + ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_uni, &v); + got_initial_max_stream_data_uni = 1; + break; + + case QUIC_TPARAM_ACK_DELAY_EXP: + if (got_ack_delay_exp) { + /* must not appear more than once */ + reason = TP_REASON_DUP("ACK_DELAY_EXP"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v > QUIC_MAX_ACK_DELAY_EXP) { + reason = TP_REASON_MALFORMED("ACK_DELAY_EXP"); + goto malformed; + } + + ch->rx_ack_delay_exp = (unsigned char)v; + got_ack_delay_exp = 1; + break; + + case QUIC_TPARAM_MAX_ACK_DELAY: + if (got_max_ack_delay) { + /* must not appear more than once */ + reason = TP_REASON_DUP("MAX_ACK_DELAY"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v >= (((uint64_t)1) << 14)) { + reason = TP_REASON_MALFORMED("MAX_ACK_DELAY"); + goto malformed; + } + + ch->rx_max_ack_delay = v; + ossl_ackm_set_rx_max_ack_delay(ch->ackm, + ossl_ms2time(ch->rx_max_ack_delay)); + + got_max_ack_delay = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI: + if (got_initial_max_streams_bidi) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_BIDI"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v > (((uint64_t)1) << 60)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_BIDI"); + goto malformed; + } + + assert(ch->max_local_streams_bidi == 0); + ch->max_local_streams_bidi = v; + got_initial_max_streams_bidi = 1; + break; + + case QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI: + if (got_initial_max_streams_uni) { + /* must not appear more than once */ + reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_UNI"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v > (((uint64_t)1) << 60)) { + reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_UNI"); + goto malformed; + } + + assert(ch->max_local_streams_uni == 0); + ch->max_local_streams_uni = v; + got_initial_max_streams_uni = 1; + break; + + case QUIC_TPARAM_MAX_IDLE_TIMEOUT: + if (got_max_idle_timeout) { + /* must not appear more than once */ + reason = TP_REASON_DUP("MAX_IDLE_TIMEOUT"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { + reason = TP_REASON_MALFORMED("MAX_IDLE_TIMEOUT"); + goto malformed; + } + + if (v > 0 && v < ch->max_idle_timeout) + ch->max_idle_timeout = v; + + ch_update_idle(ch); + got_max_idle_timeout = 1; + break; + + case QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE: + if (got_max_udp_payload_size) { + /* must not appear more than once */ + reason = TP_REASON_DUP("MAX_UDP_PAYLOAD_SIZE"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v < QUIC_MIN_INITIAL_DGRAM_LEN) { + reason = TP_REASON_MALFORMED("MAX_UDP_PAYLOAD_SIZE"); + goto malformed; + } + + ch->rx_max_udp_payload_size = v; + got_max_udp_payload_size = 1; + break; + + case QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT: + if (got_active_conn_id_limit) { + /* must not appear more than once */ + reason = TP_REASON_DUP("ACTIVE_CONN_ID_LIMIT"); + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v) + || v < QUIC_MIN_ACTIVE_CONN_ID_LIMIT) { + reason = TP_REASON_MALFORMED("ACTIVE_CONN_ID_LIMIT"); + goto malformed; + } + + ch->rx_active_conn_id_limit = v; + got_active_conn_id_limit = 1; + break; + + case QUIC_TPARAM_STATELESS_RESET_TOKEN: + if (got_stateless_reset_token) { + reason = TP_REASON_DUP("STATELESS_RESET_TOKEN"); + goto malformed; + } + + /* + * We must ensure a client doesn't send them because we don't have + * processing for them. + * + * TODO(QUIC SERVER): remove this restriction + */ + if (ch->is_server) { + reason = TP_REASON_SERVER_ONLY("STATELESS_RESET_TOKEN"); + goto malformed; + } + + body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len); + if (body == NULL || len != QUIC_STATELESS_RESET_TOKEN_LEN) { + reason = TP_REASON_MALFORMED("STATELESS_RESET_TOKEN"); + goto malformed; + } + if (!chan_add_reset_token(ch, body, ch->cur_remote_seq_num)) { + reason = TP_REASON_INTERNAL_ERROR("STATELESS_RESET_TOKEN"); + goto malformed; + } + + got_stateless_reset_token = 1; + break; + + case QUIC_TPARAM_PREFERRED_ADDR: + { + /* TODO(QUIC FUTURE): Handle preferred address. */ + QUIC_PREFERRED_ADDR pfa; + if (got_preferred_addr) { + reason = TP_REASON_DUP("PREFERRED_ADDR"); + goto malformed; + } + + /* + * RFC 9000 s. 18.2: "A server that chooses a zero-length + * connection ID MUST NOT provide a preferred address. + * Similarly, a server MUST NOT include a zero-length connection + * ID in this transport parameter. A client MUST treat a + * violation of these requirements as a connection error of type + * TRANSPORT_PARAMETER_ERROR." + */ + if (ch->is_server) { + reason = TP_REASON_SERVER_ONLY("PREFERRED_ADDR"); + goto malformed; + } + + if (ch->cur_remote_dcid.id_len == 0) { + reason = "PREFERRED_ADDR provided for zero-length CID"; + goto malformed; + } + + if (!ossl_quic_wire_decode_transport_param_preferred_addr(&pkt, &pfa)) { + reason = TP_REASON_MALFORMED("PREFERRED_ADDR"); + goto malformed; + } + + if (pfa.cid.id_len == 0) { + reason = "zero-length CID in PREFERRED_ADDR"; + goto malformed; + } + + got_preferred_addr = 1; + } + break; + + case QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION: + /* We do not currently handle migration, so nothing to do. */ + if (got_disable_active_migration) { + /* must not appear more than once */ + reason = TP_REASON_DUP("DISABLE_ACTIVE_MIGRATION"); + goto malformed; + } + + body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len); + if (body == NULL || len > 0) { + reason = TP_REASON_MALFORMED("DISABLE_ACTIVE_MIGRATION"); + goto malformed; + } + + got_disable_active_migration = 1; + break; + + default: + /* + * Skip over and ignore. + * + * RFC 9000 s. 7.4: We SHOULD treat duplicated transport parameters + * as a connection error, but we are not required to. Currently, + * handle this programmatically by checking for duplicates in the + * parameters that we recognise, as above, but don't bother + * maintaining a list of duplicates for anything we don't recognise. + */ + body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, + &len); + if (body == NULL) + goto malformed; + + break; + } + } + + if (!got_initial_scid) { + reason = TP_REASON_REQUIRED("INITIAL_SCID"); + goto malformed; + } + + if (!ch->is_server) { + if (!got_orig_dcid) { + reason = TP_REASON_REQUIRED("ORIG_DCID"); + goto malformed; + } + + if (ch->doing_retry && !got_retry_scid) { + reason = TP_REASON_REQUIRED("RETRY_SCID"); + goto malformed; + } + } + + ch->got_remote_transport_params = 1; + + if (got_initial_max_data || got_initial_max_stream_data_bidi_remote + || got_initial_max_streams_bidi || got_initial_max_streams_uni) + /* + * If FC credit was bumped, we may now be able to send. Update all + * streams. + */ + ossl_quic_stream_map_visit(&ch->qsm, do_update, ch); + + /* If we are a server, we now generate our own transport parameters. */ + if (ch->is_server && !ch_generate_transport_params(ch)) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + "internal error"); + return 0; + } + + return 1; + +malformed: + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_TRANSPORT_PARAMETER_ERROR, + 0, reason); + return 0; +} + +/* + * Called when we want to generate transport parameters. This is called + * immediately at instantiation time for a client and after we receive the + * client's transport parameters for a server. + */ +static int ch_generate_transport_params(QUIC_CHANNEL *ch) +{ + int ok = 0; + BUF_MEM *buf_mem = NULL; + WPACKET wpkt; + int wpkt_valid = 0; + size_t buf_len = 0; + + if (ch->local_transport_params != NULL) + goto err; + + if ((buf_mem = BUF_MEM_new()) == NULL) + goto err; + + if (!WPACKET_init(&wpkt, buf_mem)) + goto err; + + wpkt_valid = 1; + + if (ossl_quic_wire_encode_transport_param_bytes(&wpkt, QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION, + NULL, 0) == NULL) + goto err; + + if (ch->is_server) { + if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_ORIG_DCID, + &ch->init_dcid)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_INITIAL_SCID, + &ch->cur_local_cid)) + goto err; + } else { + /* Client always uses an empty SCID. */ + if (ossl_quic_wire_encode_transport_param_bytes(&wpkt, QUIC_TPARAM_INITIAL_SCID, + NULL, 0) == NULL) + goto err; + } + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_IDLE_TIMEOUT, + ch->max_idle_timeout)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE, + QUIC_MIN_INITIAL_DGRAM_LEN)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT, + QUIC_MIN_ACTIVE_CONN_ID_LIMIT)) + goto err; + + if (ch->tx_max_ack_delay != QUIC_DEFAULT_MAX_ACK_DELAY + && !ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_ACK_DELAY, + ch->tx_max_ack_delay)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_DATA, + ossl_quic_rxfc_get_cwm(&ch->conn_rxfc))) + goto err; + + /* Send the default CWM for a new RXFC. */ + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL, + ch->tx_init_max_stream_data_bidi_local)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE, + ch->tx_init_max_stream_data_bidi_remote)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI, + ch->tx_init_max_stream_data_uni)) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI, + ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc))) + goto err; + + if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI, + ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc))) + goto err; + + if (!WPACKET_finish(&wpkt)) + goto err; + + wpkt_valid = 0; + + if (!WPACKET_get_total_written(&wpkt, &buf_len)) + goto err; + + ch->local_transport_params = (unsigned char *)buf_mem->data; + buf_mem->data = NULL; + + + if (!ossl_quic_tls_set_transport_params(ch->qtls, ch->local_transport_params, + buf_len)) + goto err; + + ok = 1; +err: + if (wpkt_valid) + WPACKET_cleanup(&wpkt); + BUF_MEM_free(buf_mem); + return ok; +} + +/* + * QUIC Channel: Ticker-Mutator + * ============================ + */ + +/* + * The central ticker function called by the reactor. This does everything, or + * at least everything network I/O related. Best effort - not allowed to fail + * "loudly". + */ +static void ch_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) +{ + OSSL_TIME now, deadline; + QUIC_CHANNEL *ch = arg; + int channel_only = (flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0; + + /* + * When we tick the QUIC connection, we do everything we need to do + * periodically. In order, we: + * + * - handle any incoming data from the network; + * - handle any timer events which are due to fire (ACKM, etc.) + * - write any data to the network due to be sent, to the extent + * possible; + * - determine the time at which we should next be ticked. + */ + + /* If we are in the TERMINATED state, there is nothing to do. */ + if (ossl_quic_channel_is_terminated(ch)) { + res->net_read_desired = 0; + res->net_write_desired = 0; + res->tick_deadline = ossl_time_infinite(); + return; + } + + /* + * If we are in the TERMINATING state, check if the terminating timer has + * expired. + */ + if (ossl_quic_channel_is_terminating(ch)) { + now = get_time(ch); + + if (ossl_time_compare(now, ch->terminate_deadline) >= 0) { + ch_on_terminating_timeout(ch); + res->net_read_desired = 0; + res->net_write_desired = 0; + res->tick_deadline = ossl_time_infinite(); + return; /* abort normal processing, nothing to do */ + } + } + + if (!ch->inhibit_tick) { + /* Handle RXKU timeouts. */ + ch_rxku_tick(ch); + + /* Handle any incoming data from network. */ + ch_rx_pre(ch); + + do { + /* Process queued incoming packets. */ + ch->did_tls_tick = 0; + ch->have_new_rx_secret = 0; + ch_rx(ch, channel_only); + + /* + * Allow the handshake layer to check for any new incoming data and + * generate new outgoing data. + */ + if (!ch->did_tls_tick) + ch_tick_tls(ch, channel_only); + + /* + * If the handshake layer gave us a new secret, we need to do RX + * again because packets that were not previously processable and + * were deferred might now be processable. + * + * TODO(QUIC FUTURE): Consider handling this in the yield_secret callback. + */ + } while (ch->have_new_rx_secret); + } + + /* + * Handle any timer events which are due to fire; namely, the loss + * detection deadline and the idle timeout. + * + * ACKM ACK generation deadline is polled by TXP, so we don't need to + * handle it here. + */ + now = get_time(ch); + if (ossl_time_compare(now, ch->idle_deadline) >= 0) { + /* + * Idle timeout differs from normal protocol violation because we do + * not send a CONN_CLOSE frame; go straight to TERMINATED. + */ + if (!ch->inhibit_tick) + ch_on_idle_timeout(ch); + + res->net_read_desired = 0; + res->net_write_desired = 0; + res->tick_deadline = ossl_time_infinite(); + return; + } + + if (!ch->inhibit_tick) { + deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm); + if (!ossl_time_is_zero(deadline) + && ossl_time_compare(now, deadline) >= 0) + ossl_ackm_on_timeout(ch->ackm); + + /* If a ping is due, inform TXP. */ + if (ossl_time_compare(now, ch->ping_deadline) >= 0) { + int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level); + + ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space); + + /* + * If we have no CC budget at this time we cannot process the above + * PING request immediately. In any case we have scheduled the + * request so bump the ping deadline. If we don't do this we will + * busy-loop endlessly as the above deadline comparison condition + * will still be met. + */ + ch_update_ping_deadline(ch); + } + + /* Write any data to the network due to be sent. */ + ch_tx(ch); + + /* Do stream GC. */ + ossl_quic_stream_map_gc(&ch->qsm); + } + + /* Determine the time at which we should next be ticked. */ + res->tick_deadline = ch_determine_next_tick_deadline(ch); + + /* + * Always process network input unless we are now terminated. + * Although we had not terminated at the beginning of this tick, network + * errors in ch_rx_pre() or ch_tx() may have caused us to transition to the + * Terminated state. + */ + res->net_read_desired = !ossl_quic_channel_is_terminated(ch); + + /* We want to write to the network if we have any in our queue. */ + res->net_write_desired + = (!ossl_quic_channel_is_terminated(ch) + && ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0); +} + +static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only) +{ + uint64_t error_code; + const char *error_msg; + ERR_STATE *error_state = NULL; + + if (channel_only) + return 1; + + ch->did_tls_tick = 1; + ossl_quic_tls_tick(ch->qtls); + + if (ossl_quic_tls_get_error(ch->qtls, &error_code, &error_msg, + &error_state)) { + ossl_quic_channel_raise_protocol_error_state(ch, error_code, 0, + error_msg, error_state); + return 0; + } + + return 1; +} + +/* Process incoming datagrams, if any. */ +static void ch_rx_pre(QUIC_CHANNEL *ch) +{ + int ret; + + if (!ch->is_server && !ch->have_sent_any_pkt) + return; + + /* + * Get DEMUX to BIO_recvmmsg from the network and queue incoming datagrams + * to the appropriate QRX instance. + */ + ret = ossl_quic_demux_pump(ch->demux); + if (ret == QUIC_DEMUX_PUMP_RES_STATELESS_RESET) + ch_stateless_reset(ch); + else if (ret == QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL) + /* + * We don't care about transient failure, but permanent failure means we + * should tear down the connection as though a protocol violation + * occurred. Skip straight to the Terminating state as there is no point + * trying to send CONNECTION_CLOSE frames if the network BIO is not + * operating correctly. + */ + ch_raise_net_error(ch); +} + +/* Check incoming forged packet limit and terminate connection if needed. */ +static void ch_rx_check_forged_pkt_limit(QUIC_CHANNEL *ch) +{ + uint32_t enc_level; + uint64_t limit = UINT64_MAX, l; + + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) + { + /* + * Different ELs can have different AEADs which can in turn impose + * different limits, so use the lowest value of any currently valid EL. + */ + if ((ch->el_discarded & (1U << enc_level)) != 0) + continue; + + if (enc_level > ch->rx_enc_level) + break; + + l = ossl_qrx_get_max_forged_pkt_count(ch->qrx, enc_level); + if (l < limit) + limit = l; + } + + if (ossl_qrx_get_cur_forged_pkt_count(ch->qrx) < limit) + return; + + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_AEAD_LIMIT_REACHED, 0, + "forgery limit"); +} + +/* Process queued incoming packets and handle frames, if any. */ +static int ch_rx(QUIC_CHANNEL *ch, int channel_only) +{ + int handled_any = 0; + const int closing = ossl_quic_channel_is_closing(ch); + + if (!ch->is_server && !ch->have_sent_any_pkt) + /* + * We have not sent anything yet, therefore there is no need to check + * for incoming data. + */ + return 1; + + for (;;) { + assert(ch->qrx_pkt == NULL); + + if (!ossl_qrx_read_pkt(ch->qrx, &ch->qrx_pkt)) + break; + + /* Track the amount of data received while in the closing state */ + if (closing) + ossl_quic_tx_packetiser_record_received_closing_bytes( + ch->txp, ch->qrx_pkt->hdr->len); + + if (!handled_any) { + ch_update_idle(ch); + ch_update_ping_deadline(ch); + } + + ch_rx_handle_packet(ch, channel_only); /* best effort */ + + /* + * Regardless of the outcome of frame handling, unref the packet. + * This will free the packet unless something added another + * reference to it during frame processing. + */ + ossl_qrx_pkt_release(ch->qrx_pkt); + ch->qrx_pkt = NULL; + + ch->have_sent_ack_eliciting_since_rx = 0; + handled_any = 1; + } + + ch_rx_check_forged_pkt_limit(ch); + + /* + * When in TERMINATING - CLOSING, generate a CONN_CLOSE frame whenever we + * process one or more incoming packets. + */ + if (handled_any && closing) + ch->conn_close_queued = 1; + + return 1; +} + +static int bio_addr_eq(const BIO_ADDR *a, const BIO_ADDR *b) +{ + if (BIO_ADDR_family(a) != BIO_ADDR_family(b)) + return 0; + + switch (BIO_ADDR_family(a)) { + case AF_INET: + return !memcmp(&a->s_in.sin_addr, + &b->s_in.sin_addr, + sizeof(a->s_in.sin_addr)) + && a->s_in.sin_port == b->s_in.sin_port; +#if OPENSSL_USE_IPV6 + case AF_INET6: + return !memcmp(&a->s_in6.sin6_addr, + &b->s_in6.sin6_addr, + sizeof(a->s_in6.sin6_addr)) + && a->s_in6.sin6_port == b->s_in6.sin6_port; +#endif + default: + return 0; /* not supported */ + } + + return 1; +} + +/* Handles the packet currently in ch->qrx_pkt->hdr. */ +static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only) +{ + uint32_t enc_level; + int old_have_processed_any_pkt = ch->have_processed_any_pkt; + + assert(ch->qrx_pkt != NULL); + + /* + * RFC 9000 s. 10.2.1 Closing Connection State: + * An endpoint that is closing is not required to process any + * received frame. + */ + if (!ossl_quic_channel_is_active(ch)) + return; + + if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type)) { + if (!ch->have_received_enc_pkt) { + ch->cur_remote_dcid = ch->init_scid = ch->qrx_pkt->hdr->src_conn_id; + ch->have_received_enc_pkt = 1; + + /* + * We change to using the SCID in the first Initial packet as the + * DCID. + */ + ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->init_scid); + } + + enc_level = ossl_quic_pkt_type_to_enc_level(ch->qrx_pkt->hdr->type); + if ((ch->el_discarded & (1U << enc_level)) != 0) + /* Do not process packets from ELs we have already discarded. */ + return; + } + + /* + * RFC 9000 s. 9.6: "If a client receives packets from a new server address + * when the client has not initiated a migration to that address, the client + * SHOULD discard these packets." + * + * We need to be a bit careful here as due to the BIO abstraction layer an + * application is liable to be weird and lie to us about peer addresses. + * Only apply this check if we actually are using a real AF_INET or AF_INET6 + * address. + */ + if (!ch->is_server + && ch->qrx_pkt->peer != NULL + && ( + BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET +#if OPENSSL_USE_IPV6 + || BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET6 +#endif + ) + && !bio_addr_eq(ch->qrx_pkt->peer, &ch->cur_peer_addr)) + return; + + if (!ch->is_server + && ch->have_received_enc_pkt + && ossl_quic_pkt_type_has_scid(ch->qrx_pkt->hdr->type)) { + /* + * RFC 9000 s. 7.2: "Once a client has received a valid Initial packet + * from the server, it MUST discard any subsequent packet it receives on + * that connection with a different SCID." + */ + if (!ossl_quic_conn_id_eq(&ch->qrx_pkt->hdr->src_conn_id, + &ch->init_scid)) + return; + } + + if (ossl_quic_pkt_type_has_version(ch->qrx_pkt->hdr->type) + && ch->qrx_pkt->hdr->version != QUIC_VERSION_1) + /* + * RFC 9000 s. 5.2.1: If a client receives a packet that uses a + * different version than it initially selected, it MUST discard the + * packet. We only ever use v1, so require it. + */ + return; + + ch->have_processed_any_pkt = 1; + + /* + * RFC 9000 s. 17.2: "An endpoint MUST treat receipt of a packet that has a + * non-zero value for [the reserved bits] after removing both packet and + * header protection as a connection error of type PROTOCOL_VIOLATION." + */ + if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type) + && ch->qrx_pkt->hdr->reserved != 0) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + 0, "packet header reserved bits"); + return; + } + + /* Handle incoming packet. */ + switch (ch->qrx_pkt->hdr->type) { + case QUIC_PKT_TYPE_RETRY: + if (ch->doing_retry || ch->is_server) + /* + * It is not allowed to ask a client to do a retry more than + * once. Clients may not send retries. + */ + return; + + /* + * RFC 9000 s 17.2.5.2: After the client has received and processed an + * Initial or Retry packet from the server, it MUST discard any + * subsequent Retry packets that it receives. + */ + if (ch->have_received_enc_pkt) + return; + + if (ch->qrx_pkt->hdr->len <= QUIC_RETRY_INTEGRITY_TAG_LEN) + /* Packets with zero-length Retry Tokens are invalid. */ + return; + + /* + * TODO(QUIC FUTURE): Theoretically this should probably be in the QRX. + * However because validation is dependent on context (namely the + * client's initial DCID) we can't do this cleanly. In the future we + * should probably add a callback to the QRX to let it call us (via + * the DEMUX) and ask us about the correct original DCID, rather + * than allow the QRX to emit a potentially malformed packet to the + * upper layers. However, special casing this will do for now. + */ + if (!ossl_quic_validate_retry_integrity_tag(ch->libctx, + ch->propq, + ch->qrx_pkt->hdr, + &ch->init_dcid)) + /* Malformed retry packet, ignore. */ + return; + + if (!ch_retry(ch, ch->qrx_pkt->hdr->data, + ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN, + &ch->qrx_pkt->hdr->src_conn_id)) + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + 0, "handling retry packet"); + break; + + case QUIC_PKT_TYPE_0RTT: + if (!ch->is_server) + /* Clients should never receive 0-RTT packets. */ + return; + + /* + * TODO(QUIC 0RTT): Implement 0-RTT on the server side. We currently + * do not need to implement this as a client can only do 0-RTT if we + * have given it permission to in a previous session. + */ + break; + + case QUIC_PKT_TYPE_INITIAL: + case QUIC_PKT_TYPE_HANDSHAKE: + case QUIC_PKT_TYPE_1RTT: + if (ch->is_server && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_HANDSHAKE) + /* + * We automatically drop INITIAL EL keys when first successfully + * decrypting a HANDSHAKE packet, as per the RFC. + */ + ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL); + + if (ch->rxku_in_progress + && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_1RTT + && ch->qrx_pkt->pn >= ch->rxku_trigger_pn + && ch->qrx_pkt->key_epoch < ossl_qrx_get_key_epoch(ch->qrx)) { + /* + * RFC 9001 s. 6.4: Packets with higher packet numbers MUST be + * protected with either the same or newer packet protection keys + * than packets with lower packet numbers. An endpoint that + * successfully removes protection with old keys when newer keys + * were used for packets with lower packet numbers MUST treat this + * as a connection error of type KEY_UPDATE_ERROR. + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_KEY_UPDATE_ERROR, + 0, "new packet with old keys"); + break; + } + + if (!ch->is_server + && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_INITIAL + && ch->qrx_pkt->hdr->token_len > 0) { + /* + * RFC 9000 s. 17.2.2: Clients that receive an Initial packet with a + * non-zero Token Length field MUST either discard the packet or + * generate a connection error of type PROTOCOL_VIOLATION. + * + * TODO(QUIC FUTURE): consider the implications of RFC 9000 s. 10.2.3 + * Immediate Close during the Handshake: + * However, at the cost of reducing feedback about + * errors for legitimate peers, some forms of denial of + * service can be made more difficult for an attacker + * if endpoints discard illegal packets rather than + * terminating a connection with CONNECTION_CLOSE. For + * this reason, endpoints MAY discard packets rather + * than immediately close if errors are detected in + * packets that lack authentication. + * I.e. should we drop this packet instead of closing the connection? + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + 0, "client received initial token"); + break; + } + + /* This packet contains frames, pass to the RXDP. */ + ossl_quic_handle_frames(ch, ch->qrx_pkt); /* best effort */ + + if (ch->did_crypto_frame) + ch_tick_tls(ch, channel_only); + + break; + + case QUIC_PKT_TYPE_VERSION_NEG: + /* + * "A client MUST discard any Version Negotiation packet if it has + * received and successfully processed any other packet." + */ + if (!old_have_processed_any_pkt) + ch_rx_handle_version_neg(ch, ch->qrx_pkt); + + break; + + default: + assert(0); + break; + } +} + +static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt) +{ + /* + * We do not support version negotiation at this time. As per RFC 9000 s. + * 6.2., we MUST abandon the connection attempt if we receive a Version + * Negotiation packet, unless we have already successfully processed another + * incoming packet, or the packet lists the QUIC version we want to use. + */ + PACKET vpkt; + unsigned long v; + + if (!PACKET_buf_init(&vpkt, pkt->hdr->data, pkt->hdr->len)) + return; + + while (PACKET_remaining(&vpkt) > 0) { + if (!PACKET_get_net_4(&vpkt, &v)) + break; + + if ((uint32_t)v == QUIC_VERSION_1) + return; + } + + /* No match, this is a failure case. */ + ch_raise_version_neg_failure(ch); +} + +static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + + tcause.error_code = QUIC_ERR_CONNECTION_REFUSED; + tcause.reason = "version negotiation failure"; + tcause.reason_len = strlen(tcause.reason); + + /* + * Skip TERMINATING state; this is not considered a protocol error and we do + * not send CONNECTION_CLOSE. + */ + ch_start_terminating(ch, &tcause, 1); +} + +/* + * This is called by the demux when we get a packet not destined for any known + * DCID. + */ +static void ch_default_packet_handler(QUIC_URXE *e, void *arg) +{ + QUIC_CHANNEL *ch = arg; + PACKET pkt; + QUIC_PKT_HDR hdr; + + if (!ossl_assert(ch->is_server)) + goto undesirable; + + /* + * We only support one connection to our server currently, so if we already + * started one, ignore any new connection attempts. + */ + if (ch->state != QUIC_CHANNEL_STATE_IDLE) + goto undesirable; + + /* + * We have got a packet for an unknown DCID. This might be an attempt to + * open a new connection. + */ + if (e->data_len < QUIC_MIN_INITIAL_DGRAM_LEN) + goto undesirable; + + if (!PACKET_buf_init(&pkt, ossl_quic_urxe_data(e), e->data_len)) + goto err; + + /* + * We set short_conn_id_len to SIZE_MAX here which will cause the decode + * operation to fail if we get a 1-RTT packet. This is fine since we only + * care about Initial packets. + */ + if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, 0, &hdr, NULL)) + goto undesirable; + + switch (hdr.version) { + case QUIC_VERSION_1: + break; + + case QUIC_VERSION_NONE: + default: + /* Unknown version or proactive version negotiation request, bail. */ + /* TODO(QUIC SERVER): Handle version negotiation on server side */ + goto undesirable; + } + + /* + * We only care about Initial packets which might be trying to establish a + * connection. + */ + if (hdr.type != QUIC_PKT_TYPE_INITIAL) + goto undesirable; + + /* + * Assume this is a valid attempt to initiate a connection. + * + * We do not register the DCID in the initial packet we received and that + * DCID is not actually used again, thus after provisioning the correct + * Initial keys derived from it (which is done in the call below) we pass + * the received packet directly to the QRX so that it can process it as a + * one-time thing, instead of going through the usual DEMUX DCID-based + * routing. + */ + if (!ch_server_on_new_conn(ch, &e->peer, + &hdr.src_conn_id, + &hdr.dst_conn_id)) + goto err; + + ossl_qrx_inject_urxe(ch->qrx, e); + return; + +err: + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, 0, + "internal error"); +undesirable: + ossl_quic_demux_release_urxe(ch->demux, e); +} + +/* Try to generate packets and if possible, flush them to the network. */ +static int ch_tx(QUIC_CHANNEL *ch) +{ + QUIC_TXP_STATUS status; + int res; + + /* + * RFC 9000 s. 10.2.2: Draining Connection State: + * While otherwise identical to the closing state, an endpoint + * in the draining state MUST NOT send any packets. + * and: + * An endpoint MUST NOT send further packets. + */ + if (ossl_quic_channel_is_draining(ch)) + return 0; + + if (ossl_quic_channel_is_closing(ch)) { + /* + * While closing, only send CONN_CLOSE if we've received more traffic + * from the peer. Once we tell the TXP to generate CONN_CLOSE, all + * future calls to it generate CONN_CLOSE frames, so otherwise we would + * just constantly generate CONN_CLOSE frames. + * + * Confirming to RFC 9000 s. 10.2.1 Closing Connection State: + * An endpoint SHOULD limit the rate at which it generates + * packets in the closing state. + */ + if (!ch->conn_close_queued) + return 0; + + ch->conn_close_queued = 0; + } + + /* Do TXKU if we need to. */ + ch_maybe_trigger_spontaneous_txku(ch); + + ch->rxku_pending_confirm_done = 0; + + /* Loop until we stop generating packets to send */ + do { + /* + * Send packet, if we need to. Best effort. The TXP consults the CC and + * applies any limitations imposed by it, so we don't need to do it here. + * + * Best effort. In particular if TXP fails for some reason we should + * still flush any queued packets which we already generated. + */ + res = ossl_quic_tx_packetiser_generate(ch->txp, &status); + if (status.sent_pkt > 0) { + ch->have_sent_any_pkt = 1; /* Packet(s) were sent */ + + /* + * RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when + * sending an ack-eliciting packet if no other ack-eliciting packets + * have been sent since last receiving and processing a packet.' + */ + if (status.sent_ack_eliciting + && !ch->have_sent_ack_eliciting_since_rx) { + ch_update_idle(ch); + ch->have_sent_ack_eliciting_since_rx = 1; + } + + if (!ch->is_server && status.sent_handshake) + /* + * RFC 9001 s. 4.9.1: A client MUST discard Initial keys when it + * first sends a Handshake packet. + */ + ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL); + + if (ch->rxku_pending_confirm_done) + ch->rxku_pending_confirm = 0; + + ch_update_ping_deadline(ch); + } + + if (!res) { + /* + * One case where TXP can fail is if we reach a TX PN of 2**62 - 1. + * As per RFC 9000 s. 12.3, if this happens we MUST close the + * connection without sending a CONNECTION_CLOSE frame. This is + * actually handled as an emergent consequence of our design, as the + * TX packetiser will never transmit another packet when the TX PN + * reaches the limit. + * + * Calling the below function terminates the connection; its attempt + * to schedule a CONNECTION_CLOSE frame will not actually cause a + * packet to be transmitted for this reason. + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + 0, + "internal error (txp generate)"); + break; + } + } while (status.sent_pkt > 0); + + /* Flush packets to network. */ + switch (ossl_qtx_flush_net(ch->qtx)) { + case QTX_FLUSH_NET_RES_OK: + case QTX_FLUSH_NET_RES_TRANSIENT_FAIL: + /* Best effort, done for now. */ + break; + + case QTX_FLUSH_NET_RES_PERMANENT_FAIL: + default: + /* Permanent underlying network BIO, start terminating. */ + ch_raise_net_error(ch); + break; + } + + return 1; +} + +/* Determine next tick deadline. */ +static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch) +{ + OSSL_TIME deadline; + int i; + + if (ossl_quic_channel_is_terminated(ch)) + return ossl_time_infinite(); + + deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm); + if (ossl_time_is_zero(deadline)) + deadline = ossl_time_infinite(); + + /* + * Check the ack deadline for all enc_levels that are actually provisioned. + * ACKs aren't restricted by CC. + */ + for (i = 0; i < QUIC_ENC_LEVEL_NUM; i++) { + if (ossl_qtx_is_enc_level_provisioned(ch->qtx, i)) { + deadline = ossl_time_min(deadline, + ossl_ackm_get_ack_deadline(ch->ackm, + ossl_quic_enc_level_to_pn_space(i))); + } + } + + /* + * When do we need to send an ACK-eliciting packet to reset the idle + * deadline timer for the peer? + */ + if (!ossl_time_is_infinite(ch->ping_deadline)) + deadline = ossl_time_min(deadline, ch->ping_deadline); + + /* Apply TXP wakeup deadline. */ + deadline = ossl_time_min(deadline, + ossl_quic_tx_packetiser_get_deadline(ch->txp)); + + /* Is the terminating timer armed? */ + if (ossl_quic_channel_is_terminating(ch)) + deadline = ossl_time_min(deadline, + ch->terminate_deadline); + else if (!ossl_time_is_infinite(ch->idle_deadline)) + deadline = ossl_time_min(deadline, + ch->idle_deadline); + + /* When does the RXKU process complete? */ + if (ch->rxku_in_progress) + deadline = ossl_time_min(deadline, ch->rxku_update_end_deadline); + + return deadline; +} + +/* + * QUIC Channel: Network BIO Configuration + * ======================================= + */ + +/* Determines whether we can support a given poll descriptor. */ +static int validate_poll_descriptor(const BIO_POLL_DESCRIPTOR *d) +{ + if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + return 1; +} + +BIO *ossl_quic_channel_get_net_rbio(QUIC_CHANNEL *ch) +{ + return ch->net_rbio; +} + +BIO *ossl_quic_channel_get_net_wbio(QUIC_CHANNEL *ch) +{ + return ch->net_wbio; +} + +static int ch_update_poll_desc(QUIC_CHANNEL *ch, BIO *net_bio, int for_write) +{ + BIO_POLL_DESCRIPTOR d = {0}; + + if (net_bio == NULL + || (!for_write && !BIO_get_rpoll_descriptor(net_bio, &d)) + || (for_write && !BIO_get_wpoll_descriptor(net_bio, &d))) + /* Non-pollable BIO */ + d.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + + if (!validate_poll_descriptor(&d)) + return 0; + + if (for_write) + ossl_quic_reactor_set_poll_w(&ch->rtor, &d); + else + ossl_quic_reactor_set_poll_r(&ch->rtor, &d); + + return 1; +} + +int ossl_quic_channel_update_poll_descriptors(QUIC_CHANNEL *ch) +{ + int ok = 1; + + if (!ch_update_poll_desc(ch, ch->net_rbio, /*for_write=*/0)) + ok = 0; + + if (!ch_update_poll_desc(ch, ch->net_wbio, /*for_write=*/1)) + ok = 0; + + return ok; +} + +/* + * QUIC_CHANNEL does not ref any BIO it is provided with, nor is any ref + * transferred to it. The caller (i.e., QUIC_CONNECTION) is responsible for + * ensuring the BIO lasts until the channel is freed or the BIO is switched out + * for another BIO by a subsequent successful call to this function. + */ +int ossl_quic_channel_set_net_rbio(QUIC_CHANNEL *ch, BIO *net_rbio) +{ + if (ch->net_rbio == net_rbio) + return 1; + + if (!ch_update_poll_desc(ch, net_rbio, /*for_write=*/0)) + return 0; + + ossl_quic_demux_set_bio(ch->demux, net_rbio); + ch->net_rbio = net_rbio; + return 1; +} + +int ossl_quic_channel_set_net_wbio(QUIC_CHANNEL *ch, BIO *net_wbio) +{ + if (ch->net_wbio == net_wbio) + return 1; + + if (!ch_update_poll_desc(ch, net_wbio, /*for_write=*/1)) + return 0; + + ossl_qtx_set_bio(ch->qtx, net_wbio); + ch->net_wbio = net_wbio; + return 1; +} + +/* + * QUIC Channel: Lifecycle Events + * ============================== + */ +int ossl_quic_channel_start(QUIC_CHANNEL *ch) +{ + if (ch->is_server) + /* + * This is not used by the server. The server moves to active + * automatically on receiving an incoming connection. + */ + return 0; + + if (ch->state != QUIC_CHANNEL_STATE_IDLE) + /* Calls to connect are idempotent */ + return 1; + + /* Inform QTX of peer address. */ + if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr)) + return 0; + + /* Plug in secrets for the Initial EL. */ + if (!ossl_quic_provide_initial_secret(ch->libctx, + ch->propq, + &ch->init_dcid, + ch->is_server, + ch->qrx, ch->qtx)) + return 0; + + /* Change state. */ + ch->state = QUIC_CHANNEL_STATE_ACTIVE; + ch->doing_proactive_ver_neg = 0; /* not currently supported */ + + /* Handshake layer: start (e.g. send CH). */ + if (!ch_tick_tls(ch, /*channel_only=*/0)) + return 0; + + ossl_quic_reactor_tick(&ch->rtor, 0); /* best effort */ + return 1; +} + +/* Start a locally initiated connection shutdown. */ +void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code, + const char *app_reason) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + + if (ossl_quic_channel_is_term_any(ch)) + return; + + tcause.app = 1; + tcause.error_code = app_error_code; + tcause.reason = app_reason; + tcause.reason_len = app_reason != NULL ? strlen(app_reason) : 0; + ch_start_terminating(ch, &tcause, 0); +} + +static void free_token(const unsigned char *buf, size_t buf_len, void *arg) +{ + OPENSSL_free((unsigned char *)buf); +} + +/* Called when a server asks us to do a retry. */ +static int ch_retry(QUIC_CHANNEL *ch, + const unsigned char *retry_token, + size_t retry_token_len, + const QUIC_CONN_ID *retry_scid) +{ + void *buf; + + /* + * RFC 9000 s. 17.2.5.1: "A client MUST discard a Retry packet that contains + * a SCID field that is identical to the DCID field of its initial packet." + */ + if (ossl_quic_conn_id_eq(&ch->init_dcid, retry_scid)) + return 1; + + /* We change to using the SCID in the Retry packet as the DCID. */ + if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, retry_scid)) + return 0; + + /* + * Now we retry. We will release the Retry packet immediately, so copy + * the token. + */ + if ((buf = OPENSSL_memdup(retry_token, retry_token_len)) == NULL) + return 0; + + if (!ossl_quic_tx_packetiser_set_initial_token(ch->txp, buf, + retry_token_len, + free_token, NULL)) { + /* + * This may fail if the token we receive is too big for us to ever be + * able to transmit in an outgoing Initial packet. + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INVALID_TOKEN, 0, + "received oversize token"); + OPENSSL_free(buf); + return 0; + } + + ch->retry_scid = *retry_scid; + ch->doing_retry = 1; + + /* + * We need to stimulate the Initial EL to generate the first CRYPTO frame + * again. We can do this most cleanly by simply forcing the ACKM to consider + * the first Initial packet as lost, which it effectively was as the server + * hasn't processed it. This also maintains the desired behaviour with e.g. + * PNs not resetting and so on. + * + * The PN we used initially is always zero, because QUIC does not allow + * repeated retries. + */ + if (!ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL, + /*PN=*/0)) + return 0; + + /* + * Plug in new secrets for the Initial EL. This is the only time we change + * the secrets for an EL after we already provisioned it. + */ + if (!ossl_quic_provide_initial_secret(ch->libctx, + ch->propq, + &ch->retry_scid, + /*is_server=*/0, + ch->qrx, ch->qtx)) + return 0; + + return 1; +} + +/* Called when an EL is to be discarded. */ +static int ch_discard_el(QUIC_CHANNEL *ch, + uint32_t enc_level) +{ + if (!ossl_assert(enc_level < QUIC_ENC_LEVEL_1RTT)) + return 0; + + if ((ch->el_discarded & (1U << enc_level)) != 0) + /* Already done. */ + return 1; + + /* Best effort for all of these. */ + ossl_quic_tx_packetiser_discard_enc_level(ch->txp, enc_level); + ossl_qrx_discard_enc_level(ch->qrx, enc_level); + ossl_qtx_discard_enc_level(ch->qtx, enc_level); + + if (enc_level != QUIC_ENC_LEVEL_0RTT) { + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + + ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space); + + /* We should still have crypto streams at this point. */ + if (!ossl_assert(ch->crypto_send[pn_space] != NULL) + || !ossl_assert(ch->crypto_recv[pn_space] != NULL)) + return 0; + + /* Get rid of the crypto stream state for the EL. */ + ossl_quic_sstream_free(ch->crypto_send[pn_space]); + ch->crypto_send[pn_space] = NULL; + + ossl_quic_rstream_free(ch->crypto_recv[pn_space]); + ch->crypto_recv[pn_space] = NULL; + } + + ch->el_discarded |= (1U << enc_level); + return 1; +} + +/* Intended to be called by the RXDP. */ +int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch) +{ + if (ch->handshake_confirmed) + return 1; + + if (!ch->handshake_complete) { + /* + * Does not make sense for handshake to be confirmed before it is + * completed. + */ + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE, + "handshake cannot be confirmed " + "before it is completed"); + return 0; + } + + ch_discard_el(ch, QUIC_ENC_LEVEL_HANDSHAKE); + ch->handshake_confirmed = 1; + ossl_ackm_on_handshake_confirmed(ch->ackm); + return 1; +} + +/* + * Master function used when we want to start tearing down a connection: + * + * - If the connection is still IDLE we can go straight to TERMINATED; + * + * - If we are already TERMINATED this is a no-op. + * + * - If we are TERMINATING - CLOSING and we have now got a CONNECTION_CLOSE + * from the peer (tcause->remote == 1), we move to TERMINATING - DRAINING. + * + * - If we are TERMINATING - DRAINING, we remain here until the terminating + * timer expires. + * + * - Otherwise, we are in ACTIVE and move to TERMINATING - CLOSING. + * if we caused the termination (e.g. we have sent a CONNECTION_CLOSE). Note + * that we are considered to have caused a termination if we sent the first + * CONNECTION_CLOSE frame, even if it is caused by a peer protocol + * violation. If the peer sent the first CONNECTION_CLOSE frame, we move to + * TERMINATING - DRAINING. + * + * We record the termination cause structure passed on the first call only. + * Any successive calls have their termination cause data discarded; + * once we start sending a CONNECTION_CLOSE frame, we don't change the details + * in it. + * + * This conforms to RFC 9000 s. 10.2.1: Closing Connection State: + * To minimize the state that an endpoint maintains for a closing + * connection, endpoints MAY send the exact same packet in response + * to any received packet. + * + * We don't drop any connection state (specifically packet protection keys) + * even though we are permitted to. This conforms to RFC 9000 s. 10.2.1: + * Closing Connection State: + * An endpoint MAY retain packet protection keys for incoming + * packets to allow it to read and process a CONNECTION_CLOSE frame. + * + * Note that we do not conform to these two from the same section: + * An endpoint's selected connection ID and the QUIC version + * are sufficient information to identify packets for a closing + * connection; the endpoint MAY discard all other connection state. + * and: + * An endpoint MAY drop packet protection keys when entering the + * closing state and send a packet containing a CONNECTION_CLOSE + * frame in response to any UDP datagram that is received. + */ +static void copy_tcause(QUIC_TERMINATE_CAUSE *dst, + const QUIC_TERMINATE_CAUSE *src) +{ + dst->error_code = src->error_code; + dst->frame_type = src->frame_type; + dst->app = src->app; + dst->remote = src->remote; + + dst->reason = NULL; + dst->reason_len = 0; + + if (src->reason != NULL && src->reason_len > 0) { + size_t l = src->reason_len; + char *r; + + if (l >= SIZE_MAX) + --l; + + /* + * If this fails, dst->reason becomes NULL and we simply do not use a + * reason. This ensures termination is infallible. + */ + dst->reason = r = OPENSSL_memdup(src->reason, l + 1); + if (r == NULL) + return; + + r[l] = '\0'; + dst->reason_len = l; + } +} + +static void ch_start_terminating(QUIC_CHANNEL *ch, + const QUIC_TERMINATE_CAUSE *tcause, + int force_immediate) +{ + /* No point sending anything if we haven't sent anything yet. */ + if (!ch->have_sent_any_pkt) + force_immediate = 1; + + switch (ch->state) { + default: + case QUIC_CHANNEL_STATE_IDLE: + copy_tcause(&ch->terminate_cause, tcause); + ch_on_terminating_timeout(ch); + break; + + case QUIC_CHANNEL_STATE_ACTIVE: + copy_tcause(&ch->terminate_cause, tcause); + + if (!force_immediate) { + ch->state = tcause->remote ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING + : QUIC_CHANNEL_STATE_TERMINATING_CLOSING; + /* + * RFC 9000 s. 10.2 Immediate Close + * These states SHOULD persist for at least three times + * the current PTO interval as defined in [QUIC-RECOVERY]. + */ + ch->terminate_deadline + = ossl_time_add(get_time(ch), + ossl_time_multiply(ossl_ackm_get_pto_duration(ch->ackm), + 3)); + + if (!tcause->remote) { + OSSL_QUIC_FRAME_CONN_CLOSE f = {0}; + + /* best effort */ + f.error_code = ch->terminate_cause.error_code; + f.frame_type = ch->terminate_cause.frame_type; + f.is_app = ch->terminate_cause.app; + f.reason = (char *)ch->terminate_cause.reason; + f.reason_len = ch->terminate_cause.reason_len; + ossl_quic_tx_packetiser_schedule_conn_close(ch->txp, &f); + /* + * RFC 9000 s. 10.2.2 Draining Connection State: + * An endpoint that receives a CONNECTION_CLOSE frame MAY + * send a single packet containing a CONNECTION_CLOSE + * frame before entering the draining state, using a + * NO_ERROR code if appropriate + */ + ch->conn_close_queued = 1; + } + } else { + ch_on_terminating_timeout(ch); + } + break; + + case QUIC_CHANNEL_STATE_TERMINATING_CLOSING: + if (force_immediate) + ch_on_terminating_timeout(ch); + else if (tcause->remote) + /* + * RFC 9000 s. 10.2.2 Draining Connection State: + * An endpoint MAY enter the draining state from the + * closing state if it receives a CONNECTION_CLOSE frame, + * which indicates that the peer is also closing or draining. + */ + ch->state = QUIC_CHANNEL_STATE_TERMINATING_DRAINING; + + break; + + case QUIC_CHANNEL_STATE_TERMINATING_DRAINING: + /* + * Other than in the force-immediate case, we remain here until the + * timeout expires. + */ + if (force_immediate) + ch_on_terminating_timeout(ch); + + break; + + case QUIC_CHANNEL_STATE_TERMINATED: + /* No-op. */ + break; + } +} + +/* For RXDP use. */ +void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch, + OSSL_QUIC_FRAME_CONN_CLOSE *f) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + + if (!ossl_quic_channel_is_active(ch)) + return; + + tcause.remote = 1; + tcause.app = f->is_app; + tcause.error_code = f->error_code; + tcause.frame_type = f->frame_type; + tcause.reason = f->reason; + tcause.reason_len = f->reason_len; + ch_start_terminating(ch, &tcause, 0); +} + +static void free_frame_data(unsigned char *buf, size_t buf_len, void *arg) +{ + OPENSSL_free(buf); +} + +static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num) +{ + BUF_MEM *buf_mem = NULL; + WPACKET wpkt; + size_t l; + + chan_remove_reset_token(ch, seq_num); + + if ((buf_mem = BUF_MEM_new()) == NULL) + goto err; + + if (!WPACKET_init(&wpkt, buf_mem)) + goto err; + + if (!ossl_quic_wire_encode_frame_retire_conn_id(&wpkt, seq_num)) { + WPACKET_cleanup(&wpkt); + goto err; + } + + WPACKET_finish(&wpkt); + if (!WPACKET_get_total_written(&wpkt, &l)) + goto err; + + if (ossl_quic_cfq_add_frame(ch->cfq, 1, QUIC_PN_SPACE_APP, + OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, 0, + (unsigned char *)buf_mem->data, l, + free_frame_data, NULL) == NULL) + goto err; + + buf_mem->data = NULL; + BUF_MEM_free(buf_mem); + return 1; + +err: + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "internal error enqueueing retire conn id"); + BUF_MEM_free(buf_mem); + return 0; +} + +void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch, + OSSL_QUIC_FRAME_NEW_CONN_ID *f) +{ + uint64_t new_remote_seq_num = ch->cur_remote_seq_num; + uint64_t new_retire_prior_to = ch->cur_retire_prior_to; + + if (!ossl_quic_channel_is_active(ch)) + return; + + /* We allow only two active connection ids; first check some constraints */ + if (ch->cur_remote_dcid.id_len == 0) { + /* Changing from 0 length connection id is disallowed */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "zero length connection id in use"); + + return; + } + + if (f->seq_num > new_remote_seq_num) + new_remote_seq_num = f->seq_num; + if (f->retire_prior_to > new_retire_prior_to) + new_retire_prior_to = f->retire_prior_to; + + /* + * RFC 9000-5.1.1: An endpoint MUST NOT provide more connection IDs + * than the peer's limit. + * + * After processing a NEW_CONNECTION_ID frame and adding and retiring + * active connection IDs, if the number of active connection IDs exceeds + * the value advertised in its active_connection_id_limit transport + * parameter, an endpoint MUST close the connection with an error of + * type CONNECTION_ID_LIMIT_ERROR. + */ + if (new_remote_seq_num - new_retire_prior_to > 1) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "active_connection_id limit violated"); + return; + } + + /* + * RFC 9000-5.1.1: An endpoint MAY send connection IDs that temporarily + * exceed a peer's limit if the NEW_CONNECTION_ID frame also requires + * the retirement of any excess, by including a sufficiently large + * value in the Retire Prior To field. + * + * RFC 9000-5.1.2: An endpoint SHOULD allow for sending and tracking + * a number of RETIRE_CONNECTION_ID frames of at least twice the value + * of the active_connection_id_limit transport parameter. An endpoint + * MUST NOT forget a connection ID without retiring it, though it MAY + * choose to treat having connection IDs in need of retirement that + * exceed this limit as a connection error of type CONNECTION_ID_LIMIT_ERROR. + * + * We are a little bit more liberal than the minimum mandated. + */ + if (new_retire_prior_to - ch->cur_retire_prior_to > 10) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "retiring connection id limit violated"); + + return; + } + + if (new_remote_seq_num > ch->cur_remote_seq_num) { + /* Add new stateless reset token */ + if (!chan_add_reset_token(ch, f->stateless_reset.token, + new_remote_seq_num)) { + ossl_quic_channel_raise_protocol_error( + ch, QUIC_ERR_CONNECTION_ID_LIMIT_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "unable to store stateless reset token"); + + return; + } + ch->cur_remote_seq_num = new_remote_seq_num; + ch->cur_remote_dcid = f->conn_id; + ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid); + } + + /* + * RFC 9000-5.1.2: Upon receipt of an increased Retire Prior To + * field, the peer MUST stop using the corresponding connection IDs + * and retire them with RETIRE_CONNECTION_ID frames before adding the + * newly provided connection ID to the set of active connection IDs. + */ + + /* + * Note: RFC 9000 s. 19.15 says: + * "An endpoint that receives a NEW_CONNECTION_ID frame with a sequence + * number smaller than the Retire Prior To field of a previously received + * NEW_CONNECTION_ID frame MUST send a corresponding + * RETIRE_CONNECTION_ID frame that retires the newly received connection + * ID, unless it has already done so for that sequence number." + * + * Since we currently always queue RETIRE_CONN_ID frames based on the Retire + * Prior To field of a NEW_CONNECTION_ID frame immediately upon receiving + * that NEW_CONNECTION_ID frame, by definition this will always be met. + * This may change in future when we change our CID handling. + */ + while (new_retire_prior_to > ch->cur_retire_prior_to) { + if (!ch_enqueue_retire_conn_id(ch, ch->cur_retire_prior_to)) + break; + ++ch->cur_retire_prior_to; + } +} + +static void ch_save_err_state(QUIC_CHANNEL *ch) +{ + if (ch->err_state == NULL) + ch->err_state = OSSL_ERR_STATE_new(); + + if (ch->err_state == NULL) + return; + + OSSL_ERR_STATE_save(ch->err_state); +} + +static void ch_stateless_reset(QUIC_CHANNEL *ch) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + + tcause.error_code = QUIC_ERR_NO_ERROR; + ch_start_terminating(ch, &tcause, 1); +} + +static void ch_raise_net_error(QUIC_CHANNEL *ch) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + + ch->net_error = 1; + + ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR, + "connection terminated due to network error"); + ch_save_err_state(ch); + + tcause.error_code = QUIC_ERR_INTERNAL_ERROR; + + /* + * Skip Terminating state and go directly to Terminated, no point trying to + * send CONNECTION_CLOSE if we cannot communicate. + */ + ch_start_terminating(ch, &tcause, 1); +} + +int ossl_quic_channel_net_error(QUIC_CHANNEL *ch) +{ + return ch->net_error; +} + +void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch) +{ + if (ch == NULL) + return; + + OSSL_ERR_STATE_restore(ch->err_state); +} + +void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch, + uint64_t error_code, + uint64_t frame_type, + const char *reason, + ERR_STATE *err_state, + const char *src_file, + int src_line, + const char *src_func) +{ + QUIC_TERMINATE_CAUSE tcause = {0}; + int err_reason = error_code == QUIC_ERR_INTERNAL_ERROR + ? ERR_R_INTERNAL_ERROR : SSL_R_QUIC_PROTOCOL_ERROR; + const char *err_str = ossl_quic_err_to_string(error_code); + const char *err_str_pfx = " (", *err_str_sfx = ")"; + const char *ft_str = NULL; + const char *ft_str_pfx = " (", *ft_str_sfx = ")"; + + if (ch->protocol_error) + /* Only the first call to this function matters. */ + return; + + if (err_str == NULL) { + err_str = ""; + err_str_pfx = ""; + err_str_sfx = ""; + } + + /* + * If we were provided an underlying error state, restore it and then append + * our ERR on top as a "cover letter" error. + */ + if (err_state != NULL) + OSSL_ERR_STATE_restore(err_state); + + if (frame_type != 0) { + ft_str = ossl_quic_frame_type_to_string(frame_type); + if (ft_str == NULL) { + ft_str = ""; + ft_str_pfx = ""; + ft_str_sfx = ""; + } + + ERR_raise_data(ERR_LIB_SSL, err_reason, + "QUIC error code: 0x%llx%s%s%s " + "(triggered by frame type: 0x%llx%s%s%s), reason: \"%s\"", + (unsigned long long) error_code, + err_str_pfx, err_str, err_str_sfx, + (unsigned long long) frame_type, + ft_str_pfx, ft_str, ft_str_sfx, + reason); + } else { + ERR_raise_data(ERR_LIB_SSL, err_reason, + "QUIC error code: 0x%llx%s%s%s, reason: \"%s\"", + (unsigned long long) error_code, + err_str_pfx, err_str, err_str_sfx, + reason); + } + + if (src_file != NULL) + ERR_set_debug(src_file, src_line, src_func); + + ch_save_err_state(ch); + + tcause.error_code = error_code; + tcause.frame_type = frame_type; + tcause.reason = reason; + tcause.reason_len = strlen(reason); + + ch->protocol_error = 1; + ch_start_terminating(ch, &tcause, 0); +} + +/* + * Called once the terminating timer expires, meaning we move from TERMINATING + * to TERMINATED. + */ +static void ch_on_terminating_timeout(QUIC_CHANNEL *ch) +{ + ch->state = QUIC_CHANNEL_STATE_TERMINATED; +} + +/* + * Determines the effective idle timeout duration. This is based on the idle + * timeout values that we and our peer signalled in transport parameters + * but have some limits applied. + */ +static OSSL_TIME ch_get_effective_idle_timeout_duration(QUIC_CHANNEL *ch) +{ + OSSL_TIME pto; + + if (ch->max_idle_timeout == 0) + return ossl_time_infinite(); + + /* + * RFC 9000 s. 10.1: Idle Timeout + * To avoid excessively small idle timeout periods, endpoints + * MUST increase the idle timeout period to be at least three + * times the current Probe Timeout (PTO). This allows for + * multiple PTOs to expire, and therefore multiple probes to + * be sent and lost, prior to idle timeout. + */ + pto = ossl_ackm_get_pto_duration(ch->ackm); + return ossl_time_max(ossl_ms2time(ch->max_idle_timeout), + ossl_time_multiply(pto, 3)); +} + +/* + * Updates our idle deadline. Called when an event happens which should bump the + * idle timeout. + */ +static void ch_update_idle(QUIC_CHANNEL *ch) +{ + ch->idle_deadline = ossl_time_add(get_time(ch), + ch_get_effective_idle_timeout_duration(ch)); +} + +/* + * Updates our ping deadline, which determines when we next generate a ping if + * we don't have any other ACK-eliciting frames to send. + */ +static void ch_update_ping_deadline(QUIC_CHANNEL *ch) +{ + OSSL_TIME max_span, idle_duration; + + idle_duration = ch_get_effective_idle_timeout_duration(ch); + if (ossl_time_is_infinite(idle_duration)) { + ch->ping_deadline = ossl_time_infinite(); + return; + } + + /* + * Maximum amount of time without traffic before we send a PING to keep + * the connection open. Usually we use max_idle_timeout/2, but ensure + * the period never exceeds the assumed NAT interval to ensure NAT + * devices don't have their state time out (RFC 9000 s. 10.1.2). + */ + max_span = ossl_time_divide(idle_duration, 2); + max_span = ossl_time_min(max_span, MAX_NAT_INTERVAL); + ch->ping_deadline = ossl_time_add(get_time(ch), max_span); +} + +/* Called when the idle timeout expires. */ +static void ch_on_idle_timeout(QUIC_CHANNEL *ch) +{ + /* + * Idle timeout does not have an error code associated with it because a + * CONN_CLOSE is never sent for it. We shouldn't use this data once we reach + * TERMINATED anyway. + */ + ch->terminate_cause.app = 0; + ch->terminate_cause.error_code = UINT64_MAX; + ch->terminate_cause.frame_type = 0; + + ch->state = QUIC_CHANNEL_STATE_TERMINATED; +} + +/* Called when we, as a server, get a new incoming connection. */ +static int ch_server_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer, + const QUIC_CONN_ID *peer_scid, + const QUIC_CONN_ID *peer_dcid) +{ + if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server)) + return 0; + + /* Generate a SCID we will use for the connection. */ + if (!gen_rand_conn_id(ch->libctx, INIT_DCID_LEN, + &ch->cur_local_cid)) + return 0; + + /* Note our newly learnt peer address and CIDs. */ + ch->cur_peer_addr = *peer; + ch->init_dcid = *peer_dcid; + ch->cur_remote_dcid = *peer_scid; + + /* Inform QTX of peer address. */ + if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr)) + return 0; + + /* Inform TXP of desired CIDs. */ + if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid)) + return 0; + + if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid)) + return 0; + + /* Plug in secrets for the Initial EL. */ + if (!ossl_quic_provide_initial_secret(ch->libctx, + ch->propq, + &ch->init_dcid, + /*is_server=*/1, + ch->qrx, ch->qtx)) + return 0; + + /* Register our local CID in the DEMUX. */ + if (!ossl_qrx_add_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + return 0; + + /* Change state. */ + ch->state = QUIC_CHANNEL_STATE_ACTIVE; + ch->doing_proactive_ver_neg = 0; /* not currently supported */ + return 1; +} + +SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch) +{ + return ch->tls; +} + +static int ch_init_new_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs, + int can_send, int can_recv) +{ + uint64_t rxfc_wnd; + int server_init = ossl_quic_stream_is_server_init(qs); + int local_init = (ch->is_server == server_init); + int is_uni = !ossl_quic_stream_is_bidi(qs); + + if (can_send) + if ((qs->sstream = ossl_quic_sstream_new(INIT_APP_BUF_LEN)) == NULL) + goto err; + + if (can_recv) + if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, 0)) == NULL) + goto err; + + /* TXFC */ + if (!ossl_quic_txfc_init(&qs->txfc, &ch->conn_txfc)) + goto err; + + if (ch->got_remote_transport_params) { + /* + * If we already got peer TPs we need to apply the initial CWM credit + * now. If we didn't already get peer TPs this will be done + * automatically for all extant streams when we do. + */ + if (can_send) { + uint64_t cwm; + + if (is_uni) + cwm = ch->rx_init_max_stream_data_uni; + else if (local_init) + cwm = ch->rx_init_max_stream_data_bidi_local; + else + cwm = ch->rx_init_max_stream_data_bidi_remote; + + ossl_quic_txfc_bump_cwm(&qs->txfc, cwm); + } + } + + /* RXFC */ + if (!can_recv) + rxfc_wnd = 0; + else if (is_uni) + rxfc_wnd = ch->tx_init_max_stream_data_uni; + else if (local_init) + rxfc_wnd = ch->tx_init_max_stream_data_bidi_local; + else + rxfc_wnd = ch->tx_init_max_stream_data_bidi_remote; + + if (!ossl_quic_rxfc_init(&qs->rxfc, &ch->conn_rxfc, + rxfc_wnd, + DEFAULT_STREAM_RXFC_MAX_WND_MUL * rxfc_wnd, + get_time, ch)) + goto err; + + return 1; + +err: + ossl_quic_sstream_free(qs->sstream); + qs->sstream = NULL; + ossl_quic_rstream_free(qs->rstream); + qs->rstream = NULL; + return 0; +} + +static uint64_t *ch_get_local_stream_next_ordinal_ptr(QUIC_CHANNEL *ch, + int is_uni) +{ + return is_uni ? &ch->next_local_stream_ordinal_uni + : &ch->next_local_stream_ordinal_bidi; +} + +int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch, + int is_uni) +{ + uint64_t *p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni); + + return ossl_quic_stream_map_is_local_allowed_by_stream_limit(&ch->qsm, + *p_next_ordinal, + is_uni); +} + +QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni) +{ + QUIC_STREAM *qs; + int type; + uint64_t stream_id, *p_next_ordinal; + + type = ch->is_server ? QUIC_STREAM_INITIATOR_SERVER + : QUIC_STREAM_INITIATOR_CLIENT; + + p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni); + + if (is_uni) + type |= QUIC_STREAM_DIR_UNI; + else + type |= QUIC_STREAM_DIR_BIDI; + + if (*p_next_ordinal >= ((uint64_t)1) << 62) + return NULL; + + stream_id = ((*p_next_ordinal) << 2) | type; + + if ((qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id, type)) == NULL) + return NULL; + + /* Locally-initiated stream, so we always want a send buffer. */ + if (!ch_init_new_stream(ch, qs, /*can_send=*/1, /*can_recv=*/!is_uni)) + goto err; + + ++*p_next_ordinal; + return qs; + +err: + ossl_quic_stream_map_release(&ch->qsm, qs); + return NULL; +} + +QUIC_STREAM *ossl_quic_channel_new_stream_remote(QUIC_CHANNEL *ch, + uint64_t stream_id) +{ + uint64_t peer_role; + int is_uni; + QUIC_STREAM *qs; + + peer_role = ch->is_server + ? QUIC_STREAM_INITIATOR_CLIENT + : QUIC_STREAM_INITIATOR_SERVER; + + if ((stream_id & QUIC_STREAM_INITIATOR_MASK) != peer_role) + return NULL; + + is_uni = ((stream_id & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_UNI); + + qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id, + stream_id & (QUIC_STREAM_INITIATOR_MASK + | QUIC_STREAM_DIR_MASK)); + if (qs == NULL) + return NULL; + + if (!ch_init_new_stream(ch, qs, /*can_send=*/!is_uni, /*can_recv=*/1)) + goto err; + + if (ch->incoming_stream_auto_reject) + ossl_quic_channel_reject_stream(ch, qs); + else + ossl_quic_stream_map_push_accept_queue(&ch->qsm, qs); + + return qs; + +err: + ossl_quic_stream_map_release(&ch->qsm, qs); + return NULL; +} + +void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch, + int enable, + uint64_t aec) +{ + ch->incoming_stream_auto_reject = (enable != 0); + ch->incoming_stream_auto_reject_aec = aec; +} + +void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs) +{ + ossl_quic_stream_map_stop_sending_recv_part(&ch->qsm, qs, + ch->incoming_stream_auto_reject_aec); + + ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, qs, + ch->incoming_stream_auto_reject_aec); + qs->deleted = 1; + + ossl_quic_stream_map_update_state(&ch->qsm, qs); +} + +/* Replace local connection ID in TXP and DEMUX for testing purposes. */ +int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch, + const QUIC_CONN_ID *conn_id) +{ + /* Remove the current local CID from the DEMUX. */ + if (!ossl_qrx_remove_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + return 0; + ch->cur_local_cid = *conn_id; + /* Set in the TXP, used only for long header packets. */ + if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid)) + return 0; + /* Register our new local CID in the DEMUX. */ + if (!ossl_qrx_add_dst_conn_id(ch->qrx, &ch->cur_local_cid)) + return 0; + return 1; +} + +void ossl_quic_channel_set_msg_callback(QUIC_CHANNEL *ch, + ossl_msg_cb msg_callback, + SSL *msg_callback_ssl) +{ + ch->msg_callback = msg_callback; + ch->msg_callback_ssl = msg_callback_ssl; + ossl_qtx_set_msg_callback(ch->qtx, msg_callback, msg_callback_ssl); + ossl_quic_tx_packetiser_set_msg_callback(ch->txp, msg_callback, + msg_callback_ssl); + ossl_qrx_set_msg_callback(ch->qrx, msg_callback, msg_callback_ssl); +} + +void ossl_quic_channel_set_msg_callback_arg(QUIC_CHANNEL *ch, + void *msg_callback_arg) +{ + ch->msg_callback_arg = msg_callback_arg; + ossl_qtx_set_msg_callback_arg(ch->qtx, msg_callback_arg); + ossl_quic_tx_packetiser_set_msg_callback_arg(ch->txp, msg_callback_arg); + ossl_qrx_set_msg_callback_arg(ch->qrx, msg_callback_arg); +} + +void ossl_quic_channel_set_txku_threshold_override(QUIC_CHANNEL *ch, + uint64_t tx_pkt_threshold) +{ + ch->txku_threshold_override = tx_pkt_threshold; +} + +uint64_t ossl_quic_channel_get_tx_key_epoch(QUIC_CHANNEL *ch) +{ + return ossl_qtx_get_key_epoch(ch->qtx); +} + +uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch) +{ + return ossl_qrx_get_key_epoch(ch->qrx); +} + +int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch) +{ + if (!txku_allowed(ch)) + return 0; + + ch->ku_locally_initiated = 1; + ch_trigger_txku(ch); + return 1; +} + +int ossl_quic_channel_ping(QUIC_CHANNEL *ch) +{ + int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level); + + ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space); + + return 1; +} + +void ossl_quic_channel_set_inhibit_tick(QUIC_CHANNEL *ch, int inhibit) +{ + ch->inhibit_tick = (inhibit != 0); +} + +uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch) +{ + return ch->diag_num_rx_ack; +} + +void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid) +{ + *cid = ch->cur_local_cid; +} diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h new file mode 100644 index 0000000000..f0ac742420 --- /dev/null +++ b/ssl/quic/quic_channel_local.h @@ -0,0 +1,477 @@ +#ifndef OSSL_QUIC_CHANNEL_LOCAL_H +# define OSSL_QUIC_CHANNEL_LOCAL_H + +# include "internal/quic_channel.h" + +# ifndef OPENSSL_NO_QUIC + +# include +# include "internal/list.h" + + +typedef struct quic_srt_elem_st QUIC_SRT_ELEM; + +struct quic_srt_elem_st { + OSSL_LIST_MEMBER(stateless_reset_tokens, QUIC_SRT_ELEM); + QUIC_STATELESS_RESET_TOKEN token; + uint64_t seq_num; +}; + +DEFINE_LIST_OF(stateless_reset_tokens, QUIC_SRT_ELEM); + +/* + * QUIC Channel Structure + * ====================== + * + * QUIC channel internals. It is intended that only the QUIC_CHANNEL + * implementation and the RX depacketiser be allowed to access this structure + * directly. As the RX depacketiser has no state of its own and computes over a + * QUIC_CHANNEL structure, it can be viewed as an extension of the QUIC_CHANNEL + * implementation. While the RX depacketiser could be provided with adequate + * accessors to do what it needs, this would weaken the abstraction provided by + * the QUIC_CHANNEL to other components; moreover the coupling of the RX + * depacketiser to QUIC_CHANNEL internals is too deep and bespoke to make this + * desirable. + * + * Other components should not include this header. + */ +struct quic_channel_st { + OSSL_LIB_CTX *libctx; + const char *propq; + + /* + * Master synchronisation mutex used for thread assisted mode + * synchronisation. We don't own this; the instantiator of the channel + * passes it to us and is responsible for freeing it after channel + * destruction. + */ + CRYPTO_MUTEX *mutex; + + /* + * Callback used to get the current time. + */ + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; + + /* + * The associated TLS 1.3 connection data. Used to provide the handshake + * layer; its 'network' side is plugged into the crypto stream for each EL + * (other than the 0-RTT EL). + */ + QUIC_TLS *qtls; + SSL *tls; + + /* + * The transport parameter block we will send or have sent. + * Freed after sending or when connection is freed. + */ + unsigned char *local_transport_params; + + /* Asynchronous I/O reactor. */ + QUIC_REACTOR rtor; + + /* Our current L4 peer address, if any. */ + BIO_ADDR cur_peer_addr; + + /* Network-side read and write BIOs. */ + BIO *net_rbio, *net_wbio; + + /* + * Subcomponents of the connection. All of these components are instantiated + * and owned by us. + */ + OSSL_QUIC_TX_PACKETISER *txp; + QUIC_TXPIM *txpim; + QUIC_CFQ *cfq; + /* + * Connection level FC. The stream_count RXFCs is used to manage + * MAX_STREAMS signalling. + */ + QUIC_TXFC conn_txfc; + QUIC_RXFC conn_rxfc, crypto_rxfc[QUIC_PN_SPACE_NUM]; + QUIC_RXFC max_streams_bidi_rxfc, max_streams_uni_rxfc; + QUIC_STREAM_MAP qsm; + OSSL_STATM statm; + OSSL_CC_DATA *cc_data; + const OSSL_CC_METHOD *cc_method; + OSSL_ACKM *ackm; + + /* + * RX demuxer. We register incoming DCIDs with this. Since we currently only + * support client operation and use one L4 port per connection, we own the + * demuxer and register a single zero-length DCID with it. + */ + QUIC_DEMUX *demux; + + /* Record layers in the TX and RX directions, plus the RX demuxer. */ + OSSL_QTX *qtx; + OSSL_QRX *qrx; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_ssl; + + /* + * Send and receive parts of the crypto streams. + * crypto_send[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream. There is no + * 0-RTT crypto stream. + */ + QUIC_SSTREAM *crypto_send[QUIC_PN_SPACE_NUM]; + QUIC_RSTREAM *crypto_recv[QUIC_PN_SPACE_NUM]; + + /* Internal state. */ + /* + * Client: The DCID used in the first Initial packet we transmit as a client. + * Server: The DCID used in the first Initial packet the client transmitted. + * Randomly generated and required by RFC to be at least 8 bytes. + */ + QUIC_CONN_ID init_dcid; + + /* + * Client: The SCID found in the first Initial packet from the server. + * Not valid for servers. + * Valid if have_received_enc_pkt is set. + */ + QUIC_CONN_ID init_scid; + + /* + * Client only: The SCID found in an incoming Retry packet we handled. + * Not valid for servers. + */ + QUIC_CONN_ID retry_scid; + + /* + * The DCID we currently use to talk to the peer and its sequence num. + * + * TODO(QUIC FUTURE) consider removing the second two, both are contained in + * srt_list_seq (defined below). + * + * cur_remote_seq_num is same as the sequence number in the last element. + * cur_retire_prior_to corresponds to the sequence number in first element. + * + * Leaving them here avoids null checking etc + */ + QUIC_CONN_ID cur_remote_dcid; + uint64_t cur_remote_seq_num; + uint64_t cur_retire_prior_to; + + /* Server only: The DCID we currently expect the peer to use to talk to us. */ + QUIC_CONN_ID cur_local_cid; + + /* Hash of stateless reset tokens keyed on the token */ + LHASH_OF(QUIC_SRT_ELEM) *srt_hash_tok; + + /* List of the stateless reset tokens ordered by sequence number */ + OSSL_LIST(stateless_reset_tokens) srt_list_seq; + + /* Transport parameter values we send to our peer. */ + uint64_t tx_init_max_stream_data_bidi_local; + uint64_t tx_init_max_stream_data_bidi_remote; + uint64_t tx_init_max_stream_data_uni; + uint64_t tx_max_ack_delay; /* ms */ + + /* Transport parameter values received from server. */ + uint64_t rx_init_max_stream_data_bidi_local; + uint64_t rx_init_max_stream_data_bidi_remote; + uint64_t rx_init_max_stream_data_uni; + uint64_t rx_max_ack_delay; /* ms */ + unsigned char rx_ack_delay_exp; + + /* + * Temporary staging area to store information about the incoming packet we + * are currently processing. + */ + OSSL_QRX_PKT *qrx_pkt; + + /* + * Current limit on number of streams we may create. Set by transport + * parameters initially and then by MAX_STREAMS frames. + */ + uint64_t max_local_streams_bidi; + uint64_t max_local_streams_uni; + + /* The negotiated maximum idle timeout in milliseconds. */ + uint64_t max_idle_timeout; + + /* + * Maximum payload size in bytes for datagrams sent to our peer, as + * negotiated by transport parameters. + */ + uint64_t rx_max_udp_payload_size; + /* Maximum active CID limit, as negotiated by transport parameters. */ + uint64_t rx_active_conn_id_limit; + + /* + * Used to allocate stream IDs. This is a stream ordinal, i.e., a stream ID + * without the low two bits designating type and initiator. Shift and or in + * the type bits to convert to a stream ID. + */ + uint64_t next_local_stream_ordinal_bidi; + uint64_t next_local_stream_ordinal_uni; + + /* + * Used to track which stream ordinals within a given stream type have been + * used by the remote peer. This is an optimisation used to determine + * which streams should be implicitly created due to usage of a higher + * stream ordinal. + */ + uint64_t next_remote_stream_ordinal_bidi; + uint64_t next_remote_stream_ordinal_uni; + + /* + * Application error code to be used for STOP_SENDING/RESET_STREAM frames + * used to autoreject incoming streams. + */ + uint64_t incoming_stream_auto_reject_aec; + + /* + * Override packet count threshold at which we do a spontaneous TXKU. + * Usually UINT64_MAX in which case a suitable value is chosen based on AEAD + * limit advice from the QRL utility functions. This is intended for testing + * use only. Usually set to UINT64_MAX. + */ + uint64_t txku_threshold_override; + + /* Diagnostic counters for testing purposes only. May roll over. */ + uint16_t diag_num_rx_ack; /* Number of ACK frames received */ + + /* Valid if we are in the TERMINATING or TERMINATED states. */ + QUIC_TERMINATE_CAUSE terminate_cause; + + /* + * Deadline at which we move to TERMINATING state. Valid if in the + * TERMINATING state. + */ + OSSL_TIME terminate_deadline; + + /* + * Deadline at which connection dies due to idle timeout if no further + * events occur. + */ + OSSL_TIME idle_deadline; + + /* + * Deadline at which we should send an ACK-eliciting packet to ensure + * idle timeout does not occur. + */ + OSSL_TIME ping_deadline; + + /* + * The deadline at which the period in which it is RECOMMENDED that we not + * initiate any spontaneous TXKU ends. This is zero if no such deadline + * applies. + */ + OSSL_TIME txku_cooldown_deadline; + + /* + * The deadline at which we take the QRX out of UPDATING and back to NORMAL. + * Valid if rxku_in_progress in 1. + */ + OSSL_TIME rxku_update_end_deadline; + + /* + * The first (application space) PN sent with a new key phase. Valid if the + * QTX key epoch is greater than 0. Once a packet we sent with a PN p (p >= + * txku_pn) is ACKed, the TXKU is considered completed and txku_in_progress + * becomes 0. For sanity's sake, such a PN p should also be <= the highest + * PN we have ever sent, of course. + */ + QUIC_PN txku_pn; + + /* + * The (application space) PN which triggered RXKU detection. Valid if + * rxku_pending_confirm. + */ + QUIC_PN rxku_trigger_pn; + + /* + * State tracking. QUIC connection-level state is best represented based on + * whether various things have happened yet or not, rather than as an + * explicit FSM. We do have a coarse state variable which tracks the basic + * state of the connection's lifecycle, but more fine-grained conditions of + * the Active state are tracked via flags below. For more details, see + * doc/designs/quic-design/connection-state-machine.md. We are in the Open + * state if the state is QUIC_CHANNEL_STATE_ACTIVE and handshake_confirmed is + * set. + */ + unsigned int state : 3; + + /* + * Have we received at least one encrypted packet from the peer? + * (If so, Retry and Version Negotiation messages should no longer + * be received and should be ignored if they do occur.) + */ + unsigned int have_received_enc_pkt : 1; + + /* + * Have we successfully processed any packet, including a Version + * Negotiation packet? If so, further Version Negotiation packets should be + * ignored. + */ + unsigned int have_processed_any_pkt : 1; + + /* + * Have we sent literally any packet yet? If not, there is no point polling + * RX. + */ + unsigned int have_sent_any_pkt : 1; + + /* + * Are we currently doing proactive version negotiation? + */ + unsigned int doing_proactive_ver_neg : 1; + + /* We have received transport parameters from the peer. */ + unsigned int got_remote_transport_params : 1; + + /* + * This monotonically transitions to 1 once the TLS state machine is + * 'complete', meaning that it has both sent a Finished and successfully + * verified the peer's Finished (see RFC 9001 s. 4.1.1). Note that it + * does not transition to 1 at both peers simultaneously. + * + * Handshake completion is not the same as handshake confirmation (see + * below). + */ + unsigned int handshake_complete : 1; + + /* + * This monotonically transitions to 1 once the handshake is confirmed. + * This happens on the client when we receive a HANDSHAKE_DONE frame. + * At our option, we may also take acknowledgement of any 1-RTT packet + * we sent as a handshake confirmation. + */ + unsigned int handshake_confirmed : 1; + + /* + * We are sending Initial packets based on a Retry. This means we definitely + * should not receive another Retry, and if we do it is an error. + */ + unsigned int doing_retry : 1; + + /* + * We don't store the current EL here; the TXP asks the QTX which ELs + * are provisioned to determine which ELs to use. + */ + + /* Have statm, qsm been initialised? Used to track cleanup. */ + unsigned int have_statm : 1; + unsigned int have_qsm : 1; + + /* + * Preferred ELs for transmission and reception. This is not strictly needed + * as it can be inferred from what keys we have provisioned, but makes + * determining the current EL simpler and faster. A separate EL for + * transmission and reception is not strictly necessary but makes things + * easier for interoperation with the handshake layer, which likes to invoke + * the yield secret callback at different times for TX and RX. + */ + unsigned int tx_enc_level : 3; + unsigned int rx_enc_level : 3; + + /* If bit n is set, EL n has been discarded. */ + unsigned int el_discarded : 4; + + /* + * While in TERMINATING - CLOSING, set when we should generate a connection + * close frame. + */ + unsigned int conn_close_queued : 1; + + /* Are we in server mode? Never changes after instantiation. */ + unsigned int is_server : 1; + + /* + * Set temporarily when the handshake layer has given us a new RX secret. + * Used to determine if we need to check our RX queues again. + */ + unsigned int have_new_rx_secret : 1; + + /* Have we ever called QUIC_TLS yet during RX processing? */ + unsigned int did_tls_tick : 1; + /* Has any CRYPTO frame been processed during this tick? */ + unsigned int did_crypto_frame : 1; + + /* + * Have we sent an ack-eliciting packet since the last successful packet + * reception? Used to determine when to bump idle timer (see RFC 9000 s. + * 10.1). + */ + unsigned int have_sent_ack_eliciting_since_rx : 1; + + /* Should incoming streams automatically be rejected? */ + unsigned int incoming_stream_auto_reject : 1; + + /* + * 1 if a key update sequence was locally initiated, meaning we sent the + * TXKU first and the resultant RXKU shouldn't result in our triggering + * another TXKU. 0 if a key update sequence was initiated by the peer, + * meaning we detect a RXKU first and have to generate a TXKU in response. + */ + unsigned int ku_locally_initiated : 1; + + /* + * 1 if we have triggered TXKU (whether spontaneous or solicited) but are + * waiting for any PN using that new KP to be ACKed. While this is set, we + * are not allowed to trigger spontaneous TXKU (but solicited TXKU is + * potentially still possible). + */ + unsigned int txku_in_progress : 1; + + /* + * We have received an RXKU event and currently are going through + * UPDATING/COOLDOWN on the QRX. COOLDOWN is currently not used. Since RXKU + * cannot be detected in this state, this doesn't cause a protocol error or + * anything similar if a peer tries TXKU in this state. That traffic would + * simply be dropped. It's only used to track that our UPDATING timer is + * active so we know when to take the QRX out of UPDATING and back to + * NORMAL. + */ + unsigned int rxku_in_progress : 1; + + /* + * We have received an RXKU but have yet to send an ACK for it, which means + * no further RXKUs are allowed yet. Note that we cannot detect further + * RXKUs anyway while the QRX remains in the UPDATING/COOLDOWN states, so + * this restriction comes into play if we take more than PTO time to send + * an ACK for it (not likely). + */ + unsigned int rxku_pending_confirm : 1; + + /* Temporary variable indicating rxku_pending_confirm is to become 0. */ + unsigned int rxku_pending_confirm_done : 1; + + /* + * If set, RXKU is expected (because we initiated a spontaneous TXKU). + */ + unsigned int rxku_expected : 1; + + /* Permanent net error encountered */ + unsigned int net_error : 1; + + /* + * Protocol error encountered. Note that you should refer to the state field + * rather than this. This is only used so we can ignore protocol errors + * after the first protocol error, but still record the first protocol error + * if it happens during the TERMINATING state. + */ + unsigned int protocol_error : 1; + + /* Inhibit tick for testing purposes? */ + unsigned int inhibit_tick : 1; + + /* Are we using addressed mode? */ + unsigned int addressed_mode : 1; + + /* Saved error stack in case permanent error was encountered */ + ERR_STATE *err_state; + + /* Scratch area for use by RXDP to store decoded ACK ranges. */ + OSSL_QUIC_ACK_RANGE *ack_range_scratch; + size_t num_ack_range_scratch; +}; + +# endif + +#endif diff --git a/ssl/quic/quic_demux.c b/ssl/quic/quic_demux.c new file mode 100644 index 0000000000..88135fe5b9 --- /dev/null +++ b/ssl/quic/quic_demux.c @@ -0,0 +1,677 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_demux.h" +#include "internal/quic_wire_pkt.h" +#include "internal/common.h" +#include +#include + +#define URXE_DEMUX_STATE_FREE 0 /* on urx_free list */ +#define URXE_DEMUX_STATE_PENDING 1 /* on urx_pending list */ +#define URXE_DEMUX_STATE_ISSUED 2 /* on neither list */ + +#define DEMUX_MAX_MSGS_PER_CALL 32 + +#define DEMUX_DEFAULT_MTU 1500 + +/* Structure used to track a given connection ID. */ +typedef struct quic_demux_conn_st QUIC_DEMUX_CONN; + +struct quic_demux_conn_st { + QUIC_DEMUX_CONN *next; /* used when unregistering only */ + QUIC_CONN_ID dst_conn_id; + ossl_quic_demux_cb_fn *cb; + void *cb_arg; +}; + +DEFINE_LHASH_OF_EX(QUIC_DEMUX_CONN); + +static unsigned long demux_conn_hash(const QUIC_DEMUX_CONN *conn) +{ + size_t i; + unsigned long v = 0; + + assert(conn->dst_conn_id.id_len <= QUIC_MAX_CONN_ID_LEN); + + for (i = 0; i < conn->dst_conn_id.id_len; ++i) + v ^= ((unsigned long)conn->dst_conn_id.id[i]) + << ((i * 8) % (sizeof(unsigned long) * 8)); + + return v; +} + +static int demux_conn_cmp(const QUIC_DEMUX_CONN *a, const QUIC_DEMUX_CONN *b) +{ + return !ossl_quic_conn_id_eq(&a->dst_conn_id, &b->dst_conn_id); +} + +struct quic_demux_st { + /* The underlying transport BIO with datagram semantics. */ + BIO *net_bio; + + /* + * QUIC short packets do not contain the length of the connection ID field, + * therefore it must be known contextually. The demuxer requires connection + * IDs of the same length to be used for all incoming packets. + */ + size_t short_conn_id_len; + + /* + * Our current understanding of the upper bound on an incoming datagram size + * in bytes. + */ + size_t mtu; + + /* Time retrieval callback. */ + OSSL_TIME (*now)(void *arg); + void *now_arg; + + /* Hashtable mapping connection IDs to QUIC_DEMUX_CONN structures. */ + LHASH_OF(QUIC_DEMUX_CONN) *conns_by_id; + + /* The default packet handler, if any. */ + ossl_quic_demux_cb_fn *default_cb; + void *default_cb_arg; + + /* The stateless reset token checker handler, if any. */ + ossl_quic_stateless_reset_cb_fn *reset_token_cb; + void *reset_token_cb_arg; + + /* + * List of URXEs which are not currently in use (i.e., not filled with + * unconsumed data). These are moved to the pending list as they are filled. + */ + QUIC_URXE_LIST urx_free; + + /* + * List of URXEs which are filled with received encrypted data. These are + * removed from this list as we invoke the callbacks for each of them. They + * are then not on any list managed by us; we forget about them until our + * user calls ossl_quic_demux_release_urxe to return the URXE to us, at + * which point we add it to the free list. + */ + QUIC_URXE_LIST urx_pending; + + /* Whether to use local address support. */ + char use_local_addr; +}; + +QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, + size_t short_conn_id_len, + OSSL_TIME (*now)(void *arg), + void *now_arg) +{ + QUIC_DEMUX *demux; + + demux = OPENSSL_zalloc(sizeof(QUIC_DEMUX)); + if (demux == NULL) + return NULL; + + demux->net_bio = net_bio; + demux->short_conn_id_len = short_conn_id_len; + /* We update this if possible when we get a BIO. */ + demux->mtu = DEMUX_DEFAULT_MTU; + demux->now = now; + demux->now_arg = now_arg; + + demux->conns_by_id + = lh_QUIC_DEMUX_CONN_new(demux_conn_hash, demux_conn_cmp); + if (demux->conns_by_id == NULL) { + OPENSSL_free(demux); + return NULL; + } + + if (net_bio != NULL + && BIO_dgram_get_local_addr_cap(net_bio) + && BIO_dgram_set_local_addr_enable(net_bio, 1)) + demux->use_local_addr = 1; + + return demux; +} + +static void demux_free_conn_it(QUIC_DEMUX_CONN *conn, void *arg) +{ + OPENSSL_free(conn); +} + +static void demux_free_urxl(QUIC_URXE_LIST *l) +{ + QUIC_URXE *e, *enext; + + for (e = ossl_list_urxe_head(l); e != NULL; e = enext) { + enext = ossl_list_urxe_next(e); + ossl_list_urxe_remove(l, e); + OPENSSL_free(e); + } +} + +void ossl_quic_demux_free(QUIC_DEMUX *demux) +{ + if (demux == NULL) + return; + + /* Free all connection structures. */ + lh_QUIC_DEMUX_CONN_doall_arg(demux->conns_by_id, demux_free_conn_it, NULL); + lh_QUIC_DEMUX_CONN_free(demux->conns_by_id); + + /* Free all URXEs we are holding. */ + demux_free_urxl(&demux->urx_free); + demux_free_urxl(&demux->urx_pending); + + OPENSSL_free(demux); +} + +void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio) +{ + unsigned int mtu; + + demux->net_bio = net_bio; + + if (net_bio != NULL) { + /* + * Try to determine our MTU if possible. The BIO is not required to + * support this, in which case we remain at the last known MTU, or our + * initial default. + */ + mtu = BIO_dgram_get_mtu(net_bio); + if (mtu >= QUIC_MIN_INITIAL_DGRAM_LEN) + ossl_quic_demux_set_mtu(demux, mtu); /* best effort */ + } +} + +int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu) +{ + if (mtu < QUIC_MIN_INITIAL_DGRAM_LEN) + return 0; + + demux->mtu = mtu; + return 1; +} + +static QUIC_DEMUX_CONN *demux_get_by_conn_id(QUIC_DEMUX *demux, + const QUIC_CONN_ID *dst_conn_id) +{ + QUIC_DEMUX_CONN key; + + if (dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN) + return NULL; + + key.dst_conn_id = *dst_conn_id; + return lh_QUIC_DEMUX_CONN_retrieve(demux->conns_by_id, &key); +} + +int ossl_quic_demux_register(QUIC_DEMUX *demux, + const QUIC_CONN_ID *dst_conn_id, + ossl_quic_demux_cb_fn *cb, void *cb_arg) +{ + QUIC_DEMUX_CONN *conn; + + if (dst_conn_id == NULL + || dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN + || cb == NULL) + return 0; + + /* Ensure not already registered. */ + if (demux_get_by_conn_id(demux, dst_conn_id) != NULL) + /* Handler already registered with this connection ID. */ + return 0; + + conn = OPENSSL_zalloc(sizeof(QUIC_DEMUX_CONN)); + if (conn == NULL) + return 0; + + conn->dst_conn_id = *dst_conn_id; + conn->cb = cb; + conn->cb_arg = cb_arg; + + lh_QUIC_DEMUX_CONN_insert(demux->conns_by_id, conn); + return 1; +} + +static void demux_unregister(QUIC_DEMUX *demux, + QUIC_DEMUX_CONN *conn) +{ + lh_QUIC_DEMUX_CONN_delete(demux->conns_by_id, conn); + OPENSSL_free(conn); +} + +int ossl_quic_demux_unregister(QUIC_DEMUX *demux, + const QUIC_CONN_ID *dst_conn_id) +{ + QUIC_DEMUX_CONN *conn; + + if (dst_conn_id == NULL + || dst_conn_id->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + conn = demux_get_by_conn_id(demux, dst_conn_id); + if (conn == NULL) + return 0; + + demux_unregister(demux, conn); + return 1; +} + +struct unreg_arg { + ossl_quic_demux_cb_fn *cb; + void *cb_arg; + QUIC_DEMUX_CONN *head; +}; + +static void demux_unregister_by_cb(QUIC_DEMUX_CONN *conn, void *arg_) +{ + struct unreg_arg *arg = arg_; + + if (conn->cb == arg->cb && conn->cb_arg == arg->cb_arg) { + conn->next = arg->head; + arg->head = conn; + } +} + +void ossl_quic_demux_unregister_by_cb(QUIC_DEMUX *demux, + ossl_quic_demux_cb_fn *cb, + void *cb_arg) +{ + QUIC_DEMUX_CONN *conn, *cnext; + struct unreg_arg arg = {0}; + arg.cb = cb; + arg.cb_arg = cb_arg; + + lh_QUIC_DEMUX_CONN_doall_arg(demux->conns_by_id, + demux_unregister_by_cb, &arg); + + for (conn = arg.head; conn != NULL; conn = cnext) { + cnext = conn->next; + demux_unregister(demux, conn); + } +} + +void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, + ossl_quic_demux_cb_fn *cb, + void *cb_arg) +{ + demux->default_cb = cb; + demux->default_cb_arg = cb_arg; +} + +void ossl_quic_demux_set_stateless_reset_handler( + QUIC_DEMUX *demux, + ossl_quic_stateless_reset_cb_fn *cb, void *cb_arg) +{ + demux->reset_token_cb = cb; + demux->reset_token_cb_arg = cb_arg; +} + +static QUIC_URXE *demux_alloc_urxe(size_t alloc_len) +{ + QUIC_URXE *e; + + if (alloc_len >= SIZE_MAX - sizeof(QUIC_URXE)) + return NULL; + + e = OPENSSL_malloc(sizeof(QUIC_URXE) + alloc_len); + if (e == NULL) + return NULL; + + ossl_list_urxe_init_elem(e); + e->alloc_len = alloc_len; + e->data_len = 0; + return e; +} + +static QUIC_URXE *demux_resize_urxe(QUIC_DEMUX *demux, QUIC_URXE *e, + size_t new_alloc_len) +{ + QUIC_URXE *e2, *prev; + + if (!ossl_assert(e->demux_state == URXE_DEMUX_STATE_FREE)) + /* Never attempt to resize a URXE which is not on the free list. */ + return NULL; + + prev = ossl_list_urxe_prev(e); + ossl_list_urxe_remove(&demux->urx_free, e); + + e2 = OPENSSL_realloc(e, sizeof(QUIC_URXE) + new_alloc_len); + if (e2 == NULL) { + /* Failed to resize, abort. */ + if (prev == NULL) + ossl_list_urxe_insert_head(&demux->urx_free, e); + else + ossl_list_urxe_insert_after(&demux->urx_free, prev, e); + + return NULL; + } + + if (prev == NULL) + ossl_list_urxe_insert_head(&demux->urx_free, e2); + else + ossl_list_urxe_insert_after(&demux->urx_free, prev, e2); + + e2->alloc_len = new_alloc_len; + return e2; +} + +static QUIC_URXE *demux_reserve_urxe(QUIC_DEMUX *demux, QUIC_URXE *e, + size_t alloc_len) +{ + return e->alloc_len < alloc_len ? demux_resize_urxe(demux, e, alloc_len) : e; +} + +static int demux_ensure_free_urxe(QUIC_DEMUX *demux, size_t min_num_free) +{ + QUIC_URXE *e; + + while (ossl_list_urxe_num(&demux->urx_free) < min_num_free) { + e = demux_alloc_urxe(demux->mtu); + if (e == NULL) + return 0; + + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; + } + + return 1; +} + +/* + * Receive datagrams from network, placing them into URXEs. + * + * Returns 1 on success or 0 on failure. + * + * Precondition: at least one URXE is free + * Precondition: there are no pending URXEs + */ +static int demux_recv(QUIC_DEMUX *demux) +{ + BIO_MSG msg[DEMUX_MAX_MSGS_PER_CALL]; + size_t rd, i; + QUIC_URXE *urxe = ossl_list_urxe_head(&demux->urx_free), *unext; + OSSL_TIME now; + + /* This should never be called when we have any pending URXE. */ + assert(ossl_list_urxe_head(&demux->urx_pending) == NULL); + assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); + + if (demux->net_bio == NULL) + /* + * If no BIO is plugged in, treat this as no datagram being available. + */ + return QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL; + + /* + * Opportunistically receive as many messages as possible in a single + * syscall, determined by how many free URXEs are available. + */ + for (i = 0; i < (ossl_ssize_t)OSSL_NELEM(msg); + ++i, urxe = ossl_list_urxe_next(urxe)) { + if (urxe == NULL) { + /* We need at least one URXE to receive into. */ + if (!ossl_assert(i > 0)) + return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; + + break; + } + + /* Ensure the URXE is big enough. */ + urxe = demux_reserve_urxe(demux, urxe, demux->mtu); + if (urxe == NULL) + /* Allocation error, fail. */ + return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; + + /* Ensure we zero any fields added to BIO_MSG at a later date. */ + memset(&msg[i], 0, sizeof(BIO_MSG)); + msg[i].data = ossl_quic_urxe_data(urxe); + msg[i].data_len = urxe->alloc_len; + msg[i].peer = &urxe->peer; + BIO_ADDR_clear(&urxe->peer); + if (demux->use_local_addr) + msg[i].local = &urxe->local; + else + BIO_ADDR_clear(&urxe->local); + } + + ERR_set_mark(); + if (!BIO_recvmmsg(demux->net_bio, msg, sizeof(BIO_MSG), i, 0, &rd)) { + if (BIO_err_is_non_fatal(ERR_peek_last_error())) { + /* Transient error, clear the error and stop. */ + ERR_pop_to_mark(); + return QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL; + } else { + /* Non-transient error, do not clear the error. */ + ERR_clear_last_mark(); + return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; + } + } + + ERR_clear_last_mark(); + now = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); + + urxe = ossl_list_urxe_head(&demux->urx_free); + for (i = 0; i < rd; ++i, urxe = unext) { + unext = ossl_list_urxe_next(urxe); + /* Set URXE with actual length of received datagram. */ + urxe->data_len = msg[i].data_len; + /* Time we received datagram. */ + urxe->time = now; + /* Move from free list to pending list. */ + ossl_list_urxe_remove(&demux->urx_free, urxe); + ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); + urxe->demux_state = URXE_DEMUX_STATE_PENDING; + } + + return QUIC_DEMUX_PUMP_RES_OK; +} + +/* Extract destination connection ID from the first packet in a datagram. */ +static int demux_identify_conn_id(QUIC_DEMUX *demux, + QUIC_URXE *e, + QUIC_CONN_ID *dst_conn_id) +{ + return ossl_quic_wire_get_pkt_hdr_dst_conn_id(ossl_quic_urxe_data(e), + e->data_len, + demux->short_conn_id_len, + dst_conn_id); +} + +/* Identify the connection structure corresponding to a given URXE. */ +static QUIC_DEMUX_CONN *demux_identify_conn(QUIC_DEMUX *demux, QUIC_URXE *e) +{ + QUIC_CONN_ID dst_conn_id; + + if (!demux_identify_conn_id(demux, e, &dst_conn_id)) + /* + * Datagram is so badly malformed we can't get the DCID from the first + * packet in it, so just give up. + */ + return NULL; + + return demux_get_by_conn_id(demux, &dst_conn_id); +} + +/* + * Process a single pending URXE. + * Returning 1 on success, 0 on failure and -1 on stateless reset. + */ +static int demux_process_pending_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) +{ + QUIC_DEMUX_CONN *conn; + int r; + + /* The next URXE we process should be at the head of the pending list. */ + if (!ossl_assert(e == ossl_list_urxe_head(&demux->urx_pending))) + return 0; + + assert(e->demux_state == URXE_DEMUX_STATE_PENDING); + + /* + * Check if the packet ends with a stateless reset token and if it does + * skip it after dropping the connection. + * + * RFC 9000 s. 10.3.1 Detecting a Stateless Reset + * If the last 16 bytes of the datagram are identical in value to + * a stateless reset token, the endpoint MUST enter the draining + * period and not send any further packets on this connection. + * + * Returning a failure here causes the connection to enter the terminating + * state which achieves the desired outcome. + * + * TODO(QUIC FUTURE): only try to match unparsable packets + */ + if (demux->reset_token_cb != NULL) { + r = demux->reset_token_cb(ossl_quic_urxe_data(e), e->data_len, + demux->reset_token_cb_arg); + if (r > 0) /* Received a stateless reset */ + return -1; + if (r < 0) /* Error during stateless reset detection */ + return 0; + } + + conn = demux_identify_conn(demux, e); + if (conn == NULL) { + /* + * We could not identify a connection. If we have a default packet + * handler, pass it to the handler. Otherwise, we will never be able to + * process this datagram, so get rid of it. + */ + ossl_list_urxe_remove(&demux->urx_pending, e); + if (demux->default_cb != NULL) { + /* Pass to default handler. */ + e->demux_state = URXE_DEMUX_STATE_ISSUED; + demux->default_cb(e, demux->default_cb_arg); + } else { + /* Discard. */ + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; + } + return 1; /* keep processing pending URXEs */ + } + + /* + * Remove from list and invoke callback. The URXE now belongs to the + * callback. (QUIC_DEMUX_CONN never has non-NULL cb.) + */ + ossl_list_urxe_remove(&demux->urx_pending, e); + e->demux_state = URXE_DEMUX_STATE_ISSUED; + conn->cb(e, conn->cb_arg); + return 1; +} + +/* Process pending URXEs to generate callbacks. */ +static int demux_process_pending_urxl(QUIC_DEMUX *demux) +{ + QUIC_URXE *e; + int ret; + + while ((e = ossl_list_urxe_head(&demux->urx_pending)) != NULL) + if ((ret = demux_process_pending_urxe(demux, e)) <= 0) + return ret; + + return 1; +} + +/* + * Drain the pending URXE list, processing any pending URXEs by making their + * callbacks. If no URXEs are pending, a network read is attempted first. + */ +int ossl_quic_demux_pump(QUIC_DEMUX *demux) +{ + int ret; + + if (ossl_list_urxe_head(&demux->urx_pending) == NULL) { + ret = demux_ensure_free_urxe(demux, DEMUX_MAX_MSGS_PER_CALL); + if (ret != 1) + return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; + + ret = demux_recv(demux); + if (ret != QUIC_DEMUX_PUMP_RES_OK) + return ret; + + /* + * If demux_recv returned successfully, we should always have something. + */ + assert(ossl_list_urxe_head(&demux->urx_pending) != NULL); + } + + if ((ret = demux_process_pending_urxl(demux)) <= 0) + return ret == 0 ? QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL + : QUIC_DEMUX_PUMP_RES_STATELESS_RESET; + + return QUIC_DEMUX_PUMP_RES_OK; +} + +/* Artificially inject a packet into the demuxer for testing purposes. */ +int ossl_quic_demux_inject(QUIC_DEMUX *demux, + const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local) +{ + int ret; + QUIC_URXE *urxe; + + ret = demux_ensure_free_urxe(demux, 1); + if (ret != 1) + return 0; + + urxe = ossl_list_urxe_head(&demux->urx_free); + + assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); + + urxe = demux_reserve_urxe(demux, urxe, buf_len); + if (urxe == NULL) + return 0; + + memcpy(ossl_quic_urxe_data(urxe), buf, buf_len); + urxe->data_len = buf_len; + + if (peer != NULL) + urxe->peer = *peer; + else + BIO_ADDR_clear(&urxe->peer); + + if (local != NULL) + urxe->local = *local; + else + BIO_ADDR_clear(&urxe->local); + + urxe->time + = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); + + /* Move from free list to pending list. */ + ossl_list_urxe_remove(&demux->urx_free, urxe); + ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); + urxe->demux_state = URXE_DEMUX_STATE_PENDING; + + return demux_process_pending_urxl(demux) > 0; +} + +/* Called by our user to return a URXE to the free list. */ +void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux, + QUIC_URXE *e) +{ + assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); + assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; +} + +void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux, + QUIC_URXE *e) +{ + assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); + assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); + ossl_list_urxe_insert_head(&demux->urx_pending, e); + e->demux_state = URXE_DEMUX_STATE_PENDING; +} + +int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux) +{ + return ossl_list_urxe_head(&demux->urx_pending) != NULL; +} diff --git a/ssl/quic/quic_fc.c b/ssl/quic/quic_fc.c new file mode 100644 index 0000000000..750e896306 --- /dev/null +++ b/ssl/quic/quic_fc.c @@ -0,0 +1,406 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_fc.h" +#include "internal/quic_error.h" +#include "internal/common.h" +#include "internal/safe_math.h" +#include + +OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t) + +/* + * TX Flow Controller (TXFC) + * ========================= + */ + +int ossl_quic_txfc_init(QUIC_TXFC *txfc, QUIC_TXFC *conn_txfc) +{ + if (conn_txfc != NULL && conn_txfc->parent != NULL) + return 0; + + txfc->swm = 0; + txfc->cwm = 0; + txfc->parent = conn_txfc; + txfc->has_become_blocked = 0; + return 1; +} + +QUIC_TXFC *ossl_quic_txfc_get_parent(QUIC_TXFC *txfc) +{ + return txfc->parent; +} + +int ossl_quic_txfc_bump_cwm(QUIC_TXFC *txfc, uint64_t cwm) +{ + if (cwm <= txfc->cwm) + return 0; + + txfc->cwm = cwm; + return 1; +} + +uint64_t ossl_quic_txfc_get_credit_local(QUIC_TXFC *txfc, uint64_t consumed) +{ + assert((txfc->swm + consumed) <= txfc->cwm); + return txfc->cwm - (consumed + txfc->swm); +} + +uint64_t ossl_quic_txfc_get_credit(QUIC_TXFC *txfc, uint64_t consumed) +{ + uint64_t r, conn_r; + + r = ossl_quic_txfc_get_credit_local(txfc, 0); + + if (txfc->parent != NULL) { + assert(txfc->parent->parent == NULL); + conn_r = ossl_quic_txfc_get_credit_local(txfc->parent, consumed); + if (conn_r < r) + r = conn_r; + } + + return r; +} + +int ossl_quic_txfc_consume_credit_local(QUIC_TXFC *txfc, uint64_t num_bytes) +{ + int ok = 1; + uint64_t credit = ossl_quic_txfc_get_credit_local(txfc, 0); + + if (num_bytes > credit) { + ok = 0; + num_bytes = credit; + } + + if (num_bytes > 0 && num_bytes == credit) + txfc->has_become_blocked = 1; + + txfc->swm += num_bytes; + return ok; +} + +int ossl_quic_txfc_consume_credit(QUIC_TXFC *txfc, uint64_t num_bytes) +{ + int ok = ossl_quic_txfc_consume_credit_local(txfc, num_bytes); + + if (txfc->parent != NULL) { + assert(txfc->parent->parent == NULL); + if (!ossl_quic_txfc_consume_credit_local(txfc->parent, num_bytes)) + return 0; + } + + return ok; +} + +int ossl_quic_txfc_has_become_blocked(QUIC_TXFC *txfc, int clear) +{ + int r = txfc->has_become_blocked; + + if (clear) + txfc->has_become_blocked = 0; + + return r; +} + +uint64_t ossl_quic_txfc_get_cwm(QUIC_TXFC *txfc) +{ + return txfc->cwm; +} + +uint64_t ossl_quic_txfc_get_swm(QUIC_TXFC *txfc) +{ + return txfc->swm; +} + +/* + * RX Flow Controller (RXFC) + * ========================= + */ + +int ossl_quic_rxfc_init(QUIC_RXFC *rxfc, QUIC_RXFC *conn_rxfc, + uint64_t initial_window_size, + uint64_t max_window_size, + OSSL_TIME (*now)(void *now_arg), + void *now_arg) +{ + if (conn_rxfc != NULL && conn_rxfc->parent != NULL) + return 0; + + rxfc->swm = 0; + rxfc->cwm = initial_window_size; + rxfc->rwm = 0; + rxfc->esrwm = 0; + rxfc->hwm = 0; + rxfc->cur_window_size = initial_window_size; + rxfc->max_window_size = max_window_size; + rxfc->parent = conn_rxfc; + rxfc->error_code = 0; + rxfc->has_cwm_changed = 0; + rxfc->epoch_start = ossl_time_zero(); + rxfc->now = now; + rxfc->now_arg = now_arg; + rxfc->is_fin = 0; + rxfc->standalone = 0; + return 1; +} + +int ossl_quic_rxfc_init_standalone(QUIC_RXFC *rxfc, + uint64_t initial_window_size, + OSSL_TIME (*now)(void *arg), + void *now_arg) +{ + if (!ossl_quic_rxfc_init(rxfc, NULL, + initial_window_size, initial_window_size, + now, now_arg)) + return 0; + + rxfc->standalone = 1; + return 1; +} + +QUIC_RXFC *ossl_quic_rxfc_get_parent(QUIC_RXFC *rxfc) +{ + return rxfc->parent; +} + +void ossl_quic_rxfc_set_max_window_size(QUIC_RXFC *rxfc, + size_t max_window_size) +{ + rxfc->max_window_size = max_window_size; +} + +static void rxfc_start_epoch(QUIC_RXFC *rxfc) +{ + rxfc->epoch_start = rxfc->now(rxfc->now_arg); + rxfc->esrwm = rxfc->rwm; +} + +static int on_rx_controlled_bytes(QUIC_RXFC *rxfc, uint64_t num_bytes) +{ + int ok = 1; + uint64_t credit = rxfc->cwm - rxfc->swm; + + if (num_bytes > credit) { + ok = 0; + num_bytes = credit; + rxfc->error_code = QUIC_ERR_FLOW_CONTROL_ERROR; + } + + rxfc->swm += num_bytes; + return ok; +} + +int ossl_quic_rxfc_on_rx_stream_frame(QUIC_RXFC *rxfc, uint64_t end, int is_fin) +{ + uint64_t delta; + + if (!rxfc->standalone && rxfc->parent == NULL) + return 0; + + if (rxfc->is_fin && ((is_fin && rxfc->hwm != end) || end > rxfc->hwm)) { + /* Stream size cannot change after the stream is finished */ + rxfc->error_code = QUIC_ERR_FINAL_SIZE_ERROR; + return 1; /* not a caller error */ + } + + if (is_fin) + rxfc->is_fin = 1; + + if (end > rxfc->hwm) { + delta = end - rxfc->hwm; + rxfc->hwm = end; + + on_rx_controlled_bytes(rxfc, delta); /* result ignored */ + if (rxfc->parent != NULL) + on_rx_controlled_bytes(rxfc->parent, delta); /* result ignored */ + } else if (end < rxfc->hwm && is_fin) { + rxfc->error_code = QUIC_ERR_FINAL_SIZE_ERROR; + return 1; /* not a caller error */ + } + + return 1; +} + +/* threshold = 3/4 */ +#define WINDOW_THRESHOLD_NUM 3 +#define WINDOW_THRESHOLD_DEN 4 + +static int rxfc_cwm_bump_desired(QUIC_RXFC *rxfc) +{ + int err = 0; + uint64_t window_rem = rxfc->cwm - rxfc->rwm; + uint64_t threshold + = safe_muldiv_uint64_t(rxfc->cur_window_size, + WINDOW_THRESHOLD_NUM, WINDOW_THRESHOLD_DEN, &err); + + if (err) + /* + * Extremely large window should never occur, but if it does, just use + * 1/2 as the threshold. + */ + threshold = rxfc->cur_window_size / 2; + + /* + * No point emitting a new MAX_STREAM_DATA frame if the stream has a final + * size. + */ + return !rxfc->is_fin && window_rem <= threshold; +} + +static int rxfc_should_bump_window_size(QUIC_RXFC *rxfc, OSSL_TIME rtt) +{ + /* + * dt: time since start of epoch + * b: bytes of window consumed since start of epoch + * dw: proportion of window consumed since start of epoch + * T_window: time it will take to use up the entire window, based on dt, dw + * RTT: The current estimated RTT. + * + * b = rwm - esrwm + * dw = b / window_size + * T_window = dt / dw + * T_window = dt / (b / window_size) + * T_window = (dt * window_size) / b + * + * We bump the window size if T_window < 4 * RTT. + * + * We leave the division by b on the LHS to reduce the risk of overflowing + * our 64-bit nanosecond representation, which will afford plenty of + * precision left over after the division anyway. + */ + uint64_t b = rxfc->rwm - rxfc->esrwm; + OSSL_TIME now, dt, t_window; + + if (b == 0) + return 0; + + now = rxfc->now(rxfc->now_arg); + dt = ossl_time_subtract(now, rxfc->epoch_start); + t_window = ossl_time_muldiv(dt, rxfc->cur_window_size, b); + + return ossl_time_compare(t_window, ossl_time_multiply(rtt, 4)) < 0; +} + +static void rxfc_adjust_window_size(QUIC_RXFC *rxfc, uint64_t min_window_size, + OSSL_TIME rtt) +{ + /* Are we sending updates too often? */ + uint64_t new_window_size; + + new_window_size = rxfc->cur_window_size; + + if (rxfc_should_bump_window_size(rxfc, rtt)) + new_window_size *= 2; + + if (new_window_size < min_window_size) + new_window_size = min_window_size; + if (new_window_size > rxfc->max_window_size) /* takes precedence over min size */ + new_window_size = rxfc->max_window_size; + + rxfc->cur_window_size = new_window_size; + rxfc_start_epoch(rxfc); +} + +static void rxfc_update_cwm(QUIC_RXFC *rxfc, uint64_t min_window_size, + OSSL_TIME rtt) +{ + uint64_t new_cwm; + + if (!rxfc_cwm_bump_desired(rxfc)) + return; + + rxfc_adjust_window_size(rxfc, min_window_size, rtt); + + new_cwm = rxfc->rwm + rxfc->cur_window_size; + if (new_cwm > rxfc->cwm) { + rxfc->cwm = new_cwm; + rxfc->has_cwm_changed = 1; + } +} + +static int rxfc_on_retire(QUIC_RXFC *rxfc, uint64_t num_bytes, + uint64_t min_window_size, + OSSL_TIME rtt) +{ + if (ossl_time_is_zero(rxfc->epoch_start)) + /* This happens when we retire our first ever bytes. */ + rxfc_start_epoch(rxfc); + + rxfc->rwm += num_bytes; + rxfc_update_cwm(rxfc, min_window_size, rtt); + return 1; +} + +int ossl_quic_rxfc_on_retire(QUIC_RXFC *rxfc, + uint64_t num_bytes, + OSSL_TIME rtt) +{ + if (rxfc->parent == NULL && !rxfc->standalone) + return 0; + + if (num_bytes == 0) + return 1; + + if (rxfc->rwm + num_bytes > rxfc->swm) + /* Impossible for us to retire more bytes than we have received. */ + return 0; + + rxfc_on_retire(rxfc, num_bytes, 0, rtt); + + if (!rxfc->standalone) + rxfc_on_retire(rxfc->parent, num_bytes, rxfc->cur_window_size, rtt); + + return 1; +} + +uint64_t ossl_quic_rxfc_get_cwm(QUIC_RXFC *rxfc) +{ + return rxfc->cwm; +} + +uint64_t ossl_quic_rxfc_get_swm(QUIC_RXFC *rxfc) +{ + return rxfc->swm; +} + +uint64_t ossl_quic_rxfc_get_rwm(QUIC_RXFC *rxfc) +{ + return rxfc->rwm; +} + +int ossl_quic_rxfc_has_cwm_changed(QUIC_RXFC *rxfc, int clear) +{ + int r = rxfc->has_cwm_changed; + + if (clear) + rxfc->has_cwm_changed = 0; + + return r; +} + +int ossl_quic_rxfc_get_error(QUIC_RXFC *rxfc, int clear) +{ + int r = rxfc->error_code; + + if (clear) + rxfc->error_code = 0; + + return r; +} + +int ossl_quic_rxfc_get_final_size(const QUIC_RXFC *rxfc, uint64_t *final_size) +{ + if (!rxfc->is_fin) + return 0; + + if (final_size != NULL) + *final_size = rxfc->hwm; + + return 1; +} diff --git a/ssl/quic/quic_fifd.c b/ssl/quic/quic_fifd.c new file mode 100644 index 0000000000..a3dd1db978 --- /dev/null +++ b/ssl/quic/quic_fifd.c @@ -0,0 +1,290 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_fifd.h" +#include "internal/quic_wire.h" + +DEFINE_LIST_OF(tx_history, OSSL_ACKM_TX_PKT); + +int ossl_quic_fifd_init(QUIC_FIFD *fifd, + QUIC_CFQ *cfq, + OSSL_ACKM *ackm, + QUIC_TXPIM *txpim, + /* stream_id is UINT64_MAX for the crypto stream */ + QUIC_SSTREAM *(*get_sstream_by_id)(uint64_t stream_id, + uint32_t pn_space, + void *arg), + void *get_sstream_by_id_arg, + /* stream_id is UINT64_MAX if not applicable */ + void (*regen_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg), + void *regen_frame_arg, + void (*confirm_frame)(uint64_t frame_type, + uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, + void *arg), + void *confirm_frame_arg, + void (*sstream_updated)(uint64_t stream_id, + void *arg), + void *sstream_updated_arg) +{ + if (cfq == NULL || ackm == NULL || txpim == NULL + || get_sstream_by_id == NULL || regen_frame == NULL) + return 0; + + fifd->cfq = cfq; + fifd->ackm = ackm; + fifd->txpim = txpim; + fifd->get_sstream_by_id = get_sstream_by_id; + fifd->get_sstream_by_id_arg = get_sstream_by_id_arg; + fifd->regen_frame = regen_frame; + fifd->regen_frame_arg = regen_frame_arg; + fifd->confirm_frame = confirm_frame; + fifd->confirm_frame_arg = confirm_frame_arg; + fifd->sstream_updated = sstream_updated; + fifd->sstream_updated_arg = sstream_updated_arg; + return 1; +} + +void ossl_quic_fifd_cleanup(QUIC_FIFD *fifd) +{ + /* No-op. */ +} + +static void on_acked(void *arg) +{ + QUIC_TXPIM_PKT *pkt = arg; + QUIC_FIFD *fifd = pkt->fifd; + const QUIC_TXPIM_CHUNK *chunks = ossl_quic_txpim_pkt_get_chunks(pkt); + size_t i, num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt); + QUIC_SSTREAM *sstream; + QUIC_CFQ_ITEM *cfq_item, *cfq_item_next; + + /* STREAM and CRYPTO stream chunks, FINs and stream FC frames */ + for (i = 0; i < num_chunks; ++i) { + sstream = fifd->get_sstream_by_id(chunks[i].stream_id, + pkt->ackm_pkt.pkt_space, + fifd->get_sstream_by_id_arg); + if (sstream == NULL) + continue; + + if (chunks[i].end >= chunks[i].start) + /* coverity[check_return]: Best effort - we cannot fail here. */ + ossl_quic_sstream_mark_acked(sstream, + chunks[i].start, chunks[i].end); + + if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) + ossl_quic_sstream_mark_acked_fin(sstream); + + if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX) + fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING, + chunks[i].stream_id, pkt, + fifd->confirm_frame_arg); + + if (chunks[i].has_reset_stream && chunks[i].stream_id != UINT64_MAX) + fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + chunks[i].stream_id, pkt, + fifd->confirm_frame_arg); + + if (ossl_quic_sstream_is_totally_acked(sstream)) + fifd->sstream_updated(chunks[i].stream_id, fifd->sstream_updated_arg); + } + + /* GCR */ + for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) { + cfq_item_next = cfq_item->pkt_next; + ossl_quic_cfq_release(fifd->cfq, cfq_item); + } + + ossl_quic_txpim_pkt_release(fifd->txpim, pkt); +} + +static void on_lost(void *arg) +{ + QUIC_TXPIM_PKT *pkt = arg; + QUIC_FIFD *fifd = pkt->fifd; + const QUIC_TXPIM_CHUNK *chunks = ossl_quic_txpim_pkt_get_chunks(pkt); + size_t i, num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt); + QUIC_SSTREAM *sstream; + QUIC_CFQ_ITEM *cfq_item, *cfq_item_next; + int sstream_updated; + + /* STREAM and CRYPTO stream chunks, FIN and stream FC frames */ + for (i = 0; i < num_chunks; ++i) { + sstream = fifd->get_sstream_by_id(chunks[i].stream_id, + pkt->ackm_pkt.pkt_space, + fifd->get_sstream_by_id_arg); + if (sstream == NULL) + continue; + + sstream_updated = 0; + + if (chunks[i].end >= chunks[i].start) { + /* + * Note: If the stream is being reset, we do not need to retransmit + * old data as this is pointless. In this case this will be handled + * by (sstream == NULL) above as the QSM will free the QUIC_SSTREAM + * and our call to get_sstream_by_id above will return NULL. + */ + ossl_quic_sstream_mark_lost(sstream, + chunks[i].start, chunks[i].end); + sstream_updated = 1; + } + + if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) { + ossl_quic_sstream_mark_lost_fin(sstream); + sstream_updated = 1; + } + + if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING, + chunks[i].stream_id, pkt, + fifd->regen_frame_arg); + + if (chunks[i].has_reset_stream && chunks[i].stream_id != UINT64_MAX) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + chunks[i].stream_id, pkt, + fifd->regen_frame_arg); + + /* + * Inform caller that stream needs an FC frame. + * + * Note: We could track whether an FC frame was sent originally for the + * stream to determine if it really needs to be regenerated or not. + * However, if loss has occurred, it's probably better to ensure the + * peer has up-to-date flow control data for the stream. Given that + * these frames are extremely small, we may as well always send it when + * handling loss. + */ + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, + chunks[i].stream_id, + pkt, + fifd->regen_frame_arg); + + if (sstream_updated && chunks[i].stream_id != UINT64_MAX) + fifd->sstream_updated(chunks[i].stream_id, + fifd->sstream_updated_arg); + } + + /* GCR */ + for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) { + cfq_item_next = cfq_item->pkt_next; + ossl_quic_cfq_mark_lost(fifd->cfq, cfq_item, UINT32_MAX); + } + + /* Regenerate flag frames */ + if (pkt->had_handshake_done_frame) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE, + UINT64_MAX, pkt, + fifd->regen_frame_arg); + + if (pkt->had_max_data_frame) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_DATA, + UINT64_MAX, pkt, + fifd->regen_frame_arg); + + if (pkt->had_max_streams_bidi_frame) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI, + UINT64_MAX, pkt, + fifd->regen_frame_arg); + + if (pkt->had_max_streams_uni_frame) + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI, + UINT64_MAX, pkt, + fifd->regen_frame_arg); + + if (pkt->had_ack_frame) + /* + * We always use the ACK_WITH_ECN frame type to represent the ACK frame + * type in our callback; we assume it is the caller's job to decide + * whether it wants to send ECN data or not. + */ + fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN, + UINT64_MAX, pkt, + fifd->regen_frame_arg); + + ossl_quic_txpim_pkt_release(fifd->txpim, pkt); +} + +static void on_discarded(void *arg) +{ + QUIC_TXPIM_PKT *pkt = arg; + QUIC_FIFD *fifd = pkt->fifd; + QUIC_CFQ_ITEM *cfq_item, *cfq_item_next; + + /* + * Don't need to do anything to SSTREAMs for STREAM and CRYPTO streams, as + * we assume caller will clean them up. + */ + + /* GCR */ + for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) { + cfq_item_next = cfq_item->pkt_next; + ossl_quic_cfq_release(fifd->cfq, cfq_item); + } + + ossl_quic_txpim_pkt_release(fifd->txpim, pkt); +} + +int ossl_quic_fifd_pkt_commit(QUIC_FIFD *fifd, QUIC_TXPIM_PKT *pkt) +{ + QUIC_CFQ_ITEM *cfq_item; + const QUIC_TXPIM_CHUNK *chunks; + size_t i, num_chunks; + QUIC_SSTREAM *sstream; + + pkt->fifd = fifd; + + pkt->ackm_pkt.on_lost = on_lost; + pkt->ackm_pkt.on_acked = on_acked; + pkt->ackm_pkt.on_discarded = on_discarded; + pkt->ackm_pkt.cb_arg = pkt; + + ossl_list_tx_history_init_elem(&pkt->ackm_pkt); + pkt->ackm_pkt.anext = pkt->ackm_pkt.lnext = NULL; + + /* + * Mark the CFQ items which have been added to this packet as having been + * transmitted. + */ + for (cfq_item = pkt->retx_head; + cfq_item != NULL; + cfq_item = cfq_item->pkt_next) + ossl_quic_cfq_mark_tx(fifd->cfq, cfq_item); + + /* + * Mark the send stream chunks which have been added to the packet as having + * been transmitted. + */ + chunks = ossl_quic_txpim_pkt_get_chunks(pkt); + num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt); + for (i = 0; i < num_chunks; ++i) { + sstream = fifd->get_sstream_by_id(chunks[i].stream_id, + pkt->ackm_pkt.pkt_space, + fifd->get_sstream_by_id_arg); + if (sstream == NULL) + continue; + + if (chunks[i].end >= chunks[i].start + && !ossl_quic_sstream_mark_transmitted(sstream, + chunks[i].start, + chunks[i].end)) + return 0; + + if (chunks[i].has_fin + && !ossl_quic_sstream_mark_transmitted_fin(sstream, + chunks[i].end + 1)) + return 0; + } + + /* Inform the ACKM. */ + return ossl_ackm_on_tx_packet(fifd->ackm, &pkt->ackm_pkt); +} diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c new file mode 100644 index 0000000000..399d1d2afd --- /dev/null +++ b/ssl/quic/quic_impl.c @@ -0,0 +1,3657 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "quic_local.h" +#include "internal/quic_tls.h" +#include "internal/quic_rx_depack.h" +#include "internal/quic_error.h" +#include "internal/time.h" + +typedef struct qctx_st QCTX; + +static void aon_write_finish(QUIC_XSO *xso); +static int create_channel(QUIC_CONNECTION *qc); +static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs); +static int qc_try_create_default_xso_for_write(QCTX *ctx); +static int qc_wait_for_default_xso_for_read(QCTX *ctx); +static void quic_lock(QUIC_CONNECTION *qc); +static void quic_unlock(QUIC_CONNECTION *qc); +static void quic_lock_for_io(QCTX *ctx); +static int quic_do_handshake(QCTX *ctx); +static void qc_update_reject_policy(QUIC_CONNECTION *qc); +static void qc_touch_default_xso(QUIC_CONNECTION *qc); +static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch); +static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso, + int touch, QUIC_XSO **old_xso); +static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock); +static int quic_validate_for_write(QUIC_XSO *xso, int *err); +static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active); +static int qc_blocking_mode(const QUIC_CONNECTION *qc); +static int xso_blocking_mode(const QUIC_XSO *xso); + +/* + * QUIC Front-End I/O API: Common Utilities + * ======================================== + */ + +/* + * Block until a predicate is met. + * + * Precondition: Must have a channel. + * Precondition: Must hold channel lock (unchecked). + */ +QUIC_NEEDS_LOCK +static int block_until_pred(QUIC_CONNECTION *qc, + int (*pred)(void *arg), void *pred_arg, + uint32_t flags) +{ + QUIC_REACTOR *rtor; + + assert(qc->ch != NULL); + + /* + * Any attempt to block auto-disables tick inhibition as otherwise we will + * hang around forever. + */ + ossl_quic_channel_set_inhibit_tick(qc->ch, 0); + + rtor = ossl_quic_channel_get_reactor(qc->ch); + return ossl_quic_reactor_block_until_pred(rtor, pred, pred_arg, flags, + qc->mutex); +} + +static OSSL_TIME get_time(QUIC_CONNECTION *qc) +{ + if (qc->override_now_cb != NULL) + return qc->override_now_cb(qc->override_now_cb_arg); + else + return ossl_time_now(); +} + +static OSSL_TIME get_time_cb(void *arg) +{ + QUIC_CONNECTION *qc = arg; + + return get_time(qc); +} + +/* + * QCTX is a utility structure which provides information we commonly wish to + * unwrap upon an API call being dispatched to us, namely: + * + * - a pointer to the QUIC_CONNECTION (regardless of whether a QCSO or QSSO + * was passed); + * - a pointer to any applicable QUIC_XSO (e.g. if a QSSO was passed, or if + * a QCSO with a default stream was passed); + * - whether a QSSO was passed (xso == NULL must not be used to determine this + * because it may be non-NULL when a QCSO is passed if that QCSO has a + * default stream); + * - whether we are in "I/O context", meaning that non-normal errors can + * be reported via SSL_get_error() as well as via ERR. Functions such as + * SSL_read(), SSL_write() and SSL_do_handshake() are "I/O context" + * functions which are allowed to change the value returned by + * SSL_get_error. However, other functions (including functions which call + * SSL_do_handshake() implicitly) are not allowed to change the return value + * of SSL_get_error. + */ +struct qctx_st { + QUIC_CONNECTION *qc; + QUIC_XSO *xso; + int is_stream, in_io; +}; + +QUIC_NEEDS_LOCK +static void quic_set_last_error(QCTX *ctx, int last_error) +{ + if (!ctx->in_io) + return; + + if (ctx->is_stream && ctx->xso != NULL) + ctx->xso->last_error = last_error; + else if (!ctx->is_stream && ctx->qc != NULL) + ctx->qc->last_error = last_error; +} + +/* + * Raise a 'normal' error, meaning one that can be reported via SSL_get_error() + * rather than via ERR. Note that normal errors must always be raised while + * holding a lock. + */ +QUIC_NEEDS_LOCK +static int quic_raise_normal_error(QCTX *ctx, + int err) +{ + assert(ctx->in_io); + quic_set_last_error(ctx, err); + + return 0; +} + +/* + * Raise a 'non-normal' error, meaning any error that is not reported via + * SSL_get_error() and must be reported via ERR. + * + * qc should be provided if available. In exceptional circumstances when qc is + * not known NULL may be passed. This should generally only happen when an + * expect_...() function defined below fails, which generally indicates a + * dispatch error or caller error. + * + * ctx should be NULL if the connection lock is not held. + */ +static int quic_raise_non_normal_error(QCTX *ctx, + const char *file, + int line, + const char *func, + int reason, + const char *fmt, + ...) +{ + va_list args; + + if (ctx != NULL) { + quic_set_last_error(ctx, SSL_ERROR_SSL); + + if (reason == SSL_R_PROTOCOL_IS_SHUTDOWN && ctx->qc != NULL) + ossl_quic_channel_restore_err_state(ctx->qc->ch); + } + + ERR_new(); + ERR_set_debug(file, line, func); + + va_start(args, fmt); + ERR_vset_error(ERR_LIB_SSL, reason, fmt, args); + va_end(args); + + return 0; +} + +#define QUIC_RAISE_NORMAL_ERROR(ctx, err) \ + quic_raise_normal_error((ctx), (err)) + +#define QUIC_RAISE_NON_NORMAL_ERROR(ctx, reason, msg) \ + quic_raise_non_normal_error((ctx), \ + OPENSSL_FILE, OPENSSL_LINE, \ + OPENSSL_FUNC, \ + (reason), \ + (msg)) + +/* + * Given a QCSO or QSSO, initialises a QCTX, determining the contextually + * applicable QUIC_CONNECTION pointer and, if applicable, QUIC_XSO pointer. + * + * After this returns 1, all fields of the passed QCTX are initialised. + * Returns 0 on failure. This function is intended to be used to provide API + * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure. + */ +static int expect_quic(const SSL *s, QCTX *ctx) +{ + QUIC_CONNECTION *qc; + QUIC_XSO *xso; + + ctx->qc = NULL; + ctx->xso = NULL; + ctx->is_stream = 0; + + if (s == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_PASSED_NULL_PARAMETER, NULL); + + switch (s->type) { + case SSL_TYPE_QUIC_CONNECTION: + qc = (QUIC_CONNECTION *)s; + ctx->qc = qc; + ctx->xso = qc->default_xso; + ctx->is_stream = 0; + ctx->in_io = 0; + return 1; + + case SSL_TYPE_QUIC_XSO: + xso = (QUIC_XSO *)s; + ctx->qc = xso->conn; + ctx->xso = xso; + ctx->is_stream = 1; + ctx->in_io = 0; + return 1; + + default: + return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + } +} + +/* + * Like expect_quic(), but requires a QUIC_XSO be contextually available. In + * other words, requires that the passed QSO be a QSSO or a QCSO with a default + * stream. + * + * remote_init determines if we expect the default XSO to be remotely created or + * not. If it is -1, do not instantiate a default XSO if one does not yet exist. + * + * Channel mutex is acquired and retained on success. + */ +QUIC_ACQUIRES_LOCK +static int ossl_unused expect_quic_with_stream_lock(const SSL *s, int remote_init, + int in_io, QCTX *ctx) +{ + if (!expect_quic(s, ctx)) + return 0; + + if (in_io) + quic_lock_for_io(ctx); + else + quic_lock(ctx->qc); + + if (ctx->xso == NULL && remote_init >= 0) { + if (!quic_mutation_allowed(ctx->qc, /*req_active=*/0)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + goto err; + } + + /* If we haven't finished the handshake, try to advance it. */ + if (quic_do_handshake(ctx) < 1) + /* ossl_quic_do_handshake raised error here */ + goto err; + + if (remote_init == 0) { + if (!qc_try_create_default_xso_for_write(ctx)) + goto err; + } else { + if (!qc_wait_for_default_xso_for_read(ctx)) + goto err; + } + + ctx->xso = ctx->qc->default_xso; + } + + if (ctx->xso == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL); + goto err; + } + + return 1; /* coverity[missing_unlock]: lock held */ + +err: + quic_unlock(ctx->qc); + return 0; +} + +/* + * Like expect_quic(), but fails if called on a QUIC_XSO. ctx->xso may still + * be non-NULL if the QCSO has a default stream. + */ +static int ossl_unused expect_quic_conn_only(const SSL *s, QCTX *ctx) +{ + if (!expect_quic(s, ctx)) + return 0; + + if (ctx->is_stream) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_CONN_USE_ONLY, NULL); + + return 1; +} + +/* + * Ensures that the channel mutex is held for a method which touches channel + * state. + * + * Precondition: Channel mutex is not held (unchecked) + */ +static void quic_lock(QUIC_CONNECTION *qc) +{ +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_lock(qc->mutex); +#endif +} + +static void quic_lock_for_io(QCTX *ctx) +{ + quic_lock(ctx->qc); + ctx->in_io = 1; + + /* + * We are entering an I/O function so we must update the values returned by + * SSL_get_error and SSL_want. Set no error. This will be overridden later + * if a call to QUIC_RAISE_NORMAL_ERROR or QUIC_RAISE_NON_NORMAL_ERROR + * occurs during the API call. + */ + quic_set_last_error(ctx, SSL_ERROR_NONE); +} + +/* Precondition: Channel mutex is held (unchecked) */ +QUIC_NEEDS_LOCK +static void quic_unlock(QUIC_CONNECTION *qc) +{ +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_unlock(qc->mutex); +#endif +} + +/* + * This predicate is the criterion which should determine API call rejection for + * *most* mutating API calls, particularly stream-related operations for send + * parts. + * + * A call is rejected (this function returns 0) if shutdown is in progress + * (stream flushing), or we are in a TERMINATING or TERMINATED state. If + * req_active=1, the connection must be active (i.e., the IDLE state is also + * rejected). + */ +static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active) +{ + if (qc->shutting_down || ossl_quic_channel_is_term_any(qc->ch)) + return 0; + + if (req_active && !ossl_quic_channel_is_active(qc->ch)) + return 0; + + return 1; +} + +/* + * QUIC Front-End I/O API: Initialization + * ====================================== + * + * SSL_new => ossl_quic_new + * ossl_quic_init + * SSL_reset => ossl_quic_reset + * SSL_clear => ossl_quic_clear + * ossl_quic_deinit + * SSL_free => ossl_quic_free + * + * SSL_set_options => ossl_quic_set_options + * SSL_get_options => ossl_quic_get_options + * SSL_clear_options => ossl_quic_clear_options + * + */ + +/* SSL_new */ +SSL *ossl_quic_new(SSL_CTX *ctx) +{ + QUIC_CONNECTION *qc = NULL; + SSL *ssl_base = NULL; + SSL_CONNECTION *sc = NULL; + + qc = OPENSSL_zalloc(sizeof(*qc)); + if (qc == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL); + return NULL; + } +#if defined(OPENSSL_THREADS) + if ((qc->mutex = ossl_crypto_mutex_new()) == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL); + goto err; + } +#endif + + /* Initialise the QUIC_CONNECTION's stub header. */ + ssl_base = &qc->ssl; + if (!ossl_ssl_init(ssl_base, ctx, ctx->method, SSL_TYPE_QUIC_CONNECTION)) { + ssl_base = NULL; + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + goto err; + } + + qc->tls = ossl_ssl_connection_new_int(ctx, TLS_method()); + if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + goto err; + } + + /* override the user_ssl of the inner connection */ + sc->s3.flags |= TLS1_FLAGS_QUIC; + + /* Restrict options derived from the SSL_CTX. */ + sc->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN; + sc->pha_enabled = 0; + +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + qc->is_thread_assisted + = (ssl_base->method == OSSL_QUIC_client_thread_method()); +#endif + + qc->as_server = 0; /* TODO(QUIC SERVER): add server support */ + qc->as_server_state = qc->as_server; + + qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI; + qc->default_ssl_mode = qc->ssl.ctx->mode; + qc->default_ssl_options = qc->ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS; + qc->desires_blocking = 1; + qc->blocking = 0; + qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO; + qc->last_error = SSL_ERROR_NONE; + + if (!create_channel(qc)) + goto err; + + ossl_quic_channel_set_msg_callback(qc->ch, ctx->msg_callback, ssl_base); + ossl_quic_channel_set_msg_callback_arg(qc->ch, ctx->msg_callback_arg); + + qc_update_reject_policy(qc); + + /* + * We do not create the default XSO yet. The reason for this is that the + * stream ID of the default XSO will depend on whether the stream is client + * or server-initiated, which depends on who transmits first. Since we do + * not know whether the application will be using a client-transmits-first + * or server-transmits-first protocol, we defer default XSO creation until + * the client calls SSL_read() or SSL_write(). If it calls SSL_read() first, + * we take that as a cue that the client is expecting a server-initiated + * stream, and vice versa if SSL_write() is called first. + */ + return ssl_base; + +err: + if (ssl_base == NULL) { +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_free(qc->mutex); +#endif + OPENSSL_free(qc); + } else { + SSL_free(ssl_base); + } + return NULL; +} + +/* SSL_free */ +QUIC_TAKES_LOCK +void ossl_quic_free(SSL *s) +{ + QCTX ctx; + int is_default; + + /* We should never be called on anything but a QSO. */ + if (!expect_quic(s, &ctx)) + return; + + quic_lock(ctx.qc); + + if (ctx.is_stream) { + /* + * When a QSSO is freed, the XSO is freed immediately, because the XSO + * itself only contains API personality layer data. However the + * underlying QUIC_STREAM is not freed immediately but is instead marked + * as deleted for later collection. + */ + + assert(ctx.qc->num_xso > 0); + --ctx.qc->num_xso; + + /* If a stream's send part has not been finished, auto-reset it. */ + if (( ctx.xso->stream->send_state == QUIC_SSTREAM_STATE_READY + || ctx.xso->stream->send_state == QUIC_SSTREAM_STATE_SEND) + && !ossl_quic_sstream_get_final_size(ctx.xso->stream->sstream, NULL)) + ossl_quic_stream_map_reset_stream_send_part(ossl_quic_channel_get_qsm(ctx.qc->ch), + ctx.xso->stream, 0); + + /* Do STOP_SENDING for the receive part, if applicable. */ + if ( ctx.xso->stream->recv_state == QUIC_RSTREAM_STATE_RECV + || ctx.xso->stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN) + ossl_quic_stream_map_stop_sending_recv_part(ossl_quic_channel_get_qsm(ctx.qc->ch), + ctx.xso->stream, 0); + + /* Update stream state. */ + ctx.xso->stream->deleted = 1; + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(ctx.qc->ch), + ctx.xso->stream); + + is_default = (ctx.xso == ctx.qc->default_xso); + quic_unlock(ctx.qc); + + /* + * Unref the connection in most cases; the XSO has a ref to the QC and + * not vice versa. But for a default XSO, to avoid circular references, + * the QC refs the XSO but the XSO does not ref the QC. If we are the + * default XSO, we only get here when the QC is being torn down anyway, + * so don't call SSL_free(qc) as we are already in it. + */ + if (!is_default) + SSL_free(&ctx.qc->ssl); + + /* Note: SSL_free calls OPENSSL_free(xso) for us */ + return; + } + + /* + * Free the default XSO, if any. The QUIC_STREAM is not deleted at this + * stage, but is freed during the channel free when the whole QSM is freed. + */ + if (ctx.qc->default_xso != NULL) { + QUIC_XSO *xso = ctx.qc->default_xso; + + quic_unlock(ctx.qc); + SSL_free(&xso->ssl); + quic_lock(ctx.qc); + ctx.qc->default_xso = NULL; + } + + /* Ensure we have no remaining XSOs. */ + assert(ctx.qc->num_xso == 0); + +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + if (ctx.qc->is_thread_assisted && ctx.qc->started) { + ossl_quic_thread_assist_wait_stopped(&ctx.qc->thread_assist); + ossl_quic_thread_assist_cleanup(&ctx.qc->thread_assist); + } +#endif + + ossl_quic_channel_free(ctx.qc->ch); + + BIO_free_all(ctx.qc->net_rbio); + BIO_free_all(ctx.qc->net_wbio); + + /* Note: SSL_free calls OPENSSL_free(qc) for us */ + + SSL_free(ctx.qc->tls); + quic_unlock(ctx.qc); /* tsan doesn't like freeing locked mutexes */ +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_free(&ctx.qc->mutex); +#endif +} + +/* SSL method init */ +int ossl_quic_init(SSL *s) +{ + /* Same op as SSL_clear, forward the call. */ + return ossl_quic_clear(s); +} + +/* SSL method deinit */ +void ossl_quic_deinit(SSL *s) +{ + /* No-op. */ +} + +/* SSL_clear (ssl_reset method) */ +int ossl_quic_reset(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED); + return 0; +} + +/* ssl_clear method (unused) */ +int ossl_quic_clear(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED); + return 0; +} + +int ossl_quic_conn_set_override_now_cb(SSL *s, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + ctx.qc->override_now_cb = now_cb; + ctx.qc->override_now_cb_arg = now_cb_arg; + + quic_unlock(ctx.qc); + return 1; +} + +void ossl_quic_conn_force_assist_thread_wake(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return; + +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + if (ctx.qc->is_thread_assisted && ctx.qc->started) + ossl_quic_thread_assist_notify_deadline_changed(&ctx.qc->thread_assist); +#endif +} + +QUIC_NEEDS_LOCK +static void qc_touch_default_xso(QUIC_CONNECTION *qc) +{ + qc->default_xso_created = 1; + qc_update_reject_policy(qc); +} + +/* + * Changes default XSO. Allows caller to keep reference to the old default XSO + * (if any). Reference to new XSO is transferred from caller. + */ +QUIC_NEEDS_LOCK +static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso, + int touch, + QUIC_XSO **old_xso) +{ + int refs; + + *old_xso = NULL; + + if (qc->default_xso != xso) { + *old_xso = qc->default_xso; /* transfer old XSO ref to caller */ + + qc->default_xso = xso; + + if (xso == NULL) { + /* + * Changing to not having a default XSO. XSO becomes standalone and + * now has a ref to the QC. + */ + if (!ossl_assert(SSL_up_ref(&qc->ssl))) + return; + } else { + /* + * Changing from not having a default XSO to having one. The new XSO + * will have had a reference to the QC we need to drop to avoid a + * circular reference. + * + * Currently we never change directly from one default XSO to + * another, though this function would also still be correct if this + * weren't the case. + */ + assert(*old_xso == NULL); + + CRYPTO_DOWN_REF(&qc->ssl.references, &refs); + assert(refs > 0); + } + } + + if (touch) + qc_touch_default_xso(qc); +} + +/* + * Changes default XSO, releasing the reference to any previous default XSO. + * Reference to new XSO is transferred from caller. + */ +QUIC_NEEDS_LOCK +static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch) +{ + QUIC_XSO *old_xso = NULL; + + qc_set_default_xso_keep_ref(qc, xso, touch, &old_xso); + + if (old_xso != NULL) + SSL_free(&old_xso->ssl); +} + +QUIC_NEEDS_LOCK +static void xso_update_options(QUIC_XSO *xso) +{ + int cleanse = ((xso->ssl_options & SSL_OP_CLEANSE_PLAINTEXT) != 0); + + if (xso->stream->rstream != NULL) + ossl_quic_rstream_set_cleanse(xso->stream->rstream, cleanse); + + if (xso->stream->sstream != NULL) + ossl_quic_sstream_set_cleanse(xso->stream->sstream, cleanse); +} + +/* + * SSL_set_options + * --------------- + * + * Setting options on a QCSO + * - configures the handshake-layer options; + * - configures the default data-plane options for new streams; + * - configures the data-plane options on the default XSO, if there is one. + * + * Setting options on a QSSO + * - configures data-plane options for that stream only. + */ +QUIC_TAKES_LOCK +static uint64_t quic_mask_or_options(SSL *ssl, uint64_t mask_value, uint64_t or_value) +{ + QCTX ctx; + uint64_t hs_mask_value, hs_or_value, ret; + + if (!expect_quic(ssl, &ctx)) + return 0; + + quic_lock(ctx.qc); + + if (!ctx.is_stream) { + /* + * If we were called on the connection, we apply any handshake option + * changes. + */ + hs_mask_value = (mask_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN); + hs_or_value = (or_value & OSSL_QUIC_PERMITTED_OPTIONS_CONN); + + SSL_clear_options(ctx.qc->tls, hs_mask_value); + SSL_set_options(ctx.qc->tls, hs_or_value); + + /* Update defaults for new streams. */ + ctx.qc->default_ssl_options + = ((ctx.qc->default_ssl_options & ~mask_value) | or_value) + & OSSL_QUIC_PERMITTED_OPTIONS; + } + + if (ctx.xso != NULL) { + ctx.xso->ssl_options + = ((ctx.xso->ssl_options & ~mask_value) | or_value) + & OSSL_QUIC_PERMITTED_OPTIONS_STREAM; + + xso_update_options(ctx.xso); + } + + ret = ctx.is_stream ? ctx.xso->ssl_options : ctx.qc->default_ssl_options; + + quic_unlock(ctx.qc); + return ret; +} + +uint64_t ossl_quic_set_options(SSL *ssl, uint64_t options) +{ + return quic_mask_or_options(ssl, 0, options); +} + +/* SSL_clear_options */ +uint64_t ossl_quic_clear_options(SSL *ssl, uint64_t options) +{ + return quic_mask_or_options(ssl, options, 0); +} + +/* SSL_get_options */ +uint64_t ossl_quic_get_options(const SSL *ssl) +{ + return quic_mask_or_options((SSL *)ssl, 0, 0); +} + +/* + * QUIC Front-End I/O API: Network BIO Configuration + * ================================================= + * + * Handling the different BIOs is difficult: + * + * - It is more or less a requirement that we use non-blocking network I/O; + * we need to be able to have timeouts on recv() calls, and make best effort + * (non blocking) send() and recv() calls. + * + * The only sensible way to do this is to configure the socket into + * non-blocking mode. We could try to do select() before calling send() or + * recv() to get a guarantee that the call will not block, but this will + * probably run into issues with buggy OSes which generate spurious socket + * readiness events. In any case, relying on this to work reliably does not + * seem sane. + * + * Timeouts could be handled via setsockopt() socket timeout options, but + * this depends on OS support and adds another syscall to every network I/O + * operation. It also has obvious thread safety concerns if we want to move + * to concurrent use of a single socket at some later date. + * + * Some OSes support a MSG_DONTWAIT flag which allows a single I/O option to + * be made non-blocking. However some OSes (e.g. Windows) do not support + * this, so we cannot rely on this. + * + * As such, we need to configure any FD in non-blocking mode. This may + * confound users who pass a blocking socket to libssl. However, in practice + * it would be extremely strange for a user of QUIC to pass an FD to us, + * then also try and send receive traffic on the same socket(!). Thus the + * impact of this should be limited, and can be documented. + * + * - We support both blocking and non-blocking operation in terms of the API + * presented to the user. One prospect is to set the blocking mode based on + * whether the socket passed to us was already in blocking mode. However, + * Windows has no API for determining if a socket is in blocking mode (!), + * therefore this cannot be done portably. Currently therefore we expose an + * explicit API call to set this, and default to blocking mode. + * + * - We need to determine our initial destination UDP address. The "natural" + * way for a user to do this is to set the peer variable on a BIO_dgram. + * However, this has problems because BIO_dgram's peer variable is used for + * both transmission and reception. This means it can be constantly being + * changed to a malicious value (e.g. if some random unrelated entity on the + * network starts sending traffic to us) on every read call. This is not a + * direct issue because we use the 'stateless' BIO_sendmmsg and BIO_recvmmsg + * calls only, which do not use this variable. However, we do need to let + * the user specify the peer in a 'normal' manner. The compromise here is + * that we grab the current peer value set at the time the write BIO is set + * and do not read the value again. + * + * - We also need to support memory BIOs (e.g. BIO_dgram_pair) or custom BIOs. + * Currently we do this by only supporting non-blocking mode. + * + */ + +/* + * Determines what initial destination UDP address we should use, if possible. + * If this fails the client must set the destination address manually, or use a + * BIO which does not need a destination address. + */ +static int csm_analyse_init_peer_addr(BIO *net_wbio, BIO_ADDR *peer) +{ + if (BIO_dgram_detect_peer_addr(net_wbio, peer) <= 0) + return 0; + + return 1; +} + +static int qc_can_support_blocking_cached(QUIC_CONNECTION *qc) +{ + QUIC_REACTOR *rtor = ossl_quic_channel_get_reactor(qc->ch); + + return ossl_quic_reactor_can_poll_r(rtor) + && ossl_quic_reactor_can_poll_w(rtor); +} + +static void qc_update_can_support_blocking(QUIC_CONNECTION *qc) +{ + ossl_quic_channel_update_poll_descriptors(qc->ch); /* best effort */ +} + +static void qc_update_blocking_mode(QUIC_CONNECTION *qc) +{ + qc->blocking = qc->desires_blocking && qc_can_support_blocking_cached(qc); +} + +void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_rbio) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return; + + if (ctx.qc->net_rbio == net_rbio) + return; + + if (!ossl_quic_channel_set_net_rbio(ctx.qc->ch, net_rbio)) + return; + + BIO_free_all(ctx.qc->net_rbio); + ctx.qc->net_rbio = net_rbio; + + if (net_rbio != NULL) + BIO_set_nbio(net_rbio, 1); /* best effort autoconfig */ + + /* + * Determine if the current pair of read/write BIOs now set allows blocking + * mode to be supported. + */ + qc_update_can_support_blocking(ctx.qc); + qc_update_blocking_mode(ctx.qc); +} + +void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return; + + if (ctx.qc->net_wbio == net_wbio) + return; + + if (!ossl_quic_channel_set_net_wbio(ctx.qc->ch, net_wbio)) + return; + + BIO_free_all(ctx.qc->net_wbio); + ctx.qc->net_wbio = net_wbio; + + if (net_wbio != NULL) + BIO_set_nbio(net_wbio, 1); /* best effort autoconfig */ + + /* + * Determine if the current pair of read/write BIOs now set allows blocking + * mode to be supported. + */ + qc_update_can_support_blocking(ctx.qc); + qc_update_blocking_mode(ctx.qc); +} + +BIO *ossl_quic_conn_get_net_rbio(const SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return NULL; + + return ctx.qc->net_rbio; +} + +BIO *ossl_quic_conn_get_net_wbio(const SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return NULL; + + return ctx.qc->net_wbio; +} + +int ossl_quic_conn_get_blocking_mode(const SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + if (ctx.is_stream) + return xso_blocking_mode(ctx.xso); + + return qc_blocking_mode(ctx.qc); +} + +QUIC_TAKES_LOCK +int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking) +{ + int ret = 0; + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + /* Sanity check - can we support the request given the current network BIO? */ + if (blocking) { + /* + * If called directly on a QCSO, update our information on network BIO + * capabilities. + */ + if (!ctx.is_stream) + qc_update_can_support_blocking(ctx.qc); + + /* Cannot enable blocking mode if we do not have pollable FDs. */ + if (!qc_can_support_blocking_cached(ctx.qc)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL); + goto out; + } + } + + if (!ctx.is_stream) + /* + * If called directly on a QCSO, update default and connection-level + * blocking modes. + */ + ctx.qc->desires_blocking = (blocking != 0); + + if (ctx.xso != NULL) { + /* + * If called on a QSSO or a QCSO with a default XSO, update the blocking + * mode. + */ + ctx.xso->desires_blocking = (blocking != 0); + ctx.xso->desires_blocking_set = 1; + } + + ret = 1; +out: + qc_update_blocking_mode(ctx.qc); + quic_unlock(ctx.qc); + return ret; +} + +int ossl_quic_conn_set_initial_peer_addr(SSL *s, + const BIO_ADDR *peer_addr) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + if (ctx.qc->started) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + NULL); + + if (peer_addr == NULL) { + BIO_ADDR_clear(&ctx.qc->init_peer_addr); + return 1; + } + + ctx.qc->init_peer_addr = *peer_addr; + return 1; +} + +/* + * QUIC Front-End I/O API: Asynchronous I/O Management + * =================================================== + * + * (BIO/)SSL_handle_events => ossl_quic_handle_events + * (BIO/)SSL_get_event_timeout => ossl_quic_get_event_timeout + * (BIO/)SSL_get_poll_fd => ossl_quic_get_poll_fd + * + */ + +/* Returns 1 if the connection is being used in blocking mode. */ +static int qc_blocking_mode(const QUIC_CONNECTION *qc) +{ + return qc->blocking; +} + +static int xso_blocking_mode(const QUIC_XSO *xso) +{ + if (xso->desires_blocking_set) + return xso->desires_blocking && qc_can_support_blocking_cached(xso->conn); + else + /* Only ever set if we can support blocking. */ + return xso->conn->blocking; +} + +/* SSL_handle_events; performs QUIC I/O and timeout processing. */ +QUIC_TAKES_LOCK +int ossl_quic_handle_events(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + quic_unlock(ctx.qc); + return 1; +} + +/* + * SSL_get_event_timeout. Get the time in milliseconds until the SSL object + * should next have events handled by the application by calling + * SSL_handle_events(). tv is set to 0 if the object should have events handled + * immediately. If no timeout is currently active, *is_infinite is set to 1 and + * the value of *tv is undefined. + */ +QUIC_TAKES_LOCK +int ossl_quic_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite) +{ + QCTX ctx; + OSSL_TIME deadline = ossl_time_infinite(); + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + deadline + = ossl_quic_reactor_get_tick_deadline(ossl_quic_channel_get_reactor(ctx.qc->ch)); + + if (ossl_time_is_infinite(deadline)) { + *is_infinite = 1; + + /* + * Robustness against faulty applications that don't check *is_infinite; + * harmless long timeout. + */ + tv->tv_sec = 1000000; + tv->tv_usec = 0; + + quic_unlock(ctx.qc); + return 1; + } + + *tv = ossl_time_to_timeval(ossl_time_subtract(deadline, get_time(ctx.qc))); + *is_infinite = 0; + quic_unlock(ctx.qc); + return 1; +} + +/* SSL_get_rpoll_descriptor */ +int ossl_quic_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + if (desc == NULL || ctx.qc->net_rbio == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, + NULL); + + return BIO_get_rpoll_descriptor(ctx.qc->net_rbio, desc); +} + +/* SSL_get_wpoll_descriptor */ +int ossl_quic_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + if (desc == NULL || ctx.qc->net_wbio == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, + NULL); + + return BIO_get_wpoll_descriptor(ctx.qc->net_wbio, desc); +} + +/* SSL_net_read_desired */ +QUIC_TAKES_LOCK +int ossl_quic_get_net_read_desired(SSL *s) +{ + QCTX ctx; + int ret; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + ret = ossl_quic_reactor_net_read_desired(ossl_quic_channel_get_reactor(ctx.qc->ch)); + quic_unlock(ctx.qc); + return ret; +} + +/* SSL_net_write_desired */ +QUIC_TAKES_LOCK +int ossl_quic_get_net_write_desired(SSL *s) +{ + int ret; + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + ret = ossl_quic_reactor_net_write_desired(ossl_quic_channel_get_reactor(ctx.qc->ch)); + quic_unlock(ctx.qc); + return ret; +} + +/* + * QUIC Front-End I/O API: Connection Lifecycle Operations + * ======================================================= + * + * SSL_do_handshake => ossl_quic_do_handshake + * SSL_set_connect_state => ossl_quic_set_connect_state + * SSL_set_accept_state => ossl_quic_set_accept_state + * SSL_shutdown => ossl_quic_shutdown + * SSL_ctrl => ossl_quic_ctrl + * (BIO/)SSL_connect => ossl_quic_connect + * (BIO/)SSL_accept => ossl_quic_accept + * + */ + +QUIC_NEEDS_LOCK +static void qc_shutdown_flush_init(QUIC_CONNECTION *qc) +{ + QUIC_STREAM_MAP *qsm; + + if (qc->shutting_down) + return; + + qsm = ossl_quic_channel_get_qsm(qc->ch); + + ossl_quic_stream_map_begin_shutdown_flush(qsm); + qc->shutting_down = 1; +} + +/* Returns 1 if all shutdown-flush streams have been done with. */ +QUIC_NEEDS_LOCK +static int qc_shutdown_flush_finished(QUIC_CONNECTION *qc) +{ + QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(qc->ch); + + return qc->shutting_down + && ossl_quic_stream_map_is_shutdown_flush_finished(qsm); +} + +/* SSL_shutdown */ +static int quic_shutdown_wait(void *arg) +{ + QUIC_CONNECTION *qc = arg; + + return ossl_quic_channel_is_terminated(qc->ch); +} + +/* Returns 1 if shutdown flush process has finished or is inapplicable. */ +static int quic_shutdown_flush_wait(void *arg) +{ + QUIC_CONNECTION *qc = arg; + + return ossl_quic_channel_is_term_any(qc->ch) + || qc_shutdown_flush_finished(qc); +} + +static int quic_shutdown_peer_wait(void *arg) +{ + QUIC_CONNECTION *qc = arg; + return ossl_quic_channel_is_term_any(qc->ch); +} + +QUIC_TAKES_LOCK +int ossl_quic_conn_shutdown(SSL *s, uint64_t flags, + const SSL_SHUTDOWN_EX_ARGS *args, + size_t args_len) +{ + int ret; + QCTX ctx; + int stream_flush = ((flags & SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH) == 0); + int no_block = ((flags & SSL_SHUTDOWN_FLAG_NO_BLOCK) != 0); + int wait_peer = ((flags & SSL_SHUTDOWN_FLAG_WAIT_PEER) != 0); + + if (!expect_quic(s, &ctx)) + return -1; + + if (ctx.is_stream) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_CONN_USE_ONLY, NULL); + return -1; + } + + quic_lock(ctx.qc); + + if (ossl_quic_channel_is_terminated(ctx.qc->ch)) { + quic_unlock(ctx.qc); + return 1; + } + + /* Phase 1: Stream Flushing */ + if (!wait_peer && stream_flush) { + qc_shutdown_flush_init(ctx.qc); + + if (!qc_shutdown_flush_finished(ctx.qc)) { + if (!no_block && qc_blocking_mode(ctx.qc)) { + ret = block_until_pred(ctx.qc, quic_shutdown_flush_wait, ctx.qc, 0); + if (ret < 1) { + ret = 0; + goto err; + } + } else { + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + } + } + + if (!qc_shutdown_flush_finished(ctx.qc)) { + quic_unlock(ctx.qc); + return 0; /* ongoing */ + } + } + + /* Phase 2: Connection Closure */ + if (wait_peer && !ossl_quic_channel_is_term_any(ctx.qc->ch)) { + if (!no_block && qc_blocking_mode(ctx.qc)) { + ret = block_until_pred(ctx.qc, quic_shutdown_peer_wait, ctx.qc, 0); + if (ret < 1) { + ret = 0; + goto err; + } + } else { + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + } + + if (!ossl_quic_channel_is_term_any(ctx.qc->ch)) { + ret = 0; /* peer hasn't closed yet - still not done */ + goto err; + } + + /* + * We are at least terminating - go through the normal process of + * waiting until we are in the TERMINATED state. + */ + } + + /* Block mutation ops regardless of if we did stream flush. */ + ctx.qc->shutting_down = 1; + + /* + * This call is a no-op if we are already terminating, so it doesn't + * affect the wait_peer case. + */ + ossl_quic_channel_local_close(ctx.qc->ch, + args != NULL ? args->quic_error_code : 0, + args != NULL ? args->quic_reason : NULL); + + SSL_set_shutdown(ctx.qc->tls, SSL_SENT_SHUTDOWN); + + if (ossl_quic_channel_is_terminated(ctx.qc->ch)) { + quic_unlock(ctx.qc); + return 1; + } + + /* Phase 3: Terminating Wait Time */ + if (!no_block && qc_blocking_mode(ctx.qc) + && (flags & SSL_SHUTDOWN_FLAG_RAPID) == 0) { + ret = block_until_pred(ctx.qc, quic_shutdown_wait, ctx.qc, 0); + if (ret < 1) { + ret = 0; + goto err; + } + } else { + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + } + + ret = ossl_quic_channel_is_terminated(ctx.qc->ch); +err: + quic_unlock(ctx.qc); + return ret; +} + +/* SSL_ctrl */ +long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + switch (cmd) { + case SSL_CTRL_MODE: + /* If called on a QCSO, update the default mode. */ + if (!ctx.is_stream) + ctx.qc->default_ssl_mode |= (uint32_t)larg; + + /* + * If we were called on a QSSO or have a default stream, we also update + * that. + */ + if (ctx.xso != NULL) { + /* Cannot enable EPW while AON write in progress. */ + if (ctx.xso->aon_write_in_progress) + larg &= ~SSL_MODE_ENABLE_PARTIAL_WRITE; + + ctx.xso->ssl_mode |= (uint32_t)larg; + return ctx.xso->ssl_mode; + } + + return ctx.qc->default_ssl_mode; + case SSL_CTRL_CLEAR_MODE: + if (!ctx.is_stream) + ctx.qc->default_ssl_mode &= ~(uint32_t)larg; + + if (ctx.xso != NULL) { + ctx.xso->ssl_mode &= ~(uint32_t)larg; + return ctx.xso->ssl_mode; + } + + return ctx.qc->default_ssl_mode; + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ossl_quic_channel_set_msg_callback_arg(ctx.qc->ch, parg); + /* This ctrl also needs to be passed to the internal SSL object */ + return SSL_ctrl(ctx.qc->tls, cmd, larg, parg); + + case DTLS_CTRL_GET_TIMEOUT: /* DTLSv1_get_timeout */ + { + int is_infinite; + + if (!ossl_quic_get_event_timeout(s, parg, &is_infinite)) + return 0; + + return !is_infinite; + } + case DTLS_CTRL_HANDLE_TIMEOUT: /* DTLSv1_handle_timeout */ + /* For legacy compatibility with DTLS calls. */ + return ossl_quic_handle_events(s) == 1 ? 1 : -1; + + /* Mask ctrls we shouldn't support for QUIC. */ + case SSL_CTRL_GET_READ_AHEAD: + case SSL_CTRL_SET_READ_AHEAD: + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: + case SSL_CTRL_SET_MAX_PIPELINES: + return 0; + + default: + /* + * Probably a TLS related ctrl. Send back to the frontend SSL_ctrl + * implementation. Either SSL_ctrl will handle it itself by direct + * access into handshake layer state, or failing that, it will be passed + * to the handshake layer via the SSL_METHOD vtable. If the ctrl is not + * supported by anything, the handshake layer's ctrl method will finally + * return 0. + */ + return ossl_ctrl_internal(&ctx.qc->ssl, cmd, larg, parg, /*no_quic=*/1); + } +} + +/* SSL_set_connect_state */ +void ossl_quic_set_connect_state(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return; + + /* Cannot be changed after handshake started */ + if (ctx.qc->started || ctx.is_stream) + return; + + ctx.qc->as_server_state = 0; +} + +/* SSL_set_accept_state */ +void ossl_quic_set_accept_state(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return; + + /* Cannot be changed after handshake started */ + if (ctx.qc->started || ctx.is_stream) + return; + + ctx.qc->as_server_state = 1; +} + +/* SSL_do_handshake */ +struct quic_handshake_wait_args { + QUIC_CONNECTION *qc; +}; + +static int tls_wants_non_io_retry(QUIC_CONNECTION *qc) +{ + int want = SSL_want(qc->tls); + + if (want == SSL_X509_LOOKUP + || want == SSL_CLIENT_HELLO_CB + || want == SSL_RETRY_VERIFY) + return 1; + + return 0; +} + +static int quic_handshake_wait(void *arg) +{ + struct quic_handshake_wait_args *args = arg; + + if (!quic_mutation_allowed(args->qc, /*req_active=*/1)) + return -1; + + if (ossl_quic_channel_is_handshake_complete(args->qc->ch)) + return 1; + + if (tls_wants_non_io_retry(args->qc)) + return 1; + + return 0; +} + +static int configure_channel(QUIC_CONNECTION *qc) +{ + assert(qc->ch != NULL); + + if (!ossl_quic_channel_set_net_rbio(qc->ch, qc->net_rbio) + || !ossl_quic_channel_set_net_wbio(qc->ch, qc->net_wbio) + || !ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr)) + return 0; + + return 1; +} + +QUIC_NEEDS_LOCK +static int create_channel(QUIC_CONNECTION *qc) +{ + QUIC_CHANNEL_ARGS args = {0}; + + args.libctx = qc->ssl.ctx->libctx; + args.propq = qc->ssl.ctx->propq; + args.is_server = qc->as_server; + args.tls = qc->tls; + args.mutex = qc->mutex; + args.now_cb = get_time_cb; + args.now_cb_arg = qc; + + qc->ch = ossl_quic_channel_new(&args); + if (qc->ch == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + return 0; + } + + return 1; +} + +/* + * Configures a channel with the information we have accumulated via calls made + * to us from the application prior to starting a handshake attempt. + */ +QUIC_NEEDS_LOCK +static int ensure_channel_started(QCTX *ctx) +{ + QUIC_CONNECTION *qc = ctx->qc; + + if (!qc->started) { + if (!configure_channel(qc)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, + "failed to configure channel"); + return 0; + } + + if (!ossl_quic_channel_start(qc->ch)) { + ossl_quic_channel_restore_err_state(qc->ch); + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, + "failed to start channel"); + return 0; + } + +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + if (qc->is_thread_assisted) + if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch, + qc->override_now_cb, + qc->override_now_cb_arg)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, + "failed to start assist thread"); + return 0; + } +#endif + } + + qc->started = 1; + return 1; +} + +QUIC_NEEDS_LOCK +static int quic_do_handshake(QCTX *ctx) +{ + int ret; + QUIC_CONNECTION *qc = ctx->qc; + + if (ossl_quic_channel_is_handshake_complete(qc->ch)) + /* Handshake already completed. */ + return 1; + + if (!quic_mutation_allowed(qc, /*req_active=*/0)) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + + if (qc->as_server != qc->as_server_state) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL); + return -1; /* Non-protocol error */ + } + + if (qc->net_rbio == NULL || qc->net_wbio == NULL) { + /* Need read and write BIOs. */ + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_BIO_NOT_SET, NULL); + return -1; /* Non-protocol error */ + } + + /* + * We need to determine our addressing mode. There are basically two + * ways we can use L4 addresses: + * + * - Addressed mode, in which our BIO_sendmmsg calls have destination + * addresses attached to them which we expect the underlying network BIO + * to handle; + * + * - Unaddressed mode, in which the BIO provided to us on the + * network side neither provides us with L4 addresses nor is capable of + * honouring ones we provide. We don't know where the QUIC traffic we + * send ends up exactly and trust the application to know what it is + * doing. + * + * Addressed mode is preferred because it enables support for connection + * migration, multipath, etc. in the future. Addressed mode is automatically + * enabled if we are using e.g. BIO_s_datagram, with or without + * BIO_s_connect. + * + * If we are passed a BIO_s_dgram_pair (or some custom BIO) we may have to + * use unaddressed mode unless that BIO supports capability flags indicating + * it can provide and honour L4 addresses. + * + * Our strategy for determining address mode is simple: we probe the + * underlying network BIOs for their capabilities. If the network BIOs + * support what we need, we use addressed mode. Otherwise, we use + * unaddressed mode. + * + * If addressed mode is chosen, we require an initial peer address to be + * set. If this is not set, we fail. If unaddressed mode is used, we do not + * require this, as such an address is superfluous, though it can be set if + * desired. + */ + if (!qc->started && !qc->addressing_probe_done) { + long rcaps = BIO_dgram_get_effective_caps(qc->net_rbio); + long wcaps = BIO_dgram_get_effective_caps(qc->net_wbio); + + qc->addressed_mode_r = ((rcaps & BIO_DGRAM_CAP_PROVIDES_SRC_ADDR) != 0); + qc->addressed_mode_w = ((wcaps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) != 0); + qc->addressing_probe_done = 1; + } + + if (!qc->started && qc->addressed_mode_w + && BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) { + /* + * We are trying to connect and are using addressed mode, which means we + * need an initial peer address; if we do not have a peer address yet, + * we should try to autodetect one. + * + * We do this as late as possible because some BIOs (e.g. BIO_s_connect) + * may not be able to provide us with a peer address until they have + * finished their own processing. They may not be able to perform this + * processing until an application has finished configuring that BIO + * (e.g. with setter calls), which might happen after SSL_set_bio is + * called. + */ + if (!csm_analyse_init_peer_addr(qc->net_wbio, &qc->init_peer_addr)) + /* best effort */ + BIO_ADDR_clear(&qc->init_peer_addr); + else + ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr); + } + + if (!qc->started + && qc->addressed_mode_w + && BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) { + /* + * If we still don't have a peer address in addressed mode, we can't do + * anything. + */ + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET, NULL); + return -1; /* Non-protocol error */ + } + + /* + * Start connection process. Note we may come here multiple times in + * non-blocking mode, which is fine. + */ + if (!ensure_channel_started(ctx)) /* raises on failure */ + return -1; /* Non-protocol error */ + + if (ossl_quic_channel_is_handshake_complete(qc->ch)) + /* The handshake is now done. */ + return 1; + + if (!qc_blocking_mode(qc)) { + /* Try to advance the reactor. */ + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); + + if (ossl_quic_channel_is_handshake_complete(qc->ch)) + /* The handshake is now done. */ + return 1; + + if (ossl_quic_channel_is_term_any(qc->ch)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return 0; + } else if (qc->desires_blocking) { + /* + * As a special case when doing a handshake when blocking mode is + * desired yet not available, see if the network BIOs have become + * poll descriptor-enabled. This supports BIOs such as BIO_s_connect + * which do late creation of socket FDs and therefore cannot expose + * a poll descriptor until after a network BIO is set on the QCSO. + */ + assert(!qc->blocking); + qc_update_can_support_blocking(qc); + qc_update_blocking_mode(qc); + } + } + + /* + * We are either in blocking mode or just entered it due to the code above. + */ + if (qc_blocking_mode(qc)) { + /* In blocking mode, wait for the handshake to complete. */ + struct quic_handshake_wait_args args; + + args.qc = qc; + + ret = block_until_pred(qc, quic_handshake_wait, &args, 0); + if (!quic_mutation_allowed(qc, /*req_active=*/1)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return 0; /* Shutdown before completion */ + } else if (ret <= 0) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + return -1; /* Non-protocol error */ + } + + if (tls_wants_non_io_retry(qc)) { + QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0)); + return -1; + } + + assert(ossl_quic_channel_is_handshake_complete(qc->ch)); + return 1; + } + + if (tls_wants_non_io_retry(qc)) { + QUIC_RAISE_NORMAL_ERROR(ctx, SSL_get_error(qc->tls, 0)); + return -1; + } + + /* + * Otherwise, indicate that the handshake isn't done yet. + * We can only get here in non-blocking mode. + */ + QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); + return -1; /* Non-protocol error */ +} + +QUIC_TAKES_LOCK +int ossl_quic_do_handshake(SSL *s) +{ + int ret; + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock_for_io(&ctx); + + ret = quic_do_handshake(&ctx); + quic_unlock(ctx.qc); + return ret; +} + +/* SSL_connect */ +int ossl_quic_connect(SSL *s) +{ + /* Ensure we are in connect state (no-op if non-idle). */ + ossl_quic_set_connect_state(s); + + /* Begin or continue the handshake */ + return ossl_quic_do_handshake(s); +} + +/* SSL_accept */ +int ossl_quic_accept(SSL *s) +{ + /* Ensure we are in accept state (no-op if non-idle). */ + ossl_quic_set_accept_state(s); + + /* Begin or continue the handshake */ + return ossl_quic_do_handshake(s); +} + +/* + * QUIC Front-End I/O API: Stream Lifecycle Operations + * =================================================== + * + * SSL_stream_new => ossl_quic_conn_stream_new + * + */ + +/* + * Try to create the default XSO if it doesn't already exist. Returns 1 if the + * default XSO was created. Returns 0 if it was not (e.g. because it already + * exists). Note that this is NOT an error condition. + */ +QUIC_NEEDS_LOCK +static int qc_try_create_default_xso_for_write(QCTX *ctx) +{ + uint64_t flags = 0; + QUIC_CONNECTION *qc = ctx->qc; + + if (qc->default_xso_created + || qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE) + /* + * We only do this once. If the user detaches a previously created + * default XSO we don't auto-create another one. + */ + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL); + + /* Create a locally-initiated stream. */ + if (qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_AUTO_UNI) + flags |= SSL_STREAM_FLAG_UNI; + + qc_set_default_xso(qc, (QUIC_XSO *)quic_conn_stream_new(ctx, flags, + /*needs_lock=*/0), + /*touch=*/0); + if (qc->default_xso == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + + qc_touch_default_xso(qc); + return 1; +} + +struct quic_wait_for_stream_args { + QUIC_CONNECTION *qc; + QUIC_STREAM *qs; + QCTX *ctx; + uint64_t expect_id; +}; + +QUIC_NEEDS_LOCK +static int quic_wait_for_stream(void *arg) +{ + struct quic_wait_for_stream_args *args = arg; + + if (!quic_mutation_allowed(args->qc, /*req_active=*/1)) { + /* If connection is torn down due to an error while blocking, stop. */ + QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return -1; + } + + args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch), + args->expect_id | QUIC_STREAM_DIR_BIDI); + if (args->qs == NULL) + args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch), + args->expect_id | QUIC_STREAM_DIR_UNI); + + if (args->qs != NULL) + return 1; /* stream now exists */ + + return 0; /* did not get a stream, keep trying */ +} + +QUIC_NEEDS_LOCK +static int qc_wait_for_default_xso_for_read(QCTX *ctx) +{ + /* Called on a QCSO and we don't currently have a default stream. */ + uint64_t expect_id; + QUIC_CONNECTION *qc = ctx->qc; + QUIC_STREAM *qs; + int res; + struct quic_wait_for_stream_args wargs; + OSSL_RTT_INFO rtt_info; + + /* + * If default stream functionality is disabled or we already detached + * one, don't make another default stream and just fail. + */ + if (qc->default_xso_created + || qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL); + + /* + * The peer may have opened a stream since we last ticked. So tick and + * see if the stream with ordinal 0 (remote, bidi/uni based on stream + * mode) exists yet. QUIC stream IDs must be allocated in order, so the + * first stream created by a peer must have an ordinal of 0. + */ + expect_id = qc->as_server + ? QUIC_STREAM_INITIATOR_CLIENT + : QUIC_STREAM_INITIATOR_SERVER; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), + expect_id | QUIC_STREAM_DIR_BIDI); + if (qs == NULL) + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), + expect_id | QUIC_STREAM_DIR_UNI); + + if (qs == NULL) { + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0); + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), + expect_id); + } + + if (qs == NULL) { + if (!qc_blocking_mode(qc)) + /* Non-blocking mode, so just bail immediately. */ + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ); + + /* Block until we have a stream. */ + wargs.qc = qc; + wargs.qs = NULL; + wargs.ctx = ctx; + wargs.expect_id = expect_id; + + res = block_until_pred(qc, quic_wait_for_stream, &wargs, 0); + if (res == 0) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + else if (res < 0 || wargs.qs == NULL) + /* quic_wait_for_stream raised error here */ + return 0; + + qs = wargs.qs; + } + + /* + * We now have qs != NULL. Remove it from the incoming stream queue so that + * it isn't also returned by any future SSL_accept_stream calls. + */ + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(qc->ch), &rtt_info); + ossl_quic_stream_map_remove_from_accept_queue(ossl_quic_channel_get_qsm(qc->ch), + qs, rtt_info.smoothed_rtt); + + /* + * Now make qs the default stream, creating the necessary XSO. + */ + qc_set_default_xso(qc, create_xso_from_stream(qc, qs), /*touch=*/0); + if (qc->default_xso == NULL) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + + qc_touch_default_xso(qc); /* inhibits default XSO */ + return 1; +} + +QUIC_NEEDS_LOCK +static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs) +{ + QUIC_XSO *xso = NULL; + + if ((xso = OPENSSL_zalloc(sizeof(*xso))) == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL); + goto err; + } + + if (!ossl_ssl_init(&xso->ssl, qc->ssl.ctx, qc->ssl.method, SSL_TYPE_QUIC_XSO)) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + goto err; + } + + /* XSO refs QC */ + if (!SSL_up_ref(&qc->ssl)) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_SSL_LIB, NULL); + goto err; + } + + xso->conn = qc; + xso->ssl_mode = qc->default_ssl_mode; + xso->ssl_options + = qc->default_ssl_options & OSSL_QUIC_PERMITTED_OPTIONS_STREAM; + xso->last_error = SSL_ERROR_NONE; + + xso->stream = qs; + + ++qc->num_xso; + xso_update_options(xso); + return xso; + +err: + OPENSSL_free(xso); + return NULL; +} + +struct quic_new_stream_wait_args { + QUIC_CONNECTION *qc; + int is_uni; +}; + +static int quic_new_stream_wait(void *arg) +{ + struct quic_new_stream_wait_args *args = arg; + QUIC_CONNECTION *qc = args->qc; + + if (!quic_mutation_allowed(qc, /*req_active=*/1)) + return -1; + + if (ossl_quic_channel_is_new_local_stream_admissible(qc->ch, args->is_uni)) + return 1; + + return 0; +} + +/* locking depends on need_lock */ +static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock) +{ + int ret; + QUIC_CONNECTION *qc = ctx->qc; + QUIC_XSO *xso = NULL; + QUIC_STREAM *qs = NULL; + int is_uni = ((flags & SSL_STREAM_FLAG_UNI) != 0); + int no_blocking = ((flags & SSL_STREAM_FLAG_NO_BLOCK) != 0); + int advance = ((flags & SSL_STREAM_FLAG_ADVANCE) != 0); + + if (need_lock) + quic_lock(qc); + + if (!quic_mutation_allowed(qc, /*req_active=*/0)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + goto err; + } + + if (!advance + && !ossl_quic_channel_is_new_local_stream_admissible(qc->ch, is_uni)) { + struct quic_new_stream_wait_args args; + + /* + * Stream count flow control currently doesn't permit this stream to be + * opened. + */ + if (no_blocking || !qc_blocking_mode(qc)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_COUNT_LIMITED, NULL); + goto err; + } + + args.qc = qc; + args.is_uni = is_uni; + + /* Blocking mode - wait until we can get a stream. */ + ret = block_until_pred(ctx->qc, quic_new_stream_wait, &args, 0); + if (!quic_mutation_allowed(qc, /*req_active=*/1)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + goto err; /* Shutdown before completion */ + } else if (ret <= 0) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + goto err; /* Non-protocol error */ + } + } + + qs = ossl_quic_channel_new_stream_local(qc->ch, is_uni); + if (qs == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + goto err; + } + + xso = create_xso_from_stream(qc, qs); + if (xso == NULL) + goto err; + + qc_touch_default_xso(qc); /* inhibits default XSO */ + if (need_lock) + quic_unlock(qc); + + return &xso->ssl; + +err: + OPENSSL_free(xso); + ossl_quic_stream_map_release(ossl_quic_channel_get_qsm(qc->ch), qs); + if (need_lock) + quic_unlock(qc); + + return NULL; + +} + +QUIC_TAKES_LOCK +SSL *ossl_quic_conn_stream_new(SSL *s, uint64_t flags) +{ + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return NULL; + + return quic_conn_stream_new(&ctx, flags, /*need_lock=*/1); +} + +/* + * QUIC Front-End I/O API: Steady-State Operations + * =============================================== + * + * Here we dispatch calls to the steady-state front-end I/O API functions; that + * is, the functions used during the established phase of a QUIC connection + * (e.g. SSL_read, SSL_write). + * + * Each function must handle both blocking and non-blocking modes. As discussed + * above, all QUIC I/O is implemented using non-blocking mode internally. + * + * SSL_get_error => partially implemented by ossl_quic_get_error + * SSL_want => ossl_quic_want + * (BIO/)SSL_read => ossl_quic_read + * (BIO/)SSL_write => ossl_quic_write + * SSL_pending => ossl_quic_pending + * SSL_stream_conclude => ossl_quic_conn_stream_conclude + * SSL_key_update => ossl_quic_key_update + */ + +/* SSL_get_error */ +int ossl_quic_get_error(const SSL *s, int i) +{ + QCTX ctx; + int net_error, last_error; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + net_error = ossl_quic_channel_net_error(ctx.qc->ch); + last_error = ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error; + quic_unlock(ctx.qc); + + if (net_error) + return SSL_ERROR_SYSCALL; + + return last_error; +} + +/* Converts a code returned by SSL_get_error to a code returned by SSL_want. */ +static int error_to_want(int error) +{ + switch (error) { + case SSL_ERROR_WANT_CONNECT: /* never used - UDP is connectionless */ + case SSL_ERROR_WANT_ACCEPT: /* never used - UDP is connectionless */ + case SSL_ERROR_ZERO_RETURN: + default: + return SSL_NOTHING; + + case SSL_ERROR_WANT_READ: + return SSL_READING; + + case SSL_ERROR_WANT_WRITE: + return SSL_WRITING; + + case SSL_ERROR_WANT_RETRY_VERIFY: + return SSL_RETRY_VERIFY; + + case SSL_ERROR_WANT_CLIENT_HELLO_CB: + return SSL_CLIENT_HELLO_CB; + + case SSL_ERROR_WANT_X509_LOOKUP: + return SSL_X509_LOOKUP; + } +} + +/* SSL_want */ +int ossl_quic_want(const SSL *s) +{ + QCTX ctx; + int w; + + if (!expect_quic(s, &ctx)) + return SSL_NOTHING; + + quic_lock(ctx.qc); + + w = error_to_want(ctx.is_stream ? ctx.xso->last_error : ctx.qc->last_error); + + quic_unlock(ctx.qc); + return w; +} + +/* + * SSL_write + * --------- + * + * The set of functions below provide the implementation of the public SSL_write + * function. We must handle: + * + * - both blocking and non-blocking operation at the application level, + * depending on how we are configured; + * + * - SSL_MODE_ENABLE_PARTIAL_WRITE being on or off; + * + * - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER. + * + */ +QUIC_NEEDS_LOCK +static void quic_post_write(QUIC_XSO *xso, int did_append, int do_tick) +{ + /* + * We have appended at least one byte to the stream. + * Potentially mark stream as active, depending on FC. + */ + if (did_append) + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(xso->conn->ch), + xso->stream); + + /* + * Try and send. + * + * TODO(QUIC FUTURE): It is probably inefficient to try and do this + * immediately, plus we should eventually consider Nagle's algorithm. + */ + if (do_tick) + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(xso->conn->ch), 0); +} + +struct quic_write_again_args { + QUIC_XSO *xso; + const unsigned char *buf; + size_t len; + size_t total_written; + int err; +}; + +/* + * Absolute maximum write buffer size, enforced to prevent a rogue peer from + * deliberately inducing DoS. This has been chosen based on the optimal buffer + * size for an RTT of 500ms and a bandwidth of 100 Mb/s. + */ +#define MAX_WRITE_BUF_SIZE (6 * 1024 * 1024) + +/* + * Ensure spare buffer space available (up until a limit, at least). + */ +QUIC_NEEDS_LOCK +static int sstream_ensure_spare(QUIC_SSTREAM *sstream, uint64_t spare) +{ + size_t cur_sz = ossl_quic_sstream_get_buffer_size(sstream); + size_t avail = ossl_quic_sstream_get_buffer_avail(sstream); + size_t spare_ = (spare > SIZE_MAX) ? SIZE_MAX : (size_t)spare; + size_t new_sz, growth; + + if (spare_ <= avail || cur_sz == MAX_WRITE_BUF_SIZE) + return 1; + + growth = spare_ - avail; + if (cur_sz + growth > MAX_WRITE_BUF_SIZE) + new_sz = MAX_WRITE_BUF_SIZE; + else + new_sz = cur_sz + growth; + + return ossl_quic_sstream_set_buffer_size(sstream, new_sz); +} + +/* + * Append to a QUIC_STREAM's QUIC_SSTREAM, ensuring buffer space is expanded + * as needed according to flow control. + */ +QUIC_NEEDS_LOCK +static int xso_sstream_append(QUIC_XSO *xso, const unsigned char *buf, + size_t len, size_t *actual_written) +{ + QUIC_SSTREAM *sstream = xso->stream->sstream; + uint64_t cur = ossl_quic_sstream_get_cur_size(sstream); + uint64_t cwm = ossl_quic_txfc_get_cwm(&xso->stream->txfc); + uint64_t permitted = (cwm >= cur ? cwm - cur : 0); + + if (len > permitted) + len = (size_t)permitted; + + if (!sstream_ensure_spare(sstream, len)) + return 0; + + return ossl_quic_sstream_append(sstream, buf, len, actual_written); +} + +QUIC_NEEDS_LOCK +static int quic_write_again(void *arg) +{ + struct quic_write_again_args *args = arg; + size_t actual_written = 0; + + if (!quic_mutation_allowed(args->xso->conn, /*req_active=*/1)) + /* If connection is torn down due to an error while blocking, stop. */ + return -2; + + if (!quic_validate_for_write(args->xso, &args->err)) + /* + * Stream may have become invalid for write due to connection events + * while we blocked. + */ + return -2; + + args->err = ERR_R_INTERNAL_ERROR; + if (!xso_sstream_append(args->xso, args->buf, args->len, &actual_written)) + return -2; + + quic_post_write(args->xso, actual_written > 0, 0); + + args->buf += actual_written; + args->len -= actual_written; + args->total_written += actual_written; + + if (args->len == 0) + /* Written everything, done. */ + return 1; + + /* Not written everything yet, keep trying. */ + return 0; +} + +QUIC_NEEDS_LOCK +static int quic_write_blocking(QCTX *ctx, const void *buf, size_t len, + size_t *written) +{ + int res; + QUIC_XSO *xso = ctx->xso; + struct quic_write_again_args args; + size_t actual_written = 0; + + /* First make a best effort to append as much of the data as possible. */ + if (!xso_sstream_append(xso, buf, len, &actual_written)) { + /* Stream already finished or allocation error. */ + *written = 0; + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + } + + quic_post_write(xso, actual_written > 0, 1); + + if (actual_written == len) { + /* Managed to append everything on the first try. */ + *written = actual_written; + return 1; + } + + /* + * We did not manage to append all of the data immediately, so the stream + * buffer has probably filled up. This means we need to block until some of + * it is freed up. + */ + args.xso = xso; + args.buf = (const unsigned char *)buf + actual_written; + args.len = len - actual_written; + args.total_written = 0; + args.err = ERR_R_INTERNAL_ERROR; + + res = block_until_pred(xso->conn, quic_write_again, &args, 0); + if (res <= 0) { + if (!quic_mutation_allowed(xso->conn, /*req_active=*/1)) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + else + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, args.err, NULL); + } + + *written = args.total_written; + return 1; +} + +/* + * Functions to manage All-or-Nothing (AON) (that is, non-ENABLE_PARTIAL_WRITE) + * write semantics. + */ +static void aon_write_begin(QUIC_XSO *xso, const unsigned char *buf, + size_t buf_len, size_t already_sent) +{ + assert(!xso->aon_write_in_progress); + + xso->aon_write_in_progress = 1; + xso->aon_buf_base = buf; + xso->aon_buf_pos = already_sent; + xso->aon_buf_len = buf_len; +} + +static void aon_write_finish(QUIC_XSO *xso) +{ + xso->aon_write_in_progress = 0; + xso->aon_buf_base = NULL; + xso->aon_buf_pos = 0; + xso->aon_buf_len = 0; +} + +QUIC_NEEDS_LOCK +static int quic_write_nonblocking_aon(QCTX *ctx, const void *buf, + size_t len, size_t *written) +{ + QUIC_XSO *xso = ctx->xso; + const void *actual_buf; + size_t actual_len, actual_written = 0; + int accept_moving_buffer + = ((xso->ssl_mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) != 0); + + if (xso->aon_write_in_progress) { + /* + * We are in the middle of an AON write (i.e., a previous write did not + * manage to append all data to the SSTREAM and we have Enable Partial + * Write (EPW) mode disabled.) + */ + if ((!accept_moving_buffer && xso->aon_buf_base != buf) + || len != xso->aon_buf_len) + /* + * Pointer must not have changed if we are not in accept moving + * buffer mode. Length must never change. + */ + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_BAD_WRITE_RETRY, NULL); + + actual_buf = (unsigned char *)buf + xso->aon_buf_pos; + actual_len = len - xso->aon_buf_pos; + assert(actual_len > 0); + } else { + actual_buf = buf; + actual_len = len; + } + + /* First make a best effort to append as much of the data as possible. */ + if (!xso_sstream_append(xso, actual_buf, actual_len, &actual_written)) { + /* Stream already finished or allocation error. */ + *written = 0; + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + } + + quic_post_write(xso, actual_written > 0, 1); + + if (actual_written == actual_len) { + /* We have sent everything. */ + if (xso->aon_write_in_progress) { + /* + * We have sent everything, and we were in the middle of an AON + * write. The output write length is the total length of the AON + * buffer, not however many bytes we managed to write to the stream + * in this call. + */ + *written = xso->aon_buf_len; + aon_write_finish(xso); + } else { + *written = actual_written; + } + + return 1; + } + + if (xso->aon_write_in_progress) { + /* + * AON write is in progress but we have not written everything yet. We + * may have managed to send zero bytes, or some number of bytes less + * than the total remaining which need to be appended during this + * AON operation. + */ + xso->aon_buf_pos += actual_written; + assert(xso->aon_buf_pos < xso->aon_buf_len); + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_WRITE); + } + + /* + * Not in an existing AON operation but partial write is not enabled, so we + * need to begin a new AON operation. However we needn't bother if we didn't + * actually append anything. + */ + if (actual_written > 0) + aon_write_begin(xso, buf, len, actual_written); + + /* + * AON - We do not publicly admit to having appended anything until AON + * completes. + */ + *written = 0; + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_WRITE); +} + +QUIC_NEEDS_LOCK +static int quic_write_nonblocking_epw(QCTX *ctx, const void *buf, size_t len, + size_t *written) +{ + QUIC_XSO *xso = ctx->xso; + + /* Simple best effort operation. */ + if (!xso_sstream_append(xso, buf, len, written)) { + /* Stream already finished or allocation error. */ + *written = 0; + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + } + + quic_post_write(xso, *written > 0, 1); + return 1; +} + +QUIC_NEEDS_LOCK +static int quic_validate_for_write(QUIC_XSO *xso, int *err) +{ + QUIC_STREAM_MAP *qsm; + + if (xso == NULL || xso->stream == NULL) { + *err = ERR_R_INTERNAL_ERROR; + return 0; + } + + switch (xso->stream->send_state) { + default: + case QUIC_SSTREAM_STATE_NONE: + *err = SSL_R_STREAM_RECV_ONLY; + return 0; + + case QUIC_SSTREAM_STATE_READY: + qsm = ossl_quic_channel_get_qsm(xso->conn->ch); + + if (!ossl_quic_stream_map_ensure_send_part_id(qsm, xso->stream)) { + *err = ERR_R_INTERNAL_ERROR; + return 0; + } + + /* FALLTHROUGH */ + case QUIC_SSTREAM_STATE_SEND: + case QUIC_SSTREAM_STATE_DATA_SENT: + case QUIC_SSTREAM_STATE_DATA_RECVD: + if (ossl_quic_sstream_get_final_size(xso->stream->sstream, NULL)) { + *err = SSL_R_STREAM_FINISHED; + return 0; + } + + return 1; + + case QUIC_SSTREAM_STATE_RESET_SENT: + case QUIC_SSTREAM_STATE_RESET_RECVD: + *err = SSL_R_STREAM_RESET; + return 0; + } +} + +QUIC_TAKES_LOCK +int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) +{ + int ret; + QCTX ctx; + int partial_write, err; + + *written = 0; + + if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/1, &ctx)) + return 0; + + partial_write = ((ctx.xso->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0); + + if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + goto out; + } + + /* + * If we haven't finished the handshake, try to advance it. + * We don't accept writes until the handshake is completed. + */ + if (quic_do_handshake(&ctx) < 1) { + ret = 0; + goto out; + } + + /* Ensure correct stream state, stream send part not concluded, etc. */ + if (!quic_validate_for_write(ctx.xso, &err)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); + goto out; + } + + if (len == 0) { + ret = 1; + goto out; + } + + if (xso_blocking_mode(ctx.xso)) + ret = quic_write_blocking(&ctx, buf, len, written); + else if (partial_write) + ret = quic_write_nonblocking_epw(&ctx, buf, len, written); + else + ret = quic_write_nonblocking_aon(&ctx, buf, len, written); + +out: + quic_unlock(ctx.qc); + return ret; +} + +/* + * SSL_read + * -------- + */ +struct quic_read_again_args { + QCTX *ctx; + QUIC_STREAM *stream; + void *buf; + size_t len; + size_t *bytes_read; + int peek; +}; + +QUIC_NEEDS_LOCK +static int quic_validate_for_read(QUIC_XSO *xso, int *err, int *eos) +{ + QUIC_STREAM_MAP *qsm; + + *eos = 0; + + if (xso == NULL || xso->stream == NULL) { + *err = ERR_R_INTERNAL_ERROR; + return 0; + } + + switch (xso->stream->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + *err = SSL_R_STREAM_SEND_ONLY; + return 0; + + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + return 1; + + case QUIC_RSTREAM_STATE_DATA_READ: + *eos = 1; + return 0; + + case QUIC_RSTREAM_STATE_RESET_RECVD: + qsm = ossl_quic_channel_get_qsm(xso->conn->ch); + ossl_quic_stream_map_notify_app_read_reset_recv_part(qsm, xso->stream); + + /* FALLTHROUGH */ + case QUIC_RSTREAM_STATE_RESET_READ: + *err = SSL_R_STREAM_RESET; + return 0; + } +} + +QUIC_NEEDS_LOCK +static int quic_read_actual(QCTX *ctx, + QUIC_STREAM *stream, + void *buf, size_t buf_len, + size_t *bytes_read, + int peek) +{ + int is_fin = 0, err, eos; + QUIC_CONNECTION *qc = ctx->qc; + + if (!quic_validate_for_read(ctx->xso, &err, &eos)) { + if (eos) + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); + else + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, err, NULL); + } + + if (peek) { + if (!ossl_quic_rstream_peek(stream->rstream, buf, buf_len, + bytes_read, &is_fin)) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + + } else { + if (!ossl_quic_rstream_read(stream->rstream, buf, buf_len, + bytes_read, &is_fin)) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + } + + if (!peek) { + if (*bytes_read > 0) { + /* + * We have read at least one byte from the stream. Inform stream-level + * RXFC of the retirement of controlled bytes. Update the active stream + * status (the RXFC may now want to emit a frame granting more credit to + * the peer). + */ + OSSL_RTT_INFO rtt_info; + + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(qc->ch), &rtt_info); + + if (!ossl_quic_rxfc_on_retire(&stream->rxfc, *bytes_read, + rtt_info.smoothed_rtt)) + return QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, NULL); + } + + if (is_fin && !peek) { + QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(ctx->qc->ch); + + ossl_quic_stream_map_notify_totally_read(qsm, ctx->xso->stream); + } + + if (*bytes_read > 0) + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(qc->ch), + stream); + } + + if (*bytes_read == 0 && is_fin) + return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_ZERO_RETURN); + + return 1; +} + +QUIC_NEEDS_LOCK +static int quic_read_again(void *arg) +{ + struct quic_read_again_args *args = arg; + + if (!quic_mutation_allowed(args->ctx->qc, /*req_active=*/1)) { + /* If connection is torn down due to an error while blocking, stop. */ + QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return -1; + } + + if (!quic_read_actual(args->ctx, args->stream, + args->buf, args->len, args->bytes_read, + args->peek)) + return -1; + + if (*args->bytes_read > 0) + /* got at least one byte, the SSL_read op can finish now */ + return 1; + + return 0; /* did not read anything, keep trying */ +} + +QUIC_TAKES_LOCK +static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek) +{ + int ret, res; + QCTX ctx; + struct quic_read_again_args args; + + *bytes_read = 0; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock_for_io(&ctx); + + if (!quic_mutation_allowed(ctx.qc, /*req_active=*/0)) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + goto out; + } + + /* If we haven't finished the handshake, try to advance it. */ + if (quic_do_handshake(&ctx) < 1) { + ret = 0; /* ossl_quic_do_handshake raised error here */ + goto out; + } + + if (ctx.xso == NULL) { + /* + * Called on a QCSO and we don't currently have a default stream. + * + * Wait until we get a stream initiated by the peer (blocking mode) or + * fail if we don't have one yet (non-blocking mode). + */ + if (!qc_wait_for_default_xso_for_read(&ctx)) { + ret = 0; /* error already raised here */ + goto out; + } + + ctx.xso = ctx.qc->default_xso; + } + + if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) { + ret = 0; /* quic_read_actual raised error here */ + goto out; + } + + if (*bytes_read > 0) { + /* + * Even though we succeeded, tick the reactor here to ensure we are + * handling other aspects of the QUIC connection. + */ + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + ret = 1; + } else if (xso_blocking_mode(ctx.xso)) { + /* + * We were not able to read anything immediately, so our stream + * buffer is empty. This means we need to block until we get + * at least one byte. + */ + args.ctx = &ctx; + args.stream = ctx.xso->stream; + args.buf = buf; + args.len = len; + args.bytes_read = bytes_read; + args.peek = peek; + + res = block_until_pred(ctx.qc, quic_read_again, &args, 0); + if (res == 0) { + ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); + goto out; + } else if (res < 0) { + ret = 0; /* quic_read_again raised error here */ + goto out; + } + + ret = 1; + } else { + /* + * We did not get any bytes and are not in blocking mode. + * Tick to see if this delivers any more. + */ + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0); + + /* Try the read again. */ + if (!quic_read_actual(&ctx, ctx.xso->stream, buf, len, bytes_read, peek)) { + ret = 0; /* quic_read_actual raised error here */ + goto out; + } + + if (*bytes_read > 0) + ret = 1; /* Succeeded this time. */ + else + ret = QUIC_RAISE_NORMAL_ERROR(&ctx, SSL_ERROR_WANT_READ); + } + +out: + quic_unlock(ctx.qc); + return ret; +} + +int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read) +{ + return quic_read(s, buf, len, bytes_read, 0); +} + +int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *bytes_read) +{ + return quic_read(s, buf, len, bytes_read, 1); +} + +/* + * SSL_pending + * ----------- + */ + +QUIC_TAKES_LOCK +static size_t ossl_quic_pending_int(const SSL *s, int check_channel) +{ + QCTX ctx; + size_t avail = 0; + int fin = 0; + + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + if (ctx.xso == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_NO_STREAM, NULL); + goto out; + } + + if (ctx.xso->stream == NULL + || !ossl_quic_stream_has_recv_buffer(ctx.xso->stream)) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); + goto out; + } + + if (!ossl_quic_rstream_available(ctx.xso->stream->rstream, &avail, &fin)) + avail = 0; + + if (avail == 0 && check_channel && ossl_quic_channel_has_pending(ctx.qc->ch)) + avail = 1; + +out: + quic_unlock(ctx.qc); + return avail; +} + +size_t ossl_quic_pending(const SSL *s) +{ + return ossl_quic_pending_int(s, /*check_channel=*/0); +} + +int ossl_quic_has_pending(const SSL *s) +{ + /* Do we have app-side pending data or pending URXEs or RXEs? */ + return ossl_quic_pending_int(s, /*check_channel=*/1) > 0; +} + +/* + * SSL_stream_conclude + * ------------------- + */ +QUIC_TAKES_LOCK +int ossl_quic_conn_stream_conclude(SSL *s) +{ + QCTX ctx; + QUIC_STREAM *qs; + int err; + + if (!expect_quic_with_stream_lock(s, /*remote_init=*/0, /*io=*/0, &ctx)) + return 0; + + qs = ctx.xso->stream; + + if (!quic_mutation_allowed(ctx.qc, /*req_active=*/1)) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + } + + if (!quic_validate_for_write(ctx.xso, &err)) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); + } + + if (ossl_quic_sstream_get_final_size(qs->sstream, NULL)) { + quic_unlock(ctx.qc); + return 1; + } + + ossl_quic_sstream_fin(qs->sstream); + quic_post_write(ctx.xso, 1, 1); + quic_unlock(ctx.qc); + return 1; +} + +/* + * SSL_inject_net_dgram + * -------------------- + */ +QUIC_TAKES_LOCK +int SSL_inject_net_dgram(SSL *s, const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local) +{ + int ret; + QCTX ctx; + QUIC_DEMUX *demux; + + if (!expect_quic(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + demux = ossl_quic_channel_get0_demux(ctx.qc->ch); + ret = ossl_quic_demux_inject(demux, buf, buf_len, peer, local); + + quic_unlock(ctx.qc); + return ret; +} + +/* + * SSL_get0_connection + * ------------------- + */ +SSL *ossl_quic_get0_connection(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return NULL; + + return &ctx.qc->ssl; +} + +/* + * SSL_get_stream_type + * ------------------- + */ +int ossl_quic_get_stream_type(SSL *s) +{ + QCTX ctx; + + if (!expect_quic(s, &ctx)) + return SSL_STREAM_TYPE_BIDI; + + if (ctx.xso == NULL) { + /* + * If deferred XSO creation has yet to occur, proceed according to the + * default stream mode. If AUTO_BIDI or AUTO_UNI is set, we cannot know + * what kind of stream will be created yet, so return BIDI on the basis + * that at this time, the client still has the option of calling + * SSL_read() or SSL_write() first. + */ + if (ctx.qc->default_xso_created + || ctx.qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE) + return SSL_STREAM_TYPE_NONE; + else + return SSL_STREAM_TYPE_BIDI; + } + + if (ossl_quic_stream_is_bidi(ctx.xso->stream)) + return SSL_STREAM_TYPE_BIDI; + + if (ossl_quic_stream_is_server_init(ctx.xso->stream) != ctx.qc->as_server) + return SSL_STREAM_TYPE_READ; + else + return SSL_STREAM_TYPE_WRITE; +} + +/* + * SSL_get_stream_id + * ----------------- + */ +QUIC_TAKES_LOCK +uint64_t ossl_quic_get_stream_id(SSL *s) +{ + QCTX ctx; + uint64_t id; + + if (!expect_quic_with_stream_lock(s, /*remote_init=*/-1, /*io=*/0, &ctx)) + return UINT64_MAX; + + id = ctx.xso->stream->id; + quic_unlock(ctx.qc); + + return id; +} + +/* + * SSL_is_stream_local + * ------------------- + */ +QUIC_TAKES_LOCK +int ossl_quic_is_stream_local(SSL *s) +{ + QCTX ctx; + int is_local; + + if (!expect_quic_with_stream_lock(s, /*remote_init=*/-1, /*io=*/0, &ctx)) + return -1; + + is_local = ossl_quic_stream_is_local_init(ctx.xso->stream); + quic_unlock(ctx.qc); + + return is_local; +} + +/* + * SSL_set_default_stream_mode + * --------------------------- + */ +QUIC_TAKES_LOCK +int ossl_quic_set_default_stream_mode(SSL *s, uint32_t mode) +{ + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + if (ctx.qc->default_xso_created) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + "too late to change default stream mode"); + } + + switch (mode) { + case SSL_DEFAULT_STREAM_MODE_NONE: + case SSL_DEFAULT_STREAM_MODE_AUTO_BIDI: + case SSL_DEFAULT_STREAM_MODE_AUTO_UNI: + ctx.qc->default_stream_mode = mode; + break; + default: + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, + "bad default stream type"); + } + + quic_unlock(ctx.qc); + return 1; +} + +/* + * SSL_detach_stream + * ----------------- + */ +QUIC_TAKES_LOCK +SSL *ossl_quic_detach_stream(SSL *s) +{ + QCTX ctx; + QUIC_XSO *xso = NULL; + + if (!expect_quic_conn_only(s, &ctx)) + return NULL; + + quic_lock(ctx.qc); + + /* Calling this function inhibits default XSO autocreation. */ + /* QC ref to any default XSO is transferred to us and to caller. */ + qc_set_default_xso_keep_ref(ctx.qc, NULL, /*touch=*/1, &xso); + + quic_unlock(ctx.qc); + + return xso != NULL ? &xso->ssl : NULL; +} + +/* + * SSL_attach_stream + * ----------------- + */ +QUIC_TAKES_LOCK +int ossl_quic_attach_stream(SSL *conn, SSL *stream) +{ + QCTX ctx; + QUIC_XSO *xso; + int nref; + + if (!expect_quic_conn_only(conn, &ctx)) + return 0; + + if (stream == NULL || stream->type != SSL_TYPE_QUIC_XSO) + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_NULL_PARAMETER, + "stream to attach must be a valid QUIC stream"); + + xso = (QUIC_XSO *)stream; + + quic_lock(ctx.qc); + + if (ctx.qc->default_xso != NULL) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + "connection already has a default stream"); + } + + /* + * It is a caller error for the XSO being attached as a default XSO to have + * more than one ref. + */ + if (!CRYPTO_GET_REF(&xso->ssl.references, &nref)) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, + "ref"); + } + + if (nref != 1) { + quic_unlock(ctx.qc); + return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, + "stream being attached must have " + "only 1 reference"); + } + + /* Caller's reference to the XSO is transferred to us. */ + /* Calling this function inhibits default XSO autocreation. */ + qc_set_default_xso(ctx.qc, xso, /*touch=*/1); + + quic_unlock(ctx.qc); + return 1; +} + +/* + * SSL_set_incoming_stream_policy + * ------------------------------ + */ +QUIC_NEEDS_LOCK +static int qc_get_effective_incoming_stream_policy(QUIC_CONNECTION *qc) +{ + switch (qc->incoming_stream_policy) { + case SSL_INCOMING_STREAM_POLICY_AUTO: + if ((qc->default_xso == NULL && !qc->default_xso_created) + || qc->default_stream_mode == SSL_DEFAULT_STREAM_MODE_NONE) + return SSL_INCOMING_STREAM_POLICY_ACCEPT; + else + return SSL_INCOMING_STREAM_POLICY_REJECT; + + default: + return qc->incoming_stream_policy; + } +} + +QUIC_NEEDS_LOCK +static void qc_update_reject_policy(QUIC_CONNECTION *qc) +{ + int policy = qc_get_effective_incoming_stream_policy(qc); + int enable_reject = (policy == SSL_INCOMING_STREAM_POLICY_REJECT); + + ossl_quic_channel_set_incoming_stream_auto_reject(qc->ch, + enable_reject, + qc->incoming_stream_aec); +} + +QUIC_TAKES_LOCK +int ossl_quic_set_incoming_stream_policy(SSL *s, int policy, + uint64_t aec) +{ + int ret = 1; + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + switch (policy) { + case SSL_INCOMING_STREAM_POLICY_AUTO: + case SSL_INCOMING_STREAM_POLICY_ACCEPT: + case SSL_INCOMING_STREAM_POLICY_REJECT: + ctx.qc->incoming_stream_policy = policy; + ctx.qc->incoming_stream_aec = aec; + break; + + default: + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL); + ret = 0; + break; + } + + qc_update_reject_policy(ctx.qc); + quic_unlock(ctx.qc); + return ret; +} + +/* + * SSL_accept_stream + * ----------------- + */ +struct wait_for_incoming_stream_args { + QCTX *ctx; + QUIC_STREAM *qs; +}; + +QUIC_NEEDS_LOCK +static int wait_for_incoming_stream(void *arg) +{ + struct wait_for_incoming_stream_args *args = arg; + QUIC_CONNECTION *qc = args->ctx->qc; + QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(qc->ch); + + if (!quic_mutation_allowed(qc, /*req_active=*/1)) { + /* If connection is torn down due to an error while blocking, stop. */ + QUIC_RAISE_NON_NORMAL_ERROR(args->ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL); + return -1; + } + + args->qs = ossl_quic_stream_map_peek_accept_queue(qsm); + if (args->qs != NULL) + return 1; /* got a stream */ + + return 0; /* did not get a stream, keep trying */ +} + +QUIC_TAKES_LOCK +SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags) +{ + QCTX ctx; + int ret; + SSL *new_s = NULL; + QUIC_STREAM_MAP *qsm; + QUIC_STREAM *qs; + QUIC_XSO *xso; + OSSL_RTT_INFO rtt_info; + + if (!expect_quic_conn_only(s, &ctx)) + return NULL; + + quic_lock(ctx.qc); + + if (qc_get_effective_incoming_stream_policy(ctx.qc) + == SSL_INCOMING_STREAM_POLICY_REJECT) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, NULL); + goto out; + } + + qsm = ossl_quic_channel_get_qsm(ctx.qc->ch); + + qs = ossl_quic_stream_map_peek_accept_queue(qsm); + if (qs == NULL) { + if (qc_blocking_mode(ctx.qc) + && (flags & SSL_ACCEPT_STREAM_NO_BLOCK) == 0) { + struct wait_for_incoming_stream_args args; + + args.ctx = &ctx; + args.qs = NULL; + + ret = block_until_pred(ctx.qc, wait_for_incoming_stream, &args, 0); + if (ret == 0) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); + goto out; + } else if (ret < 0 || args.qs == NULL) { + goto out; + } + + qs = args.qs; + } else { + goto out; + } + } + + xso = create_xso_from_stream(ctx.qc, qs); + if (xso == NULL) + goto out; + + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ctx.qc->ch), &rtt_info); + ossl_quic_stream_map_remove_from_accept_queue(qsm, qs, + rtt_info.smoothed_rtt); + new_s = &xso->ssl; + + /* Calling this function inhibits default XSO autocreation. */ + qc_touch_default_xso(ctx.qc); /* inhibits default XSO */ + +out: + quic_unlock(ctx.qc); + return new_s; +} + +/* + * SSL_get_accept_stream_queue_len + * ------------------------------- + */ +QUIC_TAKES_LOCK +size_t ossl_quic_get_accept_stream_queue_len(SSL *s) +{ + QCTX ctx; + size_t v; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + quic_lock(ctx.qc); + + v = ossl_quic_stream_map_get_accept_queue_len(ossl_quic_channel_get_qsm(ctx.qc->ch)); + + quic_unlock(ctx.qc); + return v; +} + +/* + * SSL_stream_reset + * ---------------- + */ +int ossl_quic_stream_reset(SSL *ssl, + const SSL_STREAM_RESET_ARGS *args, + size_t args_len) +{ + QCTX ctx; + QUIC_STREAM_MAP *qsm; + QUIC_STREAM *qs; + uint64_t error_code; + int ok, err; + + if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/0, /*io=*/0, &ctx)) + return 0; + + qsm = ossl_quic_channel_get_qsm(ctx.qc->ch); + qs = ctx.xso->stream; + error_code = (args != NULL ? args->quic_error_code : 0); + + if (!quic_validate_for_write(ctx.xso, &err)) { + ok = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, err, NULL); + goto err; + } + + ok = ossl_quic_stream_map_reset_stream_send_part(qsm, qs, error_code); + +err: + quic_unlock(ctx.qc); + return ok; +} + +/* + * SSL_get_stream_read_state + * ------------------------- + */ +static void quic_classify_stream(QUIC_CONNECTION *qc, + QUIC_STREAM *qs, + int is_write, + int *state, + uint64_t *app_error_code) +{ + int local_init; + uint64_t final_size; + + local_init = (ossl_quic_stream_is_server_init(qs) == qc->as_server); + + if (app_error_code != NULL) + *app_error_code = UINT64_MAX; + else + app_error_code = &final_size; /* throw away value */ + + if (!ossl_quic_stream_is_bidi(qs) && local_init != is_write) { + /* + * Unidirectional stream and this direction of transmission doesn't + * exist. + */ + *state = SSL_STREAM_STATE_WRONG_DIR; + } else if (ossl_quic_channel_is_term_any(qc->ch)) { + /* Connection already closed. */ + *state = SSL_STREAM_STATE_CONN_CLOSED; + } else if (!is_write && qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ) { + /* Application has read a FIN. */ + *state = SSL_STREAM_STATE_FINISHED; + } else if ((!is_write && qs->stop_sending) + || (is_write && ossl_quic_stream_send_is_reset(qs))) { + /* + * Stream has been reset locally. FIN takes precedence over this for the + * read case as the application need not care if the stream is reset + * after a FIN has been successfully processed. + */ + *state = SSL_STREAM_STATE_RESET_LOCAL; + *app_error_code = !is_write + ? qs->stop_sending_aec + : qs->reset_stream_aec; + } else if ((!is_write && ossl_quic_stream_recv_is_reset(qs)) + || (is_write && qs->peer_stop_sending)) { + /* + * Stream has been reset remotely. */ + *state = SSL_STREAM_STATE_RESET_REMOTE; + *app_error_code = !is_write + ? qs->peer_reset_stream_aec + : qs->peer_stop_sending_aec; + } else if (is_write && ossl_quic_sstream_get_final_size(qs->sstream, + &final_size)) { + /* + * Stream has been finished. Stream reset takes precedence over this for + * the write case as peer may not have received all data. + */ + *state = SSL_STREAM_STATE_FINISHED; + } else { + /* Stream still healthy. */ + *state = SSL_STREAM_STATE_OK; + } +} + +static int quic_get_stream_state(SSL *ssl, int is_write) +{ + QCTX ctx; + int state; + + if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx)) + return SSL_STREAM_STATE_NONE; + + quic_classify_stream(ctx.qc, ctx.xso->stream, is_write, &state, NULL); + quic_unlock(ctx.qc); + return state; +} + +int ossl_quic_get_stream_read_state(SSL *ssl) +{ + return quic_get_stream_state(ssl, /*is_write=*/0); +} + +/* + * SSL_get_stream_write_state + * -------------------------- + */ +int ossl_quic_get_stream_write_state(SSL *ssl) +{ + return quic_get_stream_state(ssl, /*is_write=*/1); +} + +/* + * SSL_get_stream_read_error_code + * ------------------------------ + */ +static int quic_get_stream_error_code(SSL *ssl, int is_write, + uint64_t *app_error_code) +{ + QCTX ctx; + int state; + + if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx)) + return -1; + + quic_classify_stream(ctx.qc, ctx.xso->stream, /*is_write=*/0, + &state, app_error_code); + + quic_unlock(ctx.qc); + switch (state) { + case SSL_STREAM_STATE_FINISHED: + return 0; + case SSL_STREAM_STATE_RESET_LOCAL: + case SSL_STREAM_STATE_RESET_REMOTE: + return 1; + default: + return -1; + } +} + +int ossl_quic_get_stream_read_error_code(SSL *ssl, uint64_t *app_error_code) +{ + return quic_get_stream_error_code(ssl, /*is_write=*/0, app_error_code); +} + +/* + * SSL_get_stream_write_error_code + * ------------------------------- + */ +int ossl_quic_get_stream_write_error_code(SSL *ssl, uint64_t *app_error_code) +{ + return quic_get_stream_error_code(ssl, /*is_write=*/1, app_error_code); +} + +/* + * Write buffer size mutation + * -------------------------- + */ +int ossl_quic_set_write_buffer_size(SSL *ssl, size_t size) +{ + int ret = 0; + QCTX ctx; + + if (!expect_quic_with_stream_lock(ssl, /*remote_init=*/-1, /*io=*/0, &ctx)) + return 0; + + if (!ossl_quic_stream_has_send(ctx.xso->stream)) { + /* Called on a unidirectional receive-only stream - error. */ + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, NULL); + goto out; + } + + if (!ossl_quic_stream_has_send_buffer(ctx.xso->stream)) { + /* + * If the stream has a send part but we have disposed of it because we + * no longer need it, this is a no-op. + */ + ret = 1; + goto out; + } + + if (!ossl_quic_sstream_set_buffer_size(ctx.xso->stream->sstream, size)) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR, NULL); + goto out; + } + + ret = 1; + +out: + quic_unlock(ctx.qc); + return ret; +} + +/* + * SSL_get_conn_close_info + * ----------------------- + */ +int ossl_quic_get_conn_close_info(SSL *ssl, + SSL_CONN_CLOSE_INFO *info, + size_t info_len) +{ + QCTX ctx; + const QUIC_TERMINATE_CAUSE *tc; + + if (!expect_quic_conn_only(ssl, &ctx)) + return -1; + + tc = ossl_quic_channel_get_terminate_cause(ctx.qc->ch); + if (tc == NULL) + return 0; + + info->error_code = tc->error_code; + info->frame_type = tc->frame_type; + info->reason = tc->reason; + info->reason_len = tc->reason_len; + info->flags = 0; + if (!tc->remote) + info->flags |= SSL_CONN_CLOSE_FLAG_LOCAL; + if (!tc->app) + info->flags |= SSL_CONN_CLOSE_FLAG_TRANSPORT; + return 1; +} + +/* + * SSL_key_update + * -------------- + */ +int ossl_quic_key_update(SSL *ssl, int update_type) +{ + QCTX ctx; + + if (!expect_quic_conn_only(ssl, &ctx)) + return 0; + + switch (update_type) { + case SSL_KEY_UPDATE_NOT_REQUESTED: + /* + * QUIC signals peer key update implicily by triggering a local + * spontaneous TXKU. Silently upgrade this to SSL_KEY_UPDATE_REQUESTED. + */ + case SSL_KEY_UPDATE_REQUESTED: + break; + + default: + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_PASSED_INVALID_ARGUMENT, NULL); + return 0; + } + + quic_lock(ctx.qc); + + /* Attempt to perform a TXKU. */ + if (!ossl_quic_channel_trigger_txku(ctx.qc->ch)) { + QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_TOO_MANY_KEY_UPDATES, NULL); + quic_unlock(ctx.qc); + return 0; + } + + quic_unlock(ctx.qc); + return 1; +} + +/* + * SSL_get_key_update_type + * ----------------------- + */ +int ossl_quic_get_key_update_type(const SSL *s) +{ + /* + * We always handle key updates immediately so a key update is never + * pending. + */ + return SSL_KEY_UPDATE_NONE; +} + +/* + * QUIC Front-End I/O API: SSL_CTX Management + * ========================================== + */ + +long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + switch (cmd) { + default: + return ssl3_ctx_ctrl(ctx, cmd, larg, parg); + } +} + +long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ossl_quic_channel_set_msg_callback(ctx.qc->ch, (ossl_msg_cb)fp, + &ctx.qc->ssl); + /* This callback also needs to be set on the internal SSL object */ + return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp);; + + default: + /* Probably a TLS related ctrl. Defer to our internal SSL object */ + return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp); + } +} + +long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + return ssl3_ctx_callback_ctrl(ctx, cmd, fp); +} + +int ossl_quic_renegotiate_check(SSL *ssl, int initok) +{ + /* We never do renegotiation. */ + return 0; +} + +const SSL_CIPHER *ossl_quic_get_cipher_by_char(const unsigned char *p) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher_by_char(p); + + if ((ciph->algorithm2 & SSL_QUIC) == 0) + return NULL; + + return ciph; +} + +/* + * These functions define the TLSv1.2 (and below) ciphers that are supported by + * the SSL_METHOD. Since QUIC only supports TLSv1.3 we don't support any. + */ + +int ossl_quic_num_ciphers(void) +{ + return 0; +} + +const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u) +{ + return NULL; +} + +/* + * SSL_get_shutdown() + * ------------------ + */ +int ossl_quic_get_shutdown(const SSL *s) +{ + QCTX ctx; + int shut = 0; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + if (ossl_quic_channel_is_term_any(ctx.qc->ch)) { + shut |= SSL_SENT_SHUTDOWN; + if (!ossl_quic_channel_is_closing(ctx.qc->ch)) + shut |= SSL_RECEIVED_SHUTDOWN; + } + + return shut; +} + +/* + * Internal Testing APIs + * ===================== + */ + +QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s) +{ + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return NULL; + + return ctx.qc->ch; +} diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h new file mode 100644 index 0000000000..928ae4c6bf --- /dev/null +++ b/ssl/quic/quic_local.h @@ -0,0 +1,338 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_LOCAL_H +# define OSSL_QUIC_LOCAL_H + +# include +# include "internal/quic_ssl.h" /* QUIC_CONNECTION */ +# include "internal/quic_txp.h" +# include "internal/quic_statm.h" +# include "internal/quic_demux.h" +# include "internal/quic_record_rx.h" +# include "internal/quic_tls.h" +# include "internal/quic_fc.h" +# include "internal/quic_stream.h" +# include "internal/quic_channel.h" +# include "internal/quic_reactor.h" +# include "internal/quic_thread_assist.h" +# include "../ssl_local.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC stream SSL object (QSSO) type. This implements the API personality layer + * for QSSO objects, wrapping the QUIC-native QUIC_STREAM object and tracking + * state required by the libssl API personality. + */ +struct quic_xso_st { + /* SSL object common header. */ + struct ssl_st ssl; + + /* The connection this stream is associated with. Always non-NULL. */ + QUIC_CONNECTION *conn; + + /* The stream object. Always non-NULL for as long as the XSO exists. */ + QUIC_STREAM *stream; + + /* + * Has this stream been logically configured into blocking mode? Only + * meaningful if desires_blocking_set is 1. Ignored if blocking is not + * currently possible given QUIC_CONNECTION configuration. + */ + unsigned int desires_blocking : 1; + + /* + * Has SSL_set_blocking_mode been called on this stream? If not set, we + * inherit from the QUIC_CONNECTION blocking state. + */ + unsigned int desires_blocking_set : 1; + + /* + * This state tracks SSL_write all-or-nothing (AON) write semantics + * emulation. + * + * Example chronology: + * + * t=0: aon_write_in_progress=0 + * t=1: SSL_write(ssl, b1, l1) called; + * too big to enqueue into sstream at once, SSL_ERROR_WANT_WRITE; + * aon_write_in_progress=1; aon_buf_base=b1; aon_buf_len=l1; + * aon_buf_pos < l1 (depends on how much room was in sstream); + * t=2: SSL_write(ssl, b2, l2); + * b2 must equal b1 (validated unless ACCEPT_MOVING_WRITE_BUFFER) + * l2 must equal l1 (always validated) + * append into sstream from [b2 + aon_buf_pos, b2 + aon_buf_len) + * if done, aon_write_in_progress=0 + * + */ + /* Is an AON write in progress? */ + unsigned int aon_write_in_progress : 1; + /* + * The base buffer pointer the caller passed us for the initial AON write + * call. We use this for validation purposes unless + * ACCEPT_MOVING_WRITE_BUFFER is enabled. + * + * NOTE: We never dereference this, as the caller might pass a different + * (but identical) buffer if using ACCEPT_MOVING_WRITE_BUFFER. It is for + * validation by pointer comparison only. + */ + const unsigned char *aon_buf_base; + /* The total length of the AON buffer being sent, in bytes. */ + size_t aon_buf_len; + /* + * The position in the AON buffer up to which we have successfully sent data + * so far. + */ + size_t aon_buf_pos; + + /* SSL_set_mode */ + uint32_t ssl_mode; + + /* SSL_set_options */ + uint64_t ssl_options; + + /* + * Last 'normal' error during an app-level I/O operation, used by + * SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ + * and SSL_ERROR_WANT_WRITE. + */ + int last_error; +}; + +struct quic_conn_st { + /* + * ssl_st is a common header for ordinary SSL objects, QUIC connection + * objects and QUIC stream objects, allowing objects of these different + * types to be disambiguated at runtime and providing some common fields. + * + * Note: This must come first in the QUIC_CONNECTION structure. + */ + struct ssl_st ssl; + + SSL *tls; + + /* + * The QUIC channel providing the core QUIC connection implementation. Note + * that this is not instantiated until we actually start trying to do the + * handshake. This is to allow us to gather information like whether we are + * going to be in client or server mode before committing to instantiating + * the channel, since we want to determine the channel arguments based on + * that. + * + * The channel remains available after connection termination until the SSL + * object is freed, thus (ch != NULL) iff (started == 1). + */ + QUIC_CHANNEL *ch; + + /* + * The mutex used to synchronise access to the QUIC_CHANNEL. We own this but + * provide it to the channel. + */ + CRYPTO_MUTEX *mutex; + + /* + * If we have a default stream attached, this is the internal XSO + * object. If there is no default stream, this is NULL. + */ + QUIC_XSO *default_xso; + + /* The network read and write BIOs. */ + BIO *net_rbio, *net_wbio; + + /* Initial peer L4 address. */ + BIO_ADDR init_peer_addr; + +# ifndef OPENSSL_NO_QUIC_THREAD_ASSIST + /* Manages thread for QUIC thread assisted mode. */ + QUIC_THREAD_ASSIST thread_assist; +# endif + + /* If non-NULL, used instead of ossl_time_now(). Used for testing. */ + OSSL_TIME (*override_now_cb)(void *arg); + void *override_now_cb_arg; + + /* Number of XSOs allocated. Includes the default XSO, if any. */ + size_t num_xso; + + /* Have we started? */ + unsigned int started : 1; + + /* + * This is 1 if we were instantiated using a QUIC server method + * (for future use). + */ + unsigned int as_server : 1; + + /* + * Has the application called SSL_set_accept_state? We require this to be + * congruent with the value of as_server. + */ + unsigned int as_server_state : 1; + + /* Are we using thread assisted mode? Never changes after init. */ + unsigned int is_thread_assisted : 1; + + /* Do connection-level operations (e.g. handshakes) run in blocking mode? */ + unsigned int blocking : 1; + + /* Does the application want blocking mode? */ + unsigned int desires_blocking : 1; + + /* Have we created a default XSO yet? */ + unsigned int default_xso_created : 1; + + /* + * Pre-TERMINATING shutdown phase in which we are flushing streams. + * Monotonically transitions to 1. + * New streams cannot be created in this state. + */ + unsigned int shutting_down : 1; + + /* Have we probed the BIOs for addressing support? */ + unsigned int addressing_probe_done : 1; + + /* Are we using addressed mode (BIO_sendmmsg with non-NULL peer)? */ + unsigned int addressed_mode_w : 1; + unsigned int addressed_mode_r : 1; + + /* Default stream type. Defaults to SSL_DEFAULT_STREAM_MODE_AUTO_BIDI. */ + uint32_t default_stream_mode; + + /* SSL_set_mode. This is not used directly but inherited by new XSOs. */ + uint32_t default_ssl_mode; + + /* SSL_set_options. This is not used directly but inherited by new XSOs. */ + uint64_t default_ssl_options; + + /* SSL_set_incoming_stream_policy. */ + int incoming_stream_policy; + uint64_t incoming_stream_aec; + + /* + * Last 'normal' error during an app-level I/O operation, used by + * SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ + * and SSL_ERROR_WANT_WRITE. + */ + int last_error; +}; + +/* Internal calls to the QUIC CSM which come from various places. */ +int ossl_quic_conn_on_handshake_confirmed(QUIC_CONNECTION *qc); + +/* + * To be called when a protocol violation occurs. The connection is torn down + * with the given error code, which should be a QUIC_ERR_* value. Reason string + * is optional and copied if provided. frame_type should be 0 if not applicable. + */ +void ossl_quic_conn_raise_protocol_error(QUIC_CONNECTION *qc, + uint64_t error_code, + uint64_t frame_type, + const char *reason); + +void ossl_quic_conn_on_remote_conn_close(QUIC_CONNECTION *qc, + OSSL_QUIC_FRAME_CONN_CLOSE *f); + +int ossl_quic_trace(int write_p, int version, int content_type, + const void *buf, size_t msglen, SSL *ssl, void *arg); + +# define OSSL_QUIC_ANY_VERSION 0xFFFFF +# define IS_QUIC_METHOD(m) \ + ((m) == OSSL_QUIC_client_method() || \ + (m) == OSSL_QUIC_client_thread_method()) +# define IS_QUIC_CTX(ctx) IS_QUIC_METHOD((ctx)->method) + +# define QUIC_CONNECTION_FROM_SSL_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c QUIC_CONNECTION *)(ssl) \ + : NULL)) + +# define QUIC_XSO_FROM_SSL_int(ssl, c) \ + ((ssl) == NULL \ + ? NULL \ + : (((ssl)->type == SSL_TYPE_QUIC_XSO \ + ? (c QUIC_XSO *)(ssl) \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c QUIC_XSO *)((QUIC_CONNECTION *)(ssl))->default_xso \ + : NULL)))) + +# define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c SSL_CONNECTION *)((c QUIC_CONNECTION *)(ssl))->tls \ + : NULL)) + +# define IS_QUIC(ssl) ((ssl) != NULL \ + && ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + || (ssl)->type == SSL_TYPE_QUIC_XSO)) +# else +# define QUIC_CONNECTION_FROM_SSL_int(ssl, c) NULL +# define QUIC_XSO_FROM_SSL_int(ssl, c) NULL +# define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) NULL +# define IS_QUIC(ssl) 0 +# define IS_QUIC_CTX(ctx) 0 +# define IS_QUIC_METHOD(m) 0 +# endif + +# define QUIC_CONNECTION_FROM_SSL(ssl) \ + QUIC_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define QUIC_CONNECTION_FROM_CONST_SSL(ssl) \ + QUIC_CONNECTION_FROM_SSL_int(ssl, const) +# define QUIC_XSO_FROM_SSL(ssl) \ + QUIC_XSO_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define QUIC_XSO_FROM_CONST_SSL(ssl) \ + QUIC_XSO_FROM_SSL_int(ssl, const) +# define SSL_CONNECTION_FROM_QUIC_SSL(ssl) \ + SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define SSL_CONNECTION_FROM_CONST_QUIC_SSL(ssl) \ + SSL_CONNECTION_FROM_CONST_QUIC_SSL_int(ssl, const) + +# define IMPLEMENT_quic_meth_func(version, func_name, q_accept, \ + q_connect, enc_data) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + version, \ + 0, \ + 0, \ + ossl_quic_new, \ + ossl_quic_free, \ + ossl_quic_reset, \ + ossl_quic_init, \ + NULL /* clear */, \ + ossl_quic_deinit, \ + q_accept, \ + q_connect, \ + ossl_quic_read, \ + ossl_quic_peek, \ + ossl_quic_write, \ + NULL /* shutdown */, \ + NULL /* renegotiate */, \ + ossl_quic_renegotiate_check, \ + NULL /* read_bytes */, \ + NULL /* write_bytes */, \ + NULL /* dispatch_alert */, \ + ossl_quic_ctrl, \ + ossl_quic_ctx_ctrl, \ + ossl_quic_get_cipher_by_char, \ + NULL /* put_cipher_by_char */, \ + ossl_quic_pending, \ + ossl_quic_num_ciphers, \ + ossl_quic_get_cipher, \ + tls1_default_timeout, \ + &enc_data, \ + ssl_undefined_void_function, \ + ossl_quic_callback_ctrl, \ + ossl_quic_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +#endif diff --git a/ssl/quic/quic_method.c b/ssl/quic/quic_method.c new file mode 100644 index 0000000000..2882a40f3f --- /dev/null +++ b/ssl/quic/quic_method.c @@ -0,0 +1,22 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "quic_local.h" + +IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION, + OSSL_QUIC_client_method, + ssl_undefined_function, + ossl_quic_connect, ssl3_undef_enc_method) + +IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION, + OSSL_QUIC_client_thread_method, + ssl_undefined_function, + ossl_quic_connect, ssl3_undef_enc_method) diff --git a/ssl/quic/quic_reactor.c b/ssl/quic/quic_reactor.c new file mode 100644 index 0000000000..3975b87717 --- /dev/null +++ b/ssl/quic/quic_reactor.c @@ -0,0 +1,386 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include "internal/quic_reactor.h" +#include "internal/common.h" +#include "internal/thread_arch.h" + +/* + * Core I/O Reactor Framework + * ========================== + */ +void ossl_quic_reactor_init(QUIC_REACTOR *rtor, + void (*tick_cb)(QUIC_TICK_RESULT *res, void *arg, + uint32_t flags), + void *tick_cb_arg, + OSSL_TIME initial_tick_deadline) +{ + rtor->poll_r.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + rtor->poll_w.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + rtor->net_read_desired = 0; + rtor->net_write_desired = 0; + rtor->can_poll_r = 0; + rtor->can_poll_w = 0; + rtor->tick_deadline = initial_tick_deadline; + + rtor->tick_cb = tick_cb; + rtor->tick_cb_arg = tick_cb_arg; +} + +void ossl_quic_reactor_set_poll_r(QUIC_REACTOR *rtor, const BIO_POLL_DESCRIPTOR *r) +{ + if (r == NULL) + rtor->poll_r.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + else + rtor->poll_r = *r; + + rtor->can_poll_r + = ossl_quic_reactor_can_support_poll_descriptor(rtor, &rtor->poll_r); +} + +void ossl_quic_reactor_set_poll_w(QUIC_REACTOR *rtor, const BIO_POLL_DESCRIPTOR *w) +{ + if (w == NULL) + rtor->poll_w.type = BIO_POLL_DESCRIPTOR_TYPE_NONE; + else + rtor->poll_w = *w; + + rtor->can_poll_w + = ossl_quic_reactor_can_support_poll_descriptor(rtor, &rtor->poll_w); +} + +const BIO_POLL_DESCRIPTOR *ossl_quic_reactor_get_poll_r(const QUIC_REACTOR *rtor) +{ + return &rtor->poll_r; +} + +const BIO_POLL_DESCRIPTOR *ossl_quic_reactor_get_poll_w(const QUIC_REACTOR *rtor) +{ + return &rtor->poll_w; +} + +int ossl_quic_reactor_can_support_poll_descriptor(const QUIC_REACTOR *rtor, + const BIO_POLL_DESCRIPTOR *d) +{ + return d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; +} + +int ossl_quic_reactor_can_poll_r(const QUIC_REACTOR *rtor) +{ + return rtor->can_poll_r; +} + +int ossl_quic_reactor_can_poll_w(const QUIC_REACTOR *rtor) +{ + return rtor->can_poll_w; +} + +int ossl_quic_reactor_net_read_desired(QUIC_REACTOR *rtor) +{ + return rtor->net_read_desired; +} + +int ossl_quic_reactor_net_write_desired(QUIC_REACTOR *rtor) +{ + return rtor->net_write_desired; +} + +OSSL_TIME ossl_quic_reactor_get_tick_deadline(QUIC_REACTOR *rtor) +{ + return rtor->tick_deadline; +} + +int ossl_quic_reactor_tick(QUIC_REACTOR *rtor, uint32_t flags) +{ + QUIC_TICK_RESULT res = {0}; + + /* + * Note that the tick callback cannot fail; this is intentional. Arguably it + * does not make that much sense for ticking to 'fail' (in the sense of an + * explicit error indicated to the user) because ticking is by its nature + * best effort. If something fatal happens with a connection we can report + * it on the next actual application I/O call. + */ + rtor->tick_cb(&res, rtor->tick_cb_arg, flags); + + rtor->net_read_desired = res.net_read_desired; + rtor->net_write_desired = res.net_write_desired; + rtor->tick_deadline = res.tick_deadline; + return 1; +} + +/* + * Blocking I/O Adaptation Layer + * ============================= + */ + +/* + * Utility which can be used to poll on up to two FDs. This is designed to + * support use of split FDs (e.g. with SSL_set_rfd and SSL_set_wfd where + * different FDs are used for read and write). + * + * Generally use of poll(2) is preferred where available. Windows, however, + * hasn't traditionally offered poll(2), only select(2). WSAPoll() was + * introduced in Vista but has seemingly been buggy until relatively recent + * versions of Windows 10. Moreover we support XP so this is not a suitable + * target anyway. However, the traditional issues with select(2) turn out not to + * be an issue on Windows; whereas traditional *NIX select(2) uses a bitmap of + * FDs (and thus is limited in the magnitude of the FDs expressible), Windows + * select(2) is very different. In Windows, socket handles are not allocated + * contiguously from zero and thus this bitmap approach was infeasible. Thus in + * adapting the Berkeley sockets API to Windows a different approach was taken + * whereby the fd_set contains a fixed length array of socket handles and an + * integer indicating how many entries are valid; thus Windows select() + * ironically is actually much more like *NIX poll(2) than *NIX select(2). In + * any case, this means that the relevant limit for Windows select() is the + * number of FDs being polled, not the magnitude of those FDs. Since we only + * poll for two FDs here, this limit does not concern us. + * + * Usage: rfd and wfd may be the same or different. Either or both may also be + * -1. If rfd_want_read is 1, rfd is polled for readability, and if + * wfd_want_write is 1, wfd is polled for writability. Note that since any + * passed FD is always polled for error conditions, setting rfd_want_read=0 and + * wfd_want_write=0 is not the same as passing -1 for both FDs. + * + * deadline is a timestamp to return at. If it is ossl_time_infinite(), the call + * never times out. + * + * Returns 0 on error and 1 on success. Timeout expiry is considered a success + * condition. We don't elaborate our return values here because the way we are + * actually using this doesn't currently care. + * + * If mutex is non-NULL, it is assumed to be held for write and is unlocked for + * the duration of the call. + * + * Precondition: mutex is NULL or is held for write (unchecked) + * Postcondition: mutex is NULL or is held for write (unless + * CRYPTO_THREAD_write_lock fails) + */ +static int poll_two_fds(int rfd, int rfd_want_read, + int wfd, int wfd_want_write, + OSSL_TIME deadline, + CRYPTO_MUTEX *mutex) +{ +#if defined(OPENSSL_SYS_WINDOWS) || !defined(POLLIN) + fd_set rfd_set, wfd_set, efd_set; + OSSL_TIME now, timeout; + struct timeval tv, *ptv; + int maxfd, pres; + +# ifndef OPENSSL_SYS_WINDOWS + /* + * On Windows there is no relevant limit to the magnitude of a fd value (see + * above). On *NIX the fd_set uses a bitmap and we must check the limit. + */ + if (rfd >= FD_SETSIZE || wfd >= FD_SETSIZE) + return 0; +# endif + + FD_ZERO(&rfd_set); + FD_ZERO(&wfd_set); + FD_ZERO(&efd_set); + + if (rfd != -1 && rfd_want_read) + openssl_fdset(rfd, &rfd_set); + if (wfd != -1 && wfd_want_write) + openssl_fdset(wfd, &wfd_set); + + /* Always check for error conditions. */ + if (rfd != -1) + openssl_fdset(rfd, &efd_set); + if (wfd != -1) + openssl_fdset(wfd, &efd_set); + + maxfd = rfd; + if (wfd > maxfd) + maxfd = wfd; + + if (!ossl_assert(rfd != -1 || wfd != -1 + || !ossl_time_is_infinite(deadline))) + /* Do not block forever; should not happen. */ + return 0; + +# if defined(OPENSSL_THREADS) + if (mutex != NULL) + ossl_crypto_mutex_unlock(mutex); +# endif + + do { + /* + * select expects a timeout, not a deadline, so do the conversion. + * Update for each call to ensure the correct value is used if we repeat + * due to EINTR. + */ + if (ossl_time_is_infinite(deadline)) { + ptv = NULL; + } else { + now = ossl_time_now(); + /* + * ossl_time_subtract saturates to zero so we don't need to check if + * now > deadline. + */ + timeout = ossl_time_subtract(deadline, now); + tv = ossl_time_to_timeval(timeout); + ptv = &tv; + } + + pres = select(maxfd + 1, &rfd_set, &wfd_set, &efd_set, ptv); + } while (pres == -1 && get_last_socket_error_is_eintr()); + +# if defined(OPENSSL_THREADS) + if (mutex != NULL) + ossl_crypto_mutex_lock(mutex); +# endif + + return pres < 0 ? 0 : 1; +#else + int pres, timeout_ms; + OSSL_TIME now, timeout; + struct pollfd pfds[2] = {0}; + size_t npfd = 0; + + if (rfd == wfd) { + pfds[npfd].fd = rfd; + pfds[npfd].events = (rfd_want_read ? POLLIN : 0) + | (wfd_want_write ? POLLOUT : 0); + if (rfd >= 0 && pfds[npfd].events != 0) + ++npfd; + } else { + pfds[npfd].fd = rfd; + pfds[npfd].events = (rfd_want_read ? POLLIN : 0); + if (rfd >= 0 && pfds[npfd].events != 0) + ++npfd; + + pfds[npfd].fd = wfd; + pfds[npfd].events = (wfd_want_write ? POLLOUT : 0); + if (wfd >= 0 && pfds[npfd].events != 0) + ++npfd; + } + + if (!ossl_assert(npfd != 0 || !ossl_time_is_infinite(deadline))) + /* Do not block forever; should not happen. */ + return 0; + +# if defined(OPENSSL_THREADS) + if (mutex != NULL) + ossl_crypto_mutex_unlock(mutex); +# endif + + do { + if (ossl_time_is_infinite(deadline)) { + timeout_ms = -1; + } else { + now = ossl_time_now(); + timeout = ossl_time_subtract(deadline, now); + timeout_ms = ossl_time2ms(timeout); + } + + pres = poll(pfds, npfd, timeout_ms); + } while (pres == -1 && get_last_socket_error_is_eintr()); + +# if defined(OPENSSL_THREADS) + if (mutex != NULL) + ossl_crypto_mutex_lock(mutex); +# endif + + return pres < 0 ? 0 : 1; +#endif +} + +static int poll_descriptor_to_fd(const BIO_POLL_DESCRIPTOR *d, int *fd) +{ + if (d == NULL || d->type == BIO_POLL_DESCRIPTOR_TYPE_NONE) { + *fd = INVALID_SOCKET; + return 1; + } + + if (d->type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD + || d->value.fd == INVALID_SOCKET) + return 0; + + *fd = d->value.fd; + return 1; +} + +/* + * Poll up to two abstract poll descriptors. Currently we only support + * poll descriptors which represent FDs. + * + * If mutex is non-NULL, it is assumed be a lock currently held for write and is + * unlocked for the duration of any wait. + * + * Precondition: mutex is NULL or is held for write (unchecked) + * Postcondition: mutex is NULL or is held for write (unless + * CRYPTO_THREAD_write_lock fails) + */ +static int poll_two_descriptors(const BIO_POLL_DESCRIPTOR *r, int r_want_read, + const BIO_POLL_DESCRIPTOR *w, int w_want_write, + OSSL_TIME deadline, + CRYPTO_MUTEX *mutex) +{ + int rfd, wfd; + + if (!poll_descriptor_to_fd(r, &rfd) + || !poll_descriptor_to_fd(w, &wfd)) + return 0; + + return poll_two_fds(rfd, r_want_read, wfd, w_want_write, deadline, mutex); +} + +/* + * Block until a predicate function evaluates to true. + * + * If mutex is non-NULL, it is assumed be a lock currently held for write and is + * unlocked for the duration of any wait. + * + * Precondition: Must hold channel write lock (unchecked) + * Precondition: mutex is NULL or is held for write (unchecked) + * Postcondition: mutex is NULL or is held for write (unless + * CRYPTO_THREAD_write_lock fails) + */ +int ossl_quic_reactor_block_until_pred(QUIC_REACTOR *rtor, + int (*pred)(void *arg), void *pred_arg, + uint32_t flags, + CRYPTO_MUTEX *mutex) +{ + int res; + + for (;;) { + if ((flags & SKIP_FIRST_TICK) != 0) + flags &= ~SKIP_FIRST_TICK; + else + /* best effort */ + ossl_quic_reactor_tick(rtor, 0); + + if ((res = pred(pred_arg)) != 0) + return res; + + if (!poll_two_descriptors(ossl_quic_reactor_get_poll_r(rtor), + ossl_quic_reactor_net_read_desired(rtor), + ossl_quic_reactor_get_poll_w(rtor), + ossl_quic_reactor_net_write_desired(rtor), + ossl_quic_reactor_get_tick_deadline(rtor), + mutex)) + /* + * We don't actually care why the call succeeded (timeout, FD + * readiness), we just call reactor_tick and start trying to do I/O + * things again. If poll_two_fds returns 0, this is some other + * non-timeout failure and we should stop here. + * + * TODO(QUIC FUTURE): In the future we could avoid unnecessary + * syscalls by not retrying network I/O that isn't ready based + * on the result of the poll call. However this might be difficult + * because it requires we do the call to poll(2) or equivalent + * syscall ourselves, whereas in the general case the application + * does the polling and just calls SSL_handle_events(). + * Implementing this optimisation in the future will probably + * therefore require API changes. + */ + return 0; + } +} diff --git a/ssl/quic/quic_record_rx.c b/ssl/quic/quic_record_rx.c new file mode 100644 index 0000000000..4d0493baff --- /dev/null +++ b/ssl/quic/quic_record_rx.c @@ -0,0 +1,1375 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/quic_record_rx.h" +#include "quic_record_shared.h" +#include "internal/common.h" +#include "internal/list.h" +#include "../ssl_local.h" + +/* + * Mark a packet in a bitfield. + * + * pkt_idx: index of packet within datagram. + */ +static ossl_inline void pkt_mark(uint64_t *bitf, size_t pkt_idx) +{ + assert(pkt_idx < QUIC_MAX_PKT_PER_URXE); + *bitf |= ((uint64_t)1) << pkt_idx; +} + +/* Returns 1 if a packet is in the bitfield. */ +static ossl_inline int pkt_is_marked(const uint64_t *bitf, size_t pkt_idx) +{ + assert(pkt_idx < QUIC_MAX_PKT_PER_URXE); + return (*bitf & (((uint64_t)1) << pkt_idx)) != 0; +} + +/* + * RXE + * === + * + * RX Entries (RXEs) store processed (i.e., decrypted) data received from the + * network. One RXE is used per received QUIC packet. + */ +typedef struct rxe_st RXE; + +struct rxe_st { + OSSL_QRX_PKT pkt; + OSSL_LIST_MEMBER(rxe, RXE); + size_t data_len, alloc_len, refcount; + + /* Extra fields for per-packet information. */ + QUIC_PKT_HDR hdr; /* data/len are decrypted payload */ + + /* Decoded packet number. */ + QUIC_PN pn; + + /* Addresses copied from URXE. */ + BIO_ADDR peer, local; + + /* Time we received the packet (not when we processed it). */ + OSSL_TIME time; + + /* Total length of the datagram which contained this packet. */ + size_t datagram_len; + + /* + * The key epoch the packet was received with. Always 0 for non-1-RTT + * packets. + */ + uint64_t key_epoch; + + /* + * alloc_len allocated bytes (of which data_len bytes are valid) follow this + * structure. + */ +}; + +DEFINE_LIST_OF(rxe, RXE); +typedef OSSL_LIST(rxe) RXE_LIST; + +static ossl_inline unsigned char *rxe_data(const RXE *e) +{ + return (unsigned char *)(e + 1); +} + +/* + * QRL + * === + */ +struct ossl_qrx_st { + OSSL_LIB_CTX *libctx; + const char *propq; + + /* Demux to receive datagrams from. */ + QUIC_DEMUX *demux; + + /* Length of connection IDs used in short-header packets in bytes. */ + size_t short_conn_id_len; + + /* Maximum number of deferred datagrams buffered at any one time. */ + size_t max_deferred; + + /* Current count of deferred datagrams. */ + size_t num_deferred; + + /* + * List of URXEs which are filled with received encrypted data. + * These are returned to the DEMUX's free list as they are processed. + */ + QUIC_URXE_LIST urx_pending; + + /* + * List of URXEs which we could not decrypt immediately and which are being + * kept in case they can be decrypted later. + */ + QUIC_URXE_LIST urx_deferred; + + /* + * List of RXEs which are not currently in use. These are moved + * to the pending list as they are filled. + */ + RXE_LIST rx_free; + + /* + * List of RXEs which are filled with decrypted packets ready to be passed + * to the user. A RXE is removed from all lists inside the QRL when passed + * to the user, then returned to the free list when the user returns it. + */ + RXE_LIST rx_pending; + + /* Largest PN we have received and processed in a given PN space. */ + QUIC_PN largest_pn[QUIC_PN_SPACE_NUM]; + + /* Per encryption-level state. */ + OSSL_QRL_ENC_LEVEL_SET el_set; + + /* Bytes we have received since this counter was last cleared. */ + uint64_t bytes_received; + + /* + * Number of forged packets we have received since the QRX was instantiated. + * Note that as per RFC 9001, this is connection-level state; it is not per + * EL and is not reset by a key update. + */ + uint64_t forged_pkt_count; + + /* + * The PN the current key epoch started at, inclusive. + */ + uint64_t cur_epoch_start_pn; + + /* Validation callback. */ + ossl_qrx_late_validation_cb *validation_cb; + void *validation_cb_arg; + + /* Key update callback. */ + ossl_qrx_key_update_cb *key_update_cb; + void *key_update_cb_arg; + + /* Initial key phase. For debugging use only; always 0 in real use. */ + unsigned char init_key_phase_bit; + + /* Are we allowed to process 1-RTT packets yet? */ + unsigned char allow_1rtt; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_ssl; +}; + +static void qrx_on_rx(QUIC_URXE *urxe, void *arg); + +OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args) +{ + OSSL_QRX *qrx; + size_t i; + + if (args->demux == NULL || args->max_deferred == 0) + return 0; + + qrx = OPENSSL_zalloc(sizeof(OSSL_QRX)); + if (qrx == NULL) + return 0; + + for (i = 0; i < OSSL_NELEM(qrx->largest_pn); ++i) + qrx->largest_pn[i] = args->init_largest_pn[i]; + + qrx->libctx = args->libctx; + qrx->propq = args->propq; + qrx->demux = args->demux; + qrx->short_conn_id_len = args->short_conn_id_len; + qrx->init_key_phase_bit = args->init_key_phase_bit; + qrx->max_deferred = args->max_deferred; + return qrx; +} + +static void qrx_cleanup_rxl(RXE_LIST *l) +{ + RXE *e, *enext; + + for (e = ossl_list_rxe_head(l); e != NULL; e = enext) { + enext = ossl_list_rxe_next(e); + ossl_list_rxe_remove(l, e); + OPENSSL_free(e); + } +} + +static void qrx_cleanup_urxl(OSSL_QRX *qrx, QUIC_URXE_LIST *l) +{ + QUIC_URXE *e, *enext; + + for (e = ossl_list_urxe_head(l); e != NULL; e = enext) { + enext = ossl_list_urxe_next(e); + ossl_list_urxe_remove(l, e); + ossl_quic_demux_release_urxe(qrx->demux, e); + } +} + +void ossl_qrx_free(OSSL_QRX *qrx) +{ + uint32_t i; + + if (qrx == NULL) + return; + + /* Unregister from the RX DEMUX. */ + ossl_quic_demux_unregister_by_cb(qrx->demux, qrx_on_rx, qrx); + + /* Free RXE queue data. */ + qrx_cleanup_rxl(&qrx->rx_free); + qrx_cleanup_rxl(&qrx->rx_pending); + qrx_cleanup_urxl(qrx, &qrx->urx_pending); + qrx_cleanup_urxl(qrx, &qrx->urx_deferred); + + /* Drop keying material and crypto resources. */ + for (i = 0; i < QUIC_ENC_LEVEL_NUM; ++i) + ossl_qrl_enc_level_set_discard(&qrx->el_set, i); + + OPENSSL_free(qrx); +} + +void ossl_qrx_inject_urxe(OSSL_QRX *qrx, QUIC_URXE *urxe) +{ + /* Initialize our own fields inside the URXE and add to the pending list. */ + urxe->processed = 0; + urxe->hpr_removed = 0; + urxe->deferred = 0; + ossl_list_urxe_insert_tail(&qrx->urx_pending, urxe); + + if (qrx->msg_callback != NULL) + qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_DATAGRAM, urxe + 1, + urxe->data_len, qrx->msg_callback_ssl, + qrx->msg_callback_arg); +} + +static void qrx_on_rx(QUIC_URXE *urxe, void *arg) +{ + OSSL_QRX *qrx = arg; + + ossl_qrx_inject_urxe(qrx, urxe); +} + +int ossl_qrx_add_dst_conn_id(OSSL_QRX *qrx, + const QUIC_CONN_ID *dst_conn_id) +{ + return ossl_quic_demux_register(qrx->demux, + dst_conn_id, + qrx_on_rx, + qrx); +} + +int ossl_qrx_remove_dst_conn_id(OSSL_QRX *qrx, + const QUIC_CONN_ID *dst_conn_id) +{ + return ossl_quic_demux_unregister(qrx->demux, dst_conn_id); +} + +static void qrx_requeue_deferred(OSSL_QRX *qrx) +{ + QUIC_URXE *e; + + while ((e = ossl_list_urxe_head(&qrx->urx_deferred)) != NULL) { + ossl_list_urxe_remove(&qrx->urx_deferred, e); + ossl_list_urxe_insert_tail(&qrx->urx_pending, e); + } +} + +int ossl_qrx_provide_secret(OSSL_QRX *qrx, uint32_t enc_level, + uint32_t suite_id, EVP_MD *md, + const unsigned char *secret, size_t secret_len) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM) + return 0; + + if (!ossl_qrl_enc_level_set_provide_secret(&qrx->el_set, + qrx->libctx, + qrx->propq, + enc_level, + suite_id, + md, + secret, + secret_len, + qrx->init_key_phase_bit, + /*is_tx=*/0)) + return 0; + + /* + * Any packets we previously could not decrypt, we may now be able to + * decrypt, so move any datagrams containing deferred packets from the + * deferred to the pending queue. + */ + qrx_requeue_deferred(qrx); + return 1; +} + +int ossl_qrx_discard_enc_level(OSSL_QRX *qrx, uint32_t enc_level) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM) + return 0; + + ossl_qrl_enc_level_set_discard(&qrx->el_set, enc_level); + return 1; +} + +/* Returns 1 if there are one or more pending RXEs. */ +int ossl_qrx_processed_read_pending(OSSL_QRX *qrx) +{ + return !ossl_list_rxe_is_empty(&qrx->rx_pending); +} + +/* Returns 1 if there are yet-unprocessed packets. */ +int ossl_qrx_unprocessed_read_pending(OSSL_QRX *qrx) +{ + return !ossl_list_urxe_is_empty(&qrx->urx_pending) + || !ossl_list_urxe_is_empty(&qrx->urx_deferred); +} + +/* Pop the next pending RXE. Returns NULL if no RXE is pending. */ +static RXE *qrx_pop_pending_rxe(OSSL_QRX *qrx) +{ + RXE *rxe = ossl_list_rxe_head(&qrx->rx_pending); + + if (rxe == NULL) + return NULL; + + ossl_list_rxe_remove(&qrx->rx_pending, rxe); + return rxe; +} + +/* Allocate a new RXE. */ +static RXE *qrx_alloc_rxe(size_t alloc_len) +{ + RXE *rxe; + + if (alloc_len >= SIZE_MAX - sizeof(RXE)) + return NULL; + + rxe = OPENSSL_malloc(sizeof(RXE) + alloc_len); + if (rxe == NULL) + return NULL; + + ossl_list_rxe_init_elem(rxe); + rxe->alloc_len = alloc_len; + rxe->data_len = 0; + rxe->refcount = 0; + return rxe; +} + +/* + * Ensures there is at least one RXE in the RX free list, allocating a new entry + * if necessary. The returned RXE is in the RX free list; it is not popped. + * + * alloc_len is a hint which may be used to determine the RXE size if allocation + * is necessary. Returns NULL on allocation failure. + */ +static RXE *qrx_ensure_free_rxe(OSSL_QRX *qrx, size_t alloc_len) +{ + RXE *rxe; + + if (ossl_list_rxe_head(&qrx->rx_free) != NULL) + return ossl_list_rxe_head(&qrx->rx_free); + + rxe = qrx_alloc_rxe(alloc_len); + if (rxe == NULL) + return NULL; + + ossl_list_rxe_insert_tail(&qrx->rx_free, rxe); + return rxe; +} + +/* + * Resize the data buffer attached to an RXE to be n bytes in size. The address + * of the RXE might change; the new address is returned, or NULL on failure, in + * which case the original RXE remains valid. + */ +static RXE *qrx_resize_rxe(RXE_LIST *rxl, RXE *rxe, size_t n) +{ + RXE *rxe2, *p; + + /* Should never happen. */ + if (rxe == NULL) + return NULL; + + if (n >= SIZE_MAX - sizeof(RXE)) + return NULL; + + /* Remove the item from the list to avoid accessing freed memory */ + p = ossl_list_rxe_prev(rxe); + ossl_list_rxe_remove(rxl, rxe); + + /* Should never resize an RXE which has been handed out. */ + if (!ossl_assert(rxe->refcount == 0)) + return NULL; + + /* + * NOTE: We do not clear old memory, although it does contain decrypted + * data. + */ + rxe2 = OPENSSL_realloc(rxe, sizeof(RXE) + n); + if (rxe2 == NULL) { + /* Resize failed, restore old allocation. */ + if (p == NULL) + ossl_list_rxe_insert_head(rxl, rxe); + else + ossl_list_rxe_insert_after(rxl, p, rxe); + return NULL; + } + + if (p == NULL) + ossl_list_rxe_insert_head(rxl, rxe2); + else + ossl_list_rxe_insert_after(rxl, p, rxe2); + + rxe2->alloc_len = n; + return rxe2; +} + +/* + * Ensure the data buffer attached to an RXE is at least n bytes in size. + * Returns NULL on failure. + */ +static RXE *qrx_reserve_rxe(RXE_LIST *rxl, + RXE *rxe, size_t n) +{ + if (rxe->alloc_len >= n) + return rxe; + + return qrx_resize_rxe(rxl, rxe, n); +} + +/* Return a RXE handed out to the user back to our freelist. */ +static void qrx_recycle_rxe(OSSL_QRX *qrx, RXE *rxe) +{ + /* RXE should not be in any list */ + assert(ossl_list_rxe_prev(rxe) == NULL && ossl_list_rxe_next(rxe) == NULL); + rxe->pkt.hdr = NULL; + rxe->pkt.peer = NULL; + rxe->pkt.local = NULL; + ossl_list_rxe_insert_tail(&qrx->rx_free, rxe); +} + +/* + * Given a pointer to a pointer pointing to a buffer and the size of that + * buffer, copy the buffer into *prxe, expanding the RXE if necessary (its + * pointer may change due to realloc). *pi is the offset in bytes to copy the + * buffer to, and on success is updated to be the offset pointing after the + * copied buffer. *pptr is updated to point to the new location of the buffer. + */ +static int qrx_relocate_buffer(OSSL_QRX *qrx, RXE **prxe, size_t *pi, + const unsigned char **pptr, size_t buf_len) +{ + RXE *rxe; + unsigned char *dst; + + if (!buf_len) + return 1; + + if ((rxe = qrx_reserve_rxe(&qrx->rx_free, *prxe, *pi + buf_len)) == NULL) + return 0; + + *prxe = rxe; + dst = (unsigned char *)rxe_data(rxe) + *pi; + + memcpy(dst, *pptr, buf_len); + *pi += buf_len; + *pptr = dst; + return 1; +} + +static uint32_t qrx_determine_enc_level(const QUIC_PKT_HDR *hdr) +{ + switch (hdr->type) { + case QUIC_PKT_TYPE_INITIAL: + return QUIC_ENC_LEVEL_INITIAL; + case QUIC_PKT_TYPE_HANDSHAKE: + return QUIC_ENC_LEVEL_HANDSHAKE; + case QUIC_PKT_TYPE_0RTT: + return QUIC_ENC_LEVEL_0RTT; + case QUIC_PKT_TYPE_1RTT: + return QUIC_ENC_LEVEL_1RTT; + + default: + assert(0); + case QUIC_PKT_TYPE_RETRY: + case QUIC_PKT_TYPE_VERSION_NEG: + return QUIC_ENC_LEVEL_INITIAL; /* not used */ + } +} + +static uint32_t rxe_determine_pn_space(RXE *rxe) +{ + uint32_t enc_level; + + enc_level = qrx_determine_enc_level(&rxe->hdr); + return ossl_quic_enc_level_to_pn_space(enc_level); +} + +static int qrx_validate_hdr_early(OSSL_QRX *qrx, RXE *rxe, + const QUIC_CONN_ID *first_dcid) +{ + /* Ensure version is what we want. */ + if (rxe->hdr.version != QUIC_VERSION_1 + && rxe->hdr.version != QUIC_VERSION_NONE) + return 0; + + /* Clients should never receive 0-RTT packets. */ + if (rxe->hdr.type == QUIC_PKT_TYPE_0RTT) + return 0; + + /* Version negotiation and retry packets must be the first packet. */ + if (first_dcid != NULL && !ossl_quic_pkt_type_can_share_dgram(rxe->hdr.type)) + return 0; + + /* + * If this is not the first packet in a datagram, the destination connection + * ID must match the one in that packet. + */ + if (first_dcid != NULL) { + if (!ossl_assert(first_dcid->id_len < QUIC_MAX_CONN_ID_LEN) + || !ossl_quic_conn_id_eq(first_dcid, + &rxe->hdr.dst_conn_id)) + return 0; + } + + return 1; +} + +/* Validate header and decode PN. */ +static int qrx_validate_hdr(OSSL_QRX *qrx, RXE *rxe) +{ + int pn_space = rxe_determine_pn_space(rxe); + + if (!ossl_quic_wire_decode_pkt_hdr_pn(rxe->hdr.pn, rxe->hdr.pn_len, + qrx->largest_pn[pn_space], + &rxe->pn)) + return 0; + + return 1; +} + +/* Late packet header validation. */ +static int qrx_validate_hdr_late(OSSL_QRX *qrx, RXE *rxe) +{ + int pn_space = rxe_determine_pn_space(rxe); + + /* + * Allow our user to decide whether to discard the packet before we try and + * decrypt it. + */ + if (qrx->validation_cb != NULL + && !qrx->validation_cb(rxe->pn, pn_space, qrx->validation_cb_arg)) + return 0; + + return 1; +} + +/* + * Retrieves the correct cipher context for an EL and key phase. Writes the key + * epoch number actually used for packet decryption to *rx_key_epoch. + */ +static size_t qrx_get_cipher_ctx_idx(OSSL_QRX *qrx, OSSL_QRL_ENC_LEVEL *el, + uint32_t enc_level, + unsigned char key_phase_bit, + uint64_t *rx_key_epoch, + int *is_old_key) +{ + size_t idx; + + *is_old_key = 0; + + if (enc_level != QUIC_ENC_LEVEL_1RTT) { + *rx_key_epoch = 0; + return 0; + } + + if (!ossl_assert(key_phase_bit <= 1)) + return SIZE_MAX; + + /* + * RFC 9001 requires that we not create timing channels which could reveal + * the decrypted value of the Key Phase bit. We usually handle this by + * keeping the cipher contexts for both the current and next key epochs + * around, so that we just select a cipher context blindly using the key + * phase bit, which is time-invariant. + * + * In the COOLDOWN state, we only have one keyslot/cipher context. RFC 9001 + * suggests an implementation strategy to avoid creating a timing channel in + * this case: + * + * Endpoints can use randomized packet protection keys in place of + * discarded keys when key updates are not yet permitted. + * + * Rather than use a randomised key, we simply use our existing key as it + * will fail AEAD verification anyway. This avoids the need to keep around a + * dedicated garbage key. + * + * Note: Accessing different cipher contexts is technically not + * timing-channel safe due to microarchitectural side channels, but this is + * the best we can reasonably do and appears to be directly suggested by the + * RFC. + */ + idx = (el->state == QRL_EL_STATE_PROV_COOLDOWN ? el->key_epoch & 1 + : key_phase_bit); + + /* + * We also need to determine the key epoch number which this index + * corresponds to. This is so we can report the key epoch number in the + * OSSL_QRX_PKT structure, which callers need to validate whether it was OK + * for a packet to be sent using a given key epoch's keys. + */ + switch (el->state) { + case QRL_EL_STATE_PROV_NORMAL: + /* + * If we are in the NORMAL state, usually the KP bit will match the LSB + * of our key epoch, meaning no new key update is being signalled. If it + * does not match, this means the packet (purports to) belong to + * the next key epoch. + * + * IMPORTANT: The AEAD tag has not been verified yet when this function + * is called, so this code must be timing-channel safe, hence use of + * XOR. Moreover, the value output below is not yet authenticated. + */ + *rx_key_epoch + = el->key_epoch + ((el->key_epoch & 1) ^ (uint64_t)key_phase_bit); + break; + + case QRL_EL_STATE_PROV_UPDATING: + /* + * If we are in the UPDATING state, usually the KP bit will match the + * LSB of our key epoch. If it does not match, this means that the + * packet (purports to) belong to the previous key epoch. + * + * As above, must be timing-channel safe. + */ + *is_old_key = (el->key_epoch & 1) ^ (uint64_t)key_phase_bit; + *rx_key_epoch = el->key_epoch - (uint64_t)*is_old_key; + break; + + case QRL_EL_STATE_PROV_COOLDOWN: + /* + * If we are in COOLDOWN, there is only one key epoch we can possibly + * decrypt with, so just try that. If AEAD decryption fails, the + * value we output here isn't used anyway. + */ + *rx_key_epoch = el->key_epoch; + break; + } + + return idx; +} + +/* + * Tries to decrypt a packet payload. + * + * Returns 1 on success or 0 on failure (which is permanent). The payload is + * decrypted from src and written to dst. The buffer dst must be of at least + * src_len bytes in length. The actual length of the output in bytes is written + * to *dec_len on success, which will always be equal to or less than (usually + * less than) src_len. + */ +static int qrx_decrypt_pkt_body(OSSL_QRX *qrx, unsigned char *dst, + const unsigned char *src, + size_t src_len, size_t *dec_len, + const unsigned char *aad, size_t aad_len, + QUIC_PN pn, uint32_t enc_level, + unsigned char key_phase_bit, + uint64_t *rx_key_epoch) +{ + int l = 0, l2 = 0, is_old_key, nonce_len; + unsigned char nonce[EVP_MAX_IV_LENGTH]; + size_t i, cctx_idx; + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(&qrx->el_set, + enc_level, 1); + EVP_CIPHER_CTX *cctx; + + if (src_len > INT_MAX || aad_len > INT_MAX) + return 0; + + /* We should not have been called if we do not have key material. */ + if (!ossl_assert(el != NULL)) + return 0; + + if (el->tag_len >= src_len) + return 0; + + /* + * If we have failed to authenticate a certain number of ciphertexts, refuse + * to decrypt any more ciphertexts. + */ + if (qrx->forged_pkt_count >= ossl_qrl_get_suite_max_forged_pkt(el->suite_id)) + return 0; + + cctx_idx = qrx_get_cipher_ctx_idx(qrx, el, enc_level, key_phase_bit, + rx_key_epoch, &is_old_key); + if (!ossl_assert(cctx_idx < OSSL_NELEM(el->cctx))) + return 0; + + if (is_old_key && pn >= qrx->cur_epoch_start_pn) + /* + * RFC 9001 s. 5.5: Once an endpoint successfully receives a packet with + * a given PN, it MUST discard all packets in the same PN space with + * higher PNs if they cannot be successfully unprotected with the same + * key, or -- if there is a key update -- a subsequent packet protection + * key. + * + * In other words, once a PN x triggers a KU, it is invalid for us to + * receive a packet with a newer PN y (y > x) using the old keys. + */ + return 0; + + cctx = el->cctx[cctx_idx]; + + /* Construct nonce (nonce=IV ^ PN). */ + nonce_len = EVP_CIPHER_CTX_get_iv_length(cctx); + if (!ossl_assert(nonce_len >= (int)sizeof(QUIC_PN))) + return 0; + + memcpy(nonce, el->iv[cctx_idx], nonce_len); + for (i = 0; i < sizeof(QUIC_PN); ++i) + nonce[nonce_len - i - 1] ^= (unsigned char)(pn >> (i * 8)); + + /* type and key will already have been setup; feed the IV. */ + if (EVP_CipherInit_ex(cctx, NULL, + NULL, NULL, nonce, /*enc=*/0) != 1) + return 0; + + /* Feed the AEAD tag we got so the cipher can validate it. */ + if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_SET_TAG, + el->tag_len, + (unsigned char *)src + src_len - el->tag_len) != 1) + return 0; + + /* Feed AAD data. */ + if (EVP_CipherUpdate(cctx, NULL, &l, aad, aad_len) != 1) + return 0; + + /* Feed encrypted packet body. */ + if (EVP_CipherUpdate(cctx, dst, &l, src, src_len - el->tag_len) != 1) + return 0; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* + * Throw away what we just decrypted and just use the ciphertext instead + * (which should be unencrypted) + */ + memcpy(dst, src, l); + + /* Pretend to authenticate the tag but ignore it */ + if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { + /* We don't care */ + } +#else + /* Ensure authentication succeeded. */ + if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { + /* Authentication failed, increment failed auth counter. */ + ++qrx->forged_pkt_count; + return 0; + } +#endif + + *dec_len = l; + return 1; +} + +static ossl_inline void ignore_res(int x) +{ + /* No-op. */ +} + +static void qrx_key_update_initiated(OSSL_QRX *qrx, QUIC_PN pn) +{ + if (!ossl_qrl_enc_level_set_key_update(&qrx->el_set, QUIC_ENC_LEVEL_1RTT)) + /* We are already in RXKU, so we don't call the callback again. */ + return; + + qrx->cur_epoch_start_pn = pn; + + if (qrx->key_update_cb != NULL) + qrx->key_update_cb(pn, qrx->key_update_cb_arg); +} + +/* Process a single packet in a datagram. */ +static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, + PACKET *pkt, size_t pkt_idx, + QUIC_CONN_ID *first_dcid, + size_t datagram_len) +{ + RXE *rxe; + const unsigned char *eop = NULL; + size_t i, aad_len = 0, dec_len = 0; + PACKET orig_pkt = *pkt; + const unsigned char *sop = PACKET_data(pkt); + unsigned char *dst; + char need_second_decode = 0, already_processed = 0; + QUIC_PKT_HDR_PTRS ptrs; + uint32_t pn_space, enc_level; + OSSL_QRL_ENC_LEVEL *el = NULL; + uint64_t rx_key_epoch = UINT64_MAX; + + /* + * Get a free RXE. If we need to allocate a new one, use the packet length + * as a good ballpark figure. + */ + rxe = qrx_ensure_free_rxe(qrx, PACKET_remaining(pkt)); + if (rxe == NULL) + return 0; + + /* Have we already processed this packet? */ + if (pkt_is_marked(&urxe->processed, pkt_idx)) + already_processed = 1; + + /* + * Decode the header into the RXE structure. We first decrypt and read the + * unprotected part of the packet header (unless we already removed header + * protection, in which case we decode all of it). + */ + need_second_decode = !pkt_is_marked(&urxe->hpr_removed, pkt_idx); + if (!ossl_quic_wire_decode_pkt_hdr(pkt, + qrx->short_conn_id_len, + need_second_decode, 0, &rxe->hdr, &ptrs)) + goto malformed; + + /* + * Our successful decode above included an intelligible length and the + * PACKET is now pointing to the end of the QUIC packet. + */ + eop = PACKET_data(pkt); + + /* + * Make a note of the first packet's DCID so we can later ensure the + * destination connection IDs of all packets in a datagram match. + */ + if (pkt_idx == 0) + *first_dcid = rxe->hdr.dst_conn_id; + + /* + * Early header validation. Since we now know the packet length, we can also + * now skip over it if we already processed it. + */ + if (already_processed + || !qrx_validate_hdr_early(qrx, rxe, pkt_idx == 0 ? NULL : first_dcid)) + /* + * Already processed packets are handled identically to malformed + * packets; i.e., they are ignored. + */ + goto malformed; + + if (!ossl_quic_pkt_type_is_encrypted(rxe->hdr.type)) { + /* + * Version negotiation and retry packets are a special case. They do not + * contain a payload which needs decrypting and have no header + * protection. + */ + + /* Just copy the payload from the URXE to the RXE. */ + if ((rxe = qrx_reserve_rxe(&qrx->rx_free, rxe, rxe->hdr.len)) == NULL) + /* + * Allocation failure. EOP will be pointing to the end of the + * datagram so processing of this datagram will end here. + */ + goto malformed; + + /* We are now committed to returning the packet. */ + memcpy(rxe_data(rxe), rxe->hdr.data, rxe->hdr.len); + pkt_mark(&urxe->processed, pkt_idx); + + rxe->hdr.data = rxe_data(rxe); + rxe->pn = QUIC_PN_INVALID; + + rxe->data_len = rxe->hdr.len; + rxe->datagram_len = datagram_len; + rxe->key_epoch = 0; + rxe->peer = urxe->peer; + rxe->local = urxe->local; + rxe->time = urxe->time; + + /* Move RXE to pending. */ + ossl_list_rxe_remove(&qrx->rx_free, rxe); + ossl_list_rxe_insert_tail(&qrx->rx_pending, rxe); + return 0; /* success, did not defer */ + } + + /* Determine encryption level of packet. */ + enc_level = qrx_determine_enc_level(&rxe->hdr); + + /* If we do not have keying material for this encryption level yet, defer. */ + switch (ossl_qrl_enc_level_set_have_el(&qrx->el_set, enc_level)) { + case 1: + /* We have keys. */ + if (enc_level == QUIC_ENC_LEVEL_1RTT && !qrx->allow_1rtt) + /* + * But we cannot process 1-RTT packets until the handshake is + * completed (RFC 9000 s. 5.7). + */ + goto cannot_decrypt; + + break; + case 0: + /* No keys yet. */ + goto cannot_decrypt; + default: + /* We already discarded keys for this EL, we will never process this.*/ + goto malformed; + } + + /* + * We will copy any token included in the packet to the start of our RXE + * data buffer (so that we don't reference the URXE buffer any more and can + * recycle it). Track our position in the RXE buffer by index instead of + * pointer as the pointer may change as reallocs occur. + */ + i = 0; + + /* + * rxe->hdr.data is now pointing at the (encrypted) packet payload. rxe->hdr + * also has fields pointing into the PACKET buffer which will be going away + * soon (the URXE will be reused for another incoming packet). + * + * Firstly, relocate some of these fields into the RXE as needed. + * + * Relocate token buffer and fix pointer. + */ + if (rxe->hdr.type == QUIC_PKT_TYPE_INITIAL) { + const unsigned char *token = rxe->hdr.token; + + /* + * This may change the value of rxe and change the value of the token + * pointer as well. So we must make a temporary copy of the pointer to + * the token, and then copy it back into the new location of the rxe + */ + if (!qrx_relocate_buffer(qrx, &rxe, &i, &token, rxe->hdr.token_len)) + goto malformed; + + rxe->hdr.token = token; + } + + /* Now remove header protection. */ + *pkt = orig_pkt; + + el = ossl_qrl_enc_level_set_get(&qrx->el_set, enc_level, 1); + assert(el != NULL); /* Already checked above */ + + if (need_second_decode) { + if (!ossl_quic_hdr_protector_decrypt(&el->hpr, &ptrs)) + goto malformed; + + /* + * We have removed header protection, so don't attempt to do it again if + * the packet gets deferred and processed again. + */ + pkt_mark(&urxe->hpr_removed, pkt_idx); + + /* Decode the now unprotected header. */ + if (ossl_quic_wire_decode_pkt_hdr(pkt, qrx->short_conn_id_len, + 0, 0, &rxe->hdr, NULL) != 1) + goto malformed; + } + + /* Validate header and decode PN. */ + if (!qrx_validate_hdr(qrx, rxe)) + goto malformed; + + if (qrx->msg_callback != NULL) + qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, sop, + eop - sop - rxe->hdr.len, qrx->msg_callback_ssl, + qrx->msg_callback_arg); + + /* + * The AAD data is the entire (unprotected) packet header including the PN. + * The packet header has been unprotected in place, so we can just reuse the + * PACKET buffer. The header ends where the payload begins. + */ + aad_len = rxe->hdr.data - sop; + + /* Ensure the RXE buffer size is adequate for our payload. */ + if ((rxe = qrx_reserve_rxe(&qrx->rx_free, rxe, rxe->hdr.len + i)) == NULL) { + /* + * Allocation failure, treat as malformed and do not bother processing + * any further packets in the datagram as they are likely to also + * encounter allocation failures. + */ + eop = NULL; + goto malformed; + } + + /* + * We decrypt the packet body to immediately after the token at the start of + * the RXE buffer (where present). + * + * Do the decryption from the PACKET (which points into URXE memory) to our + * RXE payload (single-copy decryption), then fixup the pointers in the + * header to point to our new buffer. + * + * If decryption fails this is considered a permanent error; we defer + * packets we don't yet have decryption keys for above, so if this fails, + * something has gone wrong with the handshake process or a packet has been + * corrupted. + */ + dst = (unsigned char *)rxe_data(rxe) + i; + if (!qrx_decrypt_pkt_body(qrx, dst, rxe->hdr.data, rxe->hdr.len, + &dec_len, sop, aad_len, rxe->pn, enc_level, + rxe->hdr.key_phase, &rx_key_epoch)) + goto malformed; + + /* + * ----------------------------------------------------- + * IMPORTANT: ANYTHING ABOVE THIS LINE IS UNVERIFIED + * AND MUST BE TIMING-CHANNEL SAFE. + * ----------------------------------------------------- + * + * At this point, we have successfully authenticated the AEAD tag and no + * longer need to worry about exposing the PN, PN length or Key Phase bit in + * timing channels. Invoke any configured validation callback to allow for + * rejection of duplicate PNs. + */ + if (!qrx_validate_hdr_late(qrx, rxe)) + goto malformed; + + /* Check for a Key Phase bit differing from our expectation. */ + if (rxe->hdr.type == QUIC_PKT_TYPE_1RTT + && rxe->hdr.key_phase != (el->key_epoch & 1)) + qrx_key_update_initiated(qrx, rxe->pn); + + /* + * We have now successfully decrypted the packet payload. If there are + * additional packets in the datagram, it is possible we will fail to + * decrypt them and need to defer them until we have some key material we + * don't currently possess. If this happens, the URXE will be moved to the + * deferred queue. Since a URXE corresponds to one datagram, which may + * contain multiple packets, we must ensure any packets we have already + * processed in the URXE are not processed again (this is an RFC + * requirement). We do this by marking the nth packet in the datagram as + * processed. + * + * We are now committed to returning this decrypted packet to the user, + * meaning we now consider the packet processed and must mark it + * accordingly. + */ + pkt_mark(&urxe->processed, pkt_idx); + + /* + * Update header to point to the decrypted buffer, which may be shorter + * due to AEAD tags, block padding, etc. + */ + rxe->hdr.data = dst; + rxe->hdr.len = dec_len; + rxe->data_len = dec_len; + rxe->datagram_len = datagram_len; + rxe->key_epoch = rx_key_epoch; + + /* We processed the PN successfully, so update largest processed PN. */ + pn_space = rxe_determine_pn_space(rxe); + if (rxe->pn > qrx->largest_pn[pn_space]) + qrx->largest_pn[pn_space] = rxe->pn; + + /* Copy across network addresses and RX time from URXE to RXE. */ + rxe->peer = urxe->peer; + rxe->local = urxe->local; + rxe->time = urxe->time; + + /* Move RXE to pending. */ + ossl_list_rxe_remove(&qrx->rx_free, rxe); + ossl_list_rxe_insert_tail(&qrx->rx_pending, rxe); + return 0; /* success, did not defer; not distinguished from failure */ + +cannot_decrypt: + /* + * We cannot process this packet right now (but might be able to later). We + * MUST attempt to process any other packets in the datagram, so defer it + * and skip over it. + */ + assert(eop != NULL && eop >= PACKET_data(pkt)); + /* + * We don't care if this fails as it will just result in the packet being at + * the end of the datagram buffer. + */ + ignore_res(PACKET_forward(pkt, eop - PACKET_data(pkt))); + return 1; /* deferred */ + +malformed: + if (eop != NULL) { + /* + * This packet cannot be processed and will never be processable. We + * were at least able to decode its header and determine its length, so + * we can skip over it and try to process any subsequent packets in the + * datagram. + * + * Mark as processed as an optimization. + */ + assert(eop >= PACKET_data(pkt)); + pkt_mark(&urxe->processed, pkt_idx); + /* We don't care if this fails (see above) */ + ignore_res(PACKET_forward(pkt, eop - PACKET_data(pkt))); + } else { + /* + * This packet cannot be processed and will never be processable. + * Because even its header is not intelligible, we cannot examine any + * further packets in the datagram because its length cannot be + * discerned. + * + * Advance over the entire remainder of the datagram, and mark it as + * processed as an optimization. + */ + pkt_mark(&urxe->processed, pkt_idx); + /* We don't care if this fails (see above) */ + ignore_res(PACKET_forward(pkt, PACKET_remaining(pkt))); + } + return 0; /* failure, did not defer; not distinguished from success */ +} + +/* Process a datagram which was received. */ +static int qrx_process_datagram(OSSL_QRX *qrx, QUIC_URXE *e, + const unsigned char *data, + size_t data_len) +{ + int have_deferred = 0; + PACKET pkt; + size_t pkt_idx = 0; + QUIC_CONN_ID first_dcid = { 255 }; + + qrx->bytes_received += data_len; + + if (!PACKET_buf_init(&pkt, data, data_len)) + return 0; + + for (; PACKET_remaining(&pkt) > 0; ++pkt_idx) { + /* + * A packet smaller than the minimum possible QUIC packet size is not + * considered valid. We also ignore more than a certain number of + * packets within the same datagram. + */ + if (PACKET_remaining(&pkt) < QUIC_MIN_VALID_PKT_LEN + || pkt_idx >= QUIC_MAX_PKT_PER_URXE) + break; + + /* + * We note whether packet processing resulted in a deferral since + * this means we need to move the URXE to the deferred list rather + * than the free list after we're finished dealing with it for now. + * + * However, we don't otherwise care here whether processing succeeded or + * failed, as the RFC says even if a packet in a datagram is malformed, + * we should still try to process any packets following it. + * + * In the case where the packet is so malformed we can't determine its + * length, qrx_process_pkt will take care of advancing to the end of + * the packet, so we will exit the loop automatically in this case. + */ + if (qrx_process_pkt(qrx, e, &pkt, pkt_idx, &first_dcid, data_len)) + have_deferred = 1; + } + + /* Only report whether there were any deferrals. */ + return have_deferred; +} + +/* Process a single pending URXE. */ +static int qrx_process_one_urxe(OSSL_QRX *qrx, QUIC_URXE *e) +{ + int was_deferred; + + /* The next URXE we process should be at the head of the pending list. */ + if (!ossl_assert(e == ossl_list_urxe_head(&qrx->urx_pending))) + return 0; + + /* + * Attempt to process the datagram. The return value indicates only if + * processing of the datagram was deferred. If we failed to process the + * datagram, we do not attempt to process it again and silently eat the + * error. + */ + was_deferred = qrx_process_datagram(qrx, e, ossl_quic_urxe_data(e), + e->data_len); + + /* + * Remove the URXE from the pending list and return it to + * either the free or deferred list. + */ + ossl_list_urxe_remove(&qrx->urx_pending, e); + if (was_deferred > 0 && + (e->deferred || qrx->num_deferred < qrx->max_deferred)) { + ossl_list_urxe_insert_tail(&qrx->urx_deferred, e); + if (!e->deferred) { + e->deferred = 1; + ++qrx->num_deferred; + } + } else { + if (e->deferred) { + e->deferred = 0; + --qrx->num_deferred; + } + ossl_quic_demux_release_urxe(qrx->demux, e); + } + + return 1; +} + +/* Process any pending URXEs to generate pending RXEs. */ +static int qrx_process_pending_urxl(OSSL_QRX *qrx) +{ + QUIC_URXE *e; + + while ((e = ossl_list_urxe_head(&qrx->urx_pending)) != NULL) + if (!qrx_process_one_urxe(qrx, e)) + return 0; + + return 1; +} + +int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **ppkt) +{ + RXE *rxe; + + if (!ossl_qrx_processed_read_pending(qrx)) { + if (!qrx_process_pending_urxl(qrx)) + return 0; + + if (!ossl_qrx_processed_read_pending(qrx)) + return 0; + } + + rxe = qrx_pop_pending_rxe(qrx); + if (!ossl_assert(rxe != NULL)) + return 0; + + assert(rxe->refcount == 0); + rxe->refcount = 1; + + rxe->pkt.hdr = &rxe->hdr; + rxe->pkt.pn = rxe->pn; + rxe->pkt.time = rxe->time; + rxe->pkt.datagram_len = rxe->datagram_len; + rxe->pkt.peer + = BIO_ADDR_family(&rxe->peer) != AF_UNSPEC ? &rxe->peer : NULL; + rxe->pkt.local + = BIO_ADDR_family(&rxe->local) != AF_UNSPEC ? &rxe->local : NULL; + rxe->pkt.key_epoch = rxe->key_epoch; + rxe->pkt.qrx = qrx; + *ppkt = &rxe->pkt; + + return 1; +} + +void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt) +{ + RXE *rxe; + + if (pkt == NULL) + return; + + rxe = (RXE *)pkt; + assert(rxe->refcount > 0); + if (--rxe->refcount == 0) + qrx_recycle_rxe(pkt->qrx, rxe); +} + +void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt) +{ + RXE *rxe = (RXE *)pkt; + + assert(rxe->refcount > 0); + ++rxe->refcount; +} + +uint64_t ossl_qrx_get_bytes_received(OSSL_QRX *qrx, int clear) +{ + uint64_t v = qrx->bytes_received; + + if (clear) + qrx->bytes_received = 0; + + return v; +} + +int ossl_qrx_set_late_validation_cb(OSSL_QRX *qrx, + ossl_qrx_late_validation_cb *cb, + void *cb_arg) +{ + qrx->validation_cb = cb; + qrx->validation_cb_arg = cb_arg; + return 1; +} + +int ossl_qrx_set_key_update_cb(OSSL_QRX *qrx, + ossl_qrx_key_update_cb *cb, + void *cb_arg) +{ + qrx->key_update_cb = cb; + qrx->key_update_cb_arg = cb_arg; + return 1; +} + +uint64_t ossl_qrx_get_key_epoch(OSSL_QRX *qrx) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(&qrx->el_set, + QUIC_ENC_LEVEL_1RTT, 1); + + return el == NULL ? UINT64_MAX : el->key_epoch; +} + +int ossl_qrx_key_update_timeout(OSSL_QRX *qrx, int normal) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(&qrx->el_set, + QUIC_ENC_LEVEL_1RTT, 1); + + if (el == NULL) + return 0; + + if (el->state == QRL_EL_STATE_PROV_UPDATING + && !ossl_qrl_enc_level_set_key_update_done(&qrx->el_set, + QUIC_ENC_LEVEL_1RTT)) + return 0; + + if (normal && el->state == QRL_EL_STATE_PROV_COOLDOWN + && !ossl_qrl_enc_level_set_key_cooldown_done(&qrx->el_set, + QUIC_ENC_LEVEL_1RTT)) + return 0; + + return 1; +} + +uint64_t ossl_qrx_get_cur_forged_pkt_count(OSSL_QRX *qrx) +{ + return qrx->forged_pkt_count; +} + +uint64_t ossl_qrx_get_max_forged_pkt_count(OSSL_QRX *qrx, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(&qrx->el_set, + enc_level, 1); + + return el == NULL ? UINT64_MAX + : ossl_qrl_get_suite_max_forged_pkt(el->suite_id); +} + +void ossl_qrx_allow_1rtt_processing(OSSL_QRX *qrx) +{ + if (qrx->allow_1rtt) + return; + + qrx->allow_1rtt = 1; + qrx_requeue_deferred(qrx); +} + +void ossl_qrx_set_msg_callback(OSSL_QRX *qrx, ossl_msg_cb msg_callback, + SSL *msg_callback_ssl) +{ + qrx->msg_callback = msg_callback; + qrx->msg_callback_ssl = msg_callback_ssl; +} + +void ossl_qrx_set_msg_callback_arg(OSSL_QRX *qrx, void *msg_callback_arg) +{ + qrx->msg_callback_arg = msg_callback_arg; +} diff --git a/ssl/quic/quic_record_shared.c b/ssl/quic/quic_record_shared.c new file mode 100644 index 0000000000..a3fd51db6d --- /dev/null +++ b/ssl/quic/quic_record_shared.c @@ -0,0 +1,489 @@ +#include "quic_record_shared.h" +#include "internal/quic_record_util.h" +#include "internal/common.h" +#include "../ssl_local.h" + +/* Constants used for key derivation in QUIC v1. */ +static const unsigned char quic_v1_iv_label[] = { + 0x71, 0x75, 0x69, 0x63, 0x20, 0x69, 0x76 /* "quic iv" */ +}; +static const unsigned char quic_v1_key_label[] = { + 0x71, 0x75, 0x69, 0x63, 0x20, 0x6b, 0x65, 0x79 /* "quic key" */ +}; +static const unsigned char quic_v1_hp_label[] = { + 0x71, 0x75, 0x69, 0x63, 0x20, 0x68, 0x70 /* "quic hp" */ +}; +static const unsigned char quic_v1_ku_label[] = { + 0x71, 0x75, 0x69, 0x63, 0x20, 0x6b, 0x75 /* "quic ku" */ +}; + +OSSL_QRL_ENC_LEVEL *ossl_qrl_enc_level_set_get(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + int require_prov) +{ + OSSL_QRL_ENC_LEVEL *el; + + if (!ossl_assert(enc_level < QUIC_ENC_LEVEL_NUM)) + return NULL; + + el = &els->el[enc_level]; + + if (require_prov) + switch (el->state) { + case QRL_EL_STATE_PROV_NORMAL: + case QRL_EL_STATE_PROV_UPDATING: + case QRL_EL_STATE_PROV_COOLDOWN: + break; + default: + return NULL; + } + + return el; +} + +int ossl_qrl_enc_level_set_have_el(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + + switch (el->state) { + case QRL_EL_STATE_UNPROV: + return 0; + case QRL_EL_STATE_PROV_NORMAL: + case QRL_EL_STATE_PROV_UPDATING: + case QRL_EL_STATE_PROV_COOLDOWN: + return 1; + default: + case QRL_EL_STATE_DISCARDED: + return -1; + } +} + +int ossl_qrl_enc_level_set_has_keyslot(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + unsigned char tgt_state, + size_t keyslot) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + + if (!ossl_assert(el != NULL && keyslot < 2)) + return 0; + + switch (tgt_state) { + case QRL_EL_STATE_PROV_NORMAL: + case QRL_EL_STATE_PROV_UPDATING: + return enc_level == QUIC_ENC_LEVEL_1RTT || keyslot == 0; + case QRL_EL_STATE_PROV_COOLDOWN: + assert(enc_level == QUIC_ENC_LEVEL_1RTT); + return keyslot == (el->key_epoch & 1); + default: + return 0; + } +} + +static void el_teardown_keyslot(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + size_t keyslot) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + + if (!ossl_qrl_enc_level_set_has_keyslot(els, enc_level, el->state, keyslot)) + return; + + if (el->cctx[keyslot] != NULL) { + EVP_CIPHER_CTX_free(el->cctx[keyslot]); + el->cctx[keyslot] = NULL; + } + + OPENSSL_cleanse(el->iv[keyslot], sizeof(el->iv[keyslot])); +} + +static int el_setup_keyslot(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + unsigned char tgt_state, + size_t keyslot, + const unsigned char *secret, + size_t secret_len) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + unsigned char key[EVP_MAX_KEY_LENGTH]; + size_t key_len = 0, iv_len = 0; + const char *cipher_name = NULL; + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *cctx = NULL; + + if (!ossl_assert(el != NULL + && ossl_qrl_enc_level_set_has_keyslot(els, enc_level, + tgt_state, keyslot))) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + cipher_name = ossl_qrl_get_suite_cipher_name(el->suite_id); + iv_len = ossl_qrl_get_suite_cipher_iv_len(el->suite_id); + key_len = ossl_qrl_get_suite_cipher_key_len(el->suite_id); + if (cipher_name == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (secret_len != ossl_qrl_get_suite_secret_len(el->suite_id) + || secret_len > EVP_MAX_KEY_LENGTH) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + assert(el->cctx[keyslot] == NULL); + + /* Derive "quic iv" key. */ + if (!tls13_hkdf_expand_ex(el->libctx, el->propq, + el->md, + secret, + quic_v1_iv_label, + sizeof(quic_v1_iv_label), + NULL, 0, + el->iv[keyslot], iv_len, 1)) + goto err; + + /* Derive "quic key" key. */ + if (!tls13_hkdf_expand_ex(el->libctx, el->propq, + el->md, + secret, + quic_v1_key_label, + sizeof(quic_v1_key_label), + NULL, 0, + key, key_len, 1)) + goto err; + + /* Create and initialise cipher context. */ + if ((cipher = EVP_CIPHER_fetch(el->libctx, cipher_name, el->propq)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + if (!ossl_assert(iv_len == (size_t)EVP_CIPHER_get_iv_length(cipher)) + || !ossl_assert(key_len == (size_t)EVP_CIPHER_get_key_length(cipher))) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* IV will be changed on RX/TX so we don't need to use a real value here. */ + if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, el->iv[keyslot], 0)) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + el->cctx[keyslot] = cctx; + + /* Zeroize intermediate keys. */ + OPENSSL_cleanse(key, sizeof(key)); + EVP_CIPHER_free(cipher); + return 1; + + err: + EVP_CIPHER_CTX_free(cctx); + EVP_CIPHER_free(cipher); + OPENSSL_cleanse(el->iv[keyslot], sizeof(el->iv[keyslot])); + OPENSSL_cleanse(key, sizeof(key)); + return 0; +} + +int ossl_qrl_enc_level_set_provide_secret(OSSL_QRL_ENC_LEVEL_SET *els, + OSSL_LIB_CTX *libctx, + const char *propq, + uint32_t enc_level, + uint32_t suite_id, + EVP_MD *md, + const unsigned char *secret, + size_t secret_len, + unsigned char init_key_phase_bit, + int is_tx) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + unsigned char ku_key[EVP_MAX_KEY_LENGTH], hpr_key[EVP_MAX_KEY_LENGTH]; + int have_ks0 = 0, have_ks1 = 0, own_md = 0; + const char *md_name = ossl_qrl_get_suite_md_name(suite_id); + size_t hpr_key_len, init_keyslot; + + if (el == NULL + || md_name == NULL + || init_key_phase_bit > 1 || is_tx < 0 || is_tx > 1 + || (init_key_phase_bit > 0 && enc_level != QUIC_ENC_LEVEL_1RTT)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (enc_level == QUIC_ENC_LEVEL_INITIAL + && el->state == QRL_EL_STATE_PROV_NORMAL) { + /* + * Sometimes the INITIAL EL needs to be reprovisioned, namely if a + * connection retry occurs. Exceptionally, if the caller wants to + * reprovision the INITIAL EL, tear it down as usual and then override + * the state so it can be provisioned again. + */ + ossl_qrl_enc_level_set_discard(els, enc_level); + el->state = QRL_EL_STATE_UNPROV; + } + + if (el->state != QRL_EL_STATE_UNPROV) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + init_keyslot = is_tx ? 0 : init_key_phase_bit; + hpr_key_len = ossl_qrl_get_suite_hdr_prot_key_len(suite_id); + if (hpr_key_len == 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (md == NULL) { + md = EVP_MD_fetch(libctx, md_name, propq); + if (md == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + own_md = 1; + } + + el->libctx = libctx; + el->propq = propq; + el->md = md; + el->suite_id = suite_id; + el->tag_len = ossl_qrl_get_suite_cipher_tag_len(suite_id); + el->op_count = 0; + el->key_epoch = (uint64_t)init_key_phase_bit; + el->is_tx = (unsigned char)is_tx; + + /* Derive "quic hp" key. */ + if (!tls13_hkdf_expand_ex(libctx, propq, + md, + secret, + quic_v1_hp_label, + sizeof(quic_v1_hp_label), + NULL, 0, + hpr_key, hpr_key_len, 1)) + goto err; + + /* Setup KS0 (or KS1 if init_key_phase_bit), our initial keyslot. */ + if (!el_setup_keyslot(els, enc_level, QRL_EL_STATE_PROV_NORMAL, + init_keyslot, secret, secret_len)) + goto err; + + have_ks0 = 1; + + if (enc_level == QUIC_ENC_LEVEL_1RTT) { + /* Derive "quic ku" key (the epoch 1 secret). */ + if (!tls13_hkdf_expand_ex(libctx, propq, + md, + secret, + quic_v1_ku_label, + sizeof(quic_v1_ku_label), + NULL, 0, + is_tx ? el->ku : ku_key, secret_len, 1)) + goto err; + + if (!is_tx) { + /* Setup KS1 (or KS0 if init_key_phase_bit), our next keyslot. */ + if (!el_setup_keyslot(els, enc_level, QRL_EL_STATE_PROV_NORMAL, + !init_keyslot, ku_key, secret_len)) + goto err; + + have_ks1 = 1; + + /* Derive NEXT "quic ku" key (the epoch 2 secret). */ + if (!tls13_hkdf_expand_ex(libctx, propq, + md, + ku_key, + quic_v1_ku_label, + sizeof(quic_v1_ku_label), + NULL, 0, + el->ku, secret_len, 1)) + goto err; + } + } + + /* Setup header protection context. */ + if (!ossl_quic_hdr_protector_init(&el->hpr, + libctx, propq, + ossl_qrl_get_suite_hdr_prot_cipher_id(suite_id), + hpr_key, hpr_key_len)) + goto err; + + /* + * We are now provisioned: KS0 has our current key (for key epoch 0), KS1 + * has our next key (for key epoch 1, in the case of the 1-RTT EL only), and + * el->ku has the secret which will be used to generate keys for key epoch + * 2. + */ + OPENSSL_cleanse(hpr_key, sizeof(hpr_key)); + OPENSSL_cleanse(ku_key, sizeof(ku_key)); + el->state = QRL_EL_STATE_PROV_NORMAL; + return 1; + + err: + el->suite_id = 0; + el->md = NULL; + OPENSSL_cleanse(hpr_key, sizeof(hpr_key)); + OPENSSL_cleanse(ku_key, sizeof(ku_key)); + OPENSSL_cleanse(el->ku, sizeof(el->ku)); + if (have_ks0) + el_teardown_keyslot(els, enc_level, init_keyslot); + if (have_ks1) + el_teardown_keyslot(els, enc_level, !init_keyslot); + if (own_md) + EVP_MD_free(md); + return 0; +} + +int ossl_qrl_enc_level_set_key_update(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + size_t secret_len; + unsigned char new_ku[EVP_MAX_KEY_LENGTH]; + + if (el == NULL || !ossl_assert(enc_level == QUIC_ENC_LEVEL_1RTT)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (el->state != QRL_EL_STATE_PROV_NORMAL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!el->is_tx) { + /* + * We already have the key for the next epoch, so just move to using it. + */ + ++el->key_epoch; + el->state = QRL_EL_STATE_PROV_UPDATING; + return 1; + } + + /* + * TX case. For the TX side we use only keyslot 0; it replaces the old key + * immediately. + */ + secret_len = ossl_qrl_get_suite_secret_len(el->suite_id); + + /* Derive NEXT "quic ku" key (the epoch n+1 secret). */ + if (!tls13_hkdf_expand_ex(el->libctx, el->propq, + el->md, el->ku, + quic_v1_ku_label, + sizeof(quic_v1_ku_label), + NULL, 0, + new_ku, secret_len, 1)) + return 0; + + el_teardown_keyslot(els, enc_level, 0); + + /* Setup keyslot for CURRENT "quic ku" key. */ + if (!el_setup_keyslot(els, enc_level, QRL_EL_STATE_PROV_NORMAL, + 0, el->ku, secret_len)) + return 0; + + ++el->key_epoch; + el->op_count = 0; + memcpy(el->ku, new_ku, secret_len); + /* Remain in PROV_NORMAL state */ + return 1; +} + +/* Transitions from PROV_UPDATING to PROV_COOLDOWN. */ +int ossl_qrl_enc_level_set_key_update_done(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + + if (el == NULL || !ossl_assert(enc_level == QUIC_ENC_LEVEL_1RTT)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + /* No new key yet, but erase key material to aid PFS. */ + el_teardown_keyslot(els, enc_level, ~el->key_epoch & 1); + el->state = QRL_EL_STATE_PROV_COOLDOWN; + return 1; +} + +/* + * Transitions from PROV_COOLDOWN to PROV_NORMAL. (If in PROV_UPDATING, + * auto-transitions to PROV_COOLDOWN first.) + */ +int ossl_qrl_enc_level_set_key_cooldown_done(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + size_t secret_len; + unsigned char new_ku[EVP_MAX_KEY_LENGTH]; + + if (el == NULL || !ossl_assert(enc_level == QUIC_ENC_LEVEL_1RTT)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (el->state == QRL_EL_STATE_PROV_UPDATING + && !ossl_qrl_enc_level_set_key_update_done(els, enc_level)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (el->state != QRL_EL_STATE_PROV_COOLDOWN) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + secret_len = ossl_qrl_get_suite_secret_len(el->suite_id); + + if (!el_setup_keyslot(els, enc_level, QRL_EL_STATE_PROV_NORMAL, + ~el->key_epoch & 1, el->ku, secret_len)) + return 0; + + /* Derive NEXT "quic ku" key (the epoch n+1 secret). */ + if (!tls13_hkdf_expand_ex(el->libctx, el->propq, + el->md, + el->ku, + quic_v1_ku_label, + sizeof(quic_v1_ku_label), + NULL, 0, + new_ku, secret_len, 1)) { + el_teardown_keyslot(els, enc_level, ~el->key_epoch & 1); + return 0; + } + + memcpy(el->ku, new_ku, secret_len); + el->state = QRL_EL_STATE_PROV_NORMAL; + return 1; +} + +/* + * Discards keying material for a given encryption level. Transitions from any + * state to DISCARDED. + */ +void ossl_qrl_enc_level_set_discard(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el = ossl_qrl_enc_level_set_get(els, enc_level, 0); + + if (el == NULL || el->state == QRL_EL_STATE_DISCARDED) + return; + + if (ossl_qrl_enc_level_set_have_el(els, enc_level) == 1) { + ossl_quic_hdr_protector_cleanup(&el->hpr); + + el_teardown_keyslot(els, enc_level, 0); + el_teardown_keyslot(els, enc_level, 1); + } + + EVP_MD_free(el->md); + el->md = NULL; + el->state = QRL_EL_STATE_DISCARDED; +} diff --git a/ssl/quic/quic_record_shared.h b/ssl/quic/quic_record_shared.h new file mode 100644 index 0000000000..e8c9e28e92 --- /dev/null +++ b/ssl/quic/quic_record_shared.h @@ -0,0 +1,150 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RECORD_SHARED_H +# define OSSL_QUIC_RECORD_SHARED_H + +# include +# include "internal/quic_types.h" +# include "internal/quic_wire_pkt.h" + +/* + * QUIC Record Layer EL Management Utilities + * ========================================= + * + * This defines a structure for managing the cryptographic state at a given + * encryption level, as this functionality is shared between QRX and QTX. For + * QRL use only. + */ + +/* + * States an EL can be in. The Updating and Cooldown states are used by RX only; + * a TX EL in the Provisioned state is always in the Normal substate. + * + * Key material is available if in the Provisioned state. + */ +#define QRL_EL_STATE_UNPROV 0 /* Unprovisioned (initial state) */ +#define QRL_EL_STATE_PROV_NORMAL 1 /* Provisioned - Normal */ +#define QRL_EL_STATE_PROV_UPDATING 2 /* Provisioned - Updating */ +#define QRL_EL_STATE_PROV_COOLDOWN 3 /* Provisioned - Cooldown */ +#define QRL_EL_STATE_DISCARDED 4 /* Discarded (terminal state) */ + +typedef struct ossl_qrl_enc_level_st { + /* + * Cryptographic context used to apply and remove header protection from + * packet headers. + */ + QUIC_HDR_PROTECTOR hpr; + + /* Hash function used for key derivation. */ + EVP_MD *md; + + /* Context used for packet body ciphering. One for each keyslot. */ + EVP_CIPHER_CTX *cctx[2]; + + OSSL_LIB_CTX *libctx; + const char *propq; + + /* + * Key epoch, essentially the number of times we have done a key update. + * + * The least significant bit of this is therefore by definition the current + * Key Phase bit value. + */ + uint64_t key_epoch; + + /* Usage counter. The caller maintains this. Used by TX side only. */ + uint64_t op_count; + + /* QRL_SUITE_* value. */ + uint32_t suite_id; + + /* Length of authentication tag. */ + uint32_t tag_len; + + /* Current EL state. */ + unsigned char state; /* QRL_EL_STATE_* */ + + /* 1 if for TX, else RX. Initialised when secret provided. */ + unsigned char is_tx; + + /* IV used to construct nonces used for AEAD packet body ciphering. */ + unsigned char iv[2][EVP_MAX_IV_LENGTH]; + + /* + * Secret for next key epoch. + */ + unsigned char ku[EVP_MAX_KEY_LENGTH]; +} OSSL_QRL_ENC_LEVEL; + +typedef struct ossl_qrl_enc_level_set_st { + OSSL_QRL_ENC_LEVEL el[QUIC_ENC_LEVEL_NUM]; +} OSSL_QRL_ENC_LEVEL_SET; + +/* + * Returns 1 if we have key material for a given encryption level (that is, if + * we are in the PROVISIONED state), 0 if we do not yet have material (we are in + * the UNPROVISIONED state) and -1 if the EL is discarded (we are in the + * DISCARDED state). + */ +int ossl_qrl_enc_level_set_have_el(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level); + +/* + * Returns EL in a set. If enc_level is not a valid QUIC_ENC_LEVEL_* value, + * returns NULL. If require_prov is 1, returns NULL if the EL is not in + * the PROVISIONED state; otherwise, the returned EL may be in any state. + */ +OSSL_QRL_ENC_LEVEL *ossl_qrl_enc_level_set_get(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + int require_prov); + +/* Provide secret to an EL. md may be NULL. */ +int ossl_qrl_enc_level_set_provide_secret(OSSL_QRL_ENC_LEVEL_SET *els, + OSSL_LIB_CTX *libctx, + const char *propq, + uint32_t enc_level, + uint32_t suite_id, + EVP_MD *md, + const unsigned char *secret, + size_t secret_len, + unsigned char init_key_phase_bit, + int is_tx); + +/* + * Returns 1 if the given keyslot index is currently valid for a given EL and EL + * state. + */ +int ossl_qrl_enc_level_set_has_keyslot(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level, + unsigned char tgt_state, + size_t keyslot); + +/* Perform a key update. Transitions from PROV_NORMAL to PROV_UPDATING. */ +int ossl_qrl_enc_level_set_key_update(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level); + +/* Transitions from PROV_UPDATING to PROV_COOLDOWN. */ +int ossl_qrl_enc_level_set_key_update_done(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level); + +/* + * Transitions from PROV_COOLDOWN to PROV_NORMAL. (If in PROV_UPDATING, + * auto-transitions to PROV_COOLDOWN first.) + */ +int ossl_qrl_enc_level_set_key_cooldown_done(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level); + +/* + * Discard an EL. No secret can be provided for the EL ever again. + */ +void ossl_qrl_enc_level_set_discard(OSSL_QRL_ENC_LEVEL_SET *els, + uint32_t enc_level); + +#endif diff --git a/ssl/quic/quic_record_tx.c b/ssl/quic/quic_record_tx.c new file mode 100644 index 0000000000..c01abed0d6 --- /dev/null +++ b/ssl/quic/quic_record_tx.c @@ -0,0 +1,1061 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_record_tx.h" +#include "internal/bio_addr.h" +#include "internal/common.h" +#include "quic_record_shared.h" +#include "internal/list.h" +#include "../ssl_local.h" + +/* + * TXE + * === + * Encrypted packets awaiting transmission are kept in TX Entries (TXEs), which + * are queued in linked lists just like TXEs. + */ +typedef struct txe_st TXE; + +struct txe_st { + OSSL_LIST_MEMBER(txe, TXE); + size_t data_len, alloc_len; + + /* + * Destination and local addresses, as applicable. Both of these are only + * used if the family is not AF_UNSPEC. + */ + BIO_ADDR peer, local; + + /* + * alloc_len allocated bytes (of which data_len bytes are valid) follow this + * structure. + */ +}; + +DEFINE_LIST_OF(txe, TXE); +typedef OSSL_LIST(txe) TXE_LIST; + +static ossl_inline unsigned char *txe_data(const TXE *e) +{ + return (unsigned char *)(e + 1); +} + +/* + * QTX + * === + */ +struct ossl_qtx_st { + OSSL_LIB_CTX *libctx; + const char *propq; + + /* Per encryption-level state. */ + OSSL_QRL_ENC_LEVEL_SET el_set; + + /* TX BIO. */ + BIO *bio; + + /* TX maximum datagram payload length. */ + size_t mdpl; + + /* + * List of TXEs which are not currently in use. These are moved to the + * pending list (possibly via tx_cons first) as they are filled. + */ + TXE_LIST free; + + /* + * List of TXEs which are filled with completed datagrams ready to be + * transmitted. + */ + TXE_LIST pending; + size_t pending_count; /* items in list */ + size_t pending_bytes; /* sum(txe->data_len) in pending */ + + /* + * TXE which is under construction for coalescing purposes, if any. + * This TXE is neither on the free nor pending list. Once the datagram + * is completed, it is moved to the pending list. + */ + TXE *cons; + size_t cons_count; /* num packets */ + + /* + * Number of packets transmitted in this key epoch. Used to enforce AEAD + * confidentiality limit. + */ + uint64_t epoch_pkt_count; + + ossl_mutate_packet_cb mutatecb; + ossl_finish_mutate_cb finishmutatecb; + void *mutatearg; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_ssl; +}; + +/* Instantiates a new QTX. */ +OSSL_QTX *ossl_qtx_new(const OSSL_QTX_ARGS *args) +{ + OSSL_QTX *qtx; + + if (args->mdpl < QUIC_MIN_INITIAL_DGRAM_LEN) + return 0; + + qtx = OPENSSL_zalloc(sizeof(OSSL_QTX)); + if (qtx == NULL) + return 0; + + qtx->libctx = args->libctx; + qtx->propq = args->propq; + qtx->bio = args->bio; + qtx->mdpl = args->mdpl; + return qtx; +} + +static void qtx_cleanup_txl(TXE_LIST *l) +{ + TXE *e, *enext; + + for (e = ossl_list_txe_head(l); e != NULL; e = enext) { + enext = ossl_list_txe_next(e); + OPENSSL_free(e); + } +} + +/* Frees the QTX. */ +void ossl_qtx_free(OSSL_QTX *qtx) +{ + uint32_t i; + + if (qtx == NULL) + return; + + /* Free TXE queue data. */ + qtx_cleanup_txl(&qtx->pending); + qtx_cleanup_txl(&qtx->free); + OPENSSL_free(qtx->cons); + + /* Drop keying material and crypto resources. */ + for (i = 0; i < QUIC_ENC_LEVEL_NUM; ++i) + ossl_qrl_enc_level_set_discard(&qtx->el_set, i); + + OPENSSL_free(qtx); +} + +/* Set mutator callbacks for test framework support */ +void ossl_qtx_set_mutator(OSSL_QTX *qtx, ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, void *mutatearg) +{ + qtx->mutatecb = mutatecb; + qtx->finishmutatecb = finishmutatecb; + qtx->mutatearg = mutatearg; +} + +int ossl_qtx_provide_secret(OSSL_QTX *qtx, + uint32_t enc_level, + uint32_t suite_id, + EVP_MD *md, + const unsigned char *secret, + size_t secret_len) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM) + return 0; + + return ossl_qrl_enc_level_set_provide_secret(&qtx->el_set, + qtx->libctx, + qtx->propq, + enc_level, + suite_id, + md, + secret, + secret_len, + 0, + /*is_tx=*/1); +} + +int ossl_qtx_discard_enc_level(OSSL_QTX *qtx, uint32_t enc_level) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM) + return 0; + + ossl_qrl_enc_level_set_discard(&qtx->el_set, enc_level); + return 1; +} + +int ossl_qtx_is_enc_level_provisioned(OSSL_QTX *qtx, uint32_t enc_level) +{ + return ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1) != NULL; +} + +/* Allocate a new TXE. */ +static TXE *qtx_alloc_txe(size_t alloc_len) +{ + TXE *txe; + + if (alloc_len >= SIZE_MAX - sizeof(TXE)) + return NULL; + + txe = OPENSSL_malloc(sizeof(TXE) + alloc_len); + if (txe == NULL) + return NULL; + + ossl_list_txe_init_elem(txe); + txe->alloc_len = alloc_len; + txe->data_len = 0; + return txe; +} + +/* + * Ensures there is at least one TXE in the free list, allocating a new entry + * if necessary. The returned TXE is in the free list; it is not popped. + * + * alloc_len is a hint which may be used to determine the TXE size if allocation + * is necessary. Returns NULL on allocation failure. + */ +static TXE *qtx_ensure_free_txe(OSSL_QTX *qtx, size_t alloc_len) +{ + TXE *txe; + + txe = ossl_list_txe_head(&qtx->free); + if (txe != NULL) + return txe; + + txe = qtx_alloc_txe(alloc_len); + if (txe == NULL) + return NULL; + + ossl_list_txe_insert_tail(&qtx->free, txe); + return txe; +} + +/* + * Resize the data buffer attached to an TXE to be n bytes in size. The address + * of the TXE might change; the new address is returned, or NULL on failure, in + * which case the original TXE remains valid. + */ +static TXE *qtx_resize_txe(OSSL_QTX *qtx, TXE_LIST *txl, TXE *txe, size_t n) +{ + TXE *txe2, *p; + + /* Should never happen. */ + if (txe == NULL) + return NULL; + + if (n >= SIZE_MAX - sizeof(TXE)) + return NULL; + + /* Remove the item from the list to avoid accessing freed memory */ + p = ossl_list_txe_prev(txe); + ossl_list_txe_remove(txl, txe); + + /* + * NOTE: We do not clear old memory, although it does contain decrypted + * data. + */ + txe2 = OPENSSL_realloc(txe, sizeof(TXE) + n); + if (txe2 == NULL || txe == txe2) { + if (p == NULL) + ossl_list_txe_insert_head(txl, txe); + else + ossl_list_txe_insert_after(txl, p, txe); + return txe2; + } + + if (p == NULL) + ossl_list_txe_insert_head(txl, txe2); + else + ossl_list_txe_insert_after(txl, p, txe2); + + if (qtx->cons == txe) + qtx->cons = txe2; + + txe2->alloc_len = n; + return txe2; +} + +/* + * Ensure the data buffer attached to an TXE is at least n bytes in size. + * Returns NULL on failure. + */ +static TXE *qtx_reserve_txe(OSSL_QTX *qtx, TXE_LIST *txl, + TXE *txe, size_t n) +{ + if (txe->alloc_len >= n) + return txe; + + return qtx_resize_txe(qtx, txl, txe, n); +} + +/* Move a TXE from pending to free. */ +static void qtx_pending_to_free(OSSL_QTX *qtx) +{ + TXE *txe = ossl_list_txe_head(&qtx->pending); + + assert(txe != NULL); + ossl_list_txe_remove(&qtx->pending, txe); + --qtx->pending_count; + qtx->pending_bytes -= txe->data_len; + ossl_list_txe_insert_tail(&qtx->free, txe); +} + +/* Add a TXE not currently in any list to the pending list. */ +static void qtx_add_to_pending(OSSL_QTX *qtx, TXE *txe) +{ + ossl_list_txe_insert_tail(&qtx->pending, txe); + ++qtx->pending_count; + qtx->pending_bytes += txe->data_len; +} + +struct iovec_cur { + const OSSL_QTX_IOVEC *iovec; + size_t num_iovec, idx, byte_off, bytes_remaining; +}; + +static size_t iovec_total_bytes(const OSSL_QTX_IOVEC *iovec, + size_t num_iovec) +{ + size_t i, l = 0; + + for (i = 0; i < num_iovec; ++i) + l += iovec[i].buf_len; + + return l; +} + +static void iovec_cur_init(struct iovec_cur *cur, + const OSSL_QTX_IOVEC *iovec, + size_t num_iovec) +{ + cur->iovec = iovec; + cur->num_iovec = num_iovec; + cur->idx = 0; + cur->byte_off = 0; + cur->bytes_remaining = iovec_total_bytes(iovec, num_iovec); +} + +/* + * Get an extent of bytes from the iovec cursor. *buf is set to point to the + * buffer and the number of bytes in length of the buffer is returned. This + * value may be less than the max_buf_len argument. If no more data is + * available, returns 0. + */ +static size_t iovec_cur_get_buffer(struct iovec_cur *cur, + const unsigned char **buf, + size_t max_buf_len) +{ + size_t l; + + if (max_buf_len == 0) { + *buf = NULL; + return 0; + } + + for (;;) { + if (cur->idx >= cur->num_iovec) + return 0; + + l = cur->iovec[cur->idx].buf_len - cur->byte_off; + if (l > max_buf_len) + l = max_buf_len; + + if (l > 0) { + *buf = cur->iovec[cur->idx].buf + cur->byte_off; + cur->byte_off += l; + cur->bytes_remaining -= l; + return l; + } + + /* + * Zero-length iovec entry or we already consumed all of it, try the + * next iovec. + */ + ++cur->idx; + cur->byte_off = 0; + } +} + +/* Determines the size of the AEAD output given the input size. */ +int ossl_qtx_calculate_ciphertext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, + size_t plaintext_len, + size_t *ciphertext_len) +{ + OSSL_QRL_ENC_LEVEL *el + = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + size_t tag_len; + + if (el == NULL) { + *ciphertext_len = 0; + return 0; + } + + /* + * We currently only support ciphers with a 1:1 mapping between plaintext + * and ciphertext size, save for authentication tag. + */ + tag_len = ossl_qrl_get_suite_cipher_tag_len(el->suite_id); + + *ciphertext_len = plaintext_len + tag_len; + return 1; +} + +/* Determines the size of the AEAD input given the output size. */ +int ossl_qtx_calculate_plaintext_payload_len(OSSL_QTX *qtx, uint32_t enc_level, + size_t ciphertext_len, + size_t *plaintext_len) +{ + OSSL_QRL_ENC_LEVEL *el + = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + size_t tag_len; + + if (el == NULL) { + *plaintext_len = 0; + return 0; + } + + tag_len = ossl_qrl_get_suite_cipher_tag_len(el->suite_id); + + if (ciphertext_len <= tag_len) { + *plaintext_len = 0; + return 0; + } + + *plaintext_len = ciphertext_len - tag_len; + return 1; +} + +/* Any other error (including packet being too big for MDPL). */ +#define QTX_FAIL_GENERIC (-1) + +/* + * Returned where there is insufficient room in the datagram to write the + * packet. + */ +#define QTX_FAIL_INSUFFICIENT_LEN (-2) + +static int qtx_write_hdr(OSSL_QTX *qtx, const QUIC_PKT_HDR *hdr, TXE *txe, + QUIC_PKT_HDR_PTRS *ptrs) +{ + WPACKET wpkt; + size_t l = 0; + unsigned char *data = txe_data(txe) + txe->data_len; + + if (!WPACKET_init_static_len(&wpkt, data, txe->alloc_len - txe->data_len, 0)) + return 0; + + if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr->dst_conn_id.id_len, + hdr, ptrs) + || !WPACKET_get_total_written(&wpkt, &l)) { + WPACKET_finish(&wpkt); + return 0; + } + WPACKET_finish(&wpkt); + + if (qtx->msg_callback != NULL) + qtx->msg_callback(1, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, data, l, + qtx->msg_callback_ssl, qtx->msg_callback_arg); + + txe->data_len += l; + + return 1; +} + +static int qtx_encrypt_into_txe(OSSL_QTX *qtx, struct iovec_cur *cur, TXE *txe, + uint32_t enc_level, QUIC_PN pn, + const unsigned char *hdr, size_t hdr_len, + QUIC_PKT_HDR_PTRS *ptrs) +{ + int l = 0, l2 = 0, nonce_len; + OSSL_QRL_ENC_LEVEL *el + = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + unsigned char nonce[EVP_MAX_IV_LENGTH]; + size_t i; + EVP_CIPHER_CTX *cctx = NULL; + + /* We should not have been called if we do not have key material. */ + if (!ossl_assert(el != NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* + * Have we already encrypted the maximum number of packets using the current + * key? + */ + if (el->op_count >= ossl_qrl_get_suite_max_pkt(el->suite_id)) { + ERR_raise(ERR_LIB_SSL, SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED); + return 0; + } + + /* + * TX key update is simpler than for RX; once we initiate a key update, we + * never need the old keys, as we never deliberately send a packet with old + * keys. Thus the EL always uses keyslot 0 for the TX side. + */ + cctx = el->cctx[0]; + if (!ossl_assert(cctx != NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Construct nonce (nonce=IV ^ PN). */ + nonce_len = EVP_CIPHER_CTX_get_iv_length(cctx); + if (!ossl_assert(nonce_len >= (int)sizeof(QUIC_PN))) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + memcpy(nonce, el->iv[0], (size_t)nonce_len); + for (i = 0; i < sizeof(QUIC_PN); ++i) + nonce[nonce_len - i - 1] ^= (unsigned char)(pn >> (i * 8)); + + /* type and key will already have been setup; feed the IV. */ + if (EVP_CipherInit_ex(cctx, NULL, NULL, NULL, nonce, /*enc=*/1) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + /* Feed AAD data. */ + if (EVP_CipherUpdate(cctx, NULL, &l, hdr, hdr_len) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + /* Encrypt plaintext directly into TXE. */ + for (;;) { + const unsigned char *src; + size_t src_len; + + src_len = iovec_cur_get_buffer(cur, &src, SIZE_MAX); + if (src_len == 0) + break; + + if (EVP_CipherUpdate(cctx, txe_data(txe) + txe->data_len, + &l, src, src_len) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Ignore what we just encrypted and overwrite it with the plaintext */ + memcpy(txe_data(txe) + txe->data_len, src, l); +#endif + + assert(l > 0 && src_len == (size_t)l); + txe->data_len += src_len; + } + + /* Finalise and get tag. */ + if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, + el->tag_len, txe_data(txe) + txe->data_len) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + txe->data_len += el->tag_len; + + /* Apply header protection. */ + if (!ossl_quic_hdr_protector_encrypt(&el->hpr, ptrs)) + return 0; + + ++el->op_count; + return 1; +} + +/* + * Append a packet to the TXE buffer, serializing and encrypting it in the + * process. + */ +static int qtx_write(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt, TXE *txe, + uint32_t enc_level) +{ + int ret, needs_encrypt; + size_t hdr_len, pred_hdr_len, payload_len, pkt_len, space_left; + size_t min_len, orig_data_len; + struct iovec_cur cur; + QUIC_PKT_HDR_PTRS ptrs; + unsigned char *hdr_start; + OSSL_QRL_ENC_LEVEL *el = NULL; + QUIC_PKT_HDR *hdr; + const OSSL_QTX_IOVEC *iovec; + size_t num_iovec; + + /* + * Determine if the packet needs encryption and the minimum conceivable + * serialization length. + */ + if (!ossl_quic_pkt_type_is_encrypted(pkt->hdr->type)) { + needs_encrypt = 0; + min_len = QUIC_MIN_VALID_PKT_LEN; + } else { + needs_encrypt = 1; + min_len = QUIC_MIN_VALID_PKT_LEN_CRYPTO; + el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + if (!ossl_assert(el != NULL)) /* should already have been checked */ + return 0; + } + + orig_data_len = txe->data_len; + space_left = txe->alloc_len - txe->data_len; + if (space_left < min_len) { + /* Not even a possibility of it fitting. */ + ret = QTX_FAIL_INSUFFICIENT_LEN; + goto err; + } + + /* Set some fields in the header we are responsible for. */ + if (pkt->hdr->type == QUIC_PKT_TYPE_1RTT) + pkt->hdr->key_phase = (unsigned char)(el->key_epoch & 1); + + /* If we are running tests then mutate_packet may be non NULL */ + if (qtx->mutatecb != NULL) { + if (!qtx->mutatecb(pkt->hdr, pkt->iovec, pkt->num_iovec, &hdr, + &iovec, &num_iovec, qtx->mutatearg)) { + ret = QTX_FAIL_GENERIC; + goto err; + } + } else { + hdr = pkt->hdr; + iovec = pkt->iovec; + num_iovec = pkt->num_iovec; + } + + /* Walk the iovecs to determine actual input payload length. */ + iovec_cur_init(&cur, iovec, num_iovec); + + if (cur.bytes_remaining == 0) { + /* No zero-length payloads allowed. */ + ret = QTX_FAIL_GENERIC; + goto err; + } + + /* Determine encrypted payload length. */ + if (needs_encrypt) + ossl_qtx_calculate_ciphertext_payload_len(qtx, enc_level, + cur.bytes_remaining, + &payload_len); + else + payload_len = cur.bytes_remaining; + + /* Determine header length. */ + hdr->data = NULL; + hdr->len = payload_len; + pred_hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(hdr->dst_conn_id.id_len, + hdr); + if (pred_hdr_len == 0) { + ret = QTX_FAIL_GENERIC; + goto err; + } + + /* We now definitively know our packet length. */ + pkt_len = pred_hdr_len + payload_len; + + if (pkt_len > space_left) { + ret = QTX_FAIL_INSUFFICIENT_LEN; + goto err; + } + + if (ossl_quic_pkt_type_has_pn(hdr->type)) { + if (!ossl_quic_wire_encode_pkt_hdr_pn(pkt->pn, + hdr->pn, + hdr->pn_len)) { + ret = QTX_FAIL_GENERIC; + goto err; + } + } + + /* Append the header to the TXE. */ + hdr_start = txe_data(txe) + txe->data_len; + if (!qtx_write_hdr(qtx, hdr, txe, &ptrs)) { + ret = QTX_FAIL_GENERIC; + goto err; + } + + hdr_len = (txe_data(txe) + txe->data_len) - hdr_start; + assert(hdr_len == pred_hdr_len); + + if (!needs_encrypt) { + /* Just copy the payload across. */ + const unsigned char *src; + size_t src_len; + + for (;;) { + /* Buffer length has already been checked above. */ + src_len = iovec_cur_get_buffer(&cur, &src, SIZE_MAX); + if (src_len == 0) + break; + + memcpy(txe_data(txe) + txe->data_len, src, src_len); + txe->data_len += src_len; + } + } else { + /* Encrypt into TXE. */ + if (!qtx_encrypt_into_txe(qtx, &cur, txe, enc_level, pkt->pn, + hdr_start, hdr_len, &ptrs)) { + ret = QTX_FAIL_GENERIC; + goto err; + } + + assert(txe->data_len - orig_data_len == pkt_len); + } + + if (qtx->finishmutatecb != NULL) + qtx->finishmutatecb(qtx->mutatearg); + return 1; + +err: + /* + * Restore original length so we don't leave a half-written packet in the + * TXE. + */ + txe->data_len = orig_data_len; + if (qtx->finishmutatecb != NULL) + qtx->finishmutatecb(qtx->mutatearg); + return ret; +} + +static TXE *qtx_ensure_cons(OSSL_QTX *qtx) +{ + TXE *txe = qtx->cons; + + if (txe != NULL) + return txe; + + txe = qtx_ensure_free_txe(qtx, qtx->mdpl); + if (txe == NULL) + return NULL; + + ossl_list_txe_remove(&qtx->free, txe); + qtx->cons = txe; + qtx->cons_count = 0; + txe->data_len = 0; + return txe; +} + +static int addr_eq(const BIO_ADDR *a, const BIO_ADDR *b) +{ + return ((a == NULL || BIO_ADDR_family(a) == AF_UNSPEC) + && (b == NULL || BIO_ADDR_family(b) == AF_UNSPEC)) + || (a != NULL && b != NULL && memcmp(a, b, sizeof(*a)) == 0); +} + +int ossl_qtx_write_pkt(OSSL_QTX *qtx, const OSSL_QTX_PKT *pkt) +{ + int ret; + int coalescing = (pkt->flags & OSSL_QTX_PKT_FLAG_COALESCE) != 0; + int was_coalescing; + TXE *txe; + uint32_t enc_level; + + /* Must have EL configured, must have header. */ + if (pkt->hdr == NULL) + return 0; + + enc_level = ossl_quic_pkt_type_to_enc_level(pkt->hdr->type); + + /* Some packet types must be in a packet all by themselves. */ + if (!ossl_quic_pkt_type_can_share_dgram(pkt->hdr->type)) + ossl_qtx_finish_dgram(qtx); + else if (enc_level >= QUIC_ENC_LEVEL_NUM + || ossl_qrl_enc_level_set_have_el(&qtx->el_set, enc_level) != 1) { + /* All other packet types are encrypted. */ + return 0; + } + + was_coalescing = (qtx->cons != NULL && qtx->cons->data_len > 0); + if (was_coalescing) + if (!addr_eq(&qtx->cons->peer, pkt->peer) + || !addr_eq(&qtx->cons->local, pkt->local)) { + /* Must stop coalescing if addresses have changed */ + ossl_qtx_finish_dgram(qtx); + was_coalescing = 0; + } + + for (;;) { + /* + * Start a new coalescing session or continue using the existing one and + * serialize/encrypt the packet. We always encrypt packets as soon as + * our caller gives them to us, which relieves the caller of any need to + * keep the plaintext around. + */ + txe = qtx_ensure_cons(qtx); + if (txe == NULL) + return 0; /* allocation failure */ + + /* + * Ensure TXE has at least MDPL bytes allocated. This should only be + * possible if the MDPL has increased. + */ + if (!qtx_reserve_txe(qtx, NULL, txe, qtx->mdpl)) + return 0; + + if (!was_coalescing) { + /* Set addresses in TXE. */ + if (pkt->peer != NULL) + txe->peer = *pkt->peer; + else + BIO_ADDR_clear(&txe->peer); + + if (pkt->local != NULL) + txe->local = *pkt->local; + else + BIO_ADDR_clear(&txe->local); + } + + ret = qtx_write(qtx, pkt, txe, enc_level); + if (ret == 1) { + break; + } else if (ret == QTX_FAIL_INSUFFICIENT_LEN) { + if (was_coalescing) { + /* + * We failed due to insufficient length, so end the current + * datagram and try again. + */ + ossl_qtx_finish_dgram(qtx); + was_coalescing = 0; + } else { + /* + * We failed due to insufficient length, but we were not + * coalescing/started with an empty datagram, so any future + * attempt to write this packet must also fail. + */ + return 0; + } + } else { + return 0; /* other error */ + } + } + + ++qtx->cons_count; + + /* + * Some packet types cannot have another packet come after them. + */ + if (ossl_quic_pkt_type_must_be_last(pkt->hdr->type)) + coalescing = 0; + + if (!coalescing) + ossl_qtx_finish_dgram(qtx); + + return 1; +} + +/* + * Finish any incomplete datagrams for transmission which were flagged for + * coalescing. If there is no current coalescing datagram, this is a no-op. + */ +void ossl_qtx_finish_dgram(OSSL_QTX *qtx) +{ + TXE *txe = qtx->cons; + + if (txe == NULL) + return; + + if (txe->data_len == 0) + /* + * If we did not put anything in the datagram, just move it back to the + * free list. + */ + ossl_list_txe_insert_tail(&qtx->free, txe); + else + qtx_add_to_pending(qtx, txe); + + qtx->cons = NULL; + qtx->cons_count = 0; +} + +static void txe_to_msg(TXE *txe, BIO_MSG *msg) +{ + msg->data = txe_data(txe); + msg->data_len = txe->data_len; + msg->flags = 0; + msg->peer + = BIO_ADDR_family(&txe->peer) != AF_UNSPEC ? &txe->peer : NULL; + msg->local + = BIO_ADDR_family(&txe->local) != AF_UNSPEC ? &txe->local : NULL; +} + +#define MAX_MSGS_PER_SEND 32 + +int ossl_qtx_flush_net(OSSL_QTX *qtx) +{ + BIO_MSG msg[MAX_MSGS_PER_SEND]; + size_t wr, i, total_written = 0; + TXE *txe; + int res; + + if (ossl_list_txe_head(&qtx->pending) == NULL) + return QTX_FLUSH_NET_RES_OK; /* Nothing to send. */ + + if (qtx->bio == NULL) + return QTX_FLUSH_NET_RES_PERMANENT_FAIL; + + for (;;) { + for (txe = ossl_list_txe_head(&qtx->pending), i = 0; + txe != NULL && i < OSSL_NELEM(msg); + txe = ossl_list_txe_next(txe), ++i) + txe_to_msg(txe, &msg[i]); + + if (!i) + /* Nothing to send. */ + break; + + ERR_set_mark(); + res = BIO_sendmmsg(qtx->bio, msg, sizeof(BIO_MSG), i, 0, &wr); + if (res && wr == 0) { + /* + * Treat 0 messages sent as a transient error and just stop for now. + */ + ERR_clear_last_mark(); + break; + } else if (!res) { + /* + * We did not get anything, so further calls will probably not + * succeed either. + */ + if (BIO_err_is_non_fatal(ERR_peek_last_error())) { + /* Transient error, just stop for now, clearing the error. */ + ERR_pop_to_mark(); + break; + } else { + /* Non-transient error, fail and do not clear the error. */ + ERR_clear_last_mark(); + return QTX_FLUSH_NET_RES_PERMANENT_FAIL; + } + } + + ERR_clear_last_mark(); + + /* + * Remove everything which was successfully sent from the pending queue. + */ + for (i = 0; i < wr; ++i) { + if (qtx->msg_callback != NULL) + qtx->msg_callback(1, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_DATAGRAM, + msg[i].data, msg[i].data_len, + qtx->msg_callback_ssl, + qtx->msg_callback_arg); + qtx_pending_to_free(qtx); + } + + total_written += wr; + } + + return total_written > 0 + ? QTX_FLUSH_NET_RES_OK + : QTX_FLUSH_NET_RES_TRANSIENT_FAIL; +} + +int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg) +{ + TXE *txe = ossl_list_txe_head(&qtx->pending); + + if (txe == NULL) + return 0; + + txe_to_msg(txe, msg); + qtx_pending_to_free(qtx); + return 1; +} + +void ossl_qtx_set_bio(OSSL_QTX *qtx, BIO *bio) +{ + qtx->bio = bio; +} + +int ossl_qtx_set_mdpl(OSSL_QTX *qtx, size_t mdpl) +{ + if (mdpl < QUIC_MIN_INITIAL_DGRAM_LEN) + return 0; + + qtx->mdpl = mdpl; + return 1; +} + +size_t ossl_qtx_get_mdpl(OSSL_QTX *qtx) +{ + return qtx->mdpl; +} + +size_t ossl_qtx_get_queue_len_datagrams(OSSL_QTX *qtx) +{ + return qtx->pending_count; +} + +size_t ossl_qtx_get_queue_len_bytes(OSSL_QTX *qtx) +{ + return qtx->pending_bytes; +} + +size_t ossl_qtx_get_cur_dgram_len_bytes(OSSL_QTX *qtx) +{ + return qtx->cons != NULL ? qtx->cons->data_len : 0; +} + +size_t ossl_qtx_get_unflushed_pkt_count(OSSL_QTX *qtx) +{ + return qtx->cons_count; +} + +int ossl_qtx_trigger_key_update(OSSL_QTX *qtx) +{ + return ossl_qrl_enc_level_set_key_update(&qtx->el_set, + QUIC_ENC_LEVEL_1RTT); +} + +uint64_t ossl_qtx_get_cur_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el; + + el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + if (el == NULL) + return UINT64_MAX; + + return el->op_count; +} + +uint64_t ossl_qtx_get_max_epoch_pkt_count(OSSL_QTX *qtx, uint32_t enc_level) +{ + OSSL_QRL_ENC_LEVEL *el; + + el = ossl_qrl_enc_level_set_get(&qtx->el_set, enc_level, 1); + if (el == NULL) + return UINT64_MAX; + + return ossl_qrl_get_suite_max_pkt(el->suite_id); +} + +void ossl_qtx_set_msg_callback(OSSL_QTX *qtx, ossl_msg_cb msg_callback, + SSL *msg_callback_ssl) +{ + qtx->msg_callback = msg_callback; + qtx->msg_callback_ssl = msg_callback_ssl; +} + +void ossl_qtx_set_msg_callback_arg(OSSL_QTX *qtx, void *msg_callback_arg) +{ + qtx->msg_callback_arg = msg_callback_arg; +} + +uint64_t ossl_qtx_get_key_epoch(OSSL_QTX *qtx) +{ + OSSL_QRL_ENC_LEVEL *el; + + el = ossl_qrl_enc_level_set_get(&qtx->el_set, QUIC_ENC_LEVEL_1RTT, 1); + if (el == NULL) + return 0; + + return el->key_epoch; +} diff --git a/ssl/quic/quic_record_util.c b/ssl/quic/quic_record_util.c new file mode 100644 index 0000000000..e95a84c39b --- /dev/null +++ b/ssl/quic/quic_record_util.c @@ -0,0 +1,277 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_record_util.h" +#include "internal/quic_record_rx.h" +#include "internal/quic_record_tx.h" +#include "internal/quic_wire_pkt.h" +#include "../ssl_local.h" +#include +#include + +/* + * QUIC Key Derivation Utilities + * ============================= + */ +int ossl_quic_hkdf_extract(OSSL_LIB_CTX *libctx, + const char *propq, + const EVP_MD *md, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *out, size_t out_len) +{ + int ret = 0; + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[7], *p = params; + int mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; + const char *md_name; + + if ((md_name = EVP_MD_get0_name(md)) == NULL + || (kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_HKDF, propq)) == NULL + || (kctx = EVP_KDF_CTX_new(kdf)) == NULL) + goto err; + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)md_name, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)salt, salt_len); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)ikm, ikm_len); + *p++ = OSSL_PARAM_construct_end(); + + ret = EVP_KDF_derive(kctx, out, out_len, params); + +err: + EVP_KDF_CTX_free(kctx); + EVP_KDF_free(kdf); + return ret; +} + +/* Constants used for key derivation in QUIC v1. */ +static const unsigned char quic_client_in_label[] = { + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e /* "client in" */ +}; +static const unsigned char quic_server_in_label[] = { + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x69, 0x6e /* "server in" */ +}; + +/* Salt used to derive Initial packet protection keys (RFC 9001 Section 5.2). */ +static const unsigned char quic_v1_initial_salt[] = { + 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, + 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a +}; + +int ossl_quic_provide_initial_secret(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_CONN_ID *dst_conn_id, + int is_server, + struct ossl_qrx_st *qrx, + struct ossl_qtx_st *qtx) +{ + unsigned char initial_secret[32]; + unsigned char client_initial_secret[32], server_initial_secret[32]; + unsigned char *rx_secret, *tx_secret; + EVP_MD *sha256; + + if (qrx == NULL && qtx == NULL) + return 1; + + /* Initial encryption always uses SHA-256. */ + if ((sha256 = EVP_MD_fetch(libctx, "SHA256", propq)) == NULL) + return 0; + + if (is_server) { + rx_secret = client_initial_secret; + tx_secret = server_initial_secret; + } else { + rx_secret = server_initial_secret; + tx_secret = client_initial_secret; + } + + /* Derive initial secret from destination connection ID. */ + if (!ossl_quic_hkdf_extract(libctx, propq, + sha256, + quic_v1_initial_salt, + sizeof(quic_v1_initial_salt), + dst_conn_id->id, + dst_conn_id->id_len, + initial_secret, + sizeof(initial_secret))) + goto err; + + /* Derive "client in" secret. */ + if (((qtx != NULL && tx_secret == client_initial_secret) + || (qrx != NULL && rx_secret == client_initial_secret)) + && !tls13_hkdf_expand_ex(libctx, propq, + sha256, + initial_secret, + quic_client_in_label, + sizeof(quic_client_in_label), + NULL, 0, + client_initial_secret, + sizeof(client_initial_secret), 1)) + goto err; + + /* Derive "server in" secret. */ + if (((qtx != NULL && tx_secret == server_initial_secret) + || (qrx != NULL && rx_secret == server_initial_secret)) + && !tls13_hkdf_expand_ex(libctx, propq, + sha256, + initial_secret, + quic_server_in_label, + sizeof(quic_server_in_label), + NULL, 0, + server_initial_secret, + sizeof(server_initial_secret), 1)) + goto err; + + /* Setup RX EL. Initial encryption always uses AES-128-GCM. */ + if (qrx != NULL + && !ossl_qrx_provide_secret(qrx, QUIC_ENC_LEVEL_INITIAL, + QRL_SUITE_AES128GCM, + sha256, + rx_secret, + sizeof(server_initial_secret))) + goto err; + + /* + * ossl_qrx_provide_secret takes ownership of our ref to SHA256, so if we + * are initialising both sides, get a new ref for the following call for the + * TX side. + */ + if (qrx != NULL && qtx != NULL && !EVP_MD_up_ref(sha256)) { + sha256 = NULL; + goto err; + } + + /* Setup TX cipher. */ + if (qtx != NULL + && !ossl_qtx_provide_secret(qtx, QUIC_ENC_LEVEL_INITIAL, + QRL_SUITE_AES128GCM, + sha256, + tx_secret, + sizeof(server_initial_secret))) + goto err; + + return 1; + +err: + EVP_MD_free(sha256); + return 0; +} + +/* + * QUIC Record Layer Ciphersuite Info + * ================================== + */ + +struct suite_info { + const char *cipher_name, *md_name; + uint32_t secret_len, cipher_key_len, cipher_iv_len, cipher_tag_len; + uint32_t hdr_prot_key_len, hdr_prot_cipher_id; + uint64_t max_pkt, max_forged_pkt; +}; + +static const struct suite_info suite_aes128gcm = { + "AES-128-GCM", "SHA256", 32, 16, 12, 16, 16, + QUIC_HDR_PROT_CIPHER_AES_128, + ((uint64_t)1) << 23, /* Limits as prescribed by RFC 9001 */ + ((uint64_t)1) << 52, +}; + +static const struct suite_info suite_aes256gcm = { + "AES-256-GCM", "SHA384", 48, 32, 12, 16, 32, + QUIC_HDR_PROT_CIPHER_AES_256, + ((uint64_t)1) << 23, /* Limits as prescribed by RFC 9001 */ + ((uint64_t)1) << 52, +}; + +static const struct suite_info suite_chacha20poly1305 = { + "ChaCha20-Poly1305", "SHA256", 32, 32, 12, 16, 32, + QUIC_HDR_PROT_CIPHER_CHACHA, + /* Do not use UINT64_MAX here as this represents an invalid value */ + UINT64_MAX - 1, /* No applicable limit for this suite (RFC 9001) */ + ((uint64_t)1) << 36, /* Limit as prescribed by RFC 9001 */ +}; + +static const struct suite_info *get_suite(uint32_t suite_id) +{ + switch (suite_id) { + case QRL_SUITE_AES128GCM: + return &suite_aes128gcm; + case QRL_SUITE_AES256GCM: + return &suite_aes256gcm; + case QRL_SUITE_CHACHA20POLY1305: + return &suite_chacha20poly1305; + default: + return NULL; + } +} + +const char *ossl_qrl_get_suite_cipher_name(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->cipher_name : NULL; +} + +const char *ossl_qrl_get_suite_md_name(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->md_name : NULL; +} + +uint32_t ossl_qrl_get_suite_secret_len(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->secret_len : 0; +} + +uint32_t ossl_qrl_get_suite_cipher_key_len(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->cipher_key_len : 0; +} + +uint32_t ossl_qrl_get_suite_cipher_iv_len(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->cipher_iv_len : 0; +} + +uint32_t ossl_qrl_get_suite_cipher_tag_len(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->cipher_tag_len : 0; +} + +uint32_t ossl_qrl_get_suite_hdr_prot_cipher_id(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->hdr_prot_cipher_id : 0; +} + +uint32_t ossl_qrl_get_suite_hdr_prot_key_len(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->hdr_prot_key_len : 0; +} + +uint64_t ossl_qrl_get_suite_max_pkt(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->max_pkt : UINT64_MAX; +} + +uint64_t ossl_qrl_get_suite_max_forged_pkt(uint32_t suite_id) +{ + const struct suite_info *c = get_suite(suite_id); + return c != NULL ? c->max_forged_pkt : UINT64_MAX; +} diff --git a/ssl/quic/quic_rstream.c b/ssl/quic/quic_rstream.c new file mode 100644 index 0000000000..dd3dbf756b --- /dev/null +++ b/ssl/quic/quic_rstream.c @@ -0,0 +1,295 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ +#include +#include "internal/common.h" +#include "internal/time.h" +#include "internal/quic_stream.h" +#include "internal/quic_sf_list.h" +#include "internal/ring_buf.h" + +struct quic_rstream_st { + SFRAME_LIST fl; + QUIC_RXFC *rxfc; + OSSL_STATM *statm; + UINT_RANGE head_range; + struct ring_buf rbuf; +}; + +QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc, + OSSL_STATM *statm, size_t rbuf_size) +{ + QUIC_RSTREAM *ret = OPENSSL_zalloc(sizeof(*ret)); + + if (ret == NULL) + return NULL; + + ring_buf_init(&ret->rbuf); + if (!ring_buf_resize(&ret->rbuf, rbuf_size, 0)) { + OPENSSL_free(ret); + return NULL; + } + + ossl_sframe_list_init(&ret->fl); + ret->rxfc = rxfc; + ret->statm = statm; + return ret; +} + +void ossl_quic_rstream_free(QUIC_RSTREAM *qrs) +{ + int cleanse; + + if (qrs == NULL) + return; + + cleanse = qrs->fl.cleanse; + ossl_sframe_list_destroy(&qrs->fl); + ring_buf_destroy(&qrs->rbuf, cleanse); + OPENSSL_free(qrs); +} + +int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt, + uint64_t offset, + const unsigned char *data, uint64_t data_len, + int fin) +{ + UINT_RANGE range; + + if ((data == NULL && data_len != 0) || (data_len == 0 && fin == 0)) { + /* empty frame allowed only at the end of the stream */ + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + range.start = offset; + range.end = offset + data_len; + + return ossl_sframe_list_insert(&qrs->fl, &range, pkt, data, fin); +} + +static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size, + size_t *readbytes, int *fin, int drop) +{ + void *iter = NULL; + UINT_RANGE range; + const unsigned char *data; + uint64_t offset = 0; + size_t readbytes_ = 0; + int fin_ = 0, ret = 1; + + while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, &fin_)) { + size_t l = (size_t)(range.end - range.start); + + if (l > size) { + l = size; + fin_ = 0; + } + offset = range.start + l; + if (l == 0) + break; + + if (data == NULL) { + size_t max_len; + + data = ring_buf_get_ptr(&qrs->rbuf, range.start, &max_len); + if (!ossl_assert(data != NULL)) + return 0; + if (max_len < l) { + memcpy(buf, data, max_len); + size -= max_len; + buf += max_len; + readbytes_ += max_len; + l -= max_len; + data = ring_buf_get_ptr(&qrs->rbuf, range.start + max_len, + &max_len); + if (!ossl_assert(data != NULL) || !ossl_assert(max_len > l)) + return 0; + } + } + + memcpy(buf, data, l); + size -= l; + buf += l; + readbytes_ += l; + if (size == 0) + break; + } + + if (drop && offset != 0) { + ret = ossl_sframe_list_drop_frames(&qrs->fl, offset); + ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse); + } + + if (ret) { + *readbytes = readbytes_; + *fin = fin_; + } + + return ret; +} + +static OSSL_TIME get_rtt(QUIC_RSTREAM *qrs) +{ + OSSL_TIME rtt; + + if (qrs->statm != NULL) { + OSSL_RTT_INFO rtt_info; + + ossl_statm_get_rtt_info(qrs->statm, &rtt_info); + rtt = rtt_info.smoothed_rtt; + } else { + rtt = ossl_time_zero(); + } + return rtt; +} + +int ossl_quic_rstream_read(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size, + size_t *readbytes, int *fin) +{ + OSSL_TIME rtt = get_rtt(qrs); + + if (!read_internal(qrs, buf, size, readbytes, fin, 1)) + return 0; + + if (qrs->rxfc != NULL + && !ossl_quic_rxfc_on_retire(qrs->rxfc, *readbytes, rtt)) + return 0; + + return 1; +} + +int ossl_quic_rstream_peek(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size, + size_t *readbytes, int *fin) +{ + return read_internal(qrs, buf, size, readbytes, fin, 0); +} + +int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin) +{ + void *iter = NULL; + UINT_RANGE range; + const unsigned char *data; + uint64_t avail_ = 0; + + while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, fin)) + avail_ += range.end - range.start; + +#if SIZE_MAX < UINT64_MAX + *avail = avail_ > SIZE_MAX ? SIZE_MAX : (size_t)avail_; +#else + *avail = (size_t)avail_; +#endif + return 1; +} + +int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs, + const unsigned char **record, size_t *rec_len, + int *fin) +{ + const unsigned char *record_ = NULL; + size_t rec_len_, max_len; + + if (!ossl_sframe_list_lock_head(&qrs->fl, &qrs->head_range, &record_, fin)) { + /* No head frame to lock and return */ + *record = NULL; + *rec_len = 0; + return 1; + } + + /* if final empty frame, we drop it immediately */ + if (qrs->head_range.end == qrs->head_range.start) { + if (!ossl_assert(*fin)) + return 0; + if (!ossl_sframe_list_drop_frames(&qrs->fl, qrs->head_range.end)) + return 0; + } + + rec_len_ = (size_t)(qrs->head_range.end - qrs->head_range.start); + + if (record_ == NULL && rec_len_ != 0) { + record_ = ring_buf_get_ptr(&qrs->rbuf, qrs->head_range.start, + &max_len); + if (!ossl_assert(record_ != NULL)) + return 0; + if (max_len < rec_len_) { + rec_len_ = max_len; + qrs->head_range.end = qrs->head_range.start + max_len; + } + } + + *rec_len = rec_len_; + *record = record_; + return 1; +} + + +int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len) +{ + uint64_t offset; + + if (!ossl_sframe_list_is_head_locked(&qrs->fl)) + return 0; + + if (read_len > qrs->head_range.end - qrs->head_range.start) { + if (read_len != SIZE_MAX) + return 0; + offset = qrs->head_range.end; + } else { + offset = qrs->head_range.start + read_len; + } + + if (!ossl_sframe_list_drop_frames(&qrs->fl, offset)) + return 0; + + if (offset > 0) + ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse); + + if (qrs->rxfc != NULL) { + OSSL_TIME rtt = get_rtt(qrs); + + if (!ossl_quic_rxfc_on_retire(qrs->rxfc, offset, rtt)) + return 0; + } + + return 1; +} + +static int write_at_ring_buf_cb(uint64_t logical_offset, + const unsigned char *buf, + size_t buf_len, + void *cb_arg) +{ + struct ring_buf *rbuf = cb_arg; + + return ring_buf_write_at(rbuf, logical_offset, buf, buf_len); +} + +int ossl_quic_rstream_move_to_rbuf(QUIC_RSTREAM *qrs) +{ + if (ring_buf_avail(&qrs->rbuf) == 0) + return 0; + return ossl_sframe_list_move_data(&qrs->fl, + write_at_ring_buf_cb, &qrs->rbuf); +} + +int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size) +{ + if (ossl_sframe_list_is_head_locked(&qrs->fl)) + return 0; + + if (!ring_buf_resize(&qrs->rbuf, rbuf_size, qrs->fl.cleanse)) + return 0; + + return 1; +} + +void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse) +{ + qrs->fl.cleanse = cleanse; +} diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c new file mode 100644 index 0000000000..97c6d6095d --- /dev/null +++ b/ssl/quic/quic_rx_depack.c @@ -0,0 +1,1467 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/packet_quic.h" +#include "internal/nelem.h" +#include "internal/quic_wire.h" +#include "internal/quic_record_rx.h" +#include "internal/quic_ackm.h" +#include "internal/quic_rx_depack.h" +#include "internal/quic_error.h" +#include "internal/quic_fc.h" +#include "internal/quic_channel.h" +#include "internal/sockets.h" + +#include "quic_local.h" +#include "quic_channel_local.h" +#include "../ssl_local.h" + +/* + * Helper functions to process different frame types. + * + * Typically, those that are ACK eliciting will take an OSSL_ACKM_RX_PKT + * pointer argument, the few that aren't ACK eliciting will not. This makes + * them a verifiable pattern against tables where this is specified. + */ +static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch, + uint64_t stream_id, + uint64_t frame_type, + QUIC_STREAM **result); + +static int depack_do_frame_padding(PACKET *pkt) +{ + /* We ignore this frame */ + ossl_quic_wire_decode_padding(pkt); + return 1; +} + +static int depack_do_frame_ping(PACKET *pkt, QUIC_CHANNEL *ch, + uint32_t enc_level, + OSSL_ACKM_RX_PKT *ackm_data) +{ + /* We ignore this frame, apart from eliciting an ACK */ + if (!ossl_quic_wire_decode_frame_ping(pkt)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_PING, + "decode error"); + return 0; + } + + ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, enc_level); + return 1; +} + +static int depack_do_frame_ack(PACKET *pkt, QUIC_CHANNEL *ch, + int packet_space, OSSL_TIME received, + uint64_t frame_type, + OSSL_QRX_PKT *qpacket) +{ + OSSL_QUIC_FRAME_ACK ack; + OSSL_QUIC_ACK_RANGE *p; + uint64_t total_ranges = 0; + uint32_t ack_delay_exp = ch->rx_ack_delay_exp; + + if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges) + /* In case sizeof(uint64_t) > sizeof(size_t) */ + || total_ranges > SIZE_MAX / sizeof(OSSL_QUIC_ACK_RANGE)) + goto malformed; + + if (ch->num_ack_range_scratch < (size_t)total_ranges) { + if ((p = OPENSSL_realloc(ch->ack_range_scratch, + sizeof(OSSL_QUIC_ACK_RANGE) + * (size_t)total_ranges)) == NULL) + goto malformed; + + ch->ack_range_scratch = p; + ch->num_ack_range_scratch = (size_t)total_ranges; + } + + ack.ack_ranges = ch->ack_range_scratch; + ack.num_ack_ranges = (size_t)total_ranges; + + if (!ossl_quic_wire_decode_frame_ack(pkt, ack_delay_exp, &ack, NULL)) + goto malformed; + + if (qpacket->hdr->type == QUIC_PKT_TYPE_1RTT + && (qpacket->key_epoch < ossl_qrx_get_key_epoch(ch->qrx) + || ch->rxku_expected) + && ack.ack_ranges[0].end >= ch->txku_pn) { + /* + * RFC 9001 s. 6.2: An endpoint that receives an acknowledgment that is + * carried in a packet protected with old keys where any acknowledged + * packet was protected with newer keys MAY treat that as a connection + * error of type KEY_UPDATE_ERROR. + * + * Two cases to handle here: + * + * - We did spontaneous TXKU, the peer has responded in kind and we + * have detected RXKU; !ch->rxku_expected, but then it sent a packet + * with old keys acknowledging a packet in the new key epoch. + * + * This also covers the case where we got RXKU and triggered + * solicited TXKU, and then for some reason the peer sent an ACK of + * a PN in our new TX key epoch with old keys. + * + * - We did spontaneous TXKU; ch->txku_pn is the starting PN of our + * new TX key epoch; the peer has not initiated a solicited TXKU in + * response (so we have not detected RXKU); in this case the RX key + * epoch has not incremented and ch->rxku_expected is still 1. + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_KEY_UPDATE_ERROR, + frame_type, + "acked packet which initiated a " + "key update without a " + "corresponding key update"); + return 0; + } + + if (!ossl_ackm_on_rx_ack_frame(ch->ackm, &ack, + packet_space, received)) + goto malformed; + + ++ch->diag_num_rx_ack; + return 1; + +malformed: + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; +} + +static int depack_do_frame_reset_stream(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + OSSL_QUIC_FRAME_RESET_STREAM frame_data; + QUIC_STREAM *stream = NULL; + uint64_t fce; + + if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + "decode error"); + return 0; + } + + if (!depack_do_implicit_stream_create(ch, frame_data.stream_id, + OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + &stream)) + return 0; /* error already raised for us */ + + if (stream == NULL) + return 1; /* old deleted stream, not a protocol violation, ignore */ + + if (!ossl_quic_stream_has_recv(stream)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + "RESET_STREAM frame for " + "TX only stream"); + return 0; + } + + /* + * The final size field of the RESET_STREAM frame must be used to determine + * how much flow control credit the aborted stream was considered to have + * consumed. + * + * We also need to ensure that if we already have a final size for the + * stream, the RESET_STREAM frame's Final Size field matches this; we SHOULD + * terminate the connection otherwise (RFC 9000 s. 4.5). The RXFC takes care + * of this for us. + */ + if (!ossl_quic_rxfc_on_rx_stream_frame(&stream->rxfc, + frame_data.final_size, /*is_fin=*/1)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + "internal error (flow control)"); + return 0; + } + + /* Has a flow control error occurred? */ + fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0); + if (fce != QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, + fce, + OSSL_QUIC_FRAME_TYPE_RESET_STREAM, + "flow control violation"); + return 0; + } + + /* + * Depending on the receive part state this is handled either as a reset + * transition or a no-op (e.g. if a reset has already been received before, + * or the application already retired a FIN). Best effort - there are no + * protocol error conditions we need to check for here. + */ + ossl_quic_stream_map_notify_reset_recv_part(&ch->qsm, stream, + frame_data.app_error_code, + frame_data.final_size); + + ossl_quic_stream_map_update_state(&ch->qsm, stream); + return 1; +} + +static int depack_do_frame_stop_sending(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + OSSL_QUIC_FRAME_STOP_SENDING frame_data; + QUIC_STREAM *stream = NULL; + + if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_STOP_SENDING, + "decode error"); + return 0; + } + + if (!depack_do_implicit_stream_create(ch, frame_data.stream_id, + OSSL_QUIC_FRAME_TYPE_STOP_SENDING, + &stream)) + return 0; /* error already raised for us */ + + if (stream == NULL) + return 1; /* old deleted stream, not a protocol violation, ignore */ + + if (!ossl_quic_stream_has_send(stream)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_FRAME_TYPE_STOP_SENDING, + "STOP_SENDING frame for " + "RX only stream"); + return 0; + } + + stream->peer_stop_sending = 1; + stream->peer_stop_sending_aec = frame_data.app_error_code; + + /* + * RFC 9000 s. 3.5: Receiving a STOP_SENDING frame means we must respond in + * turn with a RESET_STREAM frame for the same part of the stream. The other + * part is unaffected. + */ + ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, stream, + frame_data.app_error_code); + return 1; +} + +static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch, + OSSL_QRX_PKT *parent_pkt, + OSSL_ACKM_RX_PKT *ackm_data, + uint64_t *datalen) +{ + OSSL_QUIC_FRAME_CRYPTO f; + QUIC_RSTREAM *rstream; + QUIC_RXFC *rxfc; + + *datalen = 0; + + if (!ossl_quic_wire_decode_frame_crypto(pkt, 0, &f)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "decode error"); + return 0; + } + + if (f.len == 0) + return 1; /* nothing to do */ + + rstream = ch->crypto_recv[ackm_data->pkt_space]; + if (!ossl_assert(rstream != NULL)) + /* + * This should not happen; we should only have a NULL stream here if + * the EL has been discarded, and if the EL has been discarded we + * shouldn't be here. + */ + return 0; + + rxfc = &ch->crypto_rxfc[ackm_data->pkt_space]; + + if (!ossl_quic_rxfc_on_rx_stream_frame(rxfc, f.offset + f.len, + /*is_fin=*/0)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "internal error (crypto RXFC)"); + return 0; + } + + if (ossl_quic_rxfc_get_error(rxfc, 0) != QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "exceeded maximum crypto buffer"); + return 0; + } + + if (!ossl_quic_rstream_queue_data(rstream, parent_pkt, + f.offset, f.data, f.len, 0)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_CRYPTO, + "internal error (rstream queue)"); + return 0; + } + + ch->did_crypto_frame = 1; + *datalen = f.len; + + return 1; +} + +static int depack_do_frame_new_token(PACKET *pkt, QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + const uint8_t *token; + size_t token_len; + + if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, + "decode error"); + return 0; + } + + if (token_len == 0) { + /* + * RFC 9000 s. 19.7: "A client MUST treat receipt of a NEW_TOKEN frame + * with an empty Token field as a connection error of type + * FRAME_ENCODING_ERROR." + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, + "zero-length NEW_TOKEN"); + return 0; + } + + /* TODO(QUIC FUTURE): ADD CODE to send |token| to the session manager */ + + return 1; +} + +/* + * Returns 1 if no protocol violation has occurred. In this case *result will be + * non-NULL unless this is an old deleted stream and we should ignore the frame + * causing this function to be called. Returns 0 on protocol violation. + */ +static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch, + uint64_t stream_id, + uint64_t frame_type, + QUIC_STREAM **result) +{ + QUIC_STREAM *stream; + uint64_t peer_role, stream_ordinal; + uint64_t *p_next_ordinal_local, *p_next_ordinal_remote; + QUIC_RXFC *max_streams_fc; + int is_uni, is_remote_init; + + stream = ossl_quic_stream_map_get_by_id(&ch->qsm, stream_id); + if (stream != NULL) { + *result = stream; + return 1; + } + + /* + * If we do not yet have a stream with the given ID, there are three + * possibilities: + * + * (a) The stream ID is for a remotely-created stream and the peer + * is creating a stream. + * + * (b) The stream ID is for a locally-created stream which has + * previously been deleted. + * + * (c) The stream ID is for a locally-created stream which does + * not exist yet. This is a protocol violation and we must + * terminate the connection in this case. + * + * We distinguish between (b) and (c) using the stream ID allocator + * variable. Since stream ordinals are allocated monotonically, we + * simply determine if the stream ordinal is in the future. + */ + peer_role = ch->is_server + ? QUIC_STREAM_INITIATOR_CLIENT + : QUIC_STREAM_INITIATOR_SERVER; + + is_remote_init = ((stream_id & QUIC_STREAM_INITIATOR_MASK) == peer_role); + is_uni = ((stream_id & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_UNI); + + stream_ordinal = stream_id >> 2; + + if (is_remote_init) { + /* + * Peer-created stream which does not yet exist. Create it. QUIC stream + * ordinals within a given stream type MUST be used in sequence and + * receiving a STREAM frame for ordinal n must implicitly create streams + * with ordinals [0, n) within that stream type even if no explicit + * STREAM frames are received for those ordinals. + */ + p_next_ordinal_remote = is_uni + ? &ch->next_remote_stream_ordinal_uni + : &ch->next_remote_stream_ordinal_bidi; + + /* Check this isn't violating stream count flow control. */ + max_streams_fc = is_uni + ? &ch->max_streams_uni_rxfc + : &ch->max_streams_bidi_rxfc; + + if (!ossl_quic_rxfc_on_rx_stream_frame(max_streams_fc, + stream_ordinal + 1, + /*is_fin=*/0)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + frame_type, + "internal error (stream count RXFC)"); + return 0; + } + + if (ossl_quic_rxfc_get_error(max_streams_fc, 0) != QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_STREAM_LIMIT_ERROR, + frame_type, + "exceeded maximum allowed streams"); + return 0; + } + + /* + * Create the named stream and any streams coming before it yet to be + * created. + */ + while (*p_next_ordinal_remote <= stream_ordinal) { + uint64_t cur_stream_id = (*p_next_ordinal_remote << 2) | + (stream_id + & (QUIC_STREAM_DIR_MASK | QUIC_STREAM_INITIATOR_MASK)); + + stream = ossl_quic_channel_new_stream_remote(ch, cur_stream_id); + if (stream == NULL) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + frame_type, + "internal error (stream allocation)"); + return 0; + } + + ++*p_next_ordinal_remote; + } + + *result = stream; + } else { + /* Locally-created stream which does not yet exist. */ + p_next_ordinal_local = is_uni + ? &ch->next_local_stream_ordinal_uni + : &ch->next_local_stream_ordinal_bidi; + + if (stream_ordinal >= *p_next_ordinal_local) { + /* + * We never created this stream yet, this is a protocol + * violation. + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + frame_type, + "STREAM frame for nonexistent " + "stream"); + return 0; + } + + /* + * Otherwise this is for an old locally-initiated stream which we + * have subsequently deleted. Ignore the data; it may simply be a + * retransmission. We already take care of notifying the peer of the + * termination of the stream during the stream deletion lifecycle. + */ + *result = NULL; + } + + return 1; +} + +static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch, + OSSL_QRX_PKT *parent_pkt, + OSSL_ACKM_RX_PKT *ackm_data, + uint64_t frame_type, + uint64_t *datalen) +{ + OSSL_QUIC_FRAME_STREAM frame_data; + QUIC_STREAM *stream; + uint64_t fce; + size_t rs_avail; + int rs_fin = 0; + + *datalen = 0; + + if (!ossl_quic_wire_decode_frame_stream(pkt, 0, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; + } + + if (!depack_do_implicit_stream_create(ch, frame_data.stream_id, + frame_type, &stream)) + return 0; /* protocol error raised by above call */ + + if (stream == NULL) + /* + * Data for old stream which is not a protocol violation but should be + * ignored, so stop here. + */ + return 1; + + if (!ossl_quic_stream_has_recv(stream)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + frame_type, + "STREAM frame for TX only " + "stream"); + return 0; + } + + /* Notify stream flow controller. */ + if (!ossl_quic_rxfc_on_rx_stream_frame(&stream->rxfc, + frame_data.offset + frame_data.len, + frame_data.is_fin)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + frame_type, + "internal error (flow control)"); + return 0; + } + + /* Has a flow control error occurred? */ + fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0); + if (fce != QUIC_ERR_NO_ERROR) { + ossl_quic_channel_raise_protocol_error(ch, + fce, + frame_type, + "flow control violation"); + return 0; + } + + switch (stream->recv_state) { + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + /* + * It only makes sense to process incoming STREAM frames in these + * states. + */ + break; + + case QUIC_RSTREAM_STATE_DATA_RECVD: + case QUIC_RSTREAM_STATE_DATA_READ: + case QUIC_RSTREAM_STATE_RESET_RECVD: + case QUIC_RSTREAM_STATE_RESET_READ: + default: + /* + * We have no use for STREAM frames once the receive part reaches any of + * these states, so just ignore. + */ + return 1; + } + + /* If we are in RECV, auto-transition to SIZE_KNOWN on FIN. */ + if (frame_data.is_fin + && !ossl_quic_stream_recv_get_final_size(stream, NULL)) { + + /* State was already checked above, so can't fail. */ + ossl_quic_stream_map_notify_size_known_recv_part(&ch->qsm, stream, + frame_data.offset + + frame_data.len); + } + + /* + * If we requested STOP_SENDING do not bother buffering the data. Note that + * this must happen after RXFC checks above as even if we sent STOP_SENDING + * we must still enforce correct flow control (RFC 9000 s. 3.5). + */ + if (stream->stop_sending) + return 1; /* not an error - packet reordering, etc. */ + + /* + * The receive stream buffer may or may not choose to consume the data + * without copying by reffing the OSSL_QRX_PKT. In this case + * ossl_qrx_pkt_release() will be eventually called when the data is no + * longer needed. + * + * It is OK for the peer to send us a zero-length non-FIN STREAM frame, + * which is a no-op, aside from the fact that it ensures the stream exists. + * In this case we have nothing to report to the receive buffer. + */ + if ((frame_data.len > 0 || frame_data.is_fin) + && !ossl_quic_rstream_queue_data(stream->rstream, parent_pkt, + frame_data.offset, + frame_data.data, + frame_data.len, + frame_data.is_fin)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + frame_type, + "internal error (rstream queue)"); + return 0; + } + + /* + * rs_fin will be 1 only if we can read all data up to and including the FIN + * without any gaps before it; this implies we have received all data. Avoid + * calling ossl_quic_rstream_available() where it is not necessary as it is + * more expensive. + */ + if (stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN + && !ossl_quic_rstream_available(stream->rstream, &rs_avail, &rs_fin)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + frame_type, + "internal error (rstream available)"); + return 0; + } + + if (rs_fin) + ossl_quic_stream_map_notify_totally_received(&ch->qsm, stream); + + *datalen = frame_data.len; + + return 1; +} + +static void update_streams(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static void update_streams_bidi(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (!ossl_quic_stream_is_bidi(s)) + return; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static void update_streams_uni(QUIC_STREAM *s, void *arg) +{ + QUIC_CHANNEL *ch = arg; + + if (ossl_quic_stream_is_bidi(s)) + return; + + ossl_quic_stream_map_update_state(&ch->qsm, s); +} + +static int depack_do_frame_max_data(PACKET *pkt, QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_MAX_DATA, + "decode error"); + return 0; + } + + ossl_quic_txfc_bump_cwm(&ch->conn_txfc, max_data); + ossl_quic_stream_map_visit(&ch->qsm, update_streams, ch); + return 1; +} + +static int depack_do_frame_max_stream_data(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t stream_id = 0; + uint64_t max_stream_data = 0; + QUIC_STREAM *stream; + + if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id, + &max_stream_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, + "decode error"); + return 0; + } + + if (!depack_do_implicit_stream_create(ch, stream_id, + OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, + &stream)) + return 0; /* error already raised for us */ + + if (stream == NULL) + return 1; /* old deleted stream, not a protocol violation, ignore */ + + if (!ossl_quic_stream_has_send(stream)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA, + "MAX_STREAM_DATA for TX only " + "stream"); + return 0; + } + + ossl_quic_txfc_bump_cwm(&stream->txfc, max_stream_data); + ossl_quic_stream_map_update_state(&ch->qsm, stream); + return 1; +} + +static int depack_do_frame_max_streams(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data, + uint64_t frame_type) +{ + uint64_t max_streams = 0; + + if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; + } + + if (max_streams > (((uint64_t)1) << 60)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "invalid max streams value"); + return 0; + } + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + if (max_streams > ch->max_local_streams_bidi) + ch->max_local_streams_bidi = max_streams; + + /* Some streams may now be able to send. */ + ossl_quic_stream_map_visit(&ch->qsm, update_streams_bidi, ch); + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + if (max_streams > ch->max_local_streams_uni) + ch->max_local_streams_uni = max_streams; + + /* Some streams may now be able to send. */ + ossl_quic_stream_map_visit(&ch->qsm, update_streams_uni, ch); + break; + default: + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; + } + + return 1; +} + +static int depack_do_frame_data_blocked(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED, + "decode error"); + return 0; + } + + /* No-op - informative/debugging frame. */ + return 1; +} + +static int depack_do_frame_stream_data_blocked(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t stream_id = 0; + uint64_t max_data = 0; + QUIC_STREAM *stream; + + if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id, + &max_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED, + "decode error"); + return 0; + } + + /* + * This is an informative/debugging frame, so we don't have to do anything, + * but it does trigger stream creation. + */ + if (!depack_do_implicit_stream_create(ch, stream_id, + OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED, + &stream)) + return 0; /* error already raised for us */ + + if (stream == NULL) + return 1; /* old deleted stream, not a protocol violation, ignore */ + + if (!ossl_quic_stream_has_recv(stream)) { + /* + * RFC 9000 s. 19.14: "An endpoint that receives a STREAM_DATA_BLOCKED + * frame for a send-only stream MUST terminate the connection with error + * STREAM_STATE_ERROR." + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_STATE_ERROR, + OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED, + "STREAM_DATA_BLOCKED frame for " + "TX only stream"); + return 0; + } + + /* No-op - informative/debugging frame. */ + return 1; +} + +static int depack_do_frame_streams_blocked(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data, + uint64_t frame_type) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; + } + + if (max_data > (((uint64_t)1) << 60)) { + /* + * RFC 9000 s. 19.14: "This value cannot exceed 2**60, as it is not + * possible to encode stream IDs larger than 2**62 - 1. Receipt of a + * frame that encodes a larger stream ID MUST be treated as a connection + * error of type STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR." + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_STREAM_LIMIT_ERROR, + frame_type, + "invalid stream count limit"); + return 0; + } + + /* No-op - informative/debugging frame. */ + return 1; +} + +static int depack_do_frame_new_conn_id(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + OSSL_QUIC_FRAME_NEW_CONN_ID frame_data; + + if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, + "decode error"); + return 0; + } + + ossl_quic_channel_on_new_conn_id(ch, &frame_data); + + return 1; +} + +static int depack_do_frame_retire_conn_id(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t seq_num; + + if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, + "decode error"); + return 0; + } + + /* + * RFC 9000 s. 19.16: "An endpoint cannot send this frame if it was provided + * with a zero-length connection ID by its peer. An endpoint that provides a + * zero-length connection ID MUST treat receipt of a RETIRE_CONNECTION_ID + * frame as a connection error of type PROTOCOL_VIOLATION." + * + * Since we always use a zero-length SCID as a client, there is no case + * where it is valid for a server to send this. Our server support is + * currently non-conformant and for internal testing use; simply handle it + * as a no-op in this case. + * + * TODO(QUIC SERVER): Revise and implement correctly for server support. + */ + if (!ch->is_server) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, + "conn has zero-length CID"); + return 0; + } + + return 1; +} + +static void free_path_response(unsigned char *buf, size_t buf_len, void *arg) +{ + OPENSSL_free(buf); +} + +static int depack_do_frame_path_challenge(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t frame_data = 0; + unsigned char *encoded = NULL; + size_t encoded_len; + WPACKET wpkt; + + if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE, + "decode error"); + return 0; + } + + /* + * RFC 9000 s. 8.2.2: On receiving a PATH_CHALLENGE frame, an endpoint MUST + * respond by echoing the data contained in the PATH_CHALLENGE frame in a + * PATH_RESPONSE frame. + * + * TODO(QUIC FUTURE): We should try to avoid allocation here in the future. + */ + encoded_len = sizeof(uint64_t) + 1; + if ((encoded = OPENSSL_malloc(encoded_len)) == NULL) + goto err; + + if (!WPACKET_init_static_len(&wpkt, encoded, encoded_len, 0)) + goto err; + + if (!ossl_quic_wire_encode_frame_path_response(&wpkt, frame_data)) { + WPACKET_cleanup(&wpkt); + goto err; + } + + WPACKET_finish(&wpkt); + + if (!ossl_quic_cfq_add_frame(ch->cfq, 0, QUIC_PN_SPACE_APP, + OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE, + QUIC_CFQ_ITEM_FLAG_UNRELIABLE, + encoded, encoded_len, + free_path_response, NULL)) + goto err; + + return 1; + +err: + OPENSSL_free(encoded); + ossl_quic_channel_raise_protocol_error(ch, QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE, + "internal error"); + return 0; +} + +static int depack_do_frame_path_response(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + uint64_t frame_data = 0; + + if (!ossl_quic_wire_decode_frame_path_response(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE, + "decode error"); + return 0; + } + + /* TODO(QUIC MULTIPATH): ADD CODE to send |frame_data| to the ch manager */ + + return 1; +} + +static int depack_do_frame_conn_close(PACKET *pkt, QUIC_CHANNEL *ch, + uint64_t frame_type) +{ + OSSL_QUIC_FRAME_CONN_CLOSE frame_data; + + if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "decode error"); + return 0; + } + + ossl_quic_channel_on_remote_conn_close(ch, &frame_data); + return 1; +} + +static int depack_do_frame_handshake_done(PACKET *pkt, + QUIC_CHANNEL *ch, + OSSL_ACKM_RX_PKT *ackm_data) +{ + if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) { + /* This can fail only with an internal error. */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_INTERNAL_ERROR, + OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE, + "internal error (decode frame handshake done)"); + return 0; + } + + ossl_quic_channel_on_handshake_confirmed(ch); + return 1; +} + +/* Main frame processor */ + +static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt, + OSSL_QRX_PKT *parent_pkt, uint32_t enc_level, + OSSL_TIME received, OSSL_ACKM_RX_PKT *ackm_data) +{ + uint32_t pkt_type = parent_pkt->hdr->type; + uint32_t packet_space = ossl_quic_enc_level_to_pn_space(enc_level); + + if (PACKET_remaining(pkt) == 0) { + /* + * RFC 9000 s. 12.4: An endpoint MUST treat receipt of a packet + * containing no frames as a connection error of type + * PROTOCOL_VIOLATION. + */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + 0, + "empty packet payload"); + return 0; + } + + while (PACKET_remaining(pkt) > 0) { + int was_minimal; + uint64_t frame_type; + const unsigned char *sof = NULL; + uint64_t datalen = 0; + + if (ch->msg_callback != NULL) + sof = PACKET_data(pkt); + + if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, &was_minimal)) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + 0, + "malformed frame header"); + return 0; + } + + if (!was_minimal) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "non-minimal frame type encoding"); + return 0; + } + + /* + * There are only a few frame types which are not ACK-eliciting. Handle + * these centrally to make error handling cases more resilient, as we + * should tell the ACKM about an ACK-eliciting frame even if it was not + * successfully handled. + */ + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_PADDING: + case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + break; + default: + ackm_data->is_ack_eliciting = 1; + break; + } + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_PING: + /* Allowed in all packet types */ + if (!depack_do_frame_ping(pkt, ch, enc_level, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_PADDING: + /* Allowed in all packet types */ + if (!depack_do_frame_padding(pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + /* ACK frames are valid everywhere except in 0RTT packets */ + if (pkt_type == QUIC_PKT_TYPE_0RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "ACK not valid in 0-RTT"); + return 0; + } + if (!depack_do_frame_ack(pkt, ch, packet_space, received, + frame_type, parent_pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + /* RESET_STREAM frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "RESET_STREAM not valid in " + "INITIAL/HANDSHAKE"); + return 0; + } + if (!depack_do_frame_reset_stream(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + /* STOP_SENDING frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "STOP_SENDING not valid in " + "INITIAL/HANDSHAKE"); + return 0; + } + if (!depack_do_frame_stop_sending(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_CRYPTO: + /* CRYPTO frames are valid everywhere except in 0RTT packets */ + if (pkt_type == QUIC_PKT_TYPE_0RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "CRYPTO frame not valid in 0-RTT"); + return 0; + } + if (!depack_do_frame_crypto(pkt, ch, parent_pkt, ackm_data, &datalen)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + /* NEW_TOKEN frames are valid in 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "NEW_TOKEN valid only in 1-RTT"); + return 0; + } + if (!depack_do_frame_new_token(pkt, ch, ackm_data)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM: + case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: + /* STREAM frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "STREAM valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_stream(pkt, ch, parent_pkt, ackm_data, + frame_type, &datalen)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_MAX_DATA: + /* MAX_DATA frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "MAX_DATA valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_max_data(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: + /* MAX_STREAM_DATA frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "MAX_STREAM_DATA valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_max_stream_data(pkt, ch, ackm_data)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + /* MAX_STREAMS frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "MAX_STREAMS valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_max_streams(pkt, ch, ackm_data, + frame_type)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: + /* DATA_BLOCKED frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "DATA_BLOCKED valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_data_blocked(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: + /* STREAM_DATA_BLOCKED frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "STREAM_DATA_BLOCKED valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_stream_data_blocked(pkt, ch, ackm_data)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI: + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: + /* STREAMS_BLOCKED frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "STREAMS valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_streams_blocked(pkt, ch, ackm_data, + frame_type)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + /* NEW_CONN_ID frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "NEW_CONN_ID valid only in 0/1-RTT"); + } + if (!depack_do_frame_new_conn_id(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + /* RETIRE_CONN_ID frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "RETIRE_CONN_ID valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_retire_conn_id(pkt, ch, ackm_data)) + return 0; + break; + case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: + /* PATH_CHALLENGE frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "PATH_CHALLENGE valid only in 0/1-RTT"); + return 0; + } + if (!depack_do_frame_path_challenge(pkt, ch, ackm_data)) + return 0; + + break; + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + /* PATH_RESPONSE frames are valid in 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "PATH_CHALLENGE valid only in 1-RTT"); + return 0; + } + if (!depack_do_frame_path_response(pkt, ch, ackm_data)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + /* CONN_CLOSE_APP frames are valid in 0RTT and 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_0RTT + && pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "CONN_CLOSE (APP) valid only in 0/1-RTT"); + return 0; + } + /* FALLTHRU */ + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: + /* CONN_CLOSE_TRANSPORT frames are valid in all packets */ + if (!depack_do_frame_conn_close(pkt, ch, frame_type)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: + /* HANDSHAKE_DONE frames are valid in 1RTT packets */ + if (pkt_type != QUIC_PKT_TYPE_1RTT) { + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_PROTOCOL_VIOLATION, + frame_type, + "HANDSHAKE_DONE valid only in 1-RTT"); + return 0; + } + if (!depack_do_frame_handshake_done(pkt, ch, ackm_data)) + return 0; + break; + + default: + /* Unknown frame type */ + ossl_quic_channel_raise_protocol_error(ch, + QUIC_ERR_FRAME_ENCODING_ERROR, + frame_type, + "Unknown frame type received"); + return 0; + } + + if (ch->msg_callback != NULL) { + int ctype = SSL3_RT_QUIC_FRAME_FULL; + + size_t framelen = PACKET_data(pkt) - sof; + + if (frame_type == OSSL_QUIC_FRAME_TYPE_PADDING) { + ctype = SSL3_RT_QUIC_FRAME_PADDING; + } else if (OSSL_QUIC_FRAME_TYPE_IS_STREAM(frame_type) + || frame_type == OSSL_QUIC_FRAME_TYPE_CRYPTO) { + ctype = SSL3_RT_QUIC_FRAME_HEADER; + framelen -= (size_t)datalen; + } + + ch->msg_callback(0, OSSL_QUIC1_VERSION, ctype, sof, framelen, + ch->msg_callback_ssl, ch->msg_callback_arg); + } + } + + return 1; +} + +QUIC_NEEDS_LOCK +int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket) +{ + PACKET pkt; + OSSL_ACKM_RX_PKT ackm_data; + uint32_t enc_level; + + /* + * ok has three states: + * -1 error with ackm_data uninitialized + * 0 error with ackm_data initialized + * 1 success (ackm_data initialized) + */ + int ok = -1; /* Assume the worst */ + + if (ch == NULL) + goto end; + + ch->did_crypto_frame = 0; + + /* Initialize |ackm_data| (and reinitialize |ok|)*/ + memset(&ackm_data, 0, sizeof(ackm_data)); + /* + * ASSUMPTION: All packets that aren't special case have a + * packet number. + */ + ackm_data.pkt_num = qpacket->pn; + ackm_data.time = qpacket->time; + enc_level = ossl_quic_pkt_type_to_enc_level(qpacket->hdr->type); + if (enc_level >= QUIC_ENC_LEVEL_NUM) + /* + * Retry and Version Negotiation packets should not be passed to this + * function. + */ + goto end; + + ok = 0; /* Still assume the worst */ + ackm_data.pkt_space = ossl_quic_enc_level_to_pn_space(enc_level); + + /* Now that special cases are out of the way, parse frames */ + if (!PACKET_buf_init(&pkt, qpacket->hdr->data, qpacket->hdr->len) + || !depack_process_frames(ch, &pkt, qpacket, + enc_level, + qpacket->time, + &ackm_data)) + goto end; + + ok = 1; + end: + /* + * ASSUMPTION: If this function is called at all, |qpacket| is + * a legitimate packet, even if its contents aren't. + * Therefore, we call ossl_ackm_on_rx_packet() unconditionally, as long as + * |ackm_data| has at least been initialized. + */ + if (ok >= 0) + ossl_ackm_on_rx_packet(ch->ackm, &ackm_data); + + return ok > 0; +} diff --git a/ssl/quic/quic_sf_list.c b/ssl/quic/quic_sf_list.c new file mode 100644 index 0000000000..0541a2ab63 --- /dev/null +++ b/ssl/quic/quic_sf_list.c @@ -0,0 +1,334 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/uint_set.h" +#include "internal/common.h" +#include "internal/quic_sf_list.h" + +struct stream_frame_st { + struct stream_frame_st *prev, *next; + UINT_RANGE range; + OSSL_QRX_PKT *pkt; + const unsigned char *data; +}; + +static void stream_frame_free(SFRAME_LIST *fl, STREAM_FRAME *sf) +{ + if (fl->cleanse && sf->data != NULL) + OPENSSL_cleanse((unsigned char *)sf->data, + (size_t)(sf->range.end - sf->range.start)); + ossl_qrx_pkt_release(sf->pkt); + OPENSSL_free(sf); +} + +static STREAM_FRAME *stream_frame_new(UINT_RANGE *range, OSSL_QRX_PKT *pkt, + const unsigned char *data) +{ + STREAM_FRAME *sf = OPENSSL_zalloc(sizeof(*sf)); + + if (sf == NULL) + return NULL; + + if (pkt != NULL) + ossl_qrx_pkt_up_ref(pkt); + + sf->range = *range; + sf->pkt = pkt; + sf->data = data; + + return sf; +} + +void ossl_sframe_list_init(SFRAME_LIST *fl) +{ + memset(fl, 0, sizeof(*fl)); +} + +void ossl_sframe_list_destroy(SFRAME_LIST *fl) +{ + STREAM_FRAME *sf, *next_frame; + + for (sf = fl->head; sf != NULL; sf = next_frame) { + next_frame = sf->next; + stream_frame_free(fl, sf); + } +} + +static int append_frame(SFRAME_LIST *fl, UINT_RANGE *range, + OSSL_QRX_PKT *pkt, + const unsigned char *data) +{ + STREAM_FRAME *new_frame; + + if ((new_frame = stream_frame_new(range, pkt, data)) == NULL) + return 0; + new_frame->prev = fl->tail; + if (fl->tail != NULL) + fl->tail->next = new_frame; + fl->tail = new_frame; + ++fl->num_frames; + return 1; +} + +int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range, + OSSL_QRX_PKT *pkt, + const unsigned char *data, int fin) +{ + STREAM_FRAME *sf, *new_frame, *prev_frame, *next_frame; +#ifndef NDEBUG + uint64_t curr_end = fl->tail != NULL ? fl->tail->range.end + : fl->offset; + + /* This check for FINAL_SIZE_ERROR is handled by QUIC FC already */ + assert((!fin || curr_end <= range->end) + && (!fl->fin || curr_end >= range->end)); +#endif + + if (fl->offset >= range->end) + goto end; + + /* nothing there yet */ + if (fl->tail == NULL) { + fl->tail = fl->head = stream_frame_new(range, pkt, data); + if (fl->tail == NULL) + return 0; + + ++fl->num_frames; + goto end; + } + + /* optimize insertion at the end */ + if (fl->tail->range.start < range->start) { + if (fl->tail->range.end >= range->end) + goto end; + + if (!append_frame(fl, range, pkt, data)) + return 0; + goto end; + } + + prev_frame = NULL; + for (sf = fl->head; sf != NULL && sf->range.start < range->start; + sf = sf->next) + prev_frame = sf; + + if (!ossl_assert(sf != NULL)) + /* frame list invariant broken */ + return 0; + + if (prev_frame != NULL && prev_frame->range.end >= range->end) + goto end; + + /* + * Now we must create a new frame although in the end we might drop it, + * because we will be potentially dropping existing overlapping frames. + */ + new_frame = stream_frame_new(range, pkt, data); + if (new_frame == NULL) + return 0; + + for (next_frame = sf; + next_frame != NULL && next_frame->range.end <= range->end;) { + STREAM_FRAME *drop_frame = next_frame; + + next_frame = next_frame->next; + if (next_frame != NULL) + next_frame->prev = drop_frame->prev; + if (prev_frame != NULL) + prev_frame->next = drop_frame->next; + if (fl->head == drop_frame) + fl->head = next_frame; + if (fl->tail == drop_frame) + fl->tail = prev_frame; + --fl->num_frames; + stream_frame_free(fl, drop_frame); + } + + if (next_frame != NULL) { + /* check whether the new_frame is redundant because there is no gap */ + if (prev_frame != NULL + && next_frame->range.start <= prev_frame->range.end) { + stream_frame_free(fl, new_frame); + goto end; + } + next_frame->prev = new_frame; + } else { + fl->tail = new_frame; + } + + new_frame->next = next_frame; + new_frame->prev = prev_frame; + + if (prev_frame != NULL) + prev_frame->next = new_frame; + else + fl->head = new_frame; + + ++fl->num_frames; + + end: + fl->fin = fin || fl->fin; + + return 1; +} + +int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter, + UINT_RANGE *range, const unsigned char **data, + int *fin) +{ + STREAM_FRAME *sf = *iter; + uint64_t start; + + if (sf == NULL) { + start = fl->offset; + sf = fl->head; + } else { + start = sf->range.end; + sf = sf->next; + } + + range->start = start; + + if (sf == NULL || sf->range.start > start + || !ossl_assert(start < sf->range.end)) { + range->end = start; + *data = NULL; + *iter = NULL; + /* set fin only if we are at the end */ + *fin = sf == NULL ? fl->fin : 0; + return 0; + } + + range->end = sf->range.end; + if (sf->data != NULL) + *data = sf->data + (start - sf->range.start); + else + *data = NULL; + *fin = sf->next == NULL ? fl->fin : 0; + *iter = sf; + return 1; +} + +int ossl_sframe_list_drop_frames(SFRAME_LIST *fl, uint64_t limit) +{ + STREAM_FRAME *sf; + + /* offset cannot move back or past the data received */ + if (!ossl_assert(limit >= fl->offset) + || !ossl_assert(fl->tail == NULL + || limit <= fl->tail->range.end) + || !ossl_assert(fl->tail != NULL + || limit == fl->offset)) + return 0; + + fl->offset = limit; + + for (sf = fl->head; sf != NULL && sf->range.end <= limit;) { + STREAM_FRAME *drop_frame = sf; + + sf = sf->next; + --fl->num_frames; + stream_frame_free(fl, drop_frame); + } + fl->head = sf; + + if (sf != NULL) + sf->prev = NULL; + else + fl->tail = NULL; + + fl->head_locked = 0; + + return 1; +} + +int ossl_sframe_list_lock_head(SFRAME_LIST *fl, UINT_RANGE *range, + const unsigned char **data, + int *fin) +{ + int ret; + void *iter = NULL; + + if (fl->head_locked) + return 0; + + ret = ossl_sframe_list_peek(fl, &iter, range, data, fin); + if (ret) + fl->head_locked = 1; + return ret; +} + +int ossl_sframe_list_is_head_locked(SFRAME_LIST *fl) +{ + return fl->head_locked; +} + +int ossl_sframe_list_move_data(SFRAME_LIST *fl, + sframe_list_write_at_cb *write_at_cb, + void *cb_arg) +{ + STREAM_FRAME *sf = fl->head, *prev_frame = NULL; + uint64_t limit = fl->offset; + + if (sf == NULL) + return 1; + + if (fl->head_locked) + sf = sf->next; + + for (; sf != NULL; sf = sf->next) { + size_t len; + const unsigned char *data = sf->data; + + if (limit < sf->range.start) + limit = sf->range.start; + + if (data != NULL) { + if (limit > sf->range.start) + data += (size_t)(limit - sf->range.start); + len = (size_t)(sf->range.end - limit); + + if (!write_at_cb(limit, data, len, cb_arg)) + /* data did not fit */ + return 0; + + if (fl->cleanse) + OPENSSL_cleanse((unsigned char *)sf->data, + (size_t)(sf->range.end - sf->range.start)); + + /* release the packet */ + sf->data = NULL; + ossl_qrx_pkt_release(sf->pkt); + sf->pkt = NULL; + } + + limit = sf->range.end; + + /* merge contiguous frames */ + if (prev_frame != NULL + && prev_frame->range.end >= sf->range.start) { + prev_frame->range.end = sf->range.end; + prev_frame->next = sf->next; + + if (sf->next != NULL) + sf->next->prev = prev_frame; + else + fl->tail = prev_frame; + + --fl->num_frames; + stream_frame_free(fl, sf); + sf = prev_frame; + continue; + } + + prev_frame = sf; + } + + return 1; +} diff --git a/ssl/quic/quic_sstream.c b/ssl/quic/quic_sstream.c new file mode 100644 index 0000000000..1f0b5497fc --- /dev/null +++ b/ssl/quic/quic_sstream.c @@ -0,0 +1,424 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_stream.h" +#include "internal/uint_set.h" +#include "internal/common.h" +#include "internal/ring_buf.h" + +/* + * ================================================================== + * QUIC Send Stream + */ +struct quic_sstream_st { + struct ring_buf ring_buf; + + /* + * Any logical byte in the stream is in one of these states: + * + * - NEW: The byte has not yet been transmitted, or has been lost and is + * in need of retransmission. + * + * - IN_FLIGHT: The byte has been transmitted but is awaiting + * acknowledgement. We continue to store the data in case we return + * to the NEW state. + * + * - ACKED: The byte has been acknowledged and we can cease storing it. + * We do not necessarily cull it immediately, so there may be a delay + * between reaching the ACKED state and the buffer space actually being + * recycled. + * + * A logical byte in the stream is + * + * - in the NEW state if it is in new_set; + * - is in the ACKED state if it is in acked_set + * (and may or may not have been culled); + * - is in the IN_FLIGHT state otherwise. + * + * Invariant: No logical byte is ever in both new_set and acked_set. + */ + UINT_SET new_set, acked_set; + + /* + * The current size of the stream is ring_buf.head_offset. If + * have_final_size is true, this is also the final size of the stream. + */ + unsigned int have_final_size : 1; + unsigned int sent_final_size : 1; + unsigned int acked_final_size : 1; + unsigned int cleanse : 1; +}; + +static void qss_cull(QUIC_SSTREAM *qss); + +QUIC_SSTREAM *ossl_quic_sstream_new(size_t init_buf_size) +{ + QUIC_SSTREAM *qss; + + qss = OPENSSL_zalloc(sizeof(QUIC_SSTREAM)); + if (qss == NULL) + return NULL; + + ring_buf_init(&qss->ring_buf); + if (!ring_buf_resize(&qss->ring_buf, init_buf_size, 0)) { + ring_buf_destroy(&qss->ring_buf, 0); + OPENSSL_free(qss); + return NULL; + } + + ossl_uint_set_init(&qss->new_set); + ossl_uint_set_init(&qss->acked_set); + return qss; +} + +void ossl_quic_sstream_free(QUIC_SSTREAM *qss) +{ + if (qss == NULL) + return; + + ossl_uint_set_destroy(&qss->new_set); + ossl_uint_set_destroy(&qss->acked_set); + ring_buf_destroy(&qss->ring_buf, qss->cleanse); + OPENSSL_free(qss); +} + +int ossl_quic_sstream_get_stream_frame(QUIC_SSTREAM *qss, + size_t skip, + OSSL_QUIC_FRAME_STREAM *hdr, + OSSL_QTX_IOVEC *iov, + size_t *num_iov) +{ + size_t num_iov_ = 0, src_len = 0, total_len = 0, i; + uint64_t max_len; + const unsigned char *src = NULL; + UINT_SET_ITEM *range = ossl_list_uint_set_head(&qss->new_set); + + if (*num_iov < 2) + return 0; + + for (i = 0; i < skip && range != NULL; ++i) + range = ossl_list_uint_set_next(range); + + if (range == NULL) { + if (i < skip) + /* Don't return FIN for infinitely increasing skip */ + return 0; + + /* No new bytes to send, but we might have a FIN */ + if (!qss->have_final_size || qss->sent_final_size) + return 0; + + hdr->offset = qss->ring_buf.head_offset; + hdr->len = 0; + hdr->is_fin = 1; + *num_iov = 0; + return 1; + } + + /* + * We can only send a contiguous range of logical bytes in a single + * stream frame, so limit ourselves to the range of the first set entry. + * + * Set entries never have 'adjacent' entries so we don't have to worry + * about them here. + */ + max_len = range->range.end - range->range.start + 1; + + for (i = 0;; ++i) { + if (total_len >= max_len) + break; + + if (!ring_buf_get_buf_at(&qss->ring_buf, + range->range.start + total_len, + &src, &src_len)) + return 0; + + if (src_len == 0) + break; + + assert(i < 2); + + if (total_len + src_len > max_len) + src_len = (size_t)(max_len - total_len); + + iov[num_iov_].buf = src; + iov[num_iov_].buf_len = src_len; + + total_len += src_len; + ++num_iov_; + } + + hdr->offset = range->range.start; + hdr->len = total_len; + hdr->is_fin = qss->have_final_size + && hdr->offset + hdr->len == qss->ring_buf.head_offset; + + *num_iov = num_iov_; + return 1; +} + +int ossl_quic_sstream_has_pending(QUIC_SSTREAM *qss) +{ + OSSL_QUIC_FRAME_STREAM shdr; + OSSL_QTX_IOVEC iov[2]; + size_t num_iov = OSSL_NELEM(iov); + + return ossl_quic_sstream_get_stream_frame(qss, 0, &shdr, iov, &num_iov); +} + +uint64_t ossl_quic_sstream_get_cur_size(QUIC_SSTREAM *qss) +{ + return qss->ring_buf.head_offset; +} + +int ossl_quic_sstream_mark_transmitted(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end) +{ + UINT_RANGE r; + + r.start = start; + r.end = end; + + if (!ossl_uint_set_remove(&qss->new_set, &r)) + return 0; + + return 1; +} + +int ossl_quic_sstream_mark_transmitted_fin(QUIC_SSTREAM *qss, + uint64_t final_size) +{ + /* + * We do not really need final_size since we already know the size of the + * stream, but this serves as a sanity check. + */ + if (!qss->have_final_size || final_size != qss->ring_buf.head_offset) + return 0; + + qss->sent_final_size = 1; + return 1; +} + +int ossl_quic_sstream_mark_lost(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end) +{ + UINT_RANGE r; + r.start = start; + r.end = end; + + /* + * We lost a range of stream data bytes, so reinsert them into the new set, + * so that they are returned once more by ossl_quic_sstream_get_stream_frame. + */ + if (!ossl_uint_set_insert(&qss->new_set, &r)) + return 0; + + return 1; +} + +int ossl_quic_sstream_mark_lost_fin(QUIC_SSTREAM *qss) +{ + if (qss->acked_final_size) + /* Does not make sense to lose a FIN after it has been ACKed */ + return 0; + + /* FIN was lost, so we need to transmit it again. */ + qss->sent_final_size = 0; + return 1; +} + +int ossl_quic_sstream_mark_acked(QUIC_SSTREAM *qss, + uint64_t start, + uint64_t end) +{ + UINT_RANGE r; + r.start = start; + r.end = end; + + if (!ossl_uint_set_insert(&qss->acked_set, &r)) + return 0; + + qss_cull(qss); + return 1; +} + +int ossl_quic_sstream_mark_acked_fin(QUIC_SSTREAM *qss) +{ + if (!qss->have_final_size) + /* Cannot ack final size before we have a final size */ + return 0; + + qss->acked_final_size = 1; + return 1; +} + +void ossl_quic_sstream_fin(QUIC_SSTREAM *qss) +{ + if (qss->have_final_size) + return; + + qss->have_final_size = 1; +} + +int ossl_quic_sstream_get_final_size(QUIC_SSTREAM *qss, uint64_t *final_size) +{ + if (!qss->have_final_size) + return 0; + + if (final_size != NULL) + *final_size = qss->ring_buf.head_offset; + + return 1; +} + +int ossl_quic_sstream_append(QUIC_SSTREAM *qss, + const unsigned char *buf, + size_t buf_len, + size_t *consumed) +{ + size_t l, consumed_ = 0; + UINT_RANGE r; + struct ring_buf old_ring_buf = qss->ring_buf; + + if (qss->have_final_size) { + *consumed = 0; + return 0; + } + + /* + * Note: It is assumed that ossl_quic_sstream_append will be called during a + * call to e.g. SSL_write and this function is therefore designed to support + * such semantics. In particular, the buffer pointed to by buf is only + * assumed to be valid for the duration of this call, therefore we must copy + * the data here. We will later copy-and-encrypt the data during packet + * encryption, so this is a two-copy design. Supporting a one-copy design in + * the future will require applications to use a different kind of API. + * Supporting such changes in future will require corresponding enhancements + * to this code. + */ + while (buf_len > 0) { + l = ring_buf_push(&qss->ring_buf, buf, buf_len); + if (l == 0) + break; + + buf += l; + buf_len -= l; + consumed_ += l; + } + + if (consumed_ > 0) { + r.start = old_ring_buf.head_offset; + r.end = r.start + consumed_ - 1; + assert(r.end + 1 == qss->ring_buf.head_offset); + if (!ossl_uint_set_insert(&qss->new_set, &r)) { + qss->ring_buf = old_ring_buf; + *consumed = 0; + return 0; + } + } + + *consumed = consumed_; + return 1; +} + +static void qss_cull(QUIC_SSTREAM *qss) +{ + UINT_SET_ITEM *h = ossl_list_uint_set_head(&qss->acked_set); + + /* + * Potentially cull data from our ring buffer. This can happen once data has + * been ACKed and we know we are never going to have to transmit it again. + * + * Since we use a ring buffer design for simplicity, we cannot cull byte n + + * k (for k > 0) from the ring buffer until byte n has also been culled. + * This means if parts of the stream get acknowledged out of order we might + * keep around some data we technically don't need to for a while. The + * impact of this is likely to be small and limited to quite a short + * duration, and doesn't justify the use of a more complex design. + */ + + /* + * We only need to check the first range entry in the integer set because we + * can only cull contiguous areas at the start of the ring buffer anyway. + */ + if (h != NULL) + ring_buf_cpop_range(&qss->ring_buf, h->range.start, h->range.end, + qss->cleanse); +} + +int ossl_quic_sstream_set_buffer_size(QUIC_SSTREAM *qss, size_t num_bytes) +{ + return ring_buf_resize(&qss->ring_buf, num_bytes, qss->cleanse); +} + +size_t ossl_quic_sstream_get_buffer_size(QUIC_SSTREAM *qss) +{ + return qss->ring_buf.alloc; +} + +size_t ossl_quic_sstream_get_buffer_used(QUIC_SSTREAM *qss) +{ + return ring_buf_used(&qss->ring_buf); +} + +size_t ossl_quic_sstream_get_buffer_avail(QUIC_SSTREAM *qss) +{ + return ring_buf_avail(&qss->ring_buf); +} + +int ossl_quic_sstream_is_totally_acked(QUIC_SSTREAM *qss) +{ + UINT_RANGE r; + uint64_t cur_size; + + if (qss->have_final_size && !qss->acked_final_size) + return 0; + + if (ossl_quic_sstream_get_cur_size(qss) == 0) + return 1; + + if (ossl_list_uint_set_num(&qss->acked_set) != 1) + return 0; + + r = ossl_list_uint_set_head(&qss->acked_set)->range; + cur_size = qss->ring_buf.head_offset; + + /* + * The invariants of UINT_SET guarantee a single list element if we have a + * single contiguous range, which is what we should have if everything has + * been acked. + */ + assert(r.end + 1 <= cur_size); + return r.start == 0 && r.end + 1 == cur_size; +} + +void ossl_quic_sstream_adjust_iov(size_t len, + OSSL_QTX_IOVEC *iov, + size_t num_iov) +{ + size_t running = 0, i, iovlen; + + for (i = 0, running = 0; i < num_iov; ++i) { + iovlen = iov[i].buf_len; + + if (running >= len) + iov[i].buf_len = 0; + else if (running + iovlen > len) + iov[i].buf_len = len - running; + + running += iovlen; + } +} + +void ossl_quic_sstream_set_cleanse(QUIC_SSTREAM *qss, int cleanse) +{ + qss->cleanse = cleanse; +} diff --git a/ssl/quic/quic_statm.c b/ssl/quic/quic_statm.c new file mode 100644 index 0000000000..f1e0f65914 --- /dev/null +++ b/ssl/quic/quic_statm.c @@ -0,0 +1,76 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_statm.h" + +void ossl_statm_update_rtt(OSSL_STATM *statm, + OSSL_TIME ack_delay, + OSSL_TIME override_latest_rtt) +{ + OSSL_TIME adjusted_rtt, latest_rtt = override_latest_rtt; + + /* Use provided RTT value, or else last RTT value. */ + if (ossl_time_is_zero(latest_rtt)) + latest_rtt = statm->latest_rtt; + else + statm->latest_rtt = latest_rtt; + + if (!statm->have_first_sample) { + statm->min_rtt = latest_rtt; + statm->smoothed_rtt = latest_rtt; + statm->rtt_variance = ossl_time_divide(latest_rtt, 2); + statm->have_first_sample = 1; + return; + } + + /* Update minimum RTT. */ + if (ossl_time_compare(latest_rtt, statm->min_rtt) < 0) + statm->min_rtt = latest_rtt; + + /* + * Enforcement of max_ack_delay is the responsibility of + * the caller as it is context-dependent. + */ + + adjusted_rtt = latest_rtt; + if (ossl_time_compare(latest_rtt, ossl_time_add(statm->min_rtt, ack_delay)) >= 0) + adjusted_rtt = ossl_time_subtract(latest_rtt, ack_delay); + + statm->rtt_variance = ossl_time_divide(ossl_time_add(ossl_time_multiply(statm->rtt_variance, 3), + ossl_time_abs_difference(statm->smoothed_rtt, + adjusted_rtt)), 4); + statm->smoothed_rtt = ossl_time_divide(ossl_time_add(ossl_time_multiply(statm->smoothed_rtt, 7), + adjusted_rtt), 8); +} + +/* RFC 9002 kInitialRtt value. RFC recommended value. */ +#define K_INITIAL_RTT ossl_ms2time(333) + +int ossl_statm_init(OSSL_STATM *statm) +{ + statm->smoothed_rtt = K_INITIAL_RTT; + statm->latest_rtt = ossl_time_zero(); + statm->min_rtt = ossl_time_infinite(); + statm->rtt_variance = ossl_time_divide(K_INITIAL_RTT, 2); + statm->have_first_sample = 0; + return 1; +} + +void ossl_statm_destroy(OSSL_STATM *statm) +{ + /* No-op. */ +} + +void ossl_statm_get_rtt_info(OSSL_STATM *statm, OSSL_RTT_INFO *rtt_info) +{ + rtt_info->min_rtt = statm->min_rtt; + rtt_info->latest_rtt = statm->latest_rtt; + rtt_info->smoothed_rtt = statm->smoothed_rtt; + rtt_info->rtt_variance = statm->rtt_variance; +} diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c new file mode 100644 index 0000000000..f8278c9913 --- /dev/null +++ b/ssl/quic/quic_stream_map.c @@ -0,0 +1,848 @@ +/* +* Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#include "internal/quic_stream_map.h" +#include "internal/nelem.h" + +/* + * QUIC Stream Map + * =============== + */ +DEFINE_LHASH_OF_EX(QUIC_STREAM); + +static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs); + +/* Circular list management. */ +static void list_insert_tail(QUIC_STREAM_LIST_NODE *l, + QUIC_STREAM_LIST_NODE *n) +{ + /* Must not be in list. */ + assert(n->prev == NULL && n->next == NULL + && l->prev != NULL && l->next != NULL); + + n->prev = l->prev; + n->prev->next = n; + l->prev = n; + n->next = l; +} + +static void list_remove(QUIC_STREAM_LIST_NODE *l, + QUIC_STREAM_LIST_NODE *n) +{ + assert(n->prev != NULL && n->next != NULL + && n->prev != n && n->next != n); + + n->prev->next = n->next; + n->next->prev = n->prev; + n->next = n->prev = NULL; +} + +static QUIC_STREAM *list_next(QUIC_STREAM_LIST_NODE *l, QUIC_STREAM_LIST_NODE *n, + size_t off) +{ + assert(n->prev != NULL && n->next != NULL + && (n == l || (n->prev != n && n->next != n)) + && l->prev != NULL && l->next != NULL); + + n = n->next; + + if (n == l) + n = n->next; + if (n == l) + return NULL; + + assert(n != NULL); + + return (QUIC_STREAM *)(((char *)n) - off); +} + +#define active_next(l, s) list_next((l), &(s)->active_node, \ + offsetof(QUIC_STREAM, active_node)) +#define accept_next(l, s) list_next((l), &(s)->accept_node, \ + offsetof(QUIC_STREAM, accept_node)) +#define ready_for_gc_next(l, s) list_next((l), &(s)->ready_for_gc_node, \ + offsetof(QUIC_STREAM, ready_for_gc_node)) +#define accept_head(l) list_next((l), (l), \ + offsetof(QUIC_STREAM, accept_node)) +#define ready_for_gc_head(l) list_next((l), (l), \ + offsetof(QUIC_STREAM, ready_for_gc_node)) + +static unsigned long hash_stream(const QUIC_STREAM *s) +{ + return (unsigned long)s->id; +} + +static int cmp_stream(const QUIC_STREAM *a, const QUIC_STREAM *b) +{ + if (a->id < b->id) + return -1; + if (a->id > b->id) + return 1; + return 0; +} + +int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm, + uint64_t (*get_stream_limit_cb)(int uni, void *arg), + void *get_stream_limit_cb_arg, + QUIC_RXFC *max_streams_bidi_rxfc, + QUIC_RXFC *max_streams_uni_rxfc, + int is_server) +{ + qsm->map = lh_QUIC_STREAM_new(hash_stream, cmp_stream); + qsm->active_list.prev = qsm->active_list.next = &qsm->active_list; + qsm->accept_list.prev = qsm->accept_list.next = &qsm->accept_list; + qsm->ready_for_gc_list.prev = qsm->ready_for_gc_list.next + = &qsm->ready_for_gc_list; + qsm->rr_stepping = 1; + qsm->rr_counter = 0; + qsm->rr_cur = NULL; + + qsm->num_accept = 0; + qsm->num_shutdown_flush = 0; + + qsm->get_stream_limit_cb = get_stream_limit_cb; + qsm->get_stream_limit_cb_arg = get_stream_limit_cb_arg; + qsm->max_streams_bidi_rxfc = max_streams_bidi_rxfc; + qsm->max_streams_uni_rxfc = max_streams_uni_rxfc; + qsm->is_server = is_server; + return 1; +} + +static void release_each(QUIC_STREAM *stream, void *arg) +{ + QUIC_STREAM_MAP *qsm = arg; + + ossl_quic_stream_map_release(qsm, stream); +} + +void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm) +{ + ossl_quic_stream_map_visit(qsm, release_each, qsm); + + lh_QUIC_STREAM_free(qsm->map); + qsm->map = NULL; +} + +void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm, + void (*visit_cb)(QUIC_STREAM *stream, void *arg), + void *visit_cb_arg) +{ + lh_QUIC_STREAM_doall_arg(qsm->map, visit_cb, visit_cb_arg); +} + +QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm, + uint64_t stream_id, + int type) +{ + QUIC_STREAM *s; + QUIC_STREAM key; + + key.id = stream_id; + + s = lh_QUIC_STREAM_retrieve(qsm->map, &key); + if (s != NULL) + return NULL; + + s = OPENSSL_zalloc(sizeof(*s)); + if (s == NULL) + return NULL; + + s->id = stream_id; + s->type = type; + s->as_server = qsm->is_server; + s->send_state = (ossl_quic_stream_is_local_init(s) + || ossl_quic_stream_is_bidi(s)) + ? QUIC_SSTREAM_STATE_READY + : QUIC_SSTREAM_STATE_NONE; + s->recv_state = (!ossl_quic_stream_is_local_init(s) + || ossl_quic_stream_is_bidi(s)) + ? QUIC_RSTREAM_STATE_RECV + : QUIC_RSTREAM_STATE_NONE; + + s->send_final_size = UINT64_MAX; + + lh_QUIC_STREAM_insert(qsm->map, s); + return s; +} + +void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream) +{ + if (stream == NULL) + return; + + if (stream->active_node.next != NULL) + list_remove(&qsm->active_list, &stream->active_node); + if (stream->accept_node.next != NULL) + list_remove(&qsm->accept_list, &stream->accept_node); + if (stream->ready_for_gc_node.next != NULL) + list_remove(&qsm->ready_for_gc_list, &stream->ready_for_gc_node); + + ossl_quic_sstream_free(stream->sstream); + stream->sstream = NULL; + + ossl_quic_rstream_free(stream->rstream); + stream->rstream = NULL; + + lh_QUIC_STREAM_delete(qsm->map, stream); + OPENSSL_free(stream); +} + +QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm, + uint64_t stream_id) +{ + QUIC_STREAM key; + + key.id = stream_id; + + return lh_QUIC_STREAM_retrieve(qsm->map, &key); +} + +static void stream_map_mark_active(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) +{ + if (s->active) + return; + + list_insert_tail(&qsm->active_list, &s->active_node); + + if (qsm->rr_cur == NULL) + qsm->rr_cur = s; + + s->active = 1; +} + +static void stream_map_mark_inactive(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) +{ + if (!s->active) + return; + + if (qsm->rr_cur == s) + qsm->rr_cur = active_next(&qsm->active_list, s); + if (qsm->rr_cur == s) + qsm->rr_cur = NULL; + + list_remove(&qsm->active_list, &s->active_node); + + s->active = 0; +} + +void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping) +{ + qsm->rr_stepping = stepping; + qsm->rr_counter = 0; +} + +static int stream_has_data_to_send(QUIC_STREAM *s) +{ + OSSL_QUIC_FRAME_STREAM shdr; + OSSL_QTX_IOVEC iov[2]; + size_t num_iov; + uint64_t fc_credit, fc_swm, fc_limit; + + switch (s->send_state) { + case QUIC_SSTREAM_STATE_READY: + case QUIC_SSTREAM_STATE_SEND: + case QUIC_SSTREAM_STATE_DATA_SENT: + /* + * We can still have data to send in DATA_SENT due to retransmissions, + * etc. + */ + break; + default: + return 0; /* Nothing to send. */ + } + + /* + * We cannot determine if we have data to send simply by checking if + * ossl_quic_txfc_get_credit() is zero, because we may also have older + * stream data we need to retransmit. The SSTREAM returns older data first, + * so we do a simple comparison of the next chunk the SSTREAM wants to send + * against the TXFC CWM. + */ + num_iov = OSSL_NELEM(iov); + if (!ossl_quic_sstream_get_stream_frame(s->sstream, 0, &shdr, iov, + &num_iov)) + return 0; + + fc_credit = ossl_quic_txfc_get_credit(&s->txfc, 0); + fc_swm = ossl_quic_txfc_get_swm(&s->txfc); + fc_limit = fc_swm + fc_credit; + + return (shdr.is_fin && shdr.len == 0) || shdr.offset < fc_limit; +} + +static ossl_unused int qsm_send_part_permits_gc(const QUIC_STREAM *qs) +{ + switch (qs->send_state) { + case QUIC_SSTREAM_STATE_NONE: + case QUIC_SSTREAM_STATE_DATA_RECVD: + case QUIC_SSTREAM_STATE_RESET_RECVD: + return 1; + default: + return 0; + } +} + +static int qsm_ready_for_gc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) +{ + int recv_stream_fully_drained = 0; /* TODO(QUIC FUTURE): Optimisation */ + + /* + * If sstream has no FIN, we auto-reset it at marked-for-deletion time, so + * we don't need to worry about that here. + */ + assert(!qs->deleted + || !ossl_quic_stream_has_send(qs) + || ossl_quic_stream_send_is_reset(qs) + || ossl_quic_stream_send_get_final_size(qs, NULL)); + + return + qs->deleted + && (!ossl_quic_stream_has_recv(qs) + || recv_stream_fully_drained + || qs->acked_stop_sending) + && (!ossl_quic_stream_has_send(qs) + || qs->send_state == QUIC_SSTREAM_STATE_DATA_RECVD + || qs->send_state == QUIC_SSTREAM_STATE_RESET_RECVD); +} + +int ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP *qsm, + uint64_t stream_ordinal, + int is_uni) +{ + uint64_t stream_limit; + + if (qsm->get_stream_limit_cb == NULL) + return 1; + + stream_limit = qsm->get_stream_limit_cb(is_uni, qsm->get_stream_limit_cb_arg); + return stream_ordinal < stream_limit; +} + +void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) +{ + int should_be_active, allowed_by_stream_limit = 1; + + if (ossl_quic_stream_is_server_init(s) == qsm->is_server) { + int is_uni = !ossl_quic_stream_is_bidi(s); + uint64_t stream_ordinal = s->id >> 2; + + allowed_by_stream_limit + = ossl_quic_stream_map_is_local_allowed_by_stream_limit(qsm, + stream_ordinal, + is_uni); + } + + if (s->send_state == QUIC_SSTREAM_STATE_DATA_SENT + && ossl_quic_sstream_is_totally_acked(s->sstream)) + ossl_quic_stream_map_notify_totally_acked(qsm, s); + else if (s->shutdown_flush + && s->send_state == QUIC_SSTREAM_STATE_SEND + && ossl_quic_sstream_is_totally_acked(s->sstream)) + shutdown_flush_done(qsm, s); + + if (!s->ready_for_gc) { + s->ready_for_gc = qsm_ready_for_gc(qsm, s); + if (s->ready_for_gc) + list_insert_tail(&qsm->ready_for_gc_list, &s->ready_for_gc_node); + } + + should_be_active + = allowed_by_stream_limit + && !s->ready_for_gc + && ((ossl_quic_stream_has_recv(s) + && !ossl_quic_stream_recv_is_reset(s) + && (s->recv_state == QUIC_RSTREAM_STATE_RECV + && (s->want_max_stream_data + || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0)))) + || s->want_stop_sending + || s->want_reset_stream + || (!s->peer_stop_sending && stream_has_data_to_send(s))); + + if (should_be_active) + stream_map_mark_active(qsm, s); + else + stream_map_mark_inactive(qsm, s); +} + +/* + * Stream Send Part State Management + * ================================= + */ + +int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->send_state) { + case QUIC_SSTREAM_STATE_NONE: + /* Stream without send part - caller error. */ + return 0; + + case QUIC_SSTREAM_STATE_READY: + /* + * We always allocate a stream ID upfront, so we don't need to do it + * here. + */ + qs->send_state = QUIC_SSTREAM_STATE_SEND; + return 1; + + default: + /* Nothing to do. */ + return 1; + } +} + +int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->send_state) { + default: + /* Wrong state - caller error. */ + case QUIC_SSTREAM_STATE_NONE: + /* Stream without send part - caller error. */ + return 0; + + case QUIC_SSTREAM_STATE_SEND: + if (!ossl_quic_sstream_get_final_size(qs->sstream, &qs->send_final_size)) + return 0; + + qs->send_state = QUIC_SSTREAM_STATE_DATA_SENT; + return 1; + } +} + +static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) +{ + if (!qs->shutdown_flush) + return; + + assert(qsm->num_shutdown_flush > 0); + qs->shutdown_flush = 0; + --qsm->num_shutdown_flush; +} + +int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->send_state) { + default: + /* Wrong state - caller error. */ + case QUIC_SSTREAM_STATE_NONE: + /* Stream without send part - caller error. */ + return 0; + + case QUIC_SSTREAM_STATE_DATA_SENT: + qs->send_state = QUIC_SSTREAM_STATE_DATA_RECVD; + /* We no longer need a QUIC_SSTREAM in this state. */ + ossl_quic_sstream_free(qs->sstream); + qs->sstream = NULL; + + shutdown_flush_done(qsm, qs); + return 1; + } +} + +int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t aec) +{ + switch (qs->send_state) { + default: + case QUIC_SSTREAM_STATE_NONE: + /* + * RESET_STREAM pertains to sending part only, so we cannot reset a + * receive-only stream. + */ + case QUIC_SSTREAM_STATE_DATA_RECVD: + /* + * RFC 9000 s. 3.3: A sender MUST NOT [...] send RESET_STREAM from a + * terminal state. If the stream has already finished normally and the + * peer has acknowledged this, we cannot reset it. + */ + return 0; + + case QUIC_SSTREAM_STATE_READY: + if (!ossl_quic_stream_map_ensure_send_part_id(qsm, qs)) + return 0; + + /* FALLTHROUGH */ + case QUIC_SSTREAM_STATE_SEND: + /* + * If we already have a final size (e.g. because we are coming from + * DATA_SENT), we have to be consistent with that, so don't change it. + * If we don't already have a final size, determine a final size value. + * This is the value which we will end up using for a RESET_STREAM frame + * for flow control purposes. We could send the stream size (total + * number of bytes appended to QUIC_SSTREAM by the application), but it + * is in our interest to exclude any bytes we have not actually + * transmitted yet, to avoid unnecessarily consuming flow control + * credit. We can get this from the TXFC. + */ + qs->send_final_size = ossl_quic_txfc_get_swm(&qs->txfc); + + /* FALLTHROUGH */ + case QUIC_SSTREAM_STATE_DATA_SENT: + qs->reset_stream_aec = aec; + qs->want_reset_stream = 1; + qs->send_state = QUIC_SSTREAM_STATE_RESET_SENT; + + ossl_quic_sstream_free(qs->sstream); + qs->sstream = NULL; + + shutdown_flush_done(qsm, qs); + ossl_quic_stream_map_update_state(qsm, qs); + return 1; + + case QUIC_SSTREAM_STATE_RESET_SENT: + case QUIC_SSTREAM_STATE_RESET_RECVD: + /* + * Idempotent - no-op. In any case, do not send RESET_STREAM again - as + * mentioned, we must not send it from a terminal state. + */ + return 1; + } +} + +int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->send_state) { + default: + /* Wrong state - caller error. */ + case QUIC_SSTREAM_STATE_NONE: + /* Stream without send part - caller error. */ + return 0; + + case QUIC_SSTREAM_STATE_RESET_SENT: + qs->send_state = QUIC_SSTREAM_STATE_RESET_RECVD; + return 1; + + case QUIC_SSTREAM_STATE_RESET_RECVD: + /* Already in the correct state. */ + return 1; + } +} + +/* + * Stream Receive Part State Management + * ==================================== + */ + +int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t final_size) +{ + switch (qs->recv_state) { + default: + /* Wrong state - caller error. */ + case QUIC_RSTREAM_STATE_NONE: + /* Stream without receive part - caller error. */ + return 0; + + case QUIC_RSTREAM_STATE_RECV: + qs->recv_state = QUIC_RSTREAM_STATE_SIZE_KNOWN; + return 1; + } +} + +int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->recv_state) { + default: + /* Wrong state - caller error. */ + case QUIC_RSTREAM_STATE_NONE: + /* Stream without receive part - caller error. */ + return 0; + + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + qs->recv_state = QUIC_RSTREAM_STATE_DATA_RECVD; + qs->want_stop_sending = 0; + return 1; + } +} + +int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->recv_state) { + default: + /* Wrong state - caller error. */ + case QUIC_RSTREAM_STATE_NONE: + /* Stream without receive part - caller error. */ + return 0; + + case QUIC_RSTREAM_STATE_DATA_RECVD: + qs->recv_state = QUIC_RSTREAM_STATE_DATA_READ; + + /* QUIC_RSTREAM is no longer needed */ + ossl_quic_rstream_free(qs->rstream); + qs->rstream = NULL; + return 1; + } +} + +int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t app_error_code, + uint64_t final_size) +{ + uint64_t prev_final_size; + + switch (qs->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + /* Stream without receive part - caller error. */ + return 0; + + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + case QUIC_RSTREAM_STATE_DATA_RECVD: + if (ossl_quic_stream_recv_get_final_size(qs, &prev_final_size) + && prev_final_size != final_size) + /* Cannot change previous final size. */ + return 0; + + qs->recv_state = QUIC_RSTREAM_STATE_RESET_RECVD; + qs->peer_reset_stream_aec = app_error_code; + + /* RFC 9000 s. 3.3: No point sending STOP_SENDING if already reset. */ + qs->want_stop_sending = 0; + + /* QUIC_RSTREAM is no longer needed */ + ossl_quic_rstream_free(qs->rstream); + qs->rstream = NULL; + + ossl_quic_stream_map_update_state(qsm, qs); + return 1; + + case QUIC_RSTREAM_STATE_DATA_READ: + /* + * If we already retired the FIN to the application this is moot + * - just ignore. + */ + case QUIC_RSTREAM_STATE_RESET_RECVD: + case QUIC_RSTREAM_STATE_RESET_READ: + /* Could be a reordered/retransmitted frame - just ignore. */ + return 1; + } +} + +int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs) +{ + switch (qs->recv_state) { + default: + /* Wrong state - caller error. */ + case QUIC_RSTREAM_STATE_NONE: + /* Stream without receive part - caller error. */ + return 0; + + case QUIC_RSTREAM_STATE_RESET_RECVD: + qs->recv_state = QUIC_RSTREAM_STATE_RESET_READ; + return 1; + } +} + +int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t aec) +{ + if (qs->stop_sending) + return 0; + + switch (qs->recv_state) { + default: + case QUIC_RSTREAM_STATE_NONE: + /* Send-only stream, so this makes no sense. */ + case QUIC_RSTREAM_STATE_DATA_RECVD: + case QUIC_RSTREAM_STATE_DATA_READ: + /* + * Not really any point in STOP_SENDING if we already received all data. + */ + case QUIC_RSTREAM_STATE_RESET_RECVD: + case QUIC_RSTREAM_STATE_RESET_READ: + /* + * RFC 9000 s. 3.5: "STOP_SENDING SHOULD only be sent for a stream that + * has not been reset by the peer." + * + * No point in STOP_SENDING if the peer already reset their send part. + */ + return 0; + + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + /* + * RFC 9000 s. 3.5: "If the stream is in the Recv or Size Known state, + * the transport SHOULD signal this by sending a STOP_SENDING frame to + * prompt closure of the stream in the opposite direction." + * + * Note that it does make sense to send STOP_SENDING for a receive part + * of a stream which has a known size (because we have received a FIN) + * but which still has other (previous) stream data yet to be received. + */ + break; + } + + qs->stop_sending = 1; + qs->stop_sending_aec = aec; + return ossl_quic_stream_map_schedule_stop_sending(qsm, qs); +} + +/* Called to mark STOP_SENDING for generation, or regeneration after loss. */ +int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) +{ + if (!qs->stop_sending) + return 0; + + /* + * Ignore the call as a no-op if already scheduled, or in a state + * where it makes no sense to send STOP_SENDING. + */ + if (qs->want_stop_sending) + return 1; + + switch (qs->recv_state) { + default: + return 1; /* ignore */ + case QUIC_RSTREAM_STATE_RECV: + case QUIC_RSTREAM_STATE_SIZE_KNOWN: + /* + * RFC 9000 s. 3.5: "An endpoint is expected to send another + * STOP_SENDING frame if a packet containing a previous STOP_SENDING is + * lost. However, once either all stream data or a RESET_STREAM frame + * has been received for the stream -- that is, the stream is in any + * state other than "Recv" or "Size Known" -- sending a STOP_SENDING + * frame is unnecessary." + */ + break; + } + + qs->want_stop_sending = 1; + ossl_quic_stream_map_update_state(qsm, qs); + return 1; +} + +QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm) +{ + return accept_head(&qsm->accept_list); +} + +void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s) +{ + list_insert_tail(&qsm->accept_list, &s->accept_node); + ++qsm->num_accept; +} + +static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) +{ + return ossl_quic_stream_is_bidi(s) + ? qsm->max_streams_bidi_rxfc + : qsm->max_streams_uni_rxfc; +} + +void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s, + OSSL_TIME rtt) +{ + QUIC_RXFC *max_streams_rxfc; + + list_remove(&qsm->accept_list, &s->accept_node); + --qsm->num_accept; + + if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL) + ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt); +} + +size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm) +{ + return qsm->num_accept; +} + +void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm) +{ + QUIC_STREAM *qs, *qs_head, *qsn = NULL; + + for (qs = qs_head = ready_for_gc_head(&qsm->ready_for_gc_list); + qs != NULL && qs != qs_head; + qs = qsn) + { + qsn = ready_for_gc_next(&qsm->ready_for_gc_list, qs); + + ossl_quic_stream_map_release(qsm, qs); + } +} + +static int eligible_for_shutdown_flush(QUIC_STREAM *qs) +{ + /* + * We only care about servicing the send part of a stream (if any) during + * shutdown flush. We make sure we flush a stream if it is either + * non-terminated or was terminated normally such as via + * SSL_stream_conclude. A stream which was terminated via a reset is not + * flushed, and we will have thrown away the send buffer in that case + * anyway. + */ + switch (qs->send_state) { + case QUIC_SSTREAM_STATE_SEND: + case QUIC_SSTREAM_STATE_DATA_SENT: + return !ossl_quic_sstream_is_totally_acked(qs->sstream); + default: + return 0; + } +} + +static void begin_shutdown_flush_each(QUIC_STREAM *qs, void *arg) +{ + QUIC_STREAM_MAP *qsm = arg; + + if (!eligible_for_shutdown_flush(qs) || qs->shutdown_flush) + return; + + qs->shutdown_flush = 1; + ++qsm->num_shutdown_flush; +} + +void ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP *qsm) +{ + qsm->num_shutdown_flush = 0; + + ossl_quic_stream_map_visit(qsm, begin_shutdown_flush_each, qsm); +} + +int ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP *qsm) +{ + return qsm->num_shutdown_flush == 0; +} + +/* + * QUIC Stream Iterator + * ==================== + */ +void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm, + int advance_rr) +{ + it->qsm = qsm; + it->stream = it->first_stream = qsm->rr_cur; + if (advance_rr && it->stream != NULL + && ++qsm->rr_counter >= qsm->rr_stepping) { + qsm->rr_counter = 0; + qsm->rr_cur = active_next(&qsm->active_list, qsm->rr_cur); + } +} + +void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it) +{ + if (it->stream == NULL) + return; + + it->stream = active_next(&it->qsm->active_list, it->stream); + if (it->stream == it->first_stream) + it->stream = NULL; +} diff --git a/ssl/quic/quic_thread_assist.c b/ssl/quic/quic_thread_assist.c new file mode 100644 index 0000000000..e1de72a910 --- /dev/null +++ b/ssl/quic/quic_thread_assist.c @@ -0,0 +1,157 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "quic_local.h" +#include "internal/time.h" +#include "internal/thread.h" +#include "internal/thread_arch.h" +#include "internal/quic_thread_assist.h" + +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + +/* Main loop for the QUIC assist thread. */ +static unsigned int assist_thread_main(void *arg) +{ + QUIC_THREAD_ASSIST *qta = arg; + CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch); + QUIC_REACTOR *rtor; + + ossl_crypto_mutex_lock(m); + + rtor = ossl_quic_channel_get_reactor(qta->ch); + + for (;;) { + OSSL_TIME deadline; + + if (qta->teardown) + break; + + deadline = ossl_quic_reactor_get_tick_deadline(rtor); + if (qta->now_cb != NULL + && !ossl_time_is_zero(deadline) + && !ossl_time_is_infinite(deadline)) { + /* + * ossl_crypto_condvar_wait_timeout needs to use real time for the + * deadline + */ + deadline = ossl_time_add(ossl_time_subtract(deadline, + qta->now_cb(qta->now_cb_arg)), + ossl_time_now()); + } + ossl_crypto_condvar_wait_timeout(qta->cv, m, deadline); + + /* + * We have now been woken up. This can be for one of the following + * reasons: + * + * - We have been asked to teardown (qta->teardown is set); + * - The tick deadline has passed. + * - The tick deadline has changed. + * + * For robustness, this loop also handles spurious wakeups correctly + * (which does not require any extra code). + */ + if (qta->teardown) + break; + + ossl_quic_reactor_tick(rtor, QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY); + } + + ossl_crypto_mutex_unlock(m); + return 1; +} + +int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) +{ + CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch); + + if (mutex == NULL) + return 0; + + qta->ch = ch; + qta->teardown = 0; + qta->joined = 0; + qta->now_cb = now_cb; + qta->now_cb_arg = now_cb_arg; + + qta->cv = ossl_crypto_condvar_new(); + if (qta->cv == NULL) + return 0; + + qta->t = ossl_crypto_thread_native_start(assist_thread_main, + qta, /*joinable=*/1); + if (qta->t == NULL) { + ossl_crypto_condvar_free(qta->cv); + return 0; + } + + return 1; +} + +int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta) +{ + if (!qta->teardown) { + qta->teardown = 1; + ossl_crypto_condvar_signal(qta->cv); + } + + return 1; +} + +int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta) +{ + CRYPTO_THREAD_RETVAL rv; + CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch); + + if (qta->joined) + return 1; + + if (!ossl_quic_thread_assist_stop_async(qta)) + return 0; + + ossl_crypto_mutex_unlock(m); + + if (!ossl_crypto_thread_native_join(qta->t, &rv)) { + ossl_crypto_mutex_lock(m); + return 0; + } + + qta->joined = 1; + + ossl_crypto_mutex_lock(m); + return 1; +} + +int ossl_quic_thread_assist_cleanup(QUIC_THREAD_ASSIST *qta) +{ + if (!ossl_assert(qta->joined)) + return 0; + + ossl_crypto_condvar_free(&qta->cv); + ossl_crypto_thread_native_clean(qta->t); + + qta->ch = NULL; + qta->t = NULL; + return 1; +} + +int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta) +{ + if (qta->teardown) + return 0; + + ossl_crypto_condvar_signal(qta->cv); + return 1; +} + +#endif diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c new file mode 100644 index 0000000000..25687db2fb --- /dev/null +++ b/ssl/quic/quic_tls.c @@ -0,0 +1,879 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include +#include "internal/recordmethod.h" +#include "internal/quic_tls.h" +#include "../ssl_local.h" +#include "internal/quic_error.h" + +#define QUIC_TLS_FATAL(rl, ad, err) \ + do { \ + if ((rl) != NULL) (rl)->alert = (ad); \ + ERR_raise(ERR_LIB_SSL, (err)); \ + if ((rl) != NULL) (rl)->qtls->inerror = 1; \ + } while(0) + +struct quic_tls_st { + QUIC_TLS_ARGS args; + + /* + * Transport parameters which client should send. Buffer lifetime must + * exceed the lifetime of the QUIC_TLS object. + */ + const unsigned char *local_transport_params; + size_t local_transport_params_len; + + ERR_STATE *error_state; + + /* + * QUIC error code (usually in the TLS Alert-mapped CRYPTO_ERR range). Valid + * only if inerror is 1. + */ + uint64_t error_code; + + /* + * Error message with static storage duration. Valid only if inerror is 1. + * Should be suitable for encapsulation in a CONNECTION_CLOSE frame. + */ + const char *error_msg; + + /* Whether our SSL object for TLS has been configured for use in QUIC */ + unsigned int configured : 1; + + /* Set if we have hit any error state */ + unsigned int inerror : 1; + + /* Set if the handshake has completed */ + unsigned int complete : 1; +}; + +struct ossl_record_layer_st { + QUIC_TLS *qtls; + + /* Protection level */ + int level; + + /* Only used for retry flags */ + BIO *dummybio; + + /* Number of bytes written so far if we are part way through a write */ + size_t written; + + /* If we are part way through a write, a copy of the template */ + OSSL_RECORD_TEMPLATE template; + + /* + * If we hit an error, what alert code should be used + */ + int alert; + + /* Amount of crypto stream data we read in the last call to quic_read_record */ + size_t recread; + + /* Amount of crypto stream data read but not yet released */ + size_t recunreleased; + + /* Callbacks */ + OSSL_FUNC_rlayer_msg_callback_fn *msg_callback; + void *cbarg; +}; + +static int quic_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio); +static int quic_free(OSSL_RECORD_LAYER *r); + +static int +quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, uint16_t epoch, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, unsigned char *iv, + size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, + const EVP_MD *kdfdigest, BIO *prev, BIO *transport, + BIO *next, BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, + OSSL_RECORD_LAYER **retrl) +{ + OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl)); + uint32_t enc_level; + int qdir; + uint32_t suite_id = 0; + + if (rl == NULL) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + rl->qtls = (QUIC_TLS *)rlarg; + rl->level = level; + if (!quic_set1_bio(rl, transport)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + rl->cbarg = cbarg; + *retrl = rl; + + if (fns != NULL) { + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + break; + case OSSL_FUNC_RLAYER_MSG_CALLBACK: + rl->msg_callback = OSSL_FUNC_rlayer_msg_callback(fns); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + } + + switch (level) { + case OSSL_RECORD_PROTECTION_LEVEL_NONE: + return 1; + + case OSSL_RECORD_PROTECTION_LEVEL_EARLY: + enc_level = QUIC_ENC_LEVEL_0RTT; + break; + + case OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE: + enc_level = QUIC_ENC_LEVEL_HANDSHAKE; + break; + + case OSSL_RECORD_PROTECTION_LEVEL_APPLICATION: + enc_level = QUIC_ENC_LEVEL_1RTT; + break; + + default: + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (direction == OSSL_RECORD_DIRECTION_READ) + qdir = 0; + else + qdir = 1; + + if (EVP_CIPHER_is_a(ciph, "AES-128-GCM")) { + suite_id = QRL_SUITE_AES128GCM; + } else if (EVP_CIPHER_is_a(ciph, "AES-256-GCM")) { + suite_id = QRL_SUITE_AES256GCM; + } else if (EVP_CIPHER_is_a(ciph, "CHACHA20-POLY1305")) { + suite_id = QRL_SUITE_CHACHA20POLY1305; + } else { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, SSL_R_UNKNOWN_CIPHER_TYPE); + goto err; + } + + /* We pass a ref to the md in a successful yield_secret_cb call */ + /* TODO(QUIC FUTURE): This cast is horrible. We should try and remove it */ + if (!EVP_MD_up_ref((EVP_MD *)kdfdigest)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!rl->qtls->args.yield_secret_cb(enc_level, qdir, suite_id, + (EVP_MD *)kdfdigest, secret, secretlen, + rl->qtls->args.yield_secret_cb_arg)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_MD_free((EVP_MD *)kdfdigest); + goto err; + } + + return 1; + err: + *retrl = NULL; + quic_free(rl); + return 0; +} + +static int quic_free(OSSL_RECORD_LAYER *rl) +{ + if (rl == NULL) + return 1; + + BIO_free(rl->dummybio); + OPENSSL_free(rl); + return 1; +} + +static int quic_unprocessed_read_pending(OSSL_RECORD_LAYER *rl) +{ + /* + * Read ahead isn't really a thing for QUIC so we never have unprocessed + * data pending + */ + return 0; +} + +static int quic_processed_read_pending(OSSL_RECORD_LAYER *rl) +{ + /* + * This is currently only ever used by: + * - SSL_has_pending() + * - to check whether we have more records that we want to supply to the + * upper layers + * + * We only ever supply 1 record at a time to the upper layers, and + * SSL_has_pending() will go via the QUIC method not the TLS method so that + * use case doesn't apply here. + * Therefore we can ignore this for now and always return 0. We might + * eventually want to change this to check in the receive buffers to see if + * we have any more data pending. + */ + return 0; +} + +static size_t quic_get_max_records(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, + size_t maxfrag, size_t *preffrag) +{ + return 1; +} + +static int quic_write_records(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *template, + size_t numtempl) +{ + size_t consumed; + unsigned char alert; + + if (!ossl_assert(numtempl == 1)) { + /* How could this be? quic_get_max_records() always returns 1 */ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + BIO_clear_retry_flags(rl->dummybio); + + if (rl->msg_callback != NULL) { + unsigned char dummyrec[SSL3_RT_HEADER_LENGTH]; + + /* + * For the purposes of the callback we "pretend" to be normal TLS, + * and manufacture a dummy record header + */ + dummyrec[0] = (rl->level == OSSL_RECORD_PROTECTION_LEVEL_NONE) + ? template->type + : SSL3_RT_APPLICATION_DATA; + dummyrec[1] = (unsigned char)((template->version >> 8) & 0xff); + dummyrec[2] = (unsigned char)(template->version & 0xff); + /* + * We assume that buflen is always <= UINT16_MAX. Since this is + * generated by libssl itself we actually expect it to never + * exceed SSL3_RT_MAX_PLAIN_LENGTH - so it should be a safe + * assumption + */ + dummyrec[3] = (unsigned char)((template->buflen >> 8) & 0xff); + dummyrec[4] = (unsigned char)(template->buflen & 0xff); + + rl->msg_callback(1, TLS1_3_VERSION, SSL3_RT_HEADER, dummyrec, + SSL3_RT_HEADER_LENGTH, rl->cbarg); + + if (rl->level != OSSL_RECORD_PROTECTION_LEVEL_NONE) { + rl->msg_callback(1, TLS1_3_VERSION, SSL3_RT_INNER_CONTENT_TYPE, + &template->type, 1, rl->cbarg); + } + } + + switch (template->type) { + case SSL3_RT_ALERT: + if (template->buflen != 2) { + /* + * We assume that libssl always sends both bytes of an alert to + * us in one go, and never fragments it. If we ever get more + * or less bytes than exactly 2 then this is very unexpected. + */ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_VALUE); + return OSSL_RECORD_RETURN_FATAL; + } + /* + * Byte 0 is the alert level (we ignore it) and byte 1 is the alert + * description that we are actually interested in. + */ + alert = template->buf[1]; + + if (!rl->qtls->args.alert_cb(rl->qtls->args.alert_cb_arg, alert)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + break; + + case SSL3_RT_HANDSHAKE: + /* + * We expect this to only fail on some fatal error (e.g. malloc + * failure) + */ + if (!rl->qtls->args.crypto_send_cb(template->buf + rl->written, + template->buflen - rl->written, + &consumed, + rl->qtls->args.crypto_send_cb_arg)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + /* + * We might have written less than we wanted to if we have filled the + * send stream buffer. + */ + if (consumed + rl->written != template->buflen) { + if (!ossl_assert(consumed + rl->written < template->buflen)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + /* + * We've not written everything we wanted to. Take a copy of the + * template, remember how much we wrote so far and signal a retry. + * The buffer supplied in the template is guaranteed to be the same + * on a retry for handshake data + */ + rl->written += consumed; + rl->template = *template; + BIO_set_retry_write(rl->dummybio); + + return OSSL_RECORD_RETURN_RETRY; + } + rl->written = 0; + break; + + default: + /* Anything else is unexpected and an error */ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int quic_retry_write_records(OSSL_RECORD_LAYER *rl) +{ + return quic_write_records(rl, &rl->template, 1); +} + +static int quic_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, + int *rversion, uint8_t *type, const unsigned char **data, + size_t *datalen, uint16_t *epoch, + unsigned char *seq_num) +{ + if (rl->recread != 0 || rl->recunreleased != 0) + return OSSL_RECORD_RETURN_FATAL; + + BIO_clear_retry_flags(rl->dummybio); + + if (!rl->qtls->args.crypto_recv_rcd_cb(data, datalen, + rl->qtls->args.crypto_recv_rcd_cb_arg)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if (*datalen == 0) { + BIO_set_retry_read(rl->dummybio); + return OSSL_RECORD_RETURN_RETRY; + } + + *rechandle = rl; + *rversion = TLS1_3_VERSION; + *type = SSL3_RT_HANDSHAKE; + rl->recread = rl->recunreleased = *datalen; + /* epoch/seq_num are not relevant for TLS */ + + if (rl->msg_callback != NULL) { + unsigned char dummyrec[SSL3_RT_HEADER_LENGTH]; + + /* + * For the purposes of the callback we "pretend" to be normal TLS, + * and manufacture a dummy record header + */ + dummyrec[0] = (rl->level == OSSL_RECORD_PROTECTION_LEVEL_NONE) + ? SSL3_RT_HANDSHAKE + : SSL3_RT_APPLICATION_DATA; + dummyrec[1] = (unsigned char)((TLS1_2_VERSION >> 8) & 0xff); + dummyrec[2] = (unsigned char)(TLS1_2_VERSION & 0xff); + /* + * *datalen will always fit into 2 bytes because our original buffer + * size is less than that. + */ + dummyrec[3] = (unsigned char)((*datalen >> 8) & 0xff); + dummyrec[4] = (unsigned char)(*datalen & 0xff); + + rl->msg_callback(0, TLS1_3_VERSION, SSL3_RT_HEADER, dummyrec, + SSL3_RT_HEADER_LENGTH, rl->cbarg); + rl->msg_callback(0, TLS1_3_VERSION, SSL3_RT_INNER_CONTENT_TYPE, type, 1, + rl->cbarg); + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int quic_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, + size_t length) +{ + if (!ossl_assert(rl->recread > 0) + || !ossl_assert(rl->recunreleased <= rl->recread) + || !ossl_assert(rl == rechandle) + || !ossl_assert(length <= rl->recunreleased)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + rl->recunreleased -= length; + + if (rl->recunreleased > 0) + return OSSL_RECORD_RETURN_SUCCESS; + + if (!rl->qtls->args.crypto_release_rcd_cb(rl->recread, + rl->qtls->args.crypto_release_rcd_cb_arg)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + rl->recread = 0; + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int quic_get_alert_code(OSSL_RECORD_LAYER *rl) +{ + return rl->alert; +} + +static int quic_set_protocol_version(OSSL_RECORD_LAYER *rl, int version) +{ + /* We only support TLSv1.3, so its bad if we negotiate anything else */ + if (!ossl_assert(version == TLS1_3_VERSION)) { + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +static void quic_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow) +{ + /* We don't care */ +} + +static void quic_set_first_handshake(OSSL_RECORD_LAYER *rl, int first) +{ + /* We don't care */ +} + +static void quic_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines) +{ + /* We don't care */ +} + +static void quic_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr, + const char **longstr) +{ + /* + * According to the docs, valid read state strings are: "RH"/"read header", + * "RB"/"read body", and "unknown"/"unknown". We don't read records in quite + * that way, so we report every "normal" state as "read header". In the + * event of error then we report "unknown". + */ + + if (rl->qtls->inerror) { + if (shortstr != NULL) + *shortstr = "unknown"; + if (longstr != NULL) + *longstr = "unknown"; + } else { + if (shortstr != NULL) + *shortstr = "RH"; + if (longstr != NULL) + *longstr = "read header"; + } +} + +static int quic_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options) +{ + /* + * We don't support any options yet - but we might do at some point so + * this could be useful. + */ + return 1; +} + +static const COMP_METHOD *quic_get_compression(OSSL_RECORD_LAYER *rl) +{ + /* We only support TLSv1.3 which doesn't have compression */ + return NULL; +} + +static void quic_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len) +{ + /* This really doesn't make any sense for QUIC. Ignore it */ +} + +static int quic_alloc_buffers(OSSL_RECORD_LAYER *rl) +{ + /* + * This is a hint only. We don't support it (yet), so just ignore the + * request + */ + return 1; +} + +static int quic_free_buffers(OSSL_RECORD_LAYER *rl) +{ + /* + * This is a hint only. We don't support it (yet), so just ignore the + * request + */ + return 1; +} + +static int quic_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio) +{ + if (bio != NULL && !BIO_up_ref(bio)) + return 0; + BIO_free(rl->dummybio); + rl->dummybio = bio; + + return 1; +} + +/* + * Never called functions + * + * Due to the way we are configured and used we never expect any of the next set + * of functions to be called. Therefore we set them to always fail. + */ + +static size_t quic_app_data_pending(OSSL_RECORD_LAYER *rl) +{ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (size_t)ossl_assert(0); +} + +static size_t quic_get_max_record_overhead(OSSL_RECORD_LAYER *rl) +{ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (size_t)ossl_assert(0); +} + +static int quic_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) +{ + QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return ossl_assert(0); +} + +/* End of never called functions */ + +static const OSSL_RECORD_METHOD quic_tls_record_method = { + quic_new_record_layer, + quic_free, + quic_unprocessed_read_pending, + quic_processed_read_pending, + quic_app_data_pending, /* Never called */ + quic_get_max_records, + quic_write_records, + quic_retry_write_records, + quic_read_record, + quic_release_record, + quic_get_alert_code, + quic_set1_bio, + quic_set_protocol_version, + quic_set_plain_alerts, + quic_set_first_handshake, + quic_set_max_pipelines, + NULL, /* set_in_init: Optional - we don't need it */ + quic_get_state, + quic_set_options, + quic_get_compression, + quic_set_max_frag_len, + quic_get_max_record_overhead, /* Never called */ + quic_increment_sequence_ctr, /* Never called */ + quic_alloc_buffers, + quic_free_buffers +}; + +static int add_transport_params_cb(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, size_t *outlen, + X509 *x, size_t chainidx, int *al, + void *add_arg) +{ + QUIC_TLS *qtls = add_arg; + + *out = qtls->local_transport_params; + *outlen = qtls->local_transport_params_len; + return 1; +} + +static void free_transport_params_cb(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *out, + void *add_arg) +{ +} + +static int parse_transport_params_cb(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *in, + size_t inlen, X509 *x, + size_t chainidx, + int *al, void *parse_arg) +{ + QUIC_TLS *qtls = parse_arg; + + return qtls->args.got_transport_params_cb(in, inlen, + qtls->args.got_transport_params_cb_arg); +} + +QUIC_TLS *ossl_quic_tls_new(const QUIC_TLS_ARGS *args) +{ + QUIC_TLS *qtls; + + if (args->crypto_send_cb == NULL + || args->crypto_recv_rcd_cb == NULL + || args->crypto_release_rcd_cb == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + qtls = OPENSSL_zalloc(sizeof(*qtls)); + if (qtls == NULL) + return NULL; + + if ((qtls->error_state = OSSL_ERR_STATE_new()) == NULL) { + OPENSSL_free(qtls); + return NULL; + } + + qtls->args = *args; + return qtls; +} + +void ossl_quic_tls_free(QUIC_TLS *qtls) +{ + if (qtls == NULL) + return; + OSSL_ERR_STATE_free(qtls->error_state); + OPENSSL_free(qtls); +} + +static int raise_error(QUIC_TLS *qtls, uint64_t error_code, + const char *error_msg, + const char *src_file, + int src_line, + const char *src_func) +{ + /* + * When QTLS fails, add a "cover letter" error with information, potentially + * with any underlying libssl errors underneath it (but our cover error may + * be the only error in some cases). Then capture this into an ERR_STATE so + * we can report it later if need be when the QUIC_CHANNEL asks for it. + */ + ERR_new(); + ERR_set_debug(src_file, src_line, src_func); + ERR_set_error(ERR_LIB_SSL, SSL_R_QUIC_HANDSHAKE_LAYER_ERROR, + "handshake layer error, error code %llu (0x%llx) (\"%s\")", + error_code, error_code, error_msg); + OSSL_ERR_STATE_save_to_mark(qtls->error_state); + + /* + * We record the error information reported via the QUIC protocol + * separately. + */ + qtls->error_code = error_code; + qtls->error_msg = error_msg; + qtls->inerror = 1; + + ERR_pop_to_mark(); + return 0; +} + +#define RAISE_ERROR(qtls, error_code, error_msg) \ + raise_error((qtls), (error_code), (error_msg), \ + OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC) + +#define RAISE_INTERNAL_ERROR(qtls) \ + RAISE_ERROR((qtls), QUIC_ERR_INTERNAL_ERROR, "internal error") + +int ossl_quic_tls_tick(QUIC_TLS *qtls) +{ + int ret, err; + const unsigned char *alpn; + unsigned int alpnlen; + + if (qtls->inerror) + return 0; + + /* + * SSL_get_error does not truly know what the cause of an SSL_read failure + * is and to some extent guesses based on contextual information. In + * particular, if there is _any_ ERR on the error stack, SSL_ERROR_SSL or + * SSL_ERROR_SYSCALL will be returned no matter what and there is no + * possibility of SSL_ERROR_WANT_READ/WRITE being returned, even if that was + * the actual cause of the SSL_read() failure. + * + * This means that ordinarily, the below code might not work right if the + * application has any ERR on the error stack. In order to make this code + * perform correctly regardless of prior ERR state, we use a variant of + * SSL_get_error() which ignores the error stack. However, some ERRs are + * raised by SSL_read() and actually indicate that something has gone wrong + * during the call to SSL_read(). We therefore adopt a strategy of marking + * the ERR stack and seeing if any errors get appended during the call to + * SSL_read(). If they are, we assume SSL_read() has raised an error and + * that we should use normal SSL_get_error() handling. + * + * NOTE: Ensure all escape paths from this function call + * ERR_clear_to_mark(). The RAISE macros handle this in failure cases. + */ + ERR_set_mark(); + + if (!qtls->configured) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc); + BIO *nullbio; + + /* + * No matter how the user has configured us, there are certain + * requirements for QUIC-TLS that we enforce + */ + + /* ALPN is a requirement for QUIC and must be set */ + if (qtls->args.is_server) { + if (sctx->ext.alpn_select_cb == NULL) + return RAISE_INTERNAL_ERROR(qtls); + } else { + if (sc->ext.alpn == NULL || sc->ext.alpn_len == 0) + return RAISE_ERROR(qtls, QUIC_ERR_CRYPTO_NO_APP_PROTO, + "ALPN must be configured when using QUIC"); + } + if (!SSL_set_min_proto_version(qtls->args.s, TLS1_3_VERSION)) + return RAISE_INTERNAL_ERROR(qtls); + + SSL_clear_options(qtls->args.s, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); + ossl_ssl_set_custom_record_layer(sc, &quic_tls_record_method, qtls); + + if (!ossl_tls_add_custom_ext_intern(NULL, &sc->cert->custext, + qtls->args.is_server ? ENDPOINT_SERVER + : ENDPOINT_CLIENT, + TLSEXT_TYPE_quic_transport_parameters, + SSL_EXT_TLS1_3_ONLY + | SSL_EXT_CLIENT_HELLO + | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, + add_transport_params_cb, + free_transport_params_cb, qtls, + parse_transport_params_cb, qtls)) + return RAISE_INTERNAL_ERROR(qtls); + + nullbio = BIO_new(BIO_s_null()); + if (nullbio == NULL) + return RAISE_INTERNAL_ERROR(qtls); + + /* + * Our custom record layer doesn't use the BIO - but libssl generally + * expects one to be present. + */ + SSL_set_bio(qtls->args.s, nullbio, nullbio); + + if (qtls->args.is_server) + SSL_set_accept_state(qtls->args.s); + else + SSL_set_connect_state(qtls->args.s); + + qtls->configured = 1; + } + + if (qtls->complete) + /* + * There should never be app data to read, but calling SSL_read() will + * ensure any post-handshake messages are processed. + */ + ret = SSL_read(qtls->args.s, NULL, 0); + else + ret = SSL_do_handshake(qtls->args.s); + + if (ret <= 0) { + err = ossl_ssl_get_error(qtls->args.s, ret, + /*check_err=*/ERR_count_to_mark() > 0); + + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CLIENT_HELLO_CB: + case SSL_ERROR_WANT_X509_LOOKUP: + case SSL_ERROR_WANT_RETRY_VERIFY: + ERR_pop_to_mark(); + return 1; + + default: + return RAISE_INTERNAL_ERROR(qtls); + } + } + + if (!qtls->complete) { + /* Validate that we have ALPN */ + SSL_get0_alpn_selected(qtls->args.s, &alpn, &alpnlen); + if (alpn == NULL || alpnlen == 0) + return RAISE_ERROR(qtls, QUIC_ERR_CRYPTO_NO_APP_PROTO, + "no application protocol negotiated"); + + qtls->complete = 1; + ERR_pop_to_mark(); + return qtls->args.handshake_complete_cb(qtls->args.handshake_complete_cb_arg); + } + + ERR_pop_to_mark(); + return 1; +} + +int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls, + const unsigned char *transport_params, + size_t transport_params_len) +{ + qtls->local_transport_params = transport_params; + qtls->local_transport_params_len = transport_params_len; + return 1; +} + +int ossl_quic_tls_get_error(QUIC_TLS *qtls, + uint64_t *error_code, + const char **error_msg, + ERR_STATE **error_state) +{ + if (qtls->inerror) { + *error_code = qtls->error_code; + *error_msg = qtls->error_msg; + *error_state = qtls->error_state; + } + + return qtls->inerror; +} + +/* + * Returns true if the last handshake record message we processed was a + * CertificateRequest + */ +int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); + + return sc->s3.tmp.message_type == SSL3_MT_CERTIFICATE_REQUEST; +} + +/* + * Returns true if the last session associated with the connection has an + * invalid max_early_data value for QUIC. + */ +int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls) +{ + uint32_t max_early_data = SSL_get0_session(qtls->args.s)->ext.max_early_data; + + /* + * If max_early_data was present we always ensure a non-zero value is + * stored in the session for QUIC. Therefore if max_early_data == 0 here + * we can be confident that it was not present in the NewSessionTicket + */ + return max_early_data != 0xffffffff && max_early_data != 0; +} diff --git a/ssl/quic/quic_trace.c b/ssl/quic/quic_trace.c new file mode 100644 index 0000000000..5a6d79bf4b --- /dev/null +++ b/ssl/quic/quic_trace.c @@ -0,0 +1,641 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "../ssl_local.h" +#include "internal/quic_wire_pkt.h" + +static const char *packet_type(int type) +{ + switch (type) { + case QUIC_PKT_TYPE_INITIAL: + return "Initial"; + + case QUIC_PKT_TYPE_0RTT: + return "0RTT"; + + case QUIC_PKT_TYPE_HANDSHAKE: + return "Handshake"; + + case QUIC_PKT_TYPE_RETRY: + return "Retry"; + + case QUIC_PKT_TYPE_1RTT: + return "1RTT"; + + case QUIC_PKT_TYPE_VERSION_NEG: + return "VersionNeg"; + + default: + return "Unknown"; + } +} + +/* Print a non-NUL terminated string to BIO */ +static void put_str(BIO *bio, char *str, size_t slen) +{ + size_t i; + + for (i = 0; i < slen; i++) + BIO_printf(bio, "%c", str[i]); +} + +static void put_data(BIO *bio, const uint8_t *data, size_t datalen) +{ + size_t i; + + for (i = 0; i < datalen; i++) + BIO_printf(bio, "%02x", data[i]); +} + +static void put_conn_id(BIO *bio, QUIC_CONN_ID *id) +{ + if (id->id_len == 0) { + BIO_puts(bio, ""); + return; + } + + BIO_puts(bio, "0x"); + put_data(bio, id->id, id->id_len); +} + +static void put_token(BIO *bio, const uint8_t *token, size_t token_len) +{ + if (token_len == 0) + BIO_puts(bio, ""); + else + put_data(bio, token, token_len); +} + +static int frame_ack(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_ACK ack; + OSSL_QUIC_ACK_RANGE *ack_ranges = NULL; + uint64_t total_ranges = 0; + uint64_t i; + + if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges) + /* In case sizeof(uint64_t) > sizeof(size_t) */ + || total_ranges > SIZE_MAX / sizeof(ack_ranges[0]) + || (ack_ranges = OPENSSL_zalloc(sizeof(ack_ranges[0]) + * (size_t)total_ranges)) == NULL) + return 0; + + ack.ack_ranges = ack_ranges; + ack.num_ack_ranges = (size_t)total_ranges; + + /* Ack delay exponent is 0, so we can get the raw delay time below */ + if (!ossl_quic_wire_decode_frame_ack(pkt, 0, &ack, NULL)) + return 0; + + BIO_printf(bio, " Largest acked: %llu\n", + (unsigned long long)ack.ack_ranges[0].end); + BIO_printf(bio, " Ack delay (raw) %llu\n", + (unsigned long long)ossl_time2ticks(ack.delay_time)); + BIO_printf(bio, " Ack range count: %llu\n", + (unsigned long long)total_ranges - 1); + BIO_printf(bio, " First ack range: %llu\n", + (unsigned long long)(ack.ack_ranges[0].end + - ack.ack_ranges[0].start)); + for (i = 1; i < total_ranges; i++) { + BIO_printf(bio, " Gap: %llu\n", + (unsigned long long)(ack.ack_ranges[i - 1].start + - ack.ack_ranges[i].end - 2)); + BIO_printf(bio, " Ack range len: %llu\n", + (unsigned long long)(ack.ack_ranges[i].end + - ack.ack_ranges[i].start)); + } + + OPENSSL_free(ack_ranges); + return 1; +} + +static int frame_reset_stream(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_RESET_STREAM frame_data; + + if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data)) + return 0; + + BIO_printf(bio, " Stream id: %llu\n", + (unsigned long long)frame_data.stream_id); + BIO_printf(bio, " App Protocol Error Code: %llu\n", + (unsigned long long)frame_data.app_error_code); + BIO_printf(bio, " Final size: %llu\n", + (unsigned long long)frame_data.final_size); + + return 1; +} + +static int frame_stop_sending(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_STOP_SENDING frame_data; + + if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data)) + return 0; + + BIO_printf(bio, " Stream id: %llu\n", + (unsigned long long)frame_data.stream_id); + BIO_printf(bio, " App Protocol Error Code: %llu\n", + (unsigned long long)frame_data.app_error_code); + + return 1; +} + +static int frame_crypto(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_CRYPTO frame_data; + + if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &frame_data)) + return 0; + + BIO_printf(bio, " Offset: %llu\n", (unsigned long long)frame_data.offset); + BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len); + + return 1; +} + +static int frame_new_token(BIO *bio, PACKET *pkt) +{ + const uint8_t *token; + size_t token_len; + + if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) + return 0; + + BIO_puts(bio, " Token: "); + put_token(bio, token, token_len); + BIO_puts(bio, "\n"); + + return 1; +} + +static int frame_stream(BIO *bio, PACKET *pkt, uint64_t frame_type) +{ + + OSSL_QUIC_FRAME_STREAM frame_data; + + BIO_puts(bio, "Stream"); + switch(frame_type) { + case OSSL_QUIC_FRAME_TYPE_STREAM: + BIO_puts(bio, "\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: + BIO_puts(bio, " (Fin)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: + BIO_puts(bio, " (Len)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: + BIO_puts(bio, " (Len, Fin)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: + BIO_puts(bio, " (Off)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: + BIO_puts(bio, " (Off, Fin)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: + BIO_puts(bio, " (Off, Len)\n"); + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: + BIO_puts(bio, " (Off, Len, Fin)\n"); + break; + + default: + return 0; + } + + if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &frame_data)) + return 0; + + BIO_printf(bio, " Stream id: %llu\n", + (unsigned long long)frame_data.stream_id); + BIO_printf(bio, " Offset: %llu\n", + (unsigned long long)frame_data.offset); + /* + * It would be nice to find a way of passing the implicit length through + * to the msg_callback. But this is not currently possible. + */ + if (frame_data.has_explicit_len) + BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len); + else + BIO_puts(bio, " Len: \n"); + + return 1; +} + +static int frame_max_data(BIO *bio, PACKET *pkt) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data)) + return 0; + + BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); + + return 1; +} + +static int frame_max_stream_data(BIO *bio, PACKET *pkt) +{ + uint64_t stream_id = 0; + uint64_t max_stream_data = 0; + + if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id, + &max_stream_data)) + return 0; + + BIO_printf(bio, " Max Stream Data: %llu\n", + (unsigned long long)max_stream_data); + + return 1; +} + +static int frame_max_streams(BIO *bio, PACKET *pkt) +{ + uint64_t max_streams = 0; + + if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams)) + return 0; + + BIO_printf(bio, " Max Streams: %llu\n", (unsigned long long)max_streams); + + return 1; +} + +static int frame_data_blocked(BIO *bio, PACKET *pkt) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data)) + return 0; + + BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); + + return 1; +} + +static int frame_stream_data_blocked(BIO *bio, PACKET *pkt) +{ + uint64_t stream_id = 0; + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id, + &max_data)) + return 0; + + BIO_printf(bio, " Stream id: %llu\n", (unsigned long long)stream_id); + BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); + + return 1; +} + +static int frame_streams_blocked(BIO *bio, PACKET *pkt) +{ + uint64_t max_data = 0; + + if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data)) + return 0; + + BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); + + return 1; +} + +static int frame_new_conn_id(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_NEW_CONN_ID frame_data; + + if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data)) + return 0; + + BIO_printf(bio, " Sequence Number: %llu\n", + (unsigned long long)frame_data.seq_num); + BIO_printf(bio, " Retire prior to: %llu\n", + (unsigned long long)frame_data.retire_prior_to); + BIO_puts(bio, " Connection id: "); + put_conn_id(bio, &frame_data.conn_id); + BIO_puts(bio, "\n Stateless Reset Token: "); + put_data(bio, frame_data.stateless_reset.token, + sizeof(frame_data.stateless_reset.token)); + BIO_puts(bio, "\n"); + + return 1; +} + +static int frame_retire_conn_id(BIO *bio, PACKET *pkt) +{ + uint64_t seq_num; + + if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) + return 0; + + BIO_printf(bio, " Sequence Number: %llu\n", (unsigned long long)seq_num); + + return 1; +} + +static int frame_path_challenge(BIO *bio, PACKET *pkt) +{ + uint64_t data = 0; + + if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &data)) + return 0; + + BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data); + + return 1; +} + +static int frame_path_response(BIO *bio, PACKET *pkt) +{ + uint64_t data = 0; + + if (!ossl_quic_wire_decode_frame_path_response(pkt, &data)) + return 0; + + BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data); + + return 1; +} + +static int frame_conn_closed(BIO *bio, PACKET *pkt) +{ + OSSL_QUIC_FRAME_CONN_CLOSE frame_data; + + if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) + return 0; + + BIO_printf(bio, " Error Code: %llu\n", + (unsigned long long)frame_data.error_code); + BIO_puts(bio, " Reason: "); + put_str(bio, frame_data.reason, frame_data.reason_len); + BIO_puts(bio, "\n"); + + return 1; +} + +static int trace_frame_data(BIO *bio, PACKET *pkt) +{ + uint64_t frame_type; + + if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, NULL)) + return 0; + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_PING: + BIO_puts(bio, "Ping\n"); + if (!ossl_quic_wire_decode_frame_ping(pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_PADDING: + BIO_puts(bio, "Padding\n"); + ossl_quic_wire_decode_padding(pkt); + break; + + case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + BIO_puts(bio, "Ack "); + if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) + BIO_puts(bio, " (with ECN)\n"); + else + BIO_puts(bio, " (without ECN)\n"); + if (!frame_ack(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + BIO_puts(bio, "Reset stream\n"); + if (!frame_reset_stream(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + BIO_puts(bio, "Stop sending\n"); + if (!frame_stop_sending(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_CRYPTO: + BIO_puts(bio, "Crypto\n"); + if (!frame_crypto(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + BIO_puts(bio, "New token\n"); + if (!frame_new_token(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM: + case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: + case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: + /* frame_stream() prints the frame type string */ + if (!frame_stream(bio, pkt, frame_type)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_MAX_DATA: + BIO_puts(bio, "Max data\n"); + if (!frame_max_data(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: + BIO_puts(bio, "Max stream data\n"); + if (!frame_max_stream_data(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + BIO_puts(bio, "Max streams "); + if (frame_type == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI) + BIO_puts(bio, " (Bidi)\n"); + else + BIO_puts(bio, " (Uni)\n"); + if (!frame_max_streams(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: + BIO_puts(bio, "Data blocked\n"); + if (!frame_data_blocked(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: + BIO_puts(bio, "Stream data blocked\n"); + if (!frame_stream_data_blocked(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI: + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: + BIO_puts(bio, "Streams blocked"); + if (frame_type == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI) + BIO_puts(bio, " (Bidi)\n"); + else + BIO_puts(bio, " (Uni)\n"); + if (!frame_streams_blocked(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + BIO_puts(bio, "New conn id\n"); + if (!frame_new_conn_id(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + BIO_puts(bio, "Retire conn id\n"); + if (!frame_retire_conn_id(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: + BIO_puts(bio, "Path challenge\n"); + if (!frame_path_challenge(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + BIO_puts(bio, "Path response\n"); + if (!frame_path_response(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: + BIO_puts(bio, "Connection close"); + if (frame_type == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP) + BIO_puts(bio, " (app)\n"); + else + BIO_puts(bio, " (transport)\n"); + if (!frame_conn_closed(bio, pkt)) + return 0; + break; + + case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: + BIO_puts(bio, "Handshake done\n"); + if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) + return 0; + break; + + default: + return 0; + } + + if (PACKET_remaining(pkt) != 0) + BIO_puts(bio, " \n"); + + return 1; +} + +int ossl_quic_trace(int write_p, int version, int content_type, + const void *buf, size_t msglen, SSL *ssl, void *arg) +{ + BIO *bio = arg; + PACKET pkt; + + switch (content_type) { + case SSL3_RT_QUIC_DATAGRAM: + BIO_puts(bio, write_p ? "Sent" : "Received"); + /* + * Unfortunately there is no way of receiving auxiliary information + * about the datagram through the msg_callback API such as the peer + * address + */ + BIO_printf(bio, " Datagram\n Length: %zu\n", msglen); + break; + + case SSL3_RT_QUIC_PACKET: + { + QUIC_PKT_HDR hdr; + size_t i; + + if (!PACKET_buf_init(&pkt, buf, msglen)) + return 0; + /* Decode the packet header */ + /* + * TODO(QUIC SERVER): We need to query the short connection id len + * here, e.g. via some API SSL_get_short_conn_id_len() + */ + if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 1, &hdr, NULL) != 1) + return 0; + + BIO_puts(bio, write_p ? "Sent" : "Received"); + BIO_puts(bio, " Packet\n"); + BIO_printf(bio, " Packet Type: %s\n", packet_type(hdr.type)); + if (hdr.type != QUIC_PKT_TYPE_1RTT) + BIO_printf(bio, " Version: 0x%08lx\n", + (unsigned long)hdr.version); + BIO_puts(bio, " Destination Conn Id: "); + put_conn_id(bio, &hdr.dst_conn_id); + BIO_puts(bio, "\n"); + if (hdr.type != QUIC_PKT_TYPE_1RTT) { + BIO_puts(bio, " Source Conn Id: "); + put_conn_id(bio, &hdr.src_conn_id); + BIO_puts(bio, "\n"); + } + BIO_printf(bio, " Payload length: %zu\n", hdr.len); + if (hdr.type == QUIC_PKT_TYPE_INITIAL) { + BIO_puts(bio, " Token: "); + put_token(bio, hdr.token, hdr.token_len); + BIO_puts(bio, "\n"); + } + if (hdr.type != QUIC_PKT_TYPE_VERSION_NEG + && hdr.type != QUIC_PKT_TYPE_RETRY) { + BIO_puts(bio, " Packet Number: 0x"); + /* Will always be at least 1 byte */ + for (i = 0; i < hdr.pn_len; i++) + BIO_printf(bio, "%02x", hdr.pn[i]); + BIO_puts(bio, "\n"); + } + break; + } + + case SSL3_RT_QUIC_FRAME_PADDING: + case SSL3_RT_QUIC_FRAME_FULL: + case SSL3_RT_QUIC_FRAME_HEADER: + { + BIO_puts(bio, write_p ? "Sent" : "Received"); + BIO_puts(bio, " Frame: "); + + if (!PACKET_buf_init(&pkt, buf, msglen)) + return 0; + if (!trace_frame_data(bio, &pkt)) { + BIO_puts(bio, " \n"); + return 0; + } + } + break; + + default: + /* Unrecognised content_type. We defer to SSL_trace */ + return 0; + } + + return 1; +} diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c new file mode 100644 index 0000000000..3fc51b4a77 --- /dev/null +++ b/ssl/quic/quic_tserver.c @@ -0,0 +1,566 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_tserver.h" +#include "internal/quic_channel.h" +#include "internal/quic_statm.h" +#include "internal/common.h" +#include "internal/time.h" +#include "quic_local.h" + +/* + * QUIC Test Server Module + * ======================= + */ +struct quic_tserver_st { + QUIC_TSERVER_ARGS args; + + /* Dummy SSL object for this QUIC connection for use by msg_callback */ + SSL *ssl; + + /* + * The QUIC channel providing the core QUIC connection implementation. + */ + QUIC_CHANNEL *ch; + + /* The mutex we give to the QUIC channel. */ + CRYPTO_MUTEX *mutex; + + /* SSL_CTX for creating the underlying TLS connection */ + SSL_CTX *ctx; + + /* SSL for the underlying TLS connection */ + SSL *tls; + + /* The current peer L4 address. AF_UNSPEC if we do not have a peer yet. */ + BIO_ADDR cur_peer_addr; + + /* Are we connected to a peer? */ + unsigned int connected : 1; +}; + +static int alpn_select_cb(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) +{ + QUIC_TSERVER *srv = arg; + static const unsigned char alpndeflt[] = { + 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' + }; + static const unsigned char *alpn; + size_t alpnlen; + + if (srv->args.alpn == NULL) { + alpn = alpndeflt; + alpnlen = sizeof(alpn); + } else { + alpn = srv->args.alpn; + alpnlen = srv->args.alpnlen; + } + + if (SSL_select_next_proto((unsigned char **)out, outlen, alpn, alpnlen, + in, inlen) != OPENSSL_NPN_NEGOTIATED) + return SSL_TLSEXT_ERR_ALERT_FATAL; + + return SSL_TLSEXT_ERR_OK; +} + +QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args, + const char *certfile, const char *keyfile) +{ + QUIC_TSERVER *srv = NULL; + QUIC_CHANNEL_ARGS ch_args = {0}; + QUIC_CONNECTION *qc = NULL; + + if (args->net_rbio == NULL || args->net_wbio == NULL) + goto err; + + if ((srv = OPENSSL_zalloc(sizeof(*srv))) == NULL) + goto err; + + srv->args = *args; + +#if defined(OPENSSL_THREADS) + if ((srv->mutex = ossl_crypto_mutex_new()) == NULL) + goto err; +#endif + + if (args->ctx != NULL) + srv->ctx = args->ctx; + else + srv->ctx = SSL_CTX_new_ex(srv->args.libctx, srv->args.propq, + TLS_method()); + if (srv->ctx == NULL) + goto err; + + if (certfile != NULL + && SSL_CTX_use_certificate_file(srv->ctx, certfile, SSL_FILETYPE_PEM) <= 0) + goto err; + + if (keyfile != NULL + && SSL_CTX_use_PrivateKey_file(srv->ctx, keyfile, SSL_FILETYPE_PEM) <= 0) + goto err; + + SSL_CTX_set_alpn_select_cb(srv->ctx, alpn_select_cb, srv); + + srv->tls = SSL_new(srv->ctx); + if (srv->tls == NULL) + goto err; + + ch_args.libctx = srv->args.libctx; + ch_args.propq = srv->args.propq; + ch_args.tls = srv->tls; + ch_args.mutex = srv->mutex; + ch_args.is_server = 1; + ch_args.now_cb = srv->args.now_cb; + ch_args.now_cb_arg = srv->args.now_cb_arg; + + if ((srv->ch = ossl_quic_channel_new(&ch_args)) == NULL) + goto err; + + if (!ossl_quic_channel_set_net_rbio(srv->ch, srv->args.net_rbio) + || !ossl_quic_channel_set_net_wbio(srv->ch, srv->args.net_wbio)) + goto err; + + qc = OPENSSL_zalloc(sizeof(*qc)); + if (qc == NULL) + goto err; + srv->ssl = (SSL *)qc; + qc->ch = srv->ch; + srv->ssl->type = SSL_TYPE_QUIC_CONNECTION; + + return srv; + +err: + if (srv != NULL) { + if (args->ctx == NULL) + SSL_CTX_free(srv->ctx); + SSL_free(srv->tls); + ossl_quic_channel_free(srv->ch); +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_free(&srv->mutex); +#endif + OPENSSL_free(qc); + } + + OPENSSL_free(srv); + return NULL; +} + +void ossl_quic_tserver_free(QUIC_TSERVER *srv) +{ + if (srv == NULL) + return; + + ossl_quic_channel_free(srv->ch); + BIO_free_all(srv->args.net_rbio); + BIO_free_all(srv->args.net_wbio); + OPENSSL_free(srv->ssl); + SSL_free(srv->tls); + SSL_CTX_free(srv->ctx); +#if defined(OPENSSL_THREADS) + ossl_crypto_mutex_free(&srv->mutex); +#endif + OPENSSL_free(srv); +} + +/* Set mutator callbacks for test framework support */ +int ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER *srv, + ossl_mutate_packet_cb mutatecb, + ossl_finish_mutate_cb finishmutatecb, + void *mutatearg) +{ + return ossl_quic_channel_set_mutator(srv->ch, mutatecb, finishmutatecb, + mutatearg); +} + +int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv, + ossl_statem_mutate_handshake_cb mutate_handshake_cb, + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, + void *mutatearg) +{ + return ossl_statem_set_mutator(ossl_quic_channel_get0_ssl(srv->ch), + mutate_handshake_cb, + finish_mutate_handshake_cb, + mutatearg); +} + +int ossl_quic_tserver_tick(QUIC_TSERVER *srv) +{ + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0); + + if (ossl_quic_channel_is_active(srv->ch)) + srv->connected = 1; + + return 1; +} + +int ossl_quic_tserver_is_connected(QUIC_TSERVER *srv) +{ + return ossl_quic_channel_is_active(srv->ch); +} + +/* Returns 1 if the server is in any terminating or terminated state */ +int ossl_quic_tserver_is_term_any(const QUIC_TSERVER *srv) +{ + return ossl_quic_channel_is_term_any(srv->ch); +} + +const QUIC_TERMINATE_CAUSE * +ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER *srv) +{ + return ossl_quic_channel_get_terminate_cause(srv->ch); +} + +/* Returns 1 if the server is in a terminated state */ +int ossl_quic_tserver_is_terminated(const QUIC_TSERVER *srv) +{ + return ossl_quic_channel_is_terminated(srv->ch); +} + +int ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER *srv) +{ + return ossl_quic_channel_is_handshake_confirmed(srv->ch); +} + +int ossl_quic_tserver_read(QUIC_TSERVER *srv, + uint64_t stream_id, + unsigned char *buf, + size_t buf_len, + size_t *bytes_read) +{ + int is_fin = 0; + QUIC_STREAM *qs; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL) { + int is_client_init + = ((stream_id & QUIC_STREAM_INITIATOR_MASK) + == QUIC_STREAM_INITIATOR_CLIENT); + + /* + * A client-initiated stream might spontaneously come into existence, so + * allow trying to read on a client-initiated stream before it exists, + * assuming the connection is still active. + * Otherwise, fail. + */ + if (!is_client_init || !ossl_quic_channel_is_active(srv->ch)) + return 0; + + *bytes_read = 0; + return 1; + } + + if (qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ + || !ossl_quic_stream_has_recv_buffer(qs)) + return 0; + + if (!ossl_quic_rstream_read(qs->rstream, buf, buf_len, + bytes_read, &is_fin)) + return 0; + + if (*bytes_read > 0) { + /* + * We have read at least one byte from the stream. Inform stream-level + * RXFC of the retirement of controlled bytes. Update the active stream + * status (the RXFC may now want to emit a frame granting more credit to + * the peer). + */ + OSSL_RTT_INFO rtt_info; + + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(srv->ch), &rtt_info); + + if (!ossl_quic_rxfc_on_retire(&qs->rxfc, *bytes_read, + rtt_info.smoothed_rtt)) + return 0; + } + + if (is_fin) + ossl_quic_stream_map_notify_totally_read(ossl_quic_channel_get_qsm(srv->ch), + qs); + + if (*bytes_read > 0) + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs); + + return 1; +} + +int ossl_quic_tserver_has_read_ended(QUIC_TSERVER *srv, uint64_t stream_id) +{ + QUIC_STREAM *qs; + unsigned char buf[1]; + size_t bytes_read = 0; + int is_fin = 0; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + + if (qs == NULL) + return 0; + + if (qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ) + return 1; + + if (!ossl_quic_stream_has_recv_buffer(qs)) + return 0; + + /* + * If we do not have the DATA_READ, it is possible we should still return 1 + * if there is a lone FIN (but no more data) remaining to be retired from + * the RSTREAM, for example because ossl_quic_tserver_read() has not been + * called since the FIN was received. + */ + if (!ossl_quic_rstream_peek(qs->rstream, buf, sizeof(buf), + &bytes_read, &is_fin)) + return 0; + + if (is_fin && bytes_read == 0) { + /* If we have a FIN awaiting retirement and no data before it... */ + /* Let RSTREAM know we've consumed this FIN. */ + if (!ossl_quic_rstream_read(qs->rstream, buf, sizeof(buf), + &bytes_read, &is_fin)) + return 0; + + assert(is_fin && bytes_read == 0); + assert(qs->recv_state == QUIC_RSTREAM_STATE_DATA_RECVD); + + ossl_quic_stream_map_notify_totally_read(ossl_quic_channel_get_qsm(srv->ch), + qs); + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs); + return 1; + } + + return 0; +} + +int ossl_quic_tserver_write(QUIC_TSERVER *srv, + uint64_t stream_id, + const unsigned char *buf, + size_t buf_len, + size_t *bytes_written) +{ + QUIC_STREAM *qs; + + if (!ossl_quic_channel_is_active(srv->ch)) + return 0; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL || !ossl_quic_stream_has_send_buffer(qs)) + return 0; + + if (!ossl_quic_sstream_append(qs->sstream, + buf, buf_len, bytes_written)) + return 0; + + if (*bytes_written > 0) + /* + * We have appended at least one byte to the stream. Potentially mark + * the stream as active, depending on FC. + */ + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs); + + /* Try and send. */ + ossl_quic_tserver_tick(srv); + return 1; +} + +int ossl_quic_tserver_conclude(QUIC_TSERVER *srv, uint64_t stream_id) +{ + QUIC_STREAM *qs; + + if (!ossl_quic_channel_is_active(srv->ch)) + return 0; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL || !ossl_quic_stream_has_send_buffer(qs)) + return 0; + + if (!ossl_quic_sstream_get_final_size(qs->sstream, NULL)) { + ossl_quic_sstream_fin(qs->sstream); + ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs); + } + + ossl_quic_tserver_tick(srv); + return 1; +} + +int ossl_quic_tserver_stream_new(QUIC_TSERVER *srv, + int is_uni, + uint64_t *stream_id) +{ + QUIC_STREAM *qs; + + if (!ossl_quic_channel_is_active(srv->ch)) + return 0; + + if ((qs = ossl_quic_channel_new_stream_local(srv->ch, is_uni)) == NULL) + return 0; + + *stream_id = qs->id; + return 1; +} + +BIO *ossl_quic_tserver_get0_rbio(QUIC_TSERVER *srv) +{ + return srv->args.net_rbio; +} + +SSL_CTX *ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER *srv) +{ + return srv->ctx; +} + +int ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER *srv, + uint64_t stream_id, + uint64_t *app_error_code) +{ + QUIC_STREAM *qs; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL) + return 0; + + if (qs->peer_stop_sending && app_error_code != NULL) + *app_error_code = qs->peer_stop_sending_aec; + + return qs->peer_stop_sending; +} + +int ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER *srv, + uint64_t stream_id, + uint64_t *app_error_code) +{ + QUIC_STREAM *qs; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL) + return 0; + + if (ossl_quic_stream_recv_is_reset(qs) && app_error_code != NULL) + *app_error_code = qs->peer_reset_stream_aec; + + return ossl_quic_stream_recv_is_reset(qs); +} + +int ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER *srv, + const QUIC_CONN_ID *conn_id) +{ + /* Replace existing local connection ID in the QUIC_CHANNEL */ + return ossl_quic_channel_replace_local_cid(srv->ch, conn_id); +} + +uint64_t ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER *srv) +{ + QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(srv->ch); + QUIC_STREAM *qs = ossl_quic_stream_map_peek_accept_queue(qsm); + + if (qs == NULL) + return UINT64_MAX; + + ossl_quic_stream_map_remove_from_accept_queue(qsm, qs, ossl_time_zero()); + + return qs->id; +} + +int ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER *srv, + uint64_t stream_id) +{ + QUIC_STREAM *qs; + + qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch), + stream_id); + if (qs == NULL) + return 1; + + return ossl_quic_sstream_is_totally_acked(qs->sstream); +} + +int ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER *srv) +{ + return ossl_quic_reactor_net_read_desired( + ossl_quic_channel_get_reactor(srv->ch)); +} + +int ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER *srv) +{ + return ossl_quic_reactor_net_write_desired( + ossl_quic_channel_get_reactor(srv->ch)); +} + +OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv) +{ + return ossl_quic_reactor_get_tick_deadline( + ossl_quic_channel_get_reactor(srv->ch)); +} + +int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv, uint64_t app_error_code) +{ + ossl_quic_channel_local_close(srv->ch, app_error_code, NULL); + + /* TODO(QUIC SERVER): !SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH */ + + if (ossl_quic_channel_is_terminated(srv->ch)) + return 1; + + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0); + + return ossl_quic_channel_is_terminated(srv->ch); +} + +int ossl_quic_tserver_ping(QUIC_TSERVER *srv) +{ + if (ossl_quic_channel_is_terminated(srv->ch)) + return 0; + + if (!ossl_quic_channel_ping(srv->ch)) + return 0; + + ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0); + return 1; +} + +QUIC_CHANNEL *ossl_quic_tserver_get_channel(QUIC_TSERVER *srv) +{ + return srv->ch; +} + +void ossl_quic_tserver_set_msg_callback(QUIC_TSERVER *srv, + void (*f)(int write_p, int version, + int content_type, + const void *buf, size_t len, + SSL *ssl, void *arg), + void *arg) +{ + ossl_quic_channel_set_msg_callback(srv->ch, f, srv->ssl); + ossl_quic_channel_set_msg_callback_arg(srv->ch, arg); + SSL_set_msg_callback(srv->tls, f); + SSL_set_msg_callback_arg(srv->tls, arg); +} + +int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv) +{ + return SSL_new_session_ticket(srv->tls); +} + +int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv, + uint32_t max_early_data) +{ + return SSL_set_max_early_data(srv->tls, max_early_data); +} + +void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv, + SSL_psk_find_session_cb_func cb) +{ + SSL_set_psk_find_session_callback(srv->tls, cb); +} diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c new file mode 100644 index 0000000000..f26f1e81a1 --- /dev/null +++ b/ssl/quic/quic_txp.c @@ -0,0 +1,3134 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_txp.h" +#include "internal/quic_fifd.h" +#include "internal/quic_stream_map.h" +#include "internal/quic_error.h" +#include "internal/common.h" +#include + +#define MIN_CRYPTO_HDR_SIZE 3 + +#define MIN_FRAME_SIZE_HANDSHAKE_DONE 1 +#define MIN_FRAME_SIZE_MAX_DATA 2 +#define MIN_FRAME_SIZE_ACK 5 +#define MIN_FRAME_SIZE_CRYPTO (MIN_CRYPTO_HDR_SIZE + 1) +#define MIN_FRAME_SIZE_STREAM 3 /* minimum useful size (for non-FIN) */ +#define MIN_FRAME_SIZE_MAX_STREAMS_BIDI 2 +#define MIN_FRAME_SIZE_MAX_STREAMS_UNI 2 + +/* + * Packet Archetypes + * ================= + */ + +/* Generate normal packets containing most frame types, subject to EL. */ +#define TX_PACKETISER_ARCHETYPE_NORMAL 0 + +/* + * A probe packet is different in that: + * - It bypasses CC, but *is* counted as in flight for purposes of CC; + * - It must be ACK-eliciting. + */ +#define TX_PACKETISER_ARCHETYPE_PROBE 1 + +/* + * An ACK-only packet is different in that: + * - It bypasses CC, and is considered a 'non-inflight' packet; + * - It may not contain anything other than an ACK frame, not even padding. + */ +#define TX_PACKETISER_ARCHETYPE_ACK_ONLY 2 + +#define TX_PACKETISER_ARCHETYPE_NUM 3 + +struct ossl_quic_tx_packetiser_st { + OSSL_QUIC_TX_PACKETISER_ARGS args; + + /* + * Opaque initial token blob provided by caller. TXP frees using the + * callback when it is no longer needed. + */ + const unsigned char *initial_token; + size_t initial_token_len; + ossl_quic_initial_token_free_fn *initial_token_free_cb; + void *initial_token_free_cb_arg; + + /* Subcomponents of the TXP that we own. */ + QUIC_FIFD fifd; /* QUIC Frame-in-Flight Dispatcher */ + + /* Internal state. */ + uint64_t next_pn[QUIC_PN_SPACE_NUM]; /* Next PN to use in given PN space. */ + OSSL_TIME last_tx_time; /* Last time a packet was generated, or 0. */ + + /* Internal state - frame (re)generation flags. */ + unsigned int want_handshake_done : 1; + unsigned int want_max_data : 1; + unsigned int want_max_streams_bidi : 1; + unsigned int want_max_streams_uni : 1; + + /* Internal state - frame (re)generation flags - per PN space. */ + unsigned int want_ack : QUIC_PN_SPACE_NUM; + unsigned int force_ack_eliciting : QUIC_PN_SPACE_NUM; + + /* + * Internal state - connection close terminal state. + * Once this is set, it is not unset unlike other want_ flags - we keep + * sending it in every packet. + */ + unsigned int want_conn_close : 1; + + /* Has the handshake been completed? */ + unsigned int handshake_complete : 1; + + OSSL_QUIC_FRAME_CONN_CLOSE conn_close_frame; + + /* + * Counts of the number of bytes received and sent while in the closing + * state. + */ + uint64_t closing_bytes_recv; + uint64_t closing_bytes_xmit; + + /* Internal state - packet assembly. */ + struct txp_el { + unsigned char *scratch; /* scratch buffer for packet assembly */ + size_t scratch_len; /* number of bytes allocated for scratch */ + OSSL_QTX_IOVEC *iovec; /* scratch iovec array for use with QTX */ + size_t alloc_iovec; /* size of iovec array */ + } el[QUIC_ENC_LEVEL_NUM]; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_ssl; + + /* Callbacks. */ + void (*ack_tx_cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg); + void *ack_tx_cb_arg; +}; + +/* + * The TX helper records state used while generating frames into packets. It + * enables serialization into the packet to be done "transactionally" where + * serialization of a frame can be rolled back if it fails midway (e.g. if it + * does not fit). + */ +struct tx_helper { + OSSL_QUIC_TX_PACKETISER *txp; + /* + * The Maximum Packet Payload Length in bytes. This is the amount of + * space we have to generate frames into. + */ + size_t max_ppl; + /* + * Number of bytes we have generated so far. + */ + size_t bytes_appended; + /* + * Number of scratch bytes in txp->scratch we have used so far. Some iovecs + * will reference this scratch buffer. When we need to use more of it (e.g. + * when we need to put frame headers somewhere), we append to the scratch + * buffer, resizing if necessary, and increase this accordingly. + */ + size_t scratch_bytes; + /* + * Bytes reserved in the MaxPPL budget. We keep this number of bytes spare + * until reserve_allowed is set to 1. Currently this is always at most 1, as + * a PING frame takes up one byte and this mechanism is only used to ensure + * we can encode a PING frame if we have been asked to ensure a packet is + * ACK-eliciting and we are unusure if we are going to add any other + * ACK-eliciting frames before we reach our MaxPPL budget. + */ + size_t reserve; + /* + * Number of iovecs we have currently appended. This is the number of + * entries valid in txp->iovec. + */ + size_t num_iovec; + /* The EL this TX helper is being used for. */ + uint32_t enc_level; + /* + * Whether we are allowed to make use of the reserve bytes in our MaxPPL + * budget. This is used to ensure we have room to append a PING frame later + * if we need to. Once we know we will not need to append a PING frame, this + * is set to 1. + */ + unsigned int reserve_allowed : 1; + /* + * Set to 1 if we have appended a STREAM frame with an implicit length. If + * this happens we should never append another frame after that frame as it + * cannot be validly encoded. This is just a safety check. + */ + unsigned int done_implicit : 1; + struct { + /* + * The fields in this structure are valid if active is set, which means + * that a serialization transaction is currently in progress. + */ + unsigned char *data; + WPACKET wpkt; + unsigned int active : 1; + } txn; +}; + +static void tx_helper_rollback(struct tx_helper *h); +static int txp_el_ensure_iovec(struct txp_el *el, size_t num); + +/* Initialises the TX helper. */ +static int tx_helper_init(struct tx_helper *h, OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level, size_t max_ppl, size_t reserve) +{ + if (reserve > max_ppl) + return 0; + + h->txp = txp; + h->enc_level = enc_level; + h->max_ppl = max_ppl; + h->reserve = reserve; + h->num_iovec = 0; + h->bytes_appended = 0; + h->scratch_bytes = 0; + h->reserve_allowed = 0; + h->done_implicit = 0; + h->txn.data = NULL; + h->txn.active = 0; + + if (max_ppl > h->txp->el[enc_level].scratch_len) { + unsigned char *scratch; + + scratch = OPENSSL_realloc(h->txp->el[enc_level].scratch, max_ppl); + if (scratch == NULL) + return 0; + + h->txp->el[enc_level].scratch = scratch; + h->txp->el[enc_level].scratch_len = max_ppl; + } + + return 1; +} + +static void tx_helper_cleanup(struct tx_helper *h) +{ + if (h->txn.active) + tx_helper_rollback(h); + + h->txp = NULL; +} + +static void tx_helper_unrestrict(struct tx_helper *h) +{ + h->reserve_allowed = 1; +} + +/* + * Append an extent of memory to the iovec list. The memory must remain + * allocated until we finish generating the packet and call the QTX. + * + * In general, the buffers passed to this function will be from one of two + * ranges: + * + * - Application data contained in stream buffers managed elsewhere + * in the QUIC stack; or + * + * - Control frame data appended into txp->scratch using tx_helper_begin and + * tx_helper_commit. + * + */ +static int tx_helper_append_iovec(struct tx_helper *h, + const unsigned char *buf, + size_t buf_len) +{ + struct txp_el *el = &h->txp->el[h->enc_level]; + + if (buf_len == 0) + return 1; + + if (!ossl_assert(!h->done_implicit)) + return 0; + + if (!txp_el_ensure_iovec(el, h->num_iovec + 1)) + return 0; + + el->iovec[h->num_iovec].buf = buf; + el->iovec[h->num_iovec].buf_len = buf_len; + + ++h->num_iovec; + h->bytes_appended += buf_len; + return 1; +} + +/* + * How many more bytes of space do we have left in our plaintext packet payload? + */ +static size_t tx_helper_get_space_left(struct tx_helper *h) +{ + return h->max_ppl + - (h->reserve_allowed ? 0 : h->reserve) - h->bytes_appended; +} + +/* + * Begin a control frame serialization transaction. This allows the + * serialization of the control frame to be backed out if it turns out it won't + * fit. Write the control frame to the returned WPACKET. Ensure you always + * call tx_helper_rollback or tx_helper_commit (or tx_helper_cleanup). Returns + * NULL on failure. + */ +static WPACKET *tx_helper_begin(struct tx_helper *h) +{ + size_t space_left, len; + unsigned char *data; + struct txp_el *el = &h->txp->el[h->enc_level]; + + if (!ossl_assert(!h->txn.active)) + return NULL; + + if (!ossl_assert(!h->done_implicit)) + return NULL; + + data = (unsigned char *)el->scratch + h->scratch_bytes; + len = el->scratch_len - h->scratch_bytes; + + space_left = tx_helper_get_space_left(h); + if (!ossl_assert(space_left <= len)) + return NULL; + + if (!WPACKET_init_static_len(&h->txn.wpkt, data, len, 0)) + return NULL; + + if (!WPACKET_set_max_size(&h->txn.wpkt, space_left)) { + WPACKET_cleanup(&h->txn.wpkt); + return NULL; + } + + h->txn.data = data; + h->txn.active = 1; + return &h->txn.wpkt; +} + +static void tx_helper_end(struct tx_helper *h, int success) +{ + if (success) + WPACKET_finish(&h->txn.wpkt); + else + WPACKET_cleanup(&h->txn.wpkt); + + h->txn.active = 0; + h->txn.data = NULL; +} + +/* Abort a control frame serialization transaction. */ +static void tx_helper_rollback(struct tx_helper *h) +{ + if (!h->txn.active) + return; + + tx_helper_end(h, 0); +} + +/* Commit a control frame. */ +static int tx_helper_commit(struct tx_helper *h) +{ + size_t l = 0; + + if (!h->txn.active) + return 0; + + if (!WPACKET_get_total_written(&h->txn.wpkt, &l)) { + tx_helper_end(h, 0); + return 0; + } + + if (!tx_helper_append_iovec(h, h->txn.data, l)) { + tx_helper_end(h, 0); + return 0; + } + + if (h->txp->msg_callback != NULL && l > 0) { + uint64_t ftype; + int ctype = SSL3_RT_QUIC_FRAME_FULL; + PACKET pkt; + + if (!PACKET_buf_init(&pkt, h->txn.data, l) + || !ossl_quic_wire_peek_frame_header(&pkt, &ftype, NULL)) { + tx_helper_end(h, 0); + return 0; + } + + if (ftype == OSSL_QUIC_FRAME_TYPE_PADDING) + ctype = SSL3_RT_QUIC_FRAME_PADDING; + else if (OSSL_QUIC_FRAME_TYPE_IS_STREAM(ftype) + || ftype == OSSL_QUIC_FRAME_TYPE_CRYPTO) + ctype = SSL3_RT_QUIC_FRAME_HEADER; + + h->txp->msg_callback(1, OSSL_QUIC1_VERSION, ctype, h->txn.data, l, + h->txp->msg_callback_ssl, + h->txp->msg_callback_arg); + } + + h->scratch_bytes += l; + tx_helper_end(h, 1); + return 1; +} + +struct archetype_data { + unsigned int allow_ack : 1; + unsigned int allow_ping : 1; + unsigned int allow_crypto : 1; + unsigned int allow_handshake_done : 1; + unsigned int allow_path_challenge : 1; + unsigned int allow_path_response : 1; + unsigned int allow_new_conn_id : 1; + unsigned int allow_retire_conn_id : 1; + unsigned int allow_stream_rel : 1; + unsigned int allow_conn_fc : 1; + unsigned int allow_conn_close : 1; + unsigned int allow_cfq_other : 1; + unsigned int allow_new_token : 1; + unsigned int allow_force_ack_eliciting : 1; + unsigned int allow_padding : 1; + unsigned int require_ack_eliciting : 1; + unsigned int bypass_cc : 1; +}; + +struct txp_pkt_geom { + size_t cmpl, cmppl, hwm, pkt_overhead; + uint32_t archetype; + struct archetype_data adata; +}; + +struct txp_pkt { + struct tx_helper h; + int h_valid; + QUIC_TXPIM_PKT *tpkt; + QUIC_STREAM *stream_head; + QUIC_PKT_HDR phdr; + struct txp_pkt_geom geom; + int force_pad; +}; + +static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space, + void *arg); +static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, void *arg); +static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, void *arg); +static void on_sstream_updated(uint64_t stream_id, void *arg); +static int sstream_is_pending(QUIC_SSTREAM *sstream); +static int txp_should_try_staging(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level, + uint32_t archetype, + uint64_t cc_limit, + uint32_t *conn_close_enc_level); +static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp); +static int txp_determine_ppl_from_pl(OSSL_QUIC_TX_PACKETISER *txp, + size_t pl, + uint32_t enc_level, + size_t hdr_len, + size_t *r); +static size_t txp_get_mdpl(OSSL_QUIC_TX_PACKETISER *txp); +static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + int chosen_for_conn_close); +static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level, uint32_t archetype, + size_t running_total); +static void txp_pkt_cleanup(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp); +static int txp_pkt_postgen_update_pkt_overhead(struct txp_pkt *pkt, + OSSL_QUIC_TX_PACKETISER *txp); +static int txp_pkt_append_padding(struct txp_pkt *pkt, + OSSL_QUIC_TX_PACKETISER *txp, size_t num_bytes); +static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, struct txp_pkt *pkt, + uint32_t archetype, int *txpim_pkt_reffed); +static uint32_t txp_determine_archetype(OSSL_QUIC_TX_PACKETISER *txp, + uint64_t cc_limit); + +OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args) +{ + OSSL_QUIC_TX_PACKETISER *txp; + + if (args == NULL + || args->qtx == NULL + || args->txpim == NULL + || args->cfq == NULL + || args->ackm == NULL + || args->qsm == NULL + || args->conn_txfc == NULL + || args->conn_rxfc == NULL + || args->max_streams_bidi_rxfc == NULL + || args->max_streams_uni_rxfc == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + txp = OPENSSL_zalloc(sizeof(*txp)); + if (txp == NULL) + return NULL; + + txp->args = *args; + txp->last_tx_time = ossl_time_zero(); + + if (!ossl_quic_fifd_init(&txp->fifd, + txp->args.cfq, txp->args.ackm, txp->args.txpim, + get_sstream_by_id, txp, + on_regen_notify, txp, + on_confirm_notify, txp, + on_sstream_updated, txp)) { + OPENSSL_free(txp); + return NULL; + } + + return txp; +} + +void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp) +{ + uint32_t enc_level; + + if (txp == NULL) + return; + + ossl_quic_tx_packetiser_set_initial_token(txp, NULL, 0, NULL, NULL); + ossl_quic_fifd_cleanup(&txp->fifd); + OPENSSL_free(txp->conn_close_frame.reason); + + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) { + OPENSSL_free(txp->el[enc_level].iovec); + OPENSSL_free(txp->el[enc_level].scratch); + } + + OPENSSL_free(txp); +} + +/* + * Determine if an Initial packet token length is reasonable based on the + * current MDPL, returning 1 if it is OK. + * + * The real PMTU to the peer could differ from our (pessimistic) understanding + * of the PMTU, therefore it is possible we could receive an Initial token from + * a server in a Retry packet which is bigger than the MDPL. In this case it is + * impossible for us ever to make forward progress and we need to error out + * and fail the connection attempt. + * + * The specific boundary condition is complex: for example, after the size of + * the Initial token, there are the Initial packet header overheads and then + * encryption/AEAD tag overheads. After that, the minimum room for frame data in + * order to guarantee forward progress must be guaranteed. For example, a crypto + * stream needs to always be able to serialize at least one byte in a CRYPTO + * frame in order to make forward progress. Because the offset field of a CRYPTO + * frame uses a variable-length integer, the number of bytes needed to ensure + * this also varies. + * + * Rather than trying to get this boundary condition check actually right, + * require a reasonable amount of slack to avoid pathological behaviours. (After + * all, transmitting a CRYPTO stream one byte at a time is probably not + * desirable anyway.) + * + * We choose 160 bytes as the required margin, which is double the rough + * estimation of the minimum we would require to guarantee forward progress + * under worst case packet overheads. + */ +#define TXP_REQUIRED_TOKEN_MARGIN 160 + +static int txp_check_token_len(size_t token_len, size_t mdpl) +{ + if (token_len == 0) + return 1; + + if (token_len >= mdpl) + return 0; + + if (TXP_REQUIRED_TOKEN_MARGIN >= mdpl) + /* (should not be possible because MDPL must be at least 1200) */ + return 0; + + if (token_len > mdpl - TXP_REQUIRED_TOKEN_MARGIN) + return 0; + + return 1; +} + +int ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp, + const unsigned char *token, + size_t token_len, + ossl_quic_initial_token_free_fn *free_cb, + void *free_cb_arg) +{ + if (!txp_check_token_len(token_len, txp_get_mdpl(txp))) + return 0; + + if (txp->initial_token != NULL && txp->initial_token_free_cb != NULL) + txp->initial_token_free_cb(txp->initial_token, txp->initial_token_len, + txp->initial_token_free_cb_arg); + + txp->initial_token = token; + txp->initial_token_len = token_len; + txp->initial_token_free_cb = free_cb; + txp->initial_token_free_cb_arg = free_cb_arg; + return 1; +} + +int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp, + const QUIC_CONN_ID *dcid) +{ + if (dcid == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + txp->args.cur_dcid = *dcid; + return 1; +} + +int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp, + const QUIC_CONN_ID *scid) +{ + if (scid == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + txp->args.cur_scid = *scid; + return 1; +} + +/* Change the destination L4 address the TXP uses to send datagrams. */ +int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp, + const BIO_ADDR *peer) +{ + if (peer == NULL) { + BIO_ADDR_clear(&txp->args.peer); + return 1; + } + + txp->args.peer = *peer; + return 1; +} + +void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, + void (*cb)(const OSSL_QUIC_FRAME_ACK *ack, + uint32_t pn_space, + void *arg), + void *cb_arg) +{ + txp->ack_tx_cb = cb; + txp->ack_tx_cb_arg = cb_arg; +} + +int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (enc_level != QUIC_ENC_LEVEL_0RTT) + txp->args.crypto[ossl_quic_enc_level_to_pn_space(enc_level)] = NULL; + + return 1; +} + +void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp) +{ + txp->handshake_complete = 1; +} + +void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp) +{ + txp->want_handshake_done = 1; +} + +void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space) +{ + txp->force_ack_eliciting |= (1UL << pn_space); +} + +void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space) +{ + txp->want_ack |= (1UL << pn_space); +} + +#define TXP_ERR_INTERNAL 0 /* Internal (e.g. alloc) error */ +#define TXP_ERR_SUCCESS 1 /* Success */ +#define TXP_ERR_SPACE 2 /* Not enough room for another packet */ +#define TXP_ERR_INPUT 3 /* Invalid/malformed input */ + +/* + * Generates a datagram by polling the various ELs to determine if they want to + * generate any frames, and generating a datagram which coalesces packets for + * any ELs which do. + */ +int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, + QUIC_TXP_STATUS *status) +{ + /* + * Called to generate one or more datagrams, each containing one or more + * packets. + * + * There are some tricky things to note here: + * + * - The TXP is only concerned with generating encrypted packets; + * other packets use a different path. + * + * - Any datagram containing an Initial packet must have a payload length + * (DPL) of at least 1200 bytes. This padding need not necessarily be + * found in the Initial packet. + * + * - It is desirable to be able to coalesce an Initial packet + * with a Handshake packet. Since, before generating the Handshake + * packet, we do not know how long it will be, we cannot know the + * correct amount of padding to ensure a DPL of at least 1200 bytes. + * Thus this padding must added to the Handshake packet (or whatever + * packet is the last in the datagram). + * + * - However, at the time that we generate the Initial packet, + * we do not actually know for sure that we will be followed + * in the datagram by another packet. For example, suppose we have + * some queued data (e.g. crypto stream data for the HANDSHAKE EL) + * it looks like we will want to send on the HANDSHAKE EL. + * We could assume padding will be placed in the Handshake packet + * subsequently and avoid adding any padding to the Initial packet + * (which would leave no room for the Handshake packet in the + * datagram). + * + * However, this is not actually a safe assumption. Suppose that we + * are using a link with a MDPL of 1200 bytes, the minimum allowed by + * QUIC. Suppose that the Initial packet consumes 1195 bytes in total. + * Since it is not possible to fit a Handshake packet in just 5 bytes, + * upon trying to add a Handshake packet after generating the Initial + * packet, we will discover we have no room to fit it! This is not a + * problem in itself as another datagram can be sent subsequently, but + * it is a problem because we were counting to use that packet to hold + * the essential padding. But if we have already finished encrypting + * the Initial packet, we cannot go and add padding to it anymore. + * This leaves us stuck. + * + * Because of this, we have to plan multiple packets simultaneously, such + * that we can start generating a Handshake (or 0-RTT or 1-RTT, or so on) + * packet while still having the option to go back and add padding to the + * Initial packet if it turns out to be needed. + * + * Trying to predict ahead of time (e.g. during Initial packet generation) + * whether we will successfully generate a subsequent packet is fraught with + * error as it relies on a large number of variables: + * + * - Do we have room to fit a packet header? (Consider that due to + * variable-length integer encoding this is highly variable and can even + * depend on payload length due to a variable-length Length field.) + * + * - Can we fit even a single one of the frames we want to put in this + * packet in the packet? (Each frame type has a bespoke encoding. While + * our encodings of some frame types are adaptive based on the available + * room - e.g. STREAM frames - ultimately all frame types have some + * absolute minimum number of bytes to be successfully encoded. For + * example, if after an Initial packet there is enough room to encode + * only one byte of frame data, it is quite likely we can't send any of + * the frames we wanted to send.) While this is not strictly a problem + * because we could just fill the packet with padding frames, this is a + * pointless packet and is wasteful. + * + * Thus we adopt a multi-phase architecture: + * + * 1. Archetype Selection: Determine desired packet archetype. + * + * 2. Packet Staging: Generation of packet information and packet payload + * data (frame data) into staging areas. + * + * 3. Packet Adjustment: Adjustment of staged packets, adding padding to + * the staged packets if needed. + * + * 4. Commit: The packets are sent to the QTX and recorded as having been + * sent to the FIFM. + * + */ + int res = 0, rc; + uint32_t archetype, enc_level; + uint32_t conn_close_enc_level = QUIC_ENC_LEVEL_NUM; + struct txp_pkt pkt[QUIC_ENC_LEVEL_NUM]; + size_t pkts_done = 0; + uint64_t cc_limit = txp->args.cc_method->get_tx_allowance(txp->args.cc_data); + int need_padding = 0, txpim_pkt_reffed; + + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) + pkt[enc_level].h_valid = 0; + + memset(status, 0, sizeof(*status)); + + /* + * Should not be needed, but a sanity check in case anyone else has been + * using the QTX. + */ + ossl_qtx_finish_dgram(txp->args.qtx); + + /* 1. Archetype Selection */ + archetype = txp_determine_archetype(txp, cc_limit); + + /* 2. Packet Staging */ + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) { + size_t running_total = (enc_level > QUIC_ENC_LEVEL_INITIAL) + ? pkt[enc_level - 1].geom.hwm : 0; + + pkt[enc_level].geom.hwm = running_total; + + if (!txp_should_try_staging(txp, enc_level, archetype, cc_limit, + &conn_close_enc_level)) + continue; + + if (!txp_pkt_init(&pkt[enc_level], txp, enc_level, archetype, + running_total)) + /* + * If this fails this is not a fatal error - it means the geometry + * planning determined there was not enough space for another + * packet. So just proceed with what we've already planned for. + */ + break; + + rc = txp_generate_for_el(txp, &pkt[enc_level], + conn_close_enc_level == enc_level); + if (rc != TXP_ERR_SUCCESS) + goto out; + + if (pkt[enc_level].force_pad) + /* + * txp_generate_for_el emitted a frame which forces packet padding. + */ + need_padding = 1; + + pkt[enc_level].geom.hwm = running_total + + pkt[enc_level].h.bytes_appended + + pkt[enc_level].geom.pkt_overhead; + } + + /* 3. Packet Adjustment */ + if (pkt[QUIC_ENC_LEVEL_INITIAL].h_valid + && pkt[QUIC_ENC_LEVEL_INITIAL].h.bytes_appended > 0) + /* + * We have an Initial packet in this datagram, so we need to make sure + * the total size of the datagram is adequate. + */ + need_padding = 1; + + if (need_padding) { + size_t total_dgram_size = 0; + const size_t min_dpl = QUIC_MIN_INITIAL_DGRAM_LEN; + uint32_t pad_el = QUIC_ENC_LEVEL_NUM; + + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) + if (pkt[enc_level].h_valid && pkt[enc_level].h.bytes_appended > 0) { + if (pad_el == QUIC_ENC_LEVEL_NUM + /* + * We might not be able to add padding, for example if we + * are using the ACK_ONLY archetype. + */ + && pkt[enc_level].geom.adata.allow_padding + && !pkt[enc_level].h.done_implicit) + pad_el = enc_level; + + txp_pkt_postgen_update_pkt_overhead(&pkt[enc_level], txp); + total_dgram_size += pkt[enc_level].geom.pkt_overhead + + pkt[enc_level].h.bytes_appended; + } + + if (pad_el != QUIC_ENC_LEVEL_NUM && total_dgram_size < min_dpl) { + size_t deficit = min_dpl - total_dgram_size; + + if (!txp_pkt_append_padding(&pkt[pad_el], txp, deficit)) + goto out; + + total_dgram_size += deficit; + + /* + * Padding frames make a packet ineligible for being a non-inflight + * packet. + */ + pkt[pad_el].tpkt->ackm_pkt.is_inflight = 1; + } + + /* + * If we have failed to make a datagram of adequate size, for example + * because we have a padding requirement but are using the ACK_ONLY + * archetype (because we are CC limited), which precludes us from + * sending padding, give up on generating the datagram - there is + * nothing we can do. + */ + if (total_dgram_size < min_dpl) { + res = 1; + goto out; + } + } + + /* 4. Commit */ + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) { + + if (!pkt[enc_level].h_valid) + /* Did not attempt to generate a packet for this EL. */ + continue; + + if (pkt[enc_level].h.bytes_appended == 0) + /* Nothing was generated for this EL, so skip. */ + continue; + + rc = txp_pkt_commit(txp, &pkt[enc_level], archetype, + &txpim_pkt_reffed); + if (rc) { + status->sent_ack_eliciting + = status->sent_ack_eliciting + || pkt[enc_level].tpkt->ackm_pkt.is_ack_eliciting; + + if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE) + status->sent_handshake + = (pkt[enc_level].h_valid + && pkt[enc_level].h.bytes_appended > 0); + } + + if (txpim_pkt_reffed) + pkt[enc_level].tpkt = NULL; /* don't free */ + + if (!rc) + goto out; + + ++pkts_done; + } + + /* Flush & Cleanup */ + res = 1; +out: + ossl_qtx_finish_dgram(txp->args.qtx); + + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) + txp_pkt_cleanup(&pkt[enc_level], txp); + + status->sent_pkt = pkts_done; + + return res; +} + +static const struct archetype_data archetypes[QUIC_ENC_LEVEL_NUM][TX_PACKETISER_ARCHETYPE_NUM] = { + /* EL 0(INITIAL) */ + { + /* EL 0(INITIAL) - Archetype 0(NORMAL) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 0, + }, + /* EL 0(INITIAL) - Archetype 1(PROBE) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 1, + /*bypass_cc =*/ 1, + }, + /* EL 0(INITIAL) - Archetype 2(ACK_ONLY) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 0, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 0, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 0, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 1, + }, + }, + /* EL 1(HANDSHAKE) */ + { + /* EL 1(HANDSHAKE) - Archetype 0(NORMAL) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 0, + }, + /* EL 1(HANDSHAKE) - Archetype 1(PROBE) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 1, + /*bypass_cc =*/ 1, + }, + /* EL 1(HANDSHAKE) - Archetype 2(ACK_ONLY) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 0, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 0, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 0, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 1, + }, + }, + /* EL 2(0RTT) */ + { + /* EL 2(0RTT) - Archetype 0(NORMAL) */ + { + /*allow_ack =*/ 0, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 1, + /*allow_retire_conn_id =*/ 1, + /*allow_stream_rel =*/ 1, + /*allow_conn_fc =*/ 1, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 0, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 0, + }, + /* EL 2(0RTT) - Archetype 1(PROBE) */ + { + /*allow_ack =*/ 0, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 1, + /*allow_retire_conn_id =*/ 1, + /*allow_stream_rel =*/ 1, + /*allow_conn_fc =*/ 1, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 0, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 1, + /*bypass_cc =*/ 1, + }, + /* EL 2(0RTT) - Archetype 2(ACK_ONLY) */ + { + /*allow_ack =*/ 0, + /*allow_ping =*/ 0, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 0, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 0, + /*allow_padding =*/ 0, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 1, + }, + }, + /* EL 3(1RTT) */ + { + /* EL 3(1RTT) - Archetype 0(NORMAL) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 1, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 1, + /*allow_new_conn_id =*/ 1, + /*allow_retire_conn_id =*/ 1, + /*allow_stream_rel =*/ 1, + /*allow_conn_fc =*/ 1, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 1, + /*allow_new_token =*/ 1, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 0, + }, + /* EL 3(1RTT) - Archetype 1(PROBE) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 1, + /*allow_crypto =*/ 1, + /*allow_handshake_done =*/ 1, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 1, + /*allow_new_conn_id =*/ 1, + /*allow_retire_conn_id =*/ 1, + /*allow_stream_rel =*/ 1, + /*allow_conn_fc =*/ 1, + /*allow_conn_close =*/ 1, + /*allow_cfq_other =*/ 1, + /*allow_new_token =*/ 1, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 1, + /*require_ack_eliciting =*/ 1, + /*bypass_cc =*/ 1, + }, + /* EL 3(1RTT) - Archetype 2(ACK_ONLY) */ + { + /*allow_ack =*/ 1, + /*allow_ping =*/ 0, + /*allow_crypto =*/ 0, + /*allow_handshake_done =*/ 0, + /*allow_path_challenge =*/ 0, + /*allow_path_response =*/ 0, + /*allow_new_conn_id =*/ 0, + /*allow_retire_conn_id =*/ 0, + /*allow_stream_rel =*/ 0, + /*allow_conn_fc =*/ 0, + /*allow_conn_close =*/ 0, + /*allow_cfq_other =*/ 0, + /*allow_new_token =*/ 0, + /*allow_force_ack_eliciting =*/ 1, + /*allow_padding =*/ 0, + /*require_ack_eliciting =*/ 0, + /*bypass_cc =*/ 1, + } + } +}; + +static int txp_get_archetype_data(uint32_t enc_level, + uint32_t archetype, + struct archetype_data *a) +{ + if (enc_level >= QUIC_ENC_LEVEL_NUM + || archetype >= TX_PACKETISER_ARCHETYPE_NUM) + return 0; + + /* No need to avoid copying this as it should not exceed one int in size. */ + *a = archetypes[enc_level][archetype]; + return 1; +} + +static int txp_determine_geometry(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t archetype, + uint32_t enc_level, + size_t running_total, + QUIC_PKT_HDR *phdr, + struct txp_pkt_geom *geom) +{ + size_t mdpl, cmpl, hdr_len; + + /* Get information about packet archetype. */ + if (!txp_get_archetype_data(enc_level, archetype, &geom->adata)) + return 0; + + /* Assemble packet header. */ + phdr->type = ossl_quic_enc_level_to_pkt_type(enc_level); + phdr->spin_bit = 0; + phdr->pn_len = txp_determine_pn_len(txp); + phdr->partial = 0; + phdr->fixed = 1; + phdr->reserved = 0; + phdr->version = QUIC_VERSION_1; + phdr->dst_conn_id = txp->args.cur_dcid; + phdr->src_conn_id = txp->args.cur_scid; + + /* + * We need to know the length of the payload to get an accurate header + * length for non-1RTT packets, because the Length field found in + * Initial/Handshake/0-RTT packets uses a variable-length encoding. However, + * we don't have a good idea of the length of our payload, because the + * length of the payload depends on the room in the datagram after fitting + * the header, which depends on the size of the header. + * + * In general, it does not matter if a packet is slightly shorter (because + * e.g. we predicted use of a 2-byte length field, but ended up only needing + * a 1-byte length field). However this does matter for Initial packets + * which must be at least 1200 bytes, which is also the assumed default MTU; + * therefore in many cases Initial packets will be padded to 1200 bytes, + * which means if we overestimated the header size, we will be short by a + * few bytes and the server will ignore the packet for being too short. In + * this case, however, such packets always *will* be padded to meet 1200 + * bytes, which requires a 2-byte length field, so we don't actually need to + * worry about this. Thus we estimate the header length assuming a 2-byte + * length field here, which should in practice work well in all cases. + */ + phdr->len = OSSL_QUIC_VLINT_2B_MAX - phdr->pn_len; + + if (enc_level == QUIC_ENC_LEVEL_INITIAL) { + phdr->token = txp->initial_token; + phdr->token_len = txp->initial_token_len; + } else { + phdr->token = NULL; + phdr->token_len = 0; + } + + hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(phdr->dst_conn_id.id_len, + phdr); + if (hdr_len == 0) + return 0; + + /* MDPL: Maximum datagram payload length. */ + mdpl = txp_get_mdpl(txp); + + /* + * CMPL: Maximum encoded packet size we can put into this datagram given any + * previous packets coalesced into it. + */ + if (running_total > mdpl) + /* Should not be possible, but if it happens: */ + cmpl = 0; + else + cmpl = mdpl - running_total; + + /* CMPPL: Maximum amount we can put into the current packet payload */ + if (!txp_determine_ppl_from_pl(txp, cmpl, enc_level, hdr_len, &geom->cmppl)) + return 0; + + geom->cmpl = cmpl; + geom->pkt_overhead = cmpl - geom->cmppl; + geom->archetype = archetype; + return 1; +} + +static uint32_t txp_determine_archetype(OSSL_QUIC_TX_PACKETISER *txp, + uint64_t cc_limit) +{ + OSSL_ACKM_PROBE_INFO *probe_info + = ossl_ackm_get0_probe_request(txp->args.ackm); + uint32_t pn_space; + + /* + * If ACKM has requested probe generation (e.g. due to PTO), we generate a + * Probe-archetype packet. Actually, we determine archetype on a + * per-datagram basis, so if any EL wants a probe, do a pass in which + * we try and generate a probe (if needed) for all ELs. + */ + if (probe_info->anti_deadlock_initial > 0 + || probe_info->anti_deadlock_handshake > 0) + return TX_PACKETISER_ARCHETYPE_PROBE; + + for (pn_space = QUIC_PN_SPACE_INITIAL; + pn_space < QUIC_PN_SPACE_NUM; + ++pn_space) + if (probe_info->pto[pn_space] > 0) + return TX_PACKETISER_ARCHETYPE_PROBE; + + /* + * If we are out of CC budget, we cannot send a normal packet, + * but we can do an ACK-only packet (potentially, if we + * want to send an ACK). + */ + if (cc_limit == 0) + return TX_PACKETISER_ARCHETYPE_ACK_ONLY; + + /* All other packets. */ + return TX_PACKETISER_ARCHETYPE_NORMAL; +} + +static int txp_should_try_staging(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level, + uint32_t archetype, + uint64_t cc_limit, + uint32_t *conn_close_enc_level) +{ + struct archetype_data a; + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + QUIC_CFQ_ITEM *cfq_item; + + if (!ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) + return 0; + + if (!txp_get_archetype_data(enc_level, archetype, &a)) + return 0; + + if (!a.bypass_cc && cc_limit == 0) + /* CC not allowing us to send. */ + return 0; + + /* + * We can produce CONNECTION_CLOSE frames on any EL in principle, which + * means we need to choose which EL we would prefer to use. After a + * connection is fully established we have only one provisioned EL and this + * is a non-issue. Where multiple ELs are provisioned, it is possible the + * peer does not have the keys for the EL yet, which suggests in general it + * is preferable to use the lowest EL which is still provisioned. + * + * However (RFC 9000 s. 10.2.3 & 12.5) we are also required to not send + * application CONNECTION_CLOSE frames in non-1-RTT ELs, so as to not + * potentially leak application data on a connection which has yet to be + * authenticated. Thus when we have an application CONNECTION_CLOSE frame + * queued and need to send it on a non-1-RTT EL, we have to convert it + * into a transport CONNECTION_CLOSE frame which contains no application + * data. Since this loses information, it suggests we should use the 1-RTT + * EL to avoid this if possible, even if a lower EL is also available. + * + * At the same time, just because we have the 1-RTT EL provisioned locally + * does not necessarily mean the peer does, for example if a handshake + * CRYPTO frame has been lost. It is fairly important that CONNECTION_CLOSE + * is signalled in a way we know our peer can decrypt, as we stop processing + * connection retransmission logic for real after connection close and + * simply 'blindly' retransmit the same CONNECTION_CLOSE frame. + * + * This is not a major concern for clients, since if a client has a 1-RTT EL + * provisioned the server is guaranteed to also have a 1-RTT EL provisioned. + * + * TODO(QUIC SERVER): Revisit this when server support is added. + */ + if (*conn_close_enc_level > enc_level + && *conn_close_enc_level != QUIC_ENC_LEVEL_1RTT) + *conn_close_enc_level = enc_level; + + /* Do we need to send a PTO probe? */ + if (a.allow_force_ack_eliciting) { + OSSL_ACKM_PROBE_INFO *probe_info + = ossl_ackm_get0_probe_request(txp->args.ackm); + + if ((enc_level == QUIC_ENC_LEVEL_INITIAL + && probe_info->anti_deadlock_initial > 0) + || (enc_level == QUIC_ENC_LEVEL_HANDSHAKE + && probe_info->anti_deadlock_handshake > 0) + || probe_info->pto[pn_space] > 0) + return 1; + } + + /* Does the crypto stream for this EL want to produce anything? */ + if (a.allow_crypto && sstream_is_pending(txp->args.crypto[pn_space])) + return 1; + + /* Does the ACKM for this PN space want to produce anything? */ + if (a.allow_ack && (ossl_ackm_is_ack_desired(txp->args.ackm, pn_space) + || (txp->want_ack & (1UL << pn_space)) != 0)) + return 1; + + /* Do we need to force emission of an ACK-eliciting packet? */ + if (a.allow_force_ack_eliciting + && (txp->force_ack_eliciting & (1UL << pn_space)) != 0) + return 1; + + /* Does the connection-level RXFC want to produce a frame? */ + if (a.allow_conn_fc && (txp->want_max_data + || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0))) + return 1; + + /* Do we want to produce a MAX_STREAMS frame? */ + if (a.allow_conn_fc + && (txp->want_max_streams_bidi + || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, + 0) + || txp->want_max_streams_uni + || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, + 0))) + return 1; + + /* Do we want to produce a HANDSHAKE_DONE frame? */ + if (a.allow_handshake_done && txp->want_handshake_done) + return 1; + + /* Do we want to produce a CONNECTION_CLOSE frame? */ + if (a.allow_conn_close && txp->want_conn_close && + *conn_close_enc_level == enc_level) + /* + * This is a bit of a special case since CONNECTION_CLOSE can appear in + * most packet types, and when we decide we want to send it this status + * isn't tied to a specific EL. So if we want to send it, we send it + * only on the lowest non-dropped EL. + */ + return 1; + + /* Does the CFQ have any frames queued for this PN space? */ + if (enc_level != QUIC_ENC_LEVEL_0RTT) + for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); + cfq_item != NULL; + cfq_item = ossl_quic_cfq_item_get_priority_next(cfq_item, pn_space)) { + uint64_t frame_type = ossl_quic_cfq_item_get_frame_type(cfq_item); + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + if (a.allow_new_conn_id) + return 1; + break; + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + if (a.allow_retire_conn_id) + return 1; + break; + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + if (a.allow_new_token) + return 1; + break; + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + if (a.allow_path_response) + return 1; + break; + default: + if (a.allow_cfq_other) + return 1; + break; + } + } + + if (a.allow_stream_rel && txp->handshake_complete) { + QUIC_STREAM_ITER it; + + /* If there are any active streams, 0/1-RTT wants to produce a packet. + * Whether a stream is on the active list is required to be precise + * (i.e., a stream is never on the active list if we cannot produce a + * frame for it), and all stream-related frames are governed by + * a.allow_stream_rel (i.e., if we can send one type of stream-related + * frame, we can send any of them), so we don't need to inspect + * individual streams on the active list, just confirm that the active + * list is non-empty. + */ + ossl_quic_stream_iter_init(&it, txp->args.qsm, 0); + if (it.stream != NULL) + return 1; + } + + return 0; +} + +static int sstream_is_pending(QUIC_SSTREAM *sstream) +{ + OSSL_QUIC_FRAME_STREAM hdr; + OSSL_QTX_IOVEC iov[2]; + size_t num_iov = OSSL_NELEM(iov); + + return ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, &num_iov); +} + +/* Determine how many bytes we should use for the encoded PN. */ +static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp) +{ + return 4; /* TODO(QUIC FUTURE) */ +} + +/* Determine plaintext packet payload length from payload length. */ +static int txp_determine_ppl_from_pl(OSSL_QUIC_TX_PACKETISER *txp, + size_t pl, + uint32_t enc_level, + size_t hdr_len, + size_t *r) +{ + if (pl < hdr_len) + return 0; + + pl -= hdr_len; + + if (!ossl_qtx_calculate_plaintext_payload_len(txp->args.qtx, enc_level, + pl, &pl)) + return 0; + + *r = pl; + return 1; +} + +static size_t txp_get_mdpl(OSSL_QUIC_TX_PACKETISER *txp) +{ + return ossl_qtx_get_mdpl(txp->args.qtx); +} + +static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space, + void *arg) +{ + OSSL_QUIC_TX_PACKETISER *txp = arg; + QUIC_STREAM *s; + + if (stream_id == UINT64_MAX) + return txp->args.crypto[pn_space]; + + s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + if (s == NULL) + return NULL; + + return s->sstream; +} + +static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, void *arg) +{ + OSSL_QUIC_TX_PACKETISER *txp = arg; + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: + txp->want_handshake_done = 1; + break; + case OSSL_QUIC_FRAME_TYPE_MAX_DATA: + txp->want_max_data = 1; + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + txp->want_max_streams_bidi = 1; + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + txp->want_max_streams_uni = 1; + break; + case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: + txp->want_ack |= (1UL << pkt->ackm_pkt.pkt_space); + break; + case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: + { + QUIC_STREAM *s + = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + + if (s == NULL) + return; + + s->want_max_stream_data = 1; + ossl_quic_stream_map_update_state(txp->args.qsm, s); + } + break; + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + { + QUIC_STREAM *s + = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + + if (s == NULL) + return; + + ossl_quic_stream_map_schedule_stop_sending(txp->args.qsm, s); + } + break; + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + { + QUIC_STREAM *s + = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + + if (s == NULL) + return; + + s->want_reset_stream = 1; + ossl_quic_stream_map_update_state(txp->args.qsm, s); + } + break; + default: + assert(0); + break; + } +} + +static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, + uint32_t enc_level, uint32_t archetype, + size_t running_total) +{ + if (!txp_determine_geometry(txp, archetype, enc_level, + running_total, &pkt->phdr, &pkt->geom)) + return 0; + + /* + * Initialise TX helper. If we must be ACK eliciting, reserve 1 byte for + * PING. + */ + if (!tx_helper_init(&pkt->h, txp, enc_level, + pkt->geom.cmppl, + pkt->geom.adata.require_ack_eliciting ? 1 : 0)) + return 0; + + pkt->h_valid = 1; + pkt->tpkt = NULL; + pkt->stream_head = NULL; + pkt->force_pad = 0; + return 1; +} + +static void txp_pkt_cleanup(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp) +{ + if (!pkt->h_valid) + return; + + tx_helper_cleanup(&pkt->h); + pkt->h_valid = 0; + + if (pkt->tpkt != NULL) { + ossl_quic_txpim_pkt_release(txp->args.txpim, pkt->tpkt); + pkt->tpkt = NULL; + } +} + +static int txp_pkt_postgen_update_pkt_overhead(struct txp_pkt *pkt, + OSSL_QUIC_TX_PACKETISER *txp) +{ + /* + * After we have staged and generated our packets, but before we commit + * them, it is possible for the estimated packet overhead (packet header + + * AEAD tag size) to shrink slightly because we generated a short packet + * whose which can be represented in fewer bytes as a variable-length + * integer than we were (pessimistically) budgeting for. We need to account + * for this to ensure that we get our padding calculation exactly right. + * + * Update pkt_overhead to be accurate now that we know how much data is + * going in a packet. + */ + size_t hdr_len, ciphertext_len; + + if (pkt->h.enc_level == QUIC_ENC_LEVEL_INITIAL) + /* + * Don't update overheads for the INITIAL EL - we have not finished + * appending padding to it and would potentially miscalculate the + * correct padding if we now update the pkt_overhead field to switch to + * e.g. a 1-byte length field in the packet header. Since we are padding + * to QUIC_MIN_INITIAL_DGRAM_LEN which requires a 2-byte length field, + * this is guaranteed to be moot anyway. See comment in + * txp_determine_geometry for more information. + */ + return 1; + + if (!ossl_qtx_calculate_ciphertext_payload_len(txp->args.qtx, pkt->h.enc_level, + pkt->h.bytes_appended, + &ciphertext_len)) + return 0; + + pkt->phdr.len = ciphertext_len; + + hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(pkt->phdr.dst_conn_id.id_len, + &pkt->phdr); + + pkt->geom.pkt_overhead = hdr_len + ciphertext_len - pkt->h.bytes_appended; + return 1; +} + +static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id, + QUIC_TXPIM_PKT *pkt, void *arg) +{ + OSSL_QUIC_TX_PACKETISER *txp = arg; + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + { + QUIC_STREAM *s + = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + + if (s == NULL) + return; + + s->acked_stop_sending = 1; + ossl_quic_stream_map_update_state(txp->args.qsm, s); + } + break; + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + { + QUIC_STREAM *s + = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + + if (s == NULL) + return; + + /* + * We must already be in RESET_SENT or RESET_RECVD if we are + * here, so we don't need to check state here. + */ + ossl_quic_stream_map_notify_reset_stream_acked(txp->args.qsm, s); + ossl_quic_stream_map_update_state(txp->args.qsm, s); + } + break; + default: + assert(0); + break; + } +} + +static int txp_pkt_append_padding(struct txp_pkt *pkt, + OSSL_QUIC_TX_PACKETISER *txp, size_t num_bytes) +{ + WPACKET *wpkt; + + if (num_bytes == 0) + return 1; + + if (!ossl_assert(pkt->h_valid)) + return 0; + + if (!ossl_assert(pkt->tpkt != NULL)) + return 0; + + wpkt = tx_helper_begin(&pkt->h); + if (wpkt == NULL) + return 0; + + if (!ossl_quic_wire_encode_padding(wpkt, num_bytes)) { + tx_helper_rollback(&pkt->h); + return 0; + } + + if (!tx_helper_commit(&pkt->h)) + return 0; + + pkt->tpkt->ackm_pkt.num_bytes += num_bytes; + /* Cannot be non-inflight if we have a PADDING frame */ + pkt->tpkt->ackm_pkt.is_inflight = 1; + return 1; +} + +static void on_sstream_updated(uint64_t stream_id, void *arg) +{ + OSSL_QUIC_TX_PACKETISER *txp = arg; + QUIC_STREAM *s; + + s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); + if (s == NULL) + return; + + ossl_quic_stream_map_update_state(txp->args.qsm, s); +} + +/* + * Returns 1 if we can send that many bytes in closing state, 0 otherwise. + * Also maintains the bytes sent state if it returns a success. + */ +static int try_commit_conn_close(OSSL_QUIC_TX_PACKETISER *txp, size_t n) +{ + int res; + + /* We can always send the first connection close frame */ + if (txp->closing_bytes_recv == 0) + return 1; + + /* + * RFC 9000 s. 10.2.1 Closing Connection State: + * To avoid being used for an amplification attack, such + * endpoints MUST limit the cumulative size of packets it sends + * to three times the cumulative size of the packets that are + * received and attributed to the connection. + * and: + * An endpoint in the closing state MUST either discard packets + * received from an unvalidated address or limit the cumulative + * size of packets it sends to an unvalidated address to three + * times the size of packets it receives from that address. + */ + res = txp->closing_bytes_xmit + n <= txp->closing_bytes_recv * 3; + + /* + * Attribute the bytes to the connection, if we are allowed to send them + * and this isn't the first closing frame. + */ + if (res && txp->closing_bytes_recv != 0) + txp->closing_bytes_xmit += n; + return res; +} + +void ossl_quic_tx_packetiser_record_received_closing_bytes( + OSSL_QUIC_TX_PACKETISER *txp, size_t n) +{ + txp->closing_bytes_recv += n; +} + +static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + int chosen_for_conn_close, + int *can_be_non_inflight) +{ + const uint32_t enc_level = pkt->h.enc_level; + const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + const struct archetype_data *a = &pkt->geom.adata; + QUIC_TXPIM_PKT *tpkt = pkt->tpkt; + struct tx_helper *h = &pkt->h; + const OSSL_QUIC_FRAME_ACK *ack; + OSSL_QUIC_FRAME_ACK ack2; + + tpkt->ackm_pkt.largest_acked = QUIC_PN_INVALID; + + /* ACK Frames (Regenerate) */ + if (a->allow_ack + && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_ACK + && (((txp->want_ack & (1UL << pn_space)) != 0) + || ossl_ackm_is_ack_desired(txp->args.ackm, pn_space)) + && (ack = ossl_ackm_get_ack_frame(txp->args.ackm, pn_space)) != NULL) { + WPACKET *wpkt = tx_helper_begin(h); + + if (wpkt == NULL) + return 0; + + /* We do not currently support ECN */ + ack2 = *ack; + ack2.ecn_present = 0; + + if (ossl_quic_wire_encode_frame_ack(wpkt, + txp->args.ack_delay_exponent, + &ack2)) { + if (!tx_helper_commit(h)) + return 0; + + tpkt->had_ack_frame = 1; + + if (ack->num_ack_ranges > 0) + tpkt->ackm_pkt.largest_acked = ack->ack_ranges[0].end; + + if (txp->ack_tx_cb != NULL) + txp->ack_tx_cb(&ack2, pn_space, txp->ack_tx_cb_arg); + } else { + tx_helper_rollback(h); + } + } + + /* CONNECTION_CLOSE Frames (Regenerate) */ + if (a->allow_conn_close && txp->want_conn_close && chosen_for_conn_close) { + WPACKET *wpkt = tx_helper_begin(h); + OSSL_QUIC_FRAME_CONN_CLOSE f, *pf = &txp->conn_close_frame; + size_t l; + + if (wpkt == NULL) + return 0; + + /* + * Application CONNECTION_CLOSE frames may only be sent in the + * Application PN space, as otherwise they may be sent before a + * connection is authenticated and leak application data. Therefore, if + * we need to send a CONNECTION_CLOSE frame in another PN space and were + * given an application CONNECTION_CLOSE frame, convert it into a + * transport CONNECTION_CLOSE frame, removing any sensitive application + * data. + * + * RFC 9000 s. 10.2.3: "A CONNECTION_CLOSE of type 0x1d MUST be replaced + * by a CONNECTION_CLOSE of type 0x1c when sending the frame in Initial + * or Handshake packets. Otherwise, information about the application + * state might be revealed. Endpoints MUST clear the value of the Reason + * Phrase field and SHOULD use the APPLICATION_ERROR code when + * converting to a CONNECTION_CLOSE of type 0x1c." + */ + if (pn_space != QUIC_PN_SPACE_APP && pf->is_app) { + pf = &f; + pf->is_app = 0; + pf->frame_type = 0; + pf->error_code = QUIC_ERR_APPLICATION_ERROR; + pf->reason = NULL; + pf->reason_len = 0; + } + + if (ossl_quic_wire_encode_frame_conn_close(wpkt, pf) + && WPACKET_get_total_written(wpkt, &l) + && try_commit_conn_close(txp, l)) { + if (!tx_helper_commit(h)) + return 0; + + tpkt->had_conn_close = 1; + *can_be_non_inflight = 0; + } else { + tx_helper_rollback(h); + } + } + + return 1; +} + +static int try_len(size_t space_left, size_t orig_len, + size_t base_hdr_len, size_t lenbytes, + uint64_t maxn, size_t *hdr_len, size_t *payload_len) +{ + size_t n; + size_t maxn_ = maxn > SIZE_MAX ? SIZE_MAX : (size_t)maxn; + + *hdr_len = base_hdr_len + lenbytes; + + if (orig_len == 0 && space_left >= *hdr_len) { + *payload_len = 0; + return 1; + } + + n = orig_len; + if (n > maxn_) + n = maxn_; + if (n + *hdr_len > space_left) + n = (space_left >= *hdr_len) ? space_left - *hdr_len : 0; + + *payload_len = n; + return n > 0; +} + +static int determine_len(size_t space_left, size_t orig_len, + size_t base_hdr_len, + uint64_t *hlen, uint64_t *len) +{ + int ok = 0; + size_t chosen_payload_len = 0; + size_t chosen_hdr_len = 0; + size_t payload_len[4], hdr_len[4]; + int i, valid[4] = {0}; + + valid[0] = try_len(space_left, orig_len, base_hdr_len, + 1, OSSL_QUIC_VLINT_1B_MAX, + &hdr_len[0], &payload_len[0]); + valid[1] = try_len(space_left, orig_len, base_hdr_len, + 2, OSSL_QUIC_VLINT_2B_MAX, + &hdr_len[1], &payload_len[1]); + valid[2] = try_len(space_left, orig_len, base_hdr_len, + 4, OSSL_QUIC_VLINT_4B_MAX, + &hdr_len[2], &payload_len[2]); + valid[3] = try_len(space_left, orig_len, base_hdr_len, + 8, OSSL_QUIC_VLINT_8B_MAX, + &hdr_len[3], &payload_len[3]); + + for (i = OSSL_NELEM(valid) - 1; i >= 0; --i) + if (valid[i] && payload_len[i] >= chosen_payload_len) { + chosen_payload_len = payload_len[i]; + chosen_hdr_len = hdr_len[i]; + ok = 1; + } + + *hlen = chosen_hdr_len; + *len = chosen_payload_len; + return ok; +} + +/* + * Given a CRYPTO frame header with accurate chdr->len and a budget + * (space_left), try to find the optimal value of chdr->len to fill as much of + * the budget as possible. This is slightly hairy because larger values of + * chdr->len cause larger encoded sizes of the length field of the frame, which + * in turn mean less space available for payload data. We check all possible + * encodings and choose the optimal encoding. + */ +static int determine_crypto_len(struct tx_helper *h, + OSSL_QUIC_FRAME_CRYPTO *chdr, + size_t space_left, + uint64_t *hlen, + uint64_t *len) +{ + size_t orig_len; + size_t base_hdr_len; /* CRYPTO header length without length field */ + + if (chdr->len > SIZE_MAX) + return 0; + + orig_len = (size_t)chdr->len; + + chdr->len = 0; + base_hdr_len = ossl_quic_wire_get_encoded_frame_len_crypto_hdr(chdr); + chdr->len = orig_len; + if (base_hdr_len == 0) + return 0; + + --base_hdr_len; + + return determine_len(space_left, orig_len, base_hdr_len, hlen, len); +} + +static int determine_stream_len(struct tx_helper *h, + OSSL_QUIC_FRAME_STREAM *shdr, + size_t space_left, + uint64_t *hlen, + uint64_t *len) +{ + size_t orig_len; + size_t base_hdr_len; /* STREAM header length without length field */ + + if (shdr->len > SIZE_MAX) + return 0; + + orig_len = (size_t)shdr->len; + + shdr->len = 0; + base_hdr_len = ossl_quic_wire_get_encoded_frame_len_stream_hdr(shdr); + shdr->len = orig_len; + if (base_hdr_len == 0) + return 0; + + if (shdr->has_explicit_len) + --base_hdr_len; + + return determine_len(space_left, orig_len, base_hdr_len, hlen, len); +} + +static int txp_generate_crypto_frames(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + int *have_ack_eliciting) +{ + const uint32_t enc_level = pkt->h.enc_level; + const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + QUIC_TXPIM_PKT *tpkt = pkt->tpkt; + struct tx_helper *h = &pkt->h; + size_t num_stream_iovec; + OSSL_QUIC_FRAME_STREAM shdr = {0}; + OSSL_QUIC_FRAME_CRYPTO chdr = {0}; + OSSL_QTX_IOVEC iov[2]; + uint64_t hdr_bytes; + WPACKET *wpkt; + QUIC_TXPIM_CHUNK chunk = {0}; + size_t i, space_left; + + for (i = 0;; ++i) { + space_left = tx_helper_get_space_left(h); + + if (space_left < MIN_FRAME_SIZE_CRYPTO) + return 1; /* no point trying */ + + /* Do we have any CRYPTO data waiting? */ + num_stream_iovec = OSSL_NELEM(iov); + if (!ossl_quic_sstream_get_stream_frame(txp->args.crypto[pn_space], + i, &shdr, iov, + &num_stream_iovec)) + return 1; /* nothing to do */ + + /* Convert STREAM frame header to CRYPTO frame header */ + chdr.offset = shdr.offset; + chdr.len = shdr.len; + + if (chdr.len == 0) + return 1; /* nothing to do */ + + /* Find best fit (header length, payload length) combination. */ + if (!determine_crypto_len(h, &chdr, space_left, &hdr_bytes, + &chdr.len)) + return 1; /* can't fit anything */ + + /* + * Truncate IOVs to match our chosen length. + * + * The length cannot be more than SIZE_MAX because this length comes + * from our send stream buffer. + */ + ossl_quic_sstream_adjust_iov((size_t)chdr.len, iov, num_stream_iovec); + + /* + * Ensure we have enough iovecs allocated (1 for the header, up to 2 for + * the stream data.) + */ + if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) + return 0; /* alloc error */ + + /* Encode the header. */ + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + return 0; /* alloc error */ + + if (!ossl_quic_wire_encode_frame_crypto_hdr(wpkt, &chdr)) { + tx_helper_rollback(h); + return 1; /* can't fit */ + } + + if (!tx_helper_commit(h)) + return 0; /* alloc error */ + + /* Add payload iovecs to the helper (infallible). */ + for (i = 0; i < num_stream_iovec; ++i) + tx_helper_append_iovec(h, iov[i].buf, iov[i].buf_len); + + *have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + + /* Log chunk to TXPIM. */ + chunk.stream_id = UINT64_MAX; /* crypto stream */ + chunk.start = chdr.offset; + chunk.end = chdr.offset + chdr.len - 1; + chunk.has_fin = 0; /* Crypto stream never ends */ + if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) + return 0; /* alloc error */ + } +} + +struct chunk_info { + OSSL_QUIC_FRAME_STREAM shdr; + uint64_t orig_len; + OSSL_QTX_IOVEC iov[2]; + size_t num_stream_iovec; + int valid; +}; + +static int txp_plan_stream_chunk(OSSL_QUIC_TX_PACKETISER *txp, + struct tx_helper *h, + QUIC_SSTREAM *sstream, + QUIC_TXFC *stream_txfc, + size_t skip, + struct chunk_info *chunk, + uint64_t consumed) +{ + uint64_t fc_credit, fc_swm, fc_limit; + + chunk->num_stream_iovec = OSSL_NELEM(chunk->iov); + chunk->valid = ossl_quic_sstream_get_stream_frame(sstream, skip, + &chunk->shdr, + chunk->iov, + &chunk->num_stream_iovec); + if (!chunk->valid) + return 1; + + if (!ossl_assert(chunk->shdr.len > 0 || chunk->shdr.is_fin)) + /* Should only have 0-length chunk if FIN */ + return 0; + + chunk->orig_len = chunk->shdr.len; + + /* Clamp according to connection and stream-level TXFC. */ + fc_credit = ossl_quic_txfc_get_credit(stream_txfc, consumed); + fc_swm = ossl_quic_txfc_get_swm(stream_txfc); + fc_limit = fc_swm + fc_credit; + + if (chunk->shdr.len > 0 && chunk->shdr.offset + chunk->shdr.len > fc_limit) { + chunk->shdr.len = (fc_limit <= chunk->shdr.offset) + ? 0 : fc_limit - chunk->shdr.offset; + chunk->shdr.is_fin = 0; + } + + if (chunk->shdr.len == 0 && !chunk->shdr.is_fin) { + /* + * Nothing to do due to TXFC. Since SSTREAM returns chunks in ascending + * order of offset we don't need to check any later chunks, so stop + * iterating here. + */ + chunk->valid = 0; + return 1; + } + + return 1; +} + +/* + * Returns 0 on fatal error (e.g. allocation failure), 1 on success. + * *packet_full is set to 1 if there is no longer enough room for another STREAM + * frame. + */ +static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + uint64_t id, + QUIC_SSTREAM *sstream, + QUIC_TXFC *stream_txfc, + QUIC_STREAM *next_stream, + int *have_ack_eliciting, + int *packet_full, + uint64_t *new_credit_consumed, + uint64_t conn_consumed) +{ + int rc = 0; + struct chunk_info chunks[2] = {0}; + const uint32_t enc_level = pkt->h.enc_level; + QUIC_TXPIM_PKT *tpkt = pkt->tpkt; + struct tx_helper *h = &pkt->h; + OSSL_QUIC_FRAME_STREAM *shdr; + WPACKET *wpkt; + QUIC_TXPIM_CHUNK chunk; + size_t i, j, space_left; + int can_fill_payload, use_explicit_len; + int could_have_following_chunk; + uint64_t orig_len; + uint64_t hdr_len_implicit, payload_len_implicit; + uint64_t hdr_len_explicit, payload_len_explicit; + uint64_t fc_swm, fc_new_hwm; + + fc_swm = ossl_quic_txfc_get_swm(stream_txfc); + fc_new_hwm = fc_swm; + + /* + * Load the first two chunks if any offered by the send stream. We retrieve + * the next chunk in advance so we can determine if we need to send any more + * chunks from the same stream after this one, which is needed when + * determining when we can use an implicit length in a STREAM frame. + */ + for (i = 0; i < 2; ++i) { + if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i, &chunks[i], + conn_consumed)) + goto err; + + if (i == 0 && !chunks[i].valid) { + /* No chunks, nothing to do. */ + rc = 1; + goto err; + } + } + + for (i = 0;; ++i) { + space_left = tx_helper_get_space_left(h); + + if (!chunks[i % 2].valid) { + /* Out of chunks; we're done. */ + rc = 1; + goto err; + } + + if (space_left < MIN_FRAME_SIZE_STREAM) { + *packet_full = 1; + rc = 1; + goto err; + } + + if (!ossl_assert(!h->done_implicit)) + /* + * Logic below should have ensured we didn't append an + * implicit-length unless we filled the packet or didn't have + * another stream to handle, so this should not be possible. + */ + goto err; + + shdr = &chunks[i % 2].shdr; + orig_len = chunks[i % 2].orig_len; + if (i > 0) + /* Load next chunk for lookahead. */ + if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i + 1, + &chunks[(i + 1) % 2], conn_consumed)) + goto err; + + /* + * Find best fit (header length, payload length) combination for if we + * use an implicit length. + */ + shdr->has_explicit_len = 0; + hdr_len_implicit = payload_len_implicit = 0; + if (!determine_stream_len(h, shdr, space_left, + &hdr_len_implicit, &payload_len_implicit)) { + *packet_full = 1; + rc = 1; + goto err; /* can't fit anything */ + } + + /* + * If there is a next stream, we don't use the implicit length so we can + * add more STREAM frames after this one, unless there is enough data + * for this STREAM frame to fill the packet. + */ + can_fill_payload = (hdr_len_implicit + payload_len_implicit + >= space_left); + + /* + * Is there is a stream after this one, or another chunk pending + * transmission in this stream? + */ + could_have_following_chunk + = (next_stream != NULL || chunks[(i + 1) % 2].valid); + + /* Choose between explicit or implicit length representations. */ + use_explicit_len = !((can_fill_payload || !could_have_following_chunk) + && !pkt->force_pad); + + if (use_explicit_len) { + /* + * Find best fit (header length, payload length) combination for if + * we use an explicit length. + */ + shdr->has_explicit_len = 1; + hdr_len_explicit = payload_len_explicit = 0; + if (!determine_stream_len(h, shdr, space_left, + &hdr_len_explicit, &payload_len_explicit)) { + *packet_full = 1; + rc = 1; + goto err; /* can't fit anything */ + } + + shdr->len = payload_len_explicit; + } else { + *packet_full = 1; + shdr->has_explicit_len = 0; + shdr->len = payload_len_implicit; + } + + /* If this is a FIN, don't keep filling the packet with more FINs. */ + if (shdr->is_fin) + chunks[(i + 1) % 2].valid = 0; + + /* + * We are now committed to our length (shdr->len can't change). + * If we truncated the chunk, clear the FIN bit. + */ + if (shdr->len < orig_len) + shdr->is_fin = 0; + + /* Truncate IOVs to match our chosen length. */ + ossl_quic_sstream_adjust_iov((size_t)shdr->len, chunks[i % 2].iov, + chunks[i % 2].num_stream_iovec); + + /* + * Ensure we have enough iovecs allocated (1 for the header, up to 2 for + * the stream data.) + */ + if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) + goto err; /* alloc error */ + + /* Encode the header. */ + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + goto err; /* alloc error */ + + shdr->stream_id = id; + if (!ossl_assert(ossl_quic_wire_encode_frame_stream_hdr(wpkt, shdr))) { + /* (Should not be possible.) */ + tx_helper_rollback(h); + *packet_full = 1; + rc = 1; + goto err; /* can't fit */ + } + + if (!tx_helper_commit(h)) + goto err; /* alloc error */ + + /* Add payload iovecs to the helper (infallible). */ + for (j = 0; j < chunks[i % 2].num_stream_iovec; ++j) + tx_helper_append_iovec(h, chunks[i % 2].iov[j].buf, + chunks[i % 2].iov[j].buf_len); + + *have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + if (!shdr->has_explicit_len) + h->done_implicit = 1; + + /* Log new TXFC credit which was consumed. */ + if (shdr->len > 0 && shdr->offset + shdr->len > fc_new_hwm) + fc_new_hwm = shdr->offset + shdr->len; + + /* Log chunk to TXPIM. */ + chunk.stream_id = shdr->stream_id; + chunk.start = shdr->offset; + chunk.end = shdr->offset + shdr->len - 1; + chunk.has_fin = shdr->is_fin; + chunk.has_stop_sending = 0; + chunk.has_reset_stream = 0; + if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) + goto err; /* alloc error */ + + if (shdr->len < orig_len) { + /* + * If we did not serialize all of this chunk we definitely do not + * want to try the next chunk + */ + rc = 1; + goto err; + } + } + +err: + *new_credit_consumed = fc_new_hwm - fc_swm; + return rc; +} + +static void txp_enlink_tmp(QUIC_STREAM **tmp_head, QUIC_STREAM *stream) +{ + stream->txp_next = *tmp_head; + *tmp_head = stream; +} + +static int txp_generate_stream_related(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + int *have_ack_eliciting, + QUIC_STREAM **tmp_head) +{ + QUIC_STREAM_ITER it; + WPACKET *wpkt; + uint64_t cwm; + QUIC_STREAM *stream, *snext; + struct tx_helper *h = &pkt->h; + uint64_t conn_consumed = 0; + + for (ossl_quic_stream_iter_init(&it, txp->args.qsm, 1); + it.stream != NULL;) { + + stream = it.stream; + ossl_quic_stream_iter_next(&it); + snext = it.stream; + + stream->txp_sent_fc = 0; + stream->txp_sent_stop_sending = 0; + stream->txp_sent_reset_stream = 0; + stream->txp_blocked = 0; + stream->txp_txfc_new_credit_consumed = 0; + + /* Stream Abort Frames (STOP_SENDING, RESET_STREAM) */ + if (stream->want_stop_sending) { + OSSL_QUIC_FRAME_STOP_SENDING f; + + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + return 0; /* alloc error */ + + f.stream_id = stream->id; + f.app_error_code = stream->stop_sending_aec; + if (!ossl_quic_wire_encode_frame_stop_sending(wpkt, &f)) { + tx_helper_rollback(h); /* can't fit */ + txp_enlink_tmp(tmp_head, stream); + break; + } + + if (!tx_helper_commit(h)) + return 0; /* alloc error */ + + *have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + stream->txp_sent_stop_sending = 1; + } + + if (stream->want_reset_stream) { + OSSL_QUIC_FRAME_RESET_STREAM f; + + if (!ossl_assert(stream->send_state == QUIC_SSTREAM_STATE_RESET_SENT)) + return 0; + + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + return 0; /* alloc error */ + + f.stream_id = stream->id; + f.app_error_code = stream->reset_stream_aec; + if (!ossl_quic_stream_send_get_final_size(stream, &f.final_size)) + return 0; /* should not be possible */ + + if (!ossl_quic_wire_encode_frame_reset_stream(wpkt, &f)) { + tx_helper_rollback(h); /* can't fit */ + txp_enlink_tmp(tmp_head, stream); + break; + } + + if (!tx_helper_commit(h)) + return 0; /* alloc error */ + + *have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + stream->txp_sent_reset_stream = 1; + + /* + * The final size of the stream as indicated by RESET_STREAM is used + * to ensure a consistent view of flow control state by both + * parties; if we happen to send a RESET_STREAM that consumes more + * flow control credit, make sure we account for that. + */ + if (!ossl_assert(f.final_size <= ossl_quic_txfc_get_swm(&stream->txfc))) + return 0; + + stream->txp_txfc_new_credit_consumed + = f.final_size - ossl_quic_txfc_get_swm(&stream->txfc); + } + + /* + * Stream Flow Control Frames (MAX_STREAM_DATA) + * + * RFC 9000 s. 13.3: "An endpoint SHOULD stop sending MAX_STREAM_DATA + * frames when the receiving part of the stream enters a "Size Known" or + * "Reset Recvd" state." -- In practice, RECV is the only state + * in which it makes sense to generate more MAX_STREAM_DATA frames. + */ + if (stream->recv_state == QUIC_RSTREAM_STATE_RECV + && (stream->want_max_stream_data + || ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 0))) { + + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + return 0; /* alloc error */ + + cwm = ossl_quic_rxfc_get_cwm(&stream->rxfc); + + if (!ossl_quic_wire_encode_frame_max_stream_data(wpkt, stream->id, + cwm)) { + tx_helper_rollback(h); /* can't fit */ + txp_enlink_tmp(tmp_head, stream); + break; + } + + if (!tx_helper_commit(h)) + return 0; /* alloc error */ + + *have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + stream->txp_sent_fc = 1; + } + + /* + * Stream Data Frames (STREAM) + * + * RFC 9000 s. 3.3: A sender MUST NOT send a STREAM [...] frame for a + * stream in the "Reset Sent" state [or any terminal state]. We don't + * send any more STREAM frames if we are sending, have sent, or are + * planning to send, RESET_STREAM. The other terminal state is Data + * Recvd, but txp_generate_stream_frames() is guaranteed to generate + * nothing in this case. + */ + if (ossl_quic_stream_has_send_buffer(stream) + && !ossl_quic_stream_send_is_reset(stream)) { + int packet_full = 0; + + if (!ossl_assert(!stream->want_reset_stream)) + return 0; + + if (!txp_generate_stream_frames(txp, pkt, + stream->id, stream->sstream, + &stream->txfc, + snext, + have_ack_eliciting, + &packet_full, + &stream->txp_txfc_new_credit_consumed, + conn_consumed)) { + /* Fatal error (allocation, etc.) */ + txp_enlink_tmp(tmp_head, stream); + return 0; + } + conn_consumed += stream->txp_txfc_new_credit_consumed; + + if (packet_full) { + txp_enlink_tmp(tmp_head, stream); + break; + } + } + + txp_enlink_tmp(tmp_head, stream); + } + + return 1; +} + +static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + int chosen_for_conn_close) +{ + int rc = TXP_ERR_SUCCESS; + const uint32_t enc_level = pkt->h.enc_level; + const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + int have_ack_eliciting = 0, done_pre_token = 0; + const struct archetype_data a = pkt->geom.adata; + /* + * Cleared if we encode any non-ACK-eliciting frame type which rules out the + * packet being a non-inflight frame. This means any non-ACK ACK-eliciting + * frame, even PADDING frames. ACK eliciting frames always cause a packet to + * become ineligible for non-inflight treatment so it is not necessary to + * clear this in cases where have_ack_eliciting is set, as it is ignored in + * that case. + */ + int can_be_non_inflight = 1; + QUIC_CFQ_ITEM *cfq_item; + QUIC_TXPIM_PKT *tpkt = NULL; + struct tx_helper *h = &pkt->h; + + /* Maximum PN reached? */ + if (!ossl_quic_pn_valid(txp->next_pn[pn_space])) + goto fatal_err; + + if (!ossl_assert(pkt->tpkt == NULL)) + goto fatal_err; + + if ((pkt->tpkt = tpkt = ossl_quic_txpim_pkt_alloc(txp->args.txpim)) == NULL) + goto fatal_err; + + /* + * Frame Serialization + * =================== + * + * We now serialize frames into the packet in descending order of priority. + */ + + /* HANDSHAKE_DONE (Regenerate) */ + if (a.allow_handshake_done && txp->want_handshake_done + && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_HANDSHAKE_DONE) { + WPACKET *wpkt = tx_helper_begin(h); + + if (wpkt == NULL) + goto fatal_err; + + if (ossl_quic_wire_encode_frame_handshake_done(wpkt)) { + tpkt->had_handshake_done_frame = 1; + have_ack_eliciting = 1; + + if (!tx_helper_commit(h)) + goto fatal_err; + + tx_helper_unrestrict(h); /* no longer need PING */ + } else { + tx_helper_rollback(h); + } + } + + /* MAX_DATA (Regenerate) */ + if (a.allow_conn_fc + && (txp->want_max_data + || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0)) + && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_DATA) { + WPACKET *wpkt = tx_helper_begin(h); + uint64_t cwm = ossl_quic_rxfc_get_cwm(txp->args.conn_rxfc); + + if (wpkt == NULL) + goto fatal_err; + + if (ossl_quic_wire_encode_frame_max_data(wpkt, cwm)) { + tpkt->had_max_data_frame = 1; + have_ack_eliciting = 1; + + if (!tx_helper_commit(h)) + goto fatal_err; + + tx_helper_unrestrict(h); /* no longer need PING */ + } else { + tx_helper_rollback(h); + } + } + + /* MAX_STREAMS_BIDI (Regenerate) */ + if (a.allow_conn_fc + && (txp->want_max_streams_bidi + || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 0)) + && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_STREAMS_BIDI) { + WPACKET *wpkt = tx_helper_begin(h); + uint64_t max_streams + = ossl_quic_rxfc_get_cwm(txp->args.max_streams_bidi_rxfc); + + if (wpkt == NULL) + goto fatal_err; + + if (ossl_quic_wire_encode_frame_max_streams(wpkt, /*is_uni=*/0, + max_streams)) { + tpkt->had_max_streams_bidi_frame = 1; + have_ack_eliciting = 1; + + if (!tx_helper_commit(h)) + goto fatal_err; + + tx_helper_unrestrict(h); /* no longer need PING */ + } else { + tx_helper_rollback(h); + } + } + + /* MAX_STREAMS_UNI (Regenerate) */ + if (a.allow_conn_fc + && (txp->want_max_streams_uni + || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 0)) + && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_STREAMS_UNI) { + WPACKET *wpkt = tx_helper_begin(h); + uint64_t max_streams + = ossl_quic_rxfc_get_cwm(txp->args.max_streams_uni_rxfc); + + if (wpkt == NULL) + goto fatal_err; + + if (ossl_quic_wire_encode_frame_max_streams(wpkt, /*is_uni=*/1, + max_streams)) { + tpkt->had_max_streams_uni_frame = 1; + have_ack_eliciting = 1; + + if (!tx_helper_commit(h)) + goto fatal_err; + + tx_helper_unrestrict(h); /* no longer need PING */ + } else { + tx_helper_rollback(h); + } + } + + /* GCR Frames */ + for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); + cfq_item != NULL; + cfq_item = ossl_quic_cfq_item_get_priority_next(cfq_item, pn_space)) { + uint64_t frame_type = ossl_quic_cfq_item_get_frame_type(cfq_item); + const unsigned char *encoded = ossl_quic_cfq_item_get_encoded(cfq_item); + size_t encoded_len = ossl_quic_cfq_item_get_encoded_len(cfq_item); + + switch (frame_type) { + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + if (!a.allow_new_conn_id) + continue; + break; + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + if (!a.allow_retire_conn_id) + continue; + break; + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + if (!a.allow_new_token) + continue; + + /* + * NEW_TOKEN frames are handled via GCR, but some + * Regenerate-strategy frames should come before them (namely + * ACK, CONNECTION_CLOSE, PATH_CHALLENGE and PATH_RESPONSE). If + * we find a NEW_TOKEN frame, do these now. If there are no + * NEW_TOKEN frames in the GCR queue we will handle these below. + */ + if (!done_pre_token) + if (txp_generate_pre_token(txp, pkt, + chosen_for_conn_close, + &can_be_non_inflight)) + done_pre_token = 1; + + break; + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + if (!a.allow_path_response) + continue; + + /* + * RFC 9000 s. 8.2.2: An endpoint MUST expand datagrams that + * contain a PATH_RESPONSE frame to at least the smallest + * allowed maximum datagram size of 1200 bytes. + */ + pkt->force_pad = 1; + break; + default: + if (!a.allow_cfq_other) + continue; + break; + } + + /* + * If the frame is too big, don't try to schedule any more GCR frames in + * this packet rather than sending subsequent ones out of order. + */ + if (encoded_len > tx_helper_get_space_left(h)) + break; + + if (!tx_helper_append_iovec(h, encoded, encoded_len)) + goto fatal_err; + + ossl_quic_txpim_pkt_add_cfq_item(tpkt, cfq_item); + + if (ossl_quic_frame_type_is_ack_eliciting(frame_type)) { + have_ack_eliciting = 1; + tx_helper_unrestrict(h); /* no longer need PING */ + } + } + + /* + * If we didn't generate ACK, CONNECTION_CLOSE, PATH_CHALLENGE or + * PATH_RESPONSE (as desired) before, do so now. + */ + if (!done_pre_token) + if (txp_generate_pre_token(txp, pkt, + chosen_for_conn_close, + &can_be_non_inflight)) + done_pre_token = 1; + + /* CRYPTO Frames */ + if (a.allow_crypto) + if (!txp_generate_crypto_frames(txp, pkt, &have_ack_eliciting)) + goto fatal_err; + + /* Stream-specific frames */ + if (a.allow_stream_rel && txp->handshake_complete) + if (!txp_generate_stream_related(txp, pkt, + &have_ack_eliciting, + &pkt->stream_head)) + goto fatal_err; + + /* PING */ + tx_helper_unrestrict(h); + + if ((a.require_ack_eliciting + || (txp->force_ack_eliciting & (1UL << pn_space)) != 0) + && !have_ack_eliciting && a.allow_ping) { + WPACKET *wpkt; + + wpkt = tx_helper_begin(h); + if (wpkt == NULL) + goto fatal_err; + + if (!ossl_quic_wire_encode_frame_ping(wpkt) + || !tx_helper_commit(h)) + /* + * We treat a request to be ACK-eliciting as a requirement, so this + * is an error. + */ + goto fatal_err; + + have_ack_eliciting = 1; + } + + /* PADDING is added by ossl_quic_tx_packetiser_generate(). */ + + /* + * ACKM Data + * ========= + */ + if (have_ack_eliciting) + can_be_non_inflight = 0; + + /* ACKM Data */ + tpkt->ackm_pkt.num_bytes = h->bytes_appended + pkt->geom.pkt_overhead; + tpkt->ackm_pkt.pkt_num = txp->next_pn[pn_space]; + /* largest_acked is set in txp_generate_pre_token */ + tpkt->ackm_pkt.pkt_space = pn_space; + tpkt->ackm_pkt.is_inflight = !can_be_non_inflight; + tpkt->ackm_pkt.is_ack_eliciting = have_ack_eliciting; + tpkt->ackm_pkt.is_pto_probe = 0; + tpkt->ackm_pkt.is_mtu_probe = 0; + tpkt->ackm_pkt.time = txp->args.now(txp->args.now_arg); + + /* Done. */ + return rc; + +fatal_err: + /* + * Handler for fatal errors, i.e. errors causing us to abort the entire + * packet rather than just one frame. Examples of such errors include + * allocation errors. + */ + if (tpkt != NULL) { + ossl_quic_txpim_pkt_release(txp->args.txpim, tpkt); + pkt->tpkt = NULL; + } + return TXP_ERR_INTERNAL; +} + +/* + * Commits and queues a packet for transmission. There is no backing out after + * this. + * + * This: + * + * - Sends the packet to the QTX for encryption and transmission; + * + * - Records the packet as having been transmitted in FIFM. ACKM is informed, + * etc. and the TXPIM record is filed. + * + * - Informs various subsystems of frames that were sent and clears frame + * wanted flags so that we do not generate the same frames again. + * + * Assumptions: + * + * - pkt is a txp_pkt for the correct EL; + * + * - pkt->tpkt is valid; + * + * - pkt->tpkt->ackm_pkt has been fully filled in; + * + * - Stream chunk records have been appended to pkt->tpkt for STREAM and + * CRYPTO frames, but not for RESET_STREAM or STOP_SENDING frames; + * + * - The chosen stream list for the packet can be fully walked from + * pkt->stream_head using stream->txp_next; + * + * - pkt->has_ack_eliciting is set correctly. + * + */ +static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, + struct txp_pkt *pkt, + uint32_t archetype, + int *txpim_pkt_reffed) +{ + int rc = 1; + uint32_t enc_level = pkt->h.enc_level; + uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + QUIC_TXPIM_PKT *tpkt = pkt->tpkt; + QUIC_STREAM *stream; + OSSL_QTX_PKT txpkt; + struct archetype_data a; + + *txpim_pkt_reffed = 0; + + /* Cannot send a packet with an empty payload. */ + if (pkt->h.bytes_appended == 0) + return 0; + + if (!txp_get_archetype_data(enc_level, archetype, &a)) + return 0; + + /* Packet Information for QTX */ + txpkt.hdr = &pkt->phdr; + txpkt.iovec = txp->el[enc_level].iovec; + txpkt.num_iovec = pkt->h.num_iovec; + txpkt.local = NULL; + txpkt.peer = BIO_ADDR_family(&txp->args.peer) == AF_UNSPEC + ? NULL : &txp->args.peer; + txpkt.pn = txp->next_pn[pn_space]; + txpkt.flags = OSSL_QTX_PKT_FLAG_COALESCE; /* always try to coalesce */ + + /* Generate TXPIM chunks representing STOP_SENDING and RESET_STREAM frames. */ + for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) + if (stream->txp_sent_stop_sending || stream->txp_sent_reset_stream) { + /* Log STOP_SENDING/RESET_STREAM chunk to TXPIM. */ + QUIC_TXPIM_CHUNK chunk; + + chunk.stream_id = stream->id; + chunk.start = UINT64_MAX; + chunk.end = 0; + chunk.has_fin = 0; + chunk.has_stop_sending = stream->txp_sent_stop_sending; + chunk.has_reset_stream = stream->txp_sent_reset_stream; + if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) + return 0; /* alloc error */ + } + + /* Dispatch to FIFD. */ + if (!ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt)) + return 0; + + /* + * Transmission and Post-Packet Generation Bookkeeping + * =================================================== + * + * No backing out anymore - at this point the ACKM has recorded the packet + * as having been sent, so we need to increment our next PN counter, or + * the ACKM will complain when we try to record a duplicate packet with + * the same PN later. At this point actually sending the packet may still + * fail. In this unlikely event it will simply be handled as though it + * were a lost packet. + */ + ++txp->next_pn[pn_space]; + *txpim_pkt_reffed = 1; + + /* Send the packet. */ + if (!ossl_qtx_write_pkt(txp->args.qtx, &txpkt)) + return 0; + + /* + * Record FC and stream abort frames as sent; deactivate streams which no + * longer have anything to do. + */ + for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) { + if (stream->txp_sent_fc) { + stream->want_max_stream_data = 0; + ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 1); + } + + if (stream->txp_sent_stop_sending) + stream->want_stop_sending = 0; + + if (stream->txp_sent_reset_stream) + stream->want_reset_stream = 0; + + if (stream->txp_txfc_new_credit_consumed > 0) { + if (!ossl_assert(ossl_quic_txfc_consume_credit(&stream->txfc, + stream->txp_txfc_new_credit_consumed))) + /* + * Should not be possible, but we should continue with our + * bookkeeping as we have already committed the packet to the + * FIFD. Just change the value we return. + */ + rc = 0; + + stream->txp_txfc_new_credit_consumed = 0; + } + + /* + * If we no longer need to generate any flow control (MAX_STREAM_DATA), + * STOP_SENDING or RESET_STREAM frames, nor any STREAM frames (because + * the stream is drained of data or TXFC-blocked), we can mark the + * stream as inactive. + */ + ossl_quic_stream_map_update_state(txp->args.qsm, stream); + + if (ossl_quic_stream_has_send_buffer(stream) + && !ossl_quic_sstream_has_pending(stream->sstream) + && ossl_quic_sstream_get_final_size(stream->sstream, NULL)) + /* + * Transition to DATA_SENT if stream has a final size and we have + * sent all data. + */ + ossl_quic_stream_map_notify_all_data_sent(txp->args.qsm, stream); + } + + /* We have now sent the packet, so update state accordingly. */ + if (tpkt->ackm_pkt.is_ack_eliciting) + txp->force_ack_eliciting &= ~(1UL << pn_space); + + if (tpkt->had_handshake_done_frame) + txp->want_handshake_done = 0; + + if (tpkt->had_max_data_frame) { + txp->want_max_data = 0; + ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 1); + } + + if (tpkt->had_max_streams_bidi_frame) { + txp->want_max_streams_bidi = 0; + ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 1); + } + + if (tpkt->had_max_streams_uni_frame) { + txp->want_max_streams_uni = 0; + ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 1); + } + + if (tpkt->had_ack_frame) + txp->want_ack &= ~(1UL << pn_space); + + if (tpkt->had_conn_close) + txp->want_conn_close = 0; + + /* + * Decrement probe request counts if we have sent a packet that meets + * the requirement of a probe, namely being ACK-eliciting. + */ + if (tpkt->ackm_pkt.is_ack_eliciting) { + OSSL_ACKM_PROBE_INFO *probe_info + = ossl_ackm_get0_probe_request(txp->args.ackm); + + if (enc_level == QUIC_ENC_LEVEL_INITIAL + && probe_info->anti_deadlock_initial > 0) + --probe_info->anti_deadlock_initial; + + if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE + && probe_info->anti_deadlock_handshake > 0) + --probe_info->anti_deadlock_handshake; + + if (a.allow_force_ack_eliciting /* (i.e., not for 0-RTT) */ + && probe_info->pto[pn_space] > 0) + --probe_info->pto[pn_space]; + } + + return rc; +} + +/* Ensure the iovec array is at least num elements long. */ +static int txp_el_ensure_iovec(struct txp_el *el, size_t num) +{ + OSSL_QTX_IOVEC *iovec; + + if (el->alloc_iovec >= num) + return 1; + + num = el->alloc_iovec != 0 ? el->alloc_iovec * 2 : 8; + + iovec = OPENSSL_realloc(el->iovec, sizeof(OSSL_QTX_IOVEC) * num); + if (iovec == NULL) + return 0; + + el->iovec = iovec; + el->alloc_iovec = num; + return 1; +} + +int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp, + const OSSL_QUIC_FRAME_CONN_CLOSE *f) +{ + char *reason = NULL; + size_t reason_len = f->reason_len; + size_t max_reason_len = txp_get_mdpl(txp) / 2; + + if (txp->want_conn_close) + return 0; + + /* + * Arbitrarily limit the length of the reason length string to half of the + * MDPL. + */ + if (reason_len > max_reason_len) + reason_len = max_reason_len; + + if (reason_len > 0) { + reason = OPENSSL_memdup(f->reason, reason_len); + if (reason == NULL) + return 0; + } + + txp->conn_close_frame = *f; + txp->conn_close_frame.reason = reason; + txp->conn_close_frame.reason_len = reason_len; + txp->want_conn_close = 1; + return 1; +} + +void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp, + ossl_msg_cb msg_callback, + SSL *msg_callback_ssl) +{ + txp->msg_callback = msg_callback; + txp->msg_callback_ssl = msg_callback_ssl; +} + +void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp, + void *msg_callback_arg) +{ + txp->msg_callback_arg = msg_callback_arg; +} + +QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp, + uint32_t pn_space) +{ + if (pn_space >= QUIC_PN_SPACE_NUM) + return UINT64_MAX; + + return txp->next_pn[pn_space]; +} + +OSSL_TIME ossl_quic_tx_packetiser_get_deadline(OSSL_QUIC_TX_PACKETISER *txp) +{ + /* + * TXP-specific deadline computations which rely on TXP innards. This is in + * turn relied on by the QUIC_CHANNEL code to determine the channel event + * handling deadline. + */ + OSSL_TIME deadline = ossl_time_infinite(); + uint32_t enc_level, pn_space; + + /* + * ACK generation is not CC-gated - packets containing only ACKs are allowed + * to bypass CC. We want to generate ACK frames even if we are currently + * restricted by CC so the peer knows we have received data. The generate + * call will take care of selecting the correct packet archetype. + */ + for (enc_level = QUIC_ENC_LEVEL_INITIAL; + enc_level < QUIC_ENC_LEVEL_NUM; + ++enc_level) + if (ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) { + pn_space = ossl_quic_enc_level_to_pn_space(enc_level); + deadline = ossl_time_min(deadline, + ossl_ackm_get_ack_deadline(txp->args.ackm, pn_space)); + } + + /* When will CC let us send more? */ + if (txp->args.cc_method->get_tx_allowance(txp->args.cc_data) == 0) + deadline = ossl_time_min(deadline, + txp->args.cc_method->get_wakeup_deadline(txp->args.cc_data)); + + return deadline; +} diff --git a/ssl/quic/quic_txpim.c b/ssl/quic/quic_txpim.c new file mode 100644 index 0000000000..04b25ee47a --- /dev/null +++ b/ssl/quic/quic_txpim.c @@ -0,0 +1,229 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_txpim.h" +#include + +typedef struct quic_txpim_pkt_ex_st QUIC_TXPIM_PKT_EX; + +struct quic_txpim_pkt_ex_st { + QUIC_TXPIM_PKT public; + QUIC_TXPIM_PKT_EX *prev, *next; + QUIC_TXPIM_CHUNK *chunks; + size_t num_chunks, alloc_chunks; + unsigned int chunks_need_sort : 1; +}; + +typedef struct quic_txpim_pkt_ex_list { + QUIC_TXPIM_PKT_EX *head, *tail; +} QUIC_TXPIM_PKT_EX_LIST; + +struct quic_txpim_st { + QUIC_TXPIM_PKT_EX_LIST free_list; + size_t in_use; +}; + +#define MAX_ALLOC_CHUNKS 512 + +QUIC_TXPIM *ossl_quic_txpim_new(void) +{ + QUIC_TXPIM *txpim = OPENSSL_zalloc(sizeof(*txpim)); + + if (txpim == NULL) + return NULL; + + return txpim; +} + +static void free_list(QUIC_TXPIM_PKT_EX_LIST *l) +{ + QUIC_TXPIM_PKT_EX *n, *nnext; + + for (n = l->head; n != NULL; n = nnext) { + nnext = n->next; + + OPENSSL_free(n->chunks); + OPENSSL_free(n); + } + + l->head = l->tail = NULL; +} + +void ossl_quic_txpim_free(QUIC_TXPIM *txpim) +{ + if (txpim == NULL) + return; + + assert(txpim->in_use == 0); + free_list(&txpim->free_list); + OPENSSL_free(txpim); +} + +static void list_remove(QUIC_TXPIM_PKT_EX_LIST *l, QUIC_TXPIM_PKT_EX *n) +{ + if (l->head == n) + l->head = n->next; + if (l->tail == n) + l->tail = n->prev; + if (n->prev != NULL) + n->prev->next = n->next; + if (n->next != NULL) + n->next->prev = n->prev; + n->prev = n->next = NULL; +} + +static void list_insert_tail(QUIC_TXPIM_PKT_EX_LIST *l, QUIC_TXPIM_PKT_EX *n) +{ + n->prev = l->tail; + n->next = NULL; + l->tail = n; + if (n->prev != NULL) + n->prev->next = n; + if (l->head == NULL) + l->head = n; +} + +static QUIC_TXPIM_PKT_EX *txpim_get_free(QUIC_TXPIM *txpim) +{ + QUIC_TXPIM_PKT_EX *ex = txpim->free_list.head; + + if (ex != NULL) + return ex; + + ex = OPENSSL_zalloc(sizeof(*ex)); + if (ex == NULL) + return NULL; + + list_insert_tail(&txpim->free_list, ex); + return ex; +} + +static void txpim_clear(QUIC_TXPIM_PKT_EX *ex) +{ + memset(&ex->public.ackm_pkt, 0, sizeof(ex->public.ackm_pkt)); + ossl_quic_txpim_pkt_clear_chunks(&ex->public); + ex->public.retx_head = NULL; + ex->public.fifd = NULL; + ex->public.had_handshake_done_frame = 0; + ex->public.had_max_data_frame = 0; + ex->public.had_max_streams_bidi_frame = 0; + ex->public.had_max_streams_uni_frame = 0; + ex->public.had_ack_frame = 0; + ex->public.had_conn_close = 0; +} + +QUIC_TXPIM_PKT *ossl_quic_txpim_pkt_alloc(QUIC_TXPIM *txpim) +{ + QUIC_TXPIM_PKT_EX *ex = txpim_get_free(txpim); + + if (ex == NULL) + return NULL; + + txpim_clear(ex); + list_remove(&txpim->free_list, ex); + ++txpim->in_use; + return &ex->public; +} + +void ossl_quic_txpim_pkt_release(QUIC_TXPIM *txpim, QUIC_TXPIM_PKT *fpkt) +{ + QUIC_TXPIM_PKT_EX *ex = (QUIC_TXPIM_PKT_EX *)fpkt; + + assert(txpim->in_use > 0); + --txpim->in_use; + list_insert_tail(&txpim->free_list, ex); +} + +void ossl_quic_txpim_pkt_add_cfq_item(QUIC_TXPIM_PKT *fpkt, + QUIC_CFQ_ITEM *item) +{ + item->pkt_next = fpkt->retx_head; + item->pkt_prev = NULL; + fpkt->retx_head = item; +} + +void ossl_quic_txpim_pkt_clear_chunks(QUIC_TXPIM_PKT *fpkt) +{ + QUIC_TXPIM_PKT_EX *ex = (QUIC_TXPIM_PKT_EX *)fpkt; + + ex->num_chunks = 0; +} + +int ossl_quic_txpim_pkt_append_chunk(QUIC_TXPIM_PKT *fpkt, + const QUIC_TXPIM_CHUNK *chunk) +{ + QUIC_TXPIM_PKT_EX *ex = (QUIC_TXPIM_PKT_EX *)fpkt; + QUIC_TXPIM_CHUNK *new_chunk; + size_t new_alloc_chunks = ex->alloc_chunks; + + if (ex->num_chunks == ex->alloc_chunks) { + new_alloc_chunks = (ex->alloc_chunks == 0) ? 4 : ex->alloc_chunks * 8 / 5; + if (new_alloc_chunks > MAX_ALLOC_CHUNKS) + new_alloc_chunks = MAX_ALLOC_CHUNKS; + if (ex->num_chunks == new_alloc_chunks) + return 0; + + new_chunk = OPENSSL_realloc(ex->chunks, + new_alloc_chunks * sizeof(QUIC_TXPIM_CHUNK)); + if (new_chunk == NULL) + return 0; + + ex->chunks = new_chunk; + ex->alloc_chunks = new_alloc_chunks; + } + + ex->chunks[ex->num_chunks++] = *chunk; + ex->chunks_need_sort = 1; + return 1; +} + +static int compare(const void *a, const void *b) +{ + const QUIC_TXPIM_CHUNK *ac = a, *bc = b; + + if (ac->stream_id < bc->stream_id) + return -1; + else if (ac->stream_id > bc->stream_id) + return 1; + + if (ac->start < bc->start) + return -1; + else if (ac->start > bc->start) + return 1; + + return 0; +} + +const QUIC_TXPIM_CHUNK *ossl_quic_txpim_pkt_get_chunks(const QUIC_TXPIM_PKT *fpkt) +{ + QUIC_TXPIM_PKT_EX *ex = (QUIC_TXPIM_PKT_EX *)fpkt; + + if (ex->chunks_need_sort) { + /* + * List of chunks will generally be very small so there is no issue + * simply sorting here. + */ + qsort(ex->chunks, ex->num_chunks, sizeof(QUIC_TXPIM_CHUNK), compare); + ex->chunks_need_sort = 0; + } + + return ex->chunks; +} + +size_t ossl_quic_txpim_pkt_get_num_chunks(const QUIC_TXPIM_PKT *fpkt) +{ + QUIC_TXPIM_PKT_EX *ex = (QUIC_TXPIM_PKT_EX *)fpkt; + + return ex->num_chunks; +} + +size_t ossl_quic_txpim_get_in_use(const QUIC_TXPIM *txpim) +{ + return txpim->in_use; +} diff --git a/ssl/quic/quic_wire.c b/ssl/quic/quic_wire.c new file mode 100644 index 0000000000..425e7efc2e --- /dev/null +++ b/ssl/quic/quic_wire.c @@ -0,0 +1,1078 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/quic_ssl.h" +#include "internal/quic_vlint.h" +#include "internal/quic_wire.h" +#include "internal/quic_error.h" + +OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t) + +int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn) +{ + size_t i; + + for (i = 0; i < ack->num_ack_ranges; ++i) + if (pn >= ack->ack_ranges[i].start + && pn <= ack->ack_ranges[i].end) + return 1; + + return 0; +} + +/* + * QUIC Wire Format Encoding + * ========================= + */ + +int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes) +{ + /* + * PADDING is frame type zero, which as a variable-length integer is + * represented as a single zero byte. As an optimisation, just use memset. + */ + return WPACKET_memset(pkt, 0, num_bytes); +} + +static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type) +{ + return WPACKET_quic_write_vlint(pkt, frame_type); +} + +int ossl_quic_wire_encode_frame_ping(WPACKET *pkt) +{ + return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING); +} + +int ossl_quic_wire_encode_frame_ack(WPACKET *pkt, + uint32_t ack_delay_exponent, + const OSSL_QUIC_FRAME_ACK *ack) +{ + uint64_t frame_type = ack->ecn_present ? OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN + : OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN; + + uint64_t largest_ackd, first_ack_range, ack_delay_enc; + uint64_t i, num_ack_ranges = ack->num_ack_ranges; + OSSL_TIME delay; + + if (num_ack_ranges == 0) + return 0; + + delay = ossl_time_divide(ossl_time_divide(ack->delay_time, OSSL_TIME_US), + (uint64_t)1 << ack_delay_exponent); + ack_delay_enc = ossl_time2ticks(delay); + + largest_ackd = ack->ack_ranges[0].end; + first_ack_range = ack->ack_ranges[0].end - ack->ack_ranges[0].start; + + if (!encode_frame_hdr(pkt, frame_type) + || !WPACKET_quic_write_vlint(pkt, largest_ackd) + || !WPACKET_quic_write_vlint(pkt, ack_delay_enc) + || !WPACKET_quic_write_vlint(pkt, num_ack_ranges - 1) + || !WPACKET_quic_write_vlint(pkt, first_ack_range)) + return 0; + + for (i = 1; i < num_ack_ranges; ++i) { + uint64_t gap, range_len; + + gap = ack->ack_ranges[i - 1].start - ack->ack_ranges[i].end - 2; + range_len = ack->ack_ranges[i].end - ack->ack_ranges[i].start; + + if (!WPACKET_quic_write_vlint(pkt, gap) + || !WPACKET_quic_write_vlint(pkt, range_len)) + return 0; + } + + if (ack->ecn_present) + if (!WPACKET_quic_write_vlint(pkt, ack->ect0) + || !WPACKET_quic_write_vlint(pkt, ack->ect1) + || !WPACKET_quic_write_vlint(pkt, ack->ecnce)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt, + const OSSL_QUIC_FRAME_RESET_STREAM *f) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM) + || !WPACKET_quic_write_vlint(pkt, f->stream_id) + || !WPACKET_quic_write_vlint(pkt, f->app_error_code) + || !WPACKET_quic_write_vlint(pkt, f->final_size)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt, + const OSSL_QUIC_FRAME_STOP_SENDING *f) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING) + || !WPACKET_quic_write_vlint(pkt, f->stream_id) + || !WPACKET_quic_write_vlint(pkt, f->app_error_code)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *pkt, + const OSSL_QUIC_FRAME_CRYPTO *f) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO) + || !WPACKET_quic_write_vlint(pkt, f->offset) + || !WPACKET_quic_write_vlint(pkt, f->len)) + return 0; + + return 1; +} + +size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f) +{ + size_t a, b, c; + + a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_CRYPTO); + b = ossl_quic_vlint_encode_len(f->offset); + c = ossl_quic_vlint_encode_len(f->len); + if (a == 0 || b == 0 || c == 0) + return 0; + + return a + b + c; +} + +void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt, + const OSSL_QUIC_FRAME_CRYPTO *f) +{ + unsigned char *p = NULL; + + if (!ossl_quic_wire_encode_frame_crypto_hdr(pkt, f) + || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */ + || !WPACKET_allocate_bytes(pkt, (size_t)f->len, &p)) + return NULL; + + if (f->data != NULL) + memcpy(p, f->data, (size_t)f->len); + + return p; +} + +int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt, + const unsigned char *token, + size_t token_len) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN) + || !WPACKET_quic_write_vlint(pkt, token_len) + || !WPACKET_memcpy(pkt, token, token_len)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt, + const OSSL_QUIC_FRAME_STREAM *f) +{ + uint64_t frame_type = OSSL_QUIC_FRAME_TYPE_STREAM; + + if (f->offset != 0) + frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_OFF; + if (f->has_explicit_len) + frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_LEN; + if (f->is_fin) + frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_FIN; + + if (!encode_frame_hdr(pkt, frame_type) + || !WPACKET_quic_write_vlint(pkt, f->stream_id)) + return 0; + + if (f->offset != 0 && !WPACKET_quic_write_vlint(pkt, f->offset)) + return 0; + + if (f->has_explicit_len && !WPACKET_quic_write_vlint(pkt, f->len)) + return 0; + + return 1; +} + +size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f) +{ + size_t a, b, c, d; + + a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_STREAM); + b = ossl_quic_vlint_encode_len(f->stream_id); + if (a == 0 || b == 0) + return 0; + + if (f->offset > 0) { + c = ossl_quic_vlint_encode_len(f->offset); + if (c == 0) + return 0; + } else { + c = 0; + } + + if (f->has_explicit_len) { + d = ossl_quic_vlint_encode_len(f->len); + if (d == 0) + return 0; + } else { + d = 0; + } + + return a + b + c + d; +} + +void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt, + const OSSL_QUIC_FRAME_STREAM *f) +{ + + unsigned char *p = NULL; + + if (!ossl_quic_wire_encode_frame_stream_hdr(pkt, f) + || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */) + return NULL; + + if (!WPACKET_allocate_bytes(pkt, (size_t)f->len, &p)) + return NULL; + + if (f->data != NULL) + memcpy(p, f->data, (size_t)f->len); + + return p; +} + +int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt, + uint64_t max_data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA) + || !WPACKET_quic_write_vlint(pkt, max_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt, + uint64_t stream_id, + uint64_t max_data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA) + || !WPACKET_quic_write_vlint(pkt, stream_id) + || !WPACKET_quic_write_vlint(pkt, max_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt, + char is_uni, + uint64_t max_streams) +{ + if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI + : OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI) + || !WPACKET_quic_write_vlint(pkt, max_streams)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt, + uint64_t max_data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED) + || !WPACKET_quic_write_vlint(pkt, max_data)) + return 0; + + return 1; +} + + +int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt, + uint64_t stream_id, + uint64_t max_stream_data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED) + || !WPACKET_quic_write_vlint(pkt, stream_id) + || !WPACKET_quic_write_vlint(pkt, max_stream_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt, + char is_uni, + uint64_t max_streams) +{ + if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI + : OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI) + || !WPACKET_quic_write_vlint(pkt, max_streams)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt, + const OSSL_QUIC_FRAME_NEW_CONN_ID *f) +{ + if (f->conn_id.id_len < 1 + || f->conn_id.id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID) + || !WPACKET_quic_write_vlint(pkt, f->seq_num) + || !WPACKET_quic_write_vlint(pkt, f->retire_prior_to) + || !WPACKET_put_bytes_u8(pkt, f->conn_id.id_len) + || !WPACKET_memcpy(pkt, f->conn_id.id, f->conn_id.id_len) + || !WPACKET_memcpy(pkt, f->stateless_reset.token, + sizeof(f->stateless_reset.token))) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt, + uint64_t seq_num) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID) + || !WPACKET_quic_write_vlint(pkt, seq_num)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt, + uint64_t data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE) + || !WPACKET_put_bytes_u64(pkt, data)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt, + uint64_t data) +{ + if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE) + || !WPACKET_put_bytes_u64(pkt, data)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt, + const OSSL_QUIC_FRAME_CONN_CLOSE *f) +{ + if (!encode_frame_hdr(pkt, f->is_app ? OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP + : OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT) + || !WPACKET_quic_write_vlint(pkt, f->error_code)) + return 0; + + /* + * RFC 9000 s. 19.19: The application-specific variant of CONNECTION_CLOSE + * (type 0x1d) does not include this field. + */ + if (!f->is_app && !WPACKET_quic_write_vlint(pkt, f->frame_type)) + return 0; + + if (!WPACKET_quic_write_vlint(pkt, f->reason_len) + || !WPACKET_memcpy(pkt, f->reason, f->reason_len)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt) +{ + return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE); +} + +unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt, + uint64_t id, + const unsigned char *value, + size_t value_len) +{ + unsigned char *b = NULL; + + if (!WPACKET_quic_write_vlint(pkt, id) + || !WPACKET_quic_write_vlint(pkt, value_len)) + return NULL; + + if (value_len == 0) + b = WPACKET_get_curr(pkt); + else if (!WPACKET_allocate_bytes(pkt, value_len, (unsigned char **)&b)) + return NULL; + + if (value != NULL) + memcpy(b, value, value_len); + + return b; +} + +int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt, + uint64_t id, + uint64_t value) +{ + if (!WPACKET_quic_write_vlint(pkt, id) + || !WPACKET_quic_write_vlint(pkt, ossl_quic_vlint_encode_len(value)) + || !WPACKET_quic_write_vlint(pkt, value)) + return 0; + + return 1; +} + +int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt, + uint64_t id, + const QUIC_CONN_ID *cid) +{ + if (cid->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if (ossl_quic_wire_encode_transport_param_bytes(wpkt, id, + cid->id, + cid->id_len) == NULL) + return 0; + + return 1; +} + +/* + * QUIC Wire Format Decoding + * ========================= + */ +int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type, + int *was_minimal) +{ + return PACKET_peek_quic_vlint_ex(pkt, type, was_minimal); +} + +int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type) +{ + return PACKET_get_quic_vlint(pkt, type); +} + +static int expect_frame_header_mask(PACKET *pkt, + uint64_t expected_frame_type, + uint64_t mask_bits, + uint64_t *actual_frame_type) +{ + uint64_t actual_frame_type_; + + if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type_) + || (actual_frame_type_ & ~mask_bits) != expected_frame_type) + return 0; + + if (actual_frame_type != NULL) + *actual_frame_type = actual_frame_type_; + + return 1; +} + +static int expect_frame_header(PACKET *pkt, uint64_t expected_frame_type) +{ + uint64_t actual_frame_type; + + if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type) + || actual_frame_type != expected_frame_type) + return 0; + + return 1; +} + +int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *orig_pkt, + uint64_t *total_ranges) +{ + PACKET pkt = *orig_pkt; + uint64_t ack_range_count, i; + + if (!expect_frame_header_mask(&pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN, + 1, NULL) + || !PACKET_skip_quic_vlint(&pkt) + || !PACKET_skip_quic_vlint(&pkt) + || !PACKET_get_quic_vlint(&pkt, &ack_range_count)) + return 0; + + /* + * Ensure the specified number of ack ranges listed in the ACK frame header + * actually are available in the frame data. This naturally bounds the + * number of ACK ranges which can be requested by the MDPL, and therefore by + * the MTU. This ensures we do not allocate memory for an excessive number + * of ACK ranges. + */ + for (i = 0; i < ack_range_count; ++i) + if (!PACKET_skip_quic_vlint(&pkt) + || !PACKET_skip_quic_vlint(&pkt)) + return 0; + + /* (cannot overflow because QUIC vlints can only encode up to 2**62-1) */ + *total_ranges = ack_range_count + 1; + return 1; +} + +int ossl_quic_wire_decode_frame_ack(PACKET *pkt, + uint32_t ack_delay_exponent, + OSSL_QUIC_FRAME_ACK *ack, + uint64_t *total_ranges) { + uint64_t frame_type, largest_ackd, ack_delay_raw; + uint64_t ack_range_count, first_ack_range, start, end, i; + + /* This call matches both ACK_WITHOUT_ECN and ACK_WITH_ECN. */ + if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN, + 1, &frame_type) + || !PACKET_get_quic_vlint(pkt, &largest_ackd) + || !PACKET_get_quic_vlint(pkt, &ack_delay_raw) + || !PACKET_get_quic_vlint(pkt, &ack_range_count) + || !PACKET_get_quic_vlint(pkt, &first_ack_range)) + return 0; + + if (first_ack_range > largest_ackd) + return 0; + + if (ack_range_count > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */) + return 0; + + start = largest_ackd - first_ack_range; + + if (ack != NULL) { + int err = 0; + ack->delay_time + = ossl_time_multiply(ossl_ticks2time(OSSL_TIME_US), + safe_mul_uint64_t(ack_delay_raw, + (uint64_t)1 << ack_delay_exponent, + &err)); + if (err) + ack->delay_time = ossl_time_infinite(); + + if (ack->num_ack_ranges > 0) { + ack->ack_ranges[0].end = largest_ackd; + ack->ack_ranges[0].start = start; + } + } + + for (i = 0; i < ack_range_count; ++i) { + uint64_t gap, len; + + if (!PACKET_get_quic_vlint(pkt, &gap) + || !PACKET_get_quic_vlint(pkt, &len)) + return 0; + + end = start - gap - 2; + if (start < gap + 2 || len > end) + return 0; + + if (ack != NULL && i + 1 < ack->num_ack_ranges) { + ack->ack_ranges[i + 1].start = start = end - len; + ack->ack_ranges[i + 1].end = end; + } + } + + if (ack != NULL && ack_range_count + 1 < ack->num_ack_ranges) + ack->num_ack_ranges = (size_t)ack_range_count + 1; + + if (total_ranges != NULL) + *total_ranges = ack_range_count + 1; + + if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) { + uint64_t ect0, ect1, ecnce; + + if (!PACKET_get_quic_vlint(pkt, &ect0) + || !PACKET_get_quic_vlint(pkt, &ect1) + || !PACKET_get_quic_vlint(pkt, &ecnce)) + return 0; + + if (ack != NULL) { + ack->ect0 = ect0; + ack->ect1 = ect1; + ack->ecnce = ecnce; + ack->ecn_present = 1; + } + } else if (ack != NULL) { + ack->ecn_present = 0; + } + + return 1; +} + +int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt, + OSSL_QUIC_FRAME_RESET_STREAM *f) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM) + || !PACKET_get_quic_vlint(pkt, &f->stream_id) + || !PACKET_get_quic_vlint(pkt, &f->app_error_code) + || !PACKET_get_quic_vlint(pkt, &f->final_size)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt, + OSSL_QUIC_FRAME_STOP_SENDING *f) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING) + || !PACKET_get_quic_vlint(pkt, &f->stream_id) + || !PACKET_get_quic_vlint(pkt, &f->app_error_code)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_crypto(PACKET *pkt, + int nodata, + OSSL_QUIC_FRAME_CRYPTO *f) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO) + || !PACKET_get_quic_vlint(pkt, &f->offset) + || !PACKET_get_quic_vlint(pkt, &f->len) + || f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */) + return 0; + + if (f->offset + f->len > (((uint64_t)1) << 62) - 1) + /* RFC 9000 s. 19.6 */ + return 0; + + if (nodata) { + f->data = NULL; + } else { + if (PACKET_remaining(pkt) < f->len) + return 0; + + f->data = PACKET_data(pkt); + + if (!PACKET_forward(pkt, (size_t)f->len)) + return 0; + } + + return 1; +} + +int ossl_quic_wire_decode_frame_new_token(PACKET *pkt, + const unsigned char **token, + size_t *token_len) +{ + uint64_t token_len_; + + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN) + || !PACKET_get_quic_vlint(pkt, &token_len_)) + return 0; + + if (token_len_ > SIZE_MAX) + return 0; + + *token = PACKET_data(pkt); + *token_len = (size_t)token_len_; + + if (!PACKET_forward(pkt, (size_t)token_len_)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_stream(PACKET *pkt, + int nodata, + OSSL_QUIC_FRAME_STREAM *f) +{ + uint64_t frame_type; + + /* This call matches all STREAM values (low 3 bits are masked). */ + if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAM, + OSSL_QUIC_FRAME_FLAG_STREAM_MASK, + &frame_type) + || !PACKET_get_quic_vlint(pkt, &f->stream_id)) + return 0; + + if ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_OFF) != 0) { + if (!PACKET_get_quic_vlint(pkt, &f->offset)) + return 0; + } else { + f->offset = 0; + } + + f->has_explicit_len = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_LEN) != 0); + f->is_fin = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_FIN) != 0); + + if (f->has_explicit_len) { + if (!PACKET_get_quic_vlint(pkt, &f->len)) + return 0; + } else { + if (nodata) + f->len = 0; + else + f->len = PACKET_remaining(pkt); + } + + /* + * RFC 9000 s. 19.8: "The largest offset delivered on a stream -- the sum of + * the offset and data length -- cannot exceed 2**62 - 1, as it is not + * possible to provide flow control credit for that data." + */ + if (f->offset + f->len > (((uint64_t)1) << 62) - 1) + return 0; + + if (nodata) { + f->data = NULL; + } else { + f->data = PACKET_data(pkt); + + if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */ + || !PACKET_forward(pkt, (size_t)f->len)) + return 0; + } + + return 1; +} + +int ossl_quic_wire_decode_frame_max_data(PACKET *pkt, + uint64_t *max_data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA) + || !PACKET_get_quic_vlint(pkt, max_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt, + uint64_t *stream_id, + uint64_t *max_stream_data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA) + || !PACKET_get_quic_vlint(pkt, stream_id) + || !PACKET_get_quic_vlint(pkt, max_stream_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt, + uint64_t *max_streams) +{ + /* This call matches both MAX_STREAMS_BIDI and MAX_STREAMS_UNI. */ + if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI, + 1, NULL) + || !PACKET_get_quic_vlint(pkt, max_streams)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt, + uint64_t *max_data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED) + || !PACKET_get_quic_vlint(pkt, max_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt, + uint64_t *stream_id, + uint64_t *max_stream_data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED) + || !PACKET_get_quic_vlint(pkt, stream_id) + || !PACKET_get_quic_vlint(pkt, max_stream_data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt, + uint64_t *max_streams) +{ + /* This call matches both STREAMS_BLOCKED_BIDI and STREAMS_BLOCKED_UNI. */ + if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI, + 1, NULL) + || !PACKET_get_quic_vlint(pkt, max_streams)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt, + OSSL_QUIC_FRAME_NEW_CONN_ID *f) +{ + unsigned int len; + + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID) + || !PACKET_get_quic_vlint(pkt, &f->seq_num) + || !PACKET_get_quic_vlint(pkt, &f->retire_prior_to) + || f->seq_num < f->retire_prior_to + || !PACKET_get_1(pkt, &len) + || len < 1 + || len > QUIC_MAX_CONN_ID_LEN) + return 0; + + f->conn_id.id_len = (unsigned char)len; + if (!PACKET_copy_bytes(pkt, f->conn_id.id, len)) + return 0; + + /* Clear unused bytes to allow consistent memcmp. */ + if (len < QUIC_MAX_CONN_ID_LEN) + memset(f->conn_id.id + len, 0, QUIC_MAX_CONN_ID_LEN - len); + + if (!PACKET_copy_bytes(pkt, f->stateless_reset.token, + sizeof(f->stateless_reset.token))) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt, + uint64_t *seq_num) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID) + || !PACKET_get_quic_vlint(pkt, seq_num)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt, + uint64_t *data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE) + || !PACKET_get_net_8(pkt, data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_path_response(PACKET *pkt, + uint64_t *data) +{ + if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE) + || !PACKET_get_net_8(pkt, data)) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt, + OSSL_QUIC_FRAME_CONN_CLOSE *f) +{ + uint64_t frame_type, reason_len; + + /* This call matches both CONN_CLOSE_TRANSPORT and CONN_CLOSE_APP. */ + if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT, + 1, &frame_type) + || !PACKET_get_quic_vlint(pkt, &f->error_code)) + return 0; + + f->is_app = ((frame_type & 1) != 0); + + if (!f->is_app) { + if (!PACKET_get_quic_vlint(pkt, &f->frame_type)) + return 0; + } else { + f->frame_type = 0; + } + + if (!PACKET_get_quic_vlint(pkt, &reason_len) + || reason_len > SIZE_MAX) + return 0; + + if (!PACKET_get_bytes(pkt, (const unsigned char **)&f->reason, + (size_t)reason_len)) + return 0; + + f->reason_len = (size_t)reason_len; + return 1; +} + +size_t ossl_quic_wire_decode_padding(PACKET *pkt) +{ + const unsigned char *start = PACKET_data(pkt), *end = PACKET_end(pkt), + *p = start; + + while (p < end && *p == 0) + ++p; + + if (!PACKET_forward(pkt, p - start)) + return 0; + + return p - start; +} + +int ossl_quic_wire_decode_frame_ping(PACKET *pkt) +{ + return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING); +} + +int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt) +{ + return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE); +} + +int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id) +{ + return PACKET_peek_quic_vlint(pkt, id); +} + +const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt, + uint64_t *id, + size_t *len) +{ + uint64_t len_; + const unsigned char *b = NULL; + uint64_t id_; + + if (!PACKET_get_quic_vlint(pkt, &id_) + || !PACKET_get_quic_vlint(pkt, &len_)) + return NULL; + + if (len_ > SIZE_MAX + || !PACKET_get_bytes(pkt, (const unsigned char **)&b, (size_t)len_)) + return NULL; + + *len = (size_t)len_; + if (id != NULL) + *id = id_; + return b; +} + +int ossl_quic_wire_decode_transport_param_int(PACKET *pkt, + uint64_t *id, + uint64_t *value) +{ + PACKET sub; + + sub.curr = ossl_quic_wire_decode_transport_param_bytes(pkt, + id, &sub.remaining); + if (sub.curr == NULL) + return 0; + + if (!PACKET_get_quic_vlint(&sub, value)) + return 0; + + if (PACKET_remaining(&sub) > 0) + return 0; + + return 1; +} + +int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt, + uint64_t *id, + QUIC_CONN_ID *cid) +{ + const unsigned char *body; + size_t len = 0; + + body = ossl_quic_wire_decode_transport_param_bytes(pkt, id, &len); + if (body == NULL || len > QUIC_MAX_CONN_ID_LEN) + return 0; + + cid->id_len = (unsigned char)len; + memcpy(cid->id, body, cid->id_len); + return 1; +} + +int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt, + QUIC_PREFERRED_ADDR *p) +{ + const unsigned char *body; + uint64_t id; + size_t len = 0; + PACKET pkt2; + unsigned int ipv4_port, ipv6_port, cidl; + + body = ossl_quic_wire_decode_transport_param_bytes(pkt, &id, &len); + if (body == NULL + || len < QUIC_MIN_ENCODED_PREFERRED_ADDR_LEN + || len > QUIC_MAX_ENCODED_PREFERRED_ADDR_LEN + || id != QUIC_TPARAM_PREFERRED_ADDR) + return 0; + + if (!PACKET_buf_init(&pkt2, body, len)) + return 0; + + if (!PACKET_copy_bytes(&pkt2, p->ipv4, sizeof(p->ipv4)) + || !PACKET_get_net_2(&pkt2, &ipv4_port) + || !PACKET_copy_bytes(&pkt2, p->ipv6, sizeof(p->ipv6)) + || !PACKET_get_net_2(&pkt2, &ipv6_port) + || !PACKET_get_1(&pkt2, &cidl) + || cidl > QUIC_MAX_CONN_ID_LEN + || !PACKET_copy_bytes(&pkt2, p->cid.id, cidl) + || !PACKET_copy_bytes(&pkt2, p->stateless_reset.token, + sizeof(p->stateless_reset.token))) + return 0; + + p->ipv4_port = (uint16_t)ipv4_port; + p->ipv6_port = (uint16_t)ipv6_port; + p->cid.id_len = (unsigned char)cidl; + return 1; +} + +const char * +ossl_quic_frame_type_to_string(uint64_t frame_type) +{ + switch (frame_type) { +#define X(name) case OSSL_QUIC_FRAME_TYPE_##name: return #name; + X(PADDING) + X(PING) + X(ACK_WITHOUT_ECN) + X(ACK_WITH_ECN) + X(RESET_STREAM) + X(STOP_SENDING) + X(CRYPTO) + X(NEW_TOKEN) + X(MAX_DATA) + X(MAX_STREAM_DATA) + X(MAX_STREAMS_BIDI) + X(MAX_STREAMS_UNI) + X(DATA_BLOCKED) + X(STREAM_DATA_BLOCKED) + X(STREAMS_BLOCKED_BIDI) + X(STREAMS_BLOCKED_UNI) + X(NEW_CONN_ID) + X(RETIRE_CONN_ID) + X(PATH_CHALLENGE) + X(PATH_RESPONSE) + X(CONN_CLOSE_TRANSPORT) + X(CONN_CLOSE_APP) + X(HANDSHAKE_DONE) + X(STREAM) + X(STREAM_FIN) + X(STREAM_LEN) + X(STREAM_LEN_FIN) + X(STREAM_OFF) + X(STREAM_OFF_FIN) + X(STREAM_OFF_LEN) + X(STREAM_OFF_LEN_FIN) +#undef X + default: + return NULL; + } +} + +const char *ossl_quic_err_to_string(uint64_t error_code) +{ + switch (error_code) { +#define X(name) case QUIC_ERR_##name: return #name; + X(NO_ERROR) + X(INTERNAL_ERROR) + X(CONNECTION_REFUSED) + X(FLOW_CONTROL_ERROR) + X(STREAM_LIMIT_ERROR) + X(STREAM_STATE_ERROR) + X(FINAL_SIZE_ERROR) + X(FRAME_ENCODING_ERROR) + X(TRANSPORT_PARAMETER_ERROR) + X(CONNECTION_ID_LIMIT_ERROR) + X(PROTOCOL_VIOLATION) + X(INVALID_TOKEN) + X(APPLICATION_ERROR) + X(CRYPTO_BUFFER_EXCEEDED) + X(KEY_UPDATE_ERROR) + X(AEAD_LIMIT_REACHED) + X(NO_VIABLE_PATH) +#undef X + default: + return NULL; + } +} diff --git a/ssl/quic/quic_wire_pkt.c b/ssl/quic/quic_wire_pkt.c new file mode 100644 index 0000000000..acb926ad38 --- /dev/null +++ b/ssl/quic/quic_wire_pkt.c @@ -0,0 +1,945 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/common.h" +#include "internal/quic_wire_pkt.h" + +int ossl_quic_hdr_protector_init(QUIC_HDR_PROTECTOR *hpr, + OSSL_LIB_CTX *libctx, + const char *propq, + uint32_t cipher_id, + const unsigned char *quic_hp_key, + size_t quic_hp_key_len) +{ + const char *cipher_name = NULL; + + switch (cipher_id) { + case QUIC_HDR_PROT_CIPHER_AES_128: + cipher_name = "AES-128-ECB"; + break; + case QUIC_HDR_PROT_CIPHER_AES_256: + cipher_name = "AES-256-ECB"; + break; + case QUIC_HDR_PROT_CIPHER_CHACHA: + cipher_name = "ChaCha20"; + break; + default: + ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED); + return 0; + } + + hpr->cipher_ctx = EVP_CIPHER_CTX_new(); + if (hpr->cipher_ctx == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + hpr->cipher = EVP_CIPHER_fetch(libctx, cipher_name, propq); + if (hpr->cipher == NULL + || quic_hp_key_len != (size_t)EVP_CIPHER_get_key_length(hpr->cipher)) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + if (!EVP_CipherInit_ex(hpr->cipher_ctx, hpr->cipher, NULL, + quic_hp_key, NULL, 1)) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + hpr->libctx = libctx; + hpr->propq = propq; + hpr->cipher_id = cipher_id; + return 1; + +err: + ossl_quic_hdr_protector_cleanup(hpr); + return 0; +} + +void ossl_quic_hdr_protector_cleanup(QUIC_HDR_PROTECTOR *hpr) +{ + EVP_CIPHER_CTX_free(hpr->cipher_ctx); + hpr->cipher_ctx = NULL; + + EVP_CIPHER_free(hpr->cipher); + hpr->cipher = NULL; +} + +static int hdr_generate_mask(QUIC_HDR_PROTECTOR *hpr, + const unsigned char *sample, size_t sample_len, + unsigned char *mask) +{ + int l = 0; + unsigned char dst[16]; + static const unsigned char zeroes[5] = {0}; + size_t i; + + if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_128 + || hpr->cipher_id == QUIC_HDR_PROT_CIPHER_AES_256) { + if (sample_len < 16) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, NULL, 1) + || !EVP_CipherUpdate(hpr->cipher_ctx, dst, &l, sample, 16)) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + for (i = 0; i < 5; ++i) + mask[i] = dst[i]; + } else if (hpr->cipher_id == QUIC_HDR_PROT_CIPHER_CHACHA) { + if (sample_len < 16) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (!EVP_CipherInit_ex(hpr->cipher_ctx, NULL, NULL, NULL, sample, 1) + || !EVP_CipherUpdate(hpr->cipher_ctx, mask, &l, + zeroes, sizeof(zeroes))) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + } else { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + assert(0); + return 0; + } + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* No matter what we did above we use the same mask in fuzzing mode */ + memset(mask, 0, 5); +#endif + + return 1; +} + +int ossl_quic_hdr_protector_decrypt(QUIC_HDR_PROTECTOR *hpr, + QUIC_PKT_HDR_PTRS *ptrs) +{ + return ossl_quic_hdr_protector_decrypt_fields(hpr, + ptrs->raw_sample, + ptrs->raw_sample_len, + ptrs->raw_start, + ptrs->raw_pn); +} + +int ossl_quic_hdr_protector_decrypt_fields(QUIC_HDR_PROTECTOR *hpr, + const unsigned char *sample, + size_t sample_len, + unsigned char *first_byte, + unsigned char *pn_bytes) +{ + unsigned char mask[5], pn_len, i; + + if (!hdr_generate_mask(hpr, sample, sample_len, mask)) + return 0; + + *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f); + pn_len = (*first_byte & 0x3) + 1; + + for (i = 0; i < pn_len; ++i) + pn_bytes[i] ^= mask[i + 1]; + + return 1; +} + +int ossl_quic_hdr_protector_encrypt(QUIC_HDR_PROTECTOR *hpr, + QUIC_PKT_HDR_PTRS *ptrs) +{ + return ossl_quic_hdr_protector_encrypt_fields(hpr, + ptrs->raw_sample, + ptrs->raw_sample_len, + ptrs->raw_start, + ptrs->raw_pn); +} + +int ossl_quic_hdr_protector_encrypt_fields(QUIC_HDR_PROTECTOR *hpr, + const unsigned char *sample, + size_t sample_len, + unsigned char *first_byte, + unsigned char *pn_bytes) +{ + unsigned char mask[5], pn_len, i; + + if (!hdr_generate_mask(hpr, sample, sample_len, mask)) + return 0; + + pn_len = (*first_byte & 0x3) + 1; + for (i = 0; i < pn_len; ++i) + pn_bytes[i] ^= mask[i + 1]; + + *first_byte ^= mask[0] & ((*first_byte & 0x80) != 0 ? 0xf : 0x1f); + return 1; +} + +int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt, + size_t short_conn_id_len, + int partial, + int nodata, + QUIC_PKT_HDR *hdr, + QUIC_PKT_HDR_PTRS *ptrs) +{ + unsigned int b0; + unsigned char *pn = NULL; + size_t l = PACKET_remaining(pkt); + + if (ptrs != NULL) { + ptrs->raw_start = (unsigned char *)PACKET_data(pkt); + ptrs->raw_sample = NULL; + ptrs->raw_sample_len = 0; + ptrs->raw_pn = NULL; + } + + if (l < QUIC_MIN_VALID_PKT_LEN + || !PACKET_get_1(pkt, &b0)) + return 0; + + hdr->partial = partial; + hdr->unused = 0; + hdr->reserved = 0; + + if ((b0 & 0x80) == 0) { + /* Short header. */ + if (short_conn_id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if ((b0 & 0x40) == 0 /* fixed bit not set? */ + || l < QUIC_MIN_VALID_PKT_LEN_CRYPTO) + return 0; + + hdr->type = QUIC_PKT_TYPE_1RTT; + hdr->fixed = 1; + hdr->spin_bit = (b0 & 0x20) != 0; + if (partial) { + hdr->key_phase = 0; /* protected, zero for now */ + hdr->pn_len = 0; /* protected, zero for now */ + hdr->reserved = 0; /* protected, zero for now */ + } else { + hdr->key_phase = (b0 & 0x04) != 0; + hdr->pn_len = (b0 & 0x03) + 1; + hdr->reserved = (b0 & 0x18) >> 3; + } + + /* Copy destination connection ID field to header structure. */ + if (!PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, short_conn_id_len)) + return 0; + + hdr->dst_conn_id.id_len = (unsigned char)short_conn_id_len; + + /* + * Skip over the PN. If this is a partial decode, the PN length field + * currently has header protection applied. Thus we do not know the + * length of the PN but we are allowed to assume it is 4 bytes long at + * this stage. + */ + memset(hdr->pn, 0, sizeof(hdr->pn)); + pn = (unsigned char *)PACKET_data(pkt); + if (partial) { + if (!PACKET_forward(pkt, sizeof(hdr->pn))) + return 0; + } else { + if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len)) + return 0; + } + + /* Fields not used in short-header packets. */ + hdr->version = 0; + hdr->src_conn_id.id_len = 0; + hdr->token = NULL; + hdr->token_len = 0; + + /* + * Short-header packets always come last in a datagram, the length + * is the remainder of the buffer. + */ + hdr->len = PACKET_remaining(pkt); + hdr->data = PACKET_data(pkt); + + /* + * Skip over payload. Since this is a short header packet, which cannot + * be followed by any other kind of packet, this advances us to the end + * of the datagram. + */ + if (!PACKET_forward(pkt, hdr->len)) + return 0; + } else { + /* Long header. */ + unsigned long version; + unsigned int dst_conn_id_len, src_conn_id_len, raw_type; + + if (!PACKET_get_net_4(pkt, &version)) + return 0; + + /* + * All QUIC packets must have the fixed bit set, except exceptionally + * for Version Negotiation packets. + */ + if (version != 0 && (b0 & 0x40) == 0) + return 0; + + if (!PACKET_get_1(pkt, &dst_conn_id_len) + || dst_conn_id_len > QUIC_MAX_CONN_ID_LEN + || !PACKET_copy_bytes(pkt, hdr->dst_conn_id.id, dst_conn_id_len) + || !PACKET_get_1(pkt, &src_conn_id_len) + || src_conn_id_len > QUIC_MAX_CONN_ID_LEN + || !PACKET_copy_bytes(pkt, hdr->src_conn_id.id, src_conn_id_len)) + return 0; + + hdr->version = (uint32_t)version; + hdr->dst_conn_id.id_len = (unsigned char)dst_conn_id_len; + hdr->src_conn_id.id_len = (unsigned char)src_conn_id_len; + + if (version == 0) { + /* + * Version negotiation packet. Version negotiation packets are + * identified by a version field of 0 and the type bits in the first + * byte are ignored (they may take any value, and we ignore them). + */ + hdr->type = QUIC_PKT_TYPE_VERSION_NEG; + hdr->fixed = (b0 & 0x40) != 0; + + hdr->data = PACKET_data(pkt); + hdr->len = PACKET_remaining(pkt); + + /* + * Version negotiation packets must contain an array of u32s, so it + * is invalid for their payload length to not be divisible by 4. + */ + if ((hdr->len % 4) != 0) + return 0; + + /* Version negotiation packets are always fully decoded. */ + hdr->partial = 0; + + /* Fields not used in version negotiation packets. */ + hdr->pn_len = 0; + hdr->spin_bit = 0; + hdr->key_phase = 0; + hdr->token = NULL; + hdr->token_len = 0; + memset(hdr->pn, 0, sizeof(hdr->pn)); + + if (!PACKET_forward(pkt, hdr->len)) + return 0; + } else if (version != QUIC_VERSION_1) { + /* Unknown version, do not decode. */ + return 0; + } else { + if (l < QUIC_MIN_VALID_PKT_LEN_CRYPTO) + return 0; + + /* Get long packet type and decode to QUIC_PKT_TYPE_*. */ + raw_type = ((b0 >> 4) & 0x3); + + switch (raw_type) { + case 0: + hdr->type = QUIC_PKT_TYPE_INITIAL; + break; + case 1: + hdr->type = QUIC_PKT_TYPE_0RTT; + break; + case 2: + hdr->type = QUIC_PKT_TYPE_HANDSHAKE; + break; + case 3: + hdr->type = QUIC_PKT_TYPE_RETRY; + break; + } + + hdr->pn_len = 0; + hdr->fixed = 1; + + /* Fields not used in long-header packets. */ + hdr->spin_bit = 0; + hdr->key_phase = 0; + + if (hdr->type == QUIC_PKT_TYPE_INITIAL) { + /* Initial packet. */ + uint64_t token_len; + + if (!PACKET_get_quic_vlint(pkt, &token_len) + || token_len > SIZE_MAX + || !PACKET_get_bytes(pkt, &hdr->token, (size_t)token_len)) + return 0; + + hdr->token_len = (size_t)token_len; + if (token_len == 0) + hdr->token = NULL; + } else { + hdr->token = NULL; + hdr->token_len = 0; + } + + if (hdr->type == QUIC_PKT_TYPE_RETRY) { + /* Retry packet. */ + hdr->data = PACKET_data(pkt); + hdr->len = PACKET_remaining(pkt); + + /* Retry packets are always fully decoded. */ + hdr->partial = 0; + + /* Unused bits in Retry header. */ + hdr->unused = b0 & 0x0f; + + /* Fields not used in Retry packets. */ + memset(hdr->pn, 0, sizeof(hdr->pn)); + + if (!PACKET_forward(pkt, hdr->len)) + return 0; + } else { + /* Initial, 0-RTT or Handshake packet. */ + uint64_t len; + + hdr->pn_len = partial ? 0 : ((b0 & 0x03) + 1); + hdr->reserved = partial ? 0 : ((b0 & 0x0C) >> 2); + + if (!PACKET_get_quic_vlint(pkt, &len) + || len < sizeof(hdr->pn)) + return 0; + + if (!nodata && len > PACKET_remaining(pkt)) + return 0; + + /* + * Skip over the PN. If this is a partial decode, the PN length + * field currently has header protection applied. Thus we do not + * know the length of the PN but we are allowed to assume it is + * 4 bytes long at this stage. + */ + pn = (unsigned char *)PACKET_data(pkt); + memset(hdr->pn, 0, sizeof(hdr->pn)); + if (partial) { + if (!PACKET_forward(pkt, sizeof(hdr->pn))) + return 0; + + hdr->len = (size_t)(len - sizeof(hdr->pn)); + } else { + if (!PACKET_copy_bytes(pkt, hdr->pn, hdr->pn_len)) + return 0; + + hdr->len = (size_t)(len - hdr->pn_len); + } + + if (nodata) { + hdr->data = NULL; + } else { + hdr->data = PACKET_data(pkt); + + /* Skip over packet body. */ + if (!PACKET_forward(pkt, hdr->len)) + return 0; + } + } + } + } + + if (ptrs != NULL) { + ptrs->raw_pn = pn; + if (pn != NULL) { + ptrs->raw_sample = pn + 4; + ptrs->raw_sample_len = PACKET_end(pkt) - ptrs->raw_sample; + } + } + + return 1; +} + +int ossl_quic_wire_encode_pkt_hdr(WPACKET *pkt, + size_t short_conn_id_len, + const QUIC_PKT_HDR *hdr, + QUIC_PKT_HDR_PTRS *ptrs) +{ + unsigned char b0; + size_t off_start, off_sample, off_pn; + unsigned char *start = WPACKET_get_curr(pkt); + + if (!WPACKET_get_total_written(pkt, &off_start)) + return 0; + + if (ptrs != NULL) { + /* ptrs would not be stable on non-static WPACKET */ + if (!ossl_assert(pkt->staticbuf != NULL)) + return 0; + ptrs->raw_start = NULL; + ptrs->raw_sample = NULL; + ptrs->raw_sample_len = 0; + ptrs->raw_pn = 0; + } + + /* Cannot serialize a partial header, or one whose DCID length is wrong. */ + if (hdr->partial + || (hdr->type == QUIC_PKT_TYPE_1RTT + && hdr->dst_conn_id.id_len != short_conn_id_len)) + return 0; + + if (hdr->type == QUIC_PKT_TYPE_1RTT) { + /* Short header. */ + + /* + * Cannot serialize a header whose DCID length is wrong, or with an + * invalid PN length. + */ + if (hdr->dst_conn_id.id_len != short_conn_id_len + || short_conn_id_len > QUIC_MAX_CONN_ID_LEN + || hdr->pn_len < 1 || hdr->pn_len > 4) + return 0; + + b0 = (hdr->spin_bit << 5) + | (hdr->key_phase << 2) + | (hdr->pn_len - 1) + | (hdr->reserved << 3) + | 0x40; /* fixed bit */ + + if (!WPACKET_put_bytes_u8(pkt, b0) + || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, short_conn_id_len) + || !WPACKET_get_total_written(pkt, &off_pn) + || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len)) + return 0; + } else { + /* Long header. */ + unsigned int raw_type; + + if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN + || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if (ossl_quic_pkt_type_has_pn(hdr->type) + && (hdr->pn_len < 1 || hdr->pn_len > 4)) + return 0; + + switch (hdr->type) { + case QUIC_PKT_TYPE_VERSION_NEG: + if (hdr->version != 0) + return 0; + + /* Version negotiation packets use zero for the type bits */ + raw_type = 0; + break; + + case QUIC_PKT_TYPE_INITIAL: raw_type = 0; break; + case QUIC_PKT_TYPE_0RTT: raw_type = 1; break; + case QUIC_PKT_TYPE_HANDSHAKE: raw_type = 2; break; + case QUIC_PKT_TYPE_RETRY: raw_type = 3; break; + default: + return 0; + } + + b0 = (raw_type << 4) | 0x80; /* long */ + if (hdr->type != QUIC_PKT_TYPE_VERSION_NEG || hdr->fixed) + b0 |= 0x40; /* fixed */ + if (ossl_quic_pkt_type_has_pn(hdr->type)) { + b0 |= hdr->pn_len - 1; + b0 |= (hdr->reserved << 2); + } + if (hdr->type == QUIC_PKT_TYPE_RETRY) + b0 |= hdr->unused; + + if (!WPACKET_put_bytes_u8(pkt, b0) + || !WPACKET_put_bytes_u32(pkt, hdr->version) + || !WPACKET_put_bytes_u8(pkt, hdr->dst_conn_id.id_len) + || !WPACKET_memcpy(pkt, hdr->dst_conn_id.id, + hdr->dst_conn_id.id_len) + || !WPACKET_put_bytes_u8(pkt, hdr->src_conn_id.id_len) + || !WPACKET_memcpy(pkt, hdr->src_conn_id.id, + hdr->src_conn_id.id_len)) + return 0; + + if (hdr->type == QUIC_PKT_TYPE_VERSION_NEG + || hdr->type == QUIC_PKT_TYPE_RETRY) { + if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL)) + return 0; + + return 1; + } + + if (hdr->type == QUIC_PKT_TYPE_INITIAL) { + if (!WPACKET_quic_write_vlint(pkt, hdr->token_len) + || !WPACKET_memcpy(pkt, hdr->token, hdr->token_len)) + return 0; + } + + if (!WPACKET_quic_write_vlint(pkt, hdr->len + hdr->pn_len) + || !WPACKET_get_total_written(pkt, &off_pn) + || !WPACKET_memcpy(pkt, hdr->pn, hdr->pn_len)) + return 0; + } + + if (hdr->len > 0 && !WPACKET_reserve_bytes(pkt, hdr->len, NULL)) + return 0; + + off_sample = off_pn + 4; + + if (ptrs != NULL) { + ptrs->raw_start = start; + ptrs->raw_sample = start + (off_sample - off_start); + ptrs->raw_sample_len + = WPACKET_get_curr(pkt) + hdr->len - ptrs->raw_sample; + ptrs->raw_pn = start + (off_pn - off_start); + } + + return 1; +} + +int ossl_quic_wire_get_encoded_pkt_hdr_len(size_t short_conn_id_len, + const QUIC_PKT_HDR *hdr) +{ + size_t len = 0, enclen; + + /* Cannot serialize a partial header, or one whose DCID length is wrong. */ + if (hdr->partial + || (hdr->type == QUIC_PKT_TYPE_1RTT + && hdr->dst_conn_id.id_len != short_conn_id_len)) + return 0; + + if (hdr->type == QUIC_PKT_TYPE_1RTT) { + /* Short header. */ + + /* + * Cannot serialize a header whose DCID length is wrong, or with an + * invalid PN length. + */ + if (hdr->dst_conn_id.id_len != short_conn_id_len + || short_conn_id_len > QUIC_MAX_CONN_ID_LEN + || hdr->pn_len < 1 || hdr->pn_len > 4) + return 0; + + return 1 + short_conn_id_len + hdr->pn_len; + } else { + /* Long header. */ + if (hdr->dst_conn_id.id_len > QUIC_MAX_CONN_ID_LEN + || hdr->src_conn_id.id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + len += 1 /* Initial byte */ + 4 /* Version */ + + 1 + hdr->dst_conn_id.id_len /* DCID Len, DCID */ + + 1 + hdr->src_conn_id.id_len /* SCID Len, SCID */ + ; + + if (ossl_quic_pkt_type_has_pn(hdr->type)) { + if (hdr->pn_len < 1 || hdr->pn_len > 4) + return 0; + + len += hdr->pn_len; + } + + if (hdr->type == QUIC_PKT_TYPE_INITIAL) { + enclen = ossl_quic_vlint_encode_len(hdr->token_len); + if (!enclen) + return 0; + + len += enclen + hdr->token_len; + } + + if (!ossl_quic_pkt_type_must_be_last(hdr->type)) { + enclen = ossl_quic_vlint_encode_len(hdr->len + hdr->pn_len); + if (!enclen) + return 0; + + len += enclen; + } + + return len; + } +} + +int ossl_quic_wire_get_pkt_hdr_dst_conn_id(const unsigned char *buf, + size_t buf_len, + size_t short_conn_id_len, + QUIC_CONN_ID *dst_conn_id) +{ + unsigned char b0; + size_t blen; + + if (buf_len < QUIC_MIN_VALID_PKT_LEN + || short_conn_id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + b0 = buf[0]; + if ((b0 & 0x80) != 0) { + /* + * Long header. We need 6 bytes (initial byte, 4 version bytes, DCID + * length byte to begin with). This is covered by the buf_len test + * above. + */ + + /* + * If the version field is non-zero (meaning that this is not a Version + * Negotiation packet), the fixed bit must be set. + */ + if ((buf[1] || buf[2] || buf[3] || buf[4]) && (b0 & 0x40) == 0) + return 0; + + blen = (size_t)buf[5]; /* DCID Length */ + if (blen > QUIC_MAX_CONN_ID_LEN + || buf_len < QUIC_MIN_VALID_PKT_LEN + blen) + return 0; + + dst_conn_id->id_len = (unsigned char)blen; + memcpy(dst_conn_id->id, buf + 6, blen); + return 1; + } else { + /* Short header. */ + if ((b0 & 0x40) == 0) + /* Fixed bit not set, not a valid QUIC packet header. */ + return 0; + + if (buf_len < QUIC_MIN_VALID_PKT_LEN_CRYPTO + short_conn_id_len) + return 0; + + dst_conn_id->id_len = (unsigned char)short_conn_id_len; + memcpy(dst_conn_id->id, buf + 1, short_conn_id_len); + return 1; + } +} + +int ossl_quic_wire_decode_pkt_hdr_pn(const unsigned char *enc_pn, + size_t enc_pn_len, + QUIC_PN largest_pn, + QUIC_PN *res_pn) +{ + int64_t expected_pn, truncated_pn, candidate_pn, pn_win, pn_hwin, pn_mask; + + switch (enc_pn_len) { + case 1: + truncated_pn = enc_pn[0]; + break; + case 2: + truncated_pn = ((QUIC_PN)enc_pn[0] << 8) + | (QUIC_PN)enc_pn[1]; + break; + case 3: + truncated_pn = ((QUIC_PN)enc_pn[0] << 16) + | ((QUIC_PN)enc_pn[1] << 8) + | (QUIC_PN)enc_pn[2]; + break; + case 4: + truncated_pn = ((QUIC_PN)enc_pn[0] << 24) + | ((QUIC_PN)enc_pn[1] << 16) + | ((QUIC_PN)enc_pn[2] << 8) + | (QUIC_PN)enc_pn[3]; + break; + default: + return 0; + } + + /* Implemented as per RFC 9000 Section A.3. */ + expected_pn = largest_pn + 1; + pn_win = ((int64_t)1) << (enc_pn_len * 8); + pn_hwin = pn_win / 2; + pn_mask = pn_win - 1; + candidate_pn = (expected_pn & ~pn_mask) | truncated_pn; + if (candidate_pn <= expected_pn - pn_hwin + && candidate_pn < (((int64_t)1) << 62) - pn_win) + *res_pn = candidate_pn + pn_win; + else if (candidate_pn > expected_pn + pn_hwin + && candidate_pn >= pn_win) + *res_pn = candidate_pn - pn_win; + else + *res_pn = candidate_pn; + return 1; +} + +/* From RFC 9000 Section A.2. Simplified implementation. */ +int ossl_quic_wire_determine_pn_len(QUIC_PN pn, + QUIC_PN largest_acked) +{ + uint64_t num_unacked + = (largest_acked == QUIC_PN_INVALID) ? pn + 1 : pn - largest_acked; + + /* + * num_unacked \in [ 0, 2** 7] -> 1 byte + * num_unacked \in (2** 7, 2**15] -> 2 bytes + * num_unacked \in (2**15, 2**23] -> 3 bytes + * num_unacked \in (2**23, ] -> 4 bytes + */ + + if (num_unacked <= (1U<<7)) return 1; + if (num_unacked <= (1U<<15)) return 2; + if (num_unacked <= (1U<<23)) return 3; + return 4; +} + +int ossl_quic_wire_encode_pkt_hdr_pn(QUIC_PN pn, + unsigned char *enc_pn, + size_t enc_pn_len) +{ + switch (enc_pn_len) { + case 1: + enc_pn[0] = (unsigned char)pn; + break; + case 2: + enc_pn[1] = (unsigned char)pn; + enc_pn[0] = (unsigned char)(pn >> 8); + break; + case 3: + enc_pn[2] = (unsigned char)pn; + enc_pn[1] = (unsigned char)(pn >> 8); + enc_pn[0] = (unsigned char)(pn >> 16); + break; + case 4: + enc_pn[3] = (unsigned char)pn; + enc_pn[2] = (unsigned char)(pn >> 8); + enc_pn[1] = (unsigned char)(pn >> 16); + enc_pn[0] = (unsigned char)(pn >> 24); + break; + default: + return 0; + } + + return 1; +} + +int ossl_quic_validate_retry_integrity_tag(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_PKT_HDR *hdr, + const QUIC_CONN_ID *client_initial_dcid) +{ + unsigned char expected_tag[QUIC_RETRY_INTEGRITY_TAG_LEN]; + const unsigned char *actual_tag; + + if (hdr == NULL || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN) + return 0; + + if (!ossl_quic_calculate_retry_integrity_tag(libctx, propq, + hdr, client_initial_dcid, + expected_tag)) + return 0; + + actual_tag = hdr->data + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN; + + return !CRYPTO_memcmp(expected_tag, actual_tag, + QUIC_RETRY_INTEGRITY_TAG_LEN); +} + +/* RFC 9001 s. 5.8 */ +static const unsigned char retry_integrity_key[] = { + 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, + 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e +}; + +static const unsigned char retry_integrity_nonce[] = { + 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, + 0x23, 0x98, 0x25, 0xbb +}; + +int ossl_quic_calculate_retry_integrity_tag(OSSL_LIB_CTX *libctx, + const char *propq, + const QUIC_PKT_HDR *hdr, + const QUIC_CONN_ID *client_initial_dcid, + unsigned char *tag) +{ + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *cctx = NULL; + int ok = 0, l = 0, l2 = 0, wpkt_valid = 0; + WPACKET wpkt; + /* Worst case length of the Retry Psuedo-Packet header is 68 bytes. */ + unsigned char buf[128]; + QUIC_PKT_HDR hdr2; + size_t hdr_enc_len = 0; + + if (hdr->type != QUIC_PKT_TYPE_RETRY || hdr->version == 0 + || hdr->len < QUIC_RETRY_INTEGRITY_TAG_LEN + || hdr->data == NULL + || client_initial_dcid == NULL || tag == NULL + || client_initial_dcid->id_len > QUIC_MAX_CONN_ID_LEN) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + /* + * Do not reserve packet body in WPACKET. Retry packet header + * does not contain a Length field so this does not affect + * the serialized packet header. + */ + hdr2 = *hdr; + hdr2.len = 0; + + /* Assemble retry psuedo-packet. */ + if (!WPACKET_init_static_len(&wpkt, buf, sizeof(buf), 0)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + wpkt_valid = 1; + + /* Prepend original DCID to the packet. */ + if (!WPACKET_put_bytes_u8(&wpkt, client_initial_dcid->id_len) + || !WPACKET_memcpy(&wpkt, client_initial_dcid->id, + client_initial_dcid->id_len)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + /* Encode main retry header. */ + if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr2.dst_conn_id.id_len, + &hdr2, NULL)) + goto err; + + if (!WPACKET_get_total_written(&wpkt, &hdr_enc_len)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + return 0; + } + + /* Create and initialise cipher context. */ + /* TODO(QUIC FUTURE): Cipher fetch caching. */ + if ((cipher = EVP_CIPHER_fetch(libctx, "AES-128-GCM", propq)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + if (!EVP_CipherInit_ex(cctx, cipher, NULL, + retry_integrity_key, retry_integrity_nonce, /*enc=*/1)) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + goto err; + } + + /* Feed packet header as AAD data. */ + if (EVP_CipherUpdate(cctx, NULL, &l, buf, hdr_enc_len) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + /* Feed packet body as AAD data. */ + if (EVP_CipherUpdate(cctx, NULL, &l, hdr->data, + hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + /* Finalise and get tag. */ + if (EVP_CipherFinal_ex(cctx, NULL, &l2) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + if (EVP_CIPHER_CTX_ctrl(cctx, EVP_CTRL_AEAD_GET_TAG, + QUIC_RETRY_INTEGRITY_TAG_LEN, + tag) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + ok = 1; +err: + EVP_CIPHER_free(cipher); + EVP_CIPHER_CTX_free(cctx); + if (wpkt_valid) + WPACKET_finish(&wpkt); + + return ok; +} diff --git a/ssl/quic/uint_set.c b/ssl/quic/uint_set.c new file mode 100644 index 0000000000..faca906003 --- /dev/null +++ b/ssl/quic/uint_set.c @@ -0,0 +1,332 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/uint_set.h" +#include "internal/common.h" +#include + +/* + * uint64_t Integer Sets + * ===================== + * + * This data structure supports the following operations: + * + * Insert Range: Adds an inclusive range of integers [start, end] + * to the set. Equivalent to Insert for each number + * in the range. + * + * Remove Range: Removes an inclusive range of integers [start, end] + * from the set. Not all of the range need already be in + * the set, but any part of the range in the set is removed. + * + * Query: Is an integer in the data structure? + * + * The data structure can be iterated. + * + * For greater efficiency in tracking large numbers of contiguous integers, we + * track integer ranges rather than individual integers. The data structure + * manages a list of integer ranges [[start, end]...]. Internally this is + * implemented as a doubly linked sorted list of range structures, which are + * automatically split and merged as necessary. + * + * This data structure requires O(n) traversal of the list for insertion, + * removal and query when we are not adding/removing ranges which are near the + * beginning or end of the set of ranges. For the applications for which this + * data structure is used (e.g. QUIC PN tracking for ACK generation), it is + * expected that the number of integer ranges needed at any given time will + * generally be small and that most operations will be close to the beginning or + * end of the range. + * + * Invariant: The data structure is always sorted in ascending order by value. + * + * Invariant: No two adjacent ranges ever 'border' one another (have no + * numerical gap between them) as the data structure always ensures + * such ranges are merged. + * + * Invariant: No two ranges ever overlap. + * + * Invariant: No range [a, b] ever has a > b. + * + * Invariant: Since ranges are represented using inclusive bounds, no range + * item inside the data structure can represent a span of zero + * integers. + */ +void ossl_uint_set_init(UINT_SET *s) +{ + ossl_list_uint_set_init(s); +} + +void ossl_uint_set_destroy(UINT_SET *s) +{ + UINT_SET_ITEM *x, *xnext; + + for (x = ossl_list_uint_set_head(s); x != NULL; x = xnext) { + xnext = ossl_list_uint_set_next(x); + OPENSSL_free(x); + } +} + +/* Possible merge of x, prev(x) */ +static void uint_set_merge_adjacent(UINT_SET *s, UINT_SET_ITEM *x) +{ + UINT_SET_ITEM *xprev = ossl_list_uint_set_prev(x); + + if (xprev == NULL) + return; + + if (x->range.start - 1 != xprev->range.end) + return; + + x->range.start = xprev->range.start; + ossl_list_uint_set_remove(s, xprev); + OPENSSL_free(xprev); +} + +static uint64_t u64_min(uint64_t x, uint64_t y) +{ + return x < y ? x : y; +} + +static uint64_t u64_max(uint64_t x, uint64_t y) +{ + return x > y ? x : y; +} + +/* + * Returns 1 if there exists an integer x which falls within both ranges a and + * b. + */ +static int uint_range_overlaps(const UINT_RANGE *a, + const UINT_RANGE *b) +{ + return u64_min(a->end, b->end) + >= u64_max(a->start, b->start); +} + +static UINT_SET_ITEM *create_set_item(uint64_t start, uint64_t end) +{ + UINT_SET_ITEM *x = OPENSSL_malloc(sizeof(UINT_SET_ITEM)); + + if (x == NULL) + return NULL; + + ossl_list_uint_set_init_elem(x); + x->range.start = start; + x->range.end = end; + return x; +} + +int ossl_uint_set_insert(UINT_SET *s, const UINT_RANGE *range) +{ + UINT_SET_ITEM *x, *xnext, *z, *zprev, *f; + uint64_t start = range->start, end = range->end; + + if (!ossl_assert(start <= end)) + return 0; + + if (ossl_list_uint_set_is_empty(s)) { + /* Nothing in the set yet, so just add this range. */ + x = create_set_item(start, end); + if (x == NULL) + return 0; + ossl_list_uint_set_insert_head(s, x); + return 1; + } + + z = ossl_list_uint_set_tail(s); + if (start > z->range.end) { + /* + * Range is after the latest range in the set, so append. + * + * Note: The case where the range is before the earliest range in the + * set is handled as a degenerate case of the final case below. See + * optimization note (*) below. + */ + if (z->range.end + 1 == start) { + z->range.end = end; + return 1; + } + + x = create_set_item(start, end); + if (x == NULL) + return 0; + ossl_list_uint_set_insert_tail(s, x); + return 1; + } + + f = ossl_list_uint_set_head(s); + if (start <= f->range.start && end >= z->range.end) { + /* + * New range dwarfs all ranges in our set. + * + * Free everything except the first range in the set, which we scavenge + * and reuse. + */ + x = ossl_list_uint_set_head(s); + x->range.start = start; + x->range.end = end; + for (x = ossl_list_uint_set_next(x); x != NULL; x = xnext) { + xnext = ossl_list_uint_set_next(x); + ossl_list_uint_set_remove(s, x); + } + return 1; + } + + /* + * Walk backwards since we will most often be inserting at the end. As an + * optimization, test the head node first and skip iterating over the + * entire list if we are inserting at the start. The assumption is that + * insertion at the start and end of the space will be the most common + * operations. (*) + */ + z = end < f->range.start ? f : z; + + for (; z != NULL; z = zprev) { + zprev = ossl_list_uint_set_prev(z); + + /* An existing range dwarfs our new range (optimisation). */ + if (z->range.start <= start && z->range.end >= end) + return 1; + + if (uint_range_overlaps(&z->range, range)) { + /* + * Our new range overlaps an existing range, or possibly several + * existing ranges. + */ + UINT_SET_ITEM *ovend = z; + + ovend->range.end = u64_max(end, z->range.end); + + /* Get earliest overlapping range. */ + while (zprev != NULL && uint_range_overlaps(&zprev->range, range)) { + z = zprev; + zprev = ossl_list_uint_set_prev(z); + } + + ovend->range.start = u64_min(start, z->range.start); + + /* Replace sequence of nodes z..ovend with updated ovend only. */ + while (z != ovend) { + z = ossl_list_uint_set_next(x = z); + ossl_list_uint_set_remove(s, x); + OPENSSL_free(x); + } + break; + } else if (end < z->range.start + && (zprev == NULL || start > zprev->range.end)) { + if (z->range.start == end + 1) { + /* We can extend the following range backwards. */ + z->range.start = start; + + /* + * If this closes a gap we now need to merge + * consecutive nodes. + */ + uint_set_merge_adjacent(s, z); + } else if (zprev != NULL && zprev->range.end + 1 == start) { + /* We can extend the preceding range forwards. */ + zprev->range.end = end; + + /* + * If this closes a gap we now need to merge + * consecutive nodes. + */ + uint_set_merge_adjacent(s, z); + } else { + /* + * The new interval is between intervals without overlapping or + * touching them, so insert between, preserving sort. + */ + x = create_set_item(start, end); + if (x == NULL) + return 0; + ossl_list_uint_set_insert_before(s, z, x); + } + break; + } + } + + return 1; +} + +int ossl_uint_set_remove(UINT_SET *s, const UINT_RANGE *range) +{ + UINT_SET_ITEM *z, *zprev, *y; + uint64_t start = range->start, end = range->end; + + if (!ossl_assert(start <= end)) + return 0; + + /* Walk backwards since we will most often be removing at the end. */ + for (z = ossl_list_uint_set_tail(s); z != NULL; z = zprev) { + zprev = ossl_list_uint_set_prev(z); + + if (start > z->range.end) + /* No overlapping ranges can exist beyond this point, so stop. */ + break; + + if (start <= z->range.start && end >= z->range.end) { + /* + * The range being removed dwarfs this range, so it should be + * removed. + */ + ossl_list_uint_set_remove(s, z); + OPENSSL_free(z); + } else if (start <= z->range.start && end >= z->range.start) { + /* + * The range being removed includes start of this range, but does + * not cover the entire range (as this would be caught by the case + * above). Shorten the range. + */ + assert(end < z->range.end); + z->range.start = end + 1; + } else if (end >= z->range.end) { + /* + * The range being removed includes the end of this range, but does + * not cover the entire range (as this would be caught by the case + * above). Shorten the range. We can also stop iterating. + */ + assert(start > z->range.start); + assert(start > 0); + z->range.end = start - 1; + break; + } else if (start > z->range.start && end < z->range.end) { + /* + * The range being removed falls entirely in this range, so cut it + * into two. Cases where a zero-length range would be created are + * handled by the above cases. + */ + y = create_set_item(end + 1, z->range.end); + ossl_list_uint_set_insert_after(s, z, y); + z->range.end = start - 1; + break; + } else { + /* Assert no partial overlap; all cases should be covered above. */ + assert(!uint_range_overlaps(&z->range, range)); + } + } + + return 1; +} + +int ossl_uint_set_query(const UINT_SET *s, uint64_t v) +{ + UINT_SET_ITEM *x; + + if (ossl_list_uint_set_is_empty(s)) + return 0; + + for (x = ossl_list_uint_set_tail(s); x != NULL; x = ossl_list_uint_set_prev(x)) + if (x->range.start <= v && x->range.end >= v) + return 1; + else if (x->range.end < v) + return 0; + + return 0; +} diff --git a/ssl/record/README.md b/ssl/record/README.md deleted file mode 100644 index 263f257c84..0000000000 --- a/ssl/record/README.md +++ /dev/null @@ -1,73 +0,0 @@ -Record Layer Design -=================== - -This file provides some guidance on the thinking behind the design of the -record layer code to aid future maintenance. - -The record layer is divided into a number of components. At the time of writing -there are four: SSL3_RECORD, SSL3_BUFFER, DLTS1_BITMAP and RECORD_LAYER. Each -of these components is defined by: -1) A struct definition of the same name as the component -2) A set of source files that define the functions for that component -3) A set of accessor macros - -All struct definitions are in record.h. The functions and macros are either -defined in record.h or record_local.h dependent on whether they are intended to -be private to the record layer, or whether they form part of the API to the rest -of libssl. - -The source files map to components as follows: - - dtls1_bitmap.c -> DTLS1_BITMAP component - ssl3_buffer.c -> SSL3_BUFFER component - ssl3_record.c -> SSL3_RECORD component - rec_layer_s3.c, rec_layer_d1.c -> RECORD_LAYER component - -The RECORD_LAYER component is a facade pattern, i.e. it provides a simplified -interface to the record layer for the rest of libssl. The other 3 components are -entirely private to the record layer and therefore should never be accessed -directly by libssl. - -Any component can directly access its own members - they are private to that -component, e.g. ssl3_buffer.c can access members of the SSL3_BUFFER struct -without using a macro. No component can directly access the members of another -component, e.g. ssl3_buffer cannot reach inside the RECORD_LAYER component to -directly access its members. Instead components use accessor macros, so if code -in ssl3_buffer.c wants to access the members of the RECORD_LAYER it uses the -RECORD_LAYER_* macros. - -Conceptually it looks like this: - - libssl - | - -------------------------|-----record.h------------------------------------ - | - _______V______________ - | | - | RECORD_LAYER | - | | - | rec_layer_s3.c | - | ^ | - | _________|__________ | - || || - || DTLS1_RECORD_LAYER || - || || - || rec_layer_d1.c || - ||____________________|| - |______________________| - record_local.h ^ ^ ^ - _________________| | |_________________ - | | | - _____V_________ ______V________ _______V________ - | | | | | | - | SSL3_BUFFER | | SSL3_RECORD | | DTLS1_BITMAP | - | |--->| | | | - | ssl3_buffer.c | | ssl3_record.c | | dtls1_bitmap.c | - |_______________| |_______________| |________________| - -The two RECORD_LAYER source files build on each other, i.e. -the main one is rec_layer_s3.c which provides the core SSL/TLS layer. The second -one is rec_layer_d1.c which builds off of the SSL/TLS code to provide DTLS -specific capabilities. It uses some DTLS specific RECORD_LAYER component members -which should only be accessed from rec_layer_d1.c. These are held in the -DTLS1_RECORD_LAYER struct. diff --git a/ssl/record/build.info b/ssl/record/build.info new file mode 100644 index 0000000000..9703d169d6 --- /dev/null +++ b/ssl/record/build.info @@ -0,0 +1,17 @@ +SUBDIRS=methods + +#Needed for the multiblock code in rec_layer_s3.c +IF[{- !$disabled{asm} -}] + $AESDEF_x86=AES_ASM + $AESDEF_x86_64=AES_ASM + + IF[$AESDEF_{- $target{asm_arch} -}] + $AESDEF=$AESDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +SOURCE[../../libssl]=\ + rec_layer_s3.c rec_layer_d1.c + +DEFINE[../../libssl]=$AESDEF + diff --git a/ssl/record/dtls1_bitmap.c b/ssl/record/dtls1_bitmap.c deleted file mode 100644 index 4733a62a96..0000000000 --- a/ssl/record/dtls1_bitmap.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "../ssl_local.h" -#include "record_local.h" - -/* mod 128 saturating subtract of two 64-bit values in big-endian order */ -static int satsub64be(const unsigned char *v1, const unsigned char *v2) -{ - int64_t ret; - uint64_t l1, l2; - - n2l8(v1, l1); - n2l8(v2, l2); - - ret = l1 - l2; - - /* We do not permit wrap-around */ - if (l1 > l2 && ret < 0) - return 128; - else if (l2 > l1 && ret > 0) - return -128; - - if (ret > 128) - return 128; - else if (ret < -128) - return -128; - else - return (int)ret; -} - -int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->rlayer.read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); - return 1; /* this record in new */ - } - shift = -cmp; - if (shift >= sizeof(bitmap->map) * 8) - return 0; /* stale, outside the window */ - else if (bitmap->map & (1UL << shift)) - return 0; /* record previously received */ - - SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); - return 1; -} - -void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer); - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - shift = cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map <<= shift, bitmap->map |= 1UL; - else - bitmap->map = 1UL; - memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE); - } else { - shift = -cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map |= 1UL << shift; - } -} diff --git a/ssl/record/methods/build.info b/ssl/record/methods/build.info new file mode 100644 index 0000000000..8b1af5dd5d --- /dev/null +++ b/ssl/record/methods/build.info @@ -0,0 +1,23 @@ +$KTLSSRC= +IF[{- !$disabled{ktls} -}] + $KTLSSRC=ktls_meth.c +ENDIF + +SOURCE[../../../libssl]=\ + tls_common.c ssl3_meth.c tls1_meth.c tls13_meth.c tlsany_meth.c \ + dtls_meth.c tls_multib.c $KTLSSRC + +# For shared builds we need to include the sources needed in providers +# (ssl3_cbc.c) in libssl as well. +IF[{- !$disabled{'deprecated-3.0'} -}] + SHARED_SOURCE[../../../libssl]=ssl3_cbc.c +ENDIF + +SOURCE[../../../providers/libdefault.a ../../../providers/libfips.a]=ssl3_cbc.c + +# For shared builds we need to include the sources needed in providers +# (tls_pad.c) in libssl as well. +SHARED_SOURCE[../../../libssl]=tls_pad.c + +SOURCE[../../../providers/libcommon.a]=tls_pad.c + diff --git a/ssl/record/methods/dtls_meth.c b/ssl/record/methods/dtls_meth.c new file mode 100644 index 0000000000..258dbd3b14 --- /dev/null +++ b/ssl/record/methods/dtls_meth.c @@ -0,0 +1,802 @@ +/* + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int satsub64be(const unsigned char *v1, const unsigned char *v2) +{ + int64_t ret; + uint64_t l1, l2; + + n2l8(v1, l1); + n2l8(v2, l2); + + ret = l1 - l2; + + /* We do not permit wrap-around */ + if (l1 > l2 && ret < 0) + return 128; + else if (l2 > l1 && ret > 0) + return -128; + + if (ret > 128) + return 128; + else if (ret < -128) + return -128; + else + return (int)ret; +} + +static int dtls_record_replay_check(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = rl->sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + ossl_tls_rl_record_set_seq_num(&rl->rrec[0], seq); + return 1; /* this record in new */ + } + shift = -cmp; + if (shift >= sizeof(bitmap->map) * 8) + return 0; /* stale, outside the window */ + else if (bitmap->map & ((uint64_t)1 << shift)) + return 0; /* record previously received */ + + ossl_tls_rl_record_set_seq_num(&rl->rrec[0], seq); + return 1; +} + +static void dtls_record_bitmap_update(OSSL_RECORD_LAYER *rl, + DTLS_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = rl->sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + shift = cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map <<= shift, bitmap->map |= 1UL; + else + bitmap->map = 1UL; + memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE); + } else { + shift = -cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map |= (uint64_t)1 << shift; + } +} + +static DTLS_BITMAP *dtls_get_bitmap(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rr, + unsigned int *is_next_epoch) +{ + *is_next_epoch = 0; + + /* In current epoch, accept HM, CCS, DATA, & ALERT */ + if (rr->epoch == rl->epoch) + return &rl->bitmap; + + /* + * We can only handle messages from the next epoch if we have already + * processed all of the unprocessed records from the previous epoch + */ + else if (rr->epoch == (unsigned long)(rl->epoch + 1) + && rl->unprocessed_rcds.epoch != rl->epoch) { + *is_next_epoch = 1; + return &rl->next_bitmap; + } + + return NULL; +} + +static void dtls_set_in_init(OSSL_RECORD_LAYER *rl, int in_init) +{ + rl->in_init = in_init; +} + +static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) +{ + int i; + int enc_err; + TLS_RL_RECORD *rr; + int imac_size; + size_t mac_size = 0; + unsigned char md[EVP_MAX_MD_SIZE]; + SSL_MAC_BUF macbuf = { NULL, 0 }; + int ret = 0; + + rr = &rl->rrec[0]; + + /* + * At this point, rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length, + * and we have that many bytes in rl->packet + */ + rr->input = &(rl->packet[DTLS1_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 'rl->packet' data into 'rr'. rr->input + * points at rr->length bytes, which need to be copied into rr->data by + * either the decryption or by the decompression. When the data is 'copied' + * into the rr->data buffer, rr->input will be pointed at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length + * bytes of encrypted compressed stuff. + */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + return 0; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + rr->orig_len = rr->length; + + if (rl->md_ctx != NULL) { + const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(rl->md_ctx); + + if (tmpmd != NULL) { + imac_size = EVP_MD_get_size(tmpmd); + if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + mac_size = (size_t)imac_size; + } + } + + if (rl->use_etm && rl->md_ctx != NULL) { + unsigned char *mac; + + if (rr->orig_len < mac_size) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); + return 0; + } + rr->length -= mac_size; + mac = rr->data + rr->length; + i = rl->funcs->mac(rl, rr, md, 0 /* not send */); + if (i == 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) { + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + return 0; + } + /* + * We've handled the mac now - there is no MAC inside the encrypted + * record + */ + mac_size = 0; + } + + /* + * Set a mark around the packet decryption attempt. This is DTLS, so + * bad packets are just ignored, and we don't want to leave stray + * errors in the queue from processing bogus junk that we ignored. + */ + ERR_set_mark(); + enc_err = rl->funcs->cipher(rl, rr, 1, 0, &macbuf, mac_size); + + /*- + * enc_err is: + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or ETM decryption failed. + * 1: Success or MTE decryption failed (MAC will be randomised) + */ + if (enc_err == 0) { + ERR_pop_to_mark(); + if (rl->alert != SSL_AD_NO_ALERT) { + /* RLAYERfatal() already called */ + goto end; + } + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + rl->packet_length = 0; + goto end; + } + ERR_clear_last_mark(); + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "dec %zd\n", rr->length); + BIO_dump_indent(trc_out, rr->data, rr->length, 4); + } OSSL_TRACE_END(TLS); + + /* r->length is now the compressed data plus mac */ + if (!rl->use_etm + && (rl->enc_ctx != NULL) + && (EVP_MD_CTX_get0_md(rl->md_ctx) != NULL)) { + /* rl->md_ctx != NULL => mac_size != -1 */ + + i = rl->funcs->mac(rl, rr, md, 0 /* not send */); + if (i == 0 || macbuf.mac == NULL + || CRYPTO_memcmp(md, macbuf.mac, mac_size) != 0) + enc_err = 0; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = 0; + } + + if (enc_err == 0) { + /* decryption failed, silently discard message */ + rr->length = 0; + rl->packet_length = 0; + goto end; + } + + /* r->length is now just compressed */ + if (rl->compctx != NULL) { + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_COMPRESSED_LENGTH_TOO_LONG); + goto end; + } + if (!tls_do_uncompress(rl, rr)) { + RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION); + goto end; + } + } + + /* + * Check if the received packet overflows the current Max Fragment + * Length setting. + */ + if (rr->length > rl->max_frag_len) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + goto end; + } + + rr->off = 0; + /*- + * So at this point the following is true + * ssl->s3.rrec.type is the type of record + * ssl->s3.rrec.length == number of bytes in record + * ssl->s3.rrec.off == offset to first valid byte + * ssl->s3.rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + rl->packet_length = 0; + + /* Mark receipt of record. */ + dtls_record_bitmap_update(rl, bitmap); + + ret = 1; + end: + if (macbuf.alloced) + OPENSSL_free(macbuf.mac); + return ret; +} + +static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, record_pqueue *queue, + unsigned char *priority) +{ + DTLS_RLAYER_RECORD_DATA *rdata; + pitem *item; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + rdata = OPENSSL_malloc(sizeof(*rdata)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) { + OPENSSL_free(rdata); + pitem_free(item); + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } + + rdata->packet = rl->packet; + rdata->packet_length = rl->packet_length; + memcpy(&(rdata->rbuf), &rl->rbuf, sizeof(TLS_BUFFER)); + memcpy(&(rdata->rrec), &rl->rrec[0], sizeof(TLS_RL_RECORD)); + + item->data = rdata; + + rl->packet = NULL; + rl->packet_length = 0; + memset(&rl->rbuf, 0, sizeof(TLS_BUFFER)); + memset(&rl->rrec[0], 0, sizeof(rl->rrec[0])); + + if (!tls_setup_read_buffer(rl)) { + /* RLAYERfatal() already called */ + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + return -1; + } + + if (pqueue_insert(queue->q, item) == NULL) { + /* Must be a duplicate so ignore it */ + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + } + + return 1; +} + +/* copy buffered record into OSSL_RECORD_LAYER structure */ +static int dtls_copy_rlayer_record(OSSL_RECORD_LAYER *rl, pitem *item) +{ + DTLS_RLAYER_RECORD_DATA *rdata; + + rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; + + ossl_tls_buffer_release(&rl->rbuf); + + rl->packet = rdata->packet; + rl->packet_length = rdata->packet_length; + memcpy(&rl->rbuf, &(rdata->rbuf), sizeof(TLS_BUFFER)); + memcpy(&rl->rrec[0], &(rdata->rrec), sizeof(TLS_RL_RECORD)); + + /* Set proper sequence number for mac calculation */ + memcpy(&(rl->sequence[2]), &(rdata->packet[5]), 6); + + return 1; +} + +static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl, + record_pqueue *queue) +{ + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + dtls_copy_rlayer_record(rl, item); + + OPENSSL_free(item->data); + pitem_free(item); + + return 1; + } + + return 0; +} + +/*- + * Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3.rrec.type - is the type of record + * ssl->s3.rrec.data - data + * ssl->s3.rrec.length - number of bytes + */ +int dtls_get_more_records(OSSL_RECORD_LAYER *rl) +{ + int ssl_major, ssl_minor; + int rret; + size_t more, n; + TLS_RL_RECORD *rr; + unsigned char *p = NULL; + DTLS_BITMAP *bitmap; + unsigned int is_next_epoch; + + rl->num_recs = 0; + rl->curr_rec = 0; + rl->num_released = 0; + + rr = rl->rrec; + + if (rl->rbuf.buf == NULL) { + if (!tls_setup_read_buffer(rl)) { + /* RLAYERfatal() already called */ + return OSSL_RECORD_RETURN_FATAL; + } + } + + again: + /* if we're renegotiating, then there may be buffered records */ + if (dtls_retrieve_rlayer_buffered_record(rl, &rl->processed_rcds)) { + rl->num_recs = 1; + return OSSL_RECORD_RETURN_SUCCESS; + } + + /* get something from the wire */ + + /* check if we have the header */ + if ((rl->rstate != SSL_ST_READ_BODY) || + (rl->packet_length < DTLS1_RT_HEADER_LENGTH)) { + rret = rl->funcs->read_n(rl, DTLS1_RT_HEADER_LENGTH, + TLS_BUFFER_get_len(&rl->rbuf), 0, 1, &n); + /* read timeout is handled by dtls1_read_bytes */ + if (rret < OSSL_RECORD_RETURN_SUCCESS) { + /* RLAYERfatal() already called if appropriate */ + return rret; /* error or non-blocking */ + } + + /* this packet contained a partial record, dump it */ + if (rl->packet_length != DTLS1_RT_HEADER_LENGTH) { + rl->packet_length = 0; + goto again; + } + + rl->rstate = SSL_ST_READ_BODY; + + p = rl->packet; + + /* Pull apart the header into the DTLS1_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + rr->rec_version = (ssl_major << 8) | ssl_minor; + + /* sequence number is 64 bits, with top 2 bytes = epoch */ + n2s(p, rr->epoch); + + memcpy(&(rl->sequence[2]), p, 6); + p += 6; + + n2s(p, rr->length); + + if (rl->msg_callback != NULL) + rl->msg_callback(0, rr->rec_version, SSL3_RT_HEADER, rl->packet, DTLS1_RT_HEADER_LENGTH, + rl->cbarg); + + /* + * Lets check the version. We tolerate alerts that don't have the exact + * version number (e.g. because of protocol version errors) + */ + if (!rl->is_first_record && rr->type != SSL3_RT_ALERT) { + if (rr->rec_version != rl->version) { + /* unexpected version, silently discard */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } + } + + if (ssl_major != + (rl->version == DTLS_ANY_VERSION ? DTLS1_VERSION_MAJOR + : rl->version >> 8)) { + /* wrong version, silently discard record */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + /* record too long, silently discard it */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + /* + * If received packet overflows maximum possible fragment length then + * silently discard it + */ + if (rr->length > rl->max_frag_len + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) { + /* record too long, silently discard it */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + /* now rl->rstate == SSL_ST_READ_BODY */ + } + + /* rl->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > rl->packet_length - DTLS1_RT_HEADER_LENGTH) { + /* now rl->packet_length == DTLS1_RT_HEADER_LENGTH */ + more = rr->length; + rret = rl->funcs->read_n(rl, more, more, 1, 1, &n); + /* this packet contained a partial record, dump it */ + if (rret < OSSL_RECORD_RETURN_SUCCESS || n != more) { + if (rl->alert != SSL_AD_NO_ALERT) { + /* read_n() called RLAYERfatal() */ + return OSSL_RECORD_RETURN_FATAL; + } + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + /* + * now n == rr->length, + * and rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length + */ + } + /* set state for later operations */ + rl->rstate = SSL_ST_READ_HEADER; + + /* match epochs. NULL means the packet is dropped on the floor */ + bitmap = dtls_get_bitmap(rl, rr, &is_next_epoch); + if (bitmap == NULL) { + rr->length = 0; + rl->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(rl->bio)) { +#endif + /* Check whether this is a repeat, or aged record. */ + if (!dtls_record_replay_check(rl, bitmap)) { + rr->length = 0; + rl->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + } +#endif + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + /* + * If this record is from the next epoch (either HM or ALERT), and a + * handshake is currently in progress, buffer it since it cannot be + * processed at this time. + */ + if (is_next_epoch) { + if (rl->in_init) { + if (dtls_rlayer_buffer_record(rl, &(rl->unprocessed_rcds), + rr->seq_num) < 0) { + /* RLAYERfatal() already called */ + return OSSL_RECORD_RETURN_FATAL; + } + } + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + if (!dtls_process_record(rl, bitmap)) { + if (rl->alert != SSL_AD_NO_ALERT) { + /* dtls_process_record() called RLAYERfatal */ + return OSSL_RECORD_RETURN_FATAL; + } + rr->length = 0; + rl->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } + + if (rl->funcs->post_process_record && !rl->funcs->post_process_record(rl, rr)) { + /* RLAYERfatal already called */ + return OSSL_RECORD_RETURN_FATAL; + } + + rl->num_recs = 1; + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int dtls_free(OSSL_RECORD_LAYER *rl) +{ + TLS_BUFFER *rbuf; + size_t left, written; + pitem *item; + DTLS_RLAYER_RECORD_DATA *rdata; + int ret = 1; + + rbuf = &rl->rbuf; + + left = rbuf->left; + if (left > 0) { + /* + * This record layer is closing but we still have data left in our + * buffer. It must be destined for the next epoch - so push it there. + */ + ret = BIO_write_ex(rl->next, rbuf->buf + rbuf->offset, left, &written); + rbuf->left = 0; + } + + if (rl->unprocessed_rcds.q != NULL) { + while ((item = pqueue_pop(rl->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; + /* Push to the next record layer */ + ret &= BIO_write_ex(rl->next, rdata->packet, rdata->packet_length, + &written); + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(item->data); + pitem_free(item); + } + pqueue_free(rl->unprocessed_rcds.q); + } + + if (rl->processed_rcds.q != NULL) { + while ((item = pqueue_pop(rl->processed_rcds.q)) != NULL) { + rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(item->data); + pitem_free(item); + } + pqueue_free(rl->processed_rcds.q); + } + + return tls_free(rl) && ret; +} + +static int +dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, uint16_t epoch, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, unsigned char *iv, + size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, + const EVP_MD *kdfdigest, BIO *prev, BIO *transport, + BIO *next, BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, + OSSL_RECORD_LAYER **retrl) +{ + int ret; + + ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, + key, keylen, iv, ivlen, mackey, mackeylen, + ciph, taglen, mactype, md, comp, prev, + transport, next, local, peer, settings, + options, fns, cbarg, retrl); + + if (ret != OSSL_RECORD_RETURN_SUCCESS) + return ret; + + (*retrl)->unprocessed_rcds.q = pqueue_new(); + (*retrl)->processed_rcds.q = pqueue_new(); + if ((*retrl)->unprocessed_rcds.q == NULL + || (*retrl)->processed_rcds.q == NULL) { + dtls_free(*retrl); + *retrl = NULL; + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + return OSSL_RECORD_RETURN_FATAL; + } + + (*retrl)->unprocessed_rcds.epoch = epoch + 1; + (*retrl)->processed_rcds.epoch = epoch; + + (*retrl)->isdtls = 1; + (*retrl)->epoch = epoch; + (*retrl)->in_init = 1; + + switch (vers) { + case DTLS_ANY_VERSION: + (*retrl)->funcs = &dtls_any_funcs; + break; + case DTLS1_2_VERSION: + case DTLS1_VERSION: + case DTLS1_BAD_VER: + (*retrl)->funcs = &dtls_1_funcs; + break; + default: + /* Should not happen */ + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + ret = OSSL_RECORD_RETURN_FATAL; + goto err; + } + + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, + ivlen, mackey, mackeylen, ciph, + taglen, mactype, md, comp); + + err: + if (ret != OSSL_RECORD_RETURN_SUCCESS) { + dtls_free(*retrl); + *retrl = NULL; + } + return ret; +} + +int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl, + WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata) +{ + size_t maxcomplen; + + *recdata = NULL; + + maxcomplen = templ->buflen; + if (rl->compctx != NULL) + maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; + + if (!WPACKET_put_bytes_u8(thispkt, rectype) + || !WPACKET_put_bytes_u16(thispkt, templ->version) + || !WPACKET_put_bytes_u16(thispkt, rl->epoch) + || !WPACKET_memcpy(thispkt, &(rl->sequence[2]), 6) + || !WPACKET_start_sub_packet_u16(thispkt) + || (rl->eivlen > 0 + && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL)) + || (maxcomplen > 0 + && !WPACKET_reserve_bytes(thispkt, maxcomplen, + recdata))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + if (!tls_post_encryption_processing_default(rl, mac_size, thistempl, + thispkt, thiswr)) { + /* RLAYERfatal() already called */ + return 0; + } + + return tls_increment_sequence_ctr(rl); +} + +static size_t dtls_get_max_record_overhead(OSSL_RECORD_LAYER *rl) +{ + size_t blocksize = 0; + + if (rl->enc_ctx != NULL && + (EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE)) + blocksize = EVP_CIPHER_CTX_get_block_size(rl->enc_ctx); + + /* + * If we have a cipher in place then the tag is mandatory. If the cipher is + * CBC mode then an explicit IV is also mandatory. If we know the digest, + * then we check it is consistent with the taglen. In the case of stitched + * ciphers or AEAD ciphers we don't now the digest (or there isn't one) so + * we just trust that the taglen is correct. + */ + assert(rl->enc_ctx == NULL || ((blocksize == 0 || rl->eivlen > 0) + && rl->taglen > 0)); + assert(rl->md == NULL || (int)rl->taglen == EVP_MD_size(rl->md)); + + /* + * Record overhead consists of the record header, the explicit IV, any + * expansion due to cbc padding, and the mac/tag len. There could be + * further expansion due to compression - but we don't know what this will + * be without knowing the length of the data. However when this function is + * called we don't know what the length will be yet - so this is a catch-22. + * We *could* use SSL_3_RT_MAX_COMPRESSED_OVERHEAD which is an upper limit + * for the maximum record size. But this value is larger than our fallback + * MTU size - so isn't very helpful. We just ignore potential expansion + * due to compression. + */ + return DTLS1_RT_HEADER_LENGTH + rl->eivlen + blocksize + rl->taglen; +} + +const OSSL_RECORD_METHOD ossl_dtls_record_method = { + dtls_new_record_layer, + dtls_free, + tls_unprocessed_read_pending, + tls_processed_read_pending, + tls_app_data_pending, + tls_get_max_records, + tls_write_records, + tls_retry_write_records, + tls_read_record, + tls_release_record, + tls_get_alert_code, + tls_set1_bio, + tls_set_protocol_version, + NULL, + tls_set_first_handshake, + tls_set_max_pipelines, + dtls_set_in_init, + tls_get_state, + tls_set_options, + tls_get_compression, + tls_set_max_frag_len, + dtls_get_max_record_overhead, + tls_increment_sequence_ctr, + tls_alloc_buffers, + tls_free_buffers +}; diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c new file mode 100644 index 0000000000..af91455c29 --- /dev/null +++ b/ssl/record/methods/ktls_meth.c @@ -0,0 +1,611 @@ +/* + * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" +#include "internal/ktls.h" + +static struct record_functions_st ossl_ktls_funcs; + +#if defined(__FreeBSD__) +# include "crypto/cryptodev.h" + +/*- + * Check if a given cipher is supported by the KTLS interface. + * The kernel might still fail the setsockopt() if no suitable + * provider is found, but this checks if the socket option + * supports the cipher suite used at all. + */ +static int ktls_int_check_supported_cipher(OSSL_RECORD_LAYER *rl, + const EVP_CIPHER *c, + const EVP_MD *md, + size_t taglen) +{ + switch (rl->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: +#ifdef OPENSSL_KTLS_TLS13 + case TLS1_3_VERSION: +#endif + break; + default: + return 0; + } + + if (EVP_CIPHER_is_a(c, "AES-128-GCM") + || EVP_CIPHER_is_a(c, "AES-256-GCM") +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + || EVP_CIPHER_is_a(c, "CHACHA20-POLY1305") +# endif + ) + return 1; + + if (!EVP_CIPHER_is_a(c, "AES-128-CBC") + && !EVP_CIPHER_is_a(c, "AES-256-CBC")) + return 0; + + if (rl->use_etm) + return 0; + + if (md == NULL) + return 0; + + if (EVP_MD_is_a(md, "SHA1") + || EVP_MD_is_a(md, "SHA2-256") + || EVP_MD_is_a(md, "SHA2-384")) + return 1; + + return 0; +} + +/* Function to configure kernel TLS structure */ +static +int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c, + EVP_MD *md, void *rl_sequence, + ktls_crypto_info_t *crypto_info, int is_tx, + unsigned char *iv, size_t ivlen, + unsigned char *key, size_t keylen, + unsigned char *mac_key, size_t mac_secret_size) +{ + memset(crypto_info, 0, sizeof(*crypto_info)); + if (EVP_CIPHER_is_a(c, "AES-128-GCM") + || EVP_CIPHER_is_a(c, "AES-256-GCM")) { + crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; + crypto_info->iv_len = ivlen; + } else +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + if (EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")) { + crypto_info->cipher_algorithm = CRYPTO_CHACHA20_POLY1305; + crypto_info->iv_len = ivlen; + } else +# endif + if (EVP_CIPHER_is_a(c, "AES-128-CBC") || EVP_CIPHER_is_a(c, "AES-256-CBC")) { + if (md == NULL) + return 0; + if (EVP_MD_is_a(md, "SHA1")) + crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; + else if (EVP_MD_is_a(md, "SHA2-256")) + crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; + else if (EVP_MD_is_a(md, "SHA2-384")) + crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; + else + return 0; + crypto_info->cipher_algorithm = CRYPTO_AES_CBC; + crypto_info->iv_len = ivlen; + crypto_info->auth_key = mac_key; + crypto_info->auth_key_len = mac_secret_size; + } else { + return 0; + } + crypto_info->cipher_key = key; + crypto_info->cipher_key_len = keylen; + crypto_info->iv = iv; + crypto_info->tls_vmajor = (version >> 8) & 0x000000ff; + crypto_info->tls_vminor = (version & 0x000000ff); +# ifdef TCP_RXTLS_ENABLE + memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); +# else + if (!is_tx) + return 0; +# endif + return 1; +}; + +#endif /* __FreeBSD__ */ + +#if defined(OPENSSL_SYS_LINUX) +/* Function to check supported ciphers in Linux */ +static int ktls_int_check_supported_cipher(OSSL_RECORD_LAYER *rl, + const EVP_CIPHER *c, + const EVP_MD *md, + size_t taglen) +{ + switch (rl->version) { + case TLS1_2_VERSION: +#ifdef OPENSSL_KTLS_TLS13 + case TLS1_3_VERSION: +#endif + break; + default: + return 0; + } + + /* + * Check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 + * or Chacha20-Poly1305 + */ +# ifdef OPENSSL_KTLS_AES_CCM_128 + if (EVP_CIPHER_is_a(c, "AES-128-CCM")) { + if (taglen != EVP_CCM_TLS_TAG_LEN) + return 0; + return 1; + } else +# endif + if (0 +# ifdef OPENSSL_KTLS_AES_GCM_128 + || EVP_CIPHER_is_a(c, "AES-128-GCM") +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + || EVP_CIPHER_is_a(c, "AES-256-GCM") +# endif +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305") +# endif + ) { + return 1; + } + return 0; +} + +/* Function to configure kernel TLS structure */ +static +int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CIPHER *c, + const EVP_MD *md, void *rl_sequence, + ktls_crypto_info_t *crypto_info, int is_tx, + unsigned char *iv, size_t ivlen, + unsigned char *key, size_t keylen, + unsigned char *mac_key, size_t mac_secret_size) +{ + unsigned char geniv[EVP_GCM_TLS_EXPLICIT_IV_LEN]; + unsigned char *eiv = NULL; + +# ifdef OPENSSL_NO_KTLS_RX + if (!is_tx) + return 0; +# endif + + if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE + || EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { + if (!ossl_assert(EVP_GCM_TLS_FIXED_IV_LEN == EVP_CCM_TLS_FIXED_IV_LEN) + || !ossl_assert(EVP_GCM_TLS_EXPLICIT_IV_LEN + == EVP_CCM_TLS_EXPLICIT_IV_LEN)) + return 0; + if (version == TLS1_2_VERSION) { + if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN)) + return 0; + if (is_tx) { + if (RAND_bytes_ex(libctx, geniv, + EVP_GCM_TLS_EXPLICIT_IV_LEN, 0) <= 0) + return 0; + } else { + memset(geniv, 0, EVP_GCM_TLS_EXPLICIT_IV_LEN); + } + eiv = geniv; + } else { + if (!ossl_assert(ivlen == EVP_GCM_TLS_FIXED_IV_LEN + + EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + eiv = iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE; + } + } + + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (EVP_CIPHER_get_nid(c)) { +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: + if (!ossl_assert(TLS_CIPHER_AES_GCM_128_SALT_SIZE + == EVP_GCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_GCM_128_IV_SIZE + == EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; + crypto_info->gcm128.info.version = version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); + memcpy(crypto_info->gcm128.iv, eiv, TLS_CIPHER_AES_GCM_128_IV_SIZE); + memcpy(crypto_info->gcm128.salt, iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + memcpy(crypto_info->gcm128.key, key, keylen); + memcpy(crypto_info->gcm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: + if (!ossl_assert(TLS_CIPHER_AES_GCM_256_SALT_SIZE + == EVP_GCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_GCM_256_IV_SIZE + == EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; + crypto_info->gcm256.info.version = version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); + memcpy(crypto_info->gcm256.iv, eiv, TLS_CIPHER_AES_GCM_256_IV_SIZE); + memcpy(crypto_info->gcm256.salt, iv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); + memcpy(crypto_info->gcm256.key, key, keylen); + memcpy(crypto_info->gcm256.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); + + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + if (!ossl_assert(TLS_CIPHER_AES_CCM_128_SALT_SIZE + == EVP_CCM_TLS_FIXED_IV_LEN) + || !ossl_assert(TLS_CIPHER_AES_CCM_128_IV_SIZE + == EVP_CCM_TLS_EXPLICIT_IV_LEN)) + return 0; + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; + crypto_info->ccm128.info.version = version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); + memcpy(crypto_info->ccm128.iv, eiv, TLS_CIPHER_AES_CCM_128_IV_SIZE); + memcpy(crypto_info->ccm128.salt, iv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info->ccm128.key, key, keylen); + memcpy(crypto_info->ccm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + return 1; +# endif +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + case NID_chacha20_poly1305: + if (!ossl_assert(ivlen == TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE)) + return 0; + crypto_info->chacha20poly1305.info.cipher_type + = TLS_CIPHER_CHACHA20_POLY1305; + crypto_info->chacha20poly1305.info.version = version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); + memcpy(crypto_info->chacha20poly1305.iv, iv, ivlen); + memcpy(crypto_info->chacha20poly1305.key, key, keylen); + memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, + TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); + return 1; +# endif + default: + return 0; + } + +} + +#endif /* OPENSSL_SYS_LINUX */ + +static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp) +{ + ktls_crypto_info_t crypto_info; + + /* + * Check if we are suitable for KTLS. If not suitable we return + * OSSL_RECORD_RETURN_NON_FATAL_ERR so that other record layers can be tried + * instead + */ + + if (comp != NULL) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + /* ktls supports only the maximum fragment size */ + if (rl->max_frag_len != SSL3_RT_MAX_PLAIN_LENGTH) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + /* check that cipher is supported */ + if (!ktls_int_check_supported_cipher(rl, ciph, md, taglen)) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + if (BIO_flush(rl->bio) <= 0) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + /* KTLS does not support record padding */ + if (rl->padding != NULL || rl->block_padding > 0) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + } + + if (!ktls_configure_crypto(rl->libctx, rl->version, ciph, md, rl->sequence, + &crypto_info, + rl->direction == OSSL_RECORD_DIRECTION_WRITE, + iv, ivlen, key, keylen, mackey, mackeylen)) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + if (!BIO_set_ktls(rl->bio, &crypto_info, rl->direction)) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE && + (rl->options & SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE) != 0) + /* Ignore errors. The application opts in to using the zerocopy + * optimization. If the running kernel doesn't support it, just + * continue without the optimization. + */ + BIO_set_ktls_tx_zerocopy_sendfile(rl->bio); + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int ktls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, + int clearold, size_t *readbytes) +{ + int ret; + + ret = tls_default_read_n(rl, n, max, extend, clearold, readbytes); + + if (ret < OSSL_RECORD_RETURN_RETRY) { + switch (errno) { + case EBADMSG: + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + break; + case EMSGSIZE: + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_PACKET_LENGTH_TOO_LONG); + break; + case EINVAL: + RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, + SSL_R_WRONG_VERSION_NUMBER); + break; + default: + break; + } + } + + return ret; +} + +static int ktls_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *inrecs, + size_t n_recs, int sending, SSL_MAC_BUF *mac, + size_t macsize) +{ + return 1; +} + +static int ktls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + if (rec->rec_version != TLS1_2_VERSION) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + + return 1; +} + +static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + if (rl->version == TLS1_3_VERSION) + return tls13_common_post_process_record(rl, rec); + + return 1; +} + +static int +ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, uint16_t epoch, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, unsigned char *iv, + size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, + const EVP_MD *kdfdigest, BIO *prev, BIO *transport, + BIO *next, BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, + OSSL_RECORD_LAYER **retrl) +{ + int ret; + + ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, + key, keylen, iv, ivlen, mackey, mackeylen, + ciph, taglen, mactype, md, comp, prev, + transport, next, local, peer, settings, + options, fns, cbarg, retrl); + + if (ret != OSSL_RECORD_RETURN_SUCCESS) + return ret; + + (*retrl)->funcs = &ossl_ktls_funcs; + + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, + ivlen, mackey, mackeylen, ciph, + taglen, mactype, md, comp); + + if (ret != OSSL_RECORD_RETURN_SUCCESS) { + OPENSSL_free(*retrl); + *retrl = NULL; + } else { + /* + * With KTLS we always try and read as much as possible and fill the + * buffer + */ + (*retrl)->read_ahead = 1; + } + return ret; +} + +static int ktls_allocate_write_buffers(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, size_t *prefix) +{ + if (!ossl_assert(numtempl == 1)) + return 0; + + /* + * We just use the end application buffer in the case of KTLS, so nothing + * to do. We pretend we set up one buffer. + */ + rl->numwpipes = 1; + + return 1; +} + +static int ktls_initialise_write_packets(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited) +{ + TLS_BUFFER *wb; + + /* + * We just use the application buffer directly and don't use any WPACKET + * structures + */ + wb = &bufs[0]; + wb->type = templates[0].type; + + /* + * ktls doesn't modify the buffer, but to avoid a warning we need + * to discard the const qualifier. + * This doesn't leak memory because the buffers have never been allocated + * with KTLS + */ + TLS_BUFFER_set_buf(wb, (unsigned char *)templates[0].buf); + TLS_BUFFER_set_offset(wb, 0); + TLS_BUFFER_set_app_buffer(wb, 1); + + return 1; +} + +static int ktls_prepare_record_header(OSSL_RECORD_LAYER *rl, + WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata) +{ + /* The kernel writes the record header, so nothing to do */ + *recdata = NULL; + + return 1; +} + +static int ktls_prepare_for_encryption(OSSL_RECORD_LAYER *rl, + size_t mac_size, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + /* No encryption, so nothing to do */ + return 1; +} + +static int ktls_post_encryption_processing(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *templ, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + /* The kernel does anything that is needed, so nothing to do here */ + return 1; +} + +static int ktls_prepare_write_bio(OSSL_RECORD_LAYER *rl, int type) +{ + /* + * To prevent coalescing of control and data messages, + * such as in buffer_write, we flush the BIO + */ + if (type != SSL3_RT_APPLICATION_DATA) { + int ret, i = BIO_flush(rl->bio); + + if (i <= 0) { + if (BIO_should_retry(rl->bio)) + ret = OSSL_RECORD_RETURN_RETRY; + else + ret = OSSL_RECORD_RETURN_FATAL; + return ret; + } + BIO_set_ktls_ctrl_msg(rl->bio, type); + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int ktls_alloc_buffers(OSSL_RECORD_LAYER *rl) +{ + /* We use the application buffer directly for writing */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) + return 1; + + return tls_alloc_buffers(rl); +} + +static int ktls_free_buffers(OSSL_RECORD_LAYER *rl) +{ + /* We use the application buffer directly for writing */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) + return 1; + + return tls_free_buffers(rl); +} + +static struct record_functions_st ossl_ktls_funcs = { + ktls_set_crypto_state, + ktls_cipher, + NULL, + tls_default_set_protocol_version, + ktls_read_n, + tls_get_more_records, + ktls_validate_record_header, + ktls_post_process_record, + tls_get_max_records_default, + tls_write_records_default, + ktls_allocate_write_buffers, + ktls_initialise_write_packets, + NULL, + ktls_prepare_record_header, + NULL, + ktls_prepare_for_encryption, + ktls_post_encryption_processing, + ktls_prepare_write_bio +}; + +const OSSL_RECORD_METHOD ossl_ktls_record_method = { + ktls_new_record_layer, + tls_free, + tls_unprocessed_read_pending, + tls_processed_read_pending, + tls_app_data_pending, + tls_get_max_records, + tls_write_records, + tls_retry_write_records, + tls_read_record, + tls_release_record, + tls_get_alert_code, + tls_set1_bio, + tls_set_protocol_version, + tls_set_plain_alerts, + tls_set_first_handshake, + tls_set_max_pipelines, + NULL, + tls_get_state, + tls_set_options, + tls_get_compression, + tls_set_max_frag_len, + NULL, + tls_increment_sequence_ctr, + ktls_alloc_buffers, + ktls_free_buffers +}; diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h new file mode 100644 index 0000000000..300b146a7b --- /dev/null +++ b/ssl/record/methods/recmethod_local.h @@ -0,0 +1,539 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "../../ssl_local.h" +#include "../record_local.h" + +typedef struct dtls_bitmap_st { + /* Track 64 packets */ + uint64_t map; + /* Max record number seen so far, 64-bit value in big-endian encoding */ + unsigned char max_seq_num[SEQ_NUM_SIZE]; +} DTLS_BITMAP; + +typedef struct ssl_mac_buf_st { + unsigned char *mac; + int alloced; +} SSL_MAC_BUF; + +typedef struct tls_buffer_st { + /* at least SSL3_RT_MAX_PACKET_SIZE bytes */ + unsigned char *buf; + /* default buffer size (or 0 if no default set) */ + size_t default_len; + /* buffer size */ + size_t len; + /* where to 'copy from' */ + size_t offset; + /* how many bytes left */ + size_t left; + /* 'buf' is from application for KTLS */ + int app_buffer; + /* The type of data stored in this buffer. Only used for writing */ + int type; +} TLS_BUFFER; + +typedef struct tls_rl_record_st { + /* Record layer version */ + /* r */ + int rec_version; + /* type of record */ + /* r */ + int type; + /* How many bytes available */ + /* rw */ + size_t length; + /* + * How many bytes were available before padding was removed? This is used + * to implement the MAC check in constant time for CBC records. + */ + /* rw */ + size_t orig_len; + /* read/write offset into 'buf' */ + /* r */ + size_t off; + /* pointer to the record data */ + /* rw */ + unsigned char *data; + /* where the decode bytes are */ + /* rw */ + unsigned char *input; + /* only used with decompression - malloc()ed */ + /* r */ + unsigned char *comp; + /* epoch number, needed by DTLS1 */ + /* r */ + uint16_t epoch; + /* sequence number, needed by DTLS1 */ + /* r */ + unsigned char seq_num[SEQ_NUM_SIZE]; +} TLS_RL_RECORD; + +/* Macros/functions provided by the TLS_RL_RECORD component */ + +#define TLS_RL_RECORD_set_type(r, t) ((r)->type = (t)) +#define TLS_RL_RECORD_set_rec_version(r, v) ((r)->rec_version = (v)) +#define TLS_RL_RECORD_get_length(r) ((r)->length) +#define TLS_RL_RECORD_set_length(r, l) ((r)->length = (l)) +#define TLS_RL_RECORD_add_length(r, l) ((r)->length += (l)) +#define TLS_RL_RECORD_set_data(r, d) ((r)->data = (d)) +#define TLS_RL_RECORD_set_input(r, i) ((r)->input = (i)) +#define TLS_RL_RECORD_reset_input(r) ((r)->input = (r)->data) + + +/* Protocol version specific function pointers */ +struct record_functions_st +{ + /* + * Returns either OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or + * OSSL_RECORD_RETURN_NON_FATAL_ERR if we can keep trying to find an + * alternative record layer. + */ + int (*set_crypto_state)(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp); + + /* + * Returns: + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or EtM decryption failed. + * 1: Success or MtE decryption failed (MAC will be randomised) + */ + int (*cipher)(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, size_t n_recs, + int sending, SSL_MAC_BUF *macs, size_t macsize); + /* Returns 1 for success or 0 for error */ + int (*mac)(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md, + int sending); + + /* Return 1 for success or 0 for error */ + int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version); + + /* Read related functions */ + + int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, + int clearold, size_t *readbytes); + + int (*get_more_records)(OSSL_RECORD_LAYER *rl); + + /* Return 1 for success or 0 for error */ + int (*validate_record_header)(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); + + /* Return 1 for success or 0 for error */ + int (*post_process_record)(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); + + /* Write related functions */ + + size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len, + size_t maxfrag, size_t *preffrag); + + /* Return 1 for success or 0 for error */ + int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, + size_t numtempl); + + /* Allocate the rl->wbuf buffers. Return 1 for success or 0 for error */ + int (*allocate_write_buffers)(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, size_t *prefix); + + /* + * Initialise the packets in the |pkt| array using the buffers in |rl->wbuf|. + * Some protocol versions may use the space in |prefixtempl| to add + * an artificial template in front of the |templates| array and hence may + * initialise 1 more WPACKET than there are templates. |*wpinited| + * returns the number of WPACKETs in |pkt| that were successfully + * initialised. This must be 0 on entry and will be filled in even on error. + */ + int (*initialise_write_packets)(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited); + + /* Get the actual record type to be used for a given template */ + uint8_t (*get_record_type)(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *template); + + /* Write the record header data to the WPACKET */ + int (*prepare_record_header)(OSSL_RECORD_LAYER *rl, WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata); + + int (*add_record_padding)(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); + + /* + * This applies any mac that might be necessary, ensures that we have enough + * space in the WPACKET to perform the encryption and sets up the + * TLS_RL_RECORD ready for that encryption. + */ + int (*prepare_for_encryption)(OSSL_RECORD_LAYER *rl, + size_t mac_size, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); + + /* + * Any updates required to the record after encryption has been applied. For + * example, adding a MAC if using encrypt-then-mac + */ + int (*post_encryption_processing)(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); + + /* + * Some record layer implementations need to do some custom preparation of + * the BIO before we write to it. KTLS does this to prevent coalescing of + * control and data messages. + */ + int (*prepare_write_bio)(OSSL_RECORD_LAYER *rl, int type); +}; + +struct ossl_record_layer_st +{ + OSSL_LIB_CTX *libctx; + const char *propq; + int isdtls; + int version; + int role; + int direction; + int level; + const EVP_MD *md; + /* DTLS only */ + uint16_t epoch; + + /* + * A BIO containing any data read in the previous epoch that was destined + * for this epoch + */ + BIO *prev; + + /* The transport BIO */ + BIO *bio; + + /* + * A BIO where we will send any data read by us that is destined for the + * next epoch. + */ + BIO *next; + + /* Types match the equivalent fields in the SSL object */ + uint64_t options; + uint32_t mode; + + /* write IO goes into here */ + TLS_BUFFER wbuf[SSL_MAX_PIPELINES + 1]; + + /* Next wbuf with pending data still to write */ + size_t nextwbuf; + + /* How many pipelines can be used to write data */ + size_t numwpipes; + + /* read IO goes into here */ + TLS_BUFFER rbuf; + /* each decoded record goes in here */ + TLS_RL_RECORD rrec[SSL_MAX_PIPELINES]; + + /* How many records have we got available in the rrec buffer */ + size_t num_recs; + + /* The record number in the rrec buffer that can be read next */ + size_t curr_rec; + + /* The number of records that have been released via tls_release_record */ + size_t num_released; + + /* where we are when reading */ + int rstate; + + /* used internally to point at a raw packet */ + unsigned char *packet; + size_t packet_length; + + /* Sequence number for the next record */ + unsigned char sequence[SEQ_NUM_SIZE]; + + /* Alert code to be used if an error occurs */ + int alert; + + /* + * Read as many input bytes as possible (for non-blocking reads) + */ + int read_ahead; + + /* The number of consecutive empty records we have received */ + size_t empty_record_count; + + /* + * Do we need to send a prefix empty record before application data as a + * countermeasure against known-IV weakness (necessary for SSLv3 and + * TLSv1.0) + */ + int need_empty_fragments; + + /* cryptographic state */ + EVP_CIPHER_CTX *enc_ctx; + + /* Explicit IV length */ + size_t eivlen; + + /* used for mac generation */ + EVP_MD_CTX *md_ctx; + + /* compress/uncompress */ + COMP_CTX *compctx; + + /* Set to 1 if this is the first handshake. 0 otherwise */ + int is_first_handshake; + + /* + * The smaller of the configured and negotiated maximum fragment length + * or SSL3_RT_MAX_PLAIN_LENGTH if none + */ + unsigned int max_frag_len; + + /* The maximum amount of early data we can receive/send */ + uint32_t max_early_data; + + /* The amount of early data that we have sent/received */ + size_t early_data_count; + + /* TLSv1.3 record padding */ + size_t block_padding; + + /* Only used by SSLv3 */ + unsigned char mac_secret[EVP_MAX_MD_SIZE]; + + /* TLSv1.0/TLSv1.1/TLSv1.2 */ + int use_etm; + + /* Flags for GOST ciphers */ + int stream_mac; + int tlstree; + + /* TLSv1.3 fields */ + /* static IV */ + unsigned char iv[EVP_MAX_IV_LENGTH]; + int allow_plain_alerts; + + /* TLS "any" fields */ + /* Set to true if this is the first record in a connection */ + unsigned int is_first_record; + + size_t taglen; + + /* DTLS received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + + /* records being received in the current epoch */ + DTLS_BITMAP bitmap; + /* renegotiation starts a new set of sequence numbers */ + DTLS_BITMAP next_bitmap; + + /* + * Whether we are currently in a handshake or not. Only maintained for DTLS + */ + int in_init; + + /* Callbacks */ + void *cbarg; + OSSL_FUNC_rlayer_skip_early_data_fn *skip_early_data; + OSSL_FUNC_rlayer_msg_callback_fn *msg_callback; + OSSL_FUNC_rlayer_security_fn *security; + OSSL_FUNC_rlayer_padding_fn *padding; + + size_t max_pipelines; + + /* Function pointers for version specific functions */ + struct record_functions_st *funcs; +}; + +typedef struct dtls_rlayer_record_data_st { + unsigned char *packet; + size_t packet_length; + TLS_BUFFER rbuf; + TLS_RL_RECORD rrec; +} DTLS_RLAYER_RECORD_DATA; + +extern struct record_functions_st ssl_3_0_funcs; +extern struct record_functions_st tls_1_funcs; +extern struct record_functions_st tls_1_3_funcs; +extern struct record_functions_st tls_any_funcs; +extern struct record_functions_st dtls_1_funcs; +extern struct record_functions_st dtls_any_funcs; + +void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, + const char *fmt, ...); + +#define RLAYERfatal(rl, al, r) RLAYERfatal_data((rl), (al), (r), NULL) +#define RLAYERfatal_data \ + (ERR_new(), \ + ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \ + ossl_rlayer_fatal) + +#define RLAYER_USE_EXPLICIT_IV(rl) ((rl)->version == TLS1_1_VERSION \ + || (rl)->version == TLS1_2_VERSION \ + || (rl)->isdtls) + +void ossl_tls_rl_record_set_seq_num(TLS_RL_RECORD *r, + const unsigned char *seq_num); + +int ossl_set_tls_provider_parameters(OSSL_RECORD_LAYER *rl, + EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *ciph, + const EVP_MD *md); + +int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl); +int tls_alloc_buffers(OSSL_RECORD_LAYER *rl); +int tls_free_buffers(OSSL_RECORD_LAYER *rl); + +int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, + int clearold, size_t *readbytes); +int tls_get_more_records(OSSL_RECORD_LAYER *rl); +int dtls_get_more_records(OSSL_RECORD_LAYER *rl); + +int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl, + WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata); +int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); + +int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); +int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *re); +int tls_do_compress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *wr); +int tls_do_uncompress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); +int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); +int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); + +int +tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, BIO *prev, + BIO *transport, BIO *next, + BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, + OSSL_RECORD_LAYER **retrl); +int tls_free(OSSL_RECORD_LAYER *rl); +int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl); +int tls_processed_read_pending(OSSL_RECORD_LAYER *rl); +size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl); +size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len, + size_t maxfrag, size_t *preffrag); +int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, + size_t numtempl); +int tls_retry_write_records(OSSL_RECORD_LAYER *rl); +int tls_get_alert_code(OSSL_RECORD_LAYER *rl); +int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio); +int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, + uint8_t *type, const unsigned char **data, size_t *datalen, + uint16_t *epoch, unsigned char *seq_num); +int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length); +int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); +int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); +void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow); +void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first); +void tls_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines); +void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr, + const char **longstr); +int tls_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options); +const COMP_METHOD *tls_get_compression(OSSL_RECORD_LAYER *rl); +void tls_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len); +int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl); +int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes, + size_t firstlen, size_t nextlen); + +int tls_write_records_multiblock(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl); + +size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, + size_t maxfrag, size_t *preffrag); +size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, size_t maxfrag, + size_t *preffrag); +int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, size_t *prefix); +int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited); +int tls1_allocate_write_buffers(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, size_t *prefix); +int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited); +int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl, + WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata); +int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl, + size_t mac_size, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); +int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr); +int tls_write_records_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl); + +/* Macros/functions provided by the TLS_BUFFER component */ + +#define TLS_BUFFER_get_buf(b) ((b)->buf) +#define TLS_BUFFER_set_buf(b, n) ((b)->buf = (n)) +#define TLS_BUFFER_get_len(b) ((b)->len) +#define TLS_BUFFER_get_left(b) ((b)->left) +#define TLS_BUFFER_set_left(b, l) ((b)->left = (l)) +#define TLS_BUFFER_sub_left(b, l) ((b)->left -= (l)) +#define TLS_BUFFER_get_offset(b) ((b)->offset) +#define TLS_BUFFER_set_offset(b, o) ((b)->offset = (o)) +#define TLS_BUFFER_add_offset(b, o) ((b)->offset += (o)) +#define TLS_BUFFER_set_app_buffer(b, l) ((b)->app_buffer = (l)) +#define TLS_BUFFER_is_app_buffer(b) ((b)->app_buffer) + +void ossl_tls_buffer_release(TLS_BUFFER *b); diff --git a/ssl/s3_cbc.c b/ssl/record/methods/ssl3_cbc.c similarity index 86% rename from ssl/s3_cbc.c rename to ssl/record/methods/ssl3_cbc.c index 85f296b807..a8282989ed 100644 --- a/ssl/s3_cbc.c +++ b/ssl/record/methods/ssl3_cbc.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,53 +16,21 @@ * moved out of libssl. */ - /* * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for * internal use. */ #include "internal/deprecated.h" -#include "internal/constant_time.h" -#include "internal/cryptlib.h" - #include #ifndef FIPS_MODULE # include #endif #include -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -int ssl3_cbc_digest_record(const EVP_MD *md, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char *header, - const unsigned char *data, - size_t data_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - size_t mac_secret_length, char is_sslv3); - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ - *((c)++)=(unsigned char)(((l)>>48)&0xff), \ - *((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) +#include "internal/ssl3_cbc.h" +#include "internal/constant_time.h" +#include "internal/cryptlib.h" /* * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's @@ -83,10 +51,10 @@ int ssl3_cbc_digest_record(const EVP_MD *md, * little-endian order. The value of p is advanced by four. */ # define u32toLE(n, p) \ - (*((p)++)=(unsigned char)(n), \ - *((p)++)=(unsigned char)(n>>8), \ - *((p)++)=(unsigned char)(n>>16), \ - *((p)++)=(unsigned char)(n>>24)) + (*((p)++) = (unsigned char)(n ), \ + *((p)++) = (unsigned char)(n >> 8), \ + *((p)++) = (unsigned char)(n >> 16), \ + *((p)++) = (unsigned char)(n >> 24)) /* * These functions serialize the state of a hash and thus perform the @@ -96,6 +64,7 @@ int ssl3_cbc_digest_record(const EVP_MD *md, static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) { MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); u32toLE(md5->B, md_out); u32toLE(md5->C, md_out); @@ -106,6 +75,7 @@ static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) { SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); l2n(sha1->h1, md_out); l2n(sha1->h2, md_out); @@ -118,9 +88,8 @@ static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) SHA256_CTX *sha256 = ctx; unsigned i; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) l2n(sha256->h[i], md_out); - } } static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) @@ -128,9 +97,8 @@ static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) SHA512_CTX *sha512 = ctx; unsigned i; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) l2n8(sha512->h[i], md_out); - } } #undef LARGEST_DIGEST_CTX @@ -226,14 +194,14 @@ int ssl3_cbc_digest_record(const EVP_MD *md, md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 224 / 8; - } else if (EVP_MD_is_a(md, "SHA2-256")) { + } else if (EVP_MD_is_a(md, "SHA2-256")) { if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 32; - } else if (EVP_MD_is_a(md, "SHA2-384")) { + } else if (EVP_MD_is_a(md, "SHA2-384")) { if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha512_final_raw; @@ -268,10 +236,11 @@ int ssl3_cbc_digest_record(const EVP_MD *md, header_length = 13; if (is_sslv3) { - header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence - * number */ + - 1 /* record type */ + - 2 /* record length */ ; + header_length = mac_secret_length + + sslv3_pad_length + + 8 /* sequence number */ + + 1 /* record type */ + + 2; /* record length */ } /* @@ -289,7 +258,9 @@ int ssl3_cbc_digest_record(const EVP_MD *md, * short and there obviously cannot be this many blocks then * variance_blocks can be reduced. */ - variance_blocks = is_sslv3 ? 2 : ( ((255 + 1 + md_size + md_block_size - 1) / md_block_size) + 1); + variance_blocks = is_sslv3 ? 2 + : (((255 + 1 + md_size + md_block_size - 1) + / md_block_size) + 1); /* * From now on we're dealing with the MAC, which conceptually has 13 * bytes of `header' before the start of the data (TLS) or 71/75 bytes @@ -431,8 +402,10 @@ int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char block[MAX_HASH_BLOCK_SIZE]; unsigned char is_block_a = constant_time_eq_8_s(i, index_a); unsigned char is_block_b = constant_time_eq_8_s(i, index_b); + for (j = 0; j < md_block_size; j++) { unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) b = header[k]; else if (k < data_plus_mac_plus_padding_size + header_length) @@ -483,7 +456,7 @@ int ssl3_cbc_digest_record(const EVP_MD *md, if (md_ctx == NULL) goto err; - if (EVP_DigestInit_ex(md_ctx, md, NULL /* engine */ ) <= 0) + if (EVP_DigestInit_ex(md_ctx, md, NULL /* engine */) <= 0) goto err; if (is_sslv3) { /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ diff --git a/ssl/record/methods/ssl3_meth.c b/ssl/record/methods/ssl3_meth.c new file mode 100644 index 0000000000..76a108e443 --- /dev/null +++ b/ssl/record/methods/ssl3_meth.c @@ -0,0 +1,327 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/ssl3_cbc.h" +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp) +{ + EVP_CIPHER_CTX *ciph_ctx; + int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; + + if (md == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if ((rl->enc_ctx = EVP_CIPHER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + ciph_ctx = rl->enc_ctx; + + rl->md_ctx = EVP_MD_CTX_new(); + if (rl->md_ctx == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if ((md != NULL && EVP_DigestInit_ex(rl->md_ctx, md, NULL) <= 0)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + +#ifndef OPENSSL_NO_COMP + if (comp != NULL) { + rl->compctx = COMP_CTX_new(comp); + if (rl->compctx == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } +#endif + + if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, iv, enc)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if (EVP_CIPHER_get0_provider(ciph) != NULL + && !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md)) { + /* ERR_raise already called */ + return OSSL_RECORD_RETURN_FATAL; + } + + if (mackeylen > sizeof(rl->mac_secret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + memcpy(rl->mac_secret, mackey, mackeylen); + + return OSSL_RECORD_RETURN_SUCCESS; +} + +/* + * ssl3_cipher encrypts/decrypts |n_recs| records in |inrecs|. Calls RLAYERfatal + * on internal error, but not otherwise. It is the responsibility of the caller + * to report a bad_record_mac + * + * Returns: + * 0: if the record is publicly invalid, or an internal error + * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) + */ +static int ssl3_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *inrecs, + size_t n_recs, int sending, SSL_MAC_BUF *mac, + size_t macsize) +{ + TLS_RL_RECORD *rec; + EVP_CIPHER_CTX *ds; + size_t l, i; + size_t bs; + const EVP_CIPHER *enc; + int provided; + + rec = inrecs; + /* + * We shouldn't ever be called with more than one record in the SSLv3 case + */ + if (n_recs != 1) + return 0; + + ds = rl->enc_ctx; + if (ds == NULL || (enc = EVP_CIPHER_CTX_get0_cipher(ds)) == NULL) + return 0; + + provided = (EVP_CIPHER_get0_provider(enc) != NULL); + + l = rec->length; + bs = EVP_CIPHER_CTX_get_block_size(ds); + + /* COMPRESS */ + + if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ + i = bs - (l % bs); + + /* we need to add 'i-1' padding bytes */ + l += i; + /* + * the last of these zero bytes will be overwritten with the + * padding length. + */ + memset(&rec->input[rec->length], 0, i); + rec->length += i; + rec->input[l - 1] = (unsigned char)(i - 1); + } + + if (!sending) { + if (l == 0 || l % bs != 0) { + /* Publicly invalid */ + return 0; + } + /* otherwise, rec->length >= bs */ + } + + if (provided) { + int outlen; + + if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input, + (unsigned int)l)) + return 0; + rec->length = outlen; + + if (!sending && mac != NULL) { + /* Now get a pointer to the MAC */ + OSSL_PARAM params[2], *p = params; + + /* Get the MAC */ + mac->alloced = 0; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, + (void **)&mac->mac, + macsize); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_get_params(ds, params)) { + /* Shouldn't normally happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + } else { + if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) { + /* Shouldn't happen */ + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!sending) + return ssl3_cbc_remove_padding_and_mac(&rec->length, + rec->orig_len, + rec->data, + (mac != NULL) ? &mac->mac : NULL, + (mac != NULL) ? &mac->alloced : NULL, + bs, + macsize, + rl->libctx); + } + + return 1; +} + +static const unsigned char ssl3_pad_1[48] = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 +}; + +static const unsigned char ssl3_pad_2[48] = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c +}; + +static int ssl3_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md, + int sending) +{ + unsigned char *mac_sec, *seq = rl->sequence; + const EVP_MD_CTX *hash; + unsigned char *p, rec_char; + size_t md_size; + size_t npad; + int t; + + mac_sec = &(rl->mac_secret[0]); + hash = rl->md_ctx; + + t = EVP_MD_CTX_get_size(hash); + if (t <= 0) + return 0; + md_size = t; + npad = (48 / md_size) * md_size; + + if (!sending + && EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE + && ssl3_cbc_record_digest_supported(hash)) { +#ifdef OPENSSL_NO_DEPRECATED_3_0 + return 0; +#else + /* + * This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of data we + * are hashing because that gives an attacker a timing-oracle. + */ + + /*- + * npad is, at most, 48 bytes and that's with MD5: + * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. + * + * With SHA-1 (the largest hash speced for SSLv3) the hash size + * goes up 4, but npad goes down by 8, resulting in a smaller + * total size. + */ + unsigned char header[75]; + size_t j = 0; + memcpy(header + j, mac_sec, md_size); + j += md_size; + memcpy(header + j, ssl3_pad_1, npad); + j += npad; + memcpy(header + j, seq, 8); + j += 8; + header[j++] = rec->type; + header[j++] = (unsigned char)(rec->length >> 8); + header[j++] = (unsigned char)(rec->length & 0xff); + + /* Final param == is SSLv3 */ + if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash), + md, &md_size, + header, rec->input, + rec->length, rec->orig_len, + mac_sec, md_size, 1) <= 0) + return 0; +#endif + } else { + unsigned int md_size_u; + /* Chop the digest off the end :-) */ + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + + if (md_ctx == NULL) + return 0; + + rec_char = rec->type; + p = md; + s2n(rec->length, p); + if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0 + || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0 + || EVP_DigestUpdate(md_ctx, seq, 8) <= 0 + || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0 + || EVP_DigestUpdate(md_ctx, md, 2) <= 0 + || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0 + || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0 + || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0 + || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0 + || EVP_DigestUpdate(md_ctx, md, md_size) <= 0 + || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) { + EVP_MD_CTX_free(md_ctx); + return 0; + } + + EVP_MD_CTX_free(md_ctx); + } + + if (!tls_increment_sequence_ctr(rl)) + return 0; + + return 1; +} + +struct record_functions_st ssl_3_0_funcs = { + ssl3_set_crypto_state, + ssl3_cipher, + ssl3_mac, + tls_default_set_protocol_version, + tls_default_read_n, + tls_get_more_records, + tls_default_validate_record_header, + tls_default_post_process_record, + tls_get_max_records_default, + tls_write_records_default, + /* These 2 functions are defined in tls1_meth.c */ + tls1_allocate_write_buffers, + tls1_initialise_write_packets, + NULL, + tls_prepare_record_header_default, + NULL, + tls_prepare_for_encryption_default, + tls_post_encryption_processing_default, + NULL +}; diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c new file mode 100644 index 0000000000..ec22f1ee49 --- /dev/null +++ b/ssl/record/methods/tls13_meth.c @@ -0,0 +1,325 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp) +{ + EVP_CIPHER_CTX *ciph_ctx; + int mode; + int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; + + if (ivlen > sizeof(rl->iv)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + memcpy(rl->iv, iv, ivlen); + + ciph_ctx = rl->enc_ctx = EVP_CIPHER_CTX_new(); + if (ciph_ctx == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + mode = EVP_CIPHER_get_mode(ciph); + + if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, enc) <= 0 + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, + NULL) <= 0 + || (mode == EVP_CIPH_CCM_MODE + && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, + NULL) <= 0) + || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, enc) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, + size_t n_recs, int sending, SSL_MAC_BUF *mac, + size_t macsize) +{ + EVP_CIPHER_CTX *ctx; + unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; + size_t ivlen, offset, loop, hdrlen; + unsigned char *staticiv; + unsigned char *seq = rl->sequence; + int lenu, lenf; + TLS_RL_RECORD *rec = &recs[0]; + WPACKET wpkt; + const EVP_CIPHER *cipher; + int mode; + + if (n_recs != 1) { + /* Should not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + ctx = rl->enc_ctx; + staticiv = rl->iv; + + cipher = EVP_CIPHER_CTX_get0_cipher(ctx); + if (cipher == NULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + mode = EVP_CIPHER_get_mode(cipher); + + /* + * If we're sending an alert and ctx != NULL then we must be forcing + * plaintext alerts. If we're reading and ctx != NULL then we allow + * plaintext alerts at certain points in the handshake. If we've got this + * far then we have already validated that a plaintext alert is ok here. + */ + if (ctx == NULL || rec->type == SSL3_RT_ALERT) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + return 1; + } + + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + + if (!sending) { + /* + * Take off tag. There must be at least one byte of content type as + * well as the tag + */ + if (rec->length < rl->taglen + 1) + return 0; + rec->length -= rl->taglen; + } + + /* Set up IV */ + if (ivlen < SEQ_NUM_SIZE) { + /* Should not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + offset = ivlen - SEQ_NUM_SIZE; + memcpy(iv, staticiv, offset); + for (loop = 0; loop < SEQ_NUM_SIZE; loop++) + iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; + + if (!tls_increment_sequence_ctr(rl)) { + /* RLAYERfatal already called */ + return 0; + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0 + || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + rl->taglen, + rec->data + rec->length) <= 0)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Set up the AAD */ + if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) + || !WPACKET_put_bytes_u8(&wpkt, rec->type) + || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version) + || !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen) + || !WPACKET_get_total_written(&wpkt, &hdrlen) + || hdrlen != SSL3_RT_HEADER_LENGTH + || !WPACKET_finish(&wpkt)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + WPACKET_cleanup(&wpkt); + return 0; + } + + /* + * For CCM we must explicitly set the total plaintext length before we add + * any AAD. + */ + if ((mode == EVP_CIPH_CCM_MODE + && EVP_CipherUpdate(ctx, NULL, &lenu, NULL, + (unsigned int)rec->length) <= 0) + || EVP_CipherUpdate(ctx, NULL, &lenu, recheader, + sizeof(recheader)) <= 0 + || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input, + (unsigned int)rec->length) <= 0 + || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 + || (size_t)(lenu + lenf) != rec->length) { + return 0; + } + if (sending) { + /* Add the tag */ + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen, + rec->data + rec->length) <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + rec->length += rl->taglen; + } + + return 1; +} + +static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl, + TLS_RL_RECORD *rec) +{ + if (rec->type != SSL3_RT_APPLICATION_DATA + && (rec->type != SSL3_RT_CHANGE_CIPHER_SPEC + || !rl->is_first_handshake) + && (rec->type != SSL3_RT_ALERT || !rl->allow_plain_alerts)) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); + return 0; + } + + if (rec->rec_version != TLS1_2_VERSION) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + + if (rec->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + return 0; + } + return 1; +} + +static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + /* Skip this if we've received a plaintext alert */ + if (rec->type != SSL3_RT_ALERT) { + size_t end; + + if (rec->length == 0 + || rec->type != SSL3_RT_APPLICATION_DATA) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_BAD_RECORD_TYPE); + return 0; + } + + /* Strip trailing padding */ + for (end = rec->length - 1; end > 0 && rec->data[end] == 0; end--) + continue; + + rec->length = end; + rec->type = rec->data[end]; + } + + if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + + if (!tls13_common_post_process_record(rl, rec)) { + /* RLAYERfatal already called */ + return 0; + } + + return 1; +} + +static uint8_t tls13_get_record_type(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *template) +{ + if (rl->allow_plain_alerts && template->type == SSL3_RT_ALERT) + return SSL3_RT_ALERT; + + /* + * Aside from the above case we always use the application data record type + * when encrypting in TLSv1.3. The "inner" record type encodes the "real" + * record type from the template. + */ + return SSL3_RT_APPLICATION_DATA; +} + +static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + size_t rlen; + + /* Nothing to be done in the case of a plaintext alert */ + if (rl->allow_plain_alerts && thistempl->type != SSL3_RT_ALERT) + return 1; + + if (!WPACKET_put_bytes_u8(thispkt, thistempl->type)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + TLS_RL_RECORD_add_length(thiswr, 1); + + /* Add TLS1.3 padding */ + rlen = TLS_RL_RECORD_get_length(thiswr); + if (rlen < rl->max_frag_len) { + size_t padding = 0; + size_t max_padding = rl->max_frag_len - rlen; + + if (rl->padding != NULL) { + padding = rl->padding(rl->cbarg, thistempl->type, rlen); + } else if (rl->block_padding > 0) { + size_t mask = rl->block_padding - 1; + size_t remainder; + + /* optimize for power of 2 */ + if ((rl->block_padding & mask) == 0) + remainder = rlen & mask; + else + remainder = rlen % rl->block_padding; + /* don't want to add a block of padding if we don't have to */ + if (remainder == 0) + padding = 0; + else + padding = rl->block_padding - remainder; + } + if (padding > 0) { + /* do not allow the record to exceed max plaintext length */ + if (padding > max_padding) + padding = max_padding; + if (!WPACKET_memset(thispkt, 0, padding)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, + ERR_R_INTERNAL_ERROR); + return 0; + } + TLS_RL_RECORD_add_length(thiswr, padding); + } + } + + return 1; +} + +struct record_functions_st tls_1_3_funcs = { + tls13_set_crypto_state, + tls13_cipher, + NULL, + tls_default_set_protocol_version, + tls_default_read_n, + tls_get_more_records, + tls13_validate_record_header, + tls13_post_process_record, + tls_get_max_records_default, + tls_write_records_default, + tls_allocate_write_buffers_default, + tls_initialise_write_packets_default, + tls13_get_record_type, + tls_prepare_record_header_default, + tls13_add_record_padding, + tls_prepare_for_encryption_default, + tls_post_encryption_processing_default, + NULL +}; diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c new file mode 100644 index 0000000000..46a83ad8f4 --- /dev/null +++ b/ssl/record/methods/tls1_meth.c @@ -0,0 +1,688 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/ssl3_cbc.h" +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp) +{ + EVP_CIPHER_CTX *ciph_ctx; + EVP_PKEY *mac_key; + int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; + + if (level != OSSL_RECORD_PROTECTION_LEVEL_APPLICATION) + return OSSL_RECORD_RETURN_FATAL; + + if ((rl->enc_ctx = EVP_CIPHER_CTX_new()) == NULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return OSSL_RECORD_RETURN_FATAL; + } + + ciph_ctx = rl->enc_ctx; + + rl->md_ctx = EVP_MD_CTX_new(); + if (rl->md_ctx == NULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } +#ifndef OPENSSL_NO_COMP + if (comp != NULL) { + rl->compctx = COMP_CTX_new(comp); + if (rl->compctx == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } +#endif + + /* + * If we have an AEAD Cipher, then there is no separate MAC, so we can skip + * setting up the MAC key. + */ + if ((EVP_CIPHER_get_flags(ciph) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0) { + if (mactype == EVP_PKEY_HMAC) { + mac_key = EVP_PKEY_new_raw_private_key_ex(rl->libctx, "HMAC", + rl->propq, mackey, + mackeylen); + } else { + /* + * If its not HMAC then the only other types of MAC we support are + * the GOST MACs, so we need to use the old style way of creating + * a MAC key. + */ + mac_key = EVP_PKEY_new_mac_key(mactype, NULL, mackey, + (int)mackeylen); + } + if (mac_key == NULL + || EVP_DigestSignInit_ex(rl->md_ctx, NULL, EVP_MD_get0_name(md), + rl->libctx, rl->propq, mac_key, + NULL) <= 0) { + EVP_PKEY_free(mac_key); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + EVP_PKEY_free(mac_key); + } + + if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_GCM_MODE) { + if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, NULL, enc) + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_GCM_SET_IV_FIXED, + (int)ivlen, iv) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } else if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) { + if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, enc) + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, + NULL) <= 0 + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, + (int)taglen, NULL) <= 0 + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_CCM_SET_IV_FIXED, + (int)ivlen, iv) <= 0 + || !EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, enc)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } else { + if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, iv, enc)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } + /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ + if ((EVP_CIPHER_get_flags(ciph) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0 + && mackeylen != 0 + && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, + (int)mackeylen, mackey) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + if (EVP_CIPHER_get0_provider(ciph) != NULL + && !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md)) + return OSSL_RECORD_RETURN_FATAL; + + /* Calculate the explicit IV length */ + if (RLAYER_USE_EXPLICIT_IV(rl)) { + int mode = EVP_CIPHER_CTX_get_mode(ciph_ctx); + int eivlen = 0; + + if (mode == EVP_CIPH_CBC_MODE) { + eivlen = EVP_CIPHER_CTX_get_iv_length(ciph_ctx); + if (eivlen < 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + return OSSL_RECORD_RETURN_FATAL; + } + if (eivlen <= 1) + eivlen = 0; + } else if (mode == EVP_CIPH_GCM_MODE) { + /* Need explicit part of IV for GCM mode */ + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (mode == EVP_CIPH_CCM_MODE) { + eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; + } + rl->eivlen = (size_t)eivlen; + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +#define MAX_PADDING 256 +/*- + * tls1_cipher encrypts/decrypts |n_recs| in |recs|. Calls RLAYERfatal on + * internal error, but not otherwise. It is the responsibility of the caller to + * report a bad_record_mac - if appropriate (DTLS just drops the record). + * + * Returns: + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or Encrypt-then-mac decryption failed. + * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) + */ +static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, + size_t n_recs, int sending, SSL_MAC_BUF *macs, + size_t macsize) +{ + EVP_CIPHER_CTX *ds; + size_t reclen[SSL_MAX_PIPELINES]; + unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN]; + unsigned char *data[SSL_MAX_PIPELINES]; + int pad = 0, tmpr, provided; + size_t bs, ctr, padnum, loop; + unsigned char padval; + const EVP_CIPHER *enc; + + if (n_recs == 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (EVP_MD_CTX_get0_md(rl->md_ctx)) { + int n = EVP_MD_CTX_get_size(rl->md_ctx); + + if (!ossl_assert(n >= 0)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + ds = rl->enc_ctx; + if (!ossl_assert(rl->enc_ctx != NULL)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + enc = EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx); + + if (sending) { + int ivlen; + + /* For TLSv1.1 and later explicit IV */ + if (RLAYER_USE_EXPLICIT_IV(rl) + && EVP_CIPHER_get_mode(enc) == EVP_CIPH_CBC_MODE) + ivlen = EVP_CIPHER_get_iv_length(enc); + else + ivlen = 0; + if (ivlen > 1) { + for (ctr = 0; ctr < n_recs; ctr++) { + if (recs[ctr].data != recs[ctr].input) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } else if (RAND_bytes_ex(rl->libctx, recs[ctr].input, + ivlen, 0) <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + } + } + if (!ossl_assert(enc != NULL)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + provided = (EVP_CIPHER_get0_provider(enc) != NULL); + + bs = EVP_CIPHER_get_block_size(EVP_CIPHER_CTX_get0_cipher(ds)); + + if (n_recs > 1) { + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_PIPELINE) == 0) { + /* + * We shouldn't have been called with pipeline data if the + * cipher doesn't support pipelining + */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; + } + } + for (ctr = 0; ctr < n_recs; ctr++) { + reclen[ctr] = recs[ctr].length; + + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { + unsigned char *seq; + + seq = rl->sequence; + + if (rl->isdtls) { + unsigned char dtlsseq[8], *p = dtlsseq; + + s2n(rl->epoch, p); + memcpy(p, &seq[2], 6); + memcpy(buf[ctr], dtlsseq, 8); + } else { + memcpy(buf[ctr], seq, 8); + if (!tls_increment_sequence_ctr(rl)) { + /* RLAYERfatal already called */ + return 0; + } + } + + buf[ctr][8] = recs[ctr].type; + buf[ctr][9] = (unsigned char)(rl->version >> 8); + buf[ctr][10] = (unsigned char)(rl->version); + buf[ctr][11] = (unsigned char)(recs[ctr].length >> 8); + buf[ctr][12] = (unsigned char)(recs[ctr].length & 0xff); + pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, + EVP_AEAD_TLS1_AAD_LEN, buf[ctr]); + if (pad <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (sending) { + reclen[ctr] += pad; + recs[ctr].length += pad; + } + } else if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ + padnum = bs - (reclen[ctr] % bs); + + /* Add weird padding of up to 256 bytes */ + + if (padnum > MAX_PADDING) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + /* we need to add 'padnum' padding bytes of value padval */ + padval = (unsigned char)(padnum - 1); + for (loop = reclen[ctr]; loop < reclen[ctr] + padnum; loop++) + recs[ctr].input[loop] = padval; + reclen[ctr] += padnum; + recs[ctr].length += padnum; + } + + if (!sending) { + if (reclen[ctr] == 0 || reclen[ctr] % bs != 0) { + /* Publicly invalid */ + return 0; + } + } + } + if (n_recs > 1) { + /* Set the output buffers */ + for (ctr = 0; ctr < n_recs; ctr++) + data[ctr] = recs[ctr].data; + + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS, + (int)n_recs, data) <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; + } + /* Set the input buffers */ + for (ctr = 0; ctr < n_recs; ctr++) + data[ctr] = recs[ctr].input; + + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_BUFS, + (int)n_recs, data) <= 0 + || EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_LENS, + (int)n_recs, reclen) <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; + } + } + + if (!rl->isdtls && rl->tlstree) { + int decrement_seq = 0; + + /* + * When sending, seq is incremented after MAC calculation. + * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. + * Otherwise we have to decrease it in the implementation + */ + if (sending && !rl->use_etm) + decrement_seq = 1; + + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, + rl->sequence) <= 0) { + + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + if (provided) { + int outlen; + + /* Provided cipher - we do not support pipelining on this path */ + if (n_recs > 1) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input, + (unsigned int)reclen[0])) + return 0; + recs[0].length = outlen; + + /* + * The length returned from EVP_CipherUpdate above is the actual + * payload length. We need to adjust the data/input ptr to skip over + * any explicit IV + */ + if (!sending) { + if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { + recs[0].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[0].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { + recs[0].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[0].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + } else if (bs != 1 && RLAYER_USE_EXPLICIT_IV(rl)) { + recs[0].data += bs; + recs[0].input += bs; + recs[0].orig_len -= bs; + } + + /* Now get a pointer to the MAC (if applicable) */ + if (macs != NULL) { + OSSL_PARAM params[2], *p = params; + + /* Get the MAC */ + macs[0].alloced = 0; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, + (void **)&macs[0].mac, + macsize); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_get_params(ds, params)) { + /* Shouldn't normally happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, + ERR_R_INTERNAL_ERROR); + return 0; + } + } + } + } else { + /* Legacy cipher */ + + tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, + (unsigned int)reclen[0]); + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0 + ? (tmpr < 0) + : (tmpr == 0)) { + /* AEAD can fail to verify MAC */ + return 0; + } + + if (!sending) { + for (ctr = 0; ctr < n_recs; ctr++) { + /* Adjust the record to remove the explicit IV/MAC/Tag */ + if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { + recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { + recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; + } else if (bs != 1 && RLAYER_USE_EXPLICIT_IV(rl)) { + if (recs[ctr].length < bs) + return 0; + recs[ctr].data += bs; + recs[ctr].input += bs; + recs[ctr].length -= bs; + recs[ctr].orig_len -= bs; + } + + /* + * If using Mac-then-encrypt, then this will succeed but + * with a random MAC if padding is invalid + */ + if (!tls1_cbc_remove_padding_and_mac(&recs[ctr].length, + recs[ctr].orig_len, + recs[ctr].data, + (macs != NULL) ? &macs[ctr].mac : NULL, + (macs != NULL) ? &macs[ctr].alloced + : NULL, + bs, + pad ? (size_t)pad : macsize, + (EVP_CIPHER_get_flags(enc) + & EVP_CIPH_FLAG_AEAD_CIPHER) != 0, + rl->libctx)) + return 0; + } + } + } + return 1; +} + +static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md, + int sending) +{ + unsigned char *seq = rl->sequence; + EVP_MD_CTX *hash; + size_t md_size; + EVP_MD_CTX *hmac = NULL, *mac_ctx; + unsigned char header[13]; + int t; + int ret = 0; + + hash = rl->md_ctx; + + t = EVP_MD_CTX_get_size(hash); + if (!ossl_assert(t >= 0)) + return 0; + md_size = t; + + if (rl->stream_mac) { + mac_ctx = hash; + } else { + hmac = EVP_MD_CTX_new(); + if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash)) { + goto end; + } + mac_ctx = hmac; + } + + if (!rl->isdtls + && rl->tlstree + && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) + goto end; + + if (rl->isdtls) { + unsigned char dtlsseq[8], *p = dtlsseq; + + s2n(rl->epoch, p); + memcpy(p, &seq[2], 6); + + memcpy(header, dtlsseq, 8); + } else { + memcpy(header, seq, 8); + } + + header[8] = rec->type; + header[9] = (unsigned char)(rl->version >> 8); + header[10] = (unsigned char)(rl->version); + header[11] = (unsigned char)(rec->length >> 8); + header[12] = (unsigned char)(rec->length & 0xff); + + if (!sending && !rl->use_etm + && EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE + && ssl3_cbc_record_digest_supported(mac_ctx)) { + OSSL_PARAM tls_hmac_params[2], *p = tls_hmac_params; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, + &rec->orig_len); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_get_pkey_ctx(mac_ctx), + tls_hmac_params)) + goto end; + } + + if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 + || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 + || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) + goto end; + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "seq:\n"); + BIO_dump_indent(trc_out, seq, 8, 4); + BIO_printf(trc_out, "rec:\n"); + BIO_dump_indent(trc_out, rec->data, rec->length, 4); + } OSSL_TRACE_END(TLS); + + if (!rl->isdtls && !tls_increment_sequence_ctr(rl)) { + /* RLAYERfatal already called */ + goto end; + } + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "md:\n"); + BIO_dump_indent(trc_out, md, md_size, 4); + } OSSL_TRACE_END(TLS); + ret = 1; + end: + EVP_MD_CTX_free(hmac); + return ret; +} + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 +# ifndef OPENSSL_NO_COMP +# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \ + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + + SSL3_RT_HEADER_LENGTH \ + + SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# else +# define MAX_PREFIX_LEN ((SSL3_ALIGN_PAYLOAD - 1) \ + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + + SSL3_RT_HEADER_LENGTH) +# endif /* OPENSSL_NO_COMP */ +#else +# ifndef OPENSSL_NO_COMP +# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + + SSL3_RT_HEADER_LENGTH \ + + SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# else +# define MAX_PREFIX_LEN (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + + SSL3_RT_HEADER_LENGTH) +# endif /* OPENSSL_NO_COMP */ +#endif + +/* This function is also used by the SSLv3 implementation */ +int tls1_allocate_write_buffers(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, size_t *prefix) +{ + /* Do we need to add an empty record prefix? */ + *prefix = rl->need_empty_fragments + && templates[0].type == SSL3_RT_APPLICATION_DATA; + + /* + * In the prefix case we can allocate a much smaller buffer. Otherwise we + * just allocate the default buffer size + */ + if (!tls_setup_write_buffer(rl, numtempl + *prefix, + *prefix ? MAX_PREFIX_LEN : 0, 0)) { + /* RLAYERfatal() already called */ + return 0; + } + + return 1; +} + +/* This function is also used by the SSLv3 implementation */ +int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited) +{ + size_t align = 0; + TLS_BUFFER *wb; + size_t prefix; + + /* Do we need to add an empty record prefix? */ + prefix = rl->need_empty_fragments + && templates[0].type == SSL3_RT_APPLICATION_DATA; + + if (prefix) { + /* + * countermeasure against known-IV weakness in CBC ciphersuites (see + * http://www.openssl.org/~bodo/tls-cbc.txt) + */ + prefixtempl->buf = NULL; + prefixtempl->version = templates[0].version; + prefixtempl->buflen = 0; + prefixtempl->type = SSL3_RT_APPLICATION_DATA; + + wb = &bufs[0]; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + align = (size_t)TLS_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH; + align = SSL3_ALIGN_PAYLOAD - 1 + - ((align - 1) % SSL3_ALIGN_PAYLOAD); +#endif + TLS_BUFFER_set_offset(wb, align); + + if (!WPACKET_init_static_len(&pkt[0], TLS_BUFFER_get_buf(wb), + TLS_BUFFER_get_len(wb), 0)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + *wpinited = 1; + if (!WPACKET_allocate_bytes(&pkt[0], align, NULL)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return tls_initialise_write_packets_default(rl, templates, numtempl, + NULL, + pkt + prefix, bufs + prefix, + wpinited); +} + +/* TLSv1.0, TLSv1.1 and TLSv1.2 all use the same funcs */ +struct record_functions_st tls_1_funcs = { + tls1_set_crypto_state, + tls1_cipher, + tls1_mac, + tls_default_set_protocol_version, + tls_default_read_n, + tls_get_more_records, + tls_default_validate_record_header, + tls_default_post_process_record, + tls_get_max_records_multiblock, + tls_write_records_multiblock, /* Defined in tls_multib.c */ + tls1_allocate_write_buffers, + tls1_initialise_write_packets, + NULL, + tls_prepare_record_header_default, + NULL, + tls_prepare_for_encryption_default, + tls_post_encryption_processing_default, + NULL +}; + +struct record_functions_st dtls_1_funcs = { + tls1_set_crypto_state, + tls1_cipher, + tls1_mac, + tls_default_set_protocol_version, + tls_default_read_n, + dtls_get_more_records, + NULL, + NULL, + NULL, + tls_write_records_default, + /* + * Don't use tls1_allocate_write_buffers since that handles empty fragment + * records which aren't needed in DTLS. We just use the default allocation + * instead. + */ + tls_allocate_write_buffers_default, + /* Don't use tls1_initialise_write_packets for same reason as above */ + tls_initialise_write_packets_default, + NULL, + dtls_prepare_record_header, + NULL, + tls_prepare_for_encryption_default, + dtls_post_encryption_processing, + NULL +}; diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c new file mode 100644 index 0000000000..423777c18d --- /dev/null +++ b/ssl/record/methods/tls_common.c @@ -0,0 +1,2152 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/e_os.h" +#include "internal/packet.h" +#include "internal/ssl3_cbc.h" +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +static void tls_int_free(OSSL_RECORD_LAYER *rl); + +void ossl_tls_buffer_release(TLS_BUFFER *b) +{ + OPENSSL_free(b->buf); + b->buf = NULL; +} + +static void TLS_RL_RECORD_release(TLS_RL_RECORD *r, size_t num_recs) +{ + size_t i; + + for (i = 0; i < num_recs; i++) { + OPENSSL_free(r[i].comp); + r[i].comp = NULL; + } +} + +void ossl_tls_rl_record_set_seq_num(TLS_RL_RECORD *r, + const unsigned char *seq_num) +{ + memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE); +} + +void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(ERR_LIB_SSL, reason, fmt, args); + va_end(args); + + rl->alert = al; +} + +int ossl_set_tls_provider_parameters(OSSL_RECORD_LAYER *rl, + EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *ciph, + const EVP_MD *md) +{ + /* + * Provided cipher, the TLS padding/MAC removal is performed provider + * side so we need to tell the ctx about our TLS version and mac size + */ + OSSL_PARAM params[3], *pprm = params; + size_t macsize = 0; + int imacsize = -1; + + if ((EVP_CIPHER_get_flags(ciph) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0 + && !rl->use_etm) + imacsize = EVP_MD_get_size(md); + if (imacsize >= 0) + macsize = (size_t)imacsize; + + *pprm++ = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_TLS_VERSION, + &rl->version); + *pprm++ = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, + &macsize); + *pprm = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_set_params(ctx, params)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +/* + * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. + */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ + switch (EVP_MD_CTX_get_type(ctx)) { + case NID_md5: + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + return 1; + default: + return 0; + } +} + +#ifndef OPENSSL_NO_COMP +static int tls_allow_compression(OSSL_RECORD_LAYER *rl) +{ + if (rl->options & SSL_OP_NO_COMPRESSION) + return 0; + + return rl->security == NULL + || rl->security(rl->cbarg, SSL_SECOP_COMPRESSION, 0, 0, NULL); +} +#endif + +static void tls_release_write_buffer_int(OSSL_RECORD_LAYER *rl, size_t start) +{ + TLS_BUFFER *wb; + size_t pipes; + + pipes = rl->numwpipes; + + while (pipes > start) { + wb = &rl->wbuf[pipes - 1]; + + if (TLS_BUFFER_is_app_buffer(wb)) + TLS_BUFFER_set_app_buffer(wb, 0); + else + OPENSSL_free(wb->buf); + wb->buf = NULL; + pipes--; + } +} + +int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes, + size_t firstlen, size_t nextlen) +{ + unsigned char *p; + size_t align = 0, headerlen; + TLS_BUFFER *wb; + size_t currpipe; + size_t defltlen = 0; + + if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) { + if (rl->isdtls) + headerlen = DTLS1_RT_HEADER_LENGTH + 1; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + align = SSL3_ALIGN_PAYLOAD - 1; +#endif + + defltlen = rl->max_frag_len + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + + headerlen + align + rl->eivlen; +#ifndef OPENSSL_NO_COMP + if (tls_allow_compression(rl)) + defltlen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + /* + * We don't need to add eivlen here since empty fragments only occur + * when we don't have an explicit IV + */ + if (!(rl->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + defltlen += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + } + + wb = rl->wbuf; + for (currpipe = 0; currpipe < numwpipes; currpipe++) { + TLS_BUFFER *thiswb = &wb[currpipe]; + size_t len = (currpipe == 0) ? firstlen : nextlen; + + if (len == 0) + len = defltlen; + + if (thiswb->len != len) { + OPENSSL_free(thiswb->buf); + thiswb->buf = NULL; /* force reallocation */ + } + + p = thiswb->buf; + if (p == NULL) { + p = OPENSSL_malloc(len); + if (p == NULL) { + if (rl->numwpipes < currpipe) + rl->numwpipes = currpipe; + /* + * We've got a malloc failure, and we're still initialising + * buffers. We assume we're so doomed that we won't even be able + * to send an alert. + */ + RLAYERfatal(rl, SSL_AD_NO_ALERT, ERR_R_CRYPTO_LIB); + return 0; + } + } + memset(thiswb, 0, sizeof(TLS_BUFFER)); + thiswb->buf = p; + thiswb->len = len; + } + + /* Free any previously allocated buffers that we are no longer using */ + tls_release_write_buffer_int(rl, currpipe); + + rl->numwpipes = numwpipes; + + return 1; +} + +static void tls_release_write_buffer(OSSL_RECORD_LAYER *rl) +{ + tls_release_write_buffer_int(rl, 0); + + rl->numwpipes = 0; +} + +int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl) +{ + unsigned char *p; + size_t len, align = 0, headerlen; + TLS_BUFFER *b; + + b = &rl->rbuf; + + if (rl->isdtls) + headerlen = DTLS1_RT_HEADER_LENGTH; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (b->buf == NULL) { + len = rl->max_frag_len + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; +#ifndef OPENSSL_NO_COMP + if (tls_allow_compression(rl)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + + /* Ensure our buffer is large enough to support all our pipelines */ + if (rl->max_pipelines > 1) + len *= rl->max_pipelines; + + if (b->default_len > len) + len = b->default_len; + + if ((p = OPENSSL_malloc(len)) == NULL) { + /* + * We've got a malloc failure, and we're still initialising buffers. + * We assume we're so doomed that we won't even be able to send an + * alert. + */ + RLAYERfatal(rl, SSL_AD_NO_ALERT, ERR_R_CRYPTO_LIB); + return 0; + } + b->buf = p; + b->len = len; + } + + return 1; +} + +static int tls_release_read_buffer(OSSL_RECORD_LAYER *rl) +{ + TLS_BUFFER *b; + + b = &rl->rbuf; + if ((rl->options & SSL_OP_CLEANSE_PLAINTEXT) != 0) + OPENSSL_cleanse(b->buf, b->len); + OPENSSL_free(b->buf); + b->buf = NULL; + return 1; +} + +/* + * Return values are as per SSL_read() + */ +int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, + int clearold, size_t *readbytes) +{ + /* + * If extend == 0, obtain new n-byte packet; if extend == 1, increase + * packet by another n bytes. The packet will be in the sub-array of + * rl->rbuf.buf specified by rl->packet and rl->packet_length. (If + * rl->read_ahead is set, 'max' bytes may be stored in rbuf [plus + * rl->packet_length bytes if extend == 1].) if clearold == 1, move the + * packet to the start of the buffer; if clearold == 0 then leave any old + * packets where they were + */ + size_t len, left, align = 0; + unsigned char *pkt; + TLS_BUFFER *rb; + + if (n == 0) + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + + rb = &rl->rbuf; + left = rb->left; +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH; + align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); +#endif + + if (!extend) { + /* start with empty packet ... */ + if (left == 0) + rb->offset = align; + + rl->packet = rb->buf + rb->offset; + rl->packet_length = 0; + /* ... now we can act as if 'extend' was set */ + } + + len = rl->packet_length; + pkt = rb->buf + align; + /* + * Move any available bytes to front of buffer: 'len' bytes already + * pointed to by 'packet', 'left' extra ones at the end + */ + if (rl->packet != pkt && clearold == 1) { + memmove(pkt, rl->packet, len + left); + rl->packet = pkt; + rb->offset = len + align; + } + + /* + * For DTLS/UDP reads should not span multiple packets because the read + * operation returns the whole packet at once (as long as it fits into + * the buffer). + */ + if (rl->isdtls) { + if (left == 0 && extend) { + /* + * We received a record with a header but no body data. This will + * get dumped. + */ + return OSSL_RECORD_RETURN_NON_FATAL_ERR; + } + if (left > 0 && n > left) + n = left; + } + + /* if there is enough in the buffer from a previous read, take some */ + if (left >= n) { + rl->packet_length += n; + rb->left = left - n; + rb->offset += n; + *readbytes = n; + return OSSL_RECORD_RETURN_SUCCESS; + } + + /* else we need to read more data */ + + if (n > rb->len - rb->offset) { + /* does not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + /* We always act like read_ahead is set for DTLS */ + if (!rl->read_ahead && !rl->isdtls) { + /* ignore max parameter */ + max = n; + } else { + if (max < n) + max = n; + if (max > rb->len - rb->offset) + max = rb->len - rb->offset; + } + + while (left < n) { + size_t bioread = 0; + int ret; + BIO *bio = rl->prev != NULL ? rl->prev : rl->bio; + + /* + * Now we have len+left bytes at the front of rl->rbuf.buf and + * need to read in more until we have len + n (up to len + max if + * possible) + */ + + clear_sys_error(); + if (bio != NULL) { + ret = BIO_read(bio, pkt + len + left, max - left); + if (ret > 0) { + bioread = ret; + ret = OSSL_RECORD_RETURN_SUCCESS; + } else if (BIO_should_retry(bio)) { + if (rl->prev != NULL) { + /* + * We were reading from the previous epoch. Now there is no + * more data, so swap to the actual transport BIO + */ + BIO_free(rl->prev); + rl->prev = NULL; + continue; + } + ret = OSSL_RECORD_RETURN_RETRY; + } else if (BIO_eof(bio)) { + ret = OSSL_RECORD_RETURN_EOF; + } else { + ret = OSSL_RECORD_RETURN_FATAL; + } + } else { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET); + ret = OSSL_RECORD_RETURN_FATAL; + } + + if (ret <= OSSL_RECORD_RETURN_RETRY) { + rb->left = left; + if ((rl->mode & SSL_MODE_RELEASE_BUFFERS) != 0 && !rl->isdtls) + if (len + left == 0) + tls_release_read_buffer(rl); + return ret; + } + left += bioread; + /* + * reads should *never* span multiple packets for DTLS because the + * underlying transport protocol is message oriented as opposed to + * byte oriented as in the TLS case. + */ + if (rl->isdtls) { + if (n > left) + n = left; /* makes the while condition false */ + } + } + + /* done reading, now the book-keeping */ + rb->offset += n; + rb->left = left - n; + rl->packet_length += n; + *readbytes = n; + return OSSL_RECORD_RETURN_SUCCESS; +} + +/* + * Peeks ahead into "read_ahead" data to see if we have a whole record waiting + * for us in the buffer. + */ +static int tls_record_app_data_waiting(OSSL_RECORD_LAYER *rl) +{ + TLS_BUFFER *rbuf; + size_t left, len; + unsigned char *p; + + rbuf = &rl->rbuf; + + p = TLS_BUFFER_get_buf(rbuf); + if (p == NULL) + return 0; + + left = TLS_BUFFER_get_left(rbuf); + + if (left < SSL3_RT_HEADER_LENGTH) + return 0; + + p += TLS_BUFFER_get_offset(rbuf); + + /* + * We only check the type and record length, we will sanity check version + * etc later + */ + if (*p != SSL3_RT_APPLICATION_DATA) + return 0; + + p += 3; + n2s(p, len); + + if (left < SSL3_RT_HEADER_LENGTH + len) + return 0; + + return 1; +} + +static int rlayer_early_data_count_ok(OSSL_RECORD_LAYER *rl, size_t length, + size_t overhead, int send) +{ + uint32_t max_early_data = rl->max_early_data; + + if (max_early_data == 0) { + RLAYERfatal(rl, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_TOO_MUCH_EARLY_DATA); + return 0; + } + + /* If we are dealing with ciphertext we need to allow for the overhead */ + max_early_data += overhead; + + if (rl->early_data_count + length > max_early_data) { + RLAYERfatal(rl, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_TOO_MUCH_EARLY_DATA); + return 0; + } + rl->early_data_count += length; + + return 1; +} + +/* + * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that + * will be processed per call to tls_get_more_records. Without this limit an + * attacker could send empty records at a faster rate than we can process and + * cause tls_get_more_records to loop forever. + */ +#define MAX_EMPTY_RECORDS 32 + +#define SSL2_RT_HEADER_LENGTH 2 + +/*- + * Call this to buffer new input records in rl->rrec. + * It will return a OSSL_RECORD_RETURN_* value. + * When it finishes successfully (OSSL_RECORD_RETURN_SUCCESS), |rl->num_recs| + * records have been decoded. For each record 'i': + * rrec[i].type - is the type of record + * rrec[i].data, - data + * rrec[i].length, - number of bytes + * Multiple records will only be returned if the record types are all + * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <= + * |max_pipelines| + */ +int tls_get_more_records(OSSL_RECORD_LAYER *rl) +{ + int enc_err, rret; + int i; + size_t more, n; + TLS_RL_RECORD *rr, *thisrr; + TLS_BUFFER *rbuf; + unsigned char *p; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int version; + size_t mac_size = 0; + int imac_size; + size_t num_recs = 0, max_recs, j; + PACKET pkt, sslv2pkt; + SSL_MAC_BUF *macbufs = NULL; + int ret = OSSL_RECORD_RETURN_FATAL; + + rr = rl->rrec; + rbuf = &rl->rbuf; + if (rbuf->buf == NULL) { + if (!tls_setup_read_buffer(rl)) { + /* RLAYERfatal() already called */ + return OSSL_RECORD_RETURN_FATAL; + } + } + + max_recs = rl->max_pipelines; + + if (max_recs == 0) + max_recs = 1; + + do { + thisrr = &rr[num_recs]; + + /* check if we have the header */ + if ((rl->rstate != SSL_ST_READ_BODY) || + (rl->packet_length < SSL3_RT_HEADER_LENGTH)) { + size_t sslv2len; + unsigned int type; + + rret = rl->funcs->read_n(rl, SSL3_RT_HEADER_LENGTH, + TLS_BUFFER_get_len(rbuf), 0, + num_recs == 0 ? 1 : 0, &n); + + if (rret < OSSL_RECORD_RETURN_SUCCESS) + return rret; /* error or non-blocking */ + + rl->rstate = SSL_ST_READ_BODY; + + p = rl->packet; + if (!PACKET_buf_init(&pkt, p, rl->packet_length)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + sslv2pkt = pkt; + if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len) + || !PACKET_get_1(&sslv2pkt, &type)) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + /* + * The first record received by the server may be a V2ClientHello. + */ + if (rl->role == OSSL_RECORD_ROLE_SERVER + && rl->is_first_record + && (sslv2len & 0x8000) != 0 + && (type == SSL2_MT_CLIENT_HELLO)) { + /* + * SSLv2 style record + * + * |num_recs| here will actually always be 0 because + * |num_recs > 0| only ever occurs when we are processing + * multiple app data records - which we know isn't the case here + * because it is an SSLv2ClientHello. We keep it using + * |num_recs| for the sake of consistency + */ + thisrr->type = SSL3_RT_HANDSHAKE; + thisrr->rec_version = SSL2_VERSION; + + thisrr->length = sslv2len & 0x7fff; + + if (thisrr->length > TLS_BUFFER_get_len(rbuf) + - SSL2_RT_HEADER_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_PACKET_LENGTH_TOO_LONG); + return OSSL_RECORD_RETURN_FATAL; + } + } else { + /* SSLv3+ style record */ + + /* Pull apart the header into the TLS_RL_RECORD */ + if (!PACKET_get_1(&pkt, &type) + || !PACKET_get_net_2(&pkt, &version) + || !PACKET_get_net_2_len(&pkt, &thisrr->length)) { + if (rl->msg_callback != NULL) + rl->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, rl->cbarg); + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + thisrr->type = type; + thisrr->rec_version = version; + + /* + * When we call validate_record_header() only records actually + * received in SSLv2 format should have the record version set + * to SSL2_VERSION. This way validate_record_header() can know + * what format the record was in based on the version. + */ + if (thisrr->rec_version == SSL2_VERSION) { + RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, + SSL_R_WRONG_VERSION_NUMBER); + return OSSL_RECORD_RETURN_FATAL; + } + + if (rl->msg_callback != NULL) + rl->msg_callback(0, version, SSL3_RT_HEADER, p, 5, rl->cbarg); + + if (thisrr->length > + TLS_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_PACKET_LENGTH_TOO_LONG); + return OSSL_RECORD_RETURN_FATAL; + } + } + + if (!rl->funcs->validate_record_header(rl, thisrr)) { + /* RLAYERfatal already called */ + return OSSL_RECORD_RETURN_FATAL; + } + + /* now rl->rstate == SSL_ST_READ_BODY */ + } + + /* + * rl->rstate == SSL_ST_READ_BODY, get and decode the data. Calculate + * how much more data we need to read for the rest of the record + */ + if (thisrr->rec_version == SSL2_VERSION) { + more = thisrr->length + SSL2_RT_HEADER_LENGTH + - SSL3_RT_HEADER_LENGTH; + } else { + more = thisrr->length; + } + + if (more > 0) { + /* now rl->packet_length == SSL3_RT_HEADER_LENGTH */ + + rret = rl->funcs->read_n(rl, more, more, 1, 0, &n); + if (rret < OSSL_RECORD_RETURN_SUCCESS) + return rret; /* error or non-blocking io */ + } + + /* set state for later operations */ + rl->rstate = SSL_ST_READ_HEADER; + + /* + * At this point, rl->packet_length == SSL3_RT_HEADER_LENGTH + * + thisrr->length, or rl->packet_length == SSL2_RT_HEADER_LENGTH + * + thisrr->length and we have that many bytes in rl->packet + */ + if (thisrr->rec_version == SSL2_VERSION) + thisrr->input = &(rl->packet[SSL2_RT_HEADER_LENGTH]); + else + thisrr->input = &(rl->packet[SSL3_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 'rl->packet' data into 'thisrr'. + * thisrr->input points at thisrr->length bytes, which need to be copied + * into thisrr->data by either the decryption or by the decompression. + * When the data is 'copied' into the thisrr->data buffer, + * thisrr->input will be updated to point at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] + * thisrr->length bytes of encrypted compressed stuff. + */ + + /* decrypt in place in 'thisrr->input' */ + thisrr->data = thisrr->input; + thisrr->orig_len = thisrr->length; + + num_recs++; + + /* we have pulled in a full packet so zero things */ + rl->packet_length = 0; + rl->is_first_record = 0; + } while (num_recs < max_recs + && thisrr->type == SSL3_RT_APPLICATION_DATA + && RLAYER_USE_EXPLICIT_IV(rl) + && rl->enc_ctx != NULL + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx)) + & EVP_CIPH_FLAG_PIPELINE) != 0 + && tls_record_app_data_waiting(rl)); + + if (num_recs == 1 + && thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC + /* The following can happen in tlsany_meth after HRR */ + && rl->version == TLS1_3_VERSION + && rl->is_first_handshake) { + /* + * CCS messages must be exactly 1 byte long, containing the value 0x01 + */ + if (thisrr->length != 1 || thisrr->data[0] != 0x01) { + RLAYERfatal(rl, SSL_AD_ILLEGAL_PARAMETER, + SSL_R_INVALID_CCS_MESSAGE); + return OSSL_RECORD_RETURN_FATAL; + } + /* + * CCS messages are ignored in TLSv1.3. We treat it like an empty + * handshake record + */ + thisrr->type = SSL3_RT_HANDSHAKE; + if (++(rl->empty_record_count) > MAX_EMPTY_RECORDS) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_UNEXPECTED_CCS_MESSAGE); + return OSSL_RECORD_RETURN_FATAL; + } + rl->num_recs = 0; + rl->curr_rec = 0; + rl->num_released = 0; + + return OSSL_RECORD_RETURN_SUCCESS; + } + + if (rl->md_ctx != NULL) { + const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(rl->md_ctx); + + if (tmpmd != NULL) { + imac_size = EVP_MD_get_size(tmpmd); + if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return OSSL_RECORD_RETURN_FATAL; + } + mac_size = (size_t)imac_size; + } + } + + /* + * If in encrypt-then-mac mode calculate mac from encrypted record. All + * the details below are public so no timing details can leak. + */ + if (rl->use_etm && rl->md_ctx != NULL) { + unsigned char *mac; + + for (j = 0; j < num_recs; j++) { + thisrr = &rr[j]; + + if (thisrr->length < mac_size) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); + return OSSL_RECORD_RETURN_FATAL; + } + thisrr->length -= mac_size; + mac = thisrr->data + thisrr->length; + i = rl->funcs->mac(rl, thisrr, md, 0 /* not send */); + if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) { + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + return OSSL_RECORD_RETURN_FATAL; + } + } + /* + * We've handled the mac now - there is no MAC inside the encrypted + * record + */ + mac_size = 0; + } + + if (mac_size > 0) { + macbufs = OPENSSL_zalloc(sizeof(*macbufs) * num_recs); + if (macbufs == NULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); + return OSSL_RECORD_RETURN_FATAL; + } + } + + ERR_set_mark(); + enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size); + + /*- + * enc_err is: + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or ETM decryption failed. + * 1: Success or MTE decryption failed (MAC will be randomised) + */ + if (enc_err == 0) { + if (rl->alert != SSL_AD_NO_ALERT) { + /* RLAYERfatal() already got called */ + ERR_clear_last_mark(); + goto end; + } + if (num_recs == 1 + && rl->skip_early_data != NULL + && rl->skip_early_data(rl->cbarg)) { + /* + * Valid early_data that we cannot decrypt will fail here. We treat + * it like an empty record. + */ + + /* + * Remove any errors from the stack. Decryption failures are normal + * behaviour. + */ + ERR_pop_to_mark(); + + thisrr = &rr[0]; + + if (!rlayer_early_data_count_ok(rl, thisrr->length, + EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { + /* RLAYERfatal() already called */ + goto end; + } + + thisrr->length = 0; + rl->num_recs = 0; + rl->curr_rec = 0; + rl->num_released = 0; + /* Reset the read sequence */ + memset(rl->sequence, 0, sizeof(rl->sequence)); + ret = 1; + goto end; + } + ERR_clear_last_mark(); + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto end; + } else { + ERR_clear_last_mark(); + } + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "dec %lu\n", (unsigned long)rr[0].length); + BIO_dump_indent(trc_out, rr[0].data, rr[0].length, 4); + } OSSL_TRACE_END(TLS); + + /* r->length is now the compressed data plus mac */ + if (rl->enc_ctx != NULL + && !rl->use_etm + && EVP_MD_CTX_get0_md(rl->md_ctx) != NULL) { + for (j = 0; j < num_recs; j++) { + SSL_MAC_BUF *thismb = &macbufs[j]; + + thisrr = &rr[j]; + + i = rl->funcs->mac(rl, thisrr, md, 0 /* not send */); + if (i == 0 || thismb == NULL || thismb->mac == NULL + || CRYPTO_memcmp(md, thismb->mac, (size_t)mac_size) != 0) + enc_err = 0; + if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = 0; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (enc_err == 0 && mac_size > 0 && thismb != NULL && + thismb->mac != NULL && (md[0] ^ thismb->mac[0]) != 0xFF) { + enc_err = 1; + } +#endif + } + } + + if (enc_err == 0) { + if (rl->alert != SSL_AD_NO_ALERT) { + /* We already called RLAYERfatal() */ + goto end; + } + /* + * A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption + * failure is directly visible from the ciphertext anyway, we should + * not reveal which kind of error occurred -- this might become + * visible to an attacker (e.g. via a logfile) + */ + RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto end; + } + + for (j = 0; j < num_recs; j++) { + thisrr = &rr[j]; + + if (!rl->funcs->post_process_record(rl, thisrr)) { + /* RLAYERfatal already called */ + goto end; + } + + /* + * Check if the received packet overflows the current + * Max Fragment Length setting. + * Note: rl->max_frag_len > 0 and KTLS are mutually exclusive. + */ + if (thisrr->length > rl->max_frag_len) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + goto end; + } + + thisrr->off = 0; + /*- + * So at this point the following is true + * thisrr->type is the type of record + * thisrr->length == number of bytes in record + * thisrr->off == offset to first valid byte + * thisrr->data == where to take bytes from, increment after use :-). + */ + + /* just read a 0 length packet */ + if (thisrr->length == 0) { + if (++(rl->empty_record_count) > MAX_EMPTY_RECORDS) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_RECORD_TOO_SMALL); + goto end; + } + } else { + rl->empty_record_count = 0; + } + } + + if (rl->level == OSSL_RECORD_PROTECTION_LEVEL_EARLY) { + thisrr = &rr[0]; + if (thisrr->type == SSL3_RT_APPLICATION_DATA + && !rlayer_early_data_count_ok(rl, thisrr->length, 0, 0)) { + /* RLAYERfatal already called */ + goto end; + } + } + + rl->num_recs = num_recs; + rl->curr_rec = 0; + rl->num_released = 0; + ret = OSSL_RECORD_RETURN_SUCCESS; + end: + if (macbufs != NULL) { + for (j = 0; j < num_recs; j++) { + if (macbufs[j].alloced) + OPENSSL_free(macbufs[j].mac); + } + OPENSSL_free(macbufs); + } + return ret; +} + +/* Shared by ssl3_meth and tls1_meth */ +int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH; + + if (rec->rec_version != rl->version) { + RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + +#ifndef OPENSSL_NO_COMP + /* + * If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH + * does not include the compression overhead anyway. + */ + if (rl->compctx == NULL) + len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + + if (rec->length > len) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + return 0; + } + + return 1; +} + +int tls_do_compress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *wr) +{ +#ifndef OPENSSL_NO_COMP + int i; + + i = COMP_compress_block(rl->compctx, wr->data, + (int)(wr->length + SSL3_RT_MAX_COMPRESSED_OVERHEAD), + wr->input, (int)wr->length); + if (i < 0) + return 0; + + wr->length = i; + wr->input = wr->data; + return 1; +#else + return 0; +#endif +} + +int tls_do_uncompress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ +#ifndef OPENSSL_NO_COMP + int i; + + if (rec->comp == NULL) { + rec->comp = (unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); + } + if (rec->comp == NULL) + return 0; + + i = COMP_expand_block(rl->compctx, rec->comp, SSL3_RT_MAX_PLAIN_LENGTH, + rec->data, (int)rec->length); + if (i < 0) + return 0; + else + rec->length = i; + rec->data = rec->comp; + return 1; +#else + return 0; +#endif +} + +/* Shared by tlsany_meth, ssl3_meth and tls1_meth */ +int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + if (rl->compctx != NULL) { + if (rec->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, + SSL_R_COMPRESSED_LENGTH_TOO_LONG); + return 0; + } + if (!tls_do_uncompress(rl, rec)) { + RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE, + SSL_R_BAD_DECOMPRESSION); + return 0; + } + } + + if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) { + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + + return 1; +} + +/* Shared by tls13_meth and ktls_meth */ +int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + if (rec->type != SSL3_RT_APPLICATION_DATA + && rec->type != SSL3_RT_ALERT + && rec->type != SSL3_RT_HANDSHAKE) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); + return 0; + } + + if (rl->msg_callback != NULL) + rl->msg_callback(0, rl->version, SSL3_RT_INNER_CONTENT_TYPE, &rec->type, + 1, rl->cbarg); + + /* + * TLSv1.3 alert and handshake records are required to be non-zero in + * length. + */ + if ((rec->type == SSL3_RT_HANDSHAKE || rec->type == SSL3_RT_ALERT) + && rec->length == 0) { + RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH); + return 0; + } + + return 1; +} + +int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, + uint8_t *type, const unsigned char **data, size_t *datalen, + uint16_t *epoch, unsigned char *seq_num) +{ + TLS_RL_RECORD *rec; + + /* + * tls_get_more_records() can return success without actually reading + * anything useful (i.e. if empty records are read). We loop here until + * we have something useful. tls_get_more_records() will eventually fail if + * too many sequential empty records are read. + */ + while (rl->curr_rec >= rl->num_recs) { + int ret; + + if (rl->num_released != rl->num_recs) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_RECORDS_NOT_RELEASED); + return OSSL_RECORD_RETURN_FATAL; + } + + ret = rl->funcs->get_more_records(rl); + + if (ret != OSSL_RECORD_RETURN_SUCCESS) + return ret; + } + + /* + * We have now got rl->num_recs records buffered in rl->rrec. rl->curr_rec + * points to the next one to read. + */ + rec = &rl->rrec[rl->curr_rec++]; + + *rechandle = rec; + *rversion = rec->rec_version; + *type = rec->type; + *data = rec->data + rec->off; + *datalen = rec->length; + if (rl->isdtls) { + *epoch = rec->epoch; + memcpy(seq_num, rec->seq_num, sizeof(rec->seq_num)); + } + + return OSSL_RECORD_RETURN_SUCCESS; +} + +int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length) +{ + TLS_RL_RECORD *rec = &rl->rrec[rl->num_released]; + + if (!ossl_assert(rl->num_released < rl->curr_rec) + || !ossl_assert(rechandle == rec)) { + /* Should not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_INVALID_RECORD); + return OSSL_RECORD_RETURN_FATAL; + } + + if (rec->length < length) { + /* Should not happen */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if ((rl->options & SSL_OP_CLEANSE_PLAINTEXT) != 0) + OPENSSL_cleanse(rec->data + rec->off, length); + + rec->off += length; + rec->length -= length; + + if (rec->length > 0) + return OSSL_RECORD_RETURN_SUCCESS; + + rl->num_released++; + + if (rl->curr_rec == rl->num_released + && (rl->mode & SSL_MODE_RELEASE_BUFFERS) != 0 + && TLS_BUFFER_get_left(&rl->rbuf) == 0) + tls_release_read_buffer(rl); + + return OSSL_RECORD_RETURN_SUCCESS; +} + +int tls_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options) +{ + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS); + if (p != NULL && !OSSL_PARAM_get_uint64(p, &rl->options)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + return 0; + } + + p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE); + if (p != NULL && !OSSL_PARAM_get_uint32(p, &rl->mode)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + return 0; + } + + if (rl->direction == OSSL_RECORD_DIRECTION_READ) { + p = OSSL_PARAM_locate_const(options, + OSSL_LIBSSL_RECORD_LAYER_READ_BUFFER_LEN); + if (p != NULL && !OSSL_PARAM_get_size_t(p, &rl->rbuf.default_len)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + return 0; + } + } else { + p = OSSL_PARAM_locate_const(options, + OSSL_LIBSSL_RECORD_LAYER_PARAM_BLOCK_PADDING); + if (p != NULL && !OSSL_PARAM_get_size_t(p, &rl->block_padding)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + return 0; + } + } + + if (rl->level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION) { + /* + * We ignore any read_ahead setting prior to the application protection + * level. Otherwise we may read ahead data in a lower protection level + * that is destined for a higher protection level. To simplify the logic + * we don't support that at this stage. + */ + p = OSSL_PARAM_locate_const(options, + OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD); + if (p != NULL && !OSSL_PARAM_get_int(p, &rl->read_ahead)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + return 0; + } + } + + return 1; +} + +int +tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, unsigned char *key, + size_t keylen, unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, BIO *prev, + BIO *transport, BIO *next, BIO_ADDR *local, + BIO_ADDR *peer, const OSSL_PARAM *settings, + const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, + OSSL_RECORD_LAYER **retrl) +{ + OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl)); + const OSSL_PARAM *p; + + *retrl = NULL; + + if (rl == NULL) + return OSSL_RECORD_RETURN_FATAL; + + /* + * Default the value for max_frag_len. This may be overridden by the + * settings + */ + rl->max_frag_len = SSL3_RT_MAX_PLAIN_LENGTH; + + /* Loop through all the settings since they must all be understood */ + if (settings != NULL) { + for (p = settings; p->key != NULL; p++) { + if (strcmp(p->key, OSSL_LIBSSL_RECORD_LAYER_PARAM_USE_ETM) == 0) { + if (!OSSL_PARAM_get_int(p, &rl->use_etm)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + } else if (strcmp(p->key, + OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN) == 0) { + if (!OSSL_PARAM_get_uint(p, &rl->max_frag_len)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + } else if (strcmp(p->key, + OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_EARLY_DATA) == 0) { + if (!OSSL_PARAM_get_uint32(p, &rl->max_early_data)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + } else if (strcmp(p->key, + OSSL_LIBSSL_RECORD_LAYER_PARAM_STREAM_MAC) == 0) { + if (!OSSL_PARAM_get_int(p, &rl->stream_mac)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + } else if (strcmp(p->key, + OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE) == 0) { + if (!OSSL_PARAM_get_int(p, &rl->tlstree)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + } else { + ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_MANDATORY_PARAMETER); + goto err; + } + } + } + + rl->libctx = libctx; + rl->propq = propq; + + rl->version = vers; + rl->role = role; + rl->direction = direction; + rl->level = level; + rl->taglen = taglen; + rl->md = md; + + rl->alert = SSL_AD_NO_ALERT; + rl->rstate = SSL_ST_READ_HEADER; + + if (level == OSSL_RECORD_PROTECTION_LEVEL_NONE) + rl->is_first_record = 1; + + if (!tls_set1_bio(rl, transport)) + goto err; + + if (prev != NULL && !BIO_up_ref(prev)) + goto err; + rl->prev = prev; + + if (next != NULL && !BIO_up_ref(next)) + goto err; + rl->next = next; + + rl->cbarg = cbarg; + if (fns != NULL) { + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_RLAYER_SKIP_EARLY_DATA: + rl->skip_early_data = OSSL_FUNC_rlayer_skip_early_data(fns); + break; + case OSSL_FUNC_RLAYER_MSG_CALLBACK: + rl->msg_callback = OSSL_FUNC_rlayer_msg_callback(fns); + break; + case OSSL_FUNC_RLAYER_SECURITY: + rl->security = OSSL_FUNC_rlayer_security(fns); + break; + case OSSL_FUNC_RLAYER_PADDING: + rl->padding = OSSL_FUNC_rlayer_padding(fns); + default: + /* Just ignore anything we don't understand */ + break; + } + } + } + + if (!tls_set_options(rl, options)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } + + if ((rl->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) == 0 + && rl->version <= TLS1_VERSION + && !EVP_CIPHER_is_a(ciph, "NULL") + && !EVP_CIPHER_is_a(ciph, "RC4")) { + /* + * Enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + rl->need_empty_fragments = 1; + } + + *retrl = rl; + return OSSL_RECORD_RETURN_SUCCESS; + err: + tls_int_free(rl); + return OSSL_RECORD_RETURN_FATAL; +} + +static int +tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + int role, int direction, int level, uint16_t epoch, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, unsigned char *iv, + size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, + const EVP_MD *md, COMP_METHOD *comp, + const EVP_MD *kdfdigest, BIO *prev, BIO *transport, + BIO *next, BIO_ADDR *local, BIO_ADDR *peer, + const OSSL_PARAM *settings, const OSSL_PARAM *options, + const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, + OSSL_RECORD_LAYER **retrl) +{ + int ret; + + ret = tls_int_new_record_layer(libctx, propq, vers, role, direction, level, + key, keylen, iv, ivlen, mackey, mackeylen, + ciph, taglen, mactype, md, comp, prev, + transport, next, local, peer, settings, + options, fns, cbarg, retrl); + + if (ret != OSSL_RECORD_RETURN_SUCCESS) + return ret; + + switch (vers) { + case TLS_ANY_VERSION: + (*retrl)->funcs = &tls_any_funcs; + break; + case TLS1_3_VERSION: + (*retrl)->funcs = &tls_1_3_funcs; + break; + case TLS1_2_VERSION: + case TLS1_1_VERSION: + case TLS1_VERSION: + (*retrl)->funcs = &tls_1_funcs; + break; + case SSL3_VERSION: + (*retrl)->funcs = &ssl_3_0_funcs; + break; + default: + /* Should not happen */ + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + ret = OSSL_RECORD_RETURN_FATAL; + goto err; + } + + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, + ivlen, mackey, mackeylen, ciph, + taglen, mactype, md, comp); + + err: + if (ret != OSSL_RECORD_RETURN_SUCCESS) { + tls_int_free(*retrl); + *retrl = NULL; + } + return ret; +} + +static void tls_int_free(OSSL_RECORD_LAYER *rl) +{ + BIO_free(rl->prev); + BIO_free(rl->bio); + BIO_free(rl->next); + ossl_tls_buffer_release(&rl->rbuf); + + tls_release_write_buffer(rl); + + EVP_CIPHER_CTX_free(rl->enc_ctx); + EVP_MD_CTX_free(rl->md_ctx); +#ifndef OPENSSL_NO_COMP + COMP_CTX_free(rl->compctx); +#endif + + if (rl->version == SSL3_VERSION) + OPENSSL_cleanse(rl->mac_secret, sizeof(rl->mac_secret)); + + TLS_RL_RECORD_release(rl->rrec, SSL_MAX_PIPELINES); + + OPENSSL_free(rl); +} + +int tls_free(OSSL_RECORD_LAYER *rl) +{ + TLS_BUFFER *rbuf; + size_t left, written; + int ret = 1; + + if (rl == NULL) + return 1; + + rbuf = &rl->rbuf; + + left = TLS_BUFFER_get_left(rbuf); + if (left > 0) { + /* + * This record layer is closing but we still have data left in our + * buffer. It must be destined for the next epoch - so push it there. + */ + ret = BIO_write_ex(rl->next, rbuf->buf + rbuf->offset, left, &written); + } + tls_int_free(rl); + + return ret; +} + +int tls_unprocessed_read_pending(OSSL_RECORD_LAYER *rl) +{ + return TLS_BUFFER_get_left(&rl->rbuf) != 0; +} + +int tls_processed_read_pending(OSSL_RECORD_LAYER *rl) +{ + return rl->curr_rec < rl->num_recs; +} + +size_t tls_app_data_pending(OSSL_RECORD_LAYER *rl) +{ + size_t i; + size_t num = 0; + + for (i = rl->curr_rec; i < rl->num_recs; i++) { + if (rl->rrec[i].type != SSL3_RT_APPLICATION_DATA) + return num; + num += rl->rrec[i].length; + } + return num; +} + +size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, + size_t maxfrag, size_t *preffrag) +{ + /* + * If we have a pipeline capable cipher, and we have been configured to use + * it, then return the preferred number of pipelines. + */ + if (rl->max_pipelines > 0 + && rl->enc_ctx != NULL + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx)) + & EVP_CIPH_FLAG_PIPELINE) != 0 + && RLAYER_USE_EXPLICIT_IV(rl)) { + size_t pipes; + + if (len == 0) + return 1; + pipes = ((len - 1) / *preffrag) + 1; + + return (pipes < rl->max_pipelines) ? pipes : rl->max_pipelines; + } + + return 1; +} + +size_t tls_get_max_records(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len, + size_t maxfrag, size_t *preffrag) +{ + return rl->funcs->get_max_records(rl, type, len, maxfrag, preffrag); +} + +int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + size_t *prefix) +{ + if (!tls_setup_write_buffer(rl, numtempl, 0, 0)) { + /* RLAYERfatal() already called */ + return 0; + } + + return 1; +} + +int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl, + OSSL_RECORD_TEMPLATE *prefixtempl, + WPACKET *pkt, + TLS_BUFFER *bufs, + size_t *wpinited) +{ + WPACKET *thispkt; + size_t j, align; + TLS_BUFFER *wb; + + for (j = 0; j < numtempl; j++) { + thispkt = &pkt[j]; + wb = &bufs[j]; + + wb->type = templates[j].type; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + align = (size_t)TLS_BUFFER_get_buf(wb); + align += rl->isdtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH; + align = SSL3_ALIGN_PAYLOAD - 1 + - ((align - 1) % SSL3_ALIGN_PAYLOAD); +#endif + TLS_BUFFER_set_offset(wb, align); + + if (!WPACKET_init_static_len(thispkt, TLS_BUFFER_get_buf(wb), + TLS_BUFFER_get_len(wb), 0)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + (*wpinited)++; + if (!WPACKET_allocate_bytes(thispkt, align, NULL)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return 1; +} + +int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl, + WPACKET *thispkt, + OSSL_RECORD_TEMPLATE *templ, + uint8_t rectype, + unsigned char **recdata) +{ + size_t maxcomplen; + + *recdata = NULL; + + maxcomplen = templ->buflen; + if (rl->compctx != NULL) + maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; + + if (!WPACKET_put_bytes_u8(thispkt, rectype) + || !WPACKET_put_bytes_u16(thispkt, templ->version) + || !WPACKET_start_sub_packet_u16(thispkt) + || (rl->eivlen > 0 + && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL)) + || (maxcomplen > 0 + && !WPACKET_reserve_bytes(thispkt, maxcomplen, + recdata))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl, + size_t mac_size, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + size_t len; + unsigned char *recordstart; + + /* + * we should still have the output to thiswr->data and the input from + * wr->input. Length should be thiswr->length. thiswr->data still points + * in the wb->buf + */ + + if (!rl->use_etm && mac_size != 0) { + unsigned char *mac; + + if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) + || !rl->funcs->mac(rl, thiswr, mac, 1)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + /* + * Reserve some bytes for any growth that may occur during encryption. If + * we are adding the MAC independently of the cipher algorithm, then the + * max encrypted overhead does not need to include an allocation for that + * MAC + */ + if (!WPACKET_reserve_bytes(thispkt, SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + - mac_size, NULL) + /* + * We also need next the amount of bytes written to this + * sub-packet + */ + || !WPACKET_get_length(thispkt, &len)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Get a pointer to the start of this record excluding header */ + recordstart = WPACKET_get_curr(thispkt) - len; + TLS_RL_RECORD_set_data(thiswr, recordstart); + TLS_RL_RECORD_reset_input(thiswr); + TLS_RL_RECORD_set_length(thiswr, len); + + return 1; +} + +int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl, + size_t mac_size, + OSSL_RECORD_TEMPLATE *thistempl, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + size_t origlen, len; + size_t headerlen = rl->isdtls ? DTLS1_RT_HEADER_LENGTH + : SSL3_RT_HEADER_LENGTH; + + /* Allocate bytes for the encryption overhead */ + if (!WPACKET_get_length(thispkt, &origlen) + /* Check we allowed enough room for the encryption growth */ + || !ossl_assert(origlen + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + - mac_size >= thiswr->length) + /* Encryption should never shrink the data! */ + || origlen > thiswr->length + || (thiswr->length > origlen + && !WPACKET_allocate_bytes(thispkt, + thiswr->length - origlen, + NULL))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + if (rl->use_etm && mac_size != 0) { + unsigned char *mac; + + if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) + || !rl->funcs->mac(rl, thiswr, mac, 1)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + TLS_RL_RECORD_add_length(thiswr, mac_size); + } + + if (!WPACKET_get_length(thispkt, &len) + || !WPACKET_close(thispkt)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (rl->msg_callback != NULL) { + unsigned char *recordstart; + + recordstart = WPACKET_get_curr(thispkt) - len - headerlen; + rl->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart, + headerlen, rl->cbarg); + + if (rl->version == TLS1_3_VERSION && rl->enc_ctx != NULL) { + unsigned char ctype = thistempl->type; + + rl->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE, + &ctype, 1, rl->cbarg); + } + } + + if (!WPACKET_finish(thispkt)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + TLS_RL_RECORD_add_length(thiswr, headerlen); + + return 1; +} + +int tls_write_records_default(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl) +{ + WPACKET pkt[SSL_MAX_PIPELINES + 1]; + TLS_RL_RECORD wr[SSL_MAX_PIPELINES + 1]; + WPACKET *thispkt; + TLS_RL_RECORD *thiswr; + int mac_size = 0, ret = 0; + size_t wpinited = 0; + size_t j, prefix = 0; + OSSL_RECORD_TEMPLATE prefixtempl; + OSSL_RECORD_TEMPLATE *thistempl; + + if (rl->md_ctx != NULL && EVP_MD_CTX_get0_md(rl->md_ctx) != NULL) { + mac_size = EVP_MD_CTX_get_size(rl->md_ctx); + if (mac_size < 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (!rl->funcs->allocate_write_buffers(rl, templates, numtempl, &prefix)) { + /* RLAYERfatal() already called */ + goto err; + } + + if (!rl->funcs->initialise_write_packets(rl, templates, numtempl, + &prefixtempl, pkt, rl->wbuf, + &wpinited)) { + /* RLAYERfatal() already called */ + goto err; + } + + /* Clear our TLS_RL_RECORD structures */ + memset(wr, 0, sizeof(wr)); + for (j = 0; j < numtempl + prefix; j++) { + unsigned char *compressdata = NULL; + uint8_t rectype; + + thispkt = &pkt[j]; + thiswr = &wr[j]; + thistempl = (j < prefix) ? &prefixtempl : &templates[j - prefix]; + + /* + * Default to the record type as specified in the template unless the + * protocol implementation says differently. + */ + if (rl->funcs->get_record_type != NULL) + rectype = rl->funcs->get_record_type(rl, thistempl); + else + rectype = thistempl->type; + + TLS_RL_RECORD_set_type(thiswr, rectype); + TLS_RL_RECORD_set_rec_version(thiswr, thistempl->version); + + if (!rl->funcs->prepare_record_header(rl, thispkt, thistempl, rectype, + &compressdata)) { + /* RLAYERfatal() already called */ + goto err; + } + + /* lets setup the record stuff. */ + TLS_RL_RECORD_set_data(thiswr, compressdata); + TLS_RL_RECORD_set_length(thiswr, thistempl->buflen); + + TLS_RL_RECORD_set_input(thiswr, (unsigned char *)thistempl->buf); + + /* + * we now 'read' from thiswr->input, thiswr->length bytes into + * thiswr->data + */ + + /* first we compress */ + if (rl->compctx != NULL) { + if (!tls_do_compress(rl, thiswr) + || !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE); + goto err; + } + } else if (compressdata != NULL) { + if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + TLS_RL_RECORD_reset_input(&wr[j]); + } + + if (rl->funcs->add_record_padding != NULL + && !rl->funcs->add_record_padding(rl, thistempl, thispkt, + thiswr)) { + /* RLAYERfatal() already called */ + goto err; + } + + if (!rl->funcs->prepare_for_encryption(rl, mac_size, thispkt, thiswr)) { + /* RLAYERfatal() already called */ + goto err; + } + } + + if (prefix) { + if (rl->funcs->cipher(rl, wr, 1, 1, NULL, mac_size) < 1) { + if (rl->alert == SSL_AD_NO_ALERT) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + } + goto err; + } + } + + if (rl->funcs->cipher(rl, wr + prefix, numtempl, 1, NULL, mac_size) < 1) { + if (rl->alert == SSL_AD_NO_ALERT) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + } + goto err; + } + + for (j = 0; j < numtempl + prefix; j++) { + thispkt = &pkt[j]; + thiswr = &wr[j]; + thistempl = (j < prefix) ? &prefixtempl : &templates[j - prefix]; + + if (!rl->funcs->post_encryption_processing(rl, mac_size, thistempl, + thispkt, thiswr)) { + /* RLAYERfatal() already called */ + goto err; + } + + /* now let's set up wb */ + TLS_BUFFER_set_left(&rl->wbuf[j], TLS_RL_RECORD_get_length(thiswr)); + } + + ret = 1; + err: + for (j = 0; j < wpinited; j++) + WPACKET_cleanup(&pkt[j]); + return ret; +} + +int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, + size_t numtempl) +{ + /* Check we don't have pending data waiting to write */ + if (!ossl_assert(rl->nextwbuf >= rl->numwpipes + || TLS_BUFFER_get_left(&rl->wbuf[rl->nextwbuf]) == 0)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return OSSL_RECORD_RETURN_FATAL; + } + + if (!rl->funcs->write_records(rl, templates, numtempl)) { + /* RLAYERfatal already called */ + return OSSL_RECORD_RETURN_FATAL; + } + + rl->nextwbuf = 0; + /* we now just need to write the buffers */ + return tls_retry_write_records(rl); +} + +int tls_retry_write_records(OSSL_RECORD_LAYER *rl) +{ + int i, ret; + TLS_BUFFER *thiswb; + size_t tmpwrit = 0; + + if (rl->nextwbuf >= rl->numwpipes) + return OSSL_RECORD_RETURN_SUCCESS; + + for (;;) { + thiswb = &rl->wbuf[rl->nextwbuf]; + + clear_sys_error(); + if (rl->bio != NULL) { + if (rl->funcs->prepare_write_bio != NULL) { + ret = rl->funcs->prepare_write_bio(rl, thiswb->type); + if (ret != OSSL_RECORD_RETURN_SUCCESS) + return ret; + } + i = BIO_write(rl->bio, (char *) + &(TLS_BUFFER_get_buf(thiswb) + [TLS_BUFFER_get_offset(thiswb)]), + (unsigned int)TLS_BUFFER_get_left(thiswb)); + if (i >= 0) { + tmpwrit = i; + if (i == 0 && BIO_should_retry(rl->bio)) + ret = OSSL_RECORD_RETURN_RETRY; + else + ret = OSSL_RECORD_RETURN_SUCCESS; + } else { + if (BIO_should_retry(rl->bio)) + ret = OSSL_RECORD_RETURN_RETRY; + else + ret = OSSL_RECORD_RETURN_FATAL; + } + } else { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BIO_NOT_SET); + ret = OSSL_RECORD_RETURN_FATAL; + i = -1; + } + + /* + * When an empty fragment is sent on a connection using KTLS, + * it is sent as a write of zero bytes. If this zero byte + * write succeeds, i will be 0 rather than a non-zero value. + * Treat i == 0 as success rather than an error for zero byte + * writes to permit this case. + */ + if (i >= 0 && tmpwrit == TLS_BUFFER_get_left(thiswb)) { + TLS_BUFFER_set_left(thiswb, 0); + TLS_BUFFER_add_offset(thiswb, tmpwrit); + if (++(rl->nextwbuf) < rl->numwpipes) + continue; + + if (rl->nextwbuf == rl->numwpipes + && (rl->mode & SSL_MODE_RELEASE_BUFFERS) != 0) + tls_release_write_buffer(rl); + return OSSL_RECORD_RETURN_SUCCESS; + } else if (i <= 0) { + if (rl->isdtls) { + /* + * For DTLS, just drop it. That's kind of the whole point in + * using a datagram service + */ + TLS_BUFFER_set_left(thiswb, 0); + if (++(rl->nextwbuf) == rl->numwpipes + && (rl->mode & SSL_MODE_RELEASE_BUFFERS) != 0) + tls_release_write_buffer(rl); + + } + return ret; + } + TLS_BUFFER_add_offset(thiswb, tmpwrit); + TLS_BUFFER_sub_left(thiswb, tmpwrit); + } +} + +int tls_get_alert_code(OSSL_RECORD_LAYER *rl) +{ + return rl->alert; +} + +int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio) +{ + if (bio != NULL && !BIO_up_ref(bio)) + return 0; + BIO_free(rl->bio); + rl->bio = bio; + + return 1; +} + +/* Shared by most methods except tlsany_meth */ +int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version) +{ + if (rl->version != version) + return 0; + + return 1; +} + +int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version) +{ + return rl->funcs->set_protocol_version(rl, version); +} + +void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow) +{ + rl->allow_plain_alerts = allow; +} + +void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first) +{ + rl->is_first_handshake = first; +} + +void tls_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines) +{ + rl->max_pipelines = max_pipelines; + if (max_pipelines > 1) + rl->read_ahead = 1; +} + +void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr, + const char **longstr) +{ + const char *shrt, *lng; + + switch (rl->rstate) { + case SSL_ST_READ_HEADER: + shrt = "RH"; + lng = "read header"; + break; + case SSL_ST_READ_BODY: + shrt = "RB"; + lng = "read body"; + break; + default: + shrt = lng = "unknown"; + break; + } + if (shortstr != NULL) + *shortstr = shrt; + if (longstr != NULL) + *longstr = lng; +} + +const COMP_METHOD *tls_get_compression(OSSL_RECORD_LAYER *rl) +{ +#ifndef OPENSSL_NO_COMP + return (rl->compctx == NULL) ? NULL : COMP_CTX_get_method(rl->compctx); +#else + return NULL; +#endif +} + +void tls_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len) +{ + rl->max_frag_len = max_frag_len; + /* + * We don't need to adjust buffer sizes. Write buffer sizes are + * automatically checked anyway. We should only be changing the read buffer + * size during the handshake, so we will create a new buffer when we create + * the new record layer. We can't change the existing buffer because it may + * already have data in it. + */ +} + +int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) +{ + int i; + + /* Increment the sequence counter */ + for (i = SEQ_NUM_SIZE; i > 0; i--) { + ++(rl->sequence[i - 1]); + if (rl->sequence[i - 1] != 0) + break; + } + if (i == 0) { + /* Sequence has wrapped */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_SEQUENCE_CTR_WRAPPED); + return 0; + } + return 1; +} + +int tls_alloc_buffers(OSSL_RECORD_LAYER *rl) +{ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + /* If we have a pending write then buffers are already allocated */ + if (rl->nextwbuf < rl->numwpipes) + return 1; + /* + * We assume 1 pipe with default sized buffer. If what we need ends up + * being a different size to that then it will be reallocated on demand. + * If we need more than 1 pipe then that will also be allocated on + * demand + */ + if (!tls_setup_write_buffer(rl, 1, 0, 0)) + return 0; + + /* + * Normally when we allocate write buffers we immediately write + * something into it. In this case we're not doing that so mark the + * buffer as empty. + */ + TLS_BUFFER_set_left(&rl->wbuf[0], 0); + return 1; + } + + /* Read direction */ + + /* If we have pending data to be read then buffers are already allocated */ + if (rl->curr_rec < rl->num_recs || TLS_BUFFER_get_left(&rl->rbuf) != 0) + return 1; + return tls_setup_read_buffer(rl); +} + +int tls_free_buffers(OSSL_RECORD_LAYER *rl) +{ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + if (rl->nextwbuf < rl->numwpipes) { + /* + * We may have pending data. If we've just got one empty buffer + * allocated then it has probably just been alloc'd via + * tls_alloc_buffers, and it is fine to free it. Otherwise this + * looks like real pending data and it is an error. + */ + if (rl->nextwbuf != 0 + || rl->numwpipes != 1 + || TLS_BUFFER_get_left(&rl->wbuf[0]) != 0) + return 0; + } + tls_release_write_buffer(rl); + return 1; + } + + /* Read direction */ + + /* If we have pending data to be read then fail */ + if (rl->curr_rec < rl->num_recs || TLS_BUFFER_get_left(&rl->rbuf) != 0) + return 0; + + return tls_release_read_buffer(rl); +} + +const OSSL_RECORD_METHOD ossl_tls_record_method = { + tls_new_record_layer, + tls_free, + tls_unprocessed_read_pending, + tls_processed_read_pending, + tls_app_data_pending, + tls_get_max_records, + tls_write_records, + tls_retry_write_records, + tls_read_record, + tls_release_record, + tls_get_alert_code, + tls_set1_bio, + tls_set_protocol_version, + tls_set_plain_alerts, + tls_set_first_handshake, + tls_set_max_pipelines, + NULL, + tls_get_state, + tls_set_options, + tls_get_compression, + tls_set_max_frag_len, + NULL, + tls_increment_sequence_ctr, + tls_alloc_buffers, + tls_free_buffers +}; diff --git a/ssl/record/methods/tls_multib.c b/ssl/record/methods/tls_multib.c new file mode 100644 index 0000000000..3c2c30ef16 --- /dev/null +++ b/ssl/record/methods/tls_multib.c @@ -0,0 +1,187 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +#if defined(OPENSSL_SMALL_FOOTPRINT) \ + || !(defined(AES_ASM) && (defined(__x86_64) \ + || defined(__x86_64__) \ + || defined(_M_AMD64) \ + || defined(_M_X64))) +# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 +#endif + +static int tls_is_multiblock_capable(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, size_t fraglen) +{ +#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + if (type == SSL3_RT_APPLICATION_DATA + && len >= 4 * fraglen + && rl->compctx == NULL + && rl->msg_callback == NULL + && !rl->use_etm + && RLAYER_USE_EXPLICIT_IV(rl) + && !BIO_get_ktls_send(rl->bio) + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx)) + & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0) + return 1; +#endif + return 0; +} + +size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, uint8_t type, + size_t len, size_t maxfrag, + size_t *preffrag) +{ + if (tls_is_multiblock_capable(rl, type, len, *preffrag)) { + /* minimize address aliasing conflicts */ + if ((*preffrag & 0xfff) == 0) + *preffrag -= 512; + + if (len >= 8 * (*preffrag)) + return 8; + + return 4; + } + + return tls_get_max_records_default(rl, type, len, maxfrag, preffrag); +} + +/* + * Write records using the multiblock method. + * + * Returns 1 on success, 0 if multiblock isn't suitable (non-fatal error), or + * -1 on fatal error. + */ +static int tls_write_records_multiblock_int(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl) +{ +#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + size_t i; + size_t totlen; + TLS_BUFFER *wb; + unsigned char aad[13]; + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; + size_t packlen; + int packleni; + + if (numtempl != 4 && numtempl != 8) + return 0; + + /* + * Check templates have contiguous buffers and are all the same type and + * length + */ + for (i = 1; i < numtempl; i++) { + if (templates[i - 1].type != templates[i].type + || templates[i - 1].buflen != templates[i].buflen + || templates[i - 1].buf + templates[i - 1].buflen + != templates[i].buf) + return 0; + } + + totlen = templates[0].buflen * numtempl; + if (!tls_is_multiblock_capable(rl, templates[0].type, totlen, + templates[0].buflen)) + return 0; + + /* + * If we get this far, then multiblock is suitable + * Depending on platform multi-block can deliver several *times* + * better performance. Downside is that it has to allocate + * jumbo buffer to accommodate up to 8 records, but the + * compromise is considered worthy. + */ + + /* + * Allocate jumbo buffer. This will get freed next time we do a non + * multiblock write in the call to tls_setup_write_buffer() - the different + * buffer sizes will be spotted and the buffer reallocated. + */ + packlen = EVP_CIPHER_CTX_ctrl(rl->enc_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, + (int)templates[0].buflen, NULL); + packlen *= numtempl; + if (!tls_setup_write_buffer(rl, 1, packlen, packlen)) { + /* RLAYERfatal() already called */ + return -1; + } + wb = &rl->wbuf[0]; + + mb_param.interleave = numtempl; + memcpy(aad, rl->sequence, 8); + aad[8] = templates[0].type; + aad[9] = (unsigned char)(templates[0].version >> 8); + aad[10] = (unsigned char)(templates[0].version); + aad[11] = 0; + aad[12] = 0; + mb_param.out = NULL; + mb_param.inp = aad; + mb_param.len = totlen; + + packleni = EVP_CIPHER_CTX_ctrl(rl->enc_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, + sizeof(mb_param), &mb_param); + packlen = (size_t)packleni; + if (packleni <= 0 || packlen > wb->len) { /* never happens */ + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } + + mb_param.out = wb->buf; + mb_param.inp = templates[0].buf; + mb_param.len = totlen; + + if (EVP_CIPHER_CTX_ctrl(rl->enc_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, + sizeof(mb_param), &mb_param) <= 0) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } + + rl->sequence[7] += mb_param.interleave; + if (rl->sequence[7] < mb_param.interleave) { + int j = 6; + while (j >= 0 && (++rl->sequence[j--]) == 0) ; + } + + wb->offset = 0; + wb->left = packlen; + + return 1; +#else /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */ + return 0; +#endif +} + +int tls_write_records_multiblock(OSSL_RECORD_LAYER *rl, + OSSL_RECORD_TEMPLATE *templates, + size_t numtempl) +{ + int ret; + + ret = tls_write_records_multiblock_int(rl, templates, numtempl); + if (ret < 0) { + /* RLAYERfatal already called */ + return 0; + } + if (ret == 0) { + /* Multiblock wasn't suitable so just do a standard write */ + if (!tls_write_records_default(rl, templates, numtempl)) { + /* RLAYERfatal already called */ + return 0; + } + } + + return 1; +} diff --git a/ssl/record/tls_pad.c b/ssl/record/methods/tls_pad.c similarity index 92% rename from ssl/record/tls_pad.c rename to ssl/record/methods/tls_pad.c index d79c4e9f63..23198f3a49 100644 --- a/ssl/record/tls_pad.c +++ b/ssl/record/methods/tls_pad.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,8 +9,10 @@ #include #include + #include "internal/constant_time.h" #include "internal/cryptlib.h" +#include "internal/ssl3_cbc.h" /* * This file has no dependencies on the rest of libssl because it is shared @@ -31,23 +33,6 @@ static int ssl3_cbc_copy_mac(size_t *reclen, size_t good, OSSL_LIB_CTX *libctx); -int ssl3_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - OSSL_LIB_CTX *libctx); - -int tls1_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - int aead, - OSSL_LIB_CTX *libctx); - /*- * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC * record in |recdata| by updating |reclen| in constant time. It also extracts diff --git a/ssl/record/methods/tlsany_meth.c b/ssl/record/methods/tlsany_meth.c new file mode 100644 index 0000000000..42bbbee8aa --- /dev/null +++ b/ssl/record/methods/tlsany_meth.c @@ -0,0 +1,197 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "../../ssl_local.h" +#include "../record_local.h" +#include "recmethod_local.h" + +#define MIN_SSL2_RECORD_LEN 9 + +static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, + size_t taglen, + int mactype, + const EVP_MD *md, + COMP_METHOD *comp) +{ + if (level != OSSL_RECORD_PROTECTION_LEVEL_NONE) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + /* No crypto protection at the "NONE" level so nothing to be done */ + + return OSSL_RECORD_RETURN_SUCCESS; +} + +static int tls_any_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, + size_t n_recs, int sending, SSL_MAC_BUF *macs, + size_t macsize) +{ + return 1; +} + +static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) +{ + if (rec->rec_version == SSL2_VERSION) { + /* SSLv2 format ClientHello */ + if (!ossl_assert(rl->version == TLS_ANY_VERSION)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + if (rec->length < MIN_SSL2_RECORD_LEN) { + RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); + return 0; + } + } else { + if (rl->version == TLS_ANY_VERSION) { + if ((rec->rec_version >> 8) != SSL3_VERSION_MAJOR) { + if (rl->is_first_record) { + unsigned char *p; + + /* + * Go back to start of packet, look at the five bytes that + * we have. + */ + p = rl->packet; + if (HAS_PREFIX((char *)p, "GET ") || + HAS_PREFIX((char *)p, "POST ") || + HAS_PREFIX((char *)p, "HEAD ") || + HAS_PREFIX((char *)p, "PUT ")) { + RLAYERfatal(rl, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST); + return 0; + } else if (HAS_PREFIX((char *)p, "CONNE")) { + RLAYERfatal(rl, SSL_AD_NO_ALERT, + SSL_R_HTTPS_PROXY_REQUEST); + return 0; + } + + /* Doesn't look like TLS - don't send an alert */ + RLAYERfatal(rl, SSL_AD_NO_ALERT, + SSL_R_WRONG_VERSION_NUMBER); + return 0; + } else { + RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, + SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + } + } else if (rl->version == TLS1_3_VERSION) { + /* + * In this case we know we are going to negotiate TLSv1.3, but we've + * had an HRR, so we haven't actually done so yet. In TLSv1.3 we + * must ignore the legacy record version in plaintext records. + */ + } else if (rec->rec_version != rl->version) { + if ((rl->version & 0xFF00) == (rec->rec_version & 0xFF00)) { + if (rec->type == SSL3_RT_ALERT) { + /* + * The record is using an incorrect version number, + * but what we've got appears to be an alert. We + * haven't read the body yet to check whether its a + * fatal or not - but chances are it is. We probably + * shouldn't send a fatal alert back. We'll just + * end. + */ + RLAYERfatal(rl, SSL_AD_NO_ALERT, + SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + /* Send back error using their minor version number */ + rl->version = (unsigned short)rec->rec_version; + } + RLAYERfatal(rl, SSL_AD_PROTOCOL_VERSION, + SSL_R_WRONG_VERSION_NUMBER); + return 0; + } + } + if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) { + /* + * We use SSL_R_DATA_LENGTH_TOO_LONG instead of + * SSL_R_ENCRYPTED_LENGTH_TOO_LONG here because we are the "any" method + * and we know that we are dealing with plaintext data + */ + RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + return 1; +} + +static int tls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers) +{ + if (rl->version != TLS_ANY_VERSION && rl->version != vers) + return 0; + rl->version = vers; + + return 1; +} + +static int tls_any_prepare_for_encryption(OSSL_RECORD_LAYER *rl, + size_t mac_size, + WPACKET *thispkt, + TLS_RL_RECORD *thiswr) +{ + /* No encryption, so nothing to do */ + return 1; +} + +struct record_functions_st tls_any_funcs = { + tls_any_set_crypto_state, + tls_any_cipher, + NULL, + tls_any_set_protocol_version, + tls_default_read_n, + tls_get_more_records, + tls_validate_record_header, + tls_default_post_process_record, + tls_get_max_records_default, + tls_write_records_default, + tls_allocate_write_buffers_default, + tls_initialise_write_packets_default, + NULL, + tls_prepare_record_header_default, + NULL, + tls_any_prepare_for_encryption, + tls_post_encryption_processing_default, + NULL +}; + +static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers) +{ + if (rl->version != DTLS_ANY_VERSION && rl->version != vers) + return 0; + rl->version = vers; + + return 1; +} + +struct record_functions_st dtls_any_funcs = { + tls_any_set_crypto_state, + tls_any_cipher, + NULL, + dtls_any_set_protocol_version, + tls_default_read_n, + dtls_get_more_records, + NULL, + NULL, + NULL, + tls_write_records_default, + tls_allocate_write_buffers_default, + tls_initialise_write_packets_default, + NULL, + dtls_prepare_record_header, + NULL, + tls_prepare_for_encryption_default, + dtls_post_encryption_processing, + NULL +}; diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 79de0219ec..87b588b84b 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -20,22 +20,14 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) { DTLS_RECORD_LAYER *d; - if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) return 0; - } rl->d = d; - d->unprocessed_rcds.q = pqueue_new(); - d->processed_rcds.q = pqueue_new(); d->buffered_app_data.q = pqueue_new(); - if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL - || d->buffered_app_data.q == NULL) { - pqueue_free(d->unprocessed_rcds.q); - pqueue_free(d->processed_rcds.q); - pqueue_free(d->buffered_app_data.q); + if (d->buffered_app_data.q == NULL) { OPENSSL_free(d); rl->d = NULL; return 0; @@ -50,8 +42,6 @@ void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl) return; DTLS_RECORD_LAYER_clear(rl); - pqueue_free(rl->d->unprocessed_rcds.q); - pqueue_free(rl->d->processed_rcds.q); pqueue_free(rl->d->buffered_app_data.q); OPENSSL_free(rl->d); rl->d = NULL; @@ -61,99 +51,42 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) { DTLS_RECORD_LAYER *d; pitem *item = NULL; - DTLS1_RECORD_DATA *rdata; - pqueue *unprocessed_rcds; - pqueue *processed_rcds; + TLS_RECORD *rec; pqueue *buffered_app_data; d = rl->d; - while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(item->data); - pitem_free(item); - } - - while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT) - OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len); - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(item->data); - pitem_free(item); - } - while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; + rec = (TLS_RECORD *)item->data; + if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT) - OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len); - OPENSSL_free(rdata->rbuf.buf); + OPENSSL_cleanse(rec->allocdata, rec->length); + OPENSSL_free(rec->allocdata); OPENSSL_free(item->data); pitem_free(item); } - unprocessed_rcds = d->unprocessed_rcds.q; - processed_rcds = d->processed_rcds.q; buffered_app_data = d->buffered_app_data.q; memset(d, 0, sizeof(*d)); - d->unprocessed_rcds.q = unprocessed_rcds; - d->processed_rcds.q = processed_rcds; d->buffered_app_data.q = buffered_app_data; } -void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e) +static int dtls_buffer_record(SSL_CONNECTION *s, TLS_RECORD *rec) { - if (e == rl->d->w_epoch - 1) { - memcpy(rl->d->curr_write_sequence, - rl->write_sequence, sizeof(rl->write_sequence)); - memcpy(rl->write_sequence, - rl->d->last_write_sequence, sizeof(rl->write_sequence)); - } else if (e == rl->d->w_epoch + 1) { - memcpy(rl->d->last_write_sequence, - rl->write_sequence, sizeof(unsigned char[8])); - memcpy(rl->write_sequence, - rl->d->curr_write_sequence, sizeof(rl->write_sequence)); - } - rl->d->w_epoch = e; -} - -void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq) -{ - memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE); -} - -/* copy buffered record into SSL structure */ -static int dtls1_copy_record(SSL *s, pitem *item) -{ - DTLS1_RECORD_DATA *rdata; - - rdata = (DTLS1_RECORD_DATA *)item->data; - - SSL3_BUFFER_release(&s->rlayer.rbuf); - - s->rlayer.packet = rdata->packet; - s->rlayer.packet_length = rdata->packet_length; - memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD)); - - /* Set proper sequence number for mac calculation */ - memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6); - - return 1; -} - -int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) -{ - DTLS1_RECORD_DATA *rdata; + TLS_RECORD *rdata; pitem *item; + record_pqueue *queue = &(s->rlayer.d->buffered_app_data); /* Limit the size of the queue to prevent DOS attacks */ if (pqueue_size(queue->q) >= 100) return 0; + /* We don't buffer partially read records */ + if (!ossl_assert(rec->off == 0)) + return -1; + rdata = OPENSSL_malloc(sizeof(*rdata)); - item = pitem_new(priority, rdata); + item = pitem_new(rec->seq_num, rdata); if (rdata == NULL || item == NULL) { OPENSSL_free(rdata); pitem_free(item); @@ -161,39 +94,40 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) return -1; } - rdata->packet = s->rlayer.packet; - rdata->packet_length = s->rlayer.packet_length; - memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER)); - memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD)); + *rdata = *rec; + /* + * We will release the record from the record layer soon, so we take a copy + * now. Copying data isn't good - but this should be infrequent so we + * accept it here. + */ + rdata->data = rdata->allocdata = OPENSSL_memdup(rec->data, rec->length); + if (rdata->data == NULL) { + OPENSSL_free(rdata); + pitem_free(item); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); + return -1; + } + /* + * We use a NULL rechandle to indicate that the data field has been + * allocated by us. + */ + rdata->rechandle = NULL; item->data = rdata; #ifndef OPENSSL_NO_SCTP /* Store bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (SSL_get_state(s) == TLS_ST_SR_FINISHED - || SSL_get_state(s) == TLS_ST_CR_FINISHED)) { - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, + if (BIO_dgram_is_sctp(s->rbio) && + (ossl_statem_get_state(s) == TLS_ST_SR_FINISHED + || ossl_statem_get_state(s) == TLS_ST_CR_FINISHED)) { + BIO_ctrl(s->rbio, BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); } #endif - s->rlayer.packet = NULL; - s->rlayer.packet_length = 0; - memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf)); - memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec)); - - if (!ssl3_setup_buffers(s)) { - /* SSLfatal() already called */ - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(rdata); - pitem_free(item); - return -1; - } - if (pqueue_insert(queue->q, item) == NULL) { /* Must be a duplicate so ignore it */ - OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata->allocdata); OPENSSL_free(rdata); pitem_free(item); } @@ -201,121 +135,42 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) return 1; } -int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +/* Unbuffer a previously buffered TLS_RECORD structure if any */ +static void dtls_unbuffer_record(SSL_CONNECTION *s) { + TLS_RECORD *rdata; pitem *item; - item = pqueue_pop(queue->q); - if (item) { - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - - return 1; - } - - return 0; -} - -/* - * retrieve a buffered record that belongs to the new epoch, i.e., not - * processed yet - */ -#define dtls1_get_unprocessed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->rlayer.d->unprocessed_rcds)) - -int dtls1_process_buffered_records(SSL *s) -{ - pitem *item; - SSL3_BUFFER *rb; - SSL3_RECORD *rr; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - int replayok = 1; - - item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q); - if (item) { - /* Check if epoch is current. */ - if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch) - return 1; /* Nothing to do. */ - - rr = RECORD_LAYER_get_rrec(&s->rlayer); + /* If we already have records to handle then do nothing */ + if (s->rlayer.curr_rec < s->rlayer.num_recs) + return; - rb = RECORD_LAYER_get_rbuf(&s->rlayer); + item = pqueue_pop(s->rlayer.d->buffered_app_data.q); + if (item != NULL) { + rdata = (TLS_RECORD *)item->data; - if (SSL3_BUFFER_get_left(rb) > 0) { - /* - * We've still got data from the current packet to read. There could - * be a record from the new epoch in it - so don't overwrite it - * with the unprocessed records yet (we'll do it when we've - * finished reading the current packet). - */ - return 1; - } + s->rlayer.tlsrecs[0] = *rdata; + s->rlayer.num_recs = 1; + s->rlayer.curr_rec = 0; - /* Process all the records. */ - while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) { - dtls1_get_unprocessed_record(s); - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - /* - * Should not happen. This will only ever be NULL when the - * current record is from a different epoch. But that cannot - * be the case because we already checked the epoch above - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } #ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) + /* Restore bio_dgram_sctp_rcvinfo struct */ + if (BIO_dgram_is_sctp(s->rbio)) { + BIO_ctrl(s->rbio, BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, + sizeof(rdata->recordinfo), &rdata->recordinfo); + } #endif - { - /* - * Check whether this is a repeat, or aged record. We did this - * check once already when we first received the record - but - * we might have updated the window since then due to - * records we subsequently processed. - */ - replayok = dtls1_record_replay_check(s, bitmap); - } - - if (!replayok || !dtls1_process_record(s, bitmap)) { - if (ossl_statem_in_error(s)) { - /* dtls1_process_record called SSLfatal() */ - return 0; - } - /* dump this record */ - rr->length = 0; - RECORD_LAYER_reset_packet_length(&s->rlayer); - continue; - } - if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds), - SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < 0) { - /* SSLfatal() already called */ - return 0; - } - } + OPENSSL_free(item->data); + pitem_free(item); } - - /* - * sync epoch numbers once all the unprocessed records have been - * processed - */ - s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch; - s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1; - - return 1; } /*- * Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_HANDSHAKE * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) * - 0 (during a shutdown, no data has to be returned) * @@ -340,32 +195,29 @@ int dtls1_process_buffered_records(SSL *s) * Application data protocol * none of our business */ -int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, - size_t len, int peek, size_t *readbytes) +int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, + unsigned char *buf, size_t len, + int peek, size_t *readbytes) { - int i, j, iret; + int i, j, ret; size_t n; - SSL3_RECORD *rr; + TLS_RECORD *rr; void (*cb) (const SSL *ssl, int type2, int val) = NULL; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) { - /* Not initialized yet */ - if (!ssl3_setup_buffers(s)) { - /* SSLfatal() already called */ - return -1; - } - } + if (sc == NULL) + return -1; if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) || (peek && (type != SSL3_RT_APPLICATION_DATA))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } - if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) { + if (!ossl_statem_get_in_handshake(sc) && SSL_in_init(s)) { /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); + i = sc->handshake_func(s); /* SSLfatal() already called if appropriate */ if (i < 0) return i; @@ -374,92 +226,76 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } start: - s->rwstate = SSL_NOTHING; - - /*- - * s->s3.rrec.type - is the type of record - * s->s3.rrec.data, - data - * s->s3.rrec.off, - offset into 'data' for next read - * s->s3.rrec.length, - number of bytes. - */ - rr = s->rlayer.rrec; + sc->rwstate = SSL_NOTHING; /* * We are not handshaking and have no data yet, so process data buffered * during the last handshake in advance, if any. */ - if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) { - pitem *item; - item = pqueue_pop(s->rlayer.d->buffered_app_data.q); - if (item) { -#ifndef OPENSSL_NO_SCTP - /* Restore bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s))) { - DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, - sizeof(rdata->recordinfo), &rdata->recordinfo); - } -#endif - - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - } - } + if (SSL_is_init_finished(s)) + dtls_unbuffer_record(sc); /* Check for timeout */ - if (dtls1_handle_timeout(s) > 0) { + if (dtls1_handle_timeout(sc) > 0) { goto start; - } else if (ossl_statem_in_error(s)) { + } else if (ossl_statem_in_error(sc)) { /* dtls1_handle_timeout() has failed with a fatal error */ return -1; } /* get new packet if necessary */ - if ((SSL3_RECORD_get_length(rr) == 0) - || (s->rlayer.rstate == SSL_ST_READ_BODY)) { - RECORD_LAYER_set_numrpipes(&s->rlayer, 0); - iret = dtls1_get_record(s); - if (iret <= 0) { - iret = dtls1_read_failed(s, iret); - /* - * Anything other than a timeout is an error. SSLfatal() already - * called if appropriate. - */ - if (iret <= 0) - return iret; - else - goto start; - } - RECORD_LAYER_set_numrpipes(&s->rlayer, 1); + if (sc->rlayer.curr_rec >= sc->rlayer.num_recs) { + sc->rlayer.curr_rec = sc->rlayer.num_recs = 0; + do { + rr = &sc->rlayer.tlsrecs[sc->rlayer.num_recs]; + + ret = HANDLE_RLAYER_READ_RETURN(sc, + sc->rlayer.rrlmethod->read_record(sc->rlayer.rrl, + &rr->rechandle, + &rr->version, &rr->type, + &rr->data, &rr->length, + &rr->epoch, rr->seq_num)); + if (ret <= 0) { + ret = dtls1_read_failed(sc, ret); + /* + * Anything other than a timeout is an error. SSLfatal() already + * called if appropriate. + */ + if (ret <= 0) + return ret; + else + goto start; + } + rr->off = 0; + sc->rlayer.num_recs++; + } while (sc->rlayer.rrlmethod->processed_read_pending(sc->rlayer.rrl) + && sc->rlayer.num_recs < SSL_MAX_PIPELINES); } + rr = &sc->rlayer.tlsrecs[sc->rlayer.curr_rec]; /* * Reset the count of consecutive warning alerts if we've got a non-empty * record that isn't an alert. */ - if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT - && SSL3_RECORD_get_length(rr) != 0) - s->rlayer.alert_count = 0; + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + sc->rlayer.alert_count = 0; /* we now have a packet which can be read and processed */ - if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, + if (sc->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, * reset by ssl3_get_finished */ - && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) { + && (rr->type != SSL3_RT_HANDSHAKE)) { /* * We now have application data between CCS and Finished. Most likely * the packets were reordered on their way, so buffer the application * data for later processing rather than dropping the connection. */ - if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data), - SSL3_RECORD_get_seq_num(rr)) < 0) { + if (dtls_buffer_record(sc, rr) < 0) { /* SSLfatal() already called */ return -1; } - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(sc, rr, 0)) + return -1; goto start; } @@ -467,15 +303,15 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * If the other end has shut down, throw anything we read away (even in * 'peek' mode) */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); - s->rwstate = SSL_NOTHING; + if (sc->shutdown & SSL_RECEIVED_SHUTDOWN) { + if (!ssl_release_record(sc, rr, 0)) + return -1; + sc->rwstate = SSL_NOTHING; return 0; } - if (type == SSL3_RECORD_get_type(rr) - || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC + if (type == rr->type + || (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) { /* * SSL3_RT_APPLICATION_DATA or @@ -486,46 +322,39 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * make sure that we are not getting application data when we are * doing a handshake for the first time */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) + && (SSL_IS_FIRST_HANDSHAKE(sc))) { + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_APP_DATA_IN_HANDSHAKE); return -1; } if (recvd_type != NULL) - *recvd_type = SSL3_RECORD_get_type(rr); + *recvd_type = rr->type; if (len == 0) { /* - * Mark a zero length record as read. This ensures multiple calls to + * Release a zero length record. This ensures multiple calls to * SSL_read() with a zero length buffer will eventually cause * SSL_pending() to report data as being available. */ - if (SSL3_RECORD_get_length(rr) == 0) - SSL3_RECORD_set_read(rr); + if (rr->length == 0 && !ssl_release_record(sc, rr, 0)) + return -1; return 0; } - if (len > SSL3_RECORD_get_length(rr)) - n = SSL3_RECORD_get_length(rr); + if (len > rr->length) + n = rr->length; else n = len; - memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n); + memcpy(buf, &(rr->data[rr->off]), n); if (peek) { - if (SSL3_RECORD_get_length(rr) == 0) - SSL3_RECORD_set_read(rr); + if (rr->length == 0 && !ssl_release_record(sc, rr, 0)) + return -1; } else { - if (s->options & SSL_OP_CLEANSE_PLAINTEXT) - OPENSSL_cleanse(&(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n); - SSL3_RECORD_sub_length(rr, n); - SSL3_RECORD_add_off(rr, n); - if (SSL3_RECORD_get_length(rr) == 0) { - s->rlayer.rstate = SSL_ST_READ_HEADER; - SSL3_RECORD_set_off(rr, 0); - SSL3_RECORD_set_read(rr); - } + if (!ssl_release_record(sc, rr, n)) + return -1; } #ifndef OPENSSL_NO_SCTP /* @@ -534,9 +363,9 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * anymore, finally set shutdown. */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - s->d1->shutdown_received + sc->d1->shutdown_received && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) <= 0) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; + sc->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } #endif @@ -549,26 +378,25 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * then it was unexpected (Hello Request or Client Hello). */ - if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) { + if (rr->type == SSL3_RT_ALERT) { unsigned int alert_level, alert_descr; - unsigned char *alert_bytes = SSL3_RECORD_get_data(rr) - + SSL3_RECORD_get_off(rr); + const unsigned char *alert_bytes = rr->data + rr->off; PACKET alert; - if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr)) + if (!PACKET_buf_init(&alert, alert_bytes, rr->length) || !PACKET_get_1(&alert, &alert_level) || !PACKET_get_1(&alert, &alert_descr) || PACKET_remaining(&alert) != 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT); + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT); return -1; } - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s, - s->msg_callback_arg); + if (sc->msg_callback) + sc->msg_callback(0, sc->version, SSL3_RT_ALERT, alert_bytes, 2, s, + sc->msg_callback_arg); - if (s->info_callback != NULL) - cb = s->info_callback; + if (sc->info_callback != NULL) + cb = sc->info_callback; else if (s->ctx->info_callback != NULL) cb = s->ctx->info_callback; @@ -578,12 +406,13 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } if (alert_level == SSL3_AL_WARNING) { - s->s3.warn_alert = alert_descr; - SSL3_RECORD_set_read(rr); + sc->s3.warn_alert = alert_descr; + if (!ssl_release_record(sc, rr, 0)) + return -1; - s->rlayer.alert_count++; - if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, + sc->rlayer.alert_count++; + if (sc->rlayer.alert_count == MAX_WARN_ALERT_COUNT) { + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_TOO_MANY_WARN_ALERTS); return -1; } @@ -597,67 +426,67 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) { - s->d1->shutdown_received = 1; - s->rwstate = SSL_READING; + sc->d1->shutdown_received = 1; + sc->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); return -1; } #endif - s->shutdown |= SSL_RECEIVED_SHUTDOWN; + sc->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } } else if (alert_level == SSL3_AL_FATAL) { - s->rwstate = SSL_NOTHING; - s->s3.fatal_alert = alert_descr; - SSLfatal_data(s, SSL_AD_NO_ALERT, + sc->rwstate = SSL_NOTHING; + sc->s3.fatal_alert = alert_descr; + SSLfatal_data(sc, SSL_AD_NO_ALERT, SSL_AD_REASON_OFFSET + alert_descr, "SSL alert number %d", alert_descr); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL3_RECORD_set_read(rr); - SSL_CTX_remove_session(s->session_ctx, s->session); + sc->shutdown |= SSL_RECEIVED_SHUTDOWN; + if (!ssl_release_record(sc, rr, 0)) + return -1; + SSL_CTX_remove_session(sc->session_ctx, sc->session); return 0; } else { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); + SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); return -1; } goto start; } - if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a + if (sc->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a * shutdown */ - s->rwstate = SSL_NOTHING; - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + sc->rwstate = SSL_NOTHING; + if (!ssl_release_record(sc, rr, 0)) + return -1; return 0; } - if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) { + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { /* * We can't process a CCS now, because previous handshake messages * are still missing, so just drop it. */ - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(sc, rr, 0)) + return -1; goto start; } /* * Unexpected handshake message (Client Hello, or protocol violation) */ - if ((SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) && - !ossl_statem_get_in_handshake(s)) { + if (rr->type == SSL3_RT_HANDSHAKE && !ossl_statem_get_in_handshake(sc)) { struct hm_header_st msg_hdr; /* * This may just be a stale retransmit. Also sanity check that we have * at least enough record bytes for a message header */ - if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch - || SSL3_RECORD_get_length(rr) < DTLS1_HM_HEADER_LENGTH) { - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + if (rr->epoch != sc->rlayer.d->r_epoch + || rr->length < DTLS1_HM_HEADER_LENGTH) { + if (!ssl_release_record(sc, rr, 0)) + return -1; goto start; } @@ -668,24 +497,24 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * here, then retransmit our CCS and FINISHED. */ if (msg_hdr.type == SSL3_MT_FINISHED) { - if (dtls1_check_timeout_num(s) < 0) { + if (dtls1_check_timeout_num(sc) < 0) { /* SSLfatal) already called */ return -1; } - if (dtls1_retransmit_buffered_messages(s) <= 0) { + if (dtls1_retransmit_buffered_messages(sc) <= 0) { /* Fail if we encountered a fatal error */ - if (ossl_statem_in_error(s)) + if (ossl_statem_in_error(sc)) return -1; } - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) { + if (!ssl_release_record(sc, rr, 0)) + return -1; + if (!(sc->mode & SSL_MODE_AUTO_RETRY)) { + if (!sc->rlayer.rrlmethod->unprocessed_read_pending(sc->rlayer.rrl)) { /* no read-ahead left? */ BIO *bio; - s->rwstate = SSL_READING; + sc->rwstate = SSL_READING; bio = SSL_get_rbio(s); BIO_clear_retry_flags(bio); BIO_set_retry_read(bio); @@ -702,22 +531,22 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * finished */ if (!ossl_assert(SSL_is_init_finished(s))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } /* We found handshake data, so we're going back into init */ - ossl_statem_set_in_init(s, 1); + ossl_statem_set_in_init(sc, 1); - i = s->handshake_func(s); + i = sc->handshake_func(s); /* SSLfatal() called if appropriate */ if (i < 0) return i; if (i == 0) return -1; - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) { + if (!(sc->mode & SSL_MODE_AUTO_RETRY)) { + if (!sc->rlayer.rrlmethod->unprocessed_read_pending(sc->rlayer.rrl)) { /* no read-ahead left? */ BIO *bio; /* @@ -726,7 +555,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * option set. Otherwise renegotiation may cause nasty * problems in the blocking world */ - s->rwstate = SSL_READING; + sc->rwstate = SSL_READING; bio = SSL_get_rbio(s); BIO_clear_retry_flags(bio); BIO_set_retry_read(bio); @@ -736,9 +565,9 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, goto start; } - switch (SSL3_RECORD_get_type(rr)) { + switch (rr->type) { default: - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; case SSL3_RT_CHANGE_CIPHER_SPEC: case SSL3_RT_ALERT: @@ -748,7 +577,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but * that should not happen when type != rr->type */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); return -1; case SSL3_RT_APPLICATION_DATA: /* @@ -758,13 +587,13 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * application data at this point (session renegotiation not yet * started), we will indulge it. */ - if (s->s3.in_read_app_data && - (s->s3.total_renegotiations != 0) && - ossl_statem_app_data_allowed(s)) { - s->s3.in_read_app_data = 2; + if (sc->s3.in_read_app_data && + (sc->s3.total_renegotiations != 0) && + ossl_statem_app_data_allowed(sc)) { + sc->s3.in_read_app_data = 2; return -1; } else { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; } } @@ -775,8 +604,8 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * Call this to write data in records of type 'type' It will return <= 0 if * not all data has been sent or non-blocking IO. */ -int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, - size_t *written) +int dtls1_write_bytes(SSL_CONNECTION *s, uint8_t type, const void *buf, + size_t len, size_t *written) { int i; @@ -785,255 +614,61 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, return -1; } s->rwstate = SSL_NOTHING; - i = do_dtls1_write(s, type, buf, len, 0, written); + i = do_dtls1_write(s, type, buf, len, written); return i; } -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - size_t len, int create_empty_fragment, size_t *written) +int do_dtls1_write(SSL_CONNECTION *sc, uint8_t type, const unsigned char *buf, + size_t len, size_t *written) { - unsigned char *p, *pseq; - int i, mac_size, clear = 0; - size_t prefix_len = 0; - int eivlen; - SSL3_RECORD wr; - SSL3_BUFFER *wb; - SSL_SESSION *sess; - - wb = &s->rlayer.wbuf[0]; - - /* - * DTLS writes whole datagrams, so there can't be anything left in - * the buffer. - */ - if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } + int i; + OSSL_RECORD_TEMPLATE tmpl; + SSL *s = SSL_CONNECTION_GET_SSL(sc); + int ret; /* If we have an alert to send, lets send it */ - if (s->s3.alert_dispatch) { + if (sc->s3.alert_dispatch > 0) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) return i; /* if it went, fall through and send more stuff */ } - if (len == 0 && !create_empty_fragment) + if (len == 0) return 0; - if (len > ssl_get_max_send_fragment(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); + if (len > ssl_get_max_send_fragment(sc)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); return 0; } - sess = s->session; - - if ((sess == NULL) - || (s->enc_write_ctx == NULL) - || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) - clear = 1; - - if (clear) - mac_size = 0; - else { - mac_size = EVP_MD_CTX_get_size(s->write_hash); - if (mac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); - return -1; - } - } - - p = SSL3_BUFFER_get_buf(wb) + prefix_len; - - /* write the header */ - - *(p++) = type & 0xff; - SSL3_RECORD_set_type(&wr, type); + tmpl.type = type; /* * Special case: for hello verify request, client version 1.0 and we * haven't decided which version to use yet send back using version 1.0 * header: otherwise some clients will ignore it. */ - if (s->method->version == DTLS_ANY_VERSION && - s->max_proto_version != DTLS1_BAD_VER) { - *(p++) = DTLS1_VERSION >> 8; - *(p++) = DTLS1_VERSION & 0xff; - } else { - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - } - - /* field where we are to write out packet epoch, seq num and len */ - pseq = p; - p += 10; - - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx) { - int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx); - if (eivlen < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); - return -1; - } - if (eivlen <= 1) - eivlen = 0; - } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - else if (mode == EVP_CIPH_CCM_MODE) - eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; - else - eivlen = 0; - } else - eivlen = 0; - - /* lets setup the record stuff. */ - SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */ - SSL3_RECORD_set_length(&wr, len); - SSL3_RECORD_set_input(&wr, (unsigned char *)buf); - - /* - * we now 'read' from wr.input, wr.length bytes into wr.data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s, &wr)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE); - return -1; - } - } else { - memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr), - SSL3_RECORD_get_length(&wr)); - SSL3_RECORD_reset_input(&wr); - } - - /* - * we should still have the output to wr.data and the input from - * wr.input. Length should be wr.length. wr.data still points in the - * wb->buf - */ - - if (!SSL_WRITE_ETM(s) && mac_size != 0) { - if (!s->method->ssl3_enc->mac(s, &wr, - &(p[SSL3_RECORD_get_length(&wr) + eivlen]), - 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - SSL3_RECORD_add_length(&wr, mac_size); - } - - /* this is true regardless of mac size */ - SSL3_RECORD_set_data(&wr, p); - SSL3_RECORD_reset_input(&wr); - - if (eivlen) - SSL3_RECORD_add_length(&wr, eivlen); - - if (s->method->ssl3_enc->enc(s, &wr, 1, 1, NULL, mac_size) < 1) { - if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - } - return -1; - } - - if (SSL_WRITE_ETM(s) && mac_size != 0) { - if (!s->method->ssl3_enc->mac(s, &wr, - &(p[SSL3_RECORD_get_length(&wr)]), 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - SSL3_RECORD_add_length(&wr, mac_size); - } - - /* record length after mac and block padding */ - - /* there's only one epoch between handshake and app data */ - - s2n(s->rlayer.d->w_epoch, pseq); - - memcpy(pseq, &(s->rlayer.write_sequence[2]), 6); - pseq += 6; - s2n(SSL3_RECORD_get_length(&wr), pseq); - - if (s->msg_callback) - s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, - DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); - - /* - * we should now have wr.data pointing to the encrypted data, which is - * wr->length long - */ - SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */ - SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH); - - ssl3_record_sequence_update(&(s->rlayer.write_sequence[0])); - - if (create_empty_fragment) { - /* - * we are in a recursive call; just return the length, don't write - * out anything here - */ - *written = wr.length; - return 1; - } - - /* now let's set up wb */ - SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr)); - SSL3_BUFFER_set_offset(wb, 0); - - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->rlayer.wpend_tot = len; - s->rlayer.wpend_buf = buf; - s->rlayer.wpend_type = type; - s->rlayer.wpend_ret = len; - - /* we now just need to write the buffer. Calls SSLfatal() as required. */ - return ssl3_write_pending(s, type, buf, len, written); -} - -DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch) -{ + if (s->method->version == DTLS_ANY_VERSION + && sc->max_proto_version != DTLS1_BAD_VER) + tmpl.version = DTLS1_VERSION; + else + tmpl.version = sc->version; + tmpl.buf = buf; + tmpl.buflen = len; - *is_next_epoch = 0; + ret = HANDLE_RLAYER_WRITE_RETURN(sc, + sc->rlayer.wrlmethod->write_records(sc->rlayer.wrl, &tmpl, 1)); - /* In current epoch, accept HM, CCS, DATA, & ALERT */ - if (rr->epoch == s->rlayer.d->r_epoch) - return &s->rlayer.d->bitmap; + if (ret > 0) + *written = (int)len; - /* - * We can only handle messages from the next epoch if we have already - * processed all of the unprocessed records from the previous epoch - */ - else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) - && s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch) { - *is_next_epoch = 1; - return &s->rlayer.d->next_bitmap; - } - - return NULL; + return ret; } -void dtls1_reset_seq_numbers(SSL *s, int rw) +void dtls1_increment_epoch(SSL_CONNECTION *s, int rw) { - unsigned char *seq; - unsigned int seq_bytes = sizeof(s->rlayer.read_sequence); - if (rw & SSL3_CC_READ) { - seq = s->rlayer.read_sequence; s->rlayer.d->r_epoch++; - memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap, - sizeof(s->rlayer.d->bitmap)); - memset(&s->rlayer.d->next_bitmap, 0, sizeof(s->rlayer.d->next_bitmap)); /* * We must not use any buffered messages received from the previous @@ -1041,11 +676,6 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) */ dtls1_clear_received_buffer(s); } else { - seq = s->rlayer.write_sequence; - memcpy(s->rlayer.d->last_write_sequence, seq, - sizeof(s->rlayer.write_sequence)); s->rlayer.d->w_epoch++; } - - memset(seq, 0, seq_bytes); } diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 3baf820761..845eff9848 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -10,42 +10,23 @@ #include #include #include +#include #include "../ssl_local.h" +#include "../quic/quic_local.h" #include #include #include +#include #include "record_local.h" #include "internal/packet.h" -#include "internal/cryptlib.h" - -#if defined(OPENSSL_SMALL_FOOTPRINT) || \ - !( defined(AES_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) ) \ - ) -# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -#endif -void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s) +void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s) { rl->s = s; - RECORD_LAYER_set_first_record(&s->rlayer); - SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES); } void RECORD_LAYER_clear(RECORD_LAYER *rl) { - rl->rstate = SSL_ST_READ_HEADER; - - /* - * Do I need to clear read_ahead? As far as I can tell read_ahead did not - * previously get reset by SSL_clear...so I'll keep it that way..but is - * that right? - */ - - rl->packet = NULL; - rl->packet_length = 0; rl->wnum = 0; memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment)); rl->handshake_fragment_len = 0; @@ -54,87 +35,122 @@ void RECORD_LAYER_clear(RECORD_LAYER *rl) rl->wpend_ret = 0; rl->wpend_buf = NULL; - SSL3_BUFFER_clear(&rl->rbuf); - ssl3_release_write_buffer(rl->s); - rl->numrpipes = 0; - SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES); - - RECORD_LAYER_reset_read_sequence(rl); - RECORD_LAYER_reset_write_sequence(rl); + if (rl->rrlmethod != NULL) + rl->rrlmethod->free(rl->rrl); /* Ignore return value */ + if (rl->wrlmethod != NULL) + rl->wrlmethod->free(rl->wrl); /* Ignore return value */ + BIO_free(rl->rrlnext); + rl->rrlmethod = NULL; + rl->wrlmethod = NULL; + rl->rrlnext = NULL; + rl->rrl = NULL; + rl->wrl = NULL; if (rl->d) DTLS_RECORD_LAYER_clear(rl); } -void RECORD_LAYER_release(RECORD_LAYER *rl) -{ - if (SSL3_BUFFER_is_initialised(&rl->rbuf)) - ssl3_release_read_buffer(rl->s); - if (rl->numwpipes > 0) - ssl3_release_write_buffer(rl->s); - SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES); -} - /* Checks if we have unprocessed read ahead data pending */ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl) { - return SSL3_BUFFER_get_left(&rl->rbuf) != 0; + return rl->rrlmethod->unprocessed_read_pending(rl->rrl); } /* Checks if we have decrypted unread record data pending */ int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl) { - size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl); - const SSL3_RECORD *rr = rl->rrec; - - while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec])) - curr_rec++; - - return curr_rec < num_recs; + return (rl->curr_rec < rl->num_recs) + || rl->rrlmethod->processed_read_pending(rl->rrl); } int RECORD_LAYER_write_pending(const RECORD_LAYER *rl) { - return (rl->numwpipes > 0) - && SSL3_BUFFER_get_left(&rl->wbuf[rl->numwpipes - 1]) != 0; + return rl->wpend_tot > 0; } -void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl) +static uint32_t ossl_get_max_early_data(SSL_CONNECTION *s) { - memset(rl->read_sequence, 0, sizeof(rl->read_sequence)); + uint32_t max_early_data; + SSL_SESSION *sess = s->session; + + /* + * If we are a client then we always use the max_early_data from the + * session/psksession. Otherwise we go with the lowest out of the max early + * data set in the session and the configured max_early_data. + */ + if (!s->server && sess->ext.max_early_data == 0) { + if (!ossl_assert(s->psksession != NULL + && s->psksession->ext.max_early_data > 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + sess = s->psksession; + } + + if (!s->server) + max_early_data = sess->ext.max_early_data; + else if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED) + max_early_data = s->recv_max_early_data; + else + max_early_data = s->recv_max_early_data < sess->ext.max_early_data + ? s->recv_max_early_data : sess->ext.max_early_data; + + return max_early_data; } -void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl) +static int ossl_early_data_count_ok(SSL_CONNECTION *s, size_t length, + size_t overhead, int send) { - memset(rl->write_sequence, 0, sizeof(rl->write_sequence)); + uint32_t max_early_data; + + max_early_data = ossl_get_max_early_data(s); + + if (max_early_data == 0) { + SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_TOO_MUCH_EARLY_DATA); + return 0; + } + + /* If we are dealing with ciphertext we need to allow for the overhead */ + max_early_data += overhead; + + if (s->early_data_count + length > max_early_data) { + SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, + SSL_R_TOO_MUCH_EARLY_DATA); + return 0; + } + s->early_data_count += length; + + return 1; } size_t ssl3_pending(const SSL *s) { size_t i, num = 0; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); - if (s->rlayer.rstate == SSL_ST_READ_BODY) + if (sc == NULL) return 0; - /* Take into account DTLS buffered app data */ - if (SSL_IS_DTLS(s)) { - DTLS1_RECORD_DATA *rdata; + if (SSL_CONNECTION_IS_DTLS(sc)) { + TLS_RECORD *rdata; pitem *item, *iter; - iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); + iter = pqueue_iterator(sc->rlayer.d->buffered_app_data.q); while ((item = pqueue_next(&iter)) != NULL) { rdata = item->data; - num += rdata->rrec.length; + num += rdata->length; } } - for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) { - if (SSL3_RECORD_get_type(&s->rlayer.rrec[i]) - != SSL3_RT_APPLICATION_DATA) + for (i = 0; i < sc->rlayer.num_recs; i++) { + if (sc->rlayer.tlsrecs[i].type != SSL3_RT_APPLICATION_DATA) return num; - num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]); + num += sc->rlayer.tlsrecs[i].length; } + num += sc->rlayer.rrlmethod->app_data_pending(sc->rlayer.rrl); + return num; } @@ -145,195 +161,59 @@ void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) void SSL_set_default_read_buffer_len(SSL *s, size_t len) { - SSL3_BUFFER_set_default_len(RECORD_LAYER_get_rbuf(&s->rlayer), len); -} + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); -const char *SSL_rstate_string_long(const SSL *s) -{ - switch (s->rlayer.rstate) { - case SSL_ST_READ_HEADER: - return "read header"; - case SSL_ST_READ_BODY: - return "read body"; - case SSL_ST_READ_DONE: - return "read done"; - default: - return "unknown"; - } + if (sc == NULL || IS_QUIC(s)) + return; + sc->rlayer.default_read_buf_len = len; } -const char *SSL_rstate_string(const SSL *s) +const char *SSL_rstate_string_long(const SSL *s) { - switch (s->rlayer.rstate) { - case SSL_ST_READ_HEADER: - return "RH"; - case SSL_ST_READ_BODY: - return "RB"; - case SSL_ST_READ_DONE: - return "RD"; - default: - return "unknown"; - } -} + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + const char *lng; -/* - * Return values are as per SSL_read() - */ -int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, - size_t *readbytes) -{ - /* - * If extend == 0, obtain new n-byte packet; if extend == 1, increase - * packet by another n bytes. The packet will be in the sub-array of - * s->rlayer.rbuf.buf specified by s->rlayer.packet and - * s->rlayer.packet_length. (If s->rlayer.read_ahead is set, 'max' bytes may - * be stored in rbuf [plus s->rlayer.packet_length bytes if extend == 1].) - * if clearold == 1, move the packet to the start of the buffer; if - * clearold == 0 then leave any old packets where they were - */ - size_t len, left, align = 0; - unsigned char *pkt; - SSL3_BUFFER *rb; + if (sc == NULL) + return NULL; - if (n == 0) - return 0; + if (sc->rlayer.rrlmethod == NULL || sc->rlayer.rrl == NULL) + return "unknown"; - rb = &s->rlayer.rbuf; - if (rb->buf == NULL) - if (!ssl3_setup_read_buffer(s)) { - /* SSLfatal() already called */ - return -1; - } + sc->rlayer.rrlmethod->get_state(sc->rlayer.rrl, NULL, &lng); - left = rb->left; -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); -#endif + return lng; +} - if (!extend) { - /* start with empty packet ... */ - if (left == 0) - rb->offset = align; +const char *SSL_rstate_string(const SSL *s) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + const char *shrt; - s->rlayer.packet = rb->buf + rb->offset; - s->rlayer.packet_length = 0; - /* ... now we can act as if 'extend' was set */ - } + if (sc == NULL) + return NULL; - len = s->rlayer.packet_length; - pkt = rb->buf + align; - /* - * Move any available bytes to front of buffer: 'len' bytes already - * pointed to by 'packet', 'left' extra ones at the end - */ - if (s->rlayer.packet != pkt && clearold == 1) { - memmove(pkt, s->rlayer.packet, len + left); - s->rlayer.packet = pkt; - rb->offset = len + align; - } + if (sc->rlayer.rrlmethod == NULL || sc->rlayer.rrl == NULL) + return "unknown"; - /* - * For DTLS/UDP reads should not span multiple packets because the read - * operation returns the whole packet at once (as long as it fits into - * the buffer). - */ - if (SSL_IS_DTLS(s)) { - if (left == 0 && extend) - return 0; - if (left > 0 && n > left) - n = left; - } + sc->rlayer.rrlmethod->get_state(sc->rlayer.rrl, &shrt, NULL); - /* if there is enough in the buffer from a previous read, take some */ - if (left >= n) { - s->rlayer.packet_length += n; - rb->left = left - n; - rb->offset += n; - *readbytes = n; - return 1; - } + return shrt; +} - /* else we need to read more data */ +static int tls_write_check_pending(SSL_CONNECTION *s, uint8_t type, + const unsigned char *buf, size_t len) +{ + if (s->rlayer.wpend_tot == 0) + return 0; - if (n > rb->len - rb->offset) { - /* does not happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + /* We have pending data, so do some sanity checks */ + if ((s->rlayer.wpend_tot > len) + || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) + && (s->rlayer.wpend_buf != buf)) + || (s->rlayer.wpend_type != type)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_WRITE_RETRY); return -1; } - - /* - * Ktls always reads full records. - * Also, we always act like read_ahead is set for DTLS. - */ - if (!BIO_get_ktls_recv(s->rbio) && !s->rlayer.read_ahead - && !SSL_IS_DTLS(s)) { - /* ignore max parameter */ - max = n; - } else { - if (max < n) - max = n; - if (max > rb->len - rb->offset) - max = rb->len - rb->offset; - } - - while (left < n) { - size_t bioread = 0; - int ret; - - /* - * Now we have len+left bytes at the front of s->s3.rbuf.buf and - * need to read in more until we have len+n (up to len+max if - * possible) - */ - - clear_sys_error(); - if (s->rbio != NULL) { - s->rwstate = SSL_READING; - ret = BIO_read(s->rbio, pkt + len + left, max - left); - if (ret >= 0) - bioread = ret; - if (ret <= 0 - && !BIO_should_retry(s->rbio) - && BIO_eof(s->rbio)) { - if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) { - SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN); - s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY; - } else { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_R_UNEXPECTED_EOF_WHILE_READING); - } - } - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET); - ret = -1; - } - - if (ret <= 0) { - rb->left = left; - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - if (len + left == 0) - ssl3_release_read_buffer(s); - return ret; - } - left += bioread; - /* - * reads should *never* span multiple packets for DTLS because the - * underlying transport protocol is message oriented as opposed to - * byte oriented as in the TLS case. - */ - if (SSL_IS_DTLS(s)) { - if (n > left) - n = left; /* makes the while condition false */ - } - } - - /* done reading, now the book-keeping */ - rb->offset += n; - rb->left = left - n; - s->rlayer.packet_length += n; - s->rwstate = SSL_NOTHING; - *readbytes = n; return 1; } @@ -341,18 +221,19 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, * Call this to write data in records of type 'type' It will return <= 0 if * not all data has been sent or non-blocking IO. */ -int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, +int ssl3_write_bytes(SSL *ssl, uint8_t type, const void *buf_, size_t len, size_t *written) { const unsigned char *buf = buf_; size_t tot; size_t n, max_send_fragment, split_send_fragment, maxpipes; -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - size_t nw; -#endif - SSL3_BUFFER *wb = &s->rlayer.wbuf[0]; int i; - size_t tmpwrit; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + OSSL_RECORD_TEMPLATE tmpls[SSL_MAX_PIPELINES]; + unsigned int recversion; + + if (s == NULL) + return -1; s->rwstate = SSL_NOTHING; tot = s->rlayer.wnum; @@ -360,19 +241,20 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * ensure that if we end up with a smaller value of data to write out * than the original len from a write which didn't complete for * non-blocking I/O and also somehow ended up avoiding the check for - * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be + * this in tls_write_check_pending/SSL_R_BAD_WRITE_RETRY as it must never be * possible to end up with (len-tot) as a large number that will then * promptly send beyond the end of the users buffer ... so we trap and * report the error in a way the user will notice */ if ((len < s->rlayer.wnum) - || ((wb->left != 0) && (len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) { + || ((s->rlayer.wpend_tot != 0) + && (len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_LENGTH); return -1; } if (s->early_data_state == SSL_EARLY_DATA_WRITING - && !early_data_count_ok(s, len, 0, 1)) { + && !ossl_early_data_count_ok(s, len, 0, 1)) { /* SSLfatal() already called */ return -1; } @@ -384,8 +266,8 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * into init unless we have writes pending - in which case we should finish * doing that first. */ - if (wb->left == 0 && (s->key_update != SSL_KEY_UPDATE_NONE - || s->ext.extra_tickets_expected > 0)) + if (s->rlayer.wpend_tot == 0 && (s->key_update != SSL_KEY_UPDATE_NONE + || s->ext.extra_tickets_expected > 0)) ossl_statem_set_in_init(s, 1); /* @@ -393,9 +275,9 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * between receiving the EoED and the CF - but we don't want to handle those * messages yet. */ - if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s) + if (SSL_in_init(ssl) && !ossl_statem_get_in_handshake(s) && s->early_data_state != SSL_EARLY_DATA_UNAUTH_WRITING) { - i = s->handshake_func(s); + i = s->handshake_func(ssl); /* SSLfatal() already called */ if (i < 0) return i; @@ -404,188 +286,54 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, } } - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (wb->left != 0) { - /* SSLfatal() already called if appropriate */ - i = ssl3_write_pending(s, type, &buf[tot], s->rlayer.wpend_tot, - &tmpwrit); + i = tls_write_check_pending(s, type, buf, len); + if (i < 0) { + /* SSLfatal() already called */ + return i; + } else if (i > 0) { + /* Retry needed */ + i = HANDLE_RLAYER_WRITE_RETURN(s, + s->rlayer.wrlmethod->retry_write_records(s->rlayer.wrl)); if (i <= 0) { - /* XXX should we ssl3_release_write_buffer if i<0? */ s->rlayer.wnum = tot; return i; } - tot += tmpwrit; /* this might be last fragment */ - } -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - /* - * Depending on platform multi-block can deliver several *times* - * better performance. Downside is that it has to allocate - * jumbo buffer to accommodate up to 8 records, but the - * compromise is considered worthy. - */ - if (type == SSL3_RT_APPLICATION_DATA - && len >= 4 * (max_send_fragment = ssl_get_max_send_fragment(s)) - && s->compress == NULL - && s->msg_callback == NULL - && !SSL_WRITE_ETM(s) - && SSL_USE_EXPLICIT_IV(s) - && BIO_get_ktls_send(s->wbio) == 0 - && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) - & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0) { - unsigned char aad[13]; - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; - size_t packlen; - int packleni; - - /* minimize address aliasing conflicts */ - if ((max_send_fragment & 0xfff) == 0) - max_send_fragment -= 512; - - if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */ - ssl3_release_write_buffer(s); - - packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, - (int)max_send_fragment, NULL); - - if (len >= 8 * max_send_fragment) - packlen *= 8; - else - packlen *= 4; - - if (!ssl3_setup_write_buffer(s, 1, packlen)) { - /* SSLfatal() already called */ - return -1; - } - } else if (tot == len) { /* done? */ - /* free jumbo buffer */ - ssl3_release_write_buffer(s); - *written = tot; - return 1; - } - - n = (len - tot); - for (;;) { - if (n < 4 * max_send_fragment) { - /* free jumbo buffer */ - ssl3_release_write_buffer(s); - break; - } - - if (s->s3.alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) { - /* SSLfatal() already called if appropriate */ - s->rlayer.wnum = tot; - return i; - } - } - - if (n >= 8 * max_send_fragment) - nw = max_send_fragment * (mb_param.interleave = 8); - else - nw = max_send_fragment * (mb_param.interleave = 4); - - memcpy(aad, s->rlayer.write_sequence, 8); - aad[8] = type; - aad[9] = (unsigned char)(s->version >> 8); - aad[10] = (unsigned char)(s->version); - aad[11] = 0; - aad[12] = 0; - mb_param.out = NULL; - mb_param.inp = aad; - mb_param.len = nw; - - packleni = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, - sizeof(mb_param), &mb_param); - packlen = (size_t)packleni; - if (packleni <= 0 || packlen > wb->len) { /* never happens */ - /* free jumbo buffer */ - ssl3_release_write_buffer(s); - break; - } - - mb_param.out = wb->buf; - mb_param.inp = &buf[tot]; - mb_param.len = nw; + tot += s->rlayer.wpend_tot; + s->rlayer.wpend_tot = 0; + } /* else no retry required */ - if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, - sizeof(mb_param), &mb_param) <= 0) - return -1; - - s->rlayer.write_sequence[7] += mb_param.interleave; - if (s->rlayer.write_sequence[7] < mb_param.interleave) { - int j = 6; - while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ; - } - - wb->offset = 0; - wb->left = packlen; - - s->rlayer.wpend_tot = nw; - s->rlayer.wpend_buf = &buf[tot]; - s->rlayer.wpend_type = type; - s->rlayer.wpend_ret = nw; + if (tot == 0) { + /* + * We've not previously sent any data for this write so memorize + * arguments so that we can detect bad write retries later + */ + s->rlayer.wpend_tot = 0; + s->rlayer.wpend_type = type; + s->rlayer.wpend_buf = buf; + s->rlayer.wpend_ret = len; + } - i = ssl3_write_pending(s, type, &buf[tot], nw, &tmpwrit); - if (i <= 0) { - /* SSLfatal() already called if appropriate */ - if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) { - /* free jumbo buffer */ - ssl3_release_write_buffer(s); - } - s->rlayer.wnum = tot; - return i; - } - if (tmpwrit == n) { - /* free jumbo buffer */ - ssl3_release_write_buffer(s); - *written = tot + tmpwrit; - return 1; - } - n -= tmpwrit; - tot += tmpwrit; - } - } else -#endif /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */ if (tot == len) { /* done? */ - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - *written = tot; return 1; } + /* If we have an alert to send, lets send it */ + if (s->s3.alert_dispatch > 0) { + i = ssl->method->ssl_dispatch_alert(ssl); + if (i <= 0) { + /* SSLfatal() already called if appropriate */ + s->rlayer.wnum = tot; + return i; + } + /* if it went, fall through and send more stuff */ + } + n = (len - tot); max_send_fragment = ssl_get_max_send_fragment(s); split_send_fragment = ssl_get_split_send_fragment(s); - /* - * If max_pipelines is 0 then this means "undefined" and we default to - * 1 pipeline. Similarly if the cipher does not support pipelined - * processing then we also only use 1 pipeline, or if we're not using - * explicit IVs - */ - maxpipes = s->max_pipelines; - if (maxpipes > SSL_MAX_PIPELINES) { - /* - * We should have prevented this when we set max_pipelines so we - * shouldn't get here - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - if (maxpipes == 0 - || s->enc_write_ctx == NULL - || (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) - & EVP_CIPH_FLAG_PIPELINE) == 0 - || !SSL_USE_EXPLICIT_IV(s)) - maxpipes = 1; + if (max_send_fragment == 0 || split_send_fragment == 0 || split_send_fragment > max_send_fragment) { @@ -597,649 +345,199 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, return -1; } + /* + * Some servers hang if initial client hello is larger than 256 bytes + * and record version number > TLS 1.0 + */ + recversion = (s->version == TLS1_3_VERSION) ? TLS1_2_VERSION : s->version; + if (SSL_get_state(ssl) == TLS_ST_CW_CLNT_HELLO + && !s->renegotiate + && TLS1_get_version(ssl) > TLS1_VERSION + && s->hello_retry_request == SSL_HRR_NONE) + recversion = TLS1_VERSION; + for (;;) { - size_t pipelens[SSL_MAX_PIPELINES], tmppipelen, remain; - size_t numpipes, j; + size_t tmppipelen, remain; + size_t j, lensofar = 0; + + /* + * Ask the record layer how it would like to split the amount of data + * that we have, and how many of those records it would like in one go. + */ + maxpipes = s->rlayer.wrlmethod->get_max_records(s->rlayer.wrl, type, n, + max_send_fragment, + &split_send_fragment); + /* + * If max_pipelines is 0 then this means "undefined" and we default to + * whatever the record layer wants to do. Otherwise we use the smallest + * value from the number requested by the record layer, and max number + * configured by the user. + */ + if (s->max_pipelines > 0 && maxpipes > s->max_pipelines) + maxpipes = s->max_pipelines; - if (n == 0) - numpipes = 1; - else - numpipes = ((n - 1) / split_send_fragment) + 1; - if (numpipes > maxpipes) - numpipes = maxpipes; + if (maxpipes > SSL_MAX_PIPELINES) + maxpipes = SSL_MAX_PIPELINES; + + if (split_send_fragment > max_send_fragment) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } - if (n / numpipes >= split_send_fragment) { + if (n / maxpipes >= split_send_fragment) { /* * We have enough data to completely fill all available * pipelines */ - for (j = 0; j < numpipes; j++) - pipelens[j] = split_send_fragment; + for (j = 0; j < maxpipes; j++) { + tmpls[j].type = type; + tmpls[j].version = recversion; + tmpls[j].buf = &(buf[tot]) + (j * split_send_fragment); + tmpls[j].buflen = split_send_fragment; + } + /* Remember how much data we are going to be sending */ + s->rlayer.wpend_tot = maxpipes * split_send_fragment; } else { /* We can partially fill all available pipelines */ - tmppipelen = n / numpipes; - remain = n % numpipes; - for (j = 0; j < numpipes; j++) { - pipelens[j] = tmppipelen; - if (j < remain) - pipelens[j]++; + tmppipelen = n / maxpipes; + remain = n % maxpipes; + /* + * If there is a remainder we add an extra byte to the first few + * pipelines + */ + if (remain > 0) + tmppipelen++; + for (j = 0; j < maxpipes; j++) { + tmpls[j].type = type; + tmpls[j].version = recversion; + tmpls[j].buf = &(buf[tot]) + lensofar; + tmpls[j].buflen = tmppipelen; + lensofar += tmppipelen; + if (j + 1 == remain) + tmppipelen--; } + /* Remember how much data we are going to be sending */ + s->rlayer.wpend_tot = n; } - i = do_ssl3_write(s, type, &(buf[tot]), pipelens, numpipes, 0, - &tmpwrit); + i = HANDLE_RLAYER_WRITE_RETURN(s, + s->rlayer.wrlmethod->write_records(s->rlayer.wrl, tmpls, maxpipes)); if (i <= 0) { /* SSLfatal() already called if appropriate */ - /* XXX should we ssl3_release_write_buffer if i<0? */ s->rlayer.wnum = tot; return i; } - if (tmpwrit == n || - (type == SSL3_RT_APPLICATION_DATA && - (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { - /* - * next chunk of data should get another prepended empty fragment - * in ciphersuites with known-IV weakness: - */ - s->s3.empty_fragment_done = 0; - - if (tmpwrit == n - && (s->mode & SSL_MODE_RELEASE_BUFFERS) != 0 - && !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - - *written = tot + tmpwrit; + if (s->rlayer.wpend_tot == n + || (type == SSL3_RT_APPLICATION_DATA + && (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0)) { + *written = tot + s->rlayer.wpend_tot; + s->rlayer.wpend_tot = 0; return 1; } - n -= tmpwrit; - tot += tmpwrit; + n -= s->rlayer.wpend_tot; + tot += s->rlayer.wpend_tot; } } -int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - size_t *pipelens, size_t numpipes, - int create_empty_fragment, size_t *written) +int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret, + char *file, int line) { - WPACKET pkt[SSL_MAX_PIPELINES]; - SSL3_RECORD wr[SSL_MAX_PIPELINES]; - WPACKET *thispkt; - SSL3_RECORD *thiswr; - unsigned char *recordstart; - int i, mac_size, clear = 0; - size_t prefix_len = 0; - int eivlen = 0; - size_t align = 0; - SSL3_BUFFER *wb; - SSL_SESSION *sess; - size_t totlen = 0, len, wpinited = 0; - size_t j; - - for (j = 0; j < numpipes; j++) - totlen += pipelens[j]; - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (RECORD_LAYER_write_pending(&s->rlayer)) { - /* Calls SSLfatal() as required */ - return ssl3_write_pending(s, type, buf, totlen, written); - } - - /* If we have an alert to send, lets send it */ - if (s->s3.alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) { - /* SSLfatal() already called if appropriate */ - return i; - } - /* if it went, fall through and send more stuff */ - } - - if (s->rlayer.numwpipes < numpipes) { - if (!ssl3_setup_write_buffer(s, numpipes, 0)) { - /* SSLfatal() already called */ - return -1; - } - } - - if (totlen == 0 && !create_empty_fragment) - return 0; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); - sess = s->session; - - if ((sess == NULL) - || (s->enc_write_ctx == NULL) - || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) { - clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ - mac_size = 0; + if (ret == OSSL_RECORD_RETURN_RETRY) { + s->rwstate = writing ? SSL_WRITING : SSL_READING; + ret = -1; } else { - mac_size = EVP_MD_CTX_get_size(s->write_hash); - if (mac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - /* - * 'create_empty_fragment' is true only when this function calls itself - */ - if (!clear && !create_empty_fragment && !s->s3.empty_fragment_done) { - /* - * countermeasure against known-IV weakness in CBC ciphersuites (see - * http://www.openssl.org/~bodo/tls-cbc.txt) - */ - - if (s->s3.need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { - /* - * recursive function call with 'create_empty_fragment' set; this - * prepares and buffers the data for an empty fragment (these - * 'prefix_len' bytes are sent out later together with the actual - * payload) - */ - size_t tmppipelen = 0; - int ret; - - ret = do_ssl3_write(s, type, buf, &tmppipelen, 1, 1, &prefix_len); - if (ret <= 0) { - /* SSLfatal() already called if appropriate */ - goto err; - } - - if (prefix_len > - (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { - /* insufficient space */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - s->s3.empty_fragment_done = 1; - } - - if (BIO_get_ktls_send(s->wbio)) { - /* - * ktls doesn't modify the buffer, but to avoid a warning we need to - * discard the const qualifier. - * This doesn't leak memory because the buffers have been released when - * switching to ktls. - */ - SSL3_BUFFER_set_buf(&s->rlayer.wbuf[0], (unsigned char *)buf); - SSL3_BUFFER_set_offset(&s->rlayer.wbuf[0], 0); - SSL3_BUFFER_set_app_buffer(&s->rlayer.wbuf[0], 1); - goto wpacket_init_complete; - } - - if (create_empty_fragment) { - wb = &s->rlayer.wbuf[0]; -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - /* - * extra fragment would be couple of cipher blocks, which would be - * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real - * payload, then we can just pretend we simply have two headers. - */ - align = (size_t)SSL3_BUFFER_get_buf(wb) + 2 * SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); -#endif - SSL3_BUFFER_set_offset(wb, align); - if (!WPACKET_init_static_len(&pkt[0], SSL3_BUFFER_get_buf(wb), - SSL3_BUFFER_get_len(wb), 0) - || !WPACKET_allocate_bytes(&pkt[0], align, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - wpinited = 1; - } else if (prefix_len) { - wb = &s->rlayer.wbuf[0]; - if (!WPACKET_init_static_len(&pkt[0], - SSL3_BUFFER_get_buf(wb), - SSL3_BUFFER_get_len(wb), 0) - || !WPACKET_allocate_bytes(&pkt[0], SSL3_BUFFER_get_offset(wb) - + prefix_len, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - wpinited = 1; - } else { - for (j = 0; j < numpipes; j++) { - thispkt = &pkt[j]; - - wb = &s->rlayer.wbuf[j]; -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 - align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD); -#endif - SSL3_BUFFER_set_offset(wb, align); - if (!WPACKET_init_static_len(thispkt, SSL3_BUFFER_get_buf(wb), - SSL3_BUFFER_get_len(wb), 0) - || !WPACKET_allocate_bytes(thispkt, align, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - wpinited++; - } - } - - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) { - int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx); - if (eivlen < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); - goto err; - } - if (eivlen <= 1) - eivlen = 0; - } else if (mode == EVP_CIPH_GCM_MODE) { - /* Need explicit part of IV for GCM mode */ - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - } else if (mode == EVP_CIPH_CCM_MODE) { - eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; - } - } - - wpacket_init_complete: - - totlen = 0; - /* Clear our SSL3_RECORD structures */ - memset(wr, 0, sizeof(wr)); - for (j = 0; j < numpipes; j++) { - unsigned int version = (s->version == TLS1_3_VERSION) ? TLS1_2_VERSION - : s->version; - unsigned char *compressdata = NULL; - size_t maxcomplen; - unsigned int rectype; - - thispkt = &pkt[j]; - thiswr = &wr[j]; - - /* - * In TLSv1.3, once encrypting, we always use application data for the - * record type - */ - if (SSL_TREAT_AS_TLS13(s) - && s->enc_write_ctx != NULL - && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS - || type != SSL3_RT_ALERT)) - rectype = SSL3_RT_APPLICATION_DATA; - else - rectype = type; - SSL3_RECORD_set_type(thiswr, rectype); - - /* - * Some servers hang if initial client hello is larger than 256 bytes - * and record version number > TLS 1.0 - */ - if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO - && !s->renegotiate - && TLS1_get_version(s) > TLS1_VERSION - && s->hello_retry_request == SSL_HRR_NONE) - version = TLS1_VERSION; - SSL3_RECORD_set_rec_version(thiswr, version); - - maxcomplen = pipelens[j]; - if (s->compress != NULL) - maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; - - /* - * When using offload kernel will write the header. - * Otherwise write the header now - */ - if (!BIO_get_ktls_send(s->wbio) - && (!WPACKET_put_bytes_u8(thispkt, rectype) - || !WPACKET_put_bytes_u16(thispkt, version) - || !WPACKET_start_sub_packet_u16(thispkt) - || (eivlen > 0 - && !WPACKET_allocate_bytes(thispkt, eivlen, NULL)) - || (maxcomplen > 0 - && !WPACKET_reserve_bytes(thispkt, maxcomplen, - &compressdata)))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* lets setup the record stuff. */ - SSL3_RECORD_set_data(thiswr, compressdata); - SSL3_RECORD_set_length(thiswr, pipelens[j]); - SSL3_RECORD_set_input(thiswr, (unsigned char *)&buf[totlen]); - totlen += pipelens[j]; - - /* - * we now 'read' from thiswr->input, thiswr->length bytes into - * thiswr->data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s, thiswr) - || !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE); - goto err; - } - } else { - if (BIO_get_ktls_send(s->wbio)) { - SSL3_RECORD_reset_data(&wr[j]); - } else { - if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - SSL3_RECORD_reset_input(&wr[j]); - } - } - - if (SSL_TREAT_AS_TLS13(s) - && !BIO_get_ktls_send(s->wbio) - && s->enc_write_ctx != NULL - && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS - || type != SSL3_RT_ALERT)) { - size_t rlen, max_send_fragment; - - if (!WPACKET_put_bytes_u8(thispkt, type)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - SSL3_RECORD_add_length(thiswr, 1); - - /* Add TLS1.3 padding */ - max_send_fragment = ssl_get_max_send_fragment(s); - rlen = SSL3_RECORD_get_length(thiswr); - if (rlen < max_send_fragment) { - size_t padding = 0; - size_t max_padding = max_send_fragment - rlen; - if (s->record_padding_cb != NULL) { - padding = s->record_padding_cb(s, type, rlen, s->record_padding_arg); - } else if (s->block_padding > 0) { - size_t mask = s->block_padding - 1; - size_t remainder; - - /* optimize for power of 2 */ - if ((s->block_padding & mask) == 0) - remainder = rlen & mask; - else - remainder = rlen % s->block_padding; - /* don't want to add a block of padding if we don't have to */ - if (remainder == 0) - padding = 0; - else - padding = s->block_padding - remainder; - } - if (padding > 0) { - /* do not allow the record to exceed max plaintext length */ - if (padding > max_padding) - padding = max_padding; - if (!WPACKET_memset(thispkt, 0, padding)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - ERR_R_INTERNAL_ERROR); - goto err; - } - SSL3_RECORD_add_length(thiswr, padding); - } - } - } - - /* - * we should still have the output to thiswr->data and the input from - * wr->input. Length should be thiswr->length. thiswr->data still points - * in the wb->buf - */ - - if (!BIO_get_ktls_send(s->wbio) && !SSL_WRITE_ETM(s) && mac_size != 0) { - unsigned char *mac; - - if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) - || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - /* - * Reserve some bytes for any growth that may occur during encryption. If - * we are adding the MAC independently of the cipher algorithm, then the - * max encrypted overhead does not need to include an allocation for that - * MAC - */ - if (!BIO_get_ktls_send(s->wbio)) { - if (!WPACKET_reserve_bytes(thispkt, - SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD - - mac_size, NULL) + s->rwstate = SSL_NOTHING; + if (ret == OSSL_RECORD_RETURN_EOF) { + if (writing) { /* - * We also need next the amount of bytes written to this - * sub-packet + * This shouldn't happen with a writing operation. We treat it + * as fatal. */ - || !WPACKET_get_length(thispkt, &len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* Get a pointer to the start of this record excluding header */ - recordstart = WPACKET_get_curr(thispkt) - len; - SSL3_RECORD_set_data(thiswr, recordstart); - SSL3_RECORD_reset_input(thiswr); - SSL3_RECORD_set_length(thiswr, len); - } - } - - if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) { - /* - * We haven't actually negotiated the version yet, but we're trying to - * send early data - so we need to use the tls13enc function. - */ - if (tls13_enc(s, wr, numpipes, 1, NULL, mac_size) < 1) { - if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - } - goto err; - } - } else { - if (!BIO_get_ktls_send(s->wbio)) { - if (s->method->ssl3_enc->enc(s, wr, numpipes, 1, NULL, - mac_size) < 1) { - if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - } - goto err; - } - } - } - - for (j = 0; j < numpipes; j++) { - size_t origlen; - - thispkt = &pkt[j]; - thiswr = &wr[j]; - - if (BIO_get_ktls_send(s->wbio)) - goto mac_done; - - /* Allocate bytes for the encryption overhead */ - if (!WPACKET_get_length(thispkt, &origlen) - /* Check we allowed enough room for the encryption growth */ - || !ossl_assert(origlen + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD - - mac_size >= thiswr->length) - /* Encryption should never shrink the data! */ - || origlen > thiswr->length - || (thiswr->length > origlen - && !WPACKET_allocate_bytes(thispkt, - thiswr->length - origlen, - NULL))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - if (SSL_WRITE_ETM(s) && mac_size != 0) { - unsigned char *mac; - - if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) - || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; + ERR_new(); + ERR_set_debug(file, line, 0); + ossl_statem_fatal(s, SSL_AD_INTERNAL_ERROR, + ERR_R_INTERNAL_ERROR, NULL); + ret = OSSL_RECORD_RETURN_FATAL; + } else if ((s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) != 0) { + SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); + s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY; + } else { + ERR_new(); + ERR_set_debug(file, line, 0); + ossl_statem_fatal(s, SSL_AD_DECODE_ERROR, + SSL_R_UNEXPECTED_EOF_WHILE_READING, NULL); } - SSL3_RECORD_add_length(thiswr, mac_size); - } - - if (!WPACKET_get_length(thispkt, &len) - || !WPACKET_close(thispkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (s->msg_callback) { - recordstart = WPACKET_get_curr(thispkt) - len - - SSL3_RT_HEADER_LENGTH; - s->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart, - SSL3_RT_HEADER_LENGTH, s, - s->msg_callback_arg); - - if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) { - unsigned char ctype = type; + } else if (ret == OSSL_RECORD_RETURN_FATAL) { + int al = s->rlayer.rrlmethod->get_alert_code(s->rlayer.rrl); - s->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE, - &ctype, 1, s, s->msg_callback_arg); + if (al != SSL_AD_NO_ALERT) { + ERR_new(); + ERR_set_debug(file, line, 0); + ossl_statem_fatal(s, al, SSL_R_RECORD_LAYER_FAILURE, NULL); } - } - - if (!WPACKET_finish(thispkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* header is added by the kernel when using offload */ - SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH); - - if (create_empty_fragment) { /* - * we are in a recursive call; just return the length, don't write - * out anything here + * else some failure but there is no alert code. We don't log an + * error for this. The record layer should have logged an error + * already or, if not, its due to some sys call error which will be + * reported via SSL_ERROR_SYSCALL and errno. */ - if (j > 0) { - /* We should never be pipelining an empty fragment!! */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - *written = SSL3_RECORD_get_length(thiswr); - return 1; } - - mac_done: /* - * we should now have thiswr->data pointing to the encrypted data, which - * is thiswr->length long + * The record layer distinguishes the cases of EOF, non-fatal + * err and retry. Upper layers do not. + * If we got a retry or success then *ret is already correct, + * otherwise we need to convert the return value. */ - SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for - * debugging */ - - /* now let's set up wb */ - SSL3_BUFFER_set_left(&s->rlayer.wbuf[j], - prefix_len + SSL3_RECORD_get_length(thiswr)); + if (ret == OSSL_RECORD_RETURN_NON_FATAL_ERR || ret == OSSL_RECORD_RETURN_EOF) + ret = 0; + else if (ret < OSSL_RECORD_RETURN_NON_FATAL_ERR) + ret = -1; } - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->rlayer.wpend_tot = totlen; - s->rlayer.wpend_buf = buf; - s->rlayer.wpend_type = type; - s->rlayer.wpend_ret = totlen; - - /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, totlen, written); - err: - for (j = 0; j < wpinited; j++) - WPACKET_cleanup(&pkt[j]); - return -1; + return ret; } -/* if s->s3.wbuf.left != 0, we need to call this - * - * Return values are as per SSL_write() - */ -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, - size_t *written) +int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length) { - int i; - SSL3_BUFFER *wb = s->rlayer.wbuf; - size_t currbuf = 0; - size_t tmpwrit = 0; - - if ((s->rlayer.wpend_tot > len) - || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) - && (s->rlayer.wpend_buf != buf)) - || (s->rlayer.wpend_type != type)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_WRITE_RETRY); - return -1; - } - - for (;;) { - /* Loop until we find a buffer we haven't written out yet */ - if (SSL3_BUFFER_get_left(&wb[currbuf]) == 0 - && currbuf < s->rlayer.numwpipes - 1) { - currbuf++; - continue; - } - clear_sys_error(); - if (s->wbio != NULL) { - s->rwstate = SSL_WRITING; - - /* - * To prevent coalescing of control and data messages, - * such as in buffer_write, we flush the BIO - */ - if (BIO_get_ktls_send(s->wbio) && type != SSL3_RT_APPLICATION_DATA) { - i = BIO_flush(s->wbio); - if (i <= 0) - return i; - BIO_set_ktls_ctrl_msg(s->wbio, type); - } - i = BIO_write(s->wbio, (char *) - &(SSL3_BUFFER_get_buf(&wb[currbuf]) - [SSL3_BUFFER_get_offset(&wb[currbuf])]), - (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf])); - if (i >= 0) - tmpwrit = i; - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BIO_NOT_SET); - i = -1; + assert(rr->length >= length); + if (rr->rechandle != NULL) { + if (length == 0) + length = rr->length; + /* The record layer allocated the buffers for this record */ + if (HANDLE_RLAYER_READ_RETURN(s, + s->rlayer.rrlmethod->release_record(s->rlayer.rrl, + rr->rechandle, + length)) <= 0) { + /* RLAYER_fatal already called */ + return 0; } - /* - * When an empty fragment is sent on a connection using KTLS, - * it is sent as a write of zero bytes. If this zero byte - * write succeeds, i will be 0 rather than a non-zero value. - * Treat i == 0 as success rather than an error for zero byte - * writes to permit this case. - */ - if (i >= 0 && tmpwrit == SSL3_BUFFER_get_left(&wb[currbuf])) { - SSL3_BUFFER_set_left(&wb[currbuf], 0); - SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit); - if (currbuf + 1 < s->rlayer.numwpipes) - continue; - s->rwstate = SSL_NOTHING; - *written = s->rlayer.wpend_ret; - return 1; - } else if (i <= 0) { - if (SSL_IS_DTLS(s)) { - /* - * For DTLS, just drop it. That's kind of the whole point in - * using a datagram service - */ - SSL3_BUFFER_set_left(&wb[currbuf], 0); - } - return i; - } - SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit); - SSL3_BUFFER_sub_left(&wb[currbuf], tmpwrit); + if (length == rr->length) + s->rlayer.curr_rec++; + } else if (length == 0 || length == rr->length) { + /* We allocated the buffers for this record (only happens with DTLS) */ + OPENSSL_free(rr->allocdata); + rr->allocdata = NULL; } + rr->length -= length; + if (rr->length > 0) + rr->off += length; + else + rr->off = 0; + + return 1; } /*- * Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_HANDSHAKE (when tls_get_message_header and tls_get_message_body + * call us) * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) * - 0 (during a shutdown, no data has to be returned) * @@ -1264,30 +562,23 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, * Application data protocol * none of our business */ -int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, - size_t len, int peek, size_t *readbytes) +int ssl3_read_bytes(SSL *ssl, uint8_t type, uint8_t *recvd_type, + unsigned char *buf, size_t len, + int peek, size_t *readbytes) { int i, j, ret; - size_t n, curr_rec, num_recs, totalbytes; - SSL3_RECORD *rr; - SSL3_BUFFER *rbuf; + size_t n, curr_rec, totalbytes; + TLS_RECORD *rr; void (*cb) (const SSL *ssl, int type2, int val) = NULL; - int is_tls13 = SSL_IS_TLS13(s); - - rbuf = &s->rlayer.rbuf; + int is_tls13; + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); - if (!SSL3_BUFFER_is_initialised(rbuf)) { - /* Not initialized yet */ - if (!ssl3_setup_read_buffer(s)) { - /* SSLfatal() already called */ - return -1; - } - } + is_tls13 = SSL_CONNECTION_IS_TLS13(s); - if ((type && (type != SSL3_RT_APPLICATION_DATA) - && (type != SSL3_RT_HANDSHAKE)) || (peek - && (type != - SSL3_RT_APPLICATION_DATA))) { + if ((type != 0 + && (type != SSL3_RT_APPLICATION_DATA) + && (type != SSL3_RT_HANDSHAKE)) + || (peek && (type != SSL3_RT_APPLICATION_DATA))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -1322,9 +613,9 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * Now s->rlayer.handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ - if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) { + if (!ossl_statem_get_in_handshake(s) && SSL_in_init(ssl)) { /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); + i = s->handshake_func(ssl); /* SSLfatal() already called */ if (i < 0) return i; @@ -1341,39 +632,32 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * rr[i].off, - offset into 'data' for next read * rr[i].length, - number of bytes. */ - rr = s->rlayer.rrec; - num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer); - - do { - /* get new records if necessary */ - if (num_recs == 0) { - ret = ssl3_get_record(s); + /* get new records if necessary */ + if (s->rlayer.curr_rec >= s->rlayer.num_recs) { + s->rlayer.curr_rec = s->rlayer.num_recs = 0; + do { + rr = &s->rlayer.tlsrecs[s->rlayer.num_recs]; + + ret = HANDLE_RLAYER_READ_RETURN(s, + s->rlayer.rrlmethod->read_record(s->rlayer.rrl, + &rr->rechandle, + &rr->version, &rr->type, + &rr->data, &rr->length, + NULL, NULL)); if (ret <= 0) { /* SSLfatal() already called if appropriate */ return ret; } - num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer); - if (num_recs == 0) { - /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - } - /* Skip over any records we have already read */ - for (curr_rec = 0; - curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]); - curr_rec++) ; - if (curr_rec == num_recs) { - RECORD_LAYER_set_numrpipes(&s->rlayer, 0); - num_recs = 0; - curr_rec = 0; - } - } while (num_recs == 0); - rr = &rr[curr_rec]; + rr->off = 0; + s->rlayer.num_recs++; + } while (s->rlayer.rrlmethod->processed_read_pending(s->rlayer.rrl) + && s->rlayer.num_recs < SSL_MAX_PIPELINES); + } + rr = &s->rlayer.tlsrecs[s->rlayer.curr_rec]; if (s->rlayer.handshake_fragment_len > 0 - && SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE - && SSL_IS_TLS13(s)) { + && rr->type != SSL3_RT_HANDSHAKE + && SSL_CONNECTION_IS_TLS13(s)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA); return -1; @@ -1383,15 +667,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * Reset the count of consecutive warning alerts if we've got a non-empty * record that isn't an alert. */ - if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT - && SSL3_RECORD_get_length(rr) != 0) + if (rr->type != SSL3_RT_ALERT && rr->length != 0) s->rlayer.alert_count = 0; /* we now have a packet which can be read and processed */ if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, * reset by ssl3_get_finished */ - && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) { + && (rr->type != SSL3_RT_HANDSHAKE)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); return -1; @@ -1402,13 +685,13 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * 'peek' mode) */ if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - SSL3_RECORD_set_length(rr, 0); + s->rlayer.curr_rec++; s->rwstate = SSL_NOTHING; return 0; } - if (type == SSL3_RECORD_get_type(rr) - || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC + if (type == rr->type + || (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && type == SSL3_RT_HANDSHAKE && recvd_type != NULL && !is_tls13)) { /* @@ -1420,37 +703,39 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * make sure that we are not getting application data when we are * doing a handshake for the first time */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { + if (SSL_in_init(ssl) && type == SSL3_RT_APPLICATION_DATA + && SSL_IS_FIRST_HANDSHAKE(s)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_APP_DATA_IN_HANDSHAKE); return -1; } if (type == SSL3_RT_HANDSHAKE - && SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC + && rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && s->rlayer.handshake_fragment_len > 0) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY); return -1; } if (recvd_type != NULL) - *recvd_type = SSL3_RECORD_get_type(rr); + *recvd_type = rr->type; if (len == 0) { /* - * Mark a zero length record as read. This ensures multiple calls to + * Skip a zero length record. This ensures multiple calls to * SSL_read() with a zero length buffer will eventually cause * SSL_pending() to report data as being available. */ - if (SSL3_RECORD_get_length(rr) == 0) - SSL3_RECORD_set_read(rr); + if (rr->length == 0 && !ssl_release_record(s, rr, 0)) + return -1; + return 0; } totalbytes = 0; + curr_rec = s->rlayer.curr_rec; do { - if (len - totalbytes > SSL3_RECORD_get_length(rr)) - n = SSL3_RECORD_get_length(rr); + if (len - totalbytes > rr->length) + n = rr->length; else n = len - totalbytes; @@ -1458,35 +743,25 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, buf += n; if (peek) { /* Mark any zero length record as consumed CVE-2016-6305 */ - if (SSL3_RECORD_get_length(rr) == 0) - SSL3_RECORD_set_read(rr); + if (rr->length == 0 && !ssl_release_record(s, rr, 0)) + return -1; } else { - if (s->options & SSL_OP_CLEANSE_PLAINTEXT) - OPENSSL_cleanse(&(rr->data[rr->off]), n); - SSL3_RECORD_sub_length(rr, n); - SSL3_RECORD_add_off(rr, n); - if (SSL3_RECORD_get_length(rr) == 0) { - s->rlayer.rstate = SSL_ST_READ_HEADER; - SSL3_RECORD_set_off(rr, 0); - SSL3_RECORD_set_read(rr); - } + if (!ssl_release_record(s, rr, n)) + return -1; } - if (SSL3_RECORD_get_length(rr) == 0 - || (peek && n == SSL3_RECORD_get_length(rr))) { - curr_rec++; + if (rr->length == 0 + || (peek && n == rr->length)) { rr++; + curr_rec++; } totalbytes += n; - } while (type == SSL3_RT_APPLICATION_DATA && curr_rec < num_recs - && totalbytes < len); + } while (type == SSL3_RT_APPLICATION_DATA + && curr_rec < s->rlayer.num_recs + && totalbytes < len); if (totalbytes == 0) { /* We must have read empty records. Get more data */ goto start; } - if (!peek && curr_rec == num_recs - && (s->mode & SSL_MODE_RELEASE_BUFFERS) - && SSL3_BUFFER_get_left(rbuf) == 0) - ssl3_release_read_buffer(s); *readbytes = totalbytes; return 1; } @@ -1500,7 +775,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, /* * Lets just double check that we've not got an SSLv2 record */ - if (rr->rec_version == SSL2_VERSION) { + if (rr->version == SSL2_VERSION) { /* * Should never happen. ssl3_get_record() should only give us an SSLv2 * record back if this is the first packet and we are looking for an @@ -1511,7 +786,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, return -1; } - if (s->method->version == TLS_ANY_VERSION + if (ssl->method->version == TLS_ANY_VERSION && (s->server || rr->type != SSL3_RT_ALERT)) { /* * If we've got this far and still haven't decided on what version @@ -1519,7 +794,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * with. We shouldn't be receiving anything other than a ClientHello * if we are a server. */ - s->version = rr->rec_version; + s->version = rr->version; SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); return -1; } @@ -1529,13 +804,12 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ - if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) { + if (rr->type == SSL3_RT_ALERT) { unsigned int alert_level, alert_descr; - unsigned char *alert_bytes = SSL3_RECORD_get_data(rr) - + SSL3_RECORD_get_off(rr); + const unsigned char *alert_bytes = rr->data + rr->off; PACKET alert; - if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr)) + if (!PACKET_buf_init(&alert, alert_bytes, rr->length) || !PACKET_get_1(&alert, &alert_level) || !PACKET_get_1(&alert, &alert_descr) || PACKET_remaining(&alert) != 0) { @@ -1544,23 +818,24 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s, + s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, ssl, s->msg_callback_arg); if (s->info_callback != NULL) cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; + else if (ssl->ctx->info_callback != NULL) + cb = ssl->ctx->info_callback; if (cb != NULL) { j = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, j); + cb(ssl, SSL_CB_READ_ALERT, j); } - if (alert_level == SSL3_AL_WARNING + if ((!is_tls13 && alert_level == SSL3_AL_WARNING) || (is_tls13 && alert_descr == SSL_AD_USER_CANCELLED)) { s->s3.warn_alert = alert_descr; - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(s, rr, 0)) + return -1; s->rlayer.alert_count++; if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) { @@ -1587,7 +862,8 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, SSL_AD_REASON_OFFSET + alert_descr, "SSL alert number %d", alert_descr); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(s, rr, 0)) + return -1; SSL_CTX_remove_session(s->session_ctx, s->session); return 0; } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { @@ -1611,7 +887,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } if ((s->shutdown & SSL_SENT_SHUTDOWN) != 0) { - if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) { + if (rr->type == SSL3_RT_HANDSHAKE) { BIO *rbio; /* @@ -1621,15 +897,15 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * because we are unable to write any response due to having already * sent close_notify. */ - if (!SSL_IS_TLS13(s)) { - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!ssl_release_record(s, rr, 0)) + return -1; if ((s->mode & SSL_MODE_AUTO_RETRY) != 0) goto start; s->rwstate = SSL_READING; - rbio = SSL_get_rbio(s); + rbio = SSL_get_rbio(ssl); BIO_clear_retry_flags(rbio); BIO_set_retry_read(rbio); return -1; @@ -1642,8 +918,8 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * above. * No alert sent because we already sent close_notify */ - SSL3_RECORD_set_length(rr, 0); - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(s, rr, 0)) + return -1; SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY); return -1; @@ -1656,29 +932,32 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * "SHUTDOWN" code above to avoid filling the fragment storage with data * that we're just going to discard. */ - if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) { + if (rr->type == SSL3_RT_HANDSHAKE) { size_t dest_maxlen = sizeof(s->rlayer.handshake_fragment); unsigned char *dest = s->rlayer.handshake_fragment; size_t *dest_len = &s->rlayer.handshake_fragment_len; n = dest_maxlen - *dest_len; /* available space in 'dest' */ - if (SSL3_RECORD_get_length(rr) < n) - n = SSL3_RECORD_get_length(rr); /* available bytes */ + if (rr->length < n) + n = rr->length; /* available bytes */ /* now move 'n' bytes: */ - memcpy(dest + *dest_len, - SSL3_RECORD_get_data(rr) + SSL3_RECORD_get_off(rr), n); - SSL3_RECORD_add_off(rr, n); - SSL3_RECORD_sub_length(rr, n); - *dest_len += n; - if (SSL3_RECORD_get_length(rr) == 0) - SSL3_RECORD_set_read(rr); + if (n > 0) { + memcpy(dest + *dest_len, rr->data + rr->off, n); + *dest_len += n; + } + /* + * We release the number of bytes consumed, or the whole record if it + * is zero length + */ + if ((n > 0 || rr->length == 0) && !ssl_release_record(s, rr, n)) + return -1; if (*dest_len < dest_maxlen) goto start; /* fragment was too small */ } - if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) { + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY); return -1; } @@ -1694,7 +973,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, /* We found handshake data, so we're going back into init */ ossl_statem_set_in_init(s, 1); - i = s->handshake_func(s); + i = s->handshake_func(ssl); /* SSLfatal() already called if appropriate */ if (i < 0) return i; @@ -1711,8 +990,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, return -1; if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (SSL3_BUFFER_get_left(rbuf) == 0) { - /* no read-ahead left? */ + if (!RECORD_LAYER_read_pending(&s->rlayer)) { BIO *bio; /* * In the case where we try to read application data, but we @@ -1721,7 +999,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * problems in the blocking world */ s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); + bio = SSL_get_rbio(ssl); BIO_clear_retry_flags(bio); BIO_set_retry_read(bio); return -1; @@ -1730,7 +1008,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, goto start; } - switch (SSL3_RECORD_get_type(rr)) { + switch (rr->type) { default: /* * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but @@ -1772,12 +1050,13 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * decryption was applied. We just skip it and move on to the next * record. */ - if (!early_data_count_ok(s, rr->length, - EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { + if (!ossl_early_data_count_ok(s, rr->length, + EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { /* SSLfatal() already called */ return -1; } - SSL3_RECORD_set_read(rr); + if (!ssl_release_record(s, rr, 0)) + return -1; goto start; } else { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); @@ -1786,30 +1065,367 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } } -void ssl3_record_sequence_update(unsigned char *seq) -{ - int i; - - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } -} - /* * Returns true if the current rrec was sent in SSLv2 backwards compatible * format and false otherwise. */ int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl) { - return SSL3_RECORD_is_sslv2_record(&rl->rrec[0]); + if (SSL_CONNECTION_IS_DTLS(rl->s)) + return 0; + return rl->tlsrecs[0].version == SSL2_VERSION; +} + +static OSSL_FUNC_rlayer_msg_callback_fn rlayer_msg_callback_wrapper; +static void rlayer_msg_callback_wrapper(int write_p, int version, + int content_type, const void *buf, + size_t len, void *cbarg) +{ + SSL_CONNECTION *s = cbarg; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + if (s->msg_callback != NULL) + s->msg_callback(write_p, version, content_type, buf, len, ssl, + s->msg_callback_arg); } -/* - * Returns the length in bytes of the current rrec - */ -size_t RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl) +static OSSL_FUNC_rlayer_security_fn rlayer_security_wrapper; +static int rlayer_security_wrapper(void *cbarg, int op, int bits, int nid, + void *other) +{ + SSL_CONNECTION *s = cbarg; + + return ssl_security(s, op, bits, nid, other); +} + +static OSSL_FUNC_rlayer_padding_fn rlayer_padding_wrapper; +static size_t rlayer_padding_wrapper(void *cbarg, int type, size_t len) +{ + SSL_CONNECTION *s = cbarg; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + return s->rlayer.record_padding_cb(ssl, type, len, + s->rlayer.record_padding_arg); +} + +static const OSSL_DISPATCH rlayer_dispatch[] = { + { OSSL_FUNC_RLAYER_SKIP_EARLY_DATA, (void (*)(void))ossl_statem_skip_early_data }, + { OSSL_FUNC_RLAYER_MSG_CALLBACK, (void (*)(void))rlayer_msg_callback_wrapper }, + { OSSL_FUNC_RLAYER_SECURITY, (void (*)(void))rlayer_security_wrapper }, + { OSSL_FUNC_RLAYER_PADDING, (void (*)(void))rlayer_padding_wrapper }, + OSSL_DISPATCH_END +}; + +void ossl_ssl_set_custom_record_layer(SSL_CONNECTION *s, + const OSSL_RECORD_METHOD *meth, + void *rlarg) +{ + s->rlayer.custom_rlmethod = meth; + s->rlayer.rlarg = rlarg; +} + +static const OSSL_RECORD_METHOD *ssl_select_next_record_layer(SSL_CONNECTION *s, + int direction, + int level) { - return SSL3_RECORD_get_length(&rl->rrec[0]); + if (s->rlayer.custom_rlmethod != NULL) + return s->rlayer.custom_rlmethod; + + if (level == OSSL_RECORD_PROTECTION_LEVEL_NONE) { + if (SSL_CONNECTION_IS_DTLS(s)) + return &ossl_dtls_record_method; + + return &ossl_tls_record_method; + } + +#ifndef OPENSSL_NO_KTLS + /* KTLS does not support renegotiation */ + if (level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION + && (s->options & SSL_OP_ENABLE_KTLS) != 0 + && (SSL_CONNECTION_IS_TLS13(s) || SSL_IS_FIRST_HANDSHAKE(s))) + return &ossl_ktls_record_method; +#endif + + /* Default to the current OSSL_RECORD_METHOD */ + return direction == OSSL_RECORD_DIRECTION_READ ? s->rlayer.rrlmethod + : s->rlayer.wrlmethod; +} + +static int ssl_post_record_layer_select(SSL_CONNECTION *s, int direction) +{ + const OSSL_RECORD_METHOD *thismethod; + OSSL_RECORD_LAYER *thisrl; + + if (direction == OSSL_RECORD_DIRECTION_READ) { + thismethod = s->rlayer.rrlmethod; + thisrl = s->rlayer.rrl; + } else { + thismethod = s->rlayer.wrlmethod; + thisrl = s->rlayer.wrl; + } + +#ifndef OPENSSL_NO_KTLS + { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + if (s->rlayer.rrlmethod == &ossl_ktls_record_method) { + /* KTLS does not support renegotiation so disallow it */ + SSL_set_options(ssl, SSL_OP_NO_RENEGOTIATION); + } + } +#endif + if (SSL_IS_FIRST_HANDSHAKE(s) && thismethod->set_first_handshake != NULL) + thismethod->set_first_handshake(thisrl, 1); + + if (s->max_pipelines != 0 && thismethod->set_max_pipelines != NULL) + thismethod->set_max_pipelines(thisrl, s->max_pipelines); + + return 1; +} + +int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, + int direction, int level, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, const EVP_MD *md, + const SSL_COMP *comp, const EVP_MD *kdfdigest) +{ + OSSL_PARAM options[5], *opts = options; + OSSL_PARAM settings[6], *set = settings; + const OSSL_RECORD_METHOD **thismethod; + OSSL_RECORD_LAYER **thisrl, *newrl = NULL; + BIO *thisbio; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const OSSL_RECORD_METHOD *meth; + int use_etm, stream_mac = 0, tlstree = 0; + unsigned int maxfrag = (direction == OSSL_RECORD_DIRECTION_WRITE) + ? ssl_get_max_send_fragment(s) + : SSL3_RT_MAX_PLAIN_LENGTH; + int use_early_data = 0; + uint32_t max_early_data; + COMP_METHOD *compm = (comp == NULL) ? NULL : comp->method; + + meth = ssl_select_next_record_layer(s, direction, level); + + if (direction == OSSL_RECORD_DIRECTION_READ) { + thismethod = &s->rlayer.rrlmethod; + thisrl = &s->rlayer.rrl; + thisbio = s->rbio; + } else { + thismethod = &s->rlayer.wrlmethod; + thisrl = &s->rlayer.wrl; + thisbio = s->wbio; + } + + if (meth == NULL) + meth = *thismethod; + + if (!ossl_assert(meth != NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Parameters that *may* be supported by a record layer if passed */ + *opts++ = OSSL_PARAM_construct_uint64(OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS, + &s->options); + *opts++ = OSSL_PARAM_construct_uint32(OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE, + &s->mode); + if (direction == OSSL_RECORD_DIRECTION_READ) { + *opts++ = OSSL_PARAM_construct_size_t(OSSL_LIBSSL_RECORD_LAYER_READ_BUFFER_LEN, + &s->rlayer.default_read_buf_len); + *opts++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD, + &s->rlayer.read_ahead); + } else { + *opts++ = OSSL_PARAM_construct_size_t(OSSL_LIBSSL_RECORD_LAYER_PARAM_BLOCK_PADDING, + &s->rlayer.block_padding); + } + *opts = OSSL_PARAM_construct_end(); + + /* Parameters that *must* be supported by a record layer if passed */ + if (direction == OSSL_RECORD_DIRECTION_READ) { + use_etm = SSL_READ_ETM(s) ? 1 : 0; + if ((s->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM) != 0) + stream_mac = 1; + + if ((s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE) != 0) + tlstree = 1; + } else { + use_etm = SSL_WRITE_ETM(s) ? 1 : 0; + if ((s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) != 0) + stream_mac = 1; + + if ((s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) != 0) + tlstree = 1; + } + + if (use_etm) + *set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_USE_ETM, + &use_etm); + + if (stream_mac) + *set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_STREAM_MAC, + &stream_mac); + + if (tlstree) + *set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE, + &tlstree); + + /* + * We only need to do this for the read side. The write side should already + * have the correct value due to the ssl_get_max_send_fragment() call above + */ + if (direction == OSSL_RECORD_DIRECTION_READ + && s->session != NULL + && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) + maxfrag = GET_MAX_FRAGMENT_LENGTH(s->session); + + + if (maxfrag != SSL3_RT_MAX_PLAIN_LENGTH) + *set++ = OSSL_PARAM_construct_uint(OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_FRAG_LEN, + &maxfrag); + + /* + * The record layer must check the amount of early data sent or received + * using the early keys. A server also needs to worry about rejected early + * data that might arrive when the handshake keys are in force. + */ + if (s->server && direction == OSSL_RECORD_DIRECTION_READ) { + use_early_data = (level == OSSL_RECORD_PROTECTION_LEVEL_EARLY + || level == OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE); + } else if (!s->server && direction == OSSL_RECORD_DIRECTION_WRITE) { + use_early_data = (level == OSSL_RECORD_PROTECTION_LEVEL_EARLY); + } + if (use_early_data) { + max_early_data = ossl_get_max_early_data(s); + + if (max_early_data != 0) + *set++ = OSSL_PARAM_construct_uint32(OSSL_LIBSSL_RECORD_LAYER_PARAM_MAX_EARLY_DATA, + &max_early_data); + } + + *set = OSSL_PARAM_construct_end(); + + for (;;) { + int rlret; + BIO *prev = NULL; + BIO *next = NULL; + unsigned int epoch = 0; + OSSL_DISPATCH rlayer_dispatch_tmp[OSSL_NELEM(rlayer_dispatch)]; + size_t i, j; + + if (direction == OSSL_RECORD_DIRECTION_READ) { + prev = s->rlayer.rrlnext; + if (SSL_CONNECTION_IS_DTLS(s) + && level != OSSL_RECORD_PROTECTION_LEVEL_NONE) + epoch = DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer) + 1; /* new epoch */ + +#ifndef OPENSSL_NO_DGRAM + if (SSL_CONNECTION_IS_DTLS(s)) + next = BIO_new(BIO_s_dgram_mem()); + else +#endif + next = BIO_new(BIO_s_mem()); + + if (next == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + s->rlayer.rrlnext = next; + } else { + if (SSL_CONNECTION_IS_DTLS(s) + && level != OSSL_RECORD_PROTECTION_LEVEL_NONE) + epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) + 1; /* new epoch */ + } + + /* + * Create a copy of the dispatch array, missing out wrappers for + * callbacks that we don't need. + */ + for (i = 0, j = 0; i < OSSL_NELEM(rlayer_dispatch); i++) { + switch (rlayer_dispatch[i].function_id) { + case OSSL_FUNC_RLAYER_MSG_CALLBACK: + if (s->msg_callback == NULL) + continue; + break; + case OSSL_FUNC_RLAYER_PADDING: + if (s->rlayer.record_padding_cb == NULL) + continue; + break; + default: + break; + } + rlayer_dispatch_tmp[j++] = rlayer_dispatch[i]; + } + + rlret = meth->new_record_layer(sctx->libctx, sctx->propq, version, + s->server, direction, level, epoch, + secret, secretlen, key, keylen, iv, + ivlen, mackey, mackeylen, ciph, taglen, + mactype, md, compm, kdfdigest, prev, + thisbio, next, NULL, NULL, settings, + options, rlayer_dispatch_tmp, s, + s->rlayer.rlarg, &newrl); + BIO_free(prev); + switch (rlret) { + case OSSL_RECORD_RETURN_FATAL: + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_RECORD_LAYER_FAILURE); + return 0; + + case OSSL_RECORD_RETURN_NON_FATAL_ERR: + if (*thismethod != meth && *thismethod != NULL) { + /* + * We tried a new record layer method, but it didn't work out, + * so we fallback to the original method and try again + */ + meth = *thismethod; + continue; + } + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_RECORD_LAYER); + return 0; + + case OSSL_RECORD_RETURN_SUCCESS: + break; + + default: + /* Should not happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + break; + } + + /* + * Free the old record layer if we have one except in the case of DTLS when + * writing and there are still buffered sent messages in our queue. In that + * case the record layer is still referenced by those buffered messages for + * potential retransmit. Only when those buffered messages get freed do we + * free the record layer object (see dtls1_hm_fragment_free) + */ + if (!SSL_CONNECTION_IS_DTLS(s) + || direction == OSSL_RECORD_DIRECTION_READ + || pqueue_peek(s->d1->sent_messages) == NULL) { + if (*thismethod != NULL && !(*thismethod)->free(*thisrl)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + *thisrl = newrl; + *thismethod = meth; + + return ssl_post_record_layer_select(s, direction); +} + +int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers) +{ + if (!ossl_assert(s->rlayer.rrlmethod != NULL) + || !ossl_assert(s->rlayer.wrlmethod != NULL)) + return 0; + s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, s->version); + s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, s->version); + + return 1; } diff --git a/ssl/record/record.h b/ssl/record/record.h index 234656bf93..6fb579fe19 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +#include +#include "internal/recordmethod.h" + /***************************************************************************** * * * These structures should be considered PRIVATE to the record layer. No * @@ -14,108 +17,52 @@ * * *****************************************************************************/ -typedef struct ssl3_buffer_st { - /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ - unsigned char *buf; - /* default buffer size (or 0 if no default set) */ - size_t default_len; - /* buffer size */ - size_t len; - /* where to 'copy from' */ - size_t offset; - /* how many bytes left */ - size_t left; - /* 'buf' is from application for KTLS */ - int app_buffer; -} SSL3_BUFFER; - #define SEQ_NUM_SIZE 8 -typedef struct ssl3_record_st { - /* Record layer version */ - /* r */ - int rec_version; - /* type of record */ - /* r */ - int type; - /* How many bytes available */ - /* rw */ - size_t length; +typedef struct tls_record_st { + void *rechandle; + int version; + uint8_t type; + /* The data buffer containing bytes from the record */ + const unsigned char *data; /* - * How many bytes were available before padding was removed? This is used - * to implement the MAC check in constant time for CBC records. + * Buffer that we allocated to store data. If non NULL always the same as + * data (but non-const) */ - /* rw */ - size_t orig_len; - /* read/write offset into 'buf' */ - /* r */ + unsigned char *allocdata; + /* Number of remaining to be read in the data buffer */ + size_t length; + /* Offset into the data buffer where to start reading */ size_t off; - /* pointer to the record data */ - /* rw */ - unsigned char *data; - /* where the decode bytes are */ - /* rw */ - unsigned char *input; - /* only used with decompression - malloc()ed */ - /* r */ - unsigned char *comp; - /* Whether the data from this record has already been read or not */ - /* r */ - unsigned int read; - /* epoch number, needed by DTLS1 */ - /* r */ - unsigned long epoch; - /* sequence number, needed by DTLS1 */ - /* r */ + /* epoch number. DTLS only */ + uint16_t epoch; + /* sequence number. DTLS only */ unsigned char seq_num[SEQ_NUM_SIZE]; -} SSL3_RECORD; - -typedef struct dtls1_bitmap_st { - /* Track 32 packets on 32-bit systems and 64 - on 64-bit systems */ - unsigned long map; - /* Max record number seen so far, 64-bit value in big-endian encoding */ - unsigned char max_seq_num[SEQ_NUM_SIZE]; -} DTLS1_BITMAP; +#ifndef OPENSSL_NO_SCTP + struct bio_dgram_sctp_rcvinfo recordinfo; +#endif +} TLS_RECORD; typedef struct record_pqueue_st { - unsigned short epoch; + uint16_t epoch; struct pqueue_st *q; } record_pqueue; -typedef struct dtls1_record_data_st { - unsigned char *packet; - size_t packet_length; - SSL3_BUFFER rbuf; - SSL3_RECORD rrec; -#ifndef OPENSSL_NO_SCTP - struct bio_dgram_sctp_rcvinfo recordinfo; -#endif -} DTLS1_RECORD_DATA; - typedef struct dtls_record_layer_st { /* * The current data and handshake epoch. This is initially * undefined, and starts at zero once the initial handshake is * completed */ - unsigned short r_epoch; - unsigned short w_epoch; - /* records being received in the current epoch */ - DTLS1_BITMAP bitmap; - /* renegotiation starts a new set of sequence numbers */ - DTLS1_BITMAP next_bitmap; - /* Received handshake records (processed and unprocessed) */ - record_pqueue unprocessed_rcds; - record_pqueue processed_rcds; + uint16_t r_epoch; + uint16_t w_epoch; + /* * Buffered application records. Only for records between CCS and * Finished to prevent either protocol violation or unnecessary message * loss. */ record_pqueue buffered_app_data; - /* save last and current sequence numbers for retransmissions */ - unsigned char last_write_sequence[8]; - unsigned char curr_write_sequence[8]; } DTLS_RECORD_LAYER; /***************************************************************************** @@ -127,48 +74,60 @@ typedef struct dtls_record_layer_st { *****************************************************************************/ typedef struct record_layer_st { - /* The parent SSL structure */ - SSL *s; + /* The parent SSL_CONNECTION structure */ + SSL_CONNECTION *s; + + /* Custom record layer: always selected if set */ + const OSSL_RECORD_METHOD *custom_rlmethod; + /* Record layer specific argument */ + void *rlarg; + /* Method to use for the read record layer*/ + const OSSL_RECORD_METHOD *rrlmethod; + /* Method to use for the write record layer*/ + const OSSL_RECORD_METHOD *wrlmethod; + /* The read record layer object itself */ + OSSL_RECORD_LAYER *rrl; + /* The write record layer object itself */ + OSSL_RECORD_LAYER *wrl; + /* BIO to store data destined for the next read record layer epoch */ + BIO *rrlnext; + /* Default read buffer length to be passed to the record layer */ + size_t default_read_buf_len; + /* * Read as many input bytes as possible (for * non-blocking reads) */ int read_ahead; - /* where we are when reading */ - int rstate; - /* How many pipelines can be used to read data */ - size_t numrpipes; - /* How many pipelines can be used to write data */ - size_t numwpipes; - /* read IO goes into here */ - SSL3_BUFFER rbuf; - /* write IO goes into here */ - SSL3_BUFFER wbuf[SSL_MAX_PIPELINES]; - /* each decoded record goes in here */ - SSL3_RECORD rrec[SSL_MAX_PIPELINES]; - /* used internally to point at a raw packet */ - unsigned char *packet; - size_t packet_length; + /* number of bytes sent so far */ size_t wnum; unsigned char handshake_fragment[4]; size_t handshake_fragment_len; - /* The number of consecutive empty records we have received */ - size_t empty_record_count; /* partial write - check the numbers match */ /* number bytes written */ size_t wpend_tot; - int wpend_type; + uint8_t wpend_type; /* number of bytes submitted */ size_t wpend_ret; const unsigned char *wpend_buf; - unsigned char read_sequence[SEQ_NUM_SIZE]; - unsigned char write_sequence[SEQ_NUM_SIZE]; - /* Set to true if this is the first record in a connection */ - unsigned int is_first_record; + /* Count of the number of consecutive warning alerts received */ unsigned int alert_count; DTLS_RECORD_LAYER *d; + + /* TLS1.3 padding callback */ + size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg); + void *record_padding_arg; + size_t block_padding; + + /* How many records we have read from the record layer */ + size_t num_recs; + /* The next record from the record layer that we need to process */ + size_t curr_rec; + /* Record layer data to be processed */ + TLS_RECORD tlsrecs[SSL_MAX_PIPELINES]; + } RECORD_LAYER; /***************************************************************************** @@ -178,70 +137,65 @@ typedef struct record_layer_st { * * *****************************************************************************/ -struct ssl_mac_buf_st { - unsigned char *mac; - int alloced; -}; -typedef struct ssl_mac_buf_st SSL_MAC_BUF; - -#define MIN_SSL2_RECORD_LEN 9 - #define RECORD_LAYER_set_read_ahead(rl, ra) ((rl)->read_ahead = (ra)) #define RECORD_LAYER_get_read_ahead(rl) ((rl)->read_ahead) -#define RECORD_LAYER_get_packet(rl) ((rl)->packet) -#define RECORD_LAYER_get_packet_length(rl) ((rl)->packet_length) -#define RECORD_LAYER_add_packet_length(rl, inc) ((rl)->packet_length += (inc)) #define DTLS_RECORD_LAYER_get_w_epoch(rl) ((rl)->d->w_epoch) -#define DTLS_RECORD_LAYER_get_processed_rcds(rl) \ - ((rl)->d->processed_rcds) -#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \ - ((rl)->d->unprocessed_rcds) -#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf) -#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf) - -void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s); + +void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s); void RECORD_LAYER_clear(RECORD_LAYER *rl); -void RECORD_LAYER_release(RECORD_LAYER *rl); int RECORD_LAYER_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_write_pending(const RECORD_LAYER *rl); -void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl); -void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl); int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl); -size_t RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl); __owur size_t ssl3_pending(const SSL *s); -__owur int ssl3_write_bytes(SSL *s, int type, const void *buf, size_t len, +__owur int ssl3_write_bytes(SSL *s, uint8_t type, const void *buf, size_t len, size_t *written); -int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - size_t *pipelens, size_t numpipes, - int create_empty_fragment, size_t *written); -__owur int ssl3_read_bytes(SSL *s, int type, int *recvd_type, +__owur int ssl3_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, unsigned char *buf, size_t len, int peek, size_t *readbytes); -__owur int ssl3_setup_buffers(SSL *s); -__owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int send, - SSL_MAC_BUF *mac, size_t macsize); -__owur int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); -__owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, - size_t *written); -__owur int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, - SSL_MAC_BUF *mac, size_t macsize); -__owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); -__owur int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send, - SSL_MAC_BUF *mac, size_t macsize); + int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl); void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl); void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl); -void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e); -void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl); -void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq); -__owur int dtls1_read_bytes(SSL *s, int type, int *recvd_type, +__owur int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, unsigned char *buf, size_t len, int peek, size_t *readbytes); -__owur int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, - size_t *written); -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - size_t len, int create_empty_fragment, size_t *written); -void dtls1_reset_seq_numbers(SSL *s, int rw); -int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, - size_t off); +__owur int dtls1_write_bytes(SSL_CONNECTION *s, uint8_t type, const void *buf, + size_t len, size_t *written); +int do_dtls1_write(SSL_CONNECTION *s, uint8_t type, const unsigned char *buf, + size_t len, size_t *written); +void dtls1_increment_epoch(SSL_CONNECTION *s, int rw); +int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length); + +# define HANDLE_RLAYER_READ_RETURN(s, ret) \ + ossl_tls_handle_rlayer_return(s, 0, ret, OPENSSL_FILE, OPENSSL_LINE) + +# define HANDLE_RLAYER_WRITE_RETURN(s, ret) \ + ossl_tls_handle_rlayer_return(s, 1, ret, OPENSSL_FILE, OPENSSL_LINE) + +int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret, + char *file, int line); + +int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, + int direction, int level, + unsigned char *secret, size_t secretlen, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, const EVP_MD *md, + const SSL_COMP *comp, const EVP_MD *kdfdigest); +int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers); + +# define OSSL_FUNC_RLAYER_SKIP_EARLY_DATA 1 +OSSL_CORE_MAKE_FUNC(int, rlayer_skip_early_data, (void *cbarg)) +# define OSSL_FUNC_RLAYER_MSG_CALLBACK 2 +OSSL_CORE_MAKE_FUNC(void, rlayer_msg_callback, (int write_p, int version, + int content_type, + const void *buf, size_t len, + void *cbarg)) +# define OSSL_FUNC_RLAYER_SECURITY 3 +OSSL_CORE_MAKE_FUNC(int, rlayer_security, (void *cbarg, int op, int bits, + int nid, void *other)) +# define OSSL_FUNC_RLAYER_PADDING 4 +OSSL_CORE_MAKE_FUNC(size_t, rlayer_padding, (void *cbarg, int type, size_t len)) diff --git a/ssl/record/record_local.h b/ssl/record/record_local.h index 0a929c696a..7bcbd14f24 100644 --- a/ssl/record/record_local.h +++ b/ssl/record/record_local.h @@ -18,110 +18,4 @@ /* Functions/macros provided by the RECORD_LAYER component */ -#define RECORD_LAYER_get_rrec(rl) ((rl)->rrec) -#define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p)) -#define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0) -#define RECORD_LAYER_get_rstate(rl) ((rl)->rstate) -#define RECORD_LAYER_set_rstate(rl, st) ((rl)->rstate = (st)) -#define RECORD_LAYER_get_read_sequence(rl) ((rl)->read_sequence) -#define RECORD_LAYER_get_write_sequence(rl) ((rl)->write_sequence) -#define RECORD_LAYER_get_numrpipes(rl) ((rl)->numrpipes) -#define RECORD_LAYER_set_numrpipes(rl, n) ((rl)->numrpipes = (n)) -#define RECORD_LAYER_inc_empty_record_count(rl) ((rl)->empty_record_count++) -#define RECORD_LAYER_reset_empty_record_count(rl) \ - ((rl)->empty_record_count = 0) -#define RECORD_LAYER_get_empty_record_count(rl) ((rl)->empty_record_count) -#define RECORD_LAYER_is_first_record(rl) ((rl)->is_first_record) -#define RECORD_LAYER_set_first_record(rl) ((rl)->is_first_record = 1) -#define RECORD_LAYER_clear_first_record(rl) ((rl)->is_first_record = 0) #define DTLS_RECORD_LAYER_get_r_epoch(rl) ((rl)->d->r_epoch) - -__owur int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, - size_t *readbytes); - -DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch); -int dtls1_process_buffered_records(SSL *s); -int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue); -int dtls1_buffer_record(SSL *s, record_pqueue *q, unsigned char *priority); -void ssl3_record_sequence_update(unsigned char *seq); - -/* Functions provided by the DTLS1_BITMAP component */ - -int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); -void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); - -/* Macros/functions provided by the SSL3_BUFFER component */ - -#define SSL3_BUFFER_get_buf(b) ((b)->buf) -#define SSL3_BUFFER_set_buf(b, n) ((b)->buf = (n)) -#define SSL3_BUFFER_get_len(b) ((b)->len) -#define SSL3_BUFFER_set_len(b, l) ((b)->len = (l)) -#define SSL3_BUFFER_get_left(b) ((b)->left) -#define SSL3_BUFFER_set_left(b, l) ((b)->left = (l)) -#define SSL3_BUFFER_sub_left(b, l) ((b)->left -= (l)) -#define SSL3_BUFFER_get_offset(b) ((b)->offset) -#define SSL3_BUFFER_set_offset(b, o) ((b)->offset = (o)) -#define SSL3_BUFFER_add_offset(b, o) ((b)->offset += (o)) -#define SSL3_BUFFER_is_initialised(b) ((b)->buf != NULL) -#define SSL3_BUFFER_set_default_len(b, l) ((b)->default_len = (l)) -#define SSL3_BUFFER_set_app_buffer(b, l) ((b)->app_buffer = (l)) -#define SSL3_BUFFER_is_app_buffer(b) ((b)->app_buffer) - -void SSL3_BUFFER_clear(SSL3_BUFFER *b); -void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n); -void SSL3_BUFFER_release(SSL3_BUFFER *b); -__owur int ssl3_setup_read_buffer(SSL *s); -__owur int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len); -int ssl3_release_read_buffer(SSL *s); -int ssl3_release_write_buffer(SSL *s); - -/* Macros/functions provided by the SSL3_RECORD component */ - -#define SSL3_RECORD_get_type(r) ((r)->type) -#define SSL3_RECORD_set_type(r, t) ((r)->type = (t)) -#define SSL3_RECORD_set_rec_version(r, v) ((r)->rec_version = (v)) -#define SSL3_RECORD_get_length(r) ((r)->length) -#define SSL3_RECORD_set_length(r, l) ((r)->length = (l)) -#define SSL3_RECORD_add_length(r, l) ((r)->length += (l)) -#define SSL3_RECORD_sub_length(r, l) ((r)->length -= (l)) -#define SSL3_RECORD_get_data(r) ((r)->data) -#define SSL3_RECORD_set_data(r, d) ((r)->data = (d)) -#define SSL3_RECORD_get_input(r) ((r)->input) -#define SSL3_RECORD_set_input(r, i) ((r)->input = (i)) -#define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data) -#define SSL3_RECORD_reset_data(r) ((r)->data = (r)->input) -#define SSL3_RECORD_get_seq_num(r) ((r)->seq_num) -#define SSL3_RECORD_get_off(r) ((r)->off) -#define SSL3_RECORD_set_off(r, o) ((r)->off = (o)) -#define SSL3_RECORD_add_off(r, o) ((r)->off += (o)) -#define SSL3_RECORD_get_epoch(r) ((r)->epoch) -#define SSL3_RECORD_is_sslv2_record(r) \ - ((r)->rec_version == SSL2_VERSION) -#define SSL3_RECORD_is_read(r) ((r)->read) -#define SSL3_RECORD_set_read(r) ((r)->read = 1) - -void SSL3_RECORD_clear(SSL3_RECORD *r, size_t); -void SSL3_RECORD_release(SSL3_RECORD *r, size_t num_recs); -void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num); -int ssl3_get_record(SSL *s); -__owur int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr); -__owur int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr); -__owur int ssl3_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - OSSL_LIB_CTX *libctx); -__owur int tls1_cbc_remove_padding_and_mac(size_t *reclen, - size_t origreclen, - unsigned char *recdata, - unsigned char **mac, - int *alloced, - size_t block_size, size_t mac_size, - int aead, - OSSL_LIB_CTX *libctx); -int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); -__owur int dtls1_get_record(SSL *s); -int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send); diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c deleted file mode 100644 index 97b0c26ced..0000000000 --- a/ssl/record/ssl3_buffer.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "../ssl_local.h" -#include "record_local.h" - -void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n) -{ - if (d != NULL) - memcpy(b->buf, d, n); - b->left = n; - b->offset = 0; -} - -/* - * Clear the contents of an SSL3_BUFFER but retain any memory allocated. Also - * retains the default_len setting - */ -void SSL3_BUFFER_clear(SSL3_BUFFER *b) -{ - b->offset = 0; - b->left = 0; -} - -void SSL3_BUFFER_release(SSL3_BUFFER *b) -{ - OPENSSL_free(b->buf); - b->buf = NULL; -} - -int ssl3_setup_read_buffer(SSL *s) -{ - unsigned char *p; - size_t len, align = 0, headerlen; - SSL3_BUFFER *b; - - b = RECORD_LAYER_get_rbuf(&s->rlayer); - - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (b->buf == NULL) { - len = SSL3_RT_MAX_PLAIN_LENGTH - + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; -#ifndef OPENSSL_NO_COMP - if (ssl_allow_compression(s)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - - /* Ensure our buffer is large enough to support all our pipelines */ - if (s->max_pipelines > 1) - len *= s->max_pipelines; - - if (b->default_len > len) - len = b->default_len; - if ((p = OPENSSL_malloc(len)) == NULL) { - /* - * We've got a malloc failure, and we're still initialising buffers. - * We assume we're so doomed that we won't even be able to send an - * alert. - */ - SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE); - return 0; - } - b->buf = p; - b->len = len; - } - - return 1; -} - -int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) -{ - unsigned char *p; - size_t align = 0, headerlen; - SSL3_BUFFER *wb; - size_t currpipe; - - s->rlayer.numwpipes = numwpipes; - - if (len == 0) { - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH + 1; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = SSL3_ALIGN_PAYLOAD - 1; -#endif - - len = ssl_get_max_send_fragment(s) - + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align - + SSL_RT_MAX_CIPHER_BLOCK_SIZE /* Explicit IV allowance */; -#ifndef OPENSSL_NO_COMP - if (ssl_allow_compression(s)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - /* - * We don't need to add an allowance for eivlen here since empty - * fragments only occur when we don't have an explicit IV - */ - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) - len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; - } - - wb = RECORD_LAYER_get_wbuf(&s->rlayer); - for (currpipe = 0; currpipe < numwpipes; currpipe++) { - SSL3_BUFFER *thiswb = &wb[currpipe]; - - if (thiswb->len != len) { - OPENSSL_free(thiswb->buf); - thiswb->buf = NULL; /* force reallocation */ - } - - if (thiswb->buf == NULL) { - if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio)) { - p = OPENSSL_malloc(len); - if (p == NULL) { - s->rlayer.numwpipes = currpipe; - /* - * We've got a malloc failure, and we're still initialising - * buffers. We assume we're so doomed that we won't even be able - * to send an alert. - */ - SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE); - return 0; - } - } else { - p = NULL; - } - memset(thiswb, 0, sizeof(SSL3_BUFFER)); - thiswb->buf = p; - thiswb->len = len; - } - } - - return 1; -} - -int ssl3_setup_buffers(SSL *s) -{ - if (!ssl3_setup_read_buffer(s)) { - /* SSLfatal() already called */ - return 0; - } - if (!ssl3_setup_write_buffer(s, 1, 0)) { - /* SSLfatal() already called */ - return 0; - } - return 1; -} - -int ssl3_release_write_buffer(SSL *s) -{ - SSL3_BUFFER *wb; - size_t pipes; - - pipes = s->rlayer.numwpipes; - while (pipes > 0) { - wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1]; - - if (SSL3_BUFFER_is_app_buffer(wb)) - SSL3_BUFFER_set_app_buffer(wb, 0); - else - OPENSSL_free(wb->buf); - wb->buf = NULL; - pipes--; - } - s->rlayer.numwpipes = 0; - return 1; -} - -int ssl3_release_read_buffer(SSL *s) -{ - SSL3_BUFFER *b; - - b = RECORD_LAYER_get_rbuf(&s->rlayer); - if (s->options & SSL_OP_CLEANSE_PLAINTEXT) - OPENSSL_cleanse(b->buf, b->len); - OPENSSL_free(b->buf); - b->buf = NULL; - return 1; -} diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c deleted file mode 100644 index 3c0b1323a4..0000000000 --- a/ssl/record/ssl3_record.c +++ /dev/null @@ -1,1933 +0,0 @@ -/* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "../ssl_local.h" -#include -#include -#include -#include "record_local.h" -#include "internal/cryptlib.h" - -static const unsigned char ssl3_pad_1[48] = { - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 -}; - -static const unsigned char ssl3_pad_2[48] = { - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c -}; - -/* - * Clear the contents of an SSL3_RECORD but retain any memory allocated - */ -void SSL3_RECORD_clear(SSL3_RECORD *r, size_t num_recs) -{ - unsigned char *comp; - size_t i; - - for (i = 0; i < num_recs; i++) { - comp = r[i].comp; - - memset(&r[i], 0, sizeof(*r)); - r[i].comp = comp; - } -} - -void SSL3_RECORD_release(SSL3_RECORD *r, size_t num_recs) -{ - size_t i; - - for (i = 0; i < num_recs; i++) { - OPENSSL_free(r[i].comp); - r[i].comp = NULL; - } -} - -void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num) -{ - memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE); -} - -/* - * Peeks ahead into "read_ahead" data to see if we have a whole record waiting - * for us in the buffer. - */ -static int ssl3_record_app_data_waiting(SSL *s) -{ - SSL3_BUFFER *rbuf; - size_t left, len; - unsigned char *p; - - rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); - - p = SSL3_BUFFER_get_buf(rbuf); - if (p == NULL) - return 0; - - left = SSL3_BUFFER_get_left(rbuf); - - if (left < SSL3_RT_HEADER_LENGTH) - return 0; - - p += SSL3_BUFFER_get_offset(rbuf); - - /* - * We only check the type and record length, we will sanity check version - * etc later - */ - if (*p != SSL3_RT_APPLICATION_DATA) - return 0; - - p += 3; - n2s(p, len); - - if (left < SSL3_RT_HEADER_LENGTH + len) - return 0; - - return 1; -} - -int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send) -{ - uint32_t max_early_data; - SSL_SESSION *sess = s->session; - - /* - * If we are a client then we always use the max_early_data from the - * session/psksession. Otherwise we go with the lowest out of the max early - * data set in the session and the configured max_early_data. - */ - if (!s->server && sess->ext.max_early_data == 0) { - if (!ossl_assert(s->psksession != NULL - && s->psksession->ext.max_early_data > 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - sess = s->psksession; - } - - if (!s->server) - max_early_data = sess->ext.max_early_data; - else if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED) - max_early_data = s->recv_max_early_data; - else - max_early_data = s->recv_max_early_data < sess->ext.max_early_data - ? s->recv_max_early_data : sess->ext.max_early_data; - - if (max_early_data == 0) { - SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, - SSL_R_TOO_MUCH_EARLY_DATA); - return 0; - } - - /* If we are dealing with ciphertext we need to allow for the overhead */ - max_early_data += overhead; - - if (s->early_data_count + length > max_early_data) { - SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, - SSL_R_TOO_MUCH_EARLY_DATA); - return 0; - } - s->early_data_count += length; - - return 1; -} - -/* - * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that - * will be processed per call to ssl3_get_record. Without this limit an - * attacker could send empty records at a faster rate than we can process and - * cause ssl3_get_record to loop forever. - */ -#define MAX_EMPTY_RECORDS 32 - -#define SSL2_RT_HEADER_LENGTH 2 -/*- - * Call this to get new input records. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, |numrpipes| records have been decoded. For each record 'i': - * rr[i].type - is the type of record - * rr[i].data, - data - * rr[i].length, - number of bytes - * Multiple records will only be returned if the record types are all - * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <= - * |max_pipelines| - */ -/* used only by ssl3_read_bytes */ -int ssl3_get_record(SSL *s) -{ - int enc_err, rret; - int i; - size_t more, n; - SSL3_RECORD *rr, *thisrr; - SSL3_BUFFER *rbuf; - SSL_SESSION *sess; - unsigned char *p; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int version; - size_t mac_size = 0; - int imac_size; - size_t num_recs = 0, max_recs, j; - PACKET pkt, sslv2pkt; - int is_ktls_left; - SSL_MAC_BUF *macbufs = NULL; - int ret = -1; - - rr = RECORD_LAYER_get_rrec(&s->rlayer); - rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); - is_ktls_left = (SSL3_BUFFER_get_left(rbuf) > 0); - max_recs = s->max_pipelines; - if (max_recs == 0) - max_recs = 1; - sess = s->session; - - do { - thisrr = &rr[num_recs]; - - /* check if we have the header */ - if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) || - (RECORD_LAYER_get_packet_length(&s->rlayer) - < SSL3_RT_HEADER_LENGTH)) { - size_t sslv2len; - unsigned int type; - - rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, - SSL3_BUFFER_get_len(rbuf), 0, - num_recs == 0 ? 1 : 0, &n); - if (rret <= 0) { -#ifndef OPENSSL_NO_KTLS - if (!BIO_get_ktls_recv(s->rbio) || rret == 0) - return rret; /* error or non-blocking */ - switch (errno) { - case EBADMSG: - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - break; - case EMSGSIZE: - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_PACKET_LENGTH_TOO_LONG); - break; - case EINVAL: - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_R_WRONG_VERSION_NUMBER); - break; - default: - break; - } -#endif - return rret; - } - RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); - - p = RECORD_LAYER_get_packet(&s->rlayer); - if (!PACKET_buf_init(&pkt, RECORD_LAYER_get_packet(&s->rlayer), - RECORD_LAYER_get_packet_length(&s->rlayer))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - sslv2pkt = pkt; - if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len) - || !PACKET_get_1(&sslv2pkt, &type)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - /* - * The first record received by the server may be a V2ClientHello. - */ - if (s->server && RECORD_LAYER_is_first_record(&s->rlayer) - && (sslv2len & 0x8000) != 0 - && (type == SSL2_MT_CLIENT_HELLO)) { - /* - * SSLv2 style record - * - * |num_recs| here will actually always be 0 because - * |num_recs > 0| only ever occurs when we are processing - * multiple app data records - which we know isn't the case here - * because it is an SSLv2ClientHello. We keep it using - * |num_recs| for the sake of consistency - */ - thisrr->type = SSL3_RT_HANDSHAKE; - thisrr->rec_version = SSL2_VERSION; - - thisrr->length = sslv2len & 0x7fff; - - if (thisrr->length > SSL3_BUFFER_get_len(rbuf) - - SSL2_RT_HEADER_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_PACKET_LENGTH_TOO_LONG); - return -1; - } - - if (thisrr->length < MIN_SSL2_RECORD_LEN) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); - return -1; - } - } else { - /* SSLv3+ style record */ - - /* Pull apart the header into the SSL3_RECORD */ - if (!PACKET_get_1(&pkt, &type) - || !PACKET_get_net_2(&pkt, &version) - || !PACKET_get_net_2_len(&pkt, &thisrr->length)) { - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } - thisrr->type = type; - thisrr->rec_version = version; - - if (s->msg_callback) - s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - - /* - * Lets check version. In TLSv1.3 we only check this field - * when encryption is occurring (see later check). For the - * ServerHello after an HRR we haven't actually selected TLSv1.3 - * yet, but we still treat it as TLSv1.3, so we must check for - * that explicitly - */ - if (!s->first_packet && !SSL_IS_TLS13(s) - && s->hello_retry_request != SSL_HRR_PENDING - && version != (unsigned int)s->version) { - if ((s->version & 0xFF00) == (version & 0xFF00) - && !s->enc_write_ctx && !s->write_hash) { - if (thisrr->type == SSL3_RT_ALERT) { - /* - * The record is using an incorrect version number, - * but what we've got appears to be an alert. We - * haven't read the body yet to check whether its a - * fatal or not - but chances are it is. We probably - * shouldn't send a fatal alert back. We'll just - * end. - */ - SSLfatal(s, SSL_AD_NO_ALERT, - SSL_R_WRONG_VERSION_NUMBER); - return -1; - } - /* - * Send back error using their minor version number :-) - */ - s->version = (unsigned short)version; - } - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_R_WRONG_VERSION_NUMBER); - return -1; - } - - if ((version >> 8) != SSL3_VERSION_MAJOR) { - if (RECORD_LAYER_is_first_record(&s->rlayer)) { - /* Go back to start of packet, look at the five bytes - * that we have. */ - p = RECORD_LAYER_get_packet(&s->rlayer); - if (strncmp((char *)p, "GET ", 4) == 0 || - strncmp((char *)p, "POST ", 5) == 0 || - strncmp((char *)p, "HEAD ", 5) == 0 || - strncmp((char *)p, "PUT ", 4) == 0) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST); - return -1; - } else if (strncmp((char *)p, "CONNE", 5) == 0) { - SSLfatal(s, SSL_AD_NO_ALERT, - SSL_R_HTTPS_PROXY_REQUEST); - return -1; - } - - /* Doesn't look like TLS - don't send an alert */ - SSLfatal(s, SSL_AD_NO_ALERT, - SSL_R_WRONG_VERSION_NUMBER); - return -1; - } else { - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_R_WRONG_VERSION_NUMBER); - return -1; - } - } - - if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) { - if (thisrr->type != SSL3_RT_APPLICATION_DATA - && (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC - || !SSL_IS_FIRST_HANDSHAKE(s)) - && (thisrr->type != SSL3_RT_ALERT - || s->statem.enc_read_state - != ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_R_BAD_RECORD_TYPE); - return -1; - } - if (thisrr->rec_version != TLS1_2_VERSION) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_R_WRONG_VERSION_NUMBER); - return -1; - } - } - - if (thisrr->length > - SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_PACKET_LENGTH_TOO_LONG); - return -1; - } - } - - /* now s->rlayer.rstate == SSL_ST_READ_BODY */ - } - - if (SSL_IS_TLS13(s)) { - if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - return -1; - } - } else { - size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH; - -#ifndef OPENSSL_NO_COMP - /* - * If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH - * does not include the compression overhead anyway. - */ - if (s->expand == NULL) - len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - - /* KTLS may use all of the buffer */ - if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left) - len = SSL3_BUFFER_get_left(rbuf); - - if (thisrr->length > len) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - return -1; - } - } - - /* - * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data. - * Calculate how much more data we need to read for the rest of the - * record - */ - if (thisrr->rec_version == SSL2_VERSION) { - more = thisrr->length + SSL2_RT_HEADER_LENGTH - - SSL3_RT_HEADER_LENGTH; - } else { - more = thisrr->length; - } - - if (more > 0) { - /* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */ - - rret = ssl3_read_n(s, more, more, 1, 0, &n); - if (rret <= 0) - return rret; /* error or non-blocking io */ - } - - /* set state for later operations */ - RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER); - - /* - * At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH - * + thisrr->length, or s->rlayer.packet_length == SSL2_RT_HEADER_LENGTH - * + thisrr->length and we have that many bytes in s->rlayer.packet - */ - if (thisrr->rec_version == SSL2_VERSION) { - thisrr->input = - &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]); - } else { - thisrr->input = - &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]); - } - - /* - * ok, we can now read from 's->rlayer.packet' data into 'thisrr'. - * thisrr->input points at thisrr->length bytes, which need to be copied - * into thisrr->data by either the decryption or by the decompression. - * When the data is 'copied' into the thisrr->data buffer, - * thisrr->input will be updated to point at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] - * thisrr->length bytes of encrypted compressed stuff. - */ - - /* decrypt in place in 'thisrr->input' */ - thisrr->data = thisrr->input; - thisrr->orig_len = thisrr->length; - - /* Mark this record as not read by upper layers yet */ - thisrr->read = 0; - - num_recs++; - - /* we have pulled in a full packet so zero things */ - RECORD_LAYER_reset_packet_length(&s->rlayer); - RECORD_LAYER_clear_first_record(&s->rlayer); - } while (num_recs < max_recs - && thisrr->type == SSL3_RT_APPLICATION_DATA - && SSL_USE_EXPLICIT_IV(s) - && s->enc_read_ctx != NULL - && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx)) - & EVP_CIPH_FLAG_PIPELINE) != 0 - && ssl3_record_app_data_waiting(s)); - - if (num_recs == 1 - && thisrr->type == SSL3_RT_CHANGE_CIPHER_SPEC - && (SSL_IS_TLS13(s) || s->hello_retry_request != SSL_HRR_NONE) - && SSL_IS_FIRST_HANDSHAKE(s)) { - /* - * CCS messages must be exactly 1 byte long, containing the value 0x01 - */ - if (thisrr->length != 1 || thisrr->data[0] != 0x01) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_R_INVALID_CCS_MESSAGE); - return -1; - } - /* - * CCS messages are ignored in TLSv1.3. We treat it like an empty - * handshake record - */ - thisrr->type = SSL3_RT_HANDSHAKE; - RECORD_LAYER_inc_empty_record_count(&s->rlayer); - if (RECORD_LAYER_get_empty_record_count(&s->rlayer) - > MAX_EMPTY_RECORDS) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_R_UNEXPECTED_CCS_MESSAGE); - return -1; - } - thisrr->read = 1; - RECORD_LAYER_set_numrpipes(&s->rlayer, 1); - - return 1; - } - - /* - * KTLS reads full records. If there is any data left, - * then it is from before enabling ktls - */ - if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left) - goto skip_decryption; - - if (s->read_hash != NULL) { - const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash); - - if (tmpmd != NULL) { - imac_size = EVP_MD_get_size(tmpmd); - if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); - return -1; - } - mac_size = (size_t)imac_size; - } - } - - /* - * If in encrypt-then-mac mode calculate mac from encrypted record. All - * the details below are public so no timing details can leak. - */ - if (SSL_READ_ETM(s) && s->read_hash) { - unsigned char *mac; - - for (j = 0; j < num_recs; j++) { - thisrr = &rr[j]; - - if (thisrr->length < mac_size) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); - return -1; - } - thisrr->length -= mac_size; - mac = thisrr->data + thisrr->length; - i = s->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ ); - if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) { - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - return -1; - } - } - /* - * We've handled the mac now - there is no MAC inside the encrypted - * record - */ - mac_size = 0; - } - - if (mac_size > 0) { - macbufs = OPENSSL_zalloc(sizeof(*macbufs) * num_recs); - if (macbufs == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - return -1; - } - } - - ERR_set_mark(); - enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size); - - /*- - * enc_err is: - * 0: if the record is publicly invalid, or an internal error, or AEAD - * decryption failed, or ETM decryption failed. - * 1: Success or MTE decryption failed (MAC will be randomised) - */ - if (enc_err == 0) { - if (ossl_statem_in_error(s)) { - /* SSLfatal() already got called */ - ERR_clear_last_mark(); - goto end; - } - if (num_recs == 1 && ossl_statem_skip_early_data(s)) { - /* - * Valid early_data that we cannot decrypt will fail here. We treat - * it like an empty record. - */ - - /* - * Remove any errors from the stack. Decryption failures are normal - * behaviour. - */ - ERR_pop_to_mark(); - - thisrr = &rr[0]; - - if (!early_data_count_ok(s, thisrr->length, - EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { - /* SSLfatal() already called */ - goto end; - } - - thisrr->length = 0; - thisrr->read = 1; - RECORD_LAYER_set_numrpipes(&s->rlayer, 1); - RECORD_LAYER_reset_read_sequence(&s->rlayer); - ret = 1; - goto end; - } - ERR_clear_last_mark(); - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - goto end; - } else { - ERR_clear_last_mark(); - } - OSSL_TRACE_BEGIN(TLS) { - BIO_printf(trc_out, "dec %lu\n", (unsigned long)rr[0].length); - BIO_dump_indent(trc_out, rr[0].data, rr[0].length, 4); - } OSSL_TRACE_END(TLS); - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) - && (s->enc_read_ctx != NULL) - && (!SSL_READ_ETM(s) && EVP_MD_CTX_get0_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - - for (j = 0; j < num_recs; j++) { - SSL_MAC_BUF *thismb = &macbufs[j]; - thisrr = &rr[j]; - - i = s->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ ); - if (i == 0 || thismb == NULL || thismb->mac == NULL - || CRYPTO_memcmp(md, thismb->mac, (size_t)mac_size) != 0) - enc_err = 0; - if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = 0; - } - } - - if (enc_err == 0) { - if (ossl_statem_in_error(s)) { - /* We already called SSLfatal() */ - goto end; - } - /* - * A separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, we should - * not reveal which kind of error occurred -- this might become - * visible to an attacker (e.g. via a logfile) - */ - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - goto end; - } - - skip_decryption: - - for (j = 0; j < num_recs; j++) { - thisrr = &rr[j]; - - /* thisrr->length is now just compressed */ - if (s->expand != NULL) { - if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto end; - } - if (!ssl3_do_uncompress(s, thisrr)) { - SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, - SSL_R_BAD_DECOMPRESSION); - goto end; - } - } - - if (SSL_IS_TLS13(s) - && s->enc_read_ctx != NULL - && thisrr->type != SSL3_RT_ALERT) { - size_t end; - - if (thisrr->length == 0 - || thisrr->type != SSL3_RT_APPLICATION_DATA) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); - goto end; - } - - /* Strip trailing padding */ - for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0; - end--) - continue; - - thisrr->length = end; - thisrr->type = thisrr->data[end]; - if (thisrr->type != SSL3_RT_APPLICATION_DATA - && thisrr->type != SSL3_RT_ALERT - && thisrr->type != SSL3_RT_HANDSHAKE) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); - goto end; - } - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE, - &thisrr->data[end], 1, s, s->msg_callback_arg); - } - - /* - * TLSv1.3 alert and handshake records are required to be non-zero in - * length. - */ - if (SSL_IS_TLS13(s) - && (thisrr->type == SSL3_RT_HANDSHAKE - || thisrr->type == SSL3_RT_ALERT) - && thisrr->length == 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH); - goto end; - } - - /* - * Usually thisrr->length is the length of a single record, but when - * KTLS handles the decryption, thisrr->length may be larger than - * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced - * multiple records. - * Therefore we have to rely on KTLS to check the plaintext length - * limit in the kernel. - */ - if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH - && (!BIO_get_ktls_recv(s->rbio) || is_ktls_left)) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); - goto end; - } - - /* - * Check if the received packet overflows the current - * Max Fragment Length setting. - * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive. - */ - if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) - && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); - goto end; - } - - thisrr->off = 0; - /*- - * So at this point the following is true - * thisrr->type is the type of record - * thisrr->length == number of bytes in record - * thisrr->off == offset to first valid byte - * thisrr->data == where to take bytes from, increment after use :-). - */ - - /* just read a 0 length packet */ - if (thisrr->length == 0) { - RECORD_LAYER_inc_empty_record_count(&s->rlayer); - if (RECORD_LAYER_get_empty_record_count(&s->rlayer) - > MAX_EMPTY_RECORDS) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_RECORD_TOO_SMALL); - goto end; - } - } else { - RECORD_LAYER_reset_empty_record_count(&s->rlayer); - } - } - - if (s->early_data_state == SSL_EARLY_DATA_READING) { - thisrr = &rr[0]; - if (thisrr->type == SSL3_RT_APPLICATION_DATA - && !early_data_count_ok(s, thisrr->length, 0, 0)) { - /* SSLfatal already called */ - goto end; - } - } - - RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs); - ret = 1; - end: - if (macbufs != NULL) { - for (j = 0; j < num_recs; j++) { - if (macbufs[j].alloced) - OPENSSL_free(macbufs[j].mac); - } - OPENSSL_free(macbufs); - } - return ret; -} - -int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr) -{ -#ifndef OPENSSL_NO_COMP - int i; - - if (rr->comp == NULL) { - rr->comp = (unsigned char *) - OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); - } - if (rr->comp == NULL) - return 0; - - i = COMP_expand_block(ssl->expand, rr->comp, - SSL3_RT_MAX_PLAIN_LENGTH, rr->data, (int)rr->length); - if (i < 0) - return 0; - else - rr->length = i; - rr->data = rr->comp; -#endif - return 1; -} - -int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr) -{ -#ifndef OPENSSL_NO_COMP - int i; - - i = COMP_compress_block(ssl->compress, wr->data, - (int)(wr->length + SSL3_RT_MAX_COMPRESSED_OVERHEAD), - wr->input, (int)wr->length); - if (i < 0) - return 0; - else - wr->length = i; - - wr->input = wr->data; -#endif - return 1; -} - -/*- - * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|. Calls SSLfatal on - * internal error, but not otherwise. It is the responsibility of the caller to - * report a bad_record_mac - * - * Returns: - * 0: if the record is publicly invalid, or an internal error - * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) - */ -int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending, - SSL_MAC_BUF *mac, size_t macsize) -{ - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - size_t l, i; - size_t bs; - const EVP_CIPHER *enc; - - rec = inrecs; - /* - * We shouldn't ever be called with more than one record in the SSLv3 case - */ - if (n_recs != 1) - return 0; - if (sending) { - ds = s->enc_write_ctx; - if (s->enc_write_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx); - } else { - ds = s->enc_read_ctx; - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx); - } - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - } else { - int provided = (EVP_CIPHER_get0_provider(enc) != NULL); - - l = rec->length; - bs = EVP_CIPHER_CTX_get_block_size(ds); - - /* COMPRESS */ - - if ((bs != 1) && sending && !provided) { - /* - * We only do this for legacy ciphers. Provided ciphers add the - * padding on the provider side. - */ - i = bs - (l % bs); - - /* we need to add 'i-1' padding bytes */ - l += i; - /* - * the last of these zero bytes will be overwritten with the - * padding length. - */ - memset(&rec->input[rec->length], 0, i); - rec->length += i; - rec->input[l - 1] = (unsigned char)(i - 1); - } - - if (!sending) { - if (l == 0 || l % bs != 0) { - /* Publicly invalid */ - return 0; - } - /* otherwise, rec->length >= bs */ - } - - if (EVP_CIPHER_get0_provider(enc) != NULL) { - int outlen; - - if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input, - (unsigned int)l)) - return 0; - rec->length = outlen; - - if (!sending && mac != NULL) { - /* Now get a pointer to the MAC */ - OSSL_PARAM params[2], *p = params; - - /* Get the MAC */ - mac->alloced = 0; - - *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, - (void **)&mac->mac, - macsize); - *p = OSSL_PARAM_construct_end(); - - if (!EVP_CIPHER_CTX_get_params(ds, params)) { - /* Shouldn't normally happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - } else { - if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) { - /* Shouldn't happen */ - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!sending) - return ssl3_cbc_remove_padding_and_mac(&rec->length, - rec->orig_len, - rec->data, - (mac != NULL) ? &mac->mac : NULL, - (mac != NULL) ? &mac->alloced : NULL, - bs, - macsize, - s->ctx->libctx); - } - } - return 1; -} - -#define MAX_PADDING 256 -/*- - * tls1_enc encrypts/decrypts |n_recs| in |recs|. Calls SSLfatal on internal - * error, but not otherwise. It is the responsibility of the caller to report - * a bad_record_mac - if appropriate (DTLS just drops the record). - * - * Returns: - * 0: if the record is publicly invalid, or an internal error, or AEAD - * decryption failed, or Encrypt-then-mac decryption failed. - * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) - */ -int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, - SSL_MAC_BUF *macs, size_t macsize) -{ - EVP_CIPHER_CTX *ds; - size_t reclen[SSL_MAX_PIPELINES]; - unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN]; - unsigned char *data[SSL_MAX_PIPELINES]; - int i, pad = 0, tmpr; - size_t bs, ctr, padnum, loop; - unsigned char padval; - const EVP_CIPHER *enc; - int tlstree_enc = sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) - : (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); - - if (n_recs == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (sending) { - if (EVP_MD_CTX_get0_md(s->write_hash)) { - int n = EVP_MD_CTX_get_size(s->write_hash); - if (!ossl_assert(n >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - ds = s->enc_write_ctx; - if (s->enc_write_ctx == NULL) - enc = NULL; - else { - int ivlen; - - enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx); - /* For TLSv1.1 and later explicit IV */ - if (SSL_USE_EXPLICIT_IV(s) - && EVP_CIPHER_get_mode(enc) == EVP_CIPH_CBC_MODE) - ivlen = EVP_CIPHER_get_iv_length(enc); - else - ivlen = 0; - if (ivlen > 1) { - for (ctr = 0; ctr < n_recs; ctr++) { - if (recs[ctr].data != recs[ctr].input) { - /* - * we can't write into the input stream: Can this ever - * happen?? (steve) - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } else if (RAND_bytes_ex(s->ctx->libctx, recs[ctr].input, - ivlen, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - } - } - } else { - if (EVP_MD_CTX_get0_md(s->read_hash)) { - int n = EVP_MD_CTX_get_size(s->read_hash); - if (!ossl_assert(n >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - ds = s->enc_read_ctx; - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx); - } - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - for (ctr = 0; ctr < n_recs; ctr++) { - memmove(recs[ctr].data, recs[ctr].input, recs[ctr].length); - recs[ctr].input = recs[ctr].data; - } - } else { - int provided = (EVP_CIPHER_get0_provider(enc) != NULL); - - bs = EVP_CIPHER_get_block_size(EVP_CIPHER_CTX_get0_cipher(ds)); - - if (n_recs > 1) { - if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) - & EVP_CIPH_FLAG_PIPELINE) == 0) { - /* - * We shouldn't have been called with pipeline data if the - * cipher doesn't support pipelining - */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); - return 0; - } - } - for (ctr = 0; ctr < n_recs; ctr++) { - reclen[ctr] = recs[ctr].length; - - if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) - & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { - unsigned char *seq; - - seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) - : RECORD_LAYER_get_read_sequence(&s->rlayer); - - if (SSL_IS_DTLS(s)) { - /* DTLS does not support pipelining */ - unsigned char dtlsseq[8], *p = dtlsseq; - - s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) : - DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p); - memcpy(p, &seq[2], 6); - memcpy(buf[ctr], dtlsseq, 8); - } else { - memcpy(buf[ctr], seq, 8); - for (i = 7; i >= 0; i--) { /* increment */ - ++seq[i]; - if (seq[i] != 0) - break; - } - } - - buf[ctr][8] = recs[ctr].type; - buf[ctr][9] = (unsigned char)(s->version >> 8); - buf[ctr][10] = (unsigned char)(s->version); - buf[ctr][11] = (unsigned char)(recs[ctr].length >> 8); - buf[ctr][12] = (unsigned char)(recs[ctr].length & 0xff); - pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, - EVP_AEAD_TLS1_AAD_LEN, buf[ctr]); - if (pad <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (sending) { - reclen[ctr] += pad; - recs[ctr].length += pad; - } - - } else if ((bs != 1) && sending && !provided) { - /* - * We only do this for legacy ciphers. Provided ciphers add the - * padding on the provider side. - */ - padnum = bs - (reclen[ctr] % bs); - - /* Add weird padding of up to 256 bytes */ - - if (padnum > MAX_PADDING) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - /* we need to add 'padnum' padding bytes of value padval */ - padval = (unsigned char)(padnum - 1); - for (loop = reclen[ctr]; loop < reclen[ctr] + padnum; loop++) - recs[ctr].input[loop] = padval; - reclen[ctr] += padnum; - recs[ctr].length += padnum; - } - - if (!sending) { - if (reclen[ctr] == 0 || reclen[ctr] % bs != 0) { - /* Publicly invalid */ - return 0; - } - } - } - if (n_recs > 1) { - /* Set the output buffers */ - for (ctr = 0; ctr < n_recs; ctr++) { - data[ctr] = recs[ctr].data; - } - if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS, - (int)n_recs, data) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); - return 0; - } - /* Set the input buffers */ - for (ctr = 0; ctr < n_recs; ctr++) { - data[ctr] = recs[ctr].input; - } - if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_BUFS, - (int)n_recs, data) <= 0 - || EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_LENS, - (int)n_recs, reclen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); - return 0; - } - } - - if (!SSL_IS_DTLS(s) && tlstree_enc) { - unsigned char *seq; - int decrement_seq = 0; - - /* - * When sending, seq is incremented after MAC calculation. - * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. - * Otherwise we have to decrease it in the implementation - */ - if (sending && !SSL_WRITE_ETM(s)) - decrement_seq = 1; - - seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) - : RECORD_LAYER_get_read_sequence(&s->rlayer); - if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - - if (provided) { - int outlen; - - /* Provided cipher - we do not support pipelining on this path */ - if (n_recs > 1) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input, - (unsigned int)reclen[0])) - return 0; - recs[0].length = outlen; - - /* - * The length returned from EVP_CipherUpdate above is the actual - * payload length. We need to adjust the data/input ptr to skip over - * any explicit IV - */ - if (!sending) { - if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { - recs[0].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - recs[0].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { - recs[0].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; - recs[0].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; - } else if (bs != 1 && SSL_USE_EXPLICIT_IV(s)) { - recs[0].data += bs; - recs[0].input += bs; - recs[0].orig_len -= bs; - } - - /* Now get a pointer to the MAC (if applicable) */ - if (macs != NULL) { - OSSL_PARAM params[2], *p = params; - - /* Get the MAC */ - macs[0].alloced = 0; - - *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, - (void **)&macs[0].mac, - macsize); - *p = OSSL_PARAM_construct_end(); - - if (!EVP_CIPHER_CTX_get_params(ds, params)) { - /* Shouldn't normally happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - ERR_R_INTERNAL_ERROR); - return 0; - } - } - } - } else { - /* Legacy cipher */ - - tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, - (unsigned int)reclen[0]); - if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) - & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0 - ? (tmpr < 0) - : (tmpr == 0)) { - /* AEAD can fail to verify MAC */ - return 0; - } - - if (!sending) { - for (ctr = 0; ctr < n_recs; ctr++) { - /* Adjust the record to remove the explicit IV/MAC/Tag */ - if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { - recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { - recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; - } else if (bs != 1 && SSL_USE_EXPLICIT_IV(s)) { - if (recs[ctr].length < bs) - return 0; - recs[ctr].data += bs; - recs[ctr].input += bs; - recs[ctr].length -= bs; - recs[ctr].orig_len -= bs; - } - - /* - * If using Mac-then-encrypt, then this will succeed but - * with a random MAC if padding is invalid - */ - if (!tls1_cbc_remove_padding_and_mac(&recs[ctr].length, - recs[ctr].orig_len, - recs[ctr].data, - (macs != NULL) ? &macs[ctr].mac : NULL, - (macs != NULL) ? &macs[ctr].alloced - : NULL, - bs, - pad ? (size_t)pad : macsize, - (EVP_CIPHER_get_flags(enc) - & EVP_CIPH_FLAG_AEAD_CIPHER) != 0, - s->ctx->libctx)) - return 0; - } - } - } - } - return 1; -} - -/* - * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function - * which ssl3_cbc_digest_record supports. - */ -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) -{ - switch (EVP_MD_CTX_get_type(ctx)) { - case NID_md5: - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - return 1; - default: - return 0; - } -} - -int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) -{ - unsigned char *mac_sec, *seq; - const EVP_MD_CTX *hash; - unsigned char *p, rec_char; - size_t md_size; - size_t npad; - int t; - - if (sending) { - mac_sec = &(ssl->s3.write_mac_secret[0]); - seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer); - hash = ssl->write_hash; - } else { - mac_sec = &(ssl->s3.read_mac_secret[0]); - seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_get_size(hash); - if (t <= 0) - return 0; - md_size = t; - npad = (48 / md_size) * md_size; - - if (!sending - && EVP_CIPHER_CTX_get_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE - && ssl3_cbc_record_digest_supported(hash)) { -#ifdef OPENSSL_NO_DEPRECATED_3_0 - return 0; -#else - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - - /*- - * npad is, at most, 48 bytes and that's with MD5: - * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. - * - * With SHA-1 (the largest hash speced for SSLv3) the hash size - * goes up 4, but npad goes down by 8, resulting in a smaller - * total size. - */ - unsigned char header[75]; - size_t j = 0; - memcpy(header + j, mac_sec, md_size); - j += md_size; - memcpy(header + j, ssl3_pad_1, npad); - j += npad; - memcpy(header + j, seq, 8); - j += 8; - header[j++] = rec->type; - header[j++] = (unsigned char)(rec->length >> 8); - header[j++] = (unsigned char)(rec->length & 0xff); - - /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash), - md, &md_size, - header, rec->input, - rec->length, rec->orig_len, - mac_sec, md_size, 1) <= 0) - return 0; -#endif - } else { - unsigned int md_size_u; - /* Chop the digest off the end :-) */ - EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); - - if (md_ctx == NULL) - return 0; - - rec_char = rec->type; - p = md; - s2n(rec->length, p); - if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0 - || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0 - || EVP_DigestUpdate(md_ctx, seq, 8) <= 0 - || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0 - || EVP_DigestUpdate(md_ctx, md, 2) <= 0 - || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0 - || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0 - || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0 - || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0 - || EVP_DigestUpdate(md_ctx, md, md_size) <= 0 - || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) { - EVP_MD_CTX_free(md_ctx); - return 0; - } - - EVP_MD_CTX_free(md_ctx); - } - - ssl3_record_sequence_update(seq); - return 1; -} - -int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) -{ - unsigned char *seq; - EVP_MD_CTX *hash; - size_t md_size; - int i; - EVP_MD_CTX *hmac = NULL, *mac_ctx; - unsigned char header[13]; - int stream_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM); - int tlstree_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); - int t; - int ret = 0; - - if (sending) { - seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer); - hash = ssl->write_hash; - } else { - seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_get_size(hash); - if (!ossl_assert(t >= 0)) - return 0; - md_size = t; - - /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ - if (stream_mac) { - mac_ctx = hash; - } else { - hmac = EVP_MD_CTX_new(); - if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash)) { - goto end; - } - mac_ctx = hmac; - } - - if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) { - goto end; - } - - if (SSL_IS_DTLS(ssl)) { - unsigned char dtlsseq[8], *p = dtlsseq; - - s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) : - DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p); - memcpy(p, &seq[2], 6); - - memcpy(header, dtlsseq, 8); - } else - memcpy(header, seq, 8); - - header[8] = rec->type; - header[9] = (unsigned char)(ssl->version >> 8); - header[10] = (unsigned char)(ssl->version); - header[11] = (unsigned char)(rec->length >> 8); - header[12] = (unsigned char)(rec->length & 0xff); - - if (!sending && !SSL_READ_ETM(ssl) - && EVP_CIPHER_CTX_get_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE - && ssl3_cbc_record_digest_supported(mac_ctx)) { - OSSL_PARAM tls_hmac_params[2], *p = tls_hmac_params; - - *p++ = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, - &rec->orig_len); - *p++ = OSSL_PARAM_construct_end(); - - if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_get_pkey_ctx(mac_ctx), - tls_hmac_params)) { - goto end; - } - } - - if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 - || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 - || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { - goto end; - } - - OSSL_TRACE_BEGIN(TLS) { - BIO_printf(trc_out, "seq:\n"); - BIO_dump_indent(trc_out, seq, 8, 4); - BIO_printf(trc_out, "rec:\n"); - BIO_dump_indent(trc_out, rec->data, rec->length, 4); - } OSSL_TRACE_END(TLS); - - if (!SSL_IS_DTLS(ssl)) { - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } - } - OSSL_TRACE_BEGIN(TLS) { - BIO_printf(trc_out, "md:\n"); - BIO_dump_indent(trc_out, md, md_size, 4); - } OSSL_TRACE_END(TLS); - ret = 1; - end: - EVP_MD_CTX_free(hmac); - return ret; -} - -int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) -{ - int i; - int enc_err; - SSL_SESSION *sess; - SSL3_RECORD *rr; - int imac_size; - size_t mac_size = 0; - unsigned char md[EVP_MAX_MD_SIZE]; - size_t max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH; - SSL_MAC_BUF macbuf = { NULL, 0 }; - int ret = 0; - - rr = RECORD_LAYER_get_rrec(&s->rlayer); - sess = s->session; - - /* - * At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->rlayer.packet - */ - rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->rlayer.packet' data into 'rr'. rr->input - * points at rr->length bytes, which need to be copied into rr->data by - * either the decryption or by the decompression. When the data is 'copied' - * into the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - return 0; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - rr->orig_len = rr->length; - - if (s->read_hash != NULL) { - const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash); - - if (tmpmd != NULL) { - imac_size = EVP_MD_get_size(tmpmd); - if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); - return 0; - } - mac_size = (size_t)imac_size; - } - } - - if (SSL_READ_ETM(s) && s->read_hash) { - unsigned char *mac; - - if (rr->orig_len < mac_size) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); - return 0; - } - rr->length -= mac_size; - mac = rr->data + rr->length; - i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ ); - if (i == 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) { - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - return 0; - } - /* - * We've handled the mac now - there is no MAC inside the encrypted - * record - */ - mac_size = 0; - } - - /* - * Set a mark around the packet decryption attempt. This is DTLS, so - * bad packets are just ignored, and we don't want to leave stray - * errors in the queue from processing bogus junk that we ignored. - */ - ERR_set_mark(); - enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0, &macbuf, mac_size); - - /*- - * enc_err is: - * 0: if the record is publicly invalid, or an internal error, or AEAD - * decryption failed, or ETM decryption failed. - * 1: Success or MTE decryption failed (MAC will be randomised) - */ - if (enc_err == 0) { - ERR_pop_to_mark(); - if (ossl_statem_in_error(s)) { - /* SSLfatal() got called */ - goto end; - } - /* For DTLS we simply ignore bad packets. */ - rr->length = 0; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto end; - } - ERR_clear_last_mark(); - OSSL_TRACE_BEGIN(TLS) { - BIO_printf(trc_out, "dec %zd\n", rr->length); - BIO_dump_indent(trc_out, rr->data, rr->length, 4); - } OSSL_TRACE_END(TLS); - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) - && !SSL_READ_ETM(s) - && (s->enc_read_ctx != NULL) - && (EVP_MD_CTX_get0_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - - i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ ); - if (i == 0 || macbuf.mac == NULL - || CRYPTO_memcmp(md, macbuf.mac, mac_size) != 0) - enc_err = 0; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = 0; - } - - if (enc_err == 0) { - /* decryption failed, silently discard message */ - rr->length = 0; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto end; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, - SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto end; - } - if (!ssl3_do_uncompress(s, rr)) { - SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION); - goto end; - } - } - - /* use current Max Fragment Length setting if applicable */ - if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) - max_plain_length = GET_MAX_FRAGMENT_LENGTH(s->session); - - /* send overflow if the plaintext is too long now it has passed MAC */ - if (rr->length > max_plain_length) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); - goto end; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3.rrec.type is the type of record - * ssl->s3.rrec.length == number of bytes in record - * ssl->s3.rrec.off == offset to first valid byte - * ssl->s3.rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - RECORD_LAYER_reset_packet_length(&s->rlayer); - - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); - - ret = 1; - end: - if (macbuf.alloced) - OPENSSL_free(macbuf.mac); - return ret; -} - -/* - * Retrieve a buffered record that belongs to the current epoch, i.e. processed - */ -#define dtls1_get_processed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &(DTLS_RECORD_LAYER_get_processed_rcds(&s->rlayer))) - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3.rrec.type - is the type of record - * ssl->s3.rrec.data - data - * ssl->s3.rrec.length - number of bytes - */ -/* used only by dtls1_read_bytes */ -int dtls1_get_record(SSL *s) -{ - int ssl_major, ssl_minor; - int rret; - size_t more, n; - SSL3_RECORD *rr; - unsigned char *p = NULL; - unsigned short version; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - - rr = RECORD_LAYER_get_rrec(&s->rlayer); - - again: - /* - * The epoch may have changed. If so, process all the pending records. - * This is a non-blocking operation. - */ - if (!dtls1_process_buffered_records(s)) { - /* SSLfatal() already called */ - return -1; - } - - /* if we're renegotiating, then there may be buffered records */ - if (dtls1_get_processed_record(s)) - return 1; - - /* get something from the wire */ - - /* check if we have the header */ - if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) || - (RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) { - rret = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, - SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0, 1, &n); - /* read timeout is handled by dtls1_read_bytes */ - if (rret <= 0) { - /* SSLfatal() already called if appropriate */ - return rret; /* error or non-blocking */ - } - - /* this packet contained a partial record, dump it */ - if (RECORD_LAYER_get_packet_length(&s->rlayer) != - DTLS1_RT_HEADER_LENGTH) { - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); - - p = RECORD_LAYER_get_packet(&s->rlayer); - - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, - s, s->msg_callback_arg); - - /* Pull apart the header into the DTLS1_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - - /* sequence number is 64 bits, with top 2 bytes = epoch */ - n2s(p, rr->epoch); - - memcpy(&(RECORD_LAYER_get_read_sequence(&s->rlayer)[2]), p, 6); - p += 6; - - n2s(p, rr->length); - rr->read = 0; - - /* - * Lets check the version. We tolerate alerts that don't have the exact - * version number (e.g. because of protocol version errors) - */ - if (!s->first_packet && rr->type != SSL3_RT_ALERT) { - if (version != s->version) { - /* unexpected version, silently discard */ - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - } - - if ((version & 0xff00) != (s->version & 0xff00)) { - /* wrong version, silently discard record */ - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - /* record too long, silently discard it */ - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - /* If received packet overflows own-client Max Fragment Length setting */ - if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) - && rr->length > GET_MAX_FRAGMENT_LENGTH(s->session) + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) { - /* record too long, silently discard it */ - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - /* now s->rlayer.rstate == SSL_ST_READ_BODY */ - } - - /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > - RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) { - /* now s->rlayer.packet_length == DTLS1_RT_HEADER_LENGTH */ - more = rr->length; - rret = ssl3_read_n(s, more, more, 1, 1, &n); - /* this packet contained a partial record, dump it */ - if (rret <= 0 || n != more) { - if (ossl_statem_in_error(s)) { - /* ssl3_read_n() called SSLfatal() */ - return -1; - } - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - /* - * now n == rr->length, and s->rlayer.packet_length == - * DTLS1_RT_HEADER_LENGTH + rr->length - */ - } - /* set state for later operations */ - RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER); - - /* match epochs. NULL means the packet is dropped on the floor */ - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - rr->length = 0; - RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { -#endif - /* Check whether this is a repeat, or aged record. */ - if (!dtls1_record_replay_check(s, bitmap)) { - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - } -#endif - - /* just read a 0 length packet */ - if (rr->length == 0) { - rr->read = 1; - goto again; - } - - /* - * If this record is from the next epoch (either HM or ALERT), and a - * handshake is currently in progress, buffer it since it cannot be - * processed at this time. - */ - if (is_next_epoch) { - if ((SSL_in_init(s) || ossl_statem_get_in_handshake(s))) { - if (dtls1_buffer_record (s, - &(DTLS_RECORD_LAYER_get_unprocessed_rcds(&s->rlayer)), - rr->seq_num) < 0) { - /* SSLfatal() already called */ - return -1; - } - } - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); - goto again; - } - - if (!dtls1_process_record(s, bitmap)) { - if (ossl_statem_in_error(s)) { - /* dtls1_process_record() called SSLfatal */ - return -1; - } - rr->length = 0; - rr->read = 1; - RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */ - goto again; /* get another record */ - } - - return 1; - -} - -int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, size_t off) -{ - SSL3_RECORD *rr; - - rr = RECORD_LAYER_get_rrec(&s->rlayer); - memset(rr, 0, sizeof(SSL3_RECORD)); - - rr->length = len; - rr->type = SSL3_RT_HANDSHAKE; - memcpy(rr->seq_num, seq, sizeof(rr->seq_num)); - rr->off = off; - - s->rlayer.packet = RECORD_LAYER_get_rbuf(&s->rlayer)->buf; - s->rlayer.packet_length = DTLS1_RT_HEADER_LENGTH + len; - rr->data = s->rlayer.packet + DTLS1_RT_HEADER_LENGTH; - - if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds), - SSL3_RECORD_get_seq_num(s->rlayer.rrec)) <= 0) { - /* SSLfatal() already called */ - return 0; - } - - return 1; -} diff --git a/ssl/record/ssl3_record_tls13.c b/ssl/record/ssl3_record_tls13.c deleted file mode 100644 index c605fa74d2..0000000000 --- a/ssl/record/ssl3_record_tls13.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "../ssl_local.h" -#include "record_local.h" -#include "internal/cryptlib.h" - -/*- - * tls13_enc encrypts/decrypts |n_recs| in |recs|. Calls SSLfatal on internal - * error, but not otherwise. It is the responsibility of the caller to report - * a bad_record_mac. - * - * Returns: - * 0: On failure - * 1: if the record encryption/decryption was successful. - */ -int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, - ossl_unused SSL_MAC_BUF *mac, ossl_unused size_t macsize) -{ - EVP_CIPHER_CTX *ctx; - unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; - size_t taglen, offset, loop, hdrlen; - int ivlen; - unsigned char *staticiv; - unsigned char *seq; - int lenu, lenf; - SSL3_RECORD *rec = &recs[0]; - uint32_t alg_enc; - WPACKET wpkt; - - if (n_recs != 1) { - /* Should not happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (sending) { - ctx = s->enc_write_ctx; - staticiv = s->write_iv; - seq = RECORD_LAYER_get_write_sequence(&s->rlayer); - } else { - ctx = s->enc_read_ctx; - staticiv = s->read_iv; - seq = RECORD_LAYER_get_read_sequence(&s->rlayer); - } - - /* - * If we're sending an alert and ctx != NULL then we must be forcing - * plaintext alerts. If we're reading and ctx != NULL then we allow - * plaintext alerts at certain points in the handshake. If we've got this - * far then we have already validated that a plaintext alert is ok here. - */ - if (ctx == NULL || rec->type == SSL3_RT_ALERT) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - return 1; - } - - ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); - if (ivlen < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (s->early_data_state == SSL_EARLY_DATA_WRITING - || s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { - if (s->session != NULL && s->session->ext.max_early_data > 0) { - alg_enc = s->session->cipher->algorithm_enc; - } else { - if (!ossl_assert(s->psksession != NULL - && s->psksession->ext.max_early_data > 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - alg_enc = s->psksession->cipher->algorithm_enc; - } - } else { - /* - * To get here we must have selected a ciphersuite - otherwise ctx would - * be NULL - */ - if (!ossl_assert(s->s3.tmp.new_cipher != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - alg_enc = s->s3.tmp.new_cipher->algorithm_enc; - } - - if (alg_enc & SSL_AESCCM) { - if (alg_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) - taglen = EVP_CCM8_TLS_TAG_LEN; - else - taglen = EVP_CCM_TLS_TAG_LEN; - if (sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, - NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } else if (alg_enc & SSL_AESGCM) { - taglen = EVP_GCM_TLS_TAG_LEN; - } else if (alg_enc & SSL_CHACHA20) { - taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!sending) { - /* - * Take off tag. There must be at least one byte of content type as - * well as the tag - */ - if (rec->length < taglen + 1) - return 0; - rec->length -= taglen; - } - - /* Set up IV */ - if (ivlen < SEQ_NUM_SIZE) { - /* Should not happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - offset = ivlen - SEQ_NUM_SIZE; - memcpy(iv, staticiv, offset); - for (loop = 0; loop < SEQ_NUM_SIZE; loop++) - iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; - - /* Increment the sequence counter */ - for (loop = SEQ_NUM_SIZE; loop > 0; loop--) { - ++seq[loop - 1]; - if (seq[loop - 1] != 0) - break; - } - if (loop == 0) { - /* Sequence has wrapped */ - return 0; - } - - if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0 - || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, - taglen, - rec->data + rec->length) <= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - /* Set up the AAD */ - if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) - || !WPACKET_put_bytes_u8(&wpkt, rec->type) - || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version) - || !WPACKET_put_bytes_u16(&wpkt, rec->length + taglen) - || !WPACKET_get_total_written(&wpkt, &hdrlen) - || hdrlen != SSL3_RT_HEADER_LENGTH - || !WPACKET_finish(&wpkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - WPACKET_cleanup(&wpkt); - return 0; - } - - /* - * For CCM we must explicitly set the total plaintext length before we add - * any AAD. - */ - if (((alg_enc & SSL_AESCCM) != 0 - && EVP_CipherUpdate(ctx, NULL, &lenu, NULL, - (unsigned int)rec->length) <= 0) - || EVP_CipherUpdate(ctx, NULL, &lenu, recheader, - sizeof(recheader)) <= 0 - || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input, - (unsigned int)rec->length) <= 0 - || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 - || (size_t)(lenu + lenf) != rec->length) { - return 0; - } - if (sending) { - /* Add the tag */ - if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, - rec->data + rec->length) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - rec->length += taglen; - } - - return 1; -} diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 2ca3f74ae7..54c47dd3f9 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -15,7 +15,7 @@ #include #include "internal/cryptlib.h" -static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) +static int ssl3_generate_key_block(SSL_CONNECTION *s, unsigned char *km, int num) { const EVP_MD *md5 = NULL, *sha1 = NULL; EVP_MD_CTX *m5; @@ -24,17 +24,18 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) unsigned char c = 'A'; unsigned int i, k; int ret = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); #ifdef CHARSET_EBCDIC c = os_toascii[c]; /* 'A' in ASCII */ #endif k = 0; - md5 = ssl_evp_md_fetch(s->ctx->libctx, NID_md5, s->ctx->propq); - sha1 = ssl_evp_md_fetch(s->ctx->libctx, NID_sha1, s->ctx->propq); + md5 = ssl_evp_md_fetch(sctx->libctx, NID_md5, sctx->propq); + sha1 = ssl_evp_md_fetch(sctx->libctx, NID_sha1, sctx->propq); m5 = EVP_MD_CTX_new(); s1 = EVP_MD_CTX_new(); if (md5 == NULL || sha1 == NULL || m5 == NULL || s1 == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { @@ -86,131 +87,55 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) return ret; } -int ssl3_change_cipher_state(SSL *s, int which) +int ssl3_change_cipher_state(SSL_CONNECTION *s, int which) { unsigned char *p, *mac_secret; - unsigned char *ms, *key, *iv; - EVP_CIPHER_CTX *dd; - const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - COMP_METHOD *comp; -#endif - const EVP_MD *m; + size_t md_len; + unsigned char *key, *iv; + const EVP_CIPHER *ciph; + const SSL_COMP *comp = NULL; + const EVP_MD *md; int mdi; - size_t n, i, j, k, cl; - int reuse_dd = 0; + size_t n, iv_len, key_len; + int direction = (which & SSL3_CC_READ) != 0 ? OSSL_RECORD_DIRECTION_READ + : OSSL_RECORD_DIRECTION_WRITE; - c = s->s3.tmp.new_sym_enc; - m = s->s3.tmp.new_hash; + ciph = s->s3.tmp.new_sym_enc; + md = s->s3.tmp.new_hash; /* m == NULL will lead to a crash later */ - if (!ossl_assert(m != NULL)) { + if (!ossl_assert(md != NULL)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } #ifndef OPENSSL_NO_COMP - if (s->s3.tmp.new_compression == NULL) - comp = NULL; - else - comp = s->s3.tmp.new_compression->method; -#endif - - if (which & SSL3_CC_READ) { - if (s->enc_read_ctx != NULL) { - reuse_dd = 1; - } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } else { - /* - * make sure it's initialised in case we exit later with an error - */ - EVP_CIPHER_CTX_reset(s->enc_read_ctx); - } - dd = s->enc_read_ctx; - - if (ssl_replace_hash(&s->read_hash, m) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - COMP_CTX_free(s->expand); - s->expand = NULL; - if (comp != NULL) { - s->expand = COMP_CTX_new(comp); - if (s->expand == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err; - } - } -#endif - RECORD_LAYER_reset_read_sequence(&s->rlayer); - mac_secret = &(s->s3.read_mac_secret[0]); - } else { - s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; - if (s->enc_write_ctx != NULL) { - reuse_dd = 1; - } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } else { - /* - * make sure it's initialised in case we exit later with an error - */ - EVP_CIPHER_CTX_reset(s->enc_write_ctx); - } - dd = s->enc_write_ctx; - if (ssl_replace_hash(&s->write_hash, m) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - COMP_CTX_free(s->compress); - s->compress = NULL; - if (comp != NULL) { - s->compress = COMP_CTX_new(comp); - if (s->compress == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err; - } - } + comp = s->s3.tmp.new_compression; #endif - RECORD_LAYER_reset_write_sequence(&s->rlayer); - mac_secret = &(s->s3.write_mac_secret[0]); - } - - if (reuse_dd) - EVP_CIPHER_CTX_reset(dd); p = s->s3.tmp.key_block; - mdi = EVP_MD_get_size(m); + mdi = EVP_MD_get_size(md); if (mdi < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - i = mdi; - cl = EVP_CIPHER_get_key_length(c); - j = cl; - k = EVP_CIPHER_get_iv_length(c); + md_len = (size_t)mdi; + key_len = EVP_CIPHER_get_key_length(ciph); + iv_len = EVP_CIPHER_get_iv_length(ciph); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); - n = i + i; + mac_secret = &(p[0]); + n = md_len + md_len; key = &(p[n]); - n += j + j; + n += key_len + key_len; iv = &(p[n]); - n += k + k; + n += iv_len + iv_len; } else { - n = i; - ms = &(p[n]); - n += i + j; + n = md_len; + mac_secret = &(p[n]); + n += md_len + key_len; key = &(p[n]); - n += j + k; + n += key_len + iv_len; iv = &(p[n]); - n += k; + n += iv_len; } if (n > s->s3.tmp.key_block_length) { @@ -218,26 +143,21 @@ int ssl3_change_cipher_state(SSL *s, int which) goto err; } - memcpy(mac_secret, ms, i); - - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (EVP_CIPHER_get0_provider(c) != NULL - && !tls_provider_set_tls_params(s, dd, c, m)) { + if (!ssl_set_new_record_layer(s, SSL3_VERSION, + direction, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + NULL, 0, key, key_len, iv, iv_len, mac_secret, + md_len, ciph, 0, NID_undef, md, comp, NULL)) { /* SSLfatal already called */ goto err; } - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; return 1; err: return 0; } -int ssl3_setup_key_block(SSL *s) +int ssl3_setup_key_block(SSL_CONNECTION *s) { unsigned char *p; const EVP_CIPHER *c; @@ -249,8 +169,8 @@ int ssl3_setup_key_block(SSL *s) if (s->s3.tmp.key_block_length != 0) return 1; - if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, &comp, - 0)) { + if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, + NULL, NULL, &comp, 0)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; @@ -276,7 +196,7 @@ int ssl3_setup_key_block(SSL *s) ssl3_cleanup_key_block(s); if ((p = OPENSSL_malloc(num)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } @@ -286,38 +206,22 @@ int ssl3_setup_key_block(SSL *s) /* Calls SSLfatal() as required */ ret = ssl3_generate_key_block(s, p, num); - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3.need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3.need_empty_fragments = 0; - - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3.need_empty_fragments = 0; - } - } - return ret; } -void ssl3_cleanup_key_block(SSL *s) +void ssl3_cleanup_key_block(SSL_CONNECTION *s) { OPENSSL_clear_free(s->s3.tmp.key_block, s->s3.tmp.key_block_length); s->s3.tmp.key_block = NULL; s->s3.tmp.key_block_length = 0; } -int ssl3_init_finished_mac(SSL *s) +int ssl3_init_finished_mac(SSL_CONNECTION *s) { BIO *buf = BIO_new(BIO_s_mem()); if (buf == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BIO_LIB); return 0; } ssl3_free_digest_list(s); @@ -331,7 +235,7 @@ int ssl3_init_finished_mac(SSL *s) * together. */ -void ssl3_free_digest_list(SSL *s) +void ssl3_free_digest_list(SSL_CONNECTION *s) { BIO_free(s->s3.handshake_buffer); s->s3.handshake_buffer = NULL; @@ -339,7 +243,7 @@ void ssl3_free_digest_list(SSL *s) s->s3.handshake_dgst = NULL; } -int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len) +int ssl3_finish_mac(SSL_CONNECTION *s, const unsigned char *buf, size_t len) { int ret; @@ -364,7 +268,7 @@ int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len) return 1; } -int ssl3_digest_cached_records(SSL *s, int keep) +int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep) { const EVP_MD *md; long hdatalen; @@ -379,7 +283,7 @@ int ssl3_digest_cached_records(SSL *s, int keep) s->s3.handshake_dgst = EVP_MD_CTX_new(); if (s->s3.handshake_dgst == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } @@ -413,7 +317,7 @@ void ssl3_digest_master_key_set_params(const SSL_SESSION *session, params[n++] = OSSL_PARAM_construct_end(); } -size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, +size_t ssl3_final_finish_mac(SSL_CONNECTION *s, const char *sender, size_t len, unsigned char *p) { int ret; @@ -431,7 +335,7 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, ctx = EVP_MD_CTX_new(); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } if (!EVP_MD_CTX_copy_ex(ctx, s->s3.handshake_dgst)) { @@ -466,7 +370,8 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, return ret; } -int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, +int ssl3_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, + unsigned char *p, size_t len, size_t *secret_size) { static const unsigned char *salt[3] = { @@ -487,11 +392,11 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, size_t ret_secret_size = 0; if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } for (i = 0; i < 3; i++) { - if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0 + if (EVP_DigestInit_ex(ctx, SSL_CONNECTION_GET_CTX(s)->sha1, NULL) <= 0 || EVP_DigestUpdate(ctx, salt[i], strlen((const char *)salt[i])) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 @@ -500,7 +405,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, || EVP_DigestUpdate(ctx, &(s->s3.server_random[0]), SSL3_RANDOM_SIZE) <= 0 || EVP_DigestFinal_ex(ctx, buf, &n) <= 0 - || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0 + || EVP_DigestInit_ex(ctx, SSL_CONNECTION_GET_CTX(s)->md5, NULL) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 || EVP_DigestUpdate(ctx, buf, n) <= 0 || EVP_DigestFinal_ex(ctx, out, &n) <= 0) { diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 78d4f04056..e8ec98c221 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -47,7 +47,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 128, 128, }, { @@ -62,7 +62,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA384, + SSL_HANDSHAKE_MAC_SHA384 | SSL_QUIC, 256, 256, }, @@ -78,7 +78,7 @@ static SSL_CIPHER tls13_ciphers[] = { TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, SSL_HIGH, - SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 256, 256, }, @@ -108,9 +108,9 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, 0, 0, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, } }; @@ -699,9 +699,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, }, { @@ -715,9 +715,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 256, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, { @@ -731,9 +731,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, }, { @@ -747,9 +747,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 256, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, { @@ -827,9 +827,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, }, { @@ -843,9 +843,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 256, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, { @@ -859,9 +859,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, }, { @@ -875,9 +875,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 256, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, { @@ -923,9 +923,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, }, { @@ -939,9 +939,9 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_AEAD, TLS1_2_VERSION, TLS1_2_VERSION, DTLS1_2_VERSION, DTLS1_2_VERSION, - SSL_NOT_DEFAULT | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 256, + 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, { @@ -2807,7 +2807,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2823,7 +2823,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2839,7 +2839,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2855,7 +2855,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2871,7 +2871,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2887,7 +2887,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2903,7 +2903,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2919,7 +2919,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2935,7 +2935,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, { @@ -2951,7 +2951,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, + 80, 128, }, #endif /* OPENSSL_NO_WEAK_SSL_CIPHERS */ @@ -3255,9 +3255,9 @@ void ssl_sort_cipher_list(void) qsort(ssl3_scsvs, SSL3_NUM_SCSVS, sizeof(ssl3_scsvs[0]), cipher_compare); } -static int ssl_undefined_function_1(SSL *ssl, unsigned char *r, size_t s, - const char * t, size_t u, - const unsigned char * v, size_t w, int x) +static int sslcon_undefined_function_1(SSL_CONNECTION *sc, unsigned char *r, + size_t s, const char *t, size_t u, + const unsigned char *v, size_t w, int x) { (void)r; (void)s; @@ -3266,12 +3266,10 @@ static int ssl_undefined_function_1(SSL *ssl, unsigned char *r, size_t s, (void)v; (void)w; (void)x; - return ssl_undefined_function(ssl); + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } const SSL3_ENC_METHOD SSLv3_enc_data = { - ssl3_enc, - n_ssl3_mac, ssl3_setup_key_block, ssl3_generate_master_secret, ssl3_change_cipher_state, @@ -3279,20 +3277,20 @@ const SSL3_ENC_METHOD SSLv3_enc_data = { SSL3_MD_CLIENT_FINISHED_CONST, 4, SSL3_MD_SERVER_FINISHED_CONST, 4, ssl3_alert_code, - ssl_undefined_function_1, + sslcon_undefined_function_1, 0, ssl3_set_handshake_header, tls_close_construct_packet, ssl3_handshake_write }; -long ssl3_default_timeout(void) +OSSL_TIME ssl3_default_timeout(void) { /* * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for * http, the cache would over fill */ - return (60 * 60 * 2); + return ossl_seconds2time(60 * 60 * 2); } int ssl3_num_ciphers(void) @@ -3308,7 +3306,7 @@ const SSL_CIPHER *ssl3_get_cipher(unsigned int u) return NULL; } -int ssl3_set_handshake_header(SSL *s, WPACKET *pkt, int htype) +int ssl3_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype) { /* No header in the event of a CCS */ if (htype == SSL3_MT_CHANGE_CIPHER_SPEC) @@ -3322,7 +3320,7 @@ int ssl3_set_handshake_header(SSL *s, WPACKET *pkt, int htype) return 1; } -int ssl3_handshake_write(SSL *s) +int ssl3_handshake_write(SSL_CONNECTION *s) { return ssl3_do_write(s, SSL3_RT_HANDSHAKE); } @@ -3330,7 +3328,12 @@ int ssl3_handshake_write(SSL *s) int ssl3_new(SSL *s) { #ifndef OPENSSL_NO_SRP - if (!ssl_srp_ctx_init_intern(s)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (!ssl_srp_ctx_init_intern(sc)) return 0; #endif @@ -3342,65 +3345,84 @@ int ssl3_new(SSL *s) void ssl3_free(SSL *s) { - if (s == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) return; - ssl3_cleanup_key_block(s); + ssl3_cleanup_key_block(sc); + + EVP_PKEY_free(sc->s3.peer_tmp); + sc->s3.peer_tmp = NULL; + EVP_PKEY_free(sc->s3.tmp.pkey); + sc->s3.tmp.pkey = NULL; - EVP_PKEY_free(s->s3.peer_tmp); - s->s3.peer_tmp = NULL; - EVP_PKEY_free(s->s3.tmp.pkey); - s->s3.tmp.pkey = NULL; + ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc); + ssl_evp_md_free(sc->s3.tmp.new_hash); - ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); - ssl_evp_md_free(s->s3.tmp.new_hash); + OPENSSL_free(sc->s3.tmp.ctype); + sk_X509_NAME_pop_free(sc->s3.tmp.peer_ca_names, X509_NAME_free); + OPENSSL_free(sc->s3.tmp.ciphers_raw); + OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen); + OPENSSL_free(sc->s3.tmp.peer_sigalgs); + OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs); + OPENSSL_free(sc->s3.tmp.valid_flags); + ssl3_free_digest_list(sc); + OPENSSL_free(sc->s3.alpn_selected); + OPENSSL_free(sc->s3.alpn_proposed); - OPENSSL_free(s->s3.tmp.ctype); - sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); - OPENSSL_free(s->s3.tmp.ciphers_raw); - OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); - OPENSSL_free(s->s3.tmp.peer_sigalgs); - OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); - ssl3_free_digest_list(s); - OPENSSL_free(s->s3.alpn_selected); - OPENSSL_free(s->s3.alpn_proposed); +#ifndef OPENSSL_NO_PSK + OPENSSL_free(sc->s3.tmp.psk); +#endif #ifndef OPENSSL_NO_SRP - ssl_srp_ctx_free_intern(s); + ssl_srp_ctx_free_intern(sc); #endif - memset(&s->s3, 0, sizeof(s->s3)); + memset(&sc->s3, 0, sizeof(sc->s3)); } int ssl3_clear(SSL *s) { - ssl3_cleanup_key_block(s); - OPENSSL_free(s->s3.tmp.ctype); - sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); - OPENSSL_free(s->s3.tmp.ciphers_raw); - OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); - OPENSSL_free(s->s3.tmp.peer_sigalgs); - OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + int flags; + + if (sc == NULL) + return 0; + + ssl3_cleanup_key_block(sc); + OPENSSL_free(sc->s3.tmp.ctype); + sk_X509_NAME_pop_free(sc->s3.tmp.peer_ca_names, X509_NAME_free); + OPENSSL_free(sc->s3.tmp.ciphers_raw); + OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen); + OPENSSL_free(sc->s3.tmp.peer_sigalgs); + OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs); + OPENSSL_free(sc->s3.tmp.valid_flags); - EVP_PKEY_free(s->s3.tmp.pkey); - EVP_PKEY_free(s->s3.peer_tmp); + EVP_PKEY_free(sc->s3.tmp.pkey); + EVP_PKEY_free(sc->s3.peer_tmp); - ssl3_free_digest_list(s); + ssl3_free_digest_list(sc); - OPENSSL_free(s->s3.alpn_selected); - OPENSSL_free(s->s3.alpn_proposed); + OPENSSL_free(sc->s3.alpn_selected); + OPENSSL_free(sc->s3.alpn_proposed); - /* NULL/zero-out everything in the s3 struct */ - memset(&s->s3, 0, sizeof(s->s3)); + /* + * NULL/zero-out everything in the s3 struct, but remember if we are doing + * QUIC. + */ + flags = sc->s3.flags & TLS1_FLAGS_QUIC; + memset(&sc->s3, 0, sizeof(sc->s3)); + sc->s3.flags |= flags; - if (!ssl_free_wbio_buffer(s)) + if (!ssl_free_wbio_buffer(sc)) return 0; - s->version = SSL3_VERSION; + sc->version = SSL3_VERSION; #if !defined(OPENSSL_NO_NEXTPROTONEG) - OPENSSL_free(s->ext.npn); - s->ext.npn = NULL; - s->ext.npn_len = 0; + OPENSSL_free(sc->ext.npn); + sc->ext.npn = NULL; + sc->ext.npn_len = 0; #endif return 1; @@ -3409,7 +3431,12 @@ int ssl3_clear(SSL *s) #ifndef OPENSSL_NO_SRP static char *srp_password_from_info_cb(SSL *s, void *arg) { - return OPENSSL_strdup(s->srp_ctx.info); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + return OPENSSL_strdup(sc->srp_ctx.info); } #endif @@ -3418,22 +3445,26 @@ static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len); long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) { int ret = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return ret; switch (cmd) { case SSL_CTRL_GET_CLIENT_CERT_REQUEST: break; case SSL_CTRL_GET_NUM_RENEGOTIATIONS: - ret = s->s3.num_renegotiations; + ret = sc->s3.num_renegotiations; break; case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: - ret = s->s3.num_renegotiations; - s->s3.num_renegotiations = 0; + ret = sc->s3.num_renegotiations; + sc->s3.num_renegotiations = 0; break; case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: - ret = s->s3.total_renegotiations; + ret = sc->s3.total_renegotiations; break; case SSL_CTRL_GET_FLAGS: - ret = (int)(s->s3.flags); + ret = (int)(sc->s3.flags); break; #if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH: @@ -3445,7 +3476,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } pkdh = ssl_dh_to_pkey(parg); if (pkdh == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_DH_LIB); return 0; } if (!SSL_set0_tmp_dh_pkey(s, pkdh)) { @@ -3462,7 +3493,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } #endif case SSL_CTRL_SET_DH_AUTO: - s->cert->dh_tmp_auto = larg; + sc->cert->dh_tmp_auto = larg; return 1; #if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_ECDH: @@ -3471,8 +3502,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - return ssl_set_tmp_ecdh_groups(&s->ext.supportedgroups, - &s->ext.supportedgroups_len, + return ssl_set_tmp_ecdh_groups(&sc->ext.supportedgroups, + &sc->ext.supportedgroups_len, parg); } #endif /* !OPENSSL_NO_DEPRECATED_3_0 */ @@ -3488,8 +3519,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) if (larg == TLSEXT_NAMETYPE_host_name) { size_t len; - OPENSSL_free(s->ext.hostname); - s->ext.hostname = NULL; + OPENSSL_free(sc->ext.hostname); + sc->ext.hostname = NULL; ret = 1; if (parg == NULL) @@ -3499,7 +3530,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); return 0; } - if ((s->ext.hostname = OPENSSL_strdup((char *)parg)) == NULL) { + if ((sc->ext.hostname = OPENSSL_strdup((char *)parg)) == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } @@ -3509,79 +3540,79 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } break; case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: - s->ext.debug_arg = parg; + sc->ext.debug_arg = parg; ret = 1; break; case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE: - ret = s->ext.status_type; + ret = sc->ext.status_type; break; case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: - s->ext.status_type = larg; + sc->ext.status_type = larg; ret = 1; break; case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: - *(STACK_OF(X509_EXTENSION) **)parg = s->ext.ocsp.exts; + *(STACK_OF(X509_EXTENSION) **)parg = sc->ext.ocsp.exts; ret = 1; break; case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: - s->ext.ocsp.exts = parg; + sc->ext.ocsp.exts = parg; ret = 1; break; case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: - *(STACK_OF(OCSP_RESPID) **)parg = s->ext.ocsp.ids; + *(STACK_OF(OCSP_RESPID) **)parg = sc->ext.ocsp.ids; ret = 1; break; case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: - s->ext.ocsp.ids = parg; + sc->ext.ocsp.ids = parg; ret = 1; break; case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: - *(unsigned char **)parg = s->ext.ocsp.resp; - if (s->ext.ocsp.resp_len == 0 - || s->ext.ocsp.resp_len > LONG_MAX) + *(unsigned char **)parg = sc->ext.ocsp.resp; + if (sc->ext.ocsp.resp_len == 0 + || sc->ext.ocsp.resp_len > LONG_MAX) return -1; - return (long)s->ext.ocsp.resp_len; + return (long)sc->ext.ocsp.resp_len; case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: - OPENSSL_free(s->ext.ocsp.resp); - s->ext.ocsp.resp = parg; - s->ext.ocsp.resp_len = larg; + OPENSSL_free(sc->ext.ocsp.resp); + sc->ext.ocsp.resp = parg; + sc->ext.ocsp.resp_len = larg; ret = 1; break; case SSL_CTRL_CHAIN: if (larg) - return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg); + return ssl_cert_set1_chain(sc, NULL, (STACK_OF(X509) *)parg); else - return ssl_cert_set0_chain(s, NULL, (STACK_OF(X509) *)parg); + return ssl_cert_set0_chain(sc, NULL, (STACK_OF(X509) *)parg); case SSL_CTRL_CHAIN_CERT: if (larg) - return ssl_cert_add1_chain_cert(s, NULL, (X509 *)parg); + return ssl_cert_add1_chain_cert(sc, NULL, (X509 *)parg); else - return ssl_cert_add0_chain_cert(s, NULL, (X509 *)parg); + return ssl_cert_add0_chain_cert(sc, NULL, (X509 *)parg); case SSL_CTRL_GET_CHAIN_CERTS: - *(STACK_OF(X509) **)parg = s->cert->key->chain; + *(STACK_OF(X509) **)parg = sc->cert->key->chain; ret = 1; break; case SSL_CTRL_SELECT_CURRENT_CERT: - return ssl_cert_select_current(s->cert, (X509 *)parg); + return ssl_cert_select_current(sc->cert, (X509 *)parg); case SSL_CTRL_SET_CURRENT_CERT: if (larg == SSL_CERT_SET_SERVER) { const SSL_CIPHER *cipher; - if (!s->server) + if (!sc->server) return 0; - cipher = s->s3.tmp.new_cipher; + cipher = sc->s3.tmp.new_cipher; if (cipher == NULL) return 0; /* @@ -3590,22 +3621,22 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) */ if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) return 2; - if (s->s3.tmp.cert == NULL) + if (sc->s3.tmp.cert == NULL) return 0; - s->cert->key = s->s3.tmp.cert; + sc->cert->key = sc->s3.tmp.cert; return 1; } - return ssl_cert_set_current(s->cert, larg); + return ssl_cert_set_current(sc->cert, larg); case SSL_CTRL_GET_GROUPS: { uint16_t *clist; size_t clistlen; - if (!s->session) + if (!sc->session) return 0; - clist = s->ext.peer_supportedgroups; - clistlen = s->ext.peer_supportedgroups_len; + clist = sc->ext.peer_supportedgroups; + clistlen = sc->ext.peer_supportedgroups_len; if (parg) { size_t i; int *cptr = parg; @@ -3624,16 +3655,16 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } case SSL_CTRL_SET_GROUPS: - return tls1_set_groups(&s->ext.supportedgroups, - &s->ext.supportedgroups_len, parg, larg); + return tls1_set_groups(&sc->ext.supportedgroups, + &sc->ext.supportedgroups_len, parg, larg); case SSL_CTRL_SET_GROUPS_LIST: - return tls1_set_groups_list(s->ctx, &s->ext.supportedgroups, - &s->ext.supportedgroups_len, parg); + return tls1_set_groups_list(s->ctx, &sc->ext.supportedgroups, + &sc->ext.supportedgroups_len, parg); case SSL_CTRL_GET_SHARED_GROUP: { - uint16_t id = tls1_shared_group(s, larg); + uint16_t id = tls1_shared_group(sc, larg); if (larg != -1) return tls1_group_id2nid(id, 1); @@ -3643,82 +3674,82 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) { unsigned int id; - if (SSL_IS_TLS13(s) && s->s3.did_kex) - id = s->s3.group_id; + if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + id = sc->s3.group_id; else - id = s->session->kex_group; + id = sc->session->kex_group; ret = tls1_group_id2nid(id, 1); break; } case SSL_CTRL_SET_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 0); + return tls1_set_sigalgs(sc->cert, parg, larg, 0); case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 0); + return tls1_set_sigalgs_list(sc->cert, parg, 0); case SSL_CTRL_SET_CLIENT_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 1); + return tls1_set_sigalgs(sc->cert, parg, larg, 1); case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 1); + return tls1_set_sigalgs_list(sc->cert, parg, 1); case SSL_CTRL_GET_CLIENT_CERT_TYPES: { const unsigned char **pctype = parg; - if (s->server || !s->s3.tmp.cert_req) + if (sc->server || !sc->s3.tmp.cert_req) return 0; if (pctype) - *pctype = s->s3.tmp.ctype; - return s->s3.tmp.ctype_len; + *pctype = sc->s3.tmp.ctype; + return sc->s3.tmp.ctype_len; } case SSL_CTRL_SET_CLIENT_CERT_TYPES: - if (!s->server) + if (!sc->server) return 0; - return ssl3_set_req_cert_type(s->cert, parg, larg); + return ssl3_set_req_cert_type(sc->cert, parg, larg); case SSL_CTRL_BUILD_CERT_CHAIN: - return ssl_build_cert_chain(s, NULL, larg); + return ssl_build_cert_chain(sc, NULL, larg); case SSL_CTRL_SET_VERIFY_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 0, larg); + return ssl_cert_set_cert_store(sc->cert, parg, 0, larg); case SSL_CTRL_SET_CHAIN_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 1, larg); + return ssl_cert_set_cert_store(sc->cert, parg, 1, larg); case SSL_CTRL_GET_VERIFY_CERT_STORE: - return ssl_cert_get_cert_store(s->cert, parg, 0); + return ssl_cert_get_cert_store(sc->cert, parg, 0); case SSL_CTRL_GET_CHAIN_CERT_STORE: - return ssl_cert_get_cert_store(s->cert, parg, 1); + return ssl_cert_get_cert_store(sc->cert, parg, 1); case SSL_CTRL_GET_PEER_SIGNATURE_NID: - if (s->s3.tmp.peer_sigalg == NULL) + if (sc->s3.tmp.peer_sigalg == NULL) return 0; - *(int *)parg = s->s3.tmp.peer_sigalg->hash; + *(int *)parg = sc->s3.tmp.peer_sigalg->hash; return 1; case SSL_CTRL_GET_SIGNATURE_NID: - if (s->s3.tmp.sigalg == NULL) + if (sc->s3.tmp.sigalg == NULL) return 0; - *(int *)parg = s->s3.tmp.sigalg->hash; + *(int *)parg = sc->s3.tmp.sigalg->hash; return 1; case SSL_CTRL_GET_PEER_TMP_KEY: - if (s->session == NULL || s->s3.peer_tmp == NULL) { + if (sc->session == NULL || sc->s3.peer_tmp == NULL) { return 0; } else { - EVP_PKEY_up_ref(s->s3.peer_tmp); - *(EVP_PKEY **)parg = s->s3.peer_tmp; + EVP_PKEY_up_ref(sc->s3.peer_tmp); + *(EVP_PKEY **)parg = sc->s3.peer_tmp; return 1; } case SSL_CTRL_GET_TMP_KEY: - if (s->session == NULL || s->s3.tmp.pkey == NULL) { + if (sc->session == NULL || sc->s3.tmp.pkey == NULL) { return 0; } else { - EVP_PKEY_up_ref(s->s3.tmp.pkey); - *(EVP_PKEY **)parg = s->s3.tmp.pkey; + EVP_PKEY_up_ref(sc->s3.tmp.pkey); + *(EVP_PKEY **)parg = sc->s3.tmp.pkey; return 1; } @@ -3726,12 +3757,24 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) { const unsigned char **pformat = parg; - if (s->ext.peer_ecpointformats == NULL) + if (sc->ext.peer_ecpointformats == NULL) return 0; - *pformat = s->ext.peer_ecpointformats; - return (int)s->ext.peer_ecpointformats_len; + *pformat = sc->ext.peer_ecpointformats; + return (int)sc->ext.peer_ecpointformats_len; + } + + case SSL_CTRL_GET_IANA_GROUPS: + { + if (parg != NULL) { + *(uint16_t **)parg = (uint16_t *)sc->ext.peer_supportedgroups; + } + return (int)sc->ext.peer_supportedgroups_len; } + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + sc->msg_callback_arg = parg; + return 1; + default: break; } @@ -3741,24 +3784,32 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) { int ret = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return ret; switch (cmd) { #if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH_CB: - s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + sc->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; ret = 1; break; #endif case SSL_CTRL_SET_TLSEXT_DEBUG_CB: - s->ext.debug_cb = (void (*)(SSL *, int, int, - const unsigned char *, int, void *))fp; + sc->ext.debug_cb = (void (*)(SSL *, int, int, + const unsigned char *, int, void *))fp; ret = 1; break; case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB: - s->not_resumable_session_cb = (int (*)(SSL *, int))fp; + sc->not_resumable_session_cb = (int (*)(SSL *, int))fp; ret = 1; break; + + case SSL_CTRL_SET_MSG_CALLBACK: + sc->msg_callback = (ossl_msg_cb)fp; + return 1; default: break; } @@ -3778,7 +3829,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) } pkdh = ssl_dh_to_pkey(parg); if (pkdh == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_DH_LIB); return 0; } if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkdh)) { @@ -3947,12 +3998,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_EXTRA_CHAIN_CERT: if (ctx->extra_certs == NULL) { if ((ctx->extra_certs = sk_X509_new_null()) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return 0; } } if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return 0; } break; @@ -3965,7 +4016,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) break; case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: - sk_X509_pop_free(ctx->extra_certs, X509_free); + OSSL_STACK_OF_X509_free(ctx->extra_certs); ctx->extra_certs = NULL; break; @@ -4018,9 +4069,9 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) # ifndef OPENSSL_NO_DEPRECATED_3_0 case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: ctx->ext.ticket_key_cb = (int (*)(SSL *, unsigned char *, - unsigned char *, - EVP_CIPHER_CTX *, - HMAC_CTX *, int))fp; + unsigned char *, + EVP_CIPHER_CTX *, + HMAC_CTX *, int))fp; break; #endif @@ -4127,7 +4178,7 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) * * Returns the selected cipher or NULL when no common ciphers. */ -const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *srvr) { const SSL_CIPHER *c, *ret = NULL; @@ -4211,9 +4262,9 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, allow = srvr; } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { #ifndef OPENSSL_NO_PSK - int j; + size_t j; /* * If we allow "old" style PSK callbacks, and we have no certificate (so @@ -4223,8 +4274,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, * that. */ if (s->psk_server_callback != NULL) { - for (j = 0; j < SSL_PKEY_NUM && !ssl_has_cert(s, j); j++); - if (j == SSL_PKEY_NUM) { + for (j = 0; j < s->ssl_pkey_num && !ssl_has_cert(s, j); j++); + if (j == s->ssl_pkey_num) { /* There are no certificates */ prefer_sha256 = 1; } @@ -4239,10 +4290,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, c = sk_SSL_CIPHER_value(prio, i); /* Skip ciphers not supported by the protocol version */ - if (!SSL_IS_DTLS(s) && + if (!SSL_CONNECTION_IS_DTLS(s) && ((s->version < c->min_tls) || (s->version > c->max_tls))) continue; - if (SSL_IS_DTLS(s) && + if (SSL_CONNECTION_IS_DTLS(s) && (DTLS_VERSION_LT(s->version, c->min_dtls) || DTLS_VERSION_GT(s->version, c->max_dtls))) continue; @@ -4251,7 +4302,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, * Since TLS 1.3 ciphersuites can be used with any auth or * key exchange scheme skip tests. */ - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { mask_k = s->s3.tmp.mask_k; mask_a = s->s3.tmp.mask_a; #ifndef OPENSSL_NO_SRP @@ -4301,7 +4352,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (prefer_sha256) { const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); - const EVP_MD *md = ssl_md(s->ctx, tmp->algorithm2); + const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), + tmp->algorithm2); if (md != NULL && EVP_MD_is_a(md, OSSL_DIGEST_NAME_SHA2_256)) { @@ -4322,7 +4374,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, return ret; } -int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt) +int ssl3_get_req_cert_type(SSL_CONNECTION *s, WPACKET *pkt) { uint32_t alg_k, alg_a = 0; @@ -4392,26 +4444,30 @@ static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len) int ssl3_shutdown(SSL *s) { int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; /* * Don't do anything much if we have not done the handshake or we don't * want to send messages :-) */ - if (s->quiet_shutdown || SSL_in_before(s)) { - s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + if (sc->quiet_shutdown || SSL_in_before(s)) { + sc->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); return 1; } - if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { - s->shutdown |= SSL_SENT_SHUTDOWN; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); + if (!(sc->shutdown & SSL_SENT_SHUTDOWN)) { + sc->shutdown |= SSL_SENT_SHUTDOWN; + ssl3_send_alert(sc, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); /* * our shutdown alert has been sent now, and if it still needs to be - * written, s->s3.alert_dispatch will be true + * written, s->s3.alert_dispatch will be > 0 */ - if (s->s3.alert_dispatch) + if (sc->s3.alert_dispatch > 0) return -1; /* return WANT_WRITE */ - } else if (s->s3.alert_dispatch) { + } else if (sc->s3.alert_dispatch > 0) { /* resend it if not sent */ ret = s->method->ssl_dispatch_alert(s); if (ret == -1) { @@ -4422,19 +4478,19 @@ int ssl3_shutdown(SSL *s) */ return ret; } - } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + } else if (!(sc->shutdown & SSL_RECEIVED_SHUTDOWN)) { size_t readbytes; /* * If we are waiting for a close from our peer, we are closed */ s->method->ssl_read_bytes(s, 0, NULL, NULL, 0, 0, &readbytes); - if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + if (!(sc->shutdown & SSL_RECEIVED_SHUTDOWN)) { return -1; /* return WANT_READ */ } } - if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && - !s->s3.alert_dispatch) + if ((sc->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) + && sc->s3.alert_dispatch == SSL_ALERT_DISPATCH_NONE) return 1; else return 0; @@ -4442,8 +4498,13 @@ int ssl3_shutdown(SSL *s) int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + clear_sys_error(); - if (s->s3.renegotiate) + if (sc->s3.renegotiate) ssl3_renegotiate_check(s, 0); return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, @@ -4454,15 +4515,19 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek, size_t *readbytes) { int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; clear_sys_error(); - if (s->s3.renegotiate) + if (sc->s3.renegotiate) ssl3_renegotiate_check(s, 0); - s->s3.in_read_app_data = 1; + sc->s3.in_read_app_data = 1; ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len, peek, readbytes); - if ((ret == -1) && (s->s3.in_read_app_data == 2)) { + if ((ret == -1) && (sc->s3.in_read_app_data == 2)) { /* * ssl3_read_bytes decided to call s->handshake_func, which called * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes @@ -4470,13 +4535,13 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek, * makes sense here; so disable handshake processing and try to read * application data again. */ - ossl_statem_set_in_handshake(s, 1); + ossl_statem_set_in_handshake(sc, 1); ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len, peek, readbytes); - ossl_statem_set_in_handshake(s, 0); + ossl_statem_set_in_handshake(sc, 0); } else - s->s3.in_read_app_data = 0; + sc->s3.in_read_app_data = 0; return ret; } @@ -4493,10 +4558,15 @@ int ssl3_peek(SSL *s, void *buf, size_t len, size_t *readbytes) int ssl3_renegotiate(SSL *s) { - if (s->handshake_func == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + if (sc->handshake_func == NULL) return 1; - s->s3.renegotiate = 1; + sc->s3.renegotiate = 1; return 1; } @@ -4511,20 +4581,24 @@ int ssl3_renegotiate(SSL *s) int ssl3_renegotiate_check(SSL *s, int initok) { int ret = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; - if (s->s3.renegotiate) { - if (!RECORD_LAYER_read_pending(&s->rlayer) - && !RECORD_LAYER_write_pending(&s->rlayer) + if (sc->s3.renegotiate) { + if (!RECORD_LAYER_read_pending(&sc->rlayer) + && !RECORD_LAYER_write_pending(&sc->rlayer) && (initok || !SSL_in_init(s))) { /* * if we are the server, and we have sent a 'RENEGOTIATE' * message, we need to set the state machine into the renegotiate * state. */ - ossl_statem_set_renegotiate(s); - s->s3.renegotiate = 0; - s->s3.num_renegotiations++; - s->s3.total_renegotiations++; + ossl_statem_set_renegotiate(sc); + sc->s3.renegotiate = 0; + sc->s3.num_renegotiations++; + sc->s3.total_renegotiations++; ret = 1; } } @@ -4537,13 +4611,15 @@ int ssl3_renegotiate_check(SSL *s, int initok) * * If PSK and using SHA384 for TLS < 1.2 switch to default. */ -long ssl_get_algorithm2(SSL *s) +long ssl_get_algorithm2(SSL_CONNECTION *s) { long alg2; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + if (s->s3.tmp.new_cipher == NULL) return -1; alg2 = s->s3.tmp.new_cipher->algorithm2; - if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) { + if (ssl->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) { if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; } else if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK) { @@ -4557,7 +4633,8 @@ long ssl_get_algorithm2(SSL *s) * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on * failure, 1 on success. */ -int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, +int ssl_fill_hello_random(SSL_CONNECTION *s, int server, + unsigned char *result, size_t len, DOWNGRADE dgrd) { int send_time = 0, ret; @@ -4573,9 +4650,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, unsigned char *p = result; l2n(Time, p); - ret = RAND_bytes_ex(s->ctx->libctx, p, len - 4, 0); + ret = RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, p, len - 4, 0); } else { - ret = RAND_bytes_ex(s->ctx->libctx, result, len, 0); + ret = RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, result, len, 0); } if (ret > 0) { @@ -4593,11 +4670,12 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, return ret; } -int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, - int free_pms) +int ssl_generate_master_secret(SSL_CONNECTION *s, unsigned char *pms, + size_t pmslen, int free_pms) { unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; int ret = 0; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (alg_k & SSL_PSK) { #ifndef OPENSSL_NO_PSK @@ -4628,7 +4706,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, OPENSSL_clear_free(s->s3.tmp.psk, psklen); s->s3.tmp.psk = NULL; s->s3.tmp.psklen = 0; - if (!s->method->ssl3_enc->generate_master_secret(s, + if (!ssl->method->ssl3_enc->generate_master_secret(s, s->session->master_key, pskpms, pskpmslen, &s->session->master_key_length)) { OPENSSL_clear_free(pskpms, pskpmslen); @@ -4641,7 +4719,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, goto err; #endif } else { - if (!s->method->ssl3_enc->generate_master_secret(s, + if (!ssl->method->ssl3_enc->generate_master_secret(s, s->session->master_key, pms, pmslen, &s->session->master_key_length)) { /* SSLfatal() already called */ @@ -4665,14 +4743,15 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, } /* Generate a private key from parameters */ -EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm) +EVP_PKEY *ssl_generate_pkey(SSL_CONNECTION *s, EVP_PKEY *pm) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (pm == NULL) return NULL; - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pm, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pm, sctx->propq); if (pctx == NULL) goto err; if (EVP_PKEY_keygen_init(pctx) <= 0) @@ -4688,9 +4767,10 @@ EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm) } /* Generate a private key from a group ID */ -EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) +EVP_PKEY *ssl_generate_pkey_group(SSL_CONNECTION *s, uint16_t id) { - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(sctx, id); EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; @@ -4699,11 +4779,11 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) goto err; } - pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm, - s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, ginf->algorithm, + sctx->propq); if (pctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (EVP_PKEY_keygen_init(pctx) <= 0) { @@ -4728,17 +4808,18 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) /* * Generate parameters from a group ID */ -EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id) +EVP_PKEY *ssl_generate_param_group(SSL_CONNECTION *s, uint16_t id) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id); + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(sctx, id); if (ginf == NULL) goto err; - pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm, - s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, ginf->algorithm, + sctx->propq); if (pctx == NULL) goto err; @@ -4759,12 +4840,12 @@ EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id) } /* Generate secrets from pms */ -int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen) +int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen) { int rv = 0; /* SSLfatal() called as appropriate in the below functions */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * If we are resuming then we already generated the early secret * when we created the ClientHello, so don't recreate it. @@ -4785,19 +4866,20 @@ int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen) } /* Derive secrets for ECDH/DH */ -int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) +int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) { int rv = 0; unsigned char *pms = NULL; size_t pmslen = 0; EVP_PKEY_CTX *pctx; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (privkey == NULL || pubkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, privkey, sctx->propq); if (EVP_PKEY_derive_init(pctx) <= 0 || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0 @@ -4806,12 +4888,12 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) goto err; } - if (SSL_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH")) + if (SSL_CONNECTION_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH")) EVP_PKEY_CTX_set_dh_pad(pctx, 1); pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } @@ -4838,7 +4920,7 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) } /* Decapsulate secrets for KEM */ -int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, +int ssl_decapsulate(SSL_CONNECTION *s, EVP_PKEY *privkey, const unsigned char *ct, size_t ctlen, int gensecret) { @@ -4846,13 +4928,14 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, unsigned char *pms = NULL; size_t pmslen = 0; EVP_PKEY_CTX *pctx; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (privkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, privkey, sctx->propq); if (EVP_PKEY_decapsulate_init(pctx, NULL) <= 0 || EVP_PKEY_decapsulate(pctx, NULL, &pmslen, ct, ctlen) <= 0) { @@ -4862,7 +4945,7 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } @@ -4888,7 +4971,7 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, return rv; } -int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, +int ssl_encapsulate(SSL_CONNECTION *s, EVP_PKEY *pubkey, unsigned char **ctp, size_t *ctlenp, int gensecret) { @@ -4896,13 +4979,14 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, unsigned char *pms = NULL, *ct = NULL; size_t pmslen = 0, ctlen = 0; EVP_PKEY_CTX *pctx; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (pubkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pubkey, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pubkey, sctx->propq); if (EVP_PKEY_encapsulate_init(pctx, NULL) <= 0 || EVP_PKEY_encapsulate(pctx, NULL, &ctlen, NULL, &pmslen) <= 0 @@ -4914,7 +4998,7 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, pms = OPENSSL_malloc(pmslen); ct = OPENSSL_malloc(ctlen); if (pms == NULL || ct == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } @@ -4948,6 +5032,22 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, return rv; } +const char *SSL_get0_group_name(SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + unsigned int id; + + if (sc == NULL) + return NULL; + + if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + id = sc->s3.group_id; + else + id = sc->session->kex_group; + + return tls1_group_id2name(s->ctx, id); +} + const char *SSL_group_to_name(SSL *s, int nid) { int group_id = 0; const TLS_GROUP_INFO *cinf = NULL; diff --git a/ssl/s3_msg.c b/ssl/s3_msg.c index c0f0dbc17d..3fcea15e27 100644 --- a/ssl/s3_msg.c +++ b/ssl/s3_msg.c @@ -9,9 +9,10 @@ #include "ssl_local.h" -int ssl3_do_change_cipher_spec(SSL *s) +int ssl3_do_change_cipher_spec(SSL_CONNECTION *s) { int i; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->server) i = SSL3_CHANGE_CIPHER_SERVER_READ; @@ -26,13 +27,13 @@ int ssl3_do_change_cipher_spec(SSL *s) } s->session->cipher = s->s3.tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) { + if (!ssl->method->ssl3_enc->setup_key_block(s)) { /* SSLfatal() already called */ return 0; } } - if (!s->method->ssl3_enc->change_cipher_state(s, i)) { + if (!ssl->method->ssl3_enc->change_cipher_state(s, i)) { /* SSLfatal() already called */ return 0; } @@ -40,13 +41,15 @@ int ssl3_do_change_cipher_spec(SSL *s) return 1; } -int ssl3_send_alert(SSL *s, int level, int desc) +int ssl3_send_alert(SSL_CONNECTION *s, int level, int desc) { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + /* Map tls/ssl alert value to correct one */ - if (SSL_TREAT_AS_TLS13(s)) + if (SSL_CONNECTION_TREAT_AS_TLS13(s)) desc = tls13_alert_code(desc); else - desc = s->method->ssl3_enc->alert_value(desc); + desc = ssl->method->ssl3_enc->alert_value(desc); if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have * protocol_version alerts */ @@ -58,12 +61,12 @@ int ssl3_send_alert(SSL *s, int level, int desc) if ((level == SSL3_AL_FATAL) && (s->session != NULL)) SSL_CTX_remove_session(s->session_ctx, s->session); - s->s3.alert_dispatch = 1; + s->s3.alert_dispatch = SSL_ALERT_DISPATCH_PENDING; s->s3.send_alert[0] = level; s->s3.send_alert[1] = desc; if (!RECORD_LAYER_write_pending(&s->rlayer)) { /* data still being written out? */ - return s->method->ssl_dispatch_alert(s); + return ssl->method->ssl_dispatch_alert(ssl); } /* * else data is still being written out, we will get written some time in @@ -75,34 +78,80 @@ int ssl3_send_alert(SSL *s, int level, int desc) int ssl3_dispatch_alert(SSL *s) { int i, j; - size_t alertlen; void (*cb) (const SSL *ssl, int type, int val) = NULL; - size_t written; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + OSSL_RECORD_TEMPLATE templ; + + if (sc == NULL) + return -1; + + if (sc->rlayer.wrlmethod == NULL) { + /* No write record layer so we can't sent and alert. We just ignore it */ + sc->s3.alert_dispatch = SSL_ALERT_DISPATCH_NONE; + return 1; + } + + templ.type = SSL3_RT_ALERT; + templ.version = (sc->version == TLS1_3_VERSION) ? TLS1_2_VERSION + : sc->version; + if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO + && !sc->renegotiate + && TLS1_get_version(s) > TLS1_VERSION + && sc->hello_retry_request == SSL_HRR_NONE) { + templ.version = TLS1_VERSION; + } + templ.buf = &sc->s3.send_alert[0]; + templ.buflen = 2; + + if (RECORD_LAYER_write_pending(&sc->rlayer)) { + if (sc->s3.alert_dispatch != SSL_ALERT_DISPATCH_RETRY) { + /* + * We have a write pending but it wasn't from a previous call to + * this function! Can we ever get here? Maybe via API misuse?? + * Give up. + */ + sc->s3.alert_dispatch = SSL_ALERT_DISPATCH_NONE; + return -1; + } + /* Retry what we've already got pending */ + i = HANDLE_RLAYER_WRITE_RETURN(sc, + sc->rlayer.wrlmethod->retry_write_records(sc->rlayer.wrl)); + if (i <= 0) { + /* Could be NBIO. Keep alert_dispatch as SSL_ALERT_DISPATCH_RETRY */ + return -1; + } + sc->rlayer.wpend_tot = 0; + sc->s3.alert_dispatch = SSL_ALERT_DISPATCH_NONE; + return 1; + } + + i = HANDLE_RLAYER_WRITE_RETURN(sc, + sc->rlayer.wrlmethod->write_records(sc->rlayer.wrl, &templ, 1)); - s->s3.alert_dispatch = 0; - alertlen = 2; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3.send_alert[0], &alertlen, 1, 0, - &written); if (i <= 0) { - s->s3.alert_dispatch = 1; + sc->s3.alert_dispatch = SSL_ALERT_DISPATCH_RETRY; + sc->rlayer.wpend_tot = templ.buflen; + sc->rlayer.wpend_type = templ.type; + sc->rlayer.wpend_buf = templ.buf; } else { /* * Alert sent to BIO - now flush. If the message does not get sent due * to non-blocking IO, we will not worry too much. */ - (void)BIO_flush(s->wbio); + (void)BIO_flush(sc->wbio); + sc->s3.alert_dispatch = SSL_ALERT_DISPATCH_NONE; - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3.send_alert, - 2, s, s->msg_callback_arg); + if (sc->msg_callback) + sc->msg_callback(1, sc->version, SSL3_RT_ALERT, sc->s3.send_alert, + 2, s, sc->msg_callback_arg); - if (s->info_callback != NULL) - cb = s->info_callback; + if (sc->info_callback != NULL) + cb = sc->info_callback; else if (s->ctx->info_callback != NULL) cb = s->ctx->info_callback; if (cb != NULL) { - j = (s->s3.send_alert[0] << 8) | s->s3.send_alert[1]; + j = (sc->s3.send_alert[0] << 8) | sc->s3.send_alert[1]; cb(s, SSL_CB_WRITE_ALERT, j); } } diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 3503fdc210..9964a8c1ee 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -12,6 +12,7 @@ #include #include "ssl_local.h" #include +#include #include typedef struct { @@ -44,6 +45,7 @@ typedef struct { uint32_t tlsext_max_fragment_len_mode; ASN1_OCTET_STRING *ticket_appdata; uint32_t kex_group; + ASN1_OCTET_STRING *peer_rpk; } SSL_SESSION_ASN1; ASN1_SEQUENCE(SSL_SESSION_ASN1) = { @@ -75,7 +77,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { ASN1_EXP_OPT(SSL_SESSION_ASN1, alpn_selected, ASN1_OCTET_STRING, 16), ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, tlsext_max_fragment_len_mode, ZUINT32, 17), ASN1_EXP_OPT(SSL_SESSION_ASN1, ticket_appdata, ASN1_OCTET_STRING, 18), - ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, kex_group, UINT32, 19) + ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, kex_group, UINT32, 19), + ASN1_EXP_OPT(SSL_SESSION_ASN1, peer_rpk, ASN1_OCTET_STRING, 20) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) @@ -125,8 +128,10 @@ int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp) #endif ASN1_OCTET_STRING alpn_selected; ASN1_OCTET_STRING ticket_appdata; + ASN1_OCTET_STRING peer_rpk; long l; + int ret; if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) return 0; @@ -163,12 +168,20 @@ int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp) ssl_session_oinit(&as.session_id_context, &sid_ctx, in->sid_ctx, in->sid_ctx_length); - as.time = (int64_t)in->time; - as.timeout = (int64_t)in->timeout; + as.time = (int64_t)ossl_time_to_time_t(in->time); + as.timeout = (int64_t)ossl_time2seconds(in->timeout); as.verify_result = in->verify_result; as.peer = in->peer; + as.peer_rpk = NULL; + peer_rpk.data = NULL; + if (in->peer_rpk != NULL) { + peer_rpk.length = i2d_PUBKEY(in->peer_rpk, &peer_rpk.data); + if (peer_rpk.length > 0 && peer_rpk.data != NULL) + as.peer_rpk = &peer_rpk; + } + ssl_session_sinit(&as.tlsext_hostname, &tlsext_hostname, in->ext.hostname); if (in->ext.tick) { @@ -204,8 +217,9 @@ int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp) ssl_session_oinit(&as.ticket_appdata, &ticket_appdata, in->ticket_appdata, in->ticket_appdata_len); - return i2d_SSL_SESSION_ASN1(&as, pp); - + ret = i2d_SSL_SESSION_ASN1(&as, pp); + OPENSSL_free(peer_rpk.data); + return ret; } /* Utility functions for d2i_SSL_SESSION */ @@ -242,6 +256,12 @@ static int ssl_session_memcpy(unsigned char *dst, size_t *pdstlen, SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length) +{ + return d2i_SSL_SESSION_ex(a, pp, length, NULL, NULL); +} +SSL_SESSION *d2i_SSL_SESSION_ex(SSL_SESSION **a, const unsigned char **pp, + long length, OSSL_LIB_CTX *libctx, + const char *propq) { long id; size_t tmpl; @@ -302,20 +322,33 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ret->master_key_length = tmpl; if (as->time != 0) - ret->time = (time_t)as->time; + ret->time = ossl_time_from_time_t(as->time); else - ret->time = time(NULL); + ret->time = ossl_time_now(); if (as->timeout != 0) - ret->timeout = (time_t)as->timeout; + ret->timeout = ossl_seconds2time(as->timeout); else - ret->timeout = 3; + ret->timeout = ossl_seconds2time(3); ssl_session_calculate_timeout(ret); X509_free(ret->peer); ret->peer = as->peer; as->peer = NULL; + EVP_PKEY_free(ret->peer_rpk); + ret->peer_rpk = NULL; + if (as->peer_rpk != NULL) { + const unsigned char *data = as->peer_rpk->data; + + /* + * |data| is incremented; we don't want to lose original ptr + */ + ret->peer_rpk = d2i_PUBKEY_ex(NULL, &data, as->peer_rpk->length, libctx, propq); + if (ret->peer_rpk == NULL) + goto err; + } + if (!ssl_session_memcpy(ret->sid_ctx, &ret->sid_ctx_length, as->session_id_context, SSL_MAX_SID_CTX_LENGTH)) goto err; diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 54ae159c9d..126be668fd 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -58,23 +58,31 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void) return ssl_x509_store_ctx_idx; } -CERT *ssl_cert_new(void) +CERT *ssl_cert_new(size_t ssl_pkey_num) { - CERT *ret = OPENSSL_zalloc(sizeof(*ret)); + CERT *ret = NULL; - if (ret == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + /* Should never happen */ + if (!ossl_assert(ssl_pkey_num >= SSL_PKEY_NUM)) + return NULL; + + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + + ret->ssl_pkey_num = ssl_pkey_num; + ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY)); + if (ret->pkeys == NULL) { + OPENSSL_free(ret); return NULL; } ret->key = &(ret->pkeys[SSL_PKEY_RSA]); - ret->references = 1; ret->sec_cb = ssl_security_default_callback; ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL; ret->sec_ex = NULL; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + OPENSSL_free(ret->pkeys); OPENSSL_free(ret); return NULL; } @@ -85,18 +93,24 @@ CERT *ssl_cert_new(void) CERT *ssl_cert_dup(CERT *cert) { CERT *ret = OPENSSL_zalloc(sizeof(*ret)); - int i; + size_t i; +#ifndef OPENSSL_NO_COMP_ALG + int j; +#endif - if (ret == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ret == NULL) + return NULL; + + ret->ssl_pkey_num = cert->ssl_pkey_num; + ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY)); + if (ret->pkeys == NULL) { + OPENSSL_free(ret); return NULL; } - ret->references = 1; ret->key = &ret->pkeys[cert->key - cert->pkeys]; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { + OPENSSL_free(ret->pkeys); OPENSSL_free(ret); return NULL; } @@ -109,9 +123,10 @@ CERT *ssl_cert_dup(CERT *cert) ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; - for (i = 0; i < SSL_PKEY_NUM; i++) { + for (i = 0; i < ret->ssl_pkey_num; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; + if (cpk->x509 != NULL) { rpk->x509 = cpk->x509; X509_up_ref(rpk->x509); @@ -125,22 +140,26 @@ CERT *ssl_cert_dup(CERT *cert) if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; } } - if (cert->pkeys[i].serverinfo != NULL) { + if (cpk->serverinfo != NULL) { /* Just copy everything. */ - ret->pkeys[i].serverinfo = - OPENSSL_malloc(cert->pkeys[i].serverinfo_length); - if (ret->pkeys[i].serverinfo == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + rpk->serverinfo = OPENSSL_memdup(cpk->serverinfo, cpk->serverinfo_length); + if (rpk->serverinfo == NULL) goto err; + rpk->serverinfo_length = cpk->serverinfo_length; + } +#ifndef OPENSSL_NO_COMP_ALG + for (j = TLSEXT_comp_cert_none; j < TLSEXT_comp_cert_limit; j++) { + if (cpk->comp_cert[j] != NULL) { + if (!OSSL_COMP_CERT_up_ref(cpk->comp_cert[j])) + goto err; + rpk->comp_cert[j] = cpk->comp_cert[j]; } - ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; - memcpy(ret->pkeys[i].serverinfo, - cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); } +#endif } /* Configured sigalgs copied across */ @@ -213,20 +232,31 @@ CERT *ssl_cert_dup(CERT *cert) void ssl_cert_clear_certs(CERT *c) { - int i; + size_t i; +#ifndef OPENSSL_NO_COMP_ALG + int j; +#endif + if (c == NULL) return; - for (i = 0; i < SSL_PKEY_NUM; i++) { + for (i = 0; i < c->ssl_pkey_num; i++) { CERT_PKEY *cpk = c->pkeys + i; X509_free(cpk->x509); cpk->x509 = NULL; EVP_PKEY_free(cpk->privatekey); cpk->privatekey = NULL; - sk_X509_pop_free(cpk->chain, X509_free); + OSSL_STACK_OF_X509_free(cpk->chain); cpk->chain = NULL; OPENSSL_free(cpk->serverinfo); cpk->serverinfo = NULL; cpk->serverinfo_length = 0; +#ifndef OPENSSL_NO_COMP_ALG + for (j = 0; j < TLSEXT_comp_cert_limit; j++) { + OSSL_COMP_CERT_free(cpk->comp_cert[j]); + cpk->comp_cert[j] = NULL; + cpk->cert_comp_used = 0; + } +#endif } } @@ -236,7 +266,7 @@ void ssl_cert_free(CERT *c) if (c == NULL) return; - CRYPTO_DOWN_REF(&c->references, &i, c->lock); + CRYPTO_DOWN_REF(&c->references, &i); REF_PRINT_COUNT("CERT", c); if (i > 0) return; @@ -254,11 +284,12 @@ void ssl_cert_free(CERT *c) #ifndef OPENSSL_NO_PSK OPENSSL_free(c->psk_identity_hint); #endif - CRYPTO_THREAD_lock_free(c->lock); + OPENSSL_free(c->pkeys); + CRYPTO_FREE_REF(&c->references); OPENSSL_free(c); } -int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) +int ssl_cert_set0_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain) { int i, r; CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key; @@ -274,30 +305,32 @@ int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) return 0; } } - sk_X509_pop_free(cpk->chain, X509_free); + OSSL_STACK_OF_X509_free(cpk->chain); cpk->chain = chain; return 1; } -int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) +int ssl_cert_set1_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain) { STACK_OF(X509) *dchain; + if (!chain) return ssl_cert_set0_chain(s, ctx, NULL); dchain = X509_chain_up_ref(chain); if (!dchain) return 0; if (!ssl_cert_set0_chain(s, ctx, dchain)) { - sk_X509_pop_free(dchain, X509_free); + OSSL_STACK_OF_X509_free(dchain); return 0; } return 1; } -int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) +int ssl_cert_add0_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x) { int r; CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key; + if (!cpk) return 0; r = ssl_security_cert(s, ctx, x, 0, 0); @@ -312,7 +345,7 @@ int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) return 1; } -int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) +int ssl_cert_add1_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x) { if (!ssl_cert_add0_chain_cert(s, ctx, x)) return 0; @@ -322,10 +355,11 @@ int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) int ssl_cert_select_current(CERT *c, X509 *x) { - int i; + size_t i; + if (x == NULL) return 0; - for (i = 0; i < SSL_PKEY_NUM; i++) { + for (i = 0; i < c->ssl_pkey_num; i++) { CERT_PKEY *cpk = c->pkeys + i; if (cpk->x509 == x && cpk->privatekey) { c->key = cpk; @@ -333,7 +367,7 @@ int ssl_cert_select_current(CERT *c, X509 *x) } } - for (i = 0; i < SSL_PKEY_NUM; i++) { + for (i = 0; i < c->ssl_pkey_num; i++) { CERT_PKEY *cpk = c->pkeys + i; if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { c->key = cpk; @@ -345,18 +379,19 @@ int ssl_cert_select_current(CERT *c, X509 *x) int ssl_cert_set_current(CERT *c, long op) { - int i, idx; + size_t i, idx; + if (!c) return 0; if (op == SSL_CERT_SET_FIRST) idx = 0; else if (op == SSL_CERT_SET_NEXT) { - idx = (int)(c->key - c->pkeys + 1); - if (idx >= SSL_PKEY_NUM) + idx = (size_t)(c->key - c->pkeys + 1); + if (idx >= c->ssl_pkey_num) return 0; } else return 0; - for (i = idx; i < SSL_PKEY_NUM; i++) { + for (i = idx; i < c->ssl_pkey_num; i++) { CERT_PKEY *cpk = c->pkeys + i; if (cpk->x509 && cpk->privatekey) { c->key = cpk; @@ -373,38 +408,52 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) } /* - * Verify a certificate chain + * Verify a certificate chain/raw public key * Return codes: * 1: Verify success * 0: Verify failure or error * -1: Retry required */ -int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) +static int ssl_verify_internal(SSL_CONNECTION *s, STACK_OF(X509) *sk, EVP_PKEY *rpk) { X509 *x; int i = 0; X509_STORE *verify_store; X509_STORE_CTX *ctx = NULL; X509_VERIFY_PARAM *param; + SSL_CTX *sctx; + + /* Something must be passed in */ + if ((sk == NULL || sk_X509_num(sk) == 0) && rpk == NULL) + return 0; - if ((sk == NULL) || (sk_X509_num(sk) == 0)) + /* Only one can be set */ + if (sk != NULL && rpk != NULL) return 0; + sctx = SSL_CONNECTION_GET_CTX(s); if (s->cert->verify_store) verify_store = s->cert->verify_store; else - verify_store = s->ctx->cert_store; + verify_store = sctx->cert_store; - ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, s->ctx->propq); + ctx = X509_STORE_CTX_new_ex(sctx->libctx, sctx->propq); if (ctx == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); return 0; } - x = sk_X509_value(sk, 0); - if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { - ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); - goto end; + if (sk != NULL) { + x = sk_X509_value(sk, 0); + if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); + goto end; + } + } else { + if (!X509_STORE_CTX_init_rpk(ctx, verify_store, rpk)) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); + goto end; + } } param = X509_STORE_CTX_get0_param(ctx); /* @@ -412,12 +461,13 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) * point, for now a single @SECLEVEL sets the same policy for TLS crypto * and PKI authentication. */ - X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s)); + X509_VERIFY_PARAM_set_auth_level(param, + SSL_get_security_level(SSL_CONNECTION_GET_SSL(s))); /* Set suite B flags if needed */ X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s)); - if (!X509_STORE_CTX_set_ex_data - (ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s)) { + if (!X509_STORE_CTX_set_ex_data(ctx, + SSL_get_ex_data_X509_STORE_CTX_idx(), s)) { goto end; } @@ -440,8 +490,8 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) if (s->verify_callback) X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); - if (s->ctx->app_verify_callback != NULL) { - i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg); + if (sctx->app_verify_callback != NULL) { + i = sctx->app_verify_callback(ctx, sctx->app_verify_arg); } else { i = X509_verify_cert(ctx); /* We treat an error in the same way as a failure to verify */ @@ -450,12 +500,13 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) } s->verify_result = X509_STORE_CTX_get_error(ctx); - sk_X509_pop_free(s->verified_chain, X509_free); + OSSL_STACK_OF_X509_free(s->verified_chain); s->verified_chain = NULL; - if (X509_STORE_CTX_get0_chain(ctx) != NULL) { + + if (sk != NULL && X509_STORE_CTX_get0_chain(ctx) != NULL) { s->verified_chain = X509_STORE_CTX_get1_chain(ctx); if (s->verified_chain == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); i = 0; } } @@ -468,6 +519,30 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) return i; } +/* + * Verify a raw public key + * Return codes: + * 1: Verify success + * 0: Verify failure or error + * -1: Retry required + */ +int ssl_verify_rpk(SSL_CONNECTION *s, EVP_PKEY *rpk) +{ + return ssl_verify_internal(s, NULL, rpk); +} + +/* + * Verify a certificate chain + * Return codes: + * 1: Verify success + * 0: Verify failure or error + * -1: Retry required + */ +int ssl_verify_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk) +{ + return ssl_verify_internal(s, sk, NULL); +} + static void set0_CA_list(STACK_OF(X509_NAME) **ca_list, STACK_OF(X509_NAME) *name_list) { @@ -484,13 +559,13 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) ret = sk_X509_NAME_new_reserve(NULL, num); if (ret == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return NULL; } for (i = 0; i < num; i++) { name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); if (name == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); sk_X509_NAME_pop_free(ret, X509_NAME_free); return NULL; } @@ -501,7 +576,12 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) { - set0_CA_list(&s->ca_names, name_list); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + set0_CA_list(&sc->ca_names, name_list); } void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) @@ -516,7 +596,12 @@ const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx) const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s) { - return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->ca_names != NULL ? sc->ca_names : s->ctx->ca_names; } void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) @@ -531,20 +616,35 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) { - set0_CA_list(&s->client_ca_names, name_list); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + set0_CA_list(&sc->client_ca_names, name_list); } const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s) { - return s->s3.tmp.peer_ca_names; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->s3.tmp.peer_ca_names; } STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) { - if (!s->server) - return s->s3.tmp.peer_ca_names; - return s->client_ca_names != NULL ? s->client_ca_names - : s->ctx->client_ca_names; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + if (!sc->server) + return sc->s3.tmp.peer_ca_names; + return sc->client_ca_names != NULL ? sc->client_ca_names + : s->ctx->client_ca_names; } static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) @@ -568,7 +668,12 @@ static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) int SSL_add1_to_CA_list(SSL *ssl, const X509 *x) { - return add_ca_name(&ssl->ca_names, x); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + return add_ca_name(&sc->ca_names, x); } int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) @@ -582,7 +687,12 @@ int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) */ int SSL_add_client_CA(SSL *ssl, X509 *x) { - return add_ca_name(&ssl->client_ca_names, x); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + return add_ca_name(&sc->client_ca_names, x); } int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) @@ -636,14 +746,18 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); OSSL_LIB_CTX *prev_libctx = NULL; - if ((name_hash == NULL) || (in == NULL)) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (name_hash == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + if (in == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_BIO_LIB); goto err; } x = X509_new_ex(libctx, propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; } if (BIO_read_filename(in, file) <= 0) @@ -657,7 +771,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } } @@ -713,7 +827,7 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, in = BIO_new(BIO_s_file()); if (in == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_BIO_LIB); goto err; } @@ -871,18 +985,18 @@ int SSL_add_store_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, } /* Build a certificate chain for current certificate */ -int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) +int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags) { - CERT *c = s ? s->cert : ctx->cert; + CERT *c = s != NULL ? s->cert : ctx->cert; CERT_PKEY *cpk = c->key; X509_STORE *chain_store = NULL; X509_STORE_CTX *xs_ctx = NULL; STACK_OF(X509) *chain = NULL, *untrusted = NULL; X509 *x; - SSL_CTX *real_ctx = (s == NULL) ? ctx : s->ctx; + SSL_CTX *real_ctx = (s == NULL) ? ctx : SSL_CONNECTION_GET_CTX(s); int i, rv = 0; - if (!cpk->x509) { + if (cpk->x509 == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET); goto err; } @@ -900,12 +1014,10 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) if (!X509_STORE_add_cert(chain_store, cpk->x509)) goto err; } else { - if (c->chain_store) + if (c->chain_store != NULL) chain_store = c->chain_store; - else if (s) - chain_store = s->ctx->cert_store; else - chain_store = ctx->cert_store; + chain_store = real_ctx->cert_store; if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) untrusted = cpk->chain; @@ -913,7 +1025,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) xs_ctx = X509_STORE_CTX_new_ex(real_ctx->libctx, real_ctx->propq); if (xs_ctx == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; } if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) { @@ -962,12 +1074,12 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) rv = ssl_security_cert(s, ctx, x, 0, 0); if (rv != 1) { ERR_raise(ERR_LIB_SSL, rv); - sk_X509_pop_free(chain, X509_free); + OSSL_STACK_OF_X509_free(chain); rv = 0; goto err; } } - sk_X509_pop_free(cpk->chain, X509_free); + OSSL_STACK_OF_X509_free(cpk->chain); cpk->chain = chain; if (rv == 0) rv = 1; @@ -1030,6 +1142,7 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, void *ex) { int level, minbits, pfs_mask; + const SSL_CONNECTION *sc; minbits = ssl_get_security_level_bits(s, ctx, &level); @@ -1060,9 +1173,6 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, /* SHA1 HMAC is 160 bits of security */ if (minbits > 160 && c->algorithm_mac & SSL_SHA1) return 0; - /* Level 2: no RC4 */ - if (level >= 2 && c->algorithm_enc == SSL_RC4) - return 0; /* Level 3: forward secure ciphersuites only */ pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK; if (level >= 3 && c->min_tls != TLS1_3_VERSION && @@ -1071,7 +1181,9 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, break; } case SSL_SECOP_VERSION: - if (!SSL_IS_DTLS(s)) { + if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL) + return 0; + if (!SSL_CONNECTION_IS_DTLS(sc)) { /* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */ if (nid <= TLS1_1_VERSION && level > 0) return 0; @@ -1097,9 +1209,10 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, return 1; } -int ssl_security(const SSL *s, int op, int bits, int nid, void *other) +int ssl_security(const SSL_CONNECTION *s, int op, int bits, int nid, void *other) { - return s->cert->sec_cb(s, NULL, op, bits, nid, other, s->cert->sec_ex); + return s->cert->sec_cb(SSL_CONNECTION_GET_SSL(s), NULL, op, bits, nid, + other, s->cert->sec_ex); } int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other) @@ -1108,7 +1221,7 @@ int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other) ctx->cert->sec_ex); } -int ssl_cert_lookup_by_nid(int nid, size_t *pidx) +int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx) { size_t i; @@ -1118,16 +1231,22 @@ int ssl_cert_lookup_by_nid(int nid, size_t *pidx) return 1; } } - + for (i = 0; i < ctx->sigalg_list_len; i++) { + if (ctx->ssl_cert_info[i].nid == nid) { + *pidx = SSL_PKEY_NUM + i; + return 1; + } + } return 0; } -const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) +SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) { size_t i; + /* check classic pk types */ for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { - const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; + SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { @@ -1136,13 +1255,26 @@ const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) return tmp_lu; } } + /* check provider-loaded pk types */ + for (i = 0; ctx->sigalg_list_len; i++) { + SSL_CERT_LOOKUP *tmp_lu = &(ctx->ssl_cert_info[i]); + + if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) + || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { + if (pidx != NULL) + *pidx = SSL_PKEY_NUM + i; + return &ctx->ssl_cert_info[i]; + } + } return NULL; } -const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx) +SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) { - if (idx >= OSSL_NELEM(ssl_cert_info)) + if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len)) return NULL; + else if (idx >= (OSSL_NELEM(ssl_cert_info))) + return &(ctx->ssl_cert_info[idx - SSL_PKEY_NUM]); return &ssl_cert_info[idx]; } diff --git a/ssl/ssl_cert_comp.c b/ssl/ssl_cert_comp.c new file mode 100644 index 0000000000..639610a5f7 --- /dev/null +++ b/ssl/ssl_cert_comp.c @@ -0,0 +1,465 @@ +/* + * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "ssl_local.h" +#include "internal/e_os.h" +#include "internal/refcount.h" + +size_t ossl_calculate_comp_expansion(int alg, size_t length) +{ + size_t ret; + /* + * Uncompressibility expansion: + * ZLIB: N + 11 + 5 * (N >> 14) + * Brotli: per RFC7932: N + 5 + 3 * (N >> 16) + * ZSTD: N + 4 + 14 + 3 * (N >> 17) + 4 + */ + + switch (alg) { + case TLSEXT_comp_cert_zlib: + ret = length + 11 + 5 * (length >> 14); + break; + case TLSEXT_comp_cert_brotli: + ret = length + 5 + 3 * (length >> 16); + break; + case TLSEXT_comp_cert_zstd: + ret = length + 22 + 3 * (length >> 17); + break; + default: + return 0; + } + /* Check for overflow */ + if (ret < length) + return 0; + return ret; +} + +int ossl_comp_has_alg(int a) +{ +#ifndef OPENSSL_NO_COMP_ALG + /* 0 means "any" algorithm */ + if ((a == 0 || a == TLSEXT_comp_cert_brotli) && BIO_f_brotli() != NULL) + return 1; + if ((a == 0 || a == TLSEXT_comp_cert_zstd) && BIO_f_zstd() != NULL) + return 1; + if ((a == 0 || a == TLSEXT_comp_cert_zlib) && BIO_f_zlib() != NULL) + return 1; +#endif + return 0; +} + +/* New operation Helper routine */ +#ifndef OPENSSL_NO_COMP_ALG +static OSSL_COMP_CERT *OSSL_COMP_CERT_new(unsigned char *data, size_t len, size_t orig_len, int alg) +{ + OSSL_COMP_CERT *ret = NULL; + + if (!ossl_comp_has_alg(alg) + || data == NULL + || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL + || !CRYPTO_NEW_REF(&ret->references, 1)) + goto err; + + ret->data = data; + ret->len = len; + ret->orig_len = orig_len; + ret->alg = alg; + return ret; + err: + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + OPENSSL_free(data); + OPENSSL_free(ret); + return NULL; +} + +__owur static OSSL_COMP_CERT *OSSL_COMP_CERT_from_compressed_data(unsigned char *data, size_t len, + size_t orig_len, int alg) +{ + return OSSL_COMP_CERT_new(OPENSSL_memdup(data, len), len, orig_len, alg); +} + +__owur static OSSL_COMP_CERT *OSSL_COMP_CERT_from_uncompressed_data(unsigned char *data, size_t len, + int alg) +{ + OSSL_COMP_CERT *ret = NULL; + size_t max_length; + int comp_length; + COMP_METHOD *method; + unsigned char *comp_data = NULL; + COMP_CTX *comp_ctx = NULL; + + switch (alg) { + case TLSEXT_comp_cert_brotli: + method = COMP_brotli_oneshot(); + break; + case TLSEXT_comp_cert_zlib: + method = COMP_zlib_oneshot(); + break; + case TLSEXT_comp_cert_zstd: + method = COMP_zstd_oneshot(); + break; + default: + goto err; + } + + if ((max_length = ossl_calculate_comp_expansion(alg, len)) == 0 + || method == NULL + || (comp_ctx = COMP_CTX_new(method)) == NULL + || (comp_data = OPENSSL_zalloc(max_length)) == NULL) + goto err; + + comp_length = COMP_compress_block(comp_ctx, comp_data, max_length, data, len); + if (comp_length <= 0) + goto err; + + ret = OSSL_COMP_CERT_new(comp_data, comp_length, len, alg); + comp_data = NULL; + + err: + OPENSSL_free(comp_data); + COMP_CTX_free(comp_ctx); + return ret; +} + +void OSSL_COMP_CERT_free(OSSL_COMP_CERT *cc) +{ + int i; + + if (cc == NULL) + return; + + CRYPTO_DOWN_REF(&cc->references, &i); + REF_PRINT_COUNT("OSSL_COMP_CERT", cc); + if (i > 0) + return; + REF_ASSERT_ISNT(i < 0); + + OPENSSL_free(cc->data); + CRYPTO_FREE_REF(&cc->references); + OPENSSL_free(cc); +} +int OSSL_COMP_CERT_up_ref(OSSL_COMP_CERT *cc) +{ + int i; + + if (CRYPTO_UP_REF(&cc->references, &i) <= 0) + return 0; + + REF_PRINT_COUNT("OSSL_COMP_CERT", cc); + REF_ASSERT_ISNT(i < 2); + return ((i > 1) ? 1 : 0); +} + +static int ssl_set_cert_comp_pref(int *prefs, int *algs, size_t len) +{ + size_t j = 0; + size_t i; + int found = 0; + int already_set[TLSEXT_comp_cert_limit]; + int tmp_prefs[TLSEXT_comp_cert_limit]; + + /* Note that |len| is the number of |algs| elements */ + /* clear all algorithms */ + if (len == 0 || algs == NULL) { + memset(prefs, 0, sizeof(tmp_prefs)); + return 1; + } + + /* This will 0-terminate the array */ + memset(tmp_prefs, 0, sizeof(tmp_prefs)); + memset(already_set, 0, sizeof(already_set)); + /* Include only those algorithms we support, ignoring duplicates and unknowns */ + for (i = 0; i < len; i++) { + if (algs[i] != 0 && ossl_comp_has_alg(algs[i])) { + /* Check for duplicate */ + if (already_set[algs[i]]) + return 0; + tmp_prefs[j++] = algs[i]; + already_set[algs[i]] = 1; + found = 1; + } + } + if (found) + memcpy(prefs, tmp_prefs, sizeof(tmp_prefs)); + return found; +} + +static size_t ssl_get_cert_to_compress(SSL *ssl, CERT_PKEY *cpk, unsigned char **data) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + WPACKET tmppkt; + BUF_MEM buf = { 0 }; + size_t ret = 0; + + if (sc == NULL + || cpk == NULL + || !sc->server + || !SSL_in_before(ssl)) + return 0; + + /* Use the |tmppkt| for the to-be-compressed data */ + if (!WPACKET_init(&tmppkt, &buf)) + goto out; + + /* no context present, add 0-length context */ + if (!WPACKET_put_bytes_u8(&tmppkt, 0)) + goto out; + + /* + * ssl3_output_cert_chain() may generate an SSLfatal() error, + * for this case, we want to ignore it, argument for_comp = 1 + */ + if (!ssl3_output_cert_chain(sc, &tmppkt, cpk, 1)) + goto out; + WPACKET_get_total_written(&tmppkt, &ret); + + out: + WPACKET_cleanup(&tmppkt); + if (ret != 0 && data != NULL) + *data = (unsigned char *)buf.data; + else + OPENSSL_free(buf.data); + return ret; +} + +static int ssl_compress_one_cert(SSL *ssl, CERT_PKEY *cpk, int alg) +{ + unsigned char *cert_data = NULL; + OSSL_COMP_CERT *comp_cert = NULL; + size_t length; + + if (cpk == NULL + || alg == TLSEXT_comp_cert_none + || !ossl_comp_has_alg(alg)) + return 0; + + if ((length = ssl_get_cert_to_compress(ssl, cpk, &cert_data)) == 0) + return 0; + comp_cert = OSSL_COMP_CERT_from_uncompressed_data(cert_data, length, alg); + OPENSSL_free(cert_data); + if (comp_cert == NULL) + return 0; + + OSSL_COMP_CERT_free(cpk->comp_cert[alg]); + cpk->comp_cert[alg] = comp_cert; + return 1; +} + +/* alg_in can be 0, meaning any/all algorithms */ +static int ssl_compress_certs(SSL *ssl, CERT_PKEY *cpks, int alg_in) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + int i; + int j; + int alg; + int count = 0; + + if (sc == NULL + || cpks == NULL + || !ossl_comp_has_alg(alg_in)) + return 0; + + /* Look through the preferences to see what we have */ + for (i = 0; i < TLSEXT_comp_cert_limit; i++) { + /* + * alg = 0 means compress for everything, but only for algorithms enabled + * alg != 0 means compress for that algorithm if enabled + */ + alg = sc->cert_comp_prefs[i]; + if ((alg_in == 0 && alg != TLSEXT_comp_cert_none) + || (alg_in != 0 && alg == alg_in)) { + + for (j = 0; j < SSL_PKEY_NUM; j++) { + /* No cert, move on */ + if (cpks[j].x509 == NULL) + continue; + + if (!ssl_compress_one_cert(ssl, &cpks[j], alg)) + return 0; + + /* if the cert expanded, set the value in the CERT_PKEY to NULL */ + if (cpks[j].comp_cert[alg]->len >= cpks[j].comp_cert[alg]->orig_len) { + OSSL_COMP_CERT_free(cpks[j].comp_cert[alg]); + cpks[j].comp_cert[alg] = NULL; + } else { + count++; + } + } + } + } + return (count > 0); +} + +static size_t ssl_get_compressed_cert(SSL *ssl, CERT_PKEY *cpk, int alg, unsigned char **data, + size_t *orig_len) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + size_t cert_len = 0; + size_t comp_len = 0; + unsigned char *cert_data = NULL; + OSSL_COMP_CERT *comp_cert = NULL; + + if (sc == NULL + || cpk == NULL + || data == NULL + || orig_len == NULL + || !sc->server + || !SSL_in_before(ssl) + || !ossl_comp_has_alg(alg)) + return 0; + + if ((cert_len = ssl_get_cert_to_compress(ssl, cpk, &cert_data)) == 0) + goto err; + + comp_cert = OSSL_COMP_CERT_from_uncompressed_data(cert_data, cert_len, alg); + OPENSSL_free(cert_data); + if (comp_cert == NULL) + goto err; + + comp_len = comp_cert->len; + *orig_len = comp_cert->orig_len; + *data = comp_cert->data; + comp_cert->data = NULL; + err: + OSSL_COMP_CERT_free(comp_cert); + return comp_len; +} + +static int ossl_set1_compressed_cert(CERT *cert, int algorithm, + unsigned char *comp_data, size_t comp_length, + size_t orig_length) +{ + OSSL_COMP_CERT *comp_cert; + + /* No explicit cert set */ + if (cert == NULL || cert->key == NULL) + return 0; + + comp_cert = OSSL_COMP_CERT_from_compressed_data(comp_data, comp_length, + orig_length, algorithm); + if (comp_cert == NULL) + return 0; + + OSSL_COMP_CERT_free(cert->key->comp_cert[algorithm]); + cert->key->comp_cert[algorithm] = comp_cert; + + return 1; +} +#endif + +/*- + * Public API + */ +int SSL_CTX_set1_cert_comp_preference(SSL_CTX *ctx, int *algs, size_t len) +{ +#ifndef OPENSSL_NO_COMP_ALG + return ssl_set_cert_comp_pref(ctx->cert_comp_prefs, algs, len); +#else + return 0; +#endif +} + +int SSL_set1_cert_comp_preference(SSL *ssl, int *algs, size_t len) +{ +#ifndef OPENSSL_NO_COMP_ALG + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + return ssl_set_cert_comp_pref(sc->cert_comp_prefs, algs, len); +#else + return 0; +#endif +} + +int SSL_compress_certs(SSL *ssl, int alg) +{ +#ifndef OPENSSL_NO_COMP_ALG + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL || sc->cert == NULL) + return 0; + + return ssl_compress_certs(ssl, sc->cert->pkeys, alg); +#endif + return 0; +} + +int SSL_CTX_compress_certs(SSL_CTX *ctx, int alg) +{ + int ret = 0; +#ifndef OPENSSL_NO_COMP_ALG + SSL *new = SSL_new(ctx); + + if (new == NULL) + return 0; + + ret = ssl_compress_certs(new, ctx->cert->pkeys, alg); + SSL_free(new); +#endif + return ret; +} + +size_t SSL_get1_compressed_cert(SSL *ssl, int alg, unsigned char **data, size_t *orig_len) +{ +#ifndef OPENSSL_NO_COMP_ALG + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + CERT_PKEY *cpk = NULL; + + if (sc->cert != NULL) + cpk = sc->cert->key; + else + cpk = ssl->ctx->cert->key; + + return ssl_get_compressed_cert(ssl, cpk, alg, data, orig_len); +#else + return 0; +#endif +} + +size_t SSL_CTX_get1_compressed_cert(SSL_CTX *ctx, int alg, unsigned char **data, size_t *orig_len) +{ +#ifndef OPENSSL_NO_COMP_ALG + size_t ret; + SSL *new = SSL_new(ctx); + + ret = ssl_get_compressed_cert(new, ctx->cert->key, alg, data, orig_len); + SSL_free(new); + return ret; +#else + return 0; +#endif +} + +int SSL_CTX_set1_compressed_cert(SSL_CTX *ctx, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length) +{ +#ifndef OPENSSL_NO_COMP_ALG + return ossl_set1_compressed_cert(ctx->cert, algorithm, comp_data, comp_length, orig_length); +#else + return 0; +#endif +} + +int SSL_set1_compressed_cert(SSL *ssl, int algorithm, unsigned char *comp_data, + size_t comp_length, size_t orig_length) +{ +#ifndef OPENSSL_NO_COMP_ALG + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + /* Cannot set a pre-compressed certificate on a client */ + if (sc == NULL || !sc->server) + return 0; + + return ossl_set1_compressed_cert(sc->cert, algorithm, comp_data, comp_length, orig_length); +#else + return 0; +#endif +} diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h index f66c5fe390..28918b9767 100644 --- a/ssl/ssl_cert_table.h +++ b/ssl/ssl_cert_table.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,7 +10,7 @@ /* * Certificate table information. NB: table entries must match SSL_PKEY indices */ -static const SSL_CERT_LOOKUP ssl_cert_info [] = { +static SSL_CERT_LOOKUP ssl_cert_info [] = { {EVP_PKEY_RSA, SSL_aRSA}, /* SSL_PKEY_RSA */ {EVP_PKEY_RSA_PSS, SSL_aRSA}, /* SSL_PKEY_RSA_PSS_SIGN */ {EVP_PKEY_DSA, SSL_aDSS}, /* SSL_PKEY_DSA_SIGN */ diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 93de9cf8fd..8360991ce4 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -114,7 +114,7 @@ static const ssl_cipher_table ssl_cipher_table_auth[] = { /* *INDENT-ON* */ /* Utility function for table lookup */ -static int ssl_cipher_info_find(const ssl_cipher_table * table, +static int ssl_cipher_info_find(const ssl_cipher_table *table, size_t table_cnt, uint32_t mask) { size_t i; @@ -358,7 +358,7 @@ int ssl_load_ciphers(SSL_CTX *ctx) /* * We ignore any errors from the fetches below. They are expected to fail - * if theose algorithms are not available. + * if these algorithms are not available. */ ERR_set_mark(); sig = EVP_SIGNATURE_fetch(ctx->libctx, "DSA", ctx->propq); @@ -465,7 +465,8 @@ DEFINE_RUN_ONCE_STATIC(do_load_builtin_compressions) comp->method = method; comp->id = SSL_COMP_ZLIB_IDX; comp->name = COMP_get_name(method); - sk_SSL_COMP_push(ssl_comp_methods, comp); + if (!sk_SSL_COMP_push(ssl_comp_methods, comp)) + OPENSSL_free(comp); sk_SSL_COMP_sort(ssl_comp_methods); } } @@ -626,14 +627,15 @@ const EVP_MD *ssl_md(SSL_CTX *ctx, int idx) return ctx->ssl_digest_methods[idx]; } -const EVP_MD *ssl_handshake_md(SSL *s) +const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s) { - return ssl_md(s->ctx, ssl_get_algorithm2(s)); + return ssl_md(SSL_CONNECTION_GET_CTX(s), ssl_get_algorithm2(s)); } -const EVP_MD *ssl_prf_md(SSL *s) +const EVP_MD *ssl_prf_md(SSL_CONNECTION *s) { - return ssl_md(s->ctx, ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT); + return ssl_md(SSL_CONNECTION_GET_CTX(s), + ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT); } #define ITEM_SEP(a) \ @@ -816,7 +818,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, const SSL_CIPHER *cp; int reverse = 0; - OSSL_TRACE_BEGIN(TLS_CIPHER){ + OSSL_TRACE_BEGIN(TLS_CIPHER) { BIO_printf(trc_out, "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n", rule, (unsigned int)alg_mkey, (unsigned int)alg_auth, @@ -969,10 +971,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, } number_uses = OPENSSL_zalloc(sizeof(int) * (max_strength_bits + 1)); - if (number_uses == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (number_uses == NULL) return 0; - } /* * Now find the strength_bits values actually used @@ -1010,7 +1010,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, retval = 1; l = rule_str; - for ( ; ; ) { + for (;;) { ch = *l; if (ch == '\0') @@ -1051,9 +1051,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str, while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || - (ch == '-') || (ch == '.') || (ch == '=')) + (ch == '-') || (ch == '_') || (ch == '.') || (ch == '=')) #else - while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.') + while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '_') || (ch == '.') || (ch == '=')) #endif { @@ -1102,6 +1102,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, && (ca_list[j]->name[buflen] == '\0')) { found = 1; break; + } else if (ca_list[j]->stdname != NULL + && strncmp(buf, ca_list[j]->stdname, buflen) == 0 + && ca_list[j]->stdname[buflen] == '\0') { + found = 1; + break; } else j++; } @@ -1218,10 +1223,10 @@ static int ssl_cipher_process_rulestr(const char *rule_str, */ if (rule == CIPHER_SPECIAL) { /* special command */ ok = 0; - if ((buflen == 8) && strncmp(buf, "STRENGTH", 8) == 0) { + if ((buflen == 8) && HAS_PREFIX(buf, "STRENGTH")) { ok = ssl_cipher_strength_sort(head_p, tail_p); - } else if (buflen == 10 && strncmp(buf, "SECLEVEL=", 9) == 0) { - int level = buf[9] - '0'; + } else if (buflen == 10 && CHECK_AND_SKIP_PREFIX(buf, "SECLEVEL=")) { + int level = *buf - '0'; if (level < 0 || level > 5) { ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND); } else { @@ -1261,14 +1266,14 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, const char **prule_str) { unsigned int suiteb_flags = 0, suiteb_comb2 = 0; - if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) { + if (HAS_PREFIX(*prule_str, "SUITEB128ONLY")) { suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; - } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) { + } else if (HAS_PREFIX(*prule_str, "SUITEB128C2")) { suiteb_comb2 = 1; suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) { + } else if (HAS_PREFIX(*prule_str, "SUITEB128")) { suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) { + } else if (HAS_PREFIX(*prule_str, "SUITEB192")) { suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS; } @@ -1430,15 +1435,22 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) int SSL_set_ciphersuites(SSL *s, const char *str) { STACK_OF(SSL_CIPHER) *cipher_list; - int ret = set_ciphersuites(&(s->tls13_ciphersuites), str); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + int ret; - if (s->cipher_list == NULL) { + if (sc == NULL) + return 0; + + ret = set_ciphersuites(&(sc->tls13_ciphersuites), str); + + if (sc->cipher_list == NULL) { if ((cipher_list = SSL_get_ciphers(s)) != NULL) - s->cipher_list = sk_SSL_CIPHER_dup(cipher_list); + sc->cipher_list = sk_SSL_CIPHER_dup(cipher_list); } - if (ret && s->cipher_list != NULL) - return update_cipher_list(s->ctx, &s->cipher_list, &s->cipher_list_by_id, - s->tls13_ciphersuites); + if (ret && sc->cipher_list != NULL) + return update_cipher_list(s->ctx, &sc->cipher_list, + &sc->cipher_list_by_id, + sc->tls13_ciphersuites); return ret; } @@ -1484,10 +1496,10 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, */ num_of_ciphers = ssl_method->num_ciphers(); - co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers); - if (co_list == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); - return NULL; /* Failure */ + if (num_of_ciphers > 0) { + co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers); + if (co_list == NULL) + return NULL; /* Failure */ } ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, @@ -1599,7 +1611,6 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); if (ca_list == NULL) { OPENSSL_free(co_list); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; /* Failure */ } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, @@ -1612,7 +1623,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, */ ok = 1; rule_p = rule_str; - if (strncmp(rule_str, "DEFAULT", 7) == 0) { + if (HAS_PREFIX(rule_str, "DEFAULT")) { ok = ssl_cipher_process_rulestr(OSSL_default_cipher_list(), &head, &tail, ca_list, c); rule_p += 7; @@ -1701,10 +1712,8 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) if (buf == NULL) { len = 128; - if ((buf = OPENSSL_malloc(len)) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(len)) == NULL) return NULL; - } } else if (len < 128) { return NULL; } @@ -2046,10 +2055,8 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) } comp = OPENSSL_malloc(sizeof(*comp)); - if (comp == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (comp == NULL) return 1; - } comp->id = id; comp->method = cm; @@ -2061,7 +2068,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) } if (ssl_comp_methods == NULL || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { OPENSSL_free(comp); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return 1; } return 0; @@ -2095,10 +2102,11 @@ int SSL_COMP_get_id(const SSL_COMP *comp) #endif } -const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr, +const SSL_CIPHER *ssl_get_cipher_by_char(SSL_CONNECTION *s, + const unsigned char *ptr, int all) { - const SSL_CIPHER *c = ssl->method->get_cipher_by_char(ptr); + const SSL_CIPHER *c = SSL_CONNECTION_GET_SSL(s)->method->get_cipher_by_char(ptr); if (c == NULL || (!all && c->valid == 0)) return NULL; @@ -2148,6 +2156,16 @@ int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c) return ssl_cipher_table_auth[i].nid; } +int ssl_get_md_idx(int md_nid) { + int i; + + for(i = 0; i < SSL_MD_NUM_IDX; i++) { + if (md_nid == ssl_cipher_table_mac[i].nid) + return i; + } + return -1; +} + const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c) { int idx = c->algorithm2 & SSL_HANDSHAKE_MAC_MASK; @@ -2216,8 +2234,13 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx) { - const SSL_CERT_LOOKUP *cl = ssl_cert_lookup_by_idx(idx); + SSL_CERT_LOOKUP *cl; + + /* A provider-loaded key type is always enabled */ + if (idx >= SSL_PKEY_NUM) + return 0; + cl = ssl_cert_lookup_by_idx(idx, ctx); if (cl == NULL || (cl->amask & ctx->disabled_auth_mask) != 0) return 1; return 0; diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 5146cedb96..3142370016 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -337,7 +337,7 @@ static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound) if (cctx->ctx != NULL) method_version = cctx->ctx->method->version; else if (cctx->ssl != NULL) - method_version = cctx->ssl->ctx->method->version; + method_version = cctx->ssl->defltmeth->version; else return 0; if ((new_version = protocol_from_string(value)) < 0) @@ -396,7 +396,12 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET), SSL_FLAG_TBL_INV("CANames", SSL_OP_DISABLE_TLSEXT_CA_NAMES), - SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS) + SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS), + SSL_FLAG_TBL_CERT("StrictCertCheck", SSL_CERT_FLAG_TLS_STRICT), + SSL_FLAG_TBL_INV("TxCertificateCompression", SSL_OP_NO_TX_CERTIFICATE_COMPRESSION), + SSL_FLAG_TBL_INV("RxCertificateCompression", SSL_OP_NO_RX_CERTIFICATE_COMPRESSION), + SSL_FLAG_TBL("KTLSTxZerocopySendfile", SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE), + SSL_FLAG_TBL("IgnoreUnexpectedEOF", SSL_OP_IGNORE_UNEXPECTED_EOF), }; if (value == NULL) return -3; @@ -430,16 +435,23 @@ static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) { int rv = 1; CERT *c = NULL; - if (cctx->ctx) { + if (cctx->ctx != NULL) { rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); c = cctx->ctx->cert; } - if (cctx->ssl) { - rv = SSL_use_certificate_chain_file(cctx->ssl, value); - c = cctx->ssl->cert; + if (cctx->ssl != NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl); + + if (sc != NULL) { + rv = SSL_use_certificate_chain_file(cctx->ssl, value); + c = sc->cert; + } else { + rv = 0; + } } - if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { + if (rv > 0 && c != NULL && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { char **pfilename = &cctx->cert_filename[c->key - c->pkeys]; + OPENSSL_free(*pfilename); *pfilename = OPENSSL_strdup(value); if (*pfilename == NULL) @@ -483,7 +495,12 @@ static int do_store(SSL_CONF_CTX *cctx, cert = cctx->ctx->cert; ctx = cctx->ctx; } else if (cctx->ssl != NULL) { - cert = cctx->ssl->cert; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl); + + if (sc == NULL) + return 0; + + cert = sc->cert; ctx = cctx->ssl->ctx; } else { return 1; @@ -694,6 +711,10 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("bugs", 0), SSL_CONF_CMD_SWITCH("no_comp", 0), SSL_CONF_CMD_SWITCH("comp", 0), + SSL_CONF_CMD_SWITCH("no_tx_cert_comp", 0), + SSL_CONF_CMD_SWITCH("tx_cert_comp", 0), + SSL_CONF_CMD_SWITCH("no_rx_cert_comp", 0), + SSL_CONF_CMD_SWITCH("rx_cert_comp", 0), SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_ticket", 0), SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER), @@ -710,6 +731,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_etm", 0), + SSL_CONF_CMD_SWITCH("no_ems", 0), SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0), SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0), SSL_CONF_CMD_STRING(Curves, "curves", 0), @@ -773,6 +795,10 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_ALL, 0}, /* bugs */ {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */ {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */ + {SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, 0}, /* no_tx_cert_comp */ + {SSL_OP_NO_TX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV}, /* tx_cert_comp */ + {SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, 0}, /* no_rx_cert_comp */ + {SSL_OP_NO_RX_CERTIFICATE_COMPRESSION, SSL_TFLAG_INV}, /* rx_cert_comp */ {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */ {SSL_OP_NO_TICKET, 0}, /* no_ticket */ {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */ @@ -801,6 +827,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_NO_ANTI_REPLAY, 0}, /* no Encrypt-then-Mac */ {SSL_OP_NO_ENCRYPT_THEN_MAC, 0}, + /* no Extended master secret */ + {SSL_OP_NO_EXTENDED_MASTER_SECRET, 0}, }; static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) @@ -827,7 +855,7 @@ static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) } /* Determine if a command is allowed according to cctx flags */ -static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t) +static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *t) { unsigned int tfl = t->flags; unsigned int cfl = cctx->flags; @@ -865,7 +893,7 @@ static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, return NULL; } -static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd) +static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl *cmd) { /* Find index of command in table */ size_t idx = cmd - ssl_conf_cmds; @@ -973,11 +1001,16 @@ int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) /* See if any certificates are missing private keys */ size_t i; CERT *c = NULL; - if (cctx->ctx) + + if (cctx->ctx != NULL) { c = cctx->ctx->cert; - else if (cctx->ssl) - c = cctx->ssl->cert; - if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { + } else if (cctx->ssl != NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(cctx->ssl); + + if (sc != NULL) + c = sc->cert; + } + if (c != NULL && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) { for (i = 0; i < SSL_PKEY_NUM; i++) { const char *p = cctx->cert_filename[i]; /* @@ -1046,12 +1079,16 @@ void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) { cctx->ssl = ssl; cctx->ctx = NULL; - if (ssl) { - cctx->poptions = &ssl->options; - cctx->min_version = &ssl->min_proto_version; - cctx->max_version = &ssl->max_proto_version; - cctx->pcert_flags = &ssl->cert->cert_flags; - cctx->pvfy_flags = &ssl->verify_mode; + if (ssl != NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return; + cctx->poptions = &sc->options; + cctx->min_version = &sc->min_proto_version; + cctx->max_version = &sc->max_proto_version; + cctx->pcert_flags = &sc->cert->cert_flags; + cctx->pvfy_flags = &sc->verify_mode; } else { cctx->poptions = NULL; cctx->min_version = NULL; diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 84ee821c3c..1cda4a0aef 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,9 +23,12 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "attempt to reuse session in different context"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE), "at least (D)TLS 1.2 needed in Suite B mode"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CERTIFICATE), "bad certificate"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CIPHER), "bad cipher"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_COMPRESSION_ALGORITHM), + "bad compression algorithm"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DATA), "bad data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), "bad data returned by callback"}, @@ -101,6 +104,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "compression library error"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONN_USE_ONLY), "conn use only"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONTEXT_NOT_DANE_ENABLED), "context not dane enabled"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COOKIE_GEN_CALLBACK_FAILURE), @@ -152,6 +156,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE), "ecdh required for suiteb mode"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EE_KEY_TOO_SMALL), "ee key too small"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EMPTY_RAW_PUBLIC_KEY), + "empty raw public key"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), "empty srtp protection profile list"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ENCRYPTED_LENGTH_TOO_LONG), @@ -170,6 +176,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "extra data in message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXT_LENGTH_MISMATCH), "ext length mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_GET_PARAMETER), + "failed to get parameter"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), @@ -214,6 +222,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "invalid max early data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_RAW_PUBLIC_KEY), + "invalid raw public key"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_RECORD), "invalid record"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SEQUENCE_NUMBER), "invalid sequence number"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SERVERINFO_DATA), @@ -233,6 +244,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_BUG), "library bug"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED), + "maximum encrypted pkts reached"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_ECDSA_SIGNING_CERT), @@ -301,11 +314,14 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS), "no shared signature algorithms"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_STREAM), "no stream"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM), "no suitable digest algorithm"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_GROUPS), "no suitable groups"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_KEY_SHARE), "no suitable key share"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_RECORD_LAYER), + "no suitable record layer"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM), "no suitable signature algorithm"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_VALID_SCTS), "no valid scts"}, @@ -341,12 +357,23 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "psk identity not found"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_NO_SERVER_CB), "psk no server cb"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_HANDSHAKE_LAYER_ERROR), + "quic handshake layer error"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_NETWORK_ERROR), "quic network error"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_PROTOCOL_ERROR), + "quic protocol error"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_BIO_NOT_SET), "read bio not set"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORDS_NOT_RELEASED), + "records not released"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LAYER_FAILURE), + "record layer failure"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_TOO_SMALL), "record too small"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET), + "remote peer address not set"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATION_ENCODING_ERR), @@ -363,6 +390,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "scsv received when renegotiating"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SCT_VERIFICATION_FAILED), "sct verification failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SEQUENCE_CTR_WRAPPED), + "sequence ctr wrapped"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), "session id context uninitialized"}, @@ -388,27 +417,27 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), - "sslv3 alert bad certificate"}, + "ssl/tls alert bad certificate"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), - "sslv3 alert bad record mac"}, + "ssl/tls alert bad record mac"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), - "sslv3 alert certificate expired"}, + "ssl/tls alert certificate expired"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), - "sslv3 alert certificate revoked"}, + "ssl/tls alert certificate revoked"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), - "sslv3 alert certificate unknown"}, + "ssl/tls alert certificate unknown"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), - "sslv3 alert decompression failure"}, + "ssl/tls alert decompression failure"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), - "sslv3 alert handshake failure"}, + "ssl/tls alert handshake failure"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), - "sslv3 alert illegal parameter"}, + "ssl/tls alert illegal parameter"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_NO_CERTIFICATE), - "sslv3 alert no certificate"}, + "ssl/tls alert no certificate"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), - "sslv3 alert unexpected message"}, + "ssl/tls alert unexpected message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), - "sslv3 alert unsupported certificate"}, + "ssl/tls alert unsupported certificate"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_COMMAND_SECTION_EMPTY), "ssl command section empty"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND), @@ -437,6 +466,12 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_VERSION_MISMATCH), "ssl session version mismatch"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STILL_IN_INIT), "still in init"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_COUNT_LIMITED), + "stream count limited"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_FINISHED), "stream finished"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_RECV_ONLY), "stream recv only"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_RESET), "stream reset"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_SEND_ONLY), "stream send only"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED), "tlsv13 alert certificate required"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV13_ALERT_MISSING_EXTENSION), @@ -516,6 +551,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_DIGEST), "unknown digest"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), "unknown key exchange type"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_MANDATORY_PARAMETER), + "unknown mandatory parameter"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_SSL_VERSION), @@ -544,6 +581,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CURVE), "wrong curve"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_RPK_TYPE), "wrong rpk type"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_SIZE), diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 36cb8060eb..70e567b72c 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -35,7 +35,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base) SSL_COMP_get_compression_methods(); #endif ssl_sort_cipher_list(); - OSSL_TRACE(INIT,"ossl_init_ssl_base: SSL_add_ssl_module()\n"); + OSSL_TRACE(INIT, "ossl_init_ssl_base: SSL_add_ssl_module()\n"); /* * We ignore an error return here. Not much we can do - but not that bad * either. We can still safely continue. @@ -88,7 +88,7 @@ static void ssl_library_stop(void) * called prior to any threads making calls to any OpenSSL functions, * i.e. passing a non-null settings value is assumed to be single-threaded. */ -int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings) +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { static int stoperrset = 0; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 687cb162f8..70d3b17c19 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -21,38 +21,28 @@ #include #include #include +#include #include "internal/cryptlib.h" #include "internal/nelem.h" #include "internal/refcount.h" #include "internal/ktls.h" +#include "quic/quic_local.h" -static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t, - SSL_MAC_BUF *mac, size_t macsize) -{ - return ssl_undefined_function(ssl); -} - -static int ssl_undefined_function_2(SSL *ssl, SSL3_RECORD *r, unsigned char *s, - int t) -{ - return ssl_undefined_function(ssl); -} - -static int ssl_undefined_function_3(SSL *ssl, unsigned char *r, +static int ssl_undefined_function_3(SSL_CONNECTION *sc, unsigned char *r, unsigned char *s, size_t t, size_t *u) { - return ssl_undefined_function(ssl); + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } -static int ssl_undefined_function_4(SSL *ssl, int r) +static int ssl_undefined_function_4(SSL_CONNECTION *sc, int r) { - return ssl_undefined_function(ssl); + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } -static size_t ssl_undefined_function_5(SSL *ssl, const char *r, size_t s, - unsigned char *t) +static size_t ssl_undefined_function_5(SSL_CONNECTION *sc, const char *r, + size_t s, unsigned char *t) { - return ssl_undefined_function(ssl); + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } static int ssl_undefined_function_6(int r) @@ -60,17 +50,20 @@ static int ssl_undefined_function_6(int r) return ssl_undefined_function(NULL); } -static int ssl_undefined_function_7(SSL *ssl, unsigned char *r, size_t s, - const char *t, size_t u, +static int ssl_undefined_function_7(SSL_CONNECTION *sc, unsigned char *r, + size_t s, const char *t, size_t u, const unsigned char *v, size_t w, int x) { - return ssl_undefined_function(ssl); + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); +} + +static int ssl_undefined_function_8(SSL_CONNECTION *sc) +{ + return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc)); } SSL3_ENC_METHOD ssl3_undef_enc_method = { - ssl_undefined_function_1, - ssl_undefined_function_2, - ssl_undefined_function, + ssl_undefined_function_8, ssl_undefined_function_3, ssl_undefined_function_4, ssl_undefined_function_5, @@ -127,7 +120,6 @@ static int dane_ctx_enable(struct dane_ctx_st *dctx) if (mdord == NULL || mdevp == NULL) { OPENSSL_free(mdord); OPENSSL_free(mdevp); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -173,7 +165,7 @@ static void dane_final(SSL_DANE *dane) sk_danetls_record_pop_free(dane->trecs, tlsa_free); dane->trecs = NULL; - sk_X509_pop_free(dane->certs, X509_free); + OSSL_STACK_OF_X509_free(dane->certs); dane->certs = NULL; X509_free(dane->mcert); @@ -186,7 +178,7 @@ static void dane_final(SSL_DANE *dane) /* * dane_copy - Copy dane configuration, sans verification state. */ -static int ssl_dane_dup(SSL *to, SSL *from) +static int ssl_dane_dup(SSL_CONNECTION *to, SSL_CONNECTION *from) { int num; int i; @@ -197,19 +189,19 @@ static int ssl_dane_dup(SSL *to, SSL *from) num = sk_danetls_record_num(from->dane.trecs); dane_final(&to->dane); to->dane.flags = from->dane.flags; - to->dane.dctx = &to->ctx->dane; + to->dane.dctx = &SSL_CONNECTION_GET_CTX(to)->dane; to->dane.trecs = sk_danetls_record_new_reserve(NULL, num); if (to->dane.trecs == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return 0; } for (i = 0; i < num; ++i) { danetls_record *t = sk_danetls_record_value(from->dane.trecs, i); - if (SSL_dane_tlsa_add(to, t->usage, t->selector, t->mtype, - t->data, t->dlen) <= 0) + if (SSL_dane_tlsa_add(SSL_CONNECTION_GET_SSL(to), t->usage, + t->selector, t->mtype, t->data, t->dlen) <= 0) return 0; } return 1; @@ -231,17 +223,13 @@ static int dane_mtype_set(struct dane_ctx_st *dctx, int n = ((int)mtype) + 1; mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp)); - if (mdevp == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (mdevp == NULL) return -1; - } dctx->mdevp = mdevp; mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord)); - if (mdord == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (mdord == NULL) return -1; - } dctx->mdord = mdord; /* Zero-fill any gaps */ @@ -315,10 +303,8 @@ static int dane_tlsa_add(SSL_DANE *dane, return 0; } - if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) return -1; - } t->usage = usage; t->selector = selector; @@ -326,7 +312,6 @@ static int dane_tlsa_add(SSL_DANE *dane, t->data = OPENSSL_malloc(dlen); if (t->data == NULL) { tlsa_free(t); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } memcpy(t->data, data, dlen); @@ -342,11 +327,13 @@ static int dane_tlsa_add(SSL_DANE *dane, case DANETLS_SELECTOR_CERT: if (!d2i_X509(&cert, &p, ilen) || p < data || dlen != (size_t)(p - data)) { + X509_free(cert); tlsa_free(t); ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE); return 0; } if (X509_get0_pubkey(cert) == NULL) { + X509_free(cert); tlsa_free(t); ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE); return 0; @@ -354,6 +341,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) { X509_free(cert); + tlsa_free(t); break; } @@ -367,7 +355,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if ((dane->certs == NULL && (dane->certs = sk_X509_new_null()) == NULL) || !sk_X509_push(dane->certs, cert)) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); X509_free(cert); tlsa_free(t); return -1; @@ -377,6 +365,7 @@ static int dane_tlsa_add(SSL_DANE *dane, case DANETLS_SELECTOR_SPKI: if (!d2i_PUBKEY(&pkey, &p, ilen) || p < data || dlen != (size_t)(p - data)) { + EVP_PKEY_free(pkey); tlsa_free(t); ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY); return 0; @@ -428,7 +417,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if (!sk_danetls_record_insert(dane->trecs, t, i)) { tlsa_free(t); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return -1; } dane->umask |= DANETLS_USAGE_BIT(usage); @@ -558,13 +547,30 @@ static int ssl_check_allowed_versions(int min_version, int max_version) void OPENSSL_VPROC_FUNC(void) {} #endif - -static void clear_ciphers(SSL *s) +static int clear_record_layer(SSL_CONNECTION *s) { - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + int ret; + + /* We try and reset both record layers even if one fails */ + + ret = ssl_set_new_record_layer(s, + SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION + : TLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NID_undef, NULL, NULL, NULL); + + ret &= ssl_set_new_record_layer(s, + SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION + : TLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_WRITE, + OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NID_undef, NULL, NULL, NULL); + + /* SSLfatal already called in the event of failure */ + return ret; } int SSL_clear(SSL *s) @@ -574,73 +580,90 @@ int SSL_clear(SSL *s) return 0; } - if (ssl_clear_bad_session(s)) { - SSL_SESSION_free(s->session); - s->session = NULL; + return s->method->ssl_reset(s); +} + +int ossl_ssl_connection_reset(SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (ssl_clear_bad_session(sc)) { + SSL_SESSION_free(sc->session); + sc->session = NULL; } - SSL_SESSION_free(s->psksession); - s->psksession = NULL; - OPENSSL_free(s->psksession_id); - s->psksession_id = NULL; - s->psksession_id_len = 0; - s->hello_retry_request = SSL_HRR_NONE; - s->sent_tickets = 0; + SSL_SESSION_free(sc->psksession); + sc->psksession = NULL; + OPENSSL_free(sc->psksession_id); + sc->psksession_id = NULL; + sc->psksession_id_len = 0; + sc->hello_retry_request = SSL_HRR_NONE; + sc->sent_tickets = 0; - s->error = 0; - s->hit = 0; - s->shutdown = 0; + sc->error = 0; + sc->hit = 0; + sc->shutdown = 0; - if (s->renegotiate) { + if (sc->renegotiate) { ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } - ossl_statem_clear(s); + ossl_statem_clear(sc); - s->version = s->method->version; - s->client_version = s->version; - s->rwstate = SSL_NOTHING; + sc->version = s->method->version; + sc->client_version = sc->version; + sc->rwstate = SSL_NOTHING; - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - clear_ciphers(s); - s->first_packet = 0; + BUF_MEM_free(sc->init_buf); + sc->init_buf = NULL; + sc->first_packet = 0; - s->key_update = SSL_KEY_UPDATE_NONE; + sc->key_update = SSL_KEY_UPDATE_NONE; + memset(sc->ext.compress_certificate_from_peer, 0, + sizeof(sc->ext.compress_certificate_from_peer)); + sc->ext.compress_certificate_sent = 0; - EVP_MD_CTX_free(s->pha_dgst); - s->pha_dgst = NULL; + EVP_MD_CTX_free(sc->pha_dgst); + sc->pha_dgst = NULL; /* Reset DANE verification result state */ - s->dane.mdpth = -1; - s->dane.pdpth = -1; - X509_free(s->dane.mcert); - s->dane.mcert = NULL; - s->dane.mtlsa = NULL; + sc->dane.mdpth = -1; + sc->dane.pdpth = -1; + X509_free(sc->dane.mcert); + sc->dane.mcert = NULL; + sc->dane.mtlsa = NULL; /* Clear the verification result peername */ - X509_VERIFY_PARAM_move_peername(s->param, NULL); + X509_VERIFY_PARAM_move_peername(sc->param, NULL); /* Clear any shared connection state */ - OPENSSL_free(s->shared_sigalgs); - s->shared_sigalgs = NULL; - s->shared_sigalgslen = 0; + OPENSSL_free(sc->shared_sigalgs); + sc->shared_sigalgs = NULL; + sc->shared_sigalgslen = 0; /* * Check to see if we were changed into a different method, if so, revert * back. */ - if (s->method != s->ctx->method) { - s->method->ssl_free(s); - s->method = s->ctx->method; - if (!s->method->ssl_new(s)) + if (s->method != s->defltmeth) { + s->method->ssl_deinit(s); + s->method = s->defltmeth; + if (!s->method->ssl_init(s)) return 0; } else { if (!s->method->ssl_clear(s)) return 0; } - RECORD_LAYER_clear(&s->rlayer); + RECORD_LAYER_clear(&sc->rlayer); + BIO_free(sc->rlayer.rrlnext); + sc->rlayer.rrlnext = NULL; + + if (!clear_record_layer(sc)) + return 0; return 1; } @@ -651,6 +674,11 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) { STACK_OF(SSL_CIPHER) *sk; + if (IS_QUIC_CTX(ctx)) { + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); + return 0; + } + ctx->method = meth; if (!SSL_CTX_set_ciphersuites(ctx, OSSL_default_ciphersuites())) { @@ -672,8 +700,6 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) SSL *SSL_new(SSL_CTX *ctx) { - SSL *s; - if (ctx == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_CTX); return NULL; @@ -682,36 +708,76 @@ SSL *SSL_new(SSL_CTX *ctx) ERR_raise(ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); return NULL; } + return ctx->method->ssl_new(ctx); +} + +int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, int type) +{ + ssl->type = type; + + ssl->lock = CRYPTO_THREAD_lock_new(); + if (ssl->lock == NULL) + return 0; + + if (!CRYPTO_NEW_REF(&ssl->references, 1)) { + CRYPTO_THREAD_lock_free(ssl->lock); + return 0; + } + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data)) { + CRYPTO_THREAD_lock_free(ssl->lock); + CRYPTO_FREE_REF(&ssl->references); + ssl->lock = NULL; + return 0; + } + + SSL_CTX_up_ref(ctx); + ssl->ctx = ctx; + + ssl->defltmeth = ssl->method = method; + + return 1; +} + +SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method) +{ + SSL_CONNECTION *s; + SSL *ssl; s = OPENSSL_zalloc(sizeof(*s)); if (s == NULL) - goto err; + return NULL; - s->references = 1; - s->lock = CRYPTO_THREAD_lock_new(); - if (s->lock == NULL) { + ssl = &s->ssl; + if (!ossl_ssl_init(ssl, ctx, method, SSL_TYPE_SSL_CONNECTION)) { OPENSSL_free(s); s = NULL; - goto err; + ssl = NULL; + goto sslerr; } RECORD_LAYER_init(&s->rlayer, s); s->options = ctx->options; + s->dane.flags = ctx->dane.flags; - s->min_proto_version = ctx->min_proto_version; - s->max_proto_version = ctx->max_proto_version; + if (method->version == ctx->method->version) { + s->min_proto_version = ctx->min_proto_version; + s->max_proto_version = ctx->max_proto_version; + } + s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; s->max_early_data = ctx->max_early_data; s->recv_max_early_data = ctx->recv_max_early_data; + s->num_tickets = ctx->num_tickets; s->pha_enabled = ctx->pha_enabled; /* Shallow copy of the ciphersuites stack */ s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites); if (s->tls13_ciphersuites == NULL) - goto err; + goto cerr; /* * Earlier library versions used to copy the pointer to the CERT, not @@ -724,16 +790,16 @@ SSL *SSL_new(SSL_CTX *ctx) */ s->cert = ssl_cert_dup(ctx->cert); if (s->cert == NULL) - goto err; + goto sslerr; RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead); s->msg_callback = ctx->msg_callback; s->msg_callback_arg = ctx->msg_callback_arg; s->verify_mode = ctx->verify_mode; s->not_resumable_session_cb = ctx->not_resumable_session_cb; - s->record_padding_cb = ctx->record_padding_cb; - s->record_padding_arg = ctx->record_padding_arg; - s->block_padding = ctx->block_padding; + s->rlayer.record_padding_cb = ctx->record_padding_cb; + s->rlayer.record_padding_arg = ctx->record_padding_arg; + s->rlayer.block_padding = ctx->block_padding; s->sid_ctx_length = ctx->sid_ctx_length; if (!ossl_assert(s->sid_ctx_length <= sizeof(s->sid_ctx))) goto err; @@ -743,21 +809,18 @@ SSL *SSL_new(SSL_CTX *ctx) s->param = X509_VERIFY_PARAM_new(); if (s->param == NULL) - goto err; + goto asn1err; X509_VERIFY_PARAM_inherit(s->param, ctx->param); - s->quiet_shutdown = ctx->quiet_shutdown; + s->quiet_shutdown = IS_QUIC_CTX(ctx) ? 0 : ctx->quiet_shutdown; + + if (!IS_QUIC_CTX(ctx)) + s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode; - s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode; s->max_send_fragment = ctx->max_send_fragment; s->split_send_fragment = ctx->split_send_fragment; s->max_pipelines = ctx->max_pipelines; - if (s->max_pipelines > 1) - RECORD_LAYER_set_read_ahead(&s->rlayer, 1); - if (ctx->default_read_buf_len > 0) - SSL_set_default_read_buffer_len(s, ctx->default_read_buf_len); + s->rlayer.default_read_buf_len = ctx->default_read_buf_len; - SSL_CTX_up_ref(ctx); - s->ctx = ctx; s->ext.debug_cb = 0; s->ext.debug_arg = NULL; s->ext.ticket_expected = 0; @@ -796,14 +859,14 @@ SSL *SSL_new(SSL_CTX *ctx) s->ext.npn = NULL; #endif - if (s->ctx->ext.alpn) { - s->ext.alpn = OPENSSL_malloc(s->ctx->ext.alpn_len); + if (ctx->ext.alpn != NULL) { + s->ext.alpn = OPENSSL_malloc(ctx->ext.alpn_len); if (s->ext.alpn == NULL) { s->ext.alpn_len = 0; goto err; } - memcpy(s->ext.alpn, s->ctx->ext.alpn, s->ctx->ext.alpn_len); - s->ext.alpn_len = s->ctx->ext.alpn_len; + memcpy(s->ext.alpn, ctx->ext.alpn, ctx->ext.alpn_len); + s->ext.alpn_len = ctx->ext.alpn_len; } s->verified_chain = NULL; @@ -812,23 +875,20 @@ SSL *SSL_new(SSL_CTX *ctx) s->default_passwd_callback = ctx->default_passwd_callback; s->default_passwd_callback_userdata = ctx->default_passwd_callback_userdata; - s->method = ctx->method; - s->key_update = SSL_KEY_UPDATE_NONE; - s->allow_early_data_cb = ctx->allow_early_data_cb; - s->allow_early_data_cb_data = ctx->allow_early_data_cb_data; - - if (!s->method->ssl_new(s)) - goto err; + if (!IS_QUIC_CTX(ctx)) { + s->allow_early_data_cb = ctx->allow_early_data_cb; + s->allow_early_data_cb_data = ctx->allow_early_data_cb_data; + } - s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; + if (!method->ssl_init(ssl)) + goto sslerr; - if (!SSL_clear(s)) - goto err; + s->server = (method->ssl_accept == ssl_undefined_function) ? 0 : 1; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data)) - goto err; + if (!method->ssl_reset(ssl)) + goto sslerr; #ifndef OPENSSL_NO_PSK s->psk_client_callback = ctx->psk_client_callback; @@ -842,29 +902,94 @@ SSL *SSL_new(SSL_CTX *ctx) s->job = NULL; +#ifndef OPENSSL_NO_COMP_ALG + memcpy(s->cert_comp_prefs, ctx->cert_comp_prefs, sizeof(s->cert_comp_prefs)); +#endif + if (ctx->client_cert_type != NULL) { + s->client_cert_type = OPENSSL_memdup(ctx->client_cert_type, + ctx->client_cert_type_len); + if (s->client_cert_type == NULL) + goto sslerr; + s->client_cert_type_len = ctx->client_cert_type_len; + } + if (ctx->server_cert_type != NULL) { + s->server_cert_type = OPENSSL_memdup(ctx->server_cert_type, + ctx->server_cert_type_len); + if (s->server_cert_type == NULL) + goto sslerr; + s->server_cert_type_len = ctx->server_cert_type_len; + } + #ifndef OPENSSL_NO_CT - if (!SSL_set_ct_validation_callback(s, ctx->ct_validation_callback, + if (!SSL_set_ct_validation_callback(ssl, ctx->ct_validation_callback, ctx->ct_validation_callback_arg)) - goto err; + goto sslerr; #endif - return s; + s->ssl_pkey_num = SSL_PKEY_NUM + ctx->sigalg_list_len; + return ssl; + cerr: + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + asn1err: + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); + goto err; + sslerr: + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); err: - SSL_free(s); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + SSL_free(ssl); return NULL; } +SSL *ossl_ssl_connection_new(SSL_CTX *ctx) +{ + return ossl_ssl_connection_new_int(ctx, ctx->method); +} + int SSL_is_dtls(const SSL *s) { - return SSL_IS_DTLS(s) ? 1 : 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return 0; +#endif + + if (sc == NULL) + return 0; + + return SSL_CONNECTION_IS_DTLS(sc) ? 1 : 0; +} + +int SSL_is_tls(const SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return 0; +#endif + + if (sc == NULL) + return 0; + + return SSL_CONNECTION_IS_DTLS(sc) ? 0 : 1; +} + +int SSL_is_quic(const SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return 1; +#endif + return 0; } int SSL_up_ref(SSL *s) { int i; - if (CRYPTO_UP_REF(&s->references, &i, s->lock) <= 0) + if (CRYPTO_UP_REF(&s->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL", s); @@ -888,12 +1013,17 @@ int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); return 0; } - ssl->sid_ctx_length = sid_ctx_len; - memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); + sc->sid_ctx_length = sid_ctx_len; + memcpy(sc->sid_ctx, sid_ctx, sid_ctx_len); return 1; } @@ -909,9 +1039,11 @@ int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) { - if (!CRYPTO_THREAD_write_lock(ssl->lock)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL || !CRYPTO_THREAD_write_lock(ssl->lock)) return 0; - ssl->generate_session_id = cb; + sc->generate_session_id = cb; CRYPTO_THREAD_unlock(ssl->lock); return 1; } @@ -927,18 +1059,19 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, * by this SSL. */ SSL_SESSION r, *p; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); - if (id_len > sizeof(r.session_id)) + if (sc == NULL || id_len > sizeof(r.session_id)) return 0; - r.ssl_version = ssl->version; + r.ssl_version = sc->version; r.session_id_length = id_len; memcpy(r.session_id, id, id_len); - if (!CRYPTO_THREAD_read_lock(ssl->session_ctx->lock)) + if (!CRYPTO_THREAD_read_lock(sc->session_ctx->lock)) return 0; - p = lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &r); - CRYPTO_THREAD_unlock(ssl->session_ctx->lock); + p = lh_SSL_SESSION_retrieve(sc->session_ctx->sessions, &r); + CRYPTO_THREAD_unlock(sc->session_ctx->lock); return (p != NULL); } @@ -949,7 +1082,12 @@ int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) int SSL_set_purpose(SSL *s, int purpose) { - return X509_VERIFY_PARAM_set_purpose(s->param, purpose); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return X509_VERIFY_PARAM_set_purpose(sc->param, purpose); } int SSL_CTX_set_trust(SSL_CTX *s, int trust) @@ -959,21 +1097,37 @@ int SSL_CTX_set_trust(SSL_CTX *s, int trust) int SSL_set_trust(SSL *s, int trust) { - return X509_VERIFY_PARAM_set_trust(s->param, trust); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return X509_VERIFY_PARAM_set_trust(sc->param, trust); } int SSL_set1_host(SSL *s, const char *hostname) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + /* If a hostname is provided and parses as an IP address, * treat it as such. */ - if (hostname && X509_VERIFY_PARAM_set1_ip_asc(s->param, hostname) == 1) + if (hostname != NULL + && X509_VERIFY_PARAM_set1_ip_asc(sc->param, hostname) == 1) return 1; - return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0); + return X509_VERIFY_PARAM_set1_host(sc->param, hostname, 0); } int SSL_add1_host(SSL *s, const char *hostname) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + /* If a hostname is provided and parses as an IP address, * treat it as such. */ if (hostname) @@ -986,7 +1140,7 @@ int SSL_add1_host(SSL *s, const char *hostname) /* We didn't want it; only to check if it *is* an IP address */ ASN1_OCTET_STRING_free(ip); - old_ip = X509_VERIFY_PARAM_get1_ip_asc(s->param); + old_ip = X509_VERIFY_PARAM_get1_ip_asc(sc->param); if (old_ip) { OPENSSL_free(old_ip); @@ -994,21 +1148,31 @@ int SSL_add1_host(SSL *s, const char *hostname) return 0; } - return X509_VERIFY_PARAM_set1_ip_asc(s->param, hostname); + return X509_VERIFY_PARAM_set1_ip_asc(sc->param, hostname); } } - return X509_VERIFY_PARAM_add1_host(s->param, hostname, 0); + return X509_VERIFY_PARAM_add1_host(sc->param, hostname, 0); } void SSL_set_hostflags(SSL *s, unsigned int flags) { - X509_VERIFY_PARAM_set_hostflags(s->param, flags); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + X509_VERIFY_PARAM_set_hostflags(sc->param, flags); } const char *SSL_get0_peername(SSL *s) { - return X509_VERIFY_PARAM_get0_peername(s->param); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + return X509_VERIFY_PARAM_get0_peername(sc->param); } int SSL_CTX_dane_enable(SSL_CTX *ctx) @@ -1034,8 +1198,13 @@ unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags) int SSL_dane_enable(SSL *s, const char *basedomain) { - SSL_DANE *dane = &s->dane; + SSL_DANE *dane; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + dane = &sc->dane; if (s->ctx->dane.mdmax == 0) { ERR_raise(ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED); return 0; @@ -1050,7 +1219,7 @@ int SSL_dane_enable(SSL *s, const char *basedomain) * accepts them and disables hostname checks. To avoid side-effects with * invalid input, set the SNI name first. */ - if (s->ext.hostname == NULL) { + if (sc->ext.hostname == NULL) { if (!SSL_set_tlsext_host_name(s, basedomain)) { ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); return -1; @@ -1058,7 +1227,7 @@ int SSL_dane_enable(SSL *s, const char *basedomain) } /* Primary RFC6125 reference identifier */ - if (!X509_VERIFY_PARAM_set1_host(s->param, basedomain, 0)) { + if (!X509_VERIFY_PARAM_set1_host(sc->param, basedomain, 0)) { ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); return -1; } @@ -1069,7 +1238,7 @@ int SSL_dane_enable(SSL *s, const char *basedomain) dane->trecs = sk_danetls_record_new_null(); if (dane->trecs == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); return -1; } return 1; @@ -1077,25 +1246,43 @@ int SSL_dane_enable(SSL *s, const char *basedomain) unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags) { - unsigned long orig = ssl->dane.flags; + unsigned long orig; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + orig = sc->dane.flags; - ssl->dane.flags |= flags; + sc->dane.flags |= flags; return orig; } unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags) { - unsigned long orig = ssl->dane.flags; + unsigned long orig; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; - ssl->dane.flags &= ~flags; + orig = sc->dane.flags; + + sc->dane.flags &= ~flags; return orig; } int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki) { - SSL_DANE *dane = &s->dane; + SSL_DANE *dane; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; - if (!DANETLS_ENABLED(dane) || s->verify_result != X509_V_OK) + dane = &sc->dane; + + if (!DANETLS_ENABLED(dane) || sc->verify_result != X509_V_OK) return -1; if (dane->mtlsa) { if (mcert) @@ -1109,9 +1296,15 @@ int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki) int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, uint8_t *mtype, const unsigned char **data, size_t *dlen) { - SSL_DANE *dane = &s->dane; + SSL_DANE *dane; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; - if (!DANETLS_ENABLED(dane) || s->verify_result != X509_V_OK) + dane = &sc->dane; + + if (!DANETLS_ENABLED(dane) || sc->verify_result != X509_V_OK) return -1; if (dane->mtlsa) { if (usage) @@ -1130,13 +1323,23 @@ int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, SSL_DANE *SSL_get0_dane(SSL *s) { - return &s->dane; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + return &sc->dane; } int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, uint8_t mtype, const unsigned char *data, size_t dlen) { - return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return dane_tlsa_add(&sc->dane, usage, selector, mtype, data, dlen); } int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype, @@ -1152,7 +1355,12 @@ int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) { - return X509_VERIFY_PARAM_set1(ssl->param, vpm); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + return X509_VERIFY_PARAM_set1(sc->param, vpm); } X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) @@ -1162,12 +1370,22 @@ X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { - return ssl->param; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return NULL; + + return sc->param; } void SSL_certs_clear(SSL *s) { - ssl_cert_clear_certs(s->cert); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + ssl_cert_clear_certs(sc->cert); } void SSL_free(SSL *s) @@ -1176,25 +1394,39 @@ void SSL_free(SSL *s) if (s == NULL) return; - CRYPTO_DOWN_REF(&s->references, &i, s->lock); + CRYPTO_DOWN_REF(&s->references, &i); REF_PRINT_COUNT("SSL", s); if (i > 0) return; REF_ASSERT_ISNT(i < 0); - X509_VERIFY_PARAM_free(s->param); - dane_final(&s->dane); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); - RECORD_LAYER_release(&s->rlayer); + if (s->method != NULL) + s->method->ssl_free(s); + + SSL_CTX_free(s->ctx); + CRYPTO_THREAD_lock_free(s->lock); + CRYPTO_FREE_REF(&s->references); + + OPENSSL_free(s); +} + +void ossl_ssl_connection_free(SSL *ssl) +{ + SSL_CONNECTION *s; + + s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (s == NULL) + return; + + X509_VERIFY_PARAM_free(s->param); + dane_final(&s->dane); /* Ignore return value */ ssl_free_wbio_buffer(s); - BIO_free_all(s->wbio); - s->wbio = NULL; - BIO_free_all(s->rbio); - s->rbio = NULL; + RECORD_LAYER_clear(&s->rlayer); BUF_MEM_free(s->init_buf); @@ -1212,8 +1444,6 @@ void SSL_free(SSL *s) SSL_SESSION_free(s->psksession); OPENSSL_free(s->psksession_id); - clear_ciphers(s); - ssl_cert_free(s->cert); OPENSSL_free(s->shared_sigalgs); /* Free up if allocated */ @@ -1244,12 +1474,13 @@ void SSL_free(SSL *s) sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free); sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free); - sk_X509_pop_free(s->verified_chain, X509_free); + OPENSSL_free(s->client_cert_type); + OPENSSL_free(s->server_cert_type); - if (s->method != NULL) - s->method->ssl_free(s); + OSSL_STACK_OF_X509_free(s->verified_chain); - SSL_CTX_free(s->ctx); + if (ssl->method != NULL) + ssl->method->ssl_deinit(ssl); ASYNC_WAIT_CTX_free(s->waitctx); @@ -1261,31 +1492,66 @@ void SSL_free(SSL *s) sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); #endif - CRYPTO_THREAD_lock_free(s->lock); - - OPENSSL_free(s); + /* + * We do this late. We want to ensure that any other references we held to + * these BIOs are freed first *before* we call BIO_free_all(), because + * BIO_free_all() will only free each BIO in the chain if the number of + * references to the first BIO have dropped to 0 + */ + BIO_free_all(s->wbio); + s->wbio = NULL; + BIO_free_all(s->rbio); + s->rbio = NULL; + OPENSSL_free(s->s3.tmp.valid_flags); } void SSL_set0_rbio(SSL *s, BIO *rbio) { - BIO_free_all(s->rbio); - s->rbio = rbio; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) { + ossl_quic_conn_set0_net_rbio(s, rbio); + return; + } +#endif + + if (sc == NULL) + return; + + BIO_free_all(sc->rbio); + sc->rbio = rbio; + sc->rlayer.rrlmethod->set1_bio(sc->rlayer.rrl, sc->rbio); } void SSL_set0_wbio(SSL *s, BIO *wbio) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) { + ossl_quic_conn_set0_net_wbio(s, wbio); + return; + } +#endif + + if (sc == NULL) + return; + /* * If the output buffering BIO is still in place, remove it */ - if (s->bbio != NULL) - s->wbio = BIO_pop(s->wbio); + if (sc->bbio != NULL) + sc->wbio = BIO_pop(sc->wbio); - BIO_free_all(s->wbio); - s->wbio = wbio; + BIO_free_all(sc->wbio); + sc->wbio = wbio; /* Re-attach |bbio| to the new |wbio|. */ - if (s->bbio != NULL) - s->wbio = BIO_push(s->bbio, s->wbio); + if (sc->bbio != NULL) + sc->wbio = BIO_push(sc->bbio, sc->wbio); + + sc->rlayer.wrlmethod->set1_bio(sc->rlayer.wrl, sc->wbio); } void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) @@ -1330,19 +1596,39 @@ void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) BIO *SSL_get_rbio(const SSL *s) { - return s->rbio; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_conn_get_net_rbio(s); +#endif + + if (sc == NULL) + return NULL; + + return sc->rbio; } BIO *SSL_get_wbio(const SSL *s) { - if (s->bbio != NULL) { + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_conn_get_net_wbio(s); +#endif + + if (sc == NULL) + return NULL; + + if (sc->bbio != NULL) { /* * If |bbio| is active, the true caller-configured BIO is its * |next_bio|. */ - return BIO_next(s->bbio); + return BIO_next(sc->bbio); } - return s->wbio; + return sc->wbio; } int SSL_get_fd(const SSL *s) @@ -1375,12 +1661,27 @@ int SSL_get_wfd(const SSL *s) } #ifndef OPENSSL_NO_SOCK +static const BIO_METHOD *fd_method(SSL *s) +{ +#ifndef OPENSSL_NO_DGRAM + if (IS_QUIC(s)) + return BIO_s_datagram(); +#endif + + return BIO_s_socket(); +} + int SSL_set_fd(SSL *s, int fd) { int ret = 0; BIO *bio = NULL; - bio = BIO_new(BIO_s_socket()); + if (s->type == SSL_TYPE_QUIC_XSO) { + ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY); + goto err; + } + + bio = BIO_new(fd_method(s)); if (bio == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); @@ -1405,10 +1706,16 @@ int SSL_set_fd(SSL *s, int fd) int SSL_set_wfd(SSL *s, int fd) { BIO *rbio = SSL_get_rbio(s); + int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET; - if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET + if (s->type == SSL_TYPE_QUIC_XSO) { + ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY); + return 0; + } + + if (rbio == NULL || BIO_method_type(rbio) != desired_type || (int)BIO_get_fd(rbio, NULL) != fd) { - BIO *bio = BIO_new(BIO_s_socket()); + BIO *bio = BIO_new(fd_method(s)); if (bio == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); @@ -1435,10 +1742,16 @@ int SSL_set_wfd(SSL *s, int fd) int SSL_set_rfd(SSL *s, int fd) { BIO *wbio = SSL_get_wbio(s); + int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET; + + if (s->type == SSL_TYPE_QUIC_XSO) { + ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY); + return 0; + } - if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET + if (wbio == NULL || BIO_method_type(wbio) != desired_type || ((int)BIO_get_fd(wbio, NULL) != fd)) { - BIO *bio = BIO_new(BIO_s_socket()); + BIO *bio = BIO_new(fd_method(s)); if (bio == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); @@ -1459,11 +1772,15 @@ int SSL_set_rfd(SSL *s, int fd) size_t SSL_get_finished(const SSL *s, void *buf, size_t count) { size_t ret = 0; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; - ret = s->s3.tmp.finish_md_len; + ret = sc->s3.tmp.finish_md_len; if (count > ret) count = ret; - memcpy(buf, s->s3.tmp.finish_md, count); + memcpy(buf, sc->s3.tmp.finish_md, count); return ret; } @@ -1471,26 +1788,45 @@ size_t SSL_get_finished(const SSL *s, void *buf, size_t count) size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) { size_t ret = 0; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); - ret = s->s3.tmp.peer_finish_md_len; + if (sc == NULL) + return 0; + + ret = sc->s3.tmp.peer_finish_md_len; if (count > ret) count = ret; - memcpy(buf, s->s3.tmp.peer_finish_md, count); + memcpy(buf, sc->s3.tmp.peer_finish_md, count); return ret; } int SSL_get_verify_mode(const SSL *s) { - return s->verify_mode; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->verify_mode; } int SSL_get_verify_depth(const SSL *s) { - return X509_VERIFY_PARAM_get_depth(s->param); + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return X509_VERIFY_PARAM_get_depth(sc->param); } int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) { - return s->verify_callback; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->verify_callback; } int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) @@ -1510,24 +1846,52 @@ int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) { void SSL_set_verify(SSL *s, int mode, int (*callback) (int ok, X509_STORE_CTX *ctx)) { - s->verify_mode = mode; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->verify_mode = mode; if (callback != NULL) - s->verify_callback = callback; + sc->verify_callback = callback; } void SSL_set_verify_depth(SSL *s, int depth) { - X509_VERIFY_PARAM_set_depth(s->param, depth); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + X509_VERIFY_PARAM_set_depth(sc->param, depth); } void SSL_set_read_ahead(SSL *s, int yes) { - RECORD_LAYER_set_read_ahead(&s->rlayer, yes); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + OSSL_PARAM options[2], *opts = options; + + if (sc == NULL) + return; + + RECORD_LAYER_set_read_ahead(&sc->rlayer, yes); + + *opts++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD, + &sc->rlayer.read_ahead); + *opts = OSSL_PARAM_construct_end(); + + /* Ignore return value */ + sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options); } int SSL_get_read_ahead(const SSL *s) { - return RECORD_LAYER_get_read_ahead(&s->rlayer); + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + return RECORD_LAYER_get_read_ahead(&sc->rlayer); } int SSL_pending(const SSL *s) @@ -1557,24 +1921,32 @@ int SSL_has_pending(const SSL *s) * That data may not result in any application data, or we may fail to parse * the records for some reason. */ + const SSL_CONNECTION *sc; + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_has_pending(s); +#endif + + sc = SSL_CONNECTION_FROM_CONST_SSL(s); /* Check buffered app data if any first */ - if (SSL_IS_DTLS(s)) { - DTLS1_RECORD_DATA *rdata; + if (SSL_CONNECTION_IS_DTLS(sc)) { + TLS_RECORD *rdata; pitem *item, *iter; - iter = pqueue_iterator(s->rlayer.d->buffered_app_data.q); + iter = pqueue_iterator(sc->rlayer.d->buffered_app_data.q); while ((item = pqueue_next(&iter)) != NULL) { rdata = item->data; - if (rdata->rrec.length > 0) + if (rdata->length > 0) return 1; } } - if (RECORD_LAYER_processed_read_pending(&s->rlayer)) + if (RECORD_LAYER_processed_read_pending(&sc->rlayer)) return 1; - return RECORD_LAYER_read_pending(&s->rlayer); + return RECORD_LAYER_read_pending(&sc->rlayer); } X509 *SSL_get1_peer_certificate(const SSL *s) @@ -1589,20 +1961,29 @@ X509 *SSL_get1_peer_certificate(const SSL *s) X509 *SSL_get0_peer_certificate(const SSL *s) { - if ((s == NULL) || (s->session == NULL)) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->session == NULL) return NULL; else - return s->session->peer; + return sc->session->peer; } STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) { STACK_OF(X509) *r; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); - if ((s == NULL) || (s->session == NULL)) + if (sc == NULL) + return NULL; + + if (sc->session == NULL) r = NULL; else - r = s->session->peer_chain; + r = sc->session->peer_chain; /* * If we are a client, cert_chain includes the peer's own certificate; if @@ -1619,6 +2000,13 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) int SSL_copy_session_id(SSL *t, const SSL *f) { int i; + /* TODO(QUIC FUTURE): Not allowed for QUIC currently. */ + SSL_CONNECTION *tsc = SSL_CONNECTION_FROM_SSL_ONLY(t); + const SSL_CONNECTION *fsc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(f); + + if (tsc == NULL || fsc == NULL) + return 0; + /* Do we need to do SSL locking? */ if (!SSL_set_session(t, SSL_get_session(f))) { return 0; @@ -1628,16 +2016,16 @@ int SSL_copy_session_id(SSL *t, const SSL *f) * what if we are setup for one protocol version but want to talk another */ if (t->method != f->method) { - t->method->ssl_free(t); + t->method->ssl_deinit(t); t->method = f->method; - if (t->method->ssl_new(t) == 0) + if (t->method->ssl_init(t) == 0) return 0; } - CRYPTO_UP_REF(&f->cert->references, &i, f->cert->lock); - ssl_cert_free(t->cert); - t->cert = f->cert; - if (!SSL_set_session_id_context(t, f->sid_ctx, (int)f->sid_ctx_length)) { + CRYPTO_UP_REF(&fsc->cert->references, &i); + ssl_cert_free(tsc->cert); + tsc->cert = fsc->cert; + if (!SSL_set_session_id_context(t, fsc->sid_ctx, (int)fsc->sid_ctx_length)) { return 0; } @@ -1662,25 +2050,32 @@ int SSL_CTX_check_private_key(const SSL_CTX *ctx) /* Fix this function so that it takes an optional type parameter */ int SSL_check_private_key(const SSL *ssl) { - if (ssl == NULL) { + const SSL_CONNECTION *sc; + + if ((sc = SSL_CONNECTION_FROM_CONST_SSL(ssl)) == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (ssl->cert->key->x509 == NULL) { + if (sc->cert->key->x509 == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); return 0; } - if (ssl->cert->key->privatekey == NULL) { + if (sc->cert->key->privatekey == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); return 0; } - return X509_check_private_key(ssl->cert->key->x509, - ssl->cert->key->privatekey); + return X509_check_private_key(sc->cert->key->x509, + sc->cert->key->privatekey); } int SSL_waiting_for_async(SSL *s) { - if (s->job) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->job) return 1; return 0; @@ -1688,9 +2083,13 @@ int SSL_waiting_for_async(SSL *s) int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds) { - ASYNC_WAIT_CTX *ctx = s->waitctx; + ASYNC_WAIT_CTX *ctx; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (ctx == NULL) + if (sc == NULL) + return 0; + + if ((ctx = sc->waitctx) == NULL) return 0; return ASYNC_WAIT_CTX_get_all_fds(ctx, fds, numfds); } @@ -1698,9 +2097,13 @@ int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds) int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds) { - ASYNC_WAIT_CTX *ctx = s->waitctx; + ASYNC_WAIT_CTX *ctx; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (ctx == NULL) + if (sc == NULL) + return 0; + + if ((ctx = sc->waitctx) == NULL) return 0; return ASYNC_WAIT_CTX_get_changed_fds(ctx, addfd, numaddfds, delfd, numdelfds); @@ -1720,21 +2123,35 @@ int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg) int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback) { - s->async_cb = callback; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + sc->async_cb = callback; return 1; } int SSL_set_async_callback_arg(SSL *s, void *arg) { - s->async_cb_arg = arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + sc->async_cb_arg = arg; return 1; } int SSL_get_async_status(SSL *s, int *status) { - ASYNC_WAIT_CTX *ctx = s->waitctx; + ASYNC_WAIT_CTX *ctx; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (ctx == NULL) + if (sc == NULL) + return 0; + + if ((ctx = sc->waitctx) == NULL) return 0; *status = ASYNC_WAIT_CTX_get_status(ctx); return 1; @@ -1742,7 +2159,17 @@ int SSL_get_async_status(SSL *s, int *status) int SSL_accept(SSL *s) { - if (s->handshake_func == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return s->method->ssl_accept(s); +#endif + + if (sc == NULL) + return 0; + + if (sc->handshake_func == NULL) { /* Not properly initialized yet */ SSL_set_accept_state(s); } @@ -1752,7 +2179,17 @@ int SSL_accept(SSL *s) int SSL_connect(SSL *s) { - if (s->handshake_func == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return s->method->ssl_connect(s); +#endif + + if (sc == NULL) + return 0; + + if (sc->handshake_func == NULL) { /* Not properly initialized yet */ SSL_set_connect_state(s); } @@ -1762,48 +2199,57 @@ int SSL_connect(SSL *s) long SSL_get_default_timeout(const SSL *s) { - return s->method->get_timeout(); + return (long int)ossl_time2seconds(s->method->get_timeout()); } static int ssl_async_wait_ctx_cb(void *arg) { SSL *s = (SSL *)arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; - return s->async_cb(s, s->async_cb_arg); + return sc->async_cb(s, sc->async_cb_arg); } static int ssl_start_async_job(SSL *s, struct ssl_async_args *args, int (*func) (void *)) { int ret; - if (s->waitctx == NULL) { - s->waitctx = ASYNC_WAIT_CTX_new(); - if (s->waitctx == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->waitctx == NULL) { + sc->waitctx = ASYNC_WAIT_CTX_new(); + if (sc->waitctx == NULL) return -1; - if (s->async_cb != NULL + if (sc->async_cb != NULL && !ASYNC_WAIT_CTX_set_callback - (s->waitctx, ssl_async_wait_ctx_cb, s)) + (sc->waitctx, ssl_async_wait_ctx_cb, s)) return -1; } - s->rwstate = SSL_NOTHING; - switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args, + sc->rwstate = SSL_NOTHING; + switch (ASYNC_start_job(&sc->job, sc->waitctx, &ret, func, args, sizeof(struct ssl_async_args))) { case ASYNC_ERR: - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_NOTHING; ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC); return -1; case ASYNC_PAUSE: - s->rwstate = SSL_ASYNC_PAUSED; + sc->rwstate = SSL_ASYNC_PAUSED; return -1; case ASYNC_NO_JOBS: - s->rwstate = SSL_ASYNC_NO_JOBS; + sc->rwstate = SSL_ASYNC_NO_JOBS; return -1; case ASYNC_FINISH: - s->job = NULL; + sc->job = NULL; return ret; default: - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_NOTHING; ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); /* Shouldn't happen */ return -1; @@ -1816,16 +2262,20 @@ static int ssl_io_intern(void *vargs) SSL *s; void *buf; size_t num; + SSL_CONNECTION *sc; args = (struct ssl_async_args *)vargs; s = args->s; buf = args->buf; num = args->num; + if ((sc = SSL_CONNECTION_FROM_SSL(s)) == NULL) + return -1; + switch (args->type) { case READFUNC: - return args->f.func_read(s, buf, num, &s->asyncrw); + return args->f.func_read(s, buf, num, &sc->asyncrw); case WRITEFUNC: - return args->f.func_write(s, buf, num, &s->asyncrw); + return args->f.func_write(s, buf, num, &sc->asyncrw); case OTHERFUNC: return args->f.func_other(s); } @@ -1834,18 +2284,28 @@ static int ssl_io_intern(void *vargs) int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { - if (s->handshake_func == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return s->method->ssl_read(s, buf, num, readbytes); +#endif + + if (sc == NULL) + return -1; + + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - s->rwstate = SSL_NOTHING; + if (sc->shutdown & SSL_RECEIVED_SHUTDOWN) { + sc->rwstate = SSL_NOTHING; return 0; } - if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY - || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) { + if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY + || sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) { ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -1853,9 +2313,9 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) * If we are a client and haven't received the ServerHello etc then we * better do that */ - ossl_statem_check_finish_init(s, 0); + ossl_statem_check_finish_init(sc, 0); - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; int ret; @@ -1866,7 +2326,7 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) args.f.func_read = s->method->ssl_read; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *readbytes = s->asyncrw; + *readbytes = sc->asyncrw; return ret; } else { return s->method->ssl_read(s, buf, num, readbytes); @@ -1907,13 +2367,15 @@ int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes) int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) { int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); - if (!s->server) { + /* TODO(QUIC 0RTT): 0-RTT support */ + if (sc == NULL || !sc->server) { ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return SSL_READ_EARLY_DATA_ERROR; } - switch (s->early_data_state) { + switch (sc->early_data_state) { case SSL_EARLY_DATA_NONE: if (!SSL_in_before(s)) { ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -1922,32 +2384,32 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) /* fall through */ case SSL_EARLY_DATA_ACCEPT_RETRY: - s->early_data_state = SSL_EARLY_DATA_ACCEPTING; + sc->early_data_state = SSL_EARLY_DATA_ACCEPTING; ret = SSL_accept(s); if (ret <= 0) { /* NBIO or error */ - s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY; + sc->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY; return SSL_READ_EARLY_DATA_ERROR; } /* fall through */ case SSL_EARLY_DATA_READ_RETRY: - if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) { - s->early_data_state = SSL_EARLY_DATA_READING; + if (sc->ext.early_data == SSL_EARLY_DATA_ACCEPTED) { + sc->early_data_state = SSL_EARLY_DATA_READING; ret = SSL_read_ex(s, buf, num, readbytes); /* * State machine will update early_data_state to * SSL_EARLY_DATA_FINISHED_READING if we get an EndOfEarlyData * message */ - if (ret > 0 || (ret <= 0 && s->early_data_state + if (ret > 0 || (ret <= 0 && sc->early_data_state != SSL_EARLY_DATA_FINISHED_READING)) { - s->early_data_state = SSL_EARLY_DATA_READ_RETRY; + sc->early_data_state = SSL_EARLY_DATA_READ_RETRY; return ret > 0 ? SSL_READ_EARLY_DATA_SUCCESS : SSL_READ_EARLY_DATA_ERROR; } } else { - s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; + sc->early_data_state = SSL_EARLY_DATA_FINISHED_READING; } *readbytes = 0; return SSL_READ_EARLY_DATA_FINISH; @@ -1960,20 +2422,36 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) int SSL_get_early_data_status(const SSL *s) { - return s->ext.early_data; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + /* TODO(QUIC 0RTT): 0-RTT support */ + if (sc == NULL) + return 0; + + return sc->ext.early_data; } static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { - if (s->handshake_func == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return s->method->ssl_peek(s, buf, num, readbytes); +#endif + + if (sc == NULL) + return 0; + + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + if (sc->shutdown & SSL_RECEIVED_SHUTDOWN) { return 0; } - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; int ret; @@ -1984,7 +2462,7 @@ static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes) args.f.func_read = s->method->ssl_peek; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *readbytes = s->asyncrw; + *readbytes = sc->asyncrw; return ret; } else { return s->method->ssl_peek(s, buf, num, readbytes); @@ -2025,27 +2503,37 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes) int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) { - if (s->handshake_func == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return s->method->ssl_write(s, buf, num, written); +#endif + + if (sc == NULL) + return 0; + + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } - if (s->shutdown & SSL_SENT_SHUTDOWN) { - s->rwstate = SSL_NOTHING; + if (sc->shutdown & SSL_SENT_SHUTDOWN) { + sc->rwstate = SSL_NOTHING; ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); return -1; } - if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY - || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY - || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) { + if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY + || sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY + || sc->early_data_state == SSL_EARLY_DATA_READ_RETRY) { ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } /* If we are a client and haven't sent the Finished we better do that */ - ossl_statem_check_finish_init(s, 1); + ossl_statem_check_finish_init(sc, 1); - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { int ret; struct ssl_async_args args; @@ -2056,7 +2544,7 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) args.f.func_write = s->method->ssl_write; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *written = s->asyncrw; + *written = sc->asyncrw; return ret; } else { return s->method->ssl_write(s, buf, num, written); @@ -2066,25 +2554,29 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) { ossl_ssize_t ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; - if (s->handshake_func == NULL) { + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } - if (s->shutdown & SSL_SENT_SHUTDOWN) { - s->rwstate = SSL_NOTHING; + if (sc->shutdown & SSL_SENT_SHUTDOWN) { + sc->rwstate = SSL_NOTHING; ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); return -1; } - if (!BIO_get_ktls_send(s->wbio)) { + if (!BIO_get_ktls_send(sc->wbio)) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } /* If we have an alert to send, lets send it */ - if (s->s3.alert_dispatch) { + if (sc->s3.alert_dispatch > 0) { ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s); if (ret <= 0) { /* SSLfatal() already called if appropriate */ @@ -2093,10 +2585,10 @@ ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) /* if it went, fall through and send more stuff */ } - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - if (!BIO_should_retry(s->wbio)) { - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_WRITING; + if (BIO_flush(sc->wbio) <= 0) { + if (!BIO_should_retry(sc->wbio)) { + sc->rwstate = SSL_NOTHING; } else { #ifdef EAGAIN set_sys_error(EAGAIN); @@ -2116,13 +2608,13 @@ ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) if ((get_last_sys_error() == EAGAIN) || (get_last_sys_error() == EINTR) || (get_last_sys_error() == EBUSY)) - BIO_set_retry_write(s->wbio); + BIO_set_retry_write(sc->wbio); else #endif ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return ret; } - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_NOTHING; return ret; #endif } @@ -2163,64 +2655,69 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) int ret, early_data_state; size_t writtmp; uint32_t partialwrite; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); - switch (s->early_data_state) { + /* TODO(QUIC 0RTT): This will need special handling for QUIC */ + if (sc == NULL) + return 0; + + switch (sc->early_data_state) { case SSL_EARLY_DATA_NONE: - if (s->server + if (sc->server || !SSL_in_before(s) - || ((s->session == NULL || s->session->ext.max_early_data == 0) - && (s->psk_use_session_cb == NULL))) { + || ((sc->session == NULL || sc->session->ext.max_early_data == 0) + && (sc->psk_use_session_cb == NULL))) { ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } /* fall through */ case SSL_EARLY_DATA_CONNECT_RETRY: - s->early_data_state = SSL_EARLY_DATA_CONNECTING; + sc->early_data_state = SSL_EARLY_DATA_CONNECTING; ret = SSL_connect(s); if (ret <= 0) { /* NBIO or error */ - s->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY; + sc->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY; return 0; } /* fall through */ case SSL_EARLY_DATA_WRITE_RETRY: - s->early_data_state = SSL_EARLY_DATA_WRITING; + sc->early_data_state = SSL_EARLY_DATA_WRITING; /* * We disable partial write for early data because we don't keep track * of how many bytes we've written between the SSL_write_ex() call and * the flush if the flush needs to be retried) */ - partialwrite = s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE; - s->mode &= ~SSL_MODE_ENABLE_PARTIAL_WRITE; + partialwrite = sc->mode & SSL_MODE_ENABLE_PARTIAL_WRITE; + sc->mode &= ~SSL_MODE_ENABLE_PARTIAL_WRITE; ret = SSL_write_ex(s, buf, num, &writtmp); - s->mode |= partialwrite; + sc->mode |= partialwrite; if (!ret) { - s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; + sc->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; return ret; } - s->early_data_state = SSL_EARLY_DATA_WRITE_FLUSH; + sc->early_data_state = SSL_EARLY_DATA_WRITE_FLUSH; /* fall through */ case SSL_EARLY_DATA_WRITE_FLUSH: /* The buffering BIO is still in place so we need to flush it */ - if (statem_flush(s) != 1) + if (statem_flush(sc) != 1) return 0; *written = num; - s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; + sc->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; return 1; case SSL_EARLY_DATA_FINISHED_READING: case SSL_EARLY_DATA_READ_RETRY: - early_data_state = s->early_data_state; + early_data_state = sc->early_data_state; /* We are a server writing to an unauthenticated client */ - s->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING; + sc->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING; ret = SSL_write_ex(s, buf, num, written); /* The buffering BIO is still in place */ if (ret) - (void)BIO_flush(s->wbio); - s->early_data_state = early_data_state; + (void)BIO_flush(sc->wbio); + sc->early_data_state = early_data_state; return ret; default: @@ -2237,14 +2734,23 @@ int SSL_shutdown(SSL *s) * calling it once is usually not enough, even if blocking I/O is used * (see ssl3_shutdown). */ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_conn_shutdown(s, 0, NULL, 0); +#endif - if (s->handshake_func == NULL) { + if (sc == NULL) + return -1; + + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } if (!SSL_in_init(s)) { - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; memset(&args, 0, sizeof(args)); @@ -2264,7 +2770,17 @@ int SSL_shutdown(SSL *s) int SSL_key_update(SSL *s, int updatetype) { - if (!SSL_IS_TLS13(s)) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_key_update(s, updatetype); +#endif + + if (sc == NULL) + return 0; + + if (!SSL_CONNECTION_IS_TLS13(sc)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } @@ -2280,33 +2796,43 @@ int SSL_key_update(SSL *s, int updatetype) return 0; } - if (RECORD_LAYER_write_pending(&s->rlayer)) { + if (RECORD_LAYER_write_pending(&sc->rlayer)) { ERR_raise(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY); return 0; } - ossl_statem_set_in_init(s, 1); - s->key_update = updatetype; + ossl_statem_set_in_init(sc, 1); + sc->key_update = updatetype; return 1; } int SSL_get_key_update_type(const SSL *s) { - return s->key_update; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_key_update_type(s); +#endif + + if (sc == NULL) + return 0; + + return sc->key_update; } /* * Can we accept a renegotiation request? If yes, set the flag and * return 1 if yes. If not, raise error and return 0. */ -static int can_renegotiate(const SSL *s) +static int can_renegotiate(const SSL_CONNECTION *sc) { - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(sc)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } - if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + if ((sc->options & SSL_OP_NO_RENEGOTIATION) != 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION); return 0; } @@ -2316,153 +2842,203 @@ static int can_renegotiate(const SSL *s) int SSL_renegotiate(SSL *s) { - if (!can_renegotiate(s)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + if (!can_renegotiate(sc)) return 0; - s->renegotiate = 1; - s->new_session = 1; + sc->renegotiate = 1; + sc->new_session = 1; return s->method->ssl_renegotiate(s); } int SSL_renegotiate_abbreviated(SSL *s) { - if (!can_renegotiate(s)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) return 0; - s->renegotiate = 1; - s->new_session = 0; + if (!can_renegotiate(sc)) + return 0; + + sc->renegotiate = 1; + sc->new_session = 0; return s->method->ssl_renegotiate(s); } int SSL_renegotiate_pending(const SSL *s) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + /* * becomes true when negotiation is requested; false again once a * handshake has finished */ - return (s->renegotiate != 0); + return (sc->renegotiate != 0); } int SSL_new_session_ticket(SSL *s) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + /* If we are in init because we're sending tickets, okay to send more. */ - if ((SSL_in_init(s) && s->ext.extra_tickets_expected == 0) - || SSL_IS_FIRST_HANDSHAKE(s) || !s->server - || !SSL_IS_TLS13(s)) + if ((SSL_in_init(s) && sc->ext.extra_tickets_expected == 0) + || SSL_IS_FIRST_HANDSHAKE(sc) || !sc->server + || !SSL_CONNECTION_IS_TLS13(sc)) return 0; - s->ext.extra_tickets_expected++; - if (!RECORD_LAYER_write_pending(&s->rlayer) && !SSL_in_init(s)) - ossl_statem_set_in_init(s, 1); + sc->ext.extra_tickets_expected++; + if (!RECORD_LAYER_write_pending(&sc->rlayer) && !SSL_in_init(s)) + ossl_statem_set_in_init(sc, 1); return 1; } long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + return ossl_ctrl_internal(s, cmd, larg, parg, /*no_quic=*/0); +} + +long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic) { long l; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + /* + * Routing of ctrl calls for QUIC is a little counterintuitive: + * + * - Firstly (no_quic=0), we pass the ctrl directly to our QUIC + * implementation in case it wants to handle the ctrl specially. + * + * - If our QUIC implementation does not care about the ctrl, it + * will reenter this function with no_quic=1 and we will try to handle + * it directly using the QCSO SSL object stub (not the handshake layer + * SSL object). This is important for e.g. the version configuration + * ctrls below, which must use s->defltmeth (and not sc->defltmeth). + * + * - If we don't handle a ctrl here specially, then processing is + * redirected to the handshake layer SSL object. + */ + if (!no_quic && IS_QUIC(s)) + return s->method->ssl_ctrl(s, cmd, larg, parg); switch (cmd) { case SSL_CTRL_GET_READ_AHEAD: - return RECORD_LAYER_get_read_ahead(&s->rlayer); + return RECORD_LAYER_get_read_ahead(&sc->rlayer); case SSL_CTRL_SET_READ_AHEAD: - l = RECORD_LAYER_get_read_ahead(&s->rlayer); - RECORD_LAYER_set_read_ahead(&s->rlayer, larg); + l = RECORD_LAYER_get_read_ahead(&sc->rlayer); + RECORD_LAYER_set_read_ahead(&sc->rlayer, larg); return l; - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - s->msg_callback_arg = parg; - return 1; - case SSL_CTRL_MODE: - return (s->mode |= larg); + { + OSSL_PARAM options[2], *opts = options; + + sc->mode |= larg; + + *opts++ = OSSL_PARAM_construct_uint32(OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE, + &sc->mode); + *opts = OSSL_PARAM_construct_end(); + + /* Ignore return value */ + sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options); + + return sc->mode; + } case SSL_CTRL_CLEAR_MODE: - return (s->mode &= ~larg); + return (sc->mode &= ~larg); case SSL_CTRL_GET_MAX_CERT_LIST: - return (long)s->max_cert_list; + return (long)sc->max_cert_list; case SSL_CTRL_SET_MAX_CERT_LIST: if (larg < 0) return 0; - l = (long)s->max_cert_list; - s->max_cert_list = (size_t)larg; + l = (long)sc->max_cert_list; + sc->max_cert_list = (size_t)larg; return l; case SSL_CTRL_SET_MAX_SEND_FRAGMENT: if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) return 0; #ifndef OPENSSL_NO_KTLS - if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) + if (sc->wbio != NULL && BIO_get_ktls_send(sc->wbio)) return 0; #endif /* OPENSSL_NO_KTLS */ - s->max_send_fragment = larg; - if (s->max_send_fragment < s->split_send_fragment) - s->split_send_fragment = s->max_send_fragment; + sc->max_send_fragment = larg; + if (sc->max_send_fragment < sc->split_send_fragment) + sc->split_send_fragment = sc->max_send_fragment; + sc->rlayer.wrlmethod->set_max_frag_len(sc->rlayer.wrl, larg); return 1; case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT: - if ((size_t)larg > s->max_send_fragment || larg == 0) + if ((size_t)larg > sc->max_send_fragment || larg == 0) return 0; - s->split_send_fragment = larg; + sc->split_send_fragment = larg; return 1; case SSL_CTRL_SET_MAX_PIPELINES: if (larg < 1 || larg > SSL_MAX_PIPELINES) return 0; - s->max_pipelines = larg; - if (larg > 1) - RECORD_LAYER_set_read_ahead(&s->rlayer, 1); + sc->max_pipelines = larg; + if (sc->rlayer.rrlmethod->set_max_pipelines != NULL) + sc->rlayer.rrlmethod->set_max_pipelines(sc->rlayer.rrl, (size_t)larg); return 1; case SSL_CTRL_GET_RI_SUPPORT: - return s->s3.send_connection_binding; + return sc->s3.send_connection_binding; case SSL_CTRL_SET_RETRY_VERIFY: - s->rwstate = SSL_RETRY_VERIFY; + sc->rwstate = SSL_RETRY_VERIFY; return 1; case SSL_CTRL_CERT_FLAGS: - return (s->cert->cert_flags |= larg); + return (sc->cert->cert_flags |= larg); case SSL_CTRL_CLEAR_CERT_FLAGS: - return (s->cert->cert_flags &= ~larg); + return (sc->cert->cert_flags &= ~larg); case SSL_CTRL_GET_RAW_CIPHERLIST: if (parg) { - if (s->s3.tmp.ciphers_raw == NULL) + if (sc->s3.tmp.ciphers_raw == NULL) return 0; - *(unsigned char **)parg = s->s3.tmp.ciphers_raw; - return (int)s->s3.tmp.ciphers_rawlen; + *(unsigned char **)parg = sc->s3.tmp.ciphers_raw; + return (int)sc->s3.tmp.ciphers_rawlen; } else { return TLS_CIPHER_LEN; } case SSL_CTRL_GET_EXTMS_SUPPORT: - if (!s->session || SSL_in_init(s) || ossl_statem_get_in_handshake(s)) + if (!sc->session || SSL_in_init(s) || ossl_statem_get_in_handshake(sc)) return -1; - if (s->session->flags & SSL_SESS_FLAG_EXTMS) + if (sc->session->flags & SSL_SESS_FLAG_EXTMS) return 1; else return 0; case SSL_CTRL_SET_MIN_PROTO_VERSION: - return ssl_check_allowed_versions(larg, s->max_proto_version) - && ssl_set_version_bound(s->ctx->method->version, (int)larg, - &s->min_proto_version); + return ssl_check_allowed_versions(larg, sc->max_proto_version) + && ssl_set_version_bound(s->defltmeth->version, (int)larg, + &sc->min_proto_version); case SSL_CTRL_GET_MIN_PROTO_VERSION: - return s->min_proto_version; + return sc->min_proto_version; case SSL_CTRL_SET_MAX_PROTO_VERSION: - return ssl_check_allowed_versions(s->min_proto_version, larg) - && ssl_set_version_bound(s->ctx->method->version, (int)larg, - &s->max_proto_version); + return ssl_check_allowed_versions(sc->min_proto_version, larg) + && ssl_set_version_bound(s->defltmeth->version, (int)larg, + &sc->max_proto_version); case SSL_CTRL_GET_MAX_PROTO_VERSION: - return s->max_proto_version; + return sc->max_proto_version; default: - return s->method->ssl_ctrl(s, cmd, larg, parg); + if (IS_QUIC(s)) + return SSL_ctrl((SSL *)sc, cmd, larg, parg); + else + return s->method->ssl_ctrl(s, cmd, larg, parg); } } long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) { - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - s->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return s->method->ssl_callback_ctrl(s, cmd, fp); - } + return s->method->ssl_callback_ctrl(s, cmd, fp); } LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) @@ -2633,13 +3209,17 @@ int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, return 0; } -/** return a STACK of the ciphers available for the SSL and in order of - * preference */ +/* + * return a STACK of the ciphers available for the SSL and in order of + * preference + */ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) { - if (s != NULL) { - if (s->cipher_list != NULL) { - return s->cipher_list; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc != NULL) { + if (sc->cipher_list != NULL) { + return sc->cipher_list; } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { return s->ctx->cipher_list; } @@ -2649,24 +3229,30 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s) { - if ((s == NULL) || !s->server) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL || !sc->server) return NULL; - return s->peer_ciphers; + return sc->peer_ciphers; } STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) { STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers; int i; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; ciphers = SSL_get_ciphers(s); if (!ciphers) return NULL; - if (!ssl_set_client_disabled(s)) + if (!ssl_set_client_disabled(sc)) return NULL; for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); - if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) { + if (!ssl_cipher_disabled(sc, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) { if (!sk) sk = sk_SSL_CIPHER_new_null(); if (!sk) @@ -2682,14 +3268,14 @@ STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) /** return a STACK of the ciphers available for the SSL and in order of * algorithm id */ -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL_CONNECTION *s) { if (s != NULL) { - if (s->cipher_list_by_id != NULL) { + if (s->cipher_list_by_id != NULL) return s->cipher_list_by_id; - } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) { - return s->ctx->cipher_list_by_id; - } + else if (s->ssl.ctx != NULL + && s->ssl.ctx->cipher_list_by_id != NULL) + return s->ssl.ctx->cipher_list_by_id; } return NULL; } @@ -2768,10 +3354,14 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) int SSL_set_cipher_list(SSL *s, const char *str) { STACK_OF(SSL_CIPHER) *sk; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; - sk = ssl_create_cipher_list(s->ctx, s->tls13_ciphersuites, - &s->cipher_list, &s->cipher_list_by_id, str, - s->cert); + sk = ssl_create_cipher_list(s->ctx, sc->tls13_ciphersuites, + &sc->cipher_list, &sc->cipher_list_by_id, str, + sc->cert); /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; @@ -2788,14 +3378,18 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) STACK_OF(SSL_CIPHER) *clntsk, *srvrsk; const SSL_CIPHER *c; int i; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; - if (!s->server - || s->peer_ciphers == NULL + if (!sc->server + || sc->peer_ciphers == NULL || size < 2) return NULL; p = buf; - clntsk = s->peer_ciphers; + clntsk = sc->peer_ciphers; srvrsk = SSL_get_ciphers(s); if (clntsk == NULL || srvrsk == NULL) return NULL; @@ -2833,16 +3427,23 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) * - if we are before or during/after the handshake, * - if a resumption or normal handshake is being attempted/has occurred * - whether we have negotiated TLSv1.2 (or below) or TLSv1.3 - * + * * Note that only the host_name type is defined (RFC 3546). */ const char *SSL_get_servername(const SSL *s, const int type) { + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + int server; + + if (sc == NULL) + return NULL; + /* * If we don't know if we are the client or the server yet then we assume * client. */ - int server = s->handshake_func == NULL ? 0 : s->server; + server = sc->handshake_func == NULL ? 0 : sc->server; + if (type != TLSEXT_NAMETYPE_host_name) return NULL; @@ -2863,8 +3464,8 @@ const char *SSL_get_servername(const SSL *s, const int type) * - The function will return the servername requested by the client in * this handshake or NULL if none was requested. */ - if (s->hit && !SSL_IS_TLS13(s)) - return s->session->ext.hostname; + if (sc->hit && !SSL_CONNECTION_IS_TLS13(sc)) + return sc->session->ext.hostname; } else { /** * Client side @@ -2889,17 +3490,18 @@ const char *SSL_get_servername(const SSL *s, const int type) * (or NULL if it was not called). */ if (SSL_in_before(s)) { - if (s->ext.hostname == NULL - && s->session != NULL - && s->session->ssl_version != TLS1_3_VERSION) - return s->session->ext.hostname; + if (sc->ext.hostname == NULL + && sc->session != NULL + && sc->session->ssl_version != TLS1_3_VERSION) + return sc->session->ext.hostname; } else { - if (!SSL_IS_TLS13(s) && s->hit && s->session->ext.hostname != NULL) - return s->session->ext.hostname; + if (!SSL_CONNECTION_IS_TLS13(sc) && sc->hit + && sc->session->ext.hostname != NULL) + return sc->session->ext.hostname; } } - return s->ext.hostname; + return sc->ext.hostname; } int SSL_get_servername_type(const SSL *s) @@ -2979,11 +3581,20 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len) { - *data = s->ext.npn; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) { + /* We have no other way to indicate error */ + *data = NULL; + *len = 0; + return; + } + + *data = sc->ext.npn; if (*data == NULL) { *len = 0; } else { - *len = (unsigned int)s->ext.npn_len; + *len = (unsigned int)sc->ext.npn_len; } } @@ -3001,6 +3612,10 @@ void SSL_CTX_set_npn_advertised_cb(SSL_CTX *ctx, SSL_CTX_npn_advertised_cb_func cb, void *arg) { + if (IS_QUIC_CTX(ctx)) + /* NPN not allowed for QUIC */ + return; + ctx->ext.npn_advertised_cb = cb; ctx->ext.npn_advertised_cb_arg = arg; } @@ -3019,6 +3634,10 @@ void SSL_CTX_set_npn_select_cb(SSL_CTX *ctx, SSL_CTX_npn_select_cb_func cb, void *arg) { + if (IS_QUIC_CTX(ctx)) + /* NPN not allowed for QUIC */ + return; + ctx->ext.npn_select_cb = cb; ctx->ext.npn_select_cb_arg = arg; } @@ -3058,10 +3677,8 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, return 1; alpn = OPENSSL_memdup(protos, protos_len); - if (alpn == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (alpn == NULL) return 1; - } OPENSSL_free(ctx->ext.alpn); ctx->ext.alpn = alpn; ctx->ext.alpn_len = protos_len; @@ -3078,11 +3695,15 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, unsigned int protos_len) { unsigned char *alpn; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 1; if (protos_len == 0 || protos == NULL) { - OPENSSL_free(ssl->ext.alpn); - ssl->ext.alpn = NULL; - ssl->ext.alpn_len = 0; + OPENSSL_free(sc->ext.alpn); + sc->ext.alpn = NULL; + sc->ext.alpn_len = 0; return 0; } /* Not valid per RFC */ @@ -3090,13 +3711,11 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, return 1; alpn = OPENSSL_memdup(protos, protos_len); - if (alpn == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (alpn == NULL) return 1; - } - OPENSSL_free(ssl->ext.alpn); - ssl->ext.alpn = alpn; - ssl->ext.alpn_len = protos_len; + OPENSSL_free(sc->ext.alpn); + sc->ext.alpn = alpn; + sc->ext.alpn_len = protos_len; return 0; } @@ -3123,11 +3742,20 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, unsigned int *len) { - *data = ssl->s3.alpn_selected; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) { + /* We have no other way to indicate error */ + *data = NULL; + *len = 0; + return; + } + + *data = sc->s3.alpn_selected; if (*data == NULL) *len = 0; else - *len = (unsigned int)ssl->s3.alpn_selected_len; + *len = (unsigned int)sc->s3.alpn_selected_len; } int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, @@ -3135,11 +3763,16 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *context, size_t contextlen, int use_context) { - if (s->session == NULL - || (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + + if (sc->session == NULL + || (sc->version < TLS1_VERSION && sc->version != DTLS1_BAD_VER)) return -1; - return s->method->ssl3_enc->export_keying_material(s, out, olen, label, + return s->method->ssl3_enc->export_keying_material(sc, out, olen, label, llen, context, contextlen, use_context); } @@ -3149,10 +3782,15 @@ int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, const unsigned char *context, size_t contextlen) { - if (s->version != TLS1_3_VERSION) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + + if (sc->version != TLS1_3_VERSION) return 0; - return tls13_export_keying_material_early(s, out, olen, label, llen, + return tls13_export_keying_material_early(sc, out, olen, label, llen, context, contextlen); } @@ -3203,6 +3841,9 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, const SSL_METHOD *meth) { SSL_CTX *ret = NULL; +#ifndef OPENSSL_NO_COMP_ALG + int i; +#endif if (meth == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED); @@ -3212,27 +3853,32 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL)) return NULL; + /* Doing this for the run once effect */ if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { ERR_raise(ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; } + ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) - goto err; + return NULL; /* Init the reference counting before any call to SSL_CTX_free */ - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret); return NULL; } + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + #ifdef TSAN_REQUIRES_LOCKING ret->tsan_lock = CRYPTO_THREAD_lock_new(); if (ret->tsan_lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } #endif @@ -3254,34 +3900,57 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, ret->session_timeout = meth->get_timeout(); ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; ret->verify_mode = SSL_VERIFY_NONE; - if ((ret->cert = ssl_cert_new()) == NULL) - goto err; ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp); - if (ret->sessions == NULL) + if (ret->sessions == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; + } ret->cert_store = X509_STORE_new(); - if (ret->cert_store == NULL) + if (ret->cert_store == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; + } #ifndef OPENSSL_NO_CT ret->ctlog_store = CTLOG_STORE_new_ex(libctx, propq); - if (ret->ctlog_store == NULL) + if (ret->ctlog_store == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CT_LIB); goto err; + } #endif /* initialize cipher/digest methods table */ - if (!ssl_load_ciphers(ret)) - goto err2; - /* initialise sig algs */ - if (!ssl_setup_sig_algs(ret)) - goto err2; + if (!ssl_load_ciphers(ret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + goto err; + } + + if (!ssl_load_groups(ret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + goto err; + } + + /* load provider sigalgs */ + if (!ssl_load_sigalgs(ret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + goto err; + } + /* initialise sig algs */ + if (!ssl_setup_sigalgs(ret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + goto err; + } - if (!ssl_load_groups(ret)) - goto err2; + if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); + goto err; + } - if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) + if ((ret->cert = ssl_cert_new(SSL_PKEY_NUM + ret->sigalg_list_len)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); goto err; + } if (!ssl_create_cipher_list(ret, ret->tls13_ciphersuites, @@ -3289,12 +3958,14 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, OSSL_default_cipher_list(), ret->cert) || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { ERR_raise(ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS); - goto err2; + goto err; } ret->param = X509_VERIFY_PARAM_new(); - if (ret->param == NULL) + if (ret->param == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; + } /* * If these aren't available from the provider we'll get NULL returns. @@ -3303,14 +3974,20 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, ret->md5 = ssl_evp_md_fetch(libctx, NID_md5, propq); ret->sha1 = ssl_evp_md_fetch(libctx, NID_sha1, propq); - if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) + if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; + } - if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL) + if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; + } - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data)) + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; + } if ((ret->ext.secure = OPENSSL_secure_zalloc(sizeof(*ret->ext.secure))) == NULL) goto err; @@ -3332,12 +4009,16 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, ret->options |= SSL_OP_NO_TICKET; if (RAND_priv_bytes_ex(libctx, ret->ext.cookie_hmac_key, - sizeof(ret->ext.cookie_hmac_key), 0) <= 0) + sizeof(ret->ext.cookie_hmac_key), 0) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB); goto err; + } #ifndef OPENSSL_NO_SRP - if (!ssl_ctx_srp_ctx_init_intern(ret)) + if (!ssl_ctx_srp_ctx_init_intern(ret)) { + ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); goto err; + } #endif #ifndef OPENSSL_NO_ENGINE # ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO @@ -3356,6 +4037,21 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, ERR_clear_error(); } # endif +#endif + +#ifndef OPENSSL_NO_COMP_ALG + /* + * Set the default order: brotli, zlib, zstd + * Including only those enabled algorithms + */ + memset(ret->cert_comp_prefs, 0, sizeof(ret->cert_comp_prefs)); + i = 0; + if (ossl_comp_has_alg(TLSEXT_comp_cert_brotli)) + ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_brotli; + if (ossl_comp_has_alg(TLSEXT_comp_cert_zlib)) + ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zlib; + if (ossl_comp_has_alg(TLSEXT_comp_cert_zstd)) + ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zstd; #endif /* * Disable compression by default to prevent CRIME. Applications can @@ -3404,8 +4100,6 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, return ret; err: - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); - err2: SSL_CTX_free(ret); return NULL; } @@ -3419,7 +4113,7 @@ int SSL_CTX_up_ref(SSL_CTX *ctx) { int i; - if (CRYPTO_UP_REF(&ctx->references, &i, ctx->lock) <= 0) + if (CRYPTO_UP_REF(&ctx->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL_CTX", ctx); @@ -3435,7 +4129,7 @@ void SSL_CTX_free(SSL_CTX *a) if (a == NULL) return; - CRYPTO_DOWN_REF(&a->references, &i, a->lock); + CRYPTO_DOWN_REF(&a->references, &i); REF_PRINT_COUNT("SSL_CTX", a); if (i > 0) return; @@ -3468,7 +4162,7 @@ void SSL_CTX_free(SSL_CTX *a) ssl_cert_free(a->cert); sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free); sk_X509_NAME_pop_free(a->client_ca_names, X509_NAME_free); - sk_X509_pop_free(a->extra_certs, X509_free); + OSSL_STACK_OF_X509_free(a->extra_certs); a->comp_methods = NULL; #ifndef OPENSSL_NO_SRTP sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); @@ -3499,10 +4193,28 @@ void SSL_CTX_free(SSL_CTX *a) OPENSSL_free(a->group_list[j].algorithm); } OPENSSL_free(a->group_list); + for (j = 0; j < a->sigalg_list_len; j++) { + OPENSSL_free(a->sigalg_list[j].name); + OPENSSL_free(a->sigalg_list[j].sigalg_name); + OPENSSL_free(a->sigalg_list[j].sigalg_oid); + OPENSSL_free(a->sigalg_list[j].sig_name); + OPENSSL_free(a->sigalg_list[j].sig_oid); + OPENSSL_free(a->sigalg_list[j].hash_name); + OPENSSL_free(a->sigalg_list[j].hash_oid); + OPENSSL_free(a->sigalg_list[j].keytype); + OPENSSL_free(a->sigalg_list[j].keytype_oid); + } + OPENSSL_free(a->sigalg_list); + OPENSSL_free(a->ssl_cert_info); OPENSSL_free(a->sigalg_lookup_cache); + OPENSSL_free(a->tls12_sigalgs); + + OPENSSL_free(a->client_cert_type); + OPENSSL_free(a->server_cert_type); CRYPTO_THREAD_lock_free(a->lock); + CRYPTO_FREE_REF(&a->references); #ifdef TSAN_REQUIRES_LOCKING CRYPTO_THREAD_lock_free(a->tsan_lock); #endif @@ -3534,22 +4246,42 @@ void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb) { - s->default_passwd_callback = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->default_passwd_callback = cb; } void SSL_set_default_passwd_cb_userdata(SSL *s, void *u) { - s->default_passwd_callback_userdata = u; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->default_passwd_callback_userdata = u; } pem_password_cb *SSL_get_default_passwd_cb(SSL *s) { - return s->default_passwd_callback; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->default_passwd_callback; } void *SSL_get_default_passwd_cb_userdata(SSL *s) { - return s->default_passwd_callback_userdata; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->default_passwd_callback_userdata; } void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, @@ -3579,10 +4311,15 @@ void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), void *arg) void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) { - ssl_cert_set_cert_cb(s->cert, cb, arg); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + ssl_cert_set_cert_cb(sc->cert, cb, arg); } -void ssl_set_masks(SSL *s) +void ssl_set_masks(SSL_CONNECTION *s) { CERT *c = s->cert; uint32_t *pvalid = s->s3.tmp.valid_flags; @@ -3635,7 +4372,7 @@ void ssl_set_masks(SSL *s) if (rsa_enc || rsa_sign || (ssl_has_cert(s, SSL_PKEY_RSA_PSS_SIGN) && pvalid[SSL_PKEY_RSA_PSS_SIGN] & CERT_PKEY_EXPLICIT_SIGN - && TLS1_get_version(s) == TLS1_2_VERSION)) + && TLS1_get_version(&s->ssl) == TLS1_2_VERSION)) mask_a |= SSL_aRSA; if (dsa_sign) { @@ -3644,6 +4381,24 @@ void ssl_set_masks(SSL *s) mask_a |= SSL_aNULL; + /* + * You can do anything with an RPK key, since there's no cert to restrict it + * But we need to check for private keys + */ + if (pvalid[SSL_PKEY_RSA] & CERT_PKEY_RPK) { + mask_a |= SSL_aRSA; + mask_k |= SSL_kRSA; + } + if (pvalid[SSL_PKEY_ECC] & CERT_PKEY_RPK) + mask_a |= SSL_aECDSA; + if (TLS1_get_version(&s->ssl) == TLS1_2_VERSION) { + if (pvalid[SSL_PKEY_RSA_PSS_SIGN] & CERT_PKEY_RPK) + mask_a |= SSL_aRSA; + if (pvalid[SSL_PKEY_ED25519] & CERT_PKEY_RPK + || pvalid[SSL_PKEY_ED448] & CERT_PKEY_RPK) + mask_a |= SSL_aECDSA; + } + /* * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites * depending on the key usage extension. @@ -3660,13 +4415,13 @@ void ssl_set_masks(SSL *s) /* Allow Ed25519 for TLS 1.2 if peer supports it */ if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED25519) && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN - && TLS1_get_version(s) == TLS1_2_VERSION) + && TLS1_get_version(&s->ssl) == TLS1_2_VERSION) mask_a |= SSL_aECDSA; /* Allow Ed448 for TLS 1.2 if peer supports it */ if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED448) && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN - && TLS1_get_version(s) == TLS1_2_VERSION) + && TLS1_get_version(&s->ssl) == TLS1_2_VERSION) mask_a |= SSL_aECDSA; mask_k |= SSL_kECDHE; @@ -3686,7 +4441,7 @@ void ssl_set_masks(SSL *s) s->s3.tmp.mask_a = mask_a; } -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL_CONNECTION *s) { if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aECDSA) { /* key usage, if present, must allow signing */ @@ -3698,7 +4453,8 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) return 1; /* all checks are ok */ } -int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, +int ssl_get_server_cert_serverinfo(SSL_CONNECTION *s, + const unsigned char **serverinfo, size_t *serverinfo_length) { CERT_PKEY *cpk = s->s3.tmp.cert; @@ -3712,7 +4468,7 @@ int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, return 1; } -void ssl_update_cache(SSL *s, int mode) +void ssl_update_cache(SSL_CONNECTION *s, int mode) { int i; @@ -3738,7 +4494,7 @@ void ssl_update_cache(SSL *s, int mode) i = s->session_ctx->session_cache_mode; if ((i & mode) != 0 - && (!s->hit || SSL_IS_TLS13(s))) { + && (!s->hit || SSL_CONNECTION_IS_TLS13(s))) { /* * Add the session to the internal cache. In server side TLSv1.3 we * normally don't do this because by default it's a full stateless ticket @@ -3751,7 +4507,7 @@ void ssl_update_cache(SSL *s, int mode) * - SSL_OP_NO_TICKET is set in which case it is a stateful ticket */ if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0 - && (!SSL_IS_TLS13(s) + && (!SSL_CONNECTION_IS_TLS13(s) || !s->server || (s->max_early_data > 0 && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0) @@ -3766,7 +4522,8 @@ void ssl_update_cache(SSL *s, int mode) */ if (s->session_ctx->new_session_cb != NULL) { SSL_SESSION_up_ref(s->session); - if (!s->session_ctx->new_session_cb(s, s->session)) + if (!s->session_ctx->new_session_cb(SSL_CONNECTION_GET_SSL(s), + s->session)) SSL_SESSION_free(s->session); } } @@ -3797,93 +4554,126 @@ const SSL_METHOD *SSL_get_ssl_method(const SSL *s) int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) { int ret = 1; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + /* Not allowed for QUIC */ + if (sc == NULL + || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth) + || (s->type == SSL_TYPE_SSL_CONNECTION && IS_QUIC_METHOD(meth))) + return 0; if (s->method != meth) { const SSL_METHOD *sm = s->method; - int (*hf) (SSL *) = s->handshake_func; + int (*hf) (SSL *) = sc->handshake_func; if (sm->version == meth->version) s->method = meth; else { - sm->ssl_free(s); + sm->ssl_deinit(s); s->method = meth; - ret = s->method->ssl_new(s); + ret = s->method->ssl_init(s); } if (hf == sm->ssl_connect) - s->handshake_func = meth->ssl_connect; + sc->handshake_func = meth->ssl_connect; else if (hf == sm->ssl_accept) - s->handshake_func = meth->ssl_accept; + sc->handshake_func = meth->ssl_accept; } return ret; } int SSL_get_error(const SSL *s, int i) +{ + return ossl_ssl_get_error(s, i, /*check_err=*/1); +} + +int ossl_ssl_get_error(const SSL *s, int i, int check_err) { int reason; unsigned long l; BIO *bio; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); if (i > 0) return SSL_ERROR_NONE; +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) { + reason = ossl_quic_get_error(s, i); + if (reason != SSL_ERROR_NONE) + return reason; + } +#endif + + if (sc == NULL) + return SSL_ERROR_SSL; + /* * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, * where we do encode the error */ - if ((l = ERR_peek_error()) != 0) { + if (check_err && (l = ERR_peek_error()) != 0) { if (ERR_GET_LIB(l) == ERR_LIB_SYS) return SSL_ERROR_SYSCALL; else return SSL_ERROR_SSL; } - if (SSL_want_read(s)) { - bio = SSL_get_rbio(s); - if (BIO_should_read(bio)) - return SSL_ERROR_WANT_READ; - else if (BIO_should_write(bio)) - /* - * This one doesn't make too much sense ... We never try to write - * to the rbio, and an application program where rbio and wbio - * are separate couldn't even know what it should wait for. - * However if we ever set s->rwstate incorrectly (so that we have - * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and - * wbio *are* the same, this test works around that bug; so it - * might be safer to keep it. - */ - return SSL_ERROR_WANT_WRITE; - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return SSL_ERROR_WANT_CONNECT; - else if (reason == BIO_RR_ACCEPT) - return SSL_ERROR_WANT_ACCEPT; - else - return SSL_ERROR_SYSCALL; /* unknown */ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) +#endif + { + if (SSL_want_read(s)) { + bio = SSL_get_rbio(s); + if (BIO_should_read(bio)) + return SSL_ERROR_WANT_READ; + else if (BIO_should_write(bio)) + /* + * This one doesn't make too much sense ... We never try to + * write to the rbio, and an application program where rbio and + * wbio are separate couldn't even know what it should wait for. + * However if we ever set s->rwstate incorrectly (so that we + * have SSL_want_read(s) instead of SSL_want_write(s)) and rbio + * and wbio *are* the same, this test works around that bug; so + * it might be safer to keep it. + */ + return SSL_ERROR_WANT_WRITE; + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return SSL_ERROR_WANT_CONNECT; + else if (reason == BIO_RR_ACCEPT) + return SSL_ERROR_WANT_ACCEPT; + else + return SSL_ERROR_SYSCALL; /* unknown */ + } } - } - if (SSL_want_write(s)) { - /* Access wbio directly - in order to use the buffered bio if present */ - bio = s->wbio; - if (BIO_should_write(bio)) - return SSL_ERROR_WANT_WRITE; - else if (BIO_should_read(bio)) + if (SSL_want_write(s)) { /* - * See above (SSL_want_read(s) with BIO_should_write(bio)) + * Access wbio directly - in order to use the buffered bio if + * present */ - return SSL_ERROR_WANT_READ; - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return SSL_ERROR_WANT_CONNECT; - else if (reason == BIO_RR_ACCEPT) - return SSL_ERROR_WANT_ACCEPT; - else - return SSL_ERROR_SYSCALL; + bio = sc->wbio; + if (BIO_should_write(bio)) + return SSL_ERROR_WANT_WRITE; + else if (BIO_should_read(bio)) + /* + * See above (SSL_want_read(s) with BIO_should_write(bio)) + */ + return SSL_ERROR_WANT_READ; + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return SSL_ERROR_WANT_CONNECT; + else if (reason == BIO_RR_ACCEPT) + return SSL_ERROR_WANT_ACCEPT; + else + return SSL_ERROR_SYSCALL; + } } } + if (SSL_want_x509_lookup(s)) return SSL_ERROR_WANT_X509_LOOKUP; if (SSL_want_retry_verify(s)) @@ -3895,8 +4685,8 @@ int SSL_get_error(const SSL *s, int i) if (SSL_want_client_hello_cb(s)) return SSL_ERROR_WANT_CLIENT_HELLO_CB; - if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && - (s->s3.warn_alert == SSL_AD_CLOSE_NOTIFY)) + if ((sc->shutdown & SSL_RECEIVED_SHUTDOWN) && + (sc->s3.warn_alert == SSL_AD_CLOSE_NOTIFY)) return SSL_ERROR_ZERO_RETURN; return SSL_ERROR_SYSCALL; @@ -3904,30 +4694,37 @@ int SSL_get_error(const SSL *s, int i) static int ssl_do_handshake_intern(void *vargs) { - struct ssl_async_args *args; - SSL *s; + struct ssl_async_args *args = (struct ssl_async_args *)vargs; + SSL *s = args->s; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - args = (struct ssl_async_args *)vargs; - s = args->s; + if (sc == NULL) + return -1; - return s->handshake_func(s); + return sc->handshake_func(s); } int SSL_do_handshake(SSL *s) { int ret = 1; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (s->handshake_func == NULL) { +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_do_handshake(s); +#endif + + if (sc->handshake_func == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET); return -1; } - ossl_statem_check_finish_init(s, -1); + ossl_statem_check_finish_init(sc, -1); s->method->ssl_renegotiate_check(s, 0); if (SSL_in_init(s) || SSL_in_before(s)) { - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + if ((sc->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; memset(&args, 0, sizeof(args)); @@ -3935,7 +4732,7 @@ int SSL_do_handshake(SSL *s) ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern); } else { - ret = s->handshake_func(s); + ret = sc->handshake_func(s); } } return ret; @@ -3943,20 +4740,40 @@ int SSL_do_handshake(SSL *s) void SSL_set_accept_state(SSL *s) { - s->server = 1; - s->shutdown = 0; - ossl_statem_clear(s); - s->handshake_func = s->method->ssl_accept; - clear_ciphers(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) { + ossl_quic_set_accept_state(s); + return; + } +#endif + + sc->server = 1; + sc->shutdown = 0; + ossl_statem_clear(sc); + sc->handshake_func = s->method->ssl_accept; + /* Ignore return value. Its a void public API function */ + clear_record_layer(sc); } void SSL_set_connect_state(SSL *s) { - s->server = 0; - s->shutdown = 0; - ossl_statem_clear(s); - s->handshake_func = s->method->ssl_connect; - clear_ciphers(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) { + ossl_quic_set_connect_state(s); + return; + } +#endif + + sc->server = 0; + sc->shutdown = 0; + ossl_statem_clear(sc); + sc->handshake_func = s->method->ssl_connect; + /* Ignore return value. Its a void public API function */ + clear_record_layer(sc); } int ssl_undefined_function(SSL *s) @@ -3984,7 +4801,7 @@ const SSL_METHOD *ssl_bad_method(int ver) const char *ssl_protocol_to_string(int version) { - switch(version) + switch (version) { case TLS1_3_VERSION: return "TLSv1.3"; @@ -4017,7 +4834,33 @@ const char *ssl_protocol_to_string(int version) const char *SSL_get_version(const SSL *s) { - return ssl_protocol_to_string(s->version); + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + /* We only support QUICv1 - so if its QUIC its QUICv1 */ + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return "QUICv1"; +#endif + + if (sc == NULL) + return NULL; + + return ssl_protocol_to_string(sc->version); +} + +__owur int SSL_get_handshake_rtt(const SSL *s, uint64_t *rtt) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return -1; + if (sc->ts_msg_write.t <= 0 || sc->ts_msg_read.t <= 0) + return 0; /* data not (yet) available */ + if (sc->ts_msg_read.t < sc->ts_msg_write.t) + return -1; + + *rtt = ossl_time2us(ossl_time_subtract(sc->ts_msg_read, sc->ts_msg_write)); + return 1; } static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src) @@ -4054,10 +4897,16 @@ SSL *SSL_dup(SSL *s) { SSL *ret; int i; + /* TODO(QUIC FUTURE): Add a SSL_METHOD function for duplication */ + SSL_CONNECTION *retsc; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return NULL; /* If we're not quiescent, just up_ref! */ if (!SSL_in_init(s) || !SSL_in_before(s)) { - CRYPTO_UP_REF(&s->references, &i, s->lock); + CRYPTO_UP_REF(&s->references, &i); return s; } @@ -4066,8 +4915,10 @@ SSL *SSL_dup(SSL *s) */ if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) return NULL; + if ((retsc = SSL_CONNECTION_FROM_SSL_ONLY(ret)) == NULL) + goto err; - if (s->session != NULL) { + if (sc->session != NULL) { /* * Arranges to share the same session via up_ref. This "copies" * session-id, SSL_METHOD, sid_ctx, and 'cert' @@ -4084,32 +4935,32 @@ SSL *SSL_dup(SSL *s) if (!SSL_set_ssl_method(ret, s->method)) goto err; - if (s->cert != NULL) { - ssl_cert_free(ret->cert); - ret->cert = ssl_cert_dup(s->cert); - if (ret->cert == NULL) + if (sc->cert != NULL) { + ssl_cert_free(retsc->cert); + retsc->cert = ssl_cert_dup(sc->cert); + if (retsc->cert == NULL) goto err; } - if (!SSL_set_session_id_context(ret, s->sid_ctx, - (int)s->sid_ctx_length)) + if (!SSL_set_session_id_context(ret, sc->sid_ctx, + (int)sc->sid_ctx_length)) goto err; } - if (!ssl_dane_dup(ret, s)) + if (!ssl_dane_dup(retsc, sc)) goto err; - ret->version = s->version; - ret->options = s->options; - ret->min_proto_version = s->min_proto_version; - ret->max_proto_version = s->max_proto_version; - ret->mode = s->mode; + retsc->version = sc->version; + retsc->options = sc->options; + retsc->min_proto_version = sc->min_proto_version; + retsc->max_proto_version = sc->max_proto_version; + retsc->mode = sc->mode; SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); - ret->msg_callback = s->msg_callback; - ret->msg_callback_arg = s->msg_callback_arg; + retsc->msg_callback = sc->msg_callback; + retsc->msg_callback_arg = sc->msg_callback_arg; SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s)); SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); - ret->generate_session_id = s->generate_session_id; + retsc->generate_session_id = sc->generate_session_id; SSL_set_info_callback(ret, SSL_get_info_callback(s)); @@ -4117,34 +4968,34 @@ SSL *SSL_dup(SSL *s) if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) goto err; - ret->server = s->server; - if (s->handshake_func) { - if (s->server) + retsc->server = sc->server; + if (sc->handshake_func) { + if (sc->server) SSL_set_accept_state(ret); else SSL_set_connect_state(ret); } - ret->shutdown = s->shutdown; - ret->hit = s->hit; + retsc->shutdown = sc->shutdown; + retsc->hit = sc->hit; - ret->default_passwd_callback = s->default_passwd_callback; - ret->default_passwd_callback_userdata = s->default_passwd_callback_userdata; + retsc->default_passwd_callback = sc->default_passwd_callback; + retsc->default_passwd_callback_userdata = sc->default_passwd_callback_userdata; - X509_VERIFY_PARAM_inherit(ret->param, s->param); + X509_VERIFY_PARAM_inherit(retsc->param, sc->param); /* dup the cipher_list and cipher_list_by_id stacks */ - if (s->cipher_list != NULL) { - if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) + if (sc->cipher_list != NULL) { + if ((retsc->cipher_list = sk_SSL_CIPHER_dup(sc->cipher_list)) == NULL) goto err; } - if (s->cipher_list_by_id != NULL) - if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) + if (sc->cipher_list_by_id != NULL) + if ((retsc->cipher_list_by_id = sk_SSL_CIPHER_dup(sc->cipher_list_by_id)) == NULL) goto err; /* Dup the client_CA list */ - if (!dup_ca_names(&ret->ca_names, s->ca_names) - || !dup_ca_names(&ret->client_ca_names, s->client_ca_names)) + if (!dup_ca_names(&retsc->ca_names, sc->ca_names) + || !dup_ca_names(&retsc->client_ca_names, sc->client_ca_names)) goto err; return ret; @@ -4154,36 +5005,28 @@ SSL *SSL_dup(SSL *s) return NULL; } -void ssl_clear_cipher_ctx(SSL *s) -{ - if (s->enc_read_ctx != NULL) { - EVP_CIPHER_CTX_free(s->enc_read_ctx); - s->enc_read_ctx = NULL; - } - if (s->enc_write_ctx != NULL) { - EVP_CIPHER_CTX_free(s->enc_write_ctx); - s->enc_write_ctx = NULL; - } -#ifndef OPENSSL_NO_COMP - COMP_CTX_free(s->expand); - s->expand = NULL; - COMP_CTX_free(s->compress); - s->compress = NULL; -#endif -} - X509 *SSL_get_certificate(const SSL *s) { - if (s->cert != NULL) - return s->cert->key->x509; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->cert != NULL) + return sc->cert->key->x509; else return NULL; } EVP_PKEY *SSL_get_privatekey(const SSL *s) { - if (s->cert != NULL) - return s->cert->key->privatekey; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->cert != NULL) + return sc->cert->key->privatekey; else return NULL; } @@ -4206,20 +5049,35 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) { - if ((s->session != NULL) && (s->session->cipher != NULL)) - return s->session->cipher; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + if ((sc->session != NULL) && (sc->session->cipher != NULL)) + return sc->session->cipher; return NULL; } const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s) { - return s->s3.tmp.new_cipher; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->s3.tmp.new_cipher; } const COMP_METHOD *SSL_get_current_compression(const SSL *s) { #ifndef OPENSSL_NO_COMP - return s->compress ? COMP_CTX_get_method(s->compress) : NULL; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + if (sc == NULL) + return NULL; + + return sc->rlayer.wrlmethod->get_compression(sc->rlayer.wrl); #else return NULL; #endif @@ -4228,13 +5086,18 @@ const COMP_METHOD *SSL_get_current_compression(const SSL *s) const COMP_METHOD *SSL_get_current_expansion(const SSL *s) { #ifndef OPENSSL_NO_COMP - return s->expand ? COMP_CTX_get_method(s->expand) : NULL; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + if (sc == NULL) + return NULL; + + return sc->rlayer.rrlmethod->get_compression(sc->rlayer.rrl); #else return NULL; #endif } -int ssl_init_wbio_buffer(SSL *s) +int ssl_init_wbio_buffer(SSL_CONNECTION *s) { BIO *bbio; @@ -4252,16 +5115,20 @@ int ssl_init_wbio_buffer(SSL *s) s->bbio = bbio; s->wbio = BIO_push(bbio, s->wbio); + s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio); + return 1; } -int ssl_free_wbio_buffer(SSL *s) +int ssl_free_wbio_buffer(SSL_CONNECTION *s) { /* callers ensure s is never null */ if (s->bbio == NULL) return 1; s->wbio = BIO_pop(s->wbio); + s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio); + BIO_free(s->bbio); s->bbio = NULL; @@ -4280,32 +5147,81 @@ int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) void SSL_set_quiet_shutdown(SSL *s, int mode) { - s->quiet_shutdown = mode; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + /* Not supported with QUIC */ + if (sc == NULL) + return; + + sc->quiet_shutdown = mode; } int SSL_get_quiet_shutdown(const SSL *s) { - return s->quiet_shutdown; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + /* Not supported with QUIC */ + if (sc == NULL) + return 0; + + return sc->quiet_shutdown; } void SSL_set_shutdown(SSL *s, int mode) { - s->shutdown = mode; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + /* Not supported with QUIC */ + if (sc == NULL) + return; + + sc->shutdown = mode; } int SSL_get_shutdown(const SSL *s) { - return s->shutdown; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + +#ifndef OPENSSL_NO_QUIC + /* QUIC: Just indicate whether the connection was shutdown cleanly. */ + if (IS_QUIC(s)) + return ossl_quic_get_shutdown(s); +#endif + + if (sc == NULL) + return 0; + + return sc->shutdown; } int SSL_version(const SSL *s) { - return s->version; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + /* We only support QUICv1 - so if its QUIC its QUICv1 */ + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return OSSL_QUIC1_VERSION; +#endif + if (sc == NULL) + return 0; + + return sc->version; } int SSL_client_version(const SSL *s) { - return s->client_version; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + /* We only support QUICv1 - so if its QUIC its QUICv1 */ + if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) + return OSSL_QUIC1_VERSION; +#endif + if (sc == NULL) + return 0; + + return sc->client_version; } SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) @@ -4316,28 +5232,34 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { CERT *new_cert; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + /* TODO(QUIC FUTURE): Add support for QUIC */ + if (sc == NULL) + return NULL; + if (ssl->ctx == ctx) return ssl->ctx; if (ctx == NULL) - ctx = ssl->session_ctx; + ctx = sc->session_ctx; new_cert = ssl_cert_dup(ctx->cert); if (new_cert == NULL) { return NULL; } - if (!custom_exts_copy_flags(&new_cert->custext, &ssl->cert->custext)) { + if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext)) { ssl_cert_free(new_cert); return NULL; } - ssl_cert_free(ssl->cert); - ssl->cert = new_cert; + ssl_cert_free(sc->cert); + sc->cert = new_cert; /* * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), * so setter APIs must prevent invalid lengths from entering the system. */ - if (!ossl_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx))) + if (!ossl_assert(sc->sid_ctx_length <= sizeof(sc->sid_ctx))) return NULL; /* @@ -4347,10 +5269,10 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) * leave it unchanged. */ if ((ssl->ctx != NULL) && - (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) && - (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) { - ssl->sid_ctx_length = ctx->sid_ctx_length; - memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); + (sc->sid_ctx_length == ssl->ctx->sid_ctx_length) && + (memcmp(sc->sid_ctx, ssl->ctx->sid_ctx, sc->sid_ctx_length) == 0)) { + sc->sid_ctx_length = ctx->sid_ctx_length; + memcpy(&sc->sid_ctx, &ctx->sid_ctx, sizeof(sc->sid_ctx)); } SSL_CTX_up_ref(ctx); @@ -4453,7 +5375,12 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) { - ssl->info_callback = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return; + + sc->info_callback = cb; } /* @@ -4463,36 +5390,61 @@ void SSL_set_info_callback(SSL *ssl, void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , int /* type */ , int /* val */ ) { - return ssl->info_callback; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return NULL; + + return sc->info_callback; } void SSL_set_verify_result(SSL *ssl, long arg) { - ssl->verify_result = arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return; + + sc->verify_result = arg; } long SSL_get_verify_result(const SSL *ssl) { - return ssl->verify_result; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return 0; + + return sc->verify_result; } size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) { + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return 0; + if (outlen == 0) - return sizeof(ssl->s3.client_random); - if (outlen > sizeof(ssl->s3.client_random)) - outlen = sizeof(ssl->s3.client_random); - memcpy(out, ssl->s3.client_random, outlen); + return sizeof(sc->s3.client_random); + if (outlen > sizeof(sc->s3.client_random)) + outlen = sizeof(sc->s3.client_random); + memcpy(out, sc->s3.client_random, outlen); return outlen; } size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen) { + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return 0; + if (outlen == 0) - return sizeof(ssl->s3.server_random); - if (outlen > sizeof(ssl->s3.server_random)) - outlen = sizeof(ssl->s3.server_random); - memcpy(out, ssl->s3.server_random, outlen); + return sizeof(sc->s3.server_random); + if (outlen > sizeof(sc->s3.server_random)) + outlen = sizeof(sc->s3.server_random); + memcpy(out, sc->s3.server_random, outlen); return outlen; } @@ -4559,7 +5511,17 @@ void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) int SSL_want(const SSL *s) { - return s->rwstate; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_want(s); +#endif + + if (sc == NULL) + return SSL_NOTHING; + + return sc->rwstate; } #ifndef OPENSSL_NO_PSK @@ -4581,40 +5543,53 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) { - if (s == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) return 0; if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { ERR_raise(ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } - OPENSSL_free(s->cert->psk_identity_hint); + OPENSSL_free(sc->cert->psk_identity_hint); if (identity_hint != NULL) { - s->cert->psk_identity_hint = OPENSSL_strdup(identity_hint); - if (s->cert->psk_identity_hint == NULL) + sc->cert->psk_identity_hint = OPENSSL_strdup(identity_hint); + if (sc->cert->psk_identity_hint == NULL) return 0; } else - s->cert->psk_identity_hint = NULL; + sc->cert->psk_identity_hint = NULL; return 1; } const char *SSL_get_psk_identity_hint(const SSL *s) { - if (s == NULL || s->session == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL || sc->session == NULL) return NULL; - return s->session->psk_identity_hint; + + return sc->session->psk_identity_hint; } const char *SSL_get_psk_identity(const SSL *s) { - if (s == NULL || s->session == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL || sc->session == NULL) return NULL; - return s->session->psk_identity; + + return sc->session->psk_identity; } void SSL_set_psk_client_callback(SSL *s, SSL_psk_client_cb_func cb) { - s->psk_client_callback = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->psk_client_callback = cb; } void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb) @@ -4624,7 +5599,12 @@ void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb) void SSL_set_psk_server_callback(SSL *s, SSL_psk_server_cb_func cb) { - s->psk_server_callback = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->psk_server_callback = cb; } void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb) @@ -4635,7 +5615,12 @@ void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb) void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb) { - s->psk_find_session_cb = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->psk_find_session_cb = cb; } void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, @@ -4646,7 +5631,12 @@ void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb) { - s->psk_use_session_cb = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->psk_use_session_cb = cb; } void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, @@ -4707,6 +5697,9 @@ void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx) int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) { + if (IS_QUIC_CTX(ctx) && block_size > 1) + return 0; + /* block size of 0 or 1 is basically no padding */ if (block_size == 1) ctx->block_padding = 0; @@ -4722,10 +5715,14 @@ int SSL_set_record_padding_callback(SSL *ssl, size_t len, void *arg)) { BIO *b; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc == NULL) + return 0; b = SSL_get_wbio(ssl); if (b == NULL || !BIO_get_ktls_send(b)) { - ssl->record_padding_cb = cb; + sc->rlayer.record_padding_cb = cb; return 1; } return 0; @@ -4733,21 +5730,36 @@ int SSL_set_record_padding_callback(SSL *ssl, void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) { - ssl->record_padding_arg = arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return; + + sc->rlayer.record_padding_arg = arg; } void *SSL_get_record_padding_callback_arg(const SSL *ssl) { - return ssl->record_padding_arg; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return NULL; + + return sc->rlayer.record_padding_arg; } int SSL_set_block_padding(SSL *ssl, size_t block_size) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL || (IS_QUIC(ssl) && block_size > 1)) + return 0; + /* block size of 0 or 1 is basically no padding */ if (block_size == 1) - ssl->block_padding = 0; + sc->rlayer.block_padding = 0; else if (block_size <= SSL3_RT_MAX_PLAIN_LENGTH) - ssl->block_padding = block_size; + sc->rlayer.block_padding = block_size; else return 0; return 1; @@ -4755,14 +5767,24 @@ int SSL_set_block_padding(SSL *ssl, size_t block_size) int SSL_set_num_tickets(SSL *s, size_t num_tickets) { - s->num_tickets = num_tickets; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + sc->num_tickets = num_tickets; return 1; } size_t SSL_get_num_tickets(const SSL *s) { - return s->num_tickets; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->num_tickets; } int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) @@ -4777,34 +5799,9 @@ size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx) return ctx->num_tickets; } -/* - * Allocates new EVP_MD_CTX and sets pointer to it into given pointer - * variable, freeing EVP_MD_CTX previously stored in that variable, if any. - * If EVP_MD pointer is passed, initializes ctx with this |md|. - * Returns the newly allocated ctx; - */ - -EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) -{ - ssl_clear_hash_ctx(hash); - *hash = EVP_MD_CTX_new(); - if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) { - EVP_MD_CTX_free(*hash); - *hash = NULL; - return NULL; - } - return *hash; -} - -void ssl_clear_hash_ctx(EVP_MD_CTX **hash) -{ - - EVP_MD_CTX_free(*hash); - *hash = NULL; -} - /* Retrieve handshake hashes */ -int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen, +int ssl_handshake_hash(SSL_CONNECTION *s, + unsigned char *out, size_t outlen, size_t *hashlen) { EVP_MD_CTX *ctx = NULL; @@ -4839,12 +5836,22 @@ int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen, int SSL_session_reused(const SSL *s) { - return s->hit; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->hit; } int SSL_is_server(const SSL *s) { - return s->server; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->server; } #ifndef OPENSSL_NO_DEPRECATED_1_1_0 @@ -4858,12 +5865,22 @@ void SSL_set_debug(SSL *s, int debug) void SSL_set_security_level(SSL *s, int level) { - s->cert->sec_level = level; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->cert->sec_level = level; } int SSL_get_security_level(const SSL *s) { - return s->cert->sec_level; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->cert->sec_level; } void SSL_set_security_callback(SSL *s, @@ -4871,24 +5888,44 @@ void SSL_set_security_callback(SSL *s, int op, int bits, int nid, void *other, void *ex)) { - s->cert->sec_cb = cb; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->cert->sec_cb = cb; } int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex) { - return s->cert->sec_cb; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->cert->sec_cb; } void SSL_set0_security_ex_data(SSL *s, void *ex) { - s->cert->sec_ex = ex; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + sc->cert->sec_ex = ex; } void *SSL_get0_security_ex_data(const SSL *s) { - return s->cert->sec_ex; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->cert->sec_ex; } void SSL_CTX_set_security_level(SSL_CTX *ctx, int level) @@ -4935,7 +5972,17 @@ uint64_t SSL_CTX_get_options(const SSL_CTX *ctx) uint64_t SSL_get_options(const SSL *s) { - return s->options; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_options(s); +#endif + + if (sc == NULL) + return 0; + + return sc->options; } uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op) @@ -4945,7 +5992,28 @@ uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op) uint64_t SSL_set_options(SSL *s, uint64_t op) { - return s->options |= op; + SSL_CONNECTION *sc; + OSSL_PARAM options[2], *opts = options; + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_set_options(s, op); +#endif + + sc = SSL_CONNECTION_FROM_SSL(s); + if (sc == NULL) + return 0; + + sc->options |= op; + + *opts++ = OSSL_PARAM_construct_uint64(OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS, + &sc->options); + *opts = OSSL_PARAM_construct_end(); + + /* Ignore return value */ + sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options); + + return sc->options; } uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t op) @@ -4955,12 +6023,27 @@ uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t op) uint64_t SSL_clear_options(SSL *s, uint64_t op) { - return s->options &= ~op; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_clear_options(s, op); +#endif + + if (sc == NULL) + return 0; + + return sc->options &= ~op; } STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s) { - return s->verified_chain; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return NULL; + + return sc->verified_chain; } IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); @@ -4983,7 +6066,7 @@ static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, if (*dst == NULL) { *dst = sk_SCT_new_null(); if (*dst == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } } @@ -5008,7 +6091,7 @@ static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, * Look for data collected during ServerHello and parse if found. * Returns the number of SCTs extracted. */ -static int ct_extract_tls_extension_scts(SSL *s) +static int ct_extract_tls_extension_scts(SSL_CONNECTION *s) { int scts_extracted = 0; @@ -5032,7 +6115,7 @@ static int ct_extract_tls_extension_scts(SSL *s) * - 0 if no OCSP response exists or it contains no SCTs. * - A negative integer if an error occurs. */ -static int ct_extract_ocsp_response_scts(SSL *s) +static int ct_extract_ocsp_response_scts(SSL_CONNECTION *s) { # ifndef OPENSSL_NO_OCSP int scts_extracted = 0; @@ -5083,7 +6166,7 @@ static int ct_extract_ocsp_response_scts(SSL *s) * Return the number of SCTs extracted, or a negative integer if an error * occurs. */ -static int ct_extract_x509v3_extension_scts(SSL *s) +static int ct_extract_x509v3_extension_scts(SSL_CONNECTION *s) { int scts_extracted = 0; X509 *cert = s->session != NULL ? s->session->peer : NULL; @@ -5108,26 +6191,31 @@ static int ct_extract_x509v3_extension_scts(SSL *s) */ const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s) { - if (!s->scts_parsed) { - if (ct_extract_tls_extension_scts(s) < 0 || - ct_extract_ocsp_response_scts(s) < 0 || - ct_extract_x509v3_extension_scts(s) < 0) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (!sc->scts_parsed) { + if (ct_extract_tls_extension_scts(sc) < 0 || + ct_extract_ocsp_response_scts(sc) < 0 || + ct_extract_x509v3_extension_scts(sc) < 0) goto err; - s->scts_parsed = 1; + sc->scts_parsed = 1; } - return s->scts; + return sc->scts; err: return NULL; } -static int ct_permissive(const CT_POLICY_EVAL_CTX * ctx, +static int ct_permissive(const CT_POLICY_EVAL_CTX *ctx, const STACK_OF(SCT) *scts, void *unused_arg) { return 1; } -static int ct_strict(const CT_POLICY_EVAL_CTX * ctx, +static int ct_strict(const CT_POLICY_EVAL_CTX *ctx, const STACK_OF(SCT) *scts, void *unused_arg) { int count = scts != NULL ? sk_SCT_num(scts) : 0; @@ -5147,6 +6235,11 @@ static int ct_strict(const CT_POLICY_EVAL_CTX * ctx, int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, void *arg) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + /* * Since code exists that uses the custom extension handler for CT, look * for this and throw an error if they have already registered to use CT. @@ -5166,8 +6259,8 @@ int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, return 0; } - s->ct_validation_callback = callback; - s->ct_validation_callback_arg = arg; + sc->ct_validation_callback = callback; + sc->ct_validation_callback_arg = arg; return 1; } @@ -5193,7 +6286,12 @@ int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, int SSL_ct_is_enabled(const SSL *s) { - return s->ct_validation_callback != NULL; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->ct_validation_callback != NULL; } int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx) @@ -5201,7 +6299,7 @@ int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx) return ctx->ct_validation_callback != NULL; } -int ssl_validate_ct(SSL *s) +int ssl_validate_ct(SSL_CONNECTION *s) { int ret = 0; X509 *cert = s->session != NULL ? s->session->peer : NULL; @@ -5238,20 +6336,22 @@ int ssl_validate_ct(SSL *s) } } - ctx = CT_POLICY_EVAL_CTX_new_ex(s->ctx->libctx, s->ctx->propq); + ctx = CT_POLICY_EVAL_CTX_new_ex(SSL_CONNECTION_GET_CTX(s)->libctx, + SSL_CONNECTION_GET_CTX(s)->propq); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CT_LIB); goto end; } issuer = sk_X509_value(s->verified_chain, 1); CT_POLICY_EVAL_CTX_set1_cert(ctx, cert); CT_POLICY_EVAL_CTX_set1_issuer(ctx, issuer); - CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx, s->ctx->ctlog_store); + CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx, + SSL_CONNECTION_GET_CTX(s)->ctlog_store); CT_POLICY_EVAL_CTX_set_time( - ctx, (uint64_t)SSL_SESSION_get_time(SSL_get0_session(s)) * 1000); + ctx, (uint64_t)SSL_SESSION_get_time(s->session) * 1000); - scts = SSL_get0_peer_scts(s); + scts = SSL_get0_peer_scts(SSL_CONNECTION_GET_SSL(s)); /* * This function returns success (> 0) only when all the SCTs are valid, 0 @@ -5336,7 +6436,7 @@ int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path) return CTLOG_STORE_load_file(ctx->ctlog_store, path); } -void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE * logs) +void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs) { CTLOG_STORE_free(ctx->ctlog_store); ctx->ctlog_store = logs; @@ -5358,52 +6458,82 @@ void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb, int SSL_client_hello_isv2(SSL *s) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) return 0; - return s->clienthello->isv2; + + if (sc->clienthello == NULL) + return 0; + return sc->clienthello->isv2; } unsigned int SSL_client_hello_get0_legacy_version(SSL *s) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL) return 0; - return s->clienthello->legacy_version; + return sc->clienthello->legacy_version; } size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL) return 0; if (out != NULL) - *out = s->clienthello->random; + *out = sc->clienthello->random; return SSL3_RANDOM_SIZE; } size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL) return 0; if (out != NULL) - *out = s->clienthello->session_id; - return s->clienthello->session_id_len; + *out = sc->clienthello->session_id; + return sc->clienthello->session_id_len; } size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL) return 0; if (out != NULL) - *out = PACKET_data(&s->clienthello->ciphersuites); - return PACKET_remaining(&s->clienthello->ciphersuites); + *out = PACKET_data(&sc->clienthello->ciphersuites); + return PACKET_remaining(&sc->clienthello->ciphersuites); } size_t SSL_client_hello_get0_compression_methods(SSL *s, const unsigned char **out) { - if (s->clienthello == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL) return 0; if (out != NULL) - *out = s->clienthello->compressions; - return s->clienthello->compressions_len; + *out = sc->clienthello->compressions; + return sc->clienthello->compressions_len; } int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) @@ -5411,11 +6541,15 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) RAW_EXTENSION *ext; int *present; size_t num = 0, i; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; - if (s->clienthello == NULL || out == NULL || outlen == NULL) + if (sc->clienthello == NULL || out == NULL || outlen == NULL) return 0; - for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) { - ext = s->clienthello->pre_proc_exts + i; + for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) { + ext = sc->clienthello->pre_proc_exts + i; if (ext->present) num++; } @@ -5424,12 +6558,10 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) *outlen = 0; return 1; } - if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) return 0; - } - for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) { - ext = s->clienthello->pre_proc_exts + i; + for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) { + ext = sc->clienthello->pre_proc_exts + i; if (ext->present) { if (ext->received_order >= num) goto err; @@ -5444,16 +6576,58 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) return 0; } -int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out, - size_t *outlen) +int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, size_t *num_exts) { - size_t i; - RAW_EXTENSION *r; + RAW_EXTENSION *ext; + size_t num = 0, i; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->clienthello == NULL || num_exts == NULL) + return 0; + for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) { + ext = sc->clienthello->pre_proc_exts + i; + if (ext->present) + num++; + } + if (num == 0) { + *num_exts = 0; + return 1; + } + if (exts == NULL) { + *num_exts = num; + return 1; + } + if (*num_exts < num) + return 0; + for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) { + ext = sc->clienthello->pre_proc_exts + i; + if (ext->present) { + if (ext->received_order >= num) + return 0; + exts[ext->received_order] = ext->type; + } + } + *num_exts = num; + return 1; +} + +int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out, + size_t *outlen) +{ + size_t i; + RAW_EXTENSION *r; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; - if (s->clienthello == NULL) + if (sc->clienthello == NULL) return 0; - for (i = 0; i < s->clienthello->pre_proc_exts_len; ++i) { - r = s->clienthello->pre_proc_exts + i; + for (i = 0; i < sc->clienthello->pre_proc_exts_len; ++i) { + r = sc->clienthello->pre_proc_exts + i; if (r->present && r->type == type) { if (out != NULL) *out = PACKET_data(&r->data); @@ -5467,18 +6641,34 @@ int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **o int SSL_free_buffers(SSL *ssl) { - RECORD_LAYER *rl = &ssl->rlayer; + RECORD_LAYER *rl; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); - if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl)) + if (sc == NULL) return 0; - RECORD_LAYER_release(rl); - return 1; + rl = &sc->rlayer; + + return rl->rrlmethod->free_buffers(rl->rrl) + && rl->wrlmethod->free_buffers(rl->wrl); } int SSL_alloc_buffers(SSL *ssl) { - return ssl3_setup_buffers(ssl); + RECORD_LAYER *rl; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + /* QUIC always has buffers allocated. */ + if (IS_QUIC(ssl)) + return 1; + + rl = &sc->rlayer; + + return rl->rrlmethod->alloc_buffers(rl->rrl) + && rl->wrlmethod->alloc_buffers(rl->wrl); } void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb) @@ -5492,7 +6682,7 @@ SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx) } static int nss_keylog_int(const char *prefix, - SSL *ssl, + SSL_CONNECTION *sc, const uint8_t *parameter_1, size_t parameter_1_len, const uint8_t *parameter_2, @@ -5503,8 +6693,9 @@ static int nss_keylog_int(const char *prefix, size_t out_len = 0; size_t i; size_t prefix_len; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc); - if (ssl->ctx->keylog_callback == NULL) + if (sctx->keylog_callback == NULL) return 1; /* @@ -5517,10 +6708,8 @@ static int nss_keylog_int(const char *prefix, */ prefix_len = strlen(prefix); out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3; - if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) { - SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) return 0; - } strcpy(cursor, prefix); cursor += prefix_len; @@ -5538,40 +6727,40 @@ static int nss_keylog_int(const char *prefix, } *cursor = '\0'; - ssl->ctx->keylog_callback(ssl, (const char *)out); + sctx->keylog_callback(SSL_CONNECTION_GET_SSL(sc), (const char *)out); OPENSSL_clear_free(out, out_len); return 1; } -int ssl_log_rsa_client_key_exchange(SSL *ssl, +int ssl_log_rsa_client_key_exchange(SSL_CONNECTION *sc, const uint8_t *encrypted_premaster, size_t encrypted_premaster_len, const uint8_t *premaster, size_t premaster_len) { if (encrypted_premaster_len < 8) { - SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* We only want the first 8 bytes of the encrypted premaster as a tag. */ return nss_keylog_int("RSA", - ssl, + sc, encrypted_premaster, 8, premaster, premaster_len); } -int ssl_log_secret(SSL *ssl, +int ssl_log_secret(SSL_CONNECTION *sc, const char *label, const uint8_t *secret, size_t secret_len) { return nss_keylog_int(label, - ssl, - ssl->s3.client_random, + sc, + sc->s3.client_random, SSL3_RANDOM_SIZE, secret, secret_len); @@ -5579,7 +6768,7 @@ int ssl_log_secret(SSL *ssl, #define SSLV2_CIPHER_LEN 3 -int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format) +int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, int sslv2format) { int n; @@ -5615,7 +6804,7 @@ int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format) raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN); s->s3.tmp.ciphers_raw = raw; if (raw == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } for (s->s3.tmp.ciphers_rawlen = 0; @@ -5649,16 +6838,20 @@ int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, STACK_OF(SSL_CIPHER) **scsvs) { PACKET pkt; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; if (!PACKET_buf_init(&pkt, bytes, len)) return 0; - return bytes_to_cipher_list(s, &pkt, sk, scsvs, isv2format, 0); + return ossl_bytes_to_cipher_list(sc, &pkt, sk, scsvs, isv2format, 0); } -int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, - STACK_OF(SSL_CIPHER) **skp, - STACK_OF(SSL_CIPHER) **scsvs_out, - int sslv2format, int fatal) +int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **skp, + STACK_OF(SSL_CIPHER) **scsvs_out, + int sslv2format, int fatal) { const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk = NULL; @@ -5690,9 +6883,9 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, scsvs = sk_SSL_CIPHER_new_null(); if (sk == NULL || scsvs == NULL) { if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); else - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } @@ -5711,9 +6904,9 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) || (!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) { if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); else - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } } @@ -5755,14 +6948,24 @@ uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx) int SSL_set_max_early_data(SSL *s, uint32_t max_early_data) { - s->max_early_data = max_early_data; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + sc->max_early_data = max_early_data; return 1; } uint32_t SSL_get_max_early_data(const SSL *s) { - return s->max_early_data; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->max_early_data; } int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data) @@ -5779,44 +6982,58 @@ uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx) int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data) { - s->recv_max_early_data = recv_max_early_data; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; + + sc->recv_max_early_data = recv_max_early_data; return 1; } uint32_t SSL_get_recv_max_early_data(const SSL *s) { - return s->recv_max_early_data; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->recv_max_early_data; } -__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl) +__owur unsigned int ssl_get_max_send_fragment(const SSL_CONNECTION *sc) { /* Return any active Max Fragment Len extension */ - if (ssl->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(ssl->session)) - return GET_MAX_FRAGMENT_LENGTH(ssl->session); + if (sc->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(sc->session)) + return GET_MAX_FRAGMENT_LENGTH(sc->session); /* return current SSL connection setting */ - return ssl->max_send_fragment; + return sc->max_send_fragment; } -__owur unsigned int ssl_get_split_send_fragment(const SSL *ssl) +__owur unsigned int ssl_get_split_send_fragment(const SSL_CONNECTION *sc) { /* Return a value regarding an active Max Fragment Len extension */ - if (ssl->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(ssl->session) - && ssl->split_send_fragment > GET_MAX_FRAGMENT_LENGTH(ssl->session)) - return GET_MAX_FRAGMENT_LENGTH(ssl->session); + if (sc->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(sc->session) + && sc->split_send_fragment > GET_MAX_FRAGMENT_LENGTH(sc->session)) + return GET_MAX_FRAGMENT_LENGTH(sc->session); /* else limit |split_send_fragment| to current |max_send_fragment| */ - if (ssl->split_send_fragment > ssl->max_send_fragment) - return ssl->max_send_fragment; + if (sc->split_send_fragment > sc->max_send_fragment) + return sc->max_send_fragment; /* return current SSL connection setting */ - return ssl->split_send_fragment; + return sc->split_send_fragment; } int SSL_stateless(SSL *s) { int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return 0; /* Ensure there is no state left over from a previous invocation */ if (!SSL_clear(s)) @@ -5824,14 +7041,14 @@ int SSL_stateless(SSL *s) ERR_clear_error(); - s->s3.flags |= TLS1_FLAGS_STATELESS; + sc->s3.flags |= TLS1_FLAGS_STATELESS; ret = SSL_accept(s); - s->s3.flags &= ~TLS1_FLAGS_STATELESS; + sc->s3.flags &= ~TLS1_FLAGS_STATELESS; - if (ret > 0 && s->ext.cookieok) + if (ret > 0 && sc->ext.cookieok) return 1; - if (s->hello_retry_request == SSL_HRR_PENDING && !ossl_statem_in_error(s)) + if (sc->hello_retry_request == SSL_HRR_PENDING && !ossl_statem_in_error(sc)) return 0; return -1; @@ -5844,16 +7061,33 @@ void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val) void SSL_set_post_handshake_auth(SSL *ssl, int val) { - ssl->pha_enabled = val; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc == NULL) + return; + + sc->pha_enabled = val; } int SSL_verify_client_post_handshake(SSL *ssl) { - if (!SSL_IS_TLS13(ssl)) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(ssl)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } - if (!ssl->server) { +#endif + + if (sc == NULL) + return 0; + + if (!SSL_CONNECTION_IS_TLS13(sc)) { + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); + return 0; + } + if (!sc->server) { ERR_raise(ERR_LIB_SSL, SSL_R_NOT_SERVER); return 0; } @@ -5863,7 +7097,7 @@ int SSL_verify_client_post_handshake(SSL *ssl) return 0; } - switch (ssl->post_handshake_auth) { + switch (sc->post_handshake_auth) { case SSL_PHA_NONE: ERR_raise(ERR_LIB_SSL, SSL_R_EXTENSION_NOT_RECEIVED); return 0; @@ -5881,16 +7115,16 @@ int SSL_verify_client_post_handshake(SSL *ssl) return 0; } - ssl->post_handshake_auth = SSL_PHA_REQUEST_PENDING; + sc->post_handshake_auth = SSL_PHA_REQUEST_PENDING; /* checks verify_mode and algorithm_auth */ - if (!send_certificate_request(ssl)) { - ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */ + if (!send_certificate_request(sc)) { + sc->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */ ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CONFIG); return 0; } - ossl_statem_set_in_init(ssl, 1); + ossl_statem_set_in_init(sc, 1); return 1; } @@ -5917,8 +7151,13 @@ void SSL_set_allow_early_data_cb(SSL *s, SSL_allow_early_data_cb_fn cb, void *arg) { - s->allow_early_data_cb = cb; - s->allow_early_data_cb_data = arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL) + return; + + sc->allow_early_data_cb = cb; + sc->allow_early_data_cb_data = arg; } const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx, @@ -6015,13 +7254,18 @@ void ssl_evp_md_free(const EVP_MD *md) int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey) { - if (!ssl_security(s, SSL_SECOP_TMP_DH, + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (!ssl_security(sc, SSL_SECOP_TMP_DH, EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) { ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL); return 0; } - EVP_PKEY_free(s->cert->dh_tmp); - s->cert->dh_tmp = dhpkey; + EVP_PKEY_free(sc->cert->dh_tmp); + sc->cert->dh_tmp = dhpkey; return 1; } @@ -6036,3 +7280,526 @@ int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey) ctx->cert->dh_tmp = dhpkey; return 1; } + +/* QUIC-specific methods which are supported on QUIC connections only. */ +int SSL_handle_events(SSL *s) +{ + SSL_CONNECTION *sc; + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_handle_events(s); +#endif + + sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc)) + /* + * DTLSv1_handle_timeout returns 0 if the timer wasn't expired yet, + * which we consider a success case. Theoretically DTLSv1_handle_timeout + * can also return 0 if s is NULL or not a DTLS object, but we've + * already ruled out those possibilities above, so this is not possible + * here. Thus the only failure cases are where DTLSv1_handle_timeout + * returns -1. + */ + return DTLSv1_handle_timeout(s) >= 0; + + return 1; +} + +int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite) +{ + SSL_CONNECTION *sc; + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_event_timeout(s, tv, is_infinite); +#endif + + sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc) + && DTLSv1_get_timeout(s, tv)) { + *is_infinite = 0; + return 1; + } + + tv->tv_sec = 1000000; + tv->tv_usec = 0; + *is_infinite = 1; + return 1; +} + +int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_rpoll_descriptor(s, desc); +#endif + + if (sc == NULL || sc->rbio == NULL) + return 0; + + return BIO_get_rpoll_descriptor(sc->rbio, desc); +} + +int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC(s)) + return ossl_quic_get_wpoll_descriptor(s, desc); +#endif + + if (sc == NULL || sc->wbio == NULL) + return 0; + + return BIO_get_wpoll_descriptor(sc->wbio, desc); +} + +int SSL_net_read_desired(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return SSL_want_read(s); + + return ossl_quic_get_net_read_desired(s); +#else + return SSL_want_read(s); +#endif +} + +int SSL_net_write_desired(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return SSL_want_write(s); + + return ossl_quic_get_net_write_desired(s); +#else + return SSL_want_write(s); +#endif +} + +int SSL_set_blocking_mode(SSL *s, int blocking) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_conn_set_blocking_mode(s, blocking); +#else + return 0; +#endif +} + +int SSL_get_blocking_mode(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return -1; + + return ossl_quic_conn_get_blocking_mode(s); +#else + return -1; +#endif +} + +int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_conn_set_initial_peer_addr(s, peer_addr); +#else + return 0; +#endif +} + +int SSL_shutdown_ex(SSL *ssl, uint64_t flags, + const SSL_SHUTDOWN_EX_ARGS *args, + size_t args_len) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(ssl)) + return SSL_shutdown(ssl); + + return ossl_quic_conn_shutdown(ssl, flags, args, args_len); +#else + return SSL_shutdown(ssl); +#endif +} + +int SSL_stream_conclude(SSL *ssl, uint64_t flags) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(ssl)) + return 0; + + return ossl_quic_conn_stream_conclude(ssl); +#else + return 0; +#endif +} + +SSL *SSL_new_stream(SSL *s, uint64_t flags) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return NULL; + + return ossl_quic_conn_stream_new(s, flags); +#else + return NULL; +#endif +} + +SSL *SSL_get0_connection(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return s; + + return ossl_quic_get0_connection(s); +#else + return s; +#endif +} + +int SSL_is_connection(SSL *s) +{ + return SSL_get0_connection(s) == s; +} + +int SSL_get_stream_type(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return SSL_STREAM_TYPE_BIDI; + + return ossl_quic_get_stream_type(s); +#else + return SSL_STREAM_TYPE_BIDI; +#endif +} + +uint64_t SSL_get_stream_id(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return UINT64_MAX; + + return ossl_quic_get_stream_id(s); +#else + return UINT64_MAX; +#endif +} + +int SSL_is_stream_local(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return -1; + + return ossl_quic_is_stream_local(s); +#else + return -1; +#endif +} + +int SSL_set_default_stream_mode(SSL *s, uint32_t mode) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_set_default_stream_mode(s, mode); +#else + return 0; +#endif +} + +int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_set_incoming_stream_policy(s, policy, aec); +#else + return 0; +#endif +} + +SSL *SSL_accept_stream(SSL *s, uint64_t flags) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return NULL; + + return ossl_quic_accept_stream(s, flags); +#else + return NULL; +#endif +} + +size_t SSL_get_accept_stream_queue_len(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_get_accept_stream_queue_len(s); +#else + return 0; +#endif +} + +int SSL_stream_reset(SSL *s, + const SSL_STREAM_RESET_ARGS *args, + size_t args_len) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return 0; + + return ossl_quic_stream_reset(s, args, args_len); +#else + return 0; +#endif +} + +int SSL_get_stream_read_state(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return SSL_STREAM_STATE_NONE; + + return ossl_quic_get_stream_read_state(s); +#else + return SSL_STREAM_STATE_NONE; +#endif +} + +int SSL_get_stream_write_state(SSL *s) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return SSL_STREAM_STATE_NONE; + + return ossl_quic_get_stream_write_state(s); +#else + return SSL_STREAM_STATE_NONE; +#endif +} + +int SSL_get_stream_read_error_code(SSL *s, uint64_t *app_error_code) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return -1; + + return ossl_quic_get_stream_read_error_code(s, app_error_code); +#else + return -1; +#endif +} + +int SSL_get_stream_write_error_code(SSL *s, uint64_t *app_error_code) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return -1; + + return ossl_quic_get_stream_write_error_code(s, app_error_code); +#else + return -1; +#endif +} + +int SSL_get_conn_close_info(SSL *s, SSL_CONN_CLOSE_INFO *info, + size_t info_len) +{ +#ifndef OPENSSL_NO_QUIC + if (!IS_QUIC(s)) + return -1; + + return ossl_quic_get_conn_close_info(s, info, info_len); +#else + return -1; +#endif +} + +int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk) +{ + unsigned char *data = NULL; + SSL_DANE *dane = SSL_get0_dane(s); + int ret; + + if (dane == NULL || dane->dctx == NULL) + return 0; + if ((ret = i2d_PUBKEY(rpk, &data)) <= 0) + return 0; + + ret = SSL_dane_tlsa_add(s, DANETLS_USAGE_DANE_EE, + DANETLS_SELECTOR_SPKI, + DANETLS_MATCHING_FULL, + data, (size_t)ret) > 0; + OPENSSL_free(data); + return ret; +} + +EVP_PKEY *SSL_get0_peer_rpk(const SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL || sc->session == NULL) + return NULL; + return sc->session->peer_rpk; +} + +int SSL_get_negotiated_client_cert_type(const SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return sc->ext.client_cert_type; +} + +int SSL_get_negotiated_server_cert_type(const SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return sc->ext.server_cert_type; +} + +static int validate_cert_type(const unsigned char *val, size_t len) +{ + size_t i; + int saw_rpk = 0; + int saw_x509 = 0; + + if (val == NULL && len == 0) + return 1; + + if (val == NULL || len == 0) + return 0; + + for (i = 0; i < len; i++) { + switch (val[i]) { + case TLSEXT_cert_type_rpk: + if (saw_rpk) + return 0; + saw_rpk = 1; + break; + case TLSEXT_cert_type_x509: + if (saw_x509) + return 0; + saw_x509 = 1; + break; + case TLSEXT_cert_type_pgp: + case TLSEXT_cert_type_1609dot2: + default: + return 0; + } + } + return 1; +} + +static int set_cert_type(unsigned char **cert_type, + size_t *cert_type_len, + const unsigned char *val, + size_t len) +{ + unsigned char *tmp = NULL; + + if (!validate_cert_type(val, len)) + return 0; + + if (val != NULL && (tmp = OPENSSL_memdup(val, len)) == NULL) + return 0; + + OPENSSL_free(*cert_type); + *cert_type = tmp; + *cert_type_len = len; + return 1; +} + +int SSL_set1_client_cert_type(SSL *s, const unsigned char *val, size_t len) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + return set_cert_type(&sc->client_cert_type, &sc->client_cert_type_len, + val, len); +} + +int SSL_set1_server_cert_type(SSL *s, const unsigned char *val, size_t len) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + return set_cert_type(&sc->server_cert_type, &sc->server_cert_type_len, + val, len); +} + +int SSL_CTX_set1_client_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len) +{ + return set_cert_type(&ctx->client_cert_type, &ctx->client_cert_type_len, + val, len); +} + +int SSL_CTX_set1_server_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len) +{ + return set_cert_type(&ctx->server_cert_type, &ctx->server_cert_type_len, + val, len); +} + +int SSL_get0_client_cert_type(const SSL *s, unsigned char **t, size_t *len) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (t == NULL || len == NULL) + return 0; + + *t = sc->client_cert_type; + *len = sc->client_cert_type_len; + return 1; +} + +int SSL_get0_server_cert_type(const SSL *s, unsigned char **t, size_t *len) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (t == NULL || len == NULL) + return 0; + + *t = sc->server_cert_type; + *len = sc->server_cert_type_len; + return 1; +} + +int SSL_CTX_get0_client_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len) +{ + if (t == NULL || len == NULL) + return 0; + + *t = ctx->client_cert_type; + *len = ctx->client_cert_type_len; + return 1; +} + +int SSL_CTX_get0_server_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len) +{ + if (t == NULL || len == NULL) + return 0; + + *t = ctx->server_cert_type; + *len = ctx->server_cert_type_len; + return 1; +} diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 845329a809..d1ef358932 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -15,122 +15,35 @@ # include "internal/e_os.h" /* struct timeval for DTLS */ # include # include -# include # include +# include "internal/common.h" /* for HAS_PREFIX */ # include -# include # include +# include # include # include # include # include # include # include -# include "record/record.h" -# include "statem/statem.h" +# include "internal/recordmethod.h" +# include "internal/statem.h" # include "internal/packet.h" # include "internal/dane.h" # include "internal/refcount.h" # include "internal/tsan_assist.h" # include "internal/bio.h" # include "internal/ktls.h" +# include "internal/time.h" +# include "internal/ssl.h" +# include "record/record.h" # ifdef OPENSSL_BUILD_SHLIBSSL # undef OPENSSL_EXTERN # define OPENSSL_EXTERN OPENSSL_EXPORT # endif -# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24)) - -/* NOTE - c is not incremented as per c2l */ -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff)) - -# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ - l|=((unsigned long)(*((c)++)))<<16, \ - l|=((unsigned long)(*((c)++)))<< 8, \ - l|=((unsigned long)(*((c)++)))) - -# define n2l8(c,l) (l =((uint64_t)(*((c)++)))<<56, \ - l|=((uint64_t)(*((c)++)))<<48, \ - l|=((uint64_t)(*((c)++)))<<40, \ - l|=((uint64_t)(*((c)++)))<<32, \ - l|=((uint64_t)(*((c)++)))<<24, \ - l|=((uint64_t)(*((c)++)))<<16, \ - l|=((uint64_t)(*((c)++)))<< 8, \ - l|=((uint64_t)(*((c)++)))) - - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ - *((c)++)=(unsigned char)(((l)>>48)&0xff), \ - *((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -/* NOTE - c is not incremented as per l2c */ -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -# define n2s(c,s) ((s=(((unsigned int)((c)[0]))<< 8)| \ - (((unsigned int)((c)[1])) )),(c)+=2) -# define s2n(s,c) (((c)[0]=(unsigned char)(((s)>> 8)&0xff), \ - (c)[1]=(unsigned char)(((s) )&0xff)),(c)+=2) - -# define n2l3(c,l) ((l =(((unsigned long)((c)[0]))<<16)| \ - (((unsigned long)((c)[1]))<< 8)| \ - (((unsigned long)((c)[2])) )),(c)+=3) - -# define l2n3(l,c) (((c)[0]=(unsigned char)(((l)>>16)&0xff), \ - (c)[1]=(unsigned char)(((l)>> 8)&0xff), \ - (c)[2]=(unsigned char)(((l) )&0xff)),(c)+=3) - # define TLS_MAX_VERSION_INTERNAL TLS1_3_VERSION # define DTLS_MAX_VERSION_INTERNAL DTLS1_2_VERSION @@ -144,6 +57,7 @@ # define DTLS_VERSION_LT(v1, v2) (dtls_ver_ordinal(v1) > dtls_ver_ordinal(v2)) # define DTLS_VERSION_LE(v1, v2) (dtls_ver_ordinal(v1) >= dtls_ver_ordinal(v2)) +# define SSL_AD_NO_ALERT -1 /* * Define the Bitmasks for SSL_CIPHER.algorithms. @@ -322,6 +236,9 @@ */ # define TLS1_TLSTREE 0x20000 +/* Ciphersuite supported in QUIC */ +# define SSL_QUIC 0x00040000U + # define SSL_STRONG_MASK 0x0000001FU # define SSL_DEFAULT_MASK 0X00000020U @@ -338,45 +255,47 @@ # define SSL3_CK_CIPHERSUITE_FLAG 0x03000000 /* Check if an SSL structure is using DTLS */ -# define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +# define SSL_CONNECTION_IS_DTLS(s) \ + (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) /* Check if we are using TLSv1.3 */ -# define SSL_IS_TLS13(s) (!SSL_IS_DTLS(s) \ - && (s)->method->version >= TLS1_3_VERSION \ - && (s)->method->version != TLS_ANY_VERSION) +# define SSL_CONNECTION_IS_TLS13(s) (!SSL_CONNECTION_IS_DTLS(s) \ + && SSL_CONNECTION_GET_SSL(s)->method->version >= TLS1_3_VERSION \ + && SSL_CONNECTION_GET_SSL(s)->method->version != TLS_ANY_VERSION) -# define SSL_TREAT_AS_TLS13(s) \ - (SSL_IS_TLS13(s) || (s)->early_data_state == SSL_EARLY_DATA_CONNECTING \ +# define SSL_CONNECTION_TREAT_AS_TLS13(s) \ + (SSL_CONNECTION_IS_TLS13(s) \ + || (s)->early_data_state == SSL_EARLY_DATA_CONNECTING \ || (s)->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY \ || (s)->early_data_state == SSL_EARLY_DATA_WRITING \ || (s)->early_data_state == SSL_EARLY_DATA_WRITE_RETRY \ || (s)->hello_retry_request == SSL_HRR_PENDING) -# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3.tmp.finish_md_len == 0 \ +# define SSL_IS_FIRST_HANDSHAKE(s) ((s)->s3.tmp.finish_md_len == 0 \ || (s)->s3.tmp.peer_finish_md_len == 0) /* See if we need explicit IV */ # define SSL_USE_EXPLICIT_IV(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) + (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) /* * See if we use signature algorithms extension and signature algorithm * before signatures. */ # define SSL_USE_SIGALGS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) + (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) /* * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may * apply to others in future. */ # define SSL_USE_TLS1_2_CIPHERS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) + (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) /* * Determine if a client can use TLS 1.2 ciphersuites: can't rely on method * flags because it may not be set to correct version yet. */ # define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ - ((!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION) || \ - (SSL_IS_DTLS(s) && DTLS_VERSION_GE(s->client_version, DTLS1_2_VERSION))) + ((!SSL_CONNECTION_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION) || \ + (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_GE(s->client_version, DTLS1_2_VERSION))) /* * Determine if a client should send signature algorithms extension: * as with TLS1.2 cipher we can't rely on method flags. @@ -395,6 +314,17 @@ # define SSL_READ_ETM(s) (s->s3.flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_READ) # define SSL_WRITE_ETM(s) (s->s3.flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE) +# define SSL_IS_QUIC_HANDSHAKE(s) (((s)->s3.flags & TLS1_FLAGS_QUIC) != 0) + +/* alert_dispatch values */ + +/* No alert pending */ +# define SSL_ALERT_DISPATCH_NONE 0 +/* Alert pending */ +# define SSL_ALERT_DISPATCH_PENDING 1 +/* Pending alert write needs to be retried */ +# define SSL_ALERT_DISPATCH_RETRY 2 + /* Mostly for SSLv3 */ # define SSL_PKEY_RSA 0 # define SSL_PKEY_RSA_PSS_SIGN 1 @@ -447,6 +377,11 @@ #define CERT_PRIVATE_KEY 2 */ +/* Certificate Type State */ +# define OSSL_CERT_TYPE_CTOS_NONE 0 +# define OSSL_CERT_TYPE_CTOS_GOOD 1 +# define OSSL_CERT_TYPE_CTOS_ERROR 2 + /* Post-Handshake Authentication state */ typedef enum { SSL_PHA_NONE = 0, @@ -487,9 +422,12 @@ struct ssl_method_st { int version; unsigned flags; unsigned long mask; - int (*ssl_new) (SSL *s); - int (*ssl_clear) (SSL *s); + SSL *(*ssl_new) (SSL_CTX *ctx); void (*ssl_free) (SSL *s); + int (*ssl_reset) (SSL *s); + int (*ssl_init) (SSL *s); + int (*ssl_clear) (SSL *s); + void (*ssl_deinit) (SSL *s); int (*ssl_accept) (SSL *s); int (*ssl_connect) (SSL *s); int (*ssl_read) (SSL *s, void *buf, size_t len, size_t *readbytes); @@ -498,10 +436,10 @@ struct ssl_method_st { int (*ssl_shutdown) (SSL *s); int (*ssl_renegotiate) (SSL *s); int (*ssl_renegotiate_check) (SSL *s, int); - int (*ssl_read_bytes) (SSL *s, int type, int *recvd_type, + int (*ssl_read_bytes) (SSL *s, uint8_t type, uint8_t *recvd_type, unsigned char *buf, size_t len, int peek, size_t *readbytes); - int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, size_t len, + int (*ssl_write_bytes) (SSL *s, uint8_t type, const void *buf_, size_t len, size_t *written); int (*ssl_dispatch_alert) (SSL *s); long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); @@ -512,7 +450,7 @@ struct ssl_method_st { size_t (*ssl_pending) (const SSL *s); int (*num_ciphers) (void); const SSL_CIPHER *(*get_cipher) (unsigned ncipher); - long (*get_timeout) (void); + OSSL_TIME (*get_timeout) (void); const struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ int (*ssl_version) (void); long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); @@ -583,6 +521,8 @@ struct ssl_session_st { * to disable session caching and tickets. */ int not_resumable; + /* Peer raw public key, if available */ + EVP_PKEY *peer_rpk; /* This is the cert and type for the other end. */ X509 *peer; /* Certificate chain peer sent. */ @@ -593,10 +533,9 @@ struct ssl_session_st { */ long verify_result; /* only for servers */ CRYPTO_REF_COUNT references; - time_t timeout; - time_t time; - time_t calc_timeout; - int timeout_ovf; + OSSL_TIME timeout; + OSSL_TIME time; + OSSL_TIME calc_timeout; unsigned int compress_meth; /* Need to lookup the method */ const SSL_CIPHER *cipher; unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used to @@ -637,7 +576,6 @@ struct ssl_session_st { size_t ticket_appdata_len; uint32_t flags; SSL_CTX *owner; - CRYPTO_RWLOCK *lock; }; /* Extended master secret support */ @@ -694,11 +632,11 @@ typedef enum { /* * The allowance we have between the client's calculated ticket age and our own. - * We allow for 10 seconds (units are in ms). If a ticket is presented and the + * We allow for 10 seconds. If a ticket is presented and the * client's age calculation is different by more than this than our own then we * do not allow that ticket for early_data. */ -# define TICKET_AGE_ALLOWANCE (10 * 1000) +# define TICKET_AGE_ALLOWANCE ossl_seconds2time(10) #define MAX_COMPRESSIONS_SIZE 255 @@ -758,12 +696,15 @@ typedef enum tlsext_index_en { TLSEXT_IDX_extended_master_secret, TLSEXT_IDX_signature_algorithms_cert, TLSEXT_IDX_post_handshake_auth, + TLSEXT_IDX_client_cert_type, + TLSEXT_IDX_server_cert_type, TLSEXT_IDX_signature_algorithms, TLSEXT_IDX_supported_versions, TLSEXT_IDX_psk_kex_modes, TLSEXT_IDX_key_share, TLSEXT_IDX_cookie, TLSEXT_IDX_cryptopro_bug, + TLSEXT_IDX_compress_certificate, TLSEXT_IDX_early_data, TLSEXT_IDX_certificate_authorities, TLSEXT_IDX_padding, @@ -828,6 +769,31 @@ typedef struct tls_group_info_st { char is_kem; /* Mode for this Group: 0 is KEX, 1 is KEM */ } TLS_GROUP_INFO; +typedef struct tls_sigalg_info_st { + char *name; /* name as in IANA TLS specs */ + uint16_t code_point; /* IANA-specified code point of sigalg-name */ + char *sigalg_name; /* (combined) sigalg name */ + char *sigalg_oid; /* (combined) sigalg OID */ + char *sig_name; /* pure signature algorithm name */ + char *sig_oid; /* pure signature algorithm OID */ + char *hash_name; /* hash algorithm name */ + char *hash_oid; /* hash algorithm OID */ + char *keytype; /* keytype name */ + char *keytype_oid; /* keytype OID */ + unsigned int secbits; /* Bits of security (from SP800-57) */ + int mintls; /* Minimum TLS version, -1 unsupported */ + int maxtls; /* Maximum TLS version (or 0 for undefined) */ +} TLS_SIGALG_INFO; + +/* + * Structure containing table entry of certificate info corresponding to + * CERT_PKEY entries + */ +typedef struct { + int nid; /* NID of public key algorithm */ + uint32_t amask; /* authmask corresponding to key type */ +} SSL_CERT_LOOKUP; + /* flags values */ # define TLS_GROUP_TYPE 0x0000000FU /* Mask for group type */ # define TLS_GROUP_CURVE_PRIME 0x00000001U @@ -867,7 +833,7 @@ struct ssl_ctx_st { * SSL_new() is called. This has been put in to make life easier to set * things up */ - long session_timeout; + OSSL_TIME session_timeout; /* * If this callback is not null, it will be called each time a session id * is added to the cache. If this function returns 1, it means that the @@ -974,11 +940,11 @@ struct ssl_ctx_st { size_t max_cert_list; struct cert_st /* CERT */ *cert; + SSL_CERT_LOOKUP *ssl_cert_info; int read_ahead; /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); + ossl_msg_cb msg_callback; void *msg_callback_arg; uint32_t verify_mode; @@ -1193,30 +1159,63 @@ struct ssl_ctx_st { const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]; size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; + size_t tls12_sigalgs_len; /* Cache of all sigalgs we know and whether they are available or not */ struct sigalg_lookup_st *sigalg_lookup_cache; + /* List of all sigalgs (code points) available, incl. from providers */ + uint16_t *tls12_sigalgs; TLS_GROUP_INFO *group_list; size_t group_list_len; size_t group_list_max_len; + TLS_SIGALG_INFO *sigalg_list; + size_t sigalg_list_len; + size_t sigalg_list_max_len; + /* masks of disabled algorithms */ uint32_t disabled_enc_mask; uint32_t disabled_mac_mask; uint32_t disabled_mkey_mask; uint32_t disabled_auth_mask; + +#ifndef OPENSSL_NO_COMP_ALG + /* certificate compression preferences */ + int cert_comp_prefs[TLSEXT_comp_cert_limit]; +#endif + + /* Certificate Type stuff - for RPK vs X.509 */ + unsigned char *client_cert_type; + size_t client_cert_type_len; + unsigned char *server_cert_type; + size_t server_cert_type_len; }; typedef struct cert_pkey_st CERT_PKEY; +#define SSL_TYPE_SSL_CONNECTION 0 +#define SSL_TYPE_QUIC_CONNECTION 1 +#define SSL_TYPE_QUIC_XSO 2 + struct ssl_st { + int type; + SSL_CTX *ctx; + const SSL_METHOD *defltmeth; + const SSL_METHOD *method; + CRYPTO_REF_COUNT references; + CRYPTO_RWLOCK *lock; + /* extra application data */ + CRYPTO_EX_DATA ex_data; +}; + +struct ssl_connection_st { + /* type identifier and common data */ + struct ssl_st ssl; /* * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, * DTLS1_VERSION) */ int version; - /* SSLv3 */ - const SSL_METHOD *method; /* * There are 2 BIO's even though they are normally both the same. This * is so data can be read and written to different handlers @@ -1254,26 +1253,25 @@ struct ssl_st { int quiet_shutdown; /* we have shut things down, 0x01 sent, 0x02 for received */ int shutdown; + /* Timestamps used to calculate the handshake RTT */ + OSSL_TIME ts_msg_write; + OSSL_TIME ts_msg_read; /* where we are */ OSSL_STATEM statem; SSL_EARLY_DATA_STATE early_data_state; BUF_MEM *init_buf; /* buffer used during init */ void *init_msg; /* pointer to handshake message body, set by - * ssl3_get_message() */ + * tls_get_message_header() */ size_t init_num; /* amount read/written */ size_t init_off; /* amount read/written */ + size_t ssl_pkey_num; + struct { long flags; - size_t read_mac_secret_size; - unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; - size_t write_mac_secret_size; - unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; unsigned char server_random[SSL3_RANDOM_SIZE]; unsigned char client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_empty_fragments; - int empty_fragment_done; + /* used during startup, digest all incoming/outgoing packets */ BIO *handshake_buffer; /* @@ -1303,6 +1301,7 @@ struct ssl_st { int total_renegotiations; int num_renegotiations; int in_read_app_data; + struct { /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; @@ -1366,7 +1365,7 @@ struct ssl_st { * SSL session: e.g. appropriate curve, signature algorithms etc. * If zero it can't be used at all. */ - uint32_t valid_flags[SSL_PKEY_NUM]; + uint32_t *valid_flags; /* * For servers the following masks are for the key and auth algorithms * that are supported by the certs below. For clients they are masks of @@ -1470,14 +1469,7 @@ struct ssl_st { unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char exporter_master_secret[EVP_MAX_MD_SIZE]; unsigned char early_exporter_master_secret[EVP_MAX_MD_SIZE]; - EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ - unsigned char read_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static read IV */ - EVP_MD_CTX *read_hash; /* used for mac generation */ - COMP_CTX *compress; /* compression */ - COMP_CTX *expand; /* uncompress */ - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - unsigned char write_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static write IV */ - EVP_MD_CTX *write_hash; /* used for mac generation */ + /* session info */ /* client cert? */ /* This is used to hold the server certificate used */ @@ -1535,12 +1527,9 @@ struct ssl_st { SSL_psk_find_session_cb_func psk_find_session_cb; SSL_psk_use_session_cb_func psk_use_session_cb; - SSL_CTX *ctx; /* Verified chain of peer */ STACK_OF(X509) *verified_chain; long verify_result; - /* extra application data */ - CRYPTO_EX_DATA ex_data; /* * What we put in certificate_authorities extension for TLS 1.3 * (ClientHello and CertificateRequest) or just client cert requests for @@ -1549,7 +1538,6 @@ struct ssl_st { */ STACK_OF(X509_NAME) *ca_names; STACK_OF(X509_NAME) *client_ca_names; - CRYPTO_REF_COUNT references; /* protocol behaviour */ uint64_t options; /* API behaviour */ @@ -1680,6 +1668,16 @@ struct ssl_st { * selected. */ int tick_identity; + + /* This is the list of algorithms the peer supports that we also support */ + int compress_certificate_from_peer[TLSEXT_comp_cert_limit]; + /* indicate that we sent the extension, so we'll accept it */ + int compress_certificate_sent; + + uint8_t client_cert_type; + uint8_t client_cert_type_ctos; + uint8_t server_cert_type; + uint8_t server_cert_type_ctos; } ext; /* @@ -1743,7 +1741,10 @@ struct ssl_st { * basis, depending on the chosen cipher. */ int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure); + + /* Record layer data */ RECORD_LAYER rlayer; + /* Default password callback. */ pem_password_cb *default_passwd_callback; /* Default password callback user data. */ @@ -1771,13 +1772,6 @@ struct ssl_st { */ uint32_t early_data_count; - /* TLS1.3 padding callback */ - size_t (*record_padding_cb)(SSL *s, int type, size_t len, void *arg); - void *record_padding_arg; - size_t block_padding; - - CRYPTO_RWLOCK *lock; - /* The number of TLS1.3 tickets to automatically send */ size_t num_tickets; /* The number of TLS1.3 tickets actually sent so far */ @@ -1799,8 +1793,51 @@ struct ssl_st { */ const struct sigalg_lookup_st **shared_sigalgs; size_t shared_sigalgslen; + +#ifndef OPENSSL_NO_COMP_ALG + /* certificate compression preferences */ + int cert_comp_prefs[TLSEXT_comp_cert_limit]; +#endif + + /* Certificate Type stuff - for RPK vs X.509 */ + unsigned char *client_cert_type; + size_t client_cert_type_len; + unsigned char *server_cert_type; + size_t server_cert_type_len; }; +# define SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_SSL_CONNECTION \ + ? (c SSL_CONNECTION *)(ssl) \ + : NULL)) +# define SSL_CONNECTION_NO_CONST +# define SSL_CONNECTION_FROM_SSL_ONLY(ssl) \ + SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, SSL_CONNECTION_NO_CONST) +# define SSL_CONNECTION_FROM_CONST_SSL_ONLY(ssl) \ + SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, const) +# define SSL_CONNECTION_GET_CTX(sc) ((sc)->ssl.ctx) +# define SSL_CONNECTION_GET_SSL(sc) (&(sc)->ssl) +# ifndef OPENSSL_NO_QUIC +# include "quic/quic_local.h" +# define SSL_CONNECTION_FROM_SSL_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_SSL_CONNECTION \ + ? (c SSL_CONNECTION *)(ssl) \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c SSL_CONNECTION *)((c QUIC_CONNECTION *)(ssl))->tls \ + : NULL))) +# define SSL_CONNECTION_FROM_SSL(ssl) \ + SSL_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define SSL_CONNECTION_FROM_CONST_SSL(ssl) \ + SSL_CONNECTION_FROM_SSL_int(ssl, const) +# else +# define SSL_CONNECTION_FROM_SSL(ssl) \ + SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, SSL_CONNECTION_NO_CONST) +# define SSL_CONNECTION_FROM_CONST_SSL(ssl) \ + SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, const) +# endif + /* * Structure containing table entry of values associated with the signature * algorithms (signature scheme) extension @@ -1826,15 +1863,6 @@ typedef struct sigalg_lookup_st { int enabled; } SIGALG_LOOKUP; -/* - * Structure containing table entry of certificate info corresponding to - * CERT_PKEY entries - */ -typedef struct { - int nid; /* NID of public key algorithm */ - uint32_t amask; /* authmask corresponding to key type */ -} SSL_CERT_LOOKUP; - /* DTLS structures */ # ifndef OPENSSL_NO_SCTP @@ -1851,11 +1879,8 @@ typedef struct { # define DTLS1_SKIP_RECORD_HEADER 2 struct dtls1_retransmit_state { - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - EVP_MD_CTX *write_hash; /* used for mac generation */ - COMP_CTX *compress; /* compression */ - SSL_SESSION *session; - unsigned short epoch; + const OSSL_RECORD_METHOD *wrlmethod; + OSSL_RECORD_LAYER *wrl; }; struct hm_header_st { @@ -1918,7 +1943,7 @@ typedef struct dtls1_state_st { /* * Indicates when the last handshake msg sent will timeout */ - struct timeval next_timeout; + OSSL_TIME next_timeout; /* Timeout duration */ unsigned int timeout_duration_us; @@ -1938,6 +1963,20 @@ typedef struct dtls1_state_st { # define EXPLICIT_CHAR2_CURVE_TYPE 2 # define NAMED_CURVE_TYPE 3 +# ifndef OPENSSL_NO_COMP_ALG +struct ossl_comp_cert_st { + unsigned char *data; + size_t len; + size_t orig_len; + CRYPTO_REF_COUNT references; + int alg; +}; +typedef struct ossl_comp_cert_st OSSL_COMP_CERT; + +void OSSL_COMP_CERT_free(OSSL_COMP_CERT *c); +int OSSL_COMP_CERT_up_ref(OSSL_COMP_CERT *c); +# endif + struct cert_pkey_st { X509 *x509; EVP_PKEY *privatekey; @@ -1952,6 +1991,11 @@ struct cert_pkey_st { */ unsigned char *serverinfo; size_t serverinfo_length; +# ifndef OPENSSL_NO_COMP_ALG + /* Compressed certificate data - index 0 is unused */ + OSSL_COMP_CERT *comp_cert[TLSEXT_comp_cert_limit]; + int cert_comp_used; +# endif }; /* Retrieve Suite B flags */ # define tls1_suiteb(s) (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS) @@ -2015,7 +2059,8 @@ typedef struct cert_st { int dh_tmp_auto; /* Flags related to certificates */ uint32_t cert_flags; - CERT_PKEY pkeys[SSL_PKEY_NUM]; + CERT_PKEY *pkeys; + size_t ssl_pkey_num; /* Custom certificate types sent in certificate request message. */ uint8_t *ctype; size_t ctype_len; @@ -2065,7 +2110,6 @@ typedef struct cert_st { char *psk_identity_hint; # endif CRYPTO_REF_COUNT references; /* >1 only if SSL_copy_session_id is used */ - CRYPTO_RWLOCK *lock; } CERT; # define FP_ICC (int (*)(const void *,const void *)) @@ -2075,37 +2119,36 @@ typedef struct cert_st { * of a mess of functions, but hell, think of it as an opaque structure :-) */ typedef struct ssl3_enc_method { - int (*enc) (SSL *, SSL3_RECORD *, size_t, int, SSL_MAC_BUF *, size_t); - int (*mac) (SSL *, SSL3_RECORD *, unsigned char *, int); - int (*setup_key_block) (SSL *); - int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, - size_t, size_t *); - int (*change_cipher_state) (SSL *, int); - size_t (*final_finish_mac) (SSL *, const char *, size_t, unsigned char *); + int (*setup_key_block) (SSL_CONNECTION *); + int (*generate_master_secret) (SSL_CONNECTION *, unsigned char *, + unsigned char *, size_t, size_t *); + int (*change_cipher_state) (SSL_CONNECTION *, int); + size_t (*final_finish_mac) (SSL_CONNECTION *, const char *, size_t, + unsigned char *); const char *client_finished_label; size_t client_finished_label_len; const char *server_finished_label; size_t server_finished_label_len; int (*alert_value) (int); - int (*export_keying_material) (SSL *, unsigned char *, size_t, + int (*export_keying_material) (SSL_CONNECTION *, unsigned char *, size_t, const char *, size_t, const unsigned char *, size_t, int use_context); /* Various flags indicating protocol version requirements */ uint32_t enc_flags; /* Set the handshake header */ - int (*set_handshake_header) (SSL *s, WPACKET *pkt, int type); + int (*set_handshake_header) (SSL_CONNECTION *s, WPACKET *pkt, int type); /* Close construction of the handshake message */ - int (*close_construct_packet) (SSL *s, WPACKET *pkt, int htype); + int (*close_construct_packet) (SSL_CONNECTION *s, WPACKET *pkt, int htype); /* Write out handshake message */ - int (*do_write) (SSL *s); + int (*do_write) (SSL_CONNECTION *s); } SSL3_ENC_METHOD; # define ssl_set_handshake_header(s, pkt, htype) \ - s->method->ssl3_enc->set_handshake_header((s), (pkt), (htype)) + SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->set_handshake_header((s), (pkt), (htype)) # define ssl_close_construct_packet(s, pkt, htype) \ - s->method->ssl3_enc->close_construct_packet((s), (pkt), (htype)) -# define ssl_do_write(s) s->method->ssl3_enc->do_write(s) + SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->close_construct_packet((s), (pkt), (htype)) +# define ssl_do_write(s) SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->do_write(s) /* Values for enc_flags */ @@ -2123,16 +2166,6 @@ typedef struct ssl3_enc_method { */ # define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 -# ifndef OPENSSL_NO_COMP -/* Used for holding the relevant compression methods loaded into SSL_CTX */ -typedef struct ssl3_comp_st { - int comp_id; /* The identifier byte for this compression - * type */ - char *name; /* Text name used for the compression type */ - COMP_METHOD *method; /* The method :-) */ -} SSL3_COMP; -# endif - typedef enum downgrade_en { DOWNGRADE_NONE, DOWNGRADE_TO_1_2, @@ -2175,6 +2208,9 @@ typedef enum downgrade_en { #define TLSEXT_SIGALG_ed25519 0x0807 #define TLSEXT_SIGALG_ed448 0x0808 +#define TLSEXT_SIGALG_ecdsa_brainpoolP256r1_sha256 0x081a +#define TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384 0x081b +#define TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512 0x081c /* Known PSK key exchange modes */ #define TLSEXT_KEX_MODE_KE 0x00 @@ -2245,6 +2281,9 @@ const SSL_METHOD *func_name(void) \ version, \ flags, \ mask, \ + ossl_ssl_connection_new, \ + ossl_ssl_connection_free, \ + ossl_ssl_connection_reset, \ tls1_new, \ tls1_clear, \ tls1_free, \ @@ -2282,6 +2321,9 @@ const SSL_METHOD *func_name(void) \ SSL3_VERSION, \ SSL_METHOD_NO_FIPS | SSL_METHOD_NO_SUITEB, \ SSL_OP_NO_SSLv3, \ + ossl_ssl_connection_new, \ + ossl_ssl_connection_free, \ + ossl_ssl_connection_reset, \ ssl3_new, \ ssl3_clear, \ ssl3_free, \ @@ -2320,6 +2362,9 @@ const SSL_METHOD *func_name(void) \ version, \ flags, \ mask, \ + ossl_ssl_connection_new, \ + ossl_ssl_connection_free, \ + ossl_ssl_connection_reset, \ dtls1_new, \ dtls1_clear, \ dtls1_free, \ @@ -2351,22 +2396,58 @@ const SSL_METHOD *func_name(void) \ } struct openssl_ssl_test_functions { - int (*p_ssl_init_wbio_buffer) (SSL *s); - int (*p_ssl3_setup_buffers) (SSL *s); + int (*p_ssl_init_wbio_buffer) (SSL_CONNECTION *s); }; const char *ssl_protocol_to_string(int version); +static ossl_inline int tls12_rpk_and_privkey(const SSL_CONNECTION *sc, int idx) +{ + /* + * This is to check for special cases when using RPK with just + * a private key, and NO CERTIFICATE + */ + return ((sc->server && sc->ext.server_cert_type == TLSEXT_cert_type_rpk) + || (!sc->server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk)) + && sc->cert->pkeys[idx].privatekey != NULL + && sc->cert->pkeys[idx].x509 == NULL; +} + +static ossl_inline int ssl_has_cert_type(const SSL_CONNECTION *sc, unsigned char ct) +{ + unsigned char *ptr; + size_t len; + + if (sc->server) { + ptr = sc->server_cert_type; + len = sc->server_cert_type_len; + } else { + ptr = sc->client_cert_type; + len = sc->client_cert_type_len; + } + + if (ptr == NULL) + return 0; + + return memchr(ptr, ct, len) != NULL; +} + /* Returns true if certificate and private key for 'idx' are present */ -static ossl_inline int ssl_has_cert(const SSL *s, int idx) +static ossl_inline int ssl_has_cert(const SSL_CONNECTION *s, int idx) { - if (idx < 0 || idx >= SSL_PKEY_NUM) + if (idx < 0 || idx >= (int)s->ssl_pkey_num) return 0; + + /* If RPK is enabled for this SSL... only require private key */ + if (ssl_has_cert_type(s, TLSEXT_cert_type_rpk)) + return s->cert->pkeys[idx].privatekey != NULL; + return s->cert->pkeys[idx].x509 != NULL && s->cert->pkeys[idx].privatekey != NULL; } -static ossl_inline void tls1_get_peer_groups(SSL *s, const uint16_t **pgroups, +static ossl_inline void tls1_get_peer_groups(SSL_CONNECTION *s, + const uint16_t **pgroups, size_t *pgroupslen) { *pgroups = s->ext.peer_supportedgroups; @@ -2375,19 +2456,26 @@ static ossl_inline void tls1_get_peer_groups(SSL *s, const uint16_t **pgroups, # ifndef OPENSSL_UNIT_TEST +__owur int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, + int type); +__owur SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method); +__owur SSL *ossl_ssl_connection_new(SSL_CTX *ctx); +void ossl_ssl_connection_free(SSL *ssl); +__owur int ossl_ssl_connection_reset(SSL *ssl); + __owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes); __owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written); -void ssl_clear_cipher_ctx(SSL *s); -int ssl_clear_bad_session(SSL *s); -__owur CERT *ssl_cert_new(void); +int ssl_clear_bad_session(SSL_CONNECTION *s); +__owur CERT *ssl_cert_new(size_t ssl_pkey_num); __owur CERT *ssl_cert_dup(CERT *cert); void ssl_cert_clear_certs(CERT *c); void ssl_cert_free(CERT *c); -__owur int ssl_generate_session_id(SSL *s, SSL_SESSION *ss); -__owur int ssl_get_new_session(SSL *s, int session); -__owur SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, +__owur int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss); +__owur int ssl_get_new_session(SSL_CONNECTION *s, int session); +__owur SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s, + const unsigned char *sess_id, size_t sess_id_len); -__owur int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello); +__owur int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello); __owur SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket); __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); @@ -2399,12 +2487,13 @@ __owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, STACK_OF(SSL_CIPHER) **cipher_list_by_id, const char *rule_str, CERT *c); -__owur int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format); -__owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, - STACK_OF(SSL_CIPHER) **skp, - STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, - int fatal); -void ssl_update_cache(SSL *s, int mode); +__owur int ssl_cache_cipherlist(SSL_CONNECTION *s, PACKET *cipher_suites, + int sslv2format); +__owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **skp, + STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, + int fatal); +void ssl_update_cache(SSL_CONNECTION *s, int mode); __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_CIPHER **enc); __owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, @@ -2415,81 +2504,88 @@ __owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, size_t *int_overhead, size_t *blocksize, size_t *ext_overhead); __owur int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx); -__owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, +__owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL_CONNECTION *ssl, const unsigned char *ptr, int all); -__owur int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain); -__owur int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain); -__owur int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x); -__owur int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x); +__owur int ssl_cert_set0_chain(SSL_CONNECTION *s, SSL_CTX *ctx, + STACK_OF(X509) *chain); +__owur int ssl_cert_set1_chain(SSL_CONNECTION *s, SSL_CTX *ctx, + STACK_OF(X509) *chain); +__owur int ssl_cert_add0_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x); +__owur int ssl_cert_add1_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x); __owur int ssl_cert_select_current(CERT *c, X509 *x); __owur int ssl_cert_set_current(CERT *c, long arg); void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg); -__owur int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); -__owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags); +__owur int ssl_verify_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk); +__owur int ssl_verify_rpk(SSL_CONNECTION *s, EVP_PKEY *rpk); +__owur int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags); __owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); __owur int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain); -__owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other); +__owur int ssl_security(const SSL_CONNECTION *s, int op, int bits, int nid, + void *other); __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other); int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp); -__owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx); -__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, - size_t *pidx); -__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx); +__owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx); +__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, + size_t *pidx, + SSL_CTX *ctx); +__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx); int ssl_undefined_function(SSL *s); __owur int ssl_undefined_void_function(void); __owur int ssl_undefined_const_function(const SSL *s); -__owur int ssl_get_server_cert_serverinfo(SSL *s, +__owur int ssl_get_server_cert_serverinfo(SSL_CONNECTION *s, const unsigned char **serverinfo, size_t *serverinfo_length); -void ssl_set_masks(SSL *s); -__owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +void ssl_set_masks(SSL_CONNECTION *s); +__owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL_CONNECTION *sc); __owur int ssl_x509err2alert(int type); void ssl_sort_cipher_list(void); int ssl_load_ciphers(SSL_CTX *ctx); -__owur int ssl_setup_sig_algs(SSL_CTX *ctx); +__owur int ssl_setup_sigalgs(SSL_CTX *ctx); int ssl_load_groups(SSL_CTX *ctx); -__owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, - size_t len, DOWNGRADE dgrd); -__owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, - int free_pms); -__owur EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm); -__owur int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen); -__owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, +int ssl_load_sigalgs(SSL_CTX *ctx); +__owur int ssl_fill_hello_random(SSL_CONNECTION *s, int server, + unsigned char *field, size_t len, + DOWNGRADE dgrd); +__owur int ssl_generate_master_secret(SSL_CONNECTION *s, unsigned char *pms, + size_t pmslen, int free_pms); +__owur EVP_PKEY *ssl_generate_pkey(SSL_CONNECTION *s, EVP_PKEY *pm); +__owur int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen); +__owur int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int genmaster); -__owur int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, +__owur int ssl_decapsulate(SSL_CONNECTION *s, EVP_PKEY *privkey, const unsigned char *ct, size_t ctlen, int gensecret); -__owur int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, +__owur int ssl_encapsulate(SSL_CONNECTION *s, EVP_PKEY *pubkey, unsigned char **ctp, size_t *ctlenp, int gensecret); __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh); __owur int ssl_set_tmp_ecdh_groups(uint16_t **pext, size_t *pextlen, void *key); -__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl); -__owur unsigned int ssl_get_split_send_fragment(const SSL *ssl); +__owur unsigned int ssl_get_max_send_fragment(const SSL_CONNECTION *sc); +__owur unsigned int ssl_get_split_send_fragment(const SSL_CONNECTION *sc); __owur const SSL_CIPHER *ssl3_get_cipher_by_id(uint32_t id); __owur const SSL_CIPHER *ssl3_get_cipher_by_std_name(const char *stdname); __owur const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); __owur int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len); -int ssl3_init_finished_mac(SSL *s); -__owur int ssl3_setup_key_block(SSL *s); -__owur int ssl3_change_cipher_state(SSL *s, int which); -void ssl3_cleanup_key_block(SSL *s); -__owur int ssl3_do_write(SSL *s, int type); -int ssl3_send_alert(SSL *s, int level, int desc); -__owur int ssl3_generate_master_secret(SSL *s, unsigned char *out, +int ssl3_init_finished_mac(SSL_CONNECTION *s); +__owur int ssl3_setup_key_block(SSL_CONNECTION *s); +__owur int ssl3_change_cipher_state(SSL_CONNECTION *s, int which); +void ssl3_cleanup_key_block(SSL_CONNECTION *s); +__owur int ssl3_do_write(SSL_CONNECTION *s, uint8_t type); +int ssl3_send_alert(SSL_CONNECTION *s, int level, int desc); +__owur int ssl3_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, unsigned char *p, size_t len, size_t *secret_size); -__owur int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt); +__owur int ssl3_get_req_cert_type(SSL_CONNECTION *s, WPACKET *pkt); __owur int ssl3_num_ciphers(void); __owur const SSL_CIPHER *ssl3_get_cipher(unsigned int u); int ssl3_renegotiate(SSL *ssl); @@ -2497,16 +2593,17 @@ int ssl3_renegotiate_check(SSL *ssl, int initok); void ssl3_digest_master_key_set_params(const SSL_SESSION *session, OSSL_PARAM params[]); __owur int ssl3_dispatch_alert(SSL *s); -__owur size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t slen, - unsigned char *p); -__owur int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len); -void ssl3_free_digest_list(SSL *s); -__owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, - CERT_PKEY *cpk); -__owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, +__owur size_t ssl3_final_finish_mac(SSL_CONNECTION *s, const char *sender, + size_t slen, unsigned char *p); +__owur int ssl3_finish_mac(SSL_CONNECTION *s, const unsigned char *buf, + size_t len); +void ssl3_free_digest_list(SSL_CONNECTION *s); +__owur unsigned long ssl3_output_cert_chain(SSL_CONNECTION *s, WPACKET *pkt, + CERT_PKEY *cpk, int for_comp); +__owur const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *srvr); -__owur int ssl3_digest_cached_records(SSL *s, int keep); +__owur int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep); __owur int ssl3_new(SSL *s); void ssl3_free(SSL *s); __owur int ssl3_read(SSL *s, void *buf, size_t len, size_t *readbytes); @@ -2519,62 +2616,64 @@ __owur long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); __owur long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); __owur long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); -__owur int ssl3_do_change_cipher_spec(SSL *ssl); -__owur long ssl3_default_timeout(void); +__owur int ssl3_do_change_cipher_spec(SSL_CONNECTION *s); +__owur OSSL_TIME ssl3_default_timeout(void); -__owur int ssl3_set_handshake_header(SSL *s, WPACKET *pkt, int htype); -__owur int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype); -__owur int tls_setup_handshake(SSL *s); -__owur int dtls1_set_handshake_header(SSL *s, WPACKET *pkt, int htype); -__owur int dtls1_close_construct_packet(SSL *s, WPACKET *pkt, int htype); -__owur int ssl3_handshake_write(SSL *s); +__owur int ssl3_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, + int htype); +__owur int tls_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype); +__owur int tls_setup_handshake(SSL_CONNECTION *s); +__owur int dtls1_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype); +__owur int dtls1_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype); +__owur int ssl3_handshake_write(SSL_CONNECTION *s); -__owur int ssl_allow_compression(SSL *s); +__owur int ssl_allow_compression(SSL_CONNECTION *s); -__owur int ssl_version_supported(const SSL *s, int version, +__owur int ssl_version_supported(const SSL_CONNECTION *s, int version, const SSL_METHOD **meth); -__owur int ssl_set_client_hello_version(SSL *s); -__owur int ssl_check_version_downgrade(SSL *s); +__owur int ssl_set_client_hello_version(SSL_CONNECTION *s); +__owur int ssl_check_version_downgrade(SSL_CONNECTION *s); __owur int ssl_set_version_bound(int method_version, int version, int *bound); -__owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, +__owur int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd); -__owur int ssl_choose_client_version(SSL *s, int version, +__owur int ssl_choose_client_version(SSL_CONNECTION *s, int version, RAW_EXTENSION *extensions); -__owur int ssl_get_min_max_version(const SSL *s, int *min_version, +__owur int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, int *max_version, int *real_max); -__owur long tls1_default_timeout(void); -__owur int dtls1_do_write(SSL *s, int type); -void dtls1_set_message_header(SSL *s, +__owur OSSL_TIME tls1_default_timeout(void); +__owur int dtls1_do_write(SSL_CONNECTION *s, uint8_t type); +void dtls1_set_message_header(SSL_CONNECTION *s, unsigned char mt, size_t len, size_t frag_off, size_t frag_len); -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, - size_t *written); +int dtls1_write_app_data_bytes(SSL *s, uint8_t type, const void *buf_, + size_t len, size_t *written); -__owur int dtls1_read_failed(SSL *s, int code); -__owur int dtls1_buffer_message(SSL *s, int ccs); -__owur int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found); +__owur int dtls1_read_failed(SSL_CONNECTION *s, int code); +__owur int dtls1_buffer_message(SSL_CONNECTION *s, int ccs); +__owur int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, + int *found); __owur int dtls1_get_queue_priority(unsigned short seq, int is_ccs); -int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_received_buffer(SSL *s); -void dtls1_clear_sent_buffer(SSL *s); -void dtls1_get_message_header(unsigned char *data, +int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s); +void dtls1_clear_received_buffer(SSL_CONNECTION *s); +void dtls1_clear_sent_buffer(SSL_CONNECTION *s); +void dtls1_get_message_header(const unsigned char *data, struct hm_header_st *msg_hdr); -__owur long dtls1_default_timeout(void); -__owur struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft); -__owur int dtls1_check_timeout_num(SSL *s); -__owur int dtls1_handle_timeout(SSL *s); -void dtls1_start_timer(SSL *s); -void dtls1_stop_timer(SSL *s); -__owur int dtls1_is_timer_expired(SSL *s); +__owur OSSL_TIME dtls1_default_timeout(void); +__owur int dtls1_get_timeout(const SSL_CONNECTION *s, OSSL_TIME *timeleft); +__owur int dtls1_check_timeout_num(SSL_CONNECTION *s); +__owur int dtls1_handle_timeout(SSL_CONNECTION *s); +void dtls1_start_timer(SSL_CONNECTION *s); +void dtls1_stop_timer(SSL_CONNECTION *s); +__owur int dtls1_is_timer_expired(SSL_CONNECTION *s); __owur int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, size_t cookie_len); -__owur size_t dtls1_min_mtu(SSL *s); +__owur size_t dtls1_min_mtu(SSL_CONNECTION *s); void dtls1_hm_fragment_free(hm_fragment *frag); -__owur int dtls1_query_mtu(SSL *s); +__owur int dtls1_query_mtu(SSL_CONNECTION *s); __owur int tls1_new(SSL *s); void tls1_free(SSL *s); @@ -2588,144 +2687,161 @@ __owur int dtls1_shutdown(SSL *s); __owur int dtls1_dispatch_alert(SSL *s); -__owur int ssl_init_wbio_buffer(SSL *s); -int ssl_free_wbio_buffer(SSL *s); +__owur int ssl_init_wbio_buffer(SSL_CONNECTION *s); +int ssl_free_wbio_buffer(SSL_CONNECTION *s); -__owur int tls1_change_cipher_state(SSL *s, int which); -__owur int tls1_setup_key_block(SSL *s); -__owur size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, - unsigned char *p); -__owur int tls1_generate_master_secret(SSL *s, unsigned char *out, +__owur int tls1_change_cipher_state(SSL_CONNECTION *s, int which); +__owur int tls1_setup_key_block(SSL_CONNECTION *s); +__owur size_t tls1_final_finish_mac(SSL_CONNECTION *s, const char *str, + size_t slen, unsigned char *p); +__owur int tls1_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, unsigned char *p, size_t len, size_t *secret_size); -__owur int tls13_setup_key_block(SSL *s); -__owur size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, +__owur int tls13_setup_key_block(SSL_CONNECTION *s); +__owur size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen, unsigned char *p); -__owur int tls13_change_cipher_state(SSL *s, int which); -__owur int tls13_update_key(SSL *s, int send); -__owur int tls13_hkdf_expand(SSL *s, const EVP_MD *md, +__owur int tls13_change_cipher_state(SSL_CONNECTION *s, int which); +__owur int tls13_update_key(SSL_CONNECTION *s, int send); +__owur int tls13_hkdf_expand(SSL_CONNECTION *s, + const EVP_MD *md, const unsigned char *secret, const unsigned char *label, size_t labellen, const unsigned char *data, size_t datalen, unsigned char *out, size_t outlen, int fatal); -__owur int tls13_derive_key(SSL *s, const EVP_MD *md, +__owur int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EVP_MD *md, + const unsigned char *secret, + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen, + int raise_error); +__owur int tls13_derive_key(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *secret, unsigned char *key, size_t keylen); -__owur int tls13_derive_iv(SSL *s, const EVP_MD *md, +__owur int tls13_derive_iv(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *secret, unsigned char *iv, size_t ivlen); -__owur int tls13_derive_finishedkey(SSL *s, const EVP_MD *md, +__owur int tls13_derive_finishedkey(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *secret, unsigned char *fin, size_t finlen); -int tls13_generate_secret(SSL *s, const EVP_MD *md, +int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *prevsecret, const unsigned char *insecret, size_t insecretlen, unsigned char *outsecret); -__owur int tls13_generate_handshake_secret(SSL *s, +__owur int tls13_generate_handshake_secret(SSL_CONNECTION *s, const unsigned char *insecret, size_t insecretlen); -__owur int tls13_generate_master_secret(SSL *s, unsigned char *out, +__owur int tls13_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, unsigned char *prev, size_t prevlen, size_t *secret_size); -__owur int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, +__owur int tls1_export_keying_material(SSL_CONNECTION *s, + unsigned char *out, size_t olen, const char *label, size_t llen, const unsigned char *p, size_t plen, int use_context); -__owur int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen, +__owur int tls13_export_keying_material(SSL_CONNECTION *s, + unsigned char *out, size_t olen, const char *label, size_t llen, const unsigned char *context, size_t contextlen, int use_context); -__owur int tls13_export_keying_material_early(SSL *s, unsigned char *out, - size_t olen, const char *label, - size_t llen, +__owur int tls13_export_keying_material_early(SSL_CONNECTION *s, + unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *context, size_t contextlen); __owur int tls1_alert_code(int code); __owur int tls13_alert_code(int code); __owur int ssl3_alert_code(int code); -__owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); +__owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL_CONNECTION *s); SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); __owur const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t curve_id); +__owur const char *tls1_group_id2name(SSL_CTX *ctx, uint16_t group_id); __owur int tls1_group_id2nid(uint16_t group_id, int include_unknown); __owur uint16_t tls1_nid2group_id(int nid); -__owur int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_curves); -__owur uint16_t tls1_shared_group(SSL *s, int nmatch); +__owur int tls1_check_group_id(SSL_CONNECTION *s, uint16_t group_id, + int check_own_curves); +__owur uint16_t tls1_shared_group(SSL_CONNECTION *s, int nmatch); __owur int tls1_set_groups(uint16_t **pext, size_t *pextlen, int *curves, size_t ncurves); __owur int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, const char *str); -__owur EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id); -__owur int tls_valid_group(SSL *s, uint16_t group_id, int minversion, +__owur EVP_PKEY *ssl_generate_pkey_group(SSL_CONNECTION *s, uint16_t id); +__owur int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, int minversion, int maxversion, int isec, int *okfortls13); -__owur EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id); -void tls1_get_formatlist(SSL *s, const unsigned char **pformats, +__owur EVP_PKEY *ssl_generate_param_group(SSL_CONNECTION *s, uint16_t id); +void tls1_get_formatlist(SSL_CONNECTION *s, const unsigned char **pformats, size_t *num_formats); -__owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id); +__owur int tls1_check_ec_tmp_key(SSL_CONNECTION *s, unsigned long id); -__owur int tls_group_allowed(SSL *s, uint16_t curve, int op); -void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, +__owur int tls_group_allowed(SSL_CONNECTION *s, uint16_t curve, int op); +void tls1_get_supported_groups(SSL_CONNECTION *s, const uint16_t **pgroups, size_t *pgroupslen); -__owur int tls1_set_server_sigalgs(SSL *s); +__owur int tls1_set_server_sigalgs(SSL_CONNECTION *s); -__owur SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, +__owur SSL_TICKET_STATUS tls_get_ticket_from_client(SSL_CONNECTION *s, + CLIENTHELLO_MSG *hello, SSL_SESSION **ret); -__owur SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, +__owur SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s, + const unsigned char *etick, size_t eticklen, const unsigned char *sess_id, size_t sesslen, SSL_SESSION **psess); -__owur int tls_use_ticket(SSL *s); +__owur int tls_use_ticket(SSL_CONNECTION *s); -void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op); +void ssl_set_sig_mask(uint32_t *pmask_a, SSL_CONNECTION *s, int op); __owur int tls1_set_sigalgs_list(CERT *c, const char *str, int client); __owur int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, int client); __owur int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client); -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx); -void tls1_set_cert_validity(SSL *s); +int tls1_check_chain(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pk, + STACK_OF(X509) *chain, int idx); +void tls1_set_cert_validity(SSL_CONNECTION *s); # ifndef OPENSSL_NO_CT -__owur int ssl_validate_ct(SSL *s); +__owur int ssl_validate_ct(SSL_CONNECTION *s); # endif -__owur EVP_PKEY *ssl_get_auto_dh(SSL *s); +__owur EVP_PKEY *ssl_get_auto_dh(SSL_CONNECTION *s); -__owur int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee); -__owur int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex, - int vfy); +__owur int ssl_security_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x, int vfy, + int is_ee); +__owur int ssl_security_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk, + X509 *ex, int vfy); -int tls_choose_sigalg(SSL *s, int fatalerrs); +int tls_choose_sigalg(SSL_CONNECTION *s, int fatalerrs); -__owur EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); -void ssl_clear_hash_ctx(EVP_MD_CTX **hash); -__owur long ssl_get_algorithm2(SSL *s); -__owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, +__owur long ssl_get_algorithm2(SSL_CONNECTION *s); +__owur int tls12_copy_sigalgs(SSL_CONNECTION *s, WPACKET *pkt, const uint16_t *psig, size_t psiglen); __owur int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen); -__owur int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert); -__owur int tls1_process_sigalgs(SSL *s); -__owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey); +__owur int tls1_save_sigalgs(SSL_CONNECTION *s, PACKET *pkt, int cert); +__owur int tls1_process_sigalgs(SSL_CONNECTION *s); +__owur int tls1_set_peer_legacy_sigalg(SSL_CONNECTION *s, const EVP_PKEY *pkey); __owur int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd); -__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs); -__owur int tls_check_sigalg_curve(const SSL *s, int curve); -__owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey); -__owur int ssl_set_client_disabled(SSL *s); -__owur int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int echde); - -__owur int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen, - size_t *hashlen); +__owur size_t tls12_get_psigalgs(SSL_CONNECTION *s, int sent, + const uint16_t **psigs); +__owur int tls_check_sigalg_curve(const SSL_CONNECTION *s, int curve); +__owur int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t, EVP_PKEY *pkey); +__owur int ssl_set_client_disabled(SSL_CONNECTION *s); +__owur int ssl_cipher_disabled(const SSL_CONNECTION *s, const SSL_CIPHER *c, + int op, int echde); + +__owur int ssl_handshake_hash(SSL_CONNECTION *s, + unsigned char *out, size_t outlen, + size_t *hashlen); __owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx); -__owur const EVP_MD *ssl_handshake_md(SSL *s); -__owur const EVP_MD *ssl_prf_md(SSL *s); +int ssl_get_md_idx(int md_nid); +__owur const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s); +__owur const EVP_MD *ssl_prf_md(SSL_CONNECTION *s); /* * ssl_log_rsa_client_key_exchange logs |premaster| to the SSL_CTX associated @@ -2733,7 +2849,7 @@ __owur const EVP_MD *ssl_prf_md(SSL *s); * failure. The entry is identified by the first 8 bytes of * |encrypted_premaster|. */ -__owur int ssl_log_rsa_client_key_exchange(SSL *ssl, +__owur int ssl_log_rsa_client_key_exchange(SSL_CONNECTION *s, const uint8_t *encrypted_premaster, size_t encrypted_premaster_len, const uint8_t *premaster, @@ -2744,7 +2860,7 @@ __owur int ssl_log_rsa_client_key_exchange(SSL *ssl, * logging is available. It returns one on success and zero on failure. It tags * the entry with |label|. */ -__owur int ssl_log_secret(SSL *ssl, const char *label, +__owur int ssl_log_secret(SSL_CONNECTION *s, const char *label, const uint8_t *secret, size_t secret_len); #define MASTER_SECRET_LABEL "CLIENT_RANDOM" @@ -2758,36 +2874,13 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" -# ifndef OPENSSL_NO_KTLS -/* ktls.c */ -int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd); -int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, - void *rl_sequence, ktls_crypto_info_t *crypto_info, - unsigned char **rec_seq, unsigned char *iv, - unsigned char *key, unsigned char *mac_key, - size_t mac_secret_size); -# endif - -/* s3_cbc.c */ -__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -__owur int ssl3_cbc_digest_record(const EVP_MD *md, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char *header, - const unsigned char *data, - size_t data_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - size_t mac_secret_length, char is_sslv3); - -__owur int srp_generate_server_master_secret(SSL *s); -__owur int srp_generate_client_master_secret(SSL *s); -__owur int srp_verify_server_param(SSL *s); +__owur int srp_generate_server_master_secret(SSL_CONNECTION *s); +__owur int srp_generate_client_master_secret(SSL_CONNECTION *s); +__owur int srp_verify_server_param(SSL_CONNECTION *s); /* statem/statem_srvr.c */ -__owur int send_certificate_request(SSL *s); +__owur int send_certificate_request(SSL_CONNECTION *s); /* statem/extensions_cust.c */ @@ -2797,10 +2890,19 @@ custom_ext_method *custom_ext_find(const custom_ext_methods *exts, void custom_ext_init(custom_ext_methods *meths); -__owur int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, +int ossl_tls_add_custom_ext_intern(SSL_CTX *ctx, custom_ext_methods *exts, + ENDPOINT role, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg); +__owur int custom_ext_parse(SSL_CONNECTION *s, unsigned int context, + unsigned int ext_type, const unsigned char *ext_data, size_t ext_size, X509 *x, size_t chainidx); -__owur int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, +__owur int custom_ext_add(SSL_CONNECTION *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, int maxversion); __owur int custom_exts_copy(custom_ext_methods *dst, @@ -2825,14 +2927,15 @@ const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx, int ssl_evp_md_up_ref(const EVP_MD *md); void ssl_evp_md_free(const EVP_MD *md); -int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx, +int tls_provider_set_tls_params(SSL_CONNECTION *s, EVP_CIPHER_CTX *ctx, const EVP_CIPHER *ciph, const EVP_MD *md); void tls_engine_finish(ENGINE *e); const EVP_CIPHER *tls_get_cipher_from_engine(int nid); const EVP_MD *tls_get_digest_from_engine(int nid); -int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey); +int tls_engine_load_ssl_client_cert(SSL_CONNECTION *s, X509 **px509, + EVP_PKEY **ppkey); int ssl_hmac_old_new(SSL_HMAC *ret); void ssl_hmac_old_free(SSL_HMAC *ctx); int ssl_hmac_old_init(SSL_HMAC *ctx, void *key, size_t len, char *md); @@ -2842,18 +2945,17 @@ size_t ssl_hmac_old_size(const SSL_HMAC *ctx); int ssl_ctx_srp_ctx_free_intern(SSL_CTX *ctx); int ssl_ctx_srp_ctx_init_intern(SSL_CTX *ctx); -int ssl_srp_ctx_free_intern(SSL *s); -int ssl_srp_ctx_init_intern(SSL *s); +int ssl_srp_ctx_free_intern(SSL_CONNECTION *s); +int ssl_srp_ctx_init_intern(SSL_CONNECTION *s); -int ssl_srp_calc_a_param_intern(SSL *s); -int ssl_srp_server_param_with_username_intern(SSL *s, int *ad); +int ssl_srp_calc_a_param_intern(SSL_CONNECTION *s); +int ssl_srp_server_param_with_username_intern(SSL_CONNECTION *s, int *ad); -void ssl_session_calculate_timeout(SSL_SESSION* ss); +void ssl_session_calculate_timeout(SSL_SESSION *ss); # else /* OPENSSL_UNIT_TEST */ # define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer -# define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers # endif @@ -2883,4 +2985,86 @@ static ossl_unused ossl_inline void ssl_tsan_counter(const SSL_CTX *ctx, } } +int ossl_comp_has_alg(int a); +size_t ossl_calculate_comp_expansion(int alg, size_t length); + +void ossl_ssl_set_custom_record_layer(SSL_CONNECTION *s, + const OSSL_RECORD_METHOD *meth, + void *rlarg); + +long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic); + +/* + * Options which no longer have any effect, but which can be implemented + * as no-ops for QUIC. + */ +#define OSSL_LEGACY_SSL_OPTIONS \ + (SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG | \ + SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER | \ + SSL_OP_SSLEAY_080_CLIENT_DH_BUG | \ + SSL_OP_TLS_D5_BUG | \ + SSL_OP_TLS_BLOCK_PADDING_BUG | \ + SSL_OP_MSIE_SSLV2_RSA_PADDING | \ + SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG | \ + SSL_OP_MICROSOFT_SESS_ID_BUG | \ + SSL_OP_NETSCAPE_CHALLENGE_BUG | \ + SSL_OP_PKCS1_CHECK_1 | \ + SSL_OP_PKCS1_CHECK_2 | \ + SSL_OP_SINGLE_DH_USE | \ + SSL_OP_SINGLE_ECDH_USE | \ + SSL_OP_EPHEMERAL_RSA ) + +/* This option is undefined in public headers with no-dtls1-method. */ +#ifndef SSL_OP_CISCO_ANYCONNECT +# define SSL_OP_CISCO_ANYCONNECT 0 +#endif +/* + * Options which are no-ops under QUIC or TLSv1.3 and which are therefore + * allowed but ignored under QUIC. + */ +#define OSSL_TLS1_2_OPTIONS \ + (SSL_OP_CRYPTOPRO_TLSEXT_BUG | \ + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | \ + SSL_OP_ALLOW_CLIENT_RENEGOTIATION | \ + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | \ + SSL_OP_NO_COMPRESSION | \ + SSL_OP_NO_SSLv3 | \ + SSL_OP_NO_TLSv1 | \ + SSL_OP_NO_TLSv1_1 | \ + SSL_OP_NO_TLSv1_2 | \ + SSL_OP_NO_DTLSv1 | \ + SSL_OP_NO_DTLSv1_2 | \ + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | \ + SSL_OP_CISCO_ANYCONNECT | \ + SSL_OP_NO_RENEGOTIATION | \ + SSL_OP_NO_EXTENDED_MASTER_SECRET | \ + SSL_OP_NO_ENCRYPT_THEN_MAC | \ + SSL_OP_COOKIE_EXCHANGE | \ + SSL_OP_LEGACY_SERVER_CONNECT | \ + SSL_OP_IGNORE_UNEXPECTED_EOF ) + +/* Total mask of connection-level options permitted or ignored under QUIC. */ +#define OSSL_QUIC_PERMITTED_OPTIONS_CONN \ + (OSSL_LEGACY_SSL_OPTIONS | \ + OSSL_TLS1_2_OPTIONS | \ + SSL_OP_CIPHER_SERVER_PREFERENCE | \ + SSL_OP_DISABLE_TLSEXT_CA_NAMES | \ + SSL_OP_NO_TX_CERTIFICATE_COMPRESSION | \ + SSL_OP_NO_RX_CERTIFICATE_COMPRESSION | \ + SSL_OP_PRIORITIZE_CHACHA | \ + SSL_OP_NO_QUERY_MTU | \ + SSL_OP_NO_TICKET | \ + SSL_OP_NO_ANTI_REPLAY ) + +/* Total mask of stream-level options permitted or ignored under QUIC. */ +#define OSSL_QUIC_PERMITTED_OPTIONS_STREAM \ + (OSSL_LEGACY_SSL_OPTIONS | \ + OSSL_TLS1_2_OPTIONS | \ + SSL_OP_CLEANSE_PLAINTEXT ) + +/* Total mask of options permitted on either connections or streams. */ +#define OSSL_QUIC_PERMITTED_OPTIONS \ + (OSSL_QUIC_PERMITTED_OPTIONS_CONN | \ + OSSL_QUIC_PERMITTED_OPTIONS_STREAM) + #endif diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 4f45e60535..c245c24080 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,29 +17,37 @@ #include #include -static int ssl_set_cert(CERT *c, X509 *x509); -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +static int ssl_set_cert(CERT *c, X509 *x509, SSL_CTX *ctx); +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey, SSL_CTX *ctx); #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ | SSL_EXT_CLIENT_HELLO \ | SSL_EXT_TLS1_2_SERVER_HELLO \ | SSL_EXT_IGNORE_ON_RESUMPTION) +#define NAME_PREFIX1 "SERVERINFO FOR " +#define NAME_PREFIX2 "SERVERINFOV2 FOR " + int SSL_use_certificate(SSL *ssl, X509 *x) { int rv; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + if (x == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - rv = ssl_security_cert(ssl, NULL, x, 0, 1); + rv = ssl_security_cert(sc, NULL, x, 0, 1); if (rv != 1) { ERR_raise(ERR_LIB_SSL, rv); return 0; } - return ssl_set_cert(ssl->cert, x); + return ssl_set_cert(sc->cert, x, SSL_CONNECTION_GET_CTX(sc)); } int SSL_use_certificate_file(SSL *ssl, const char *file, int type) @@ -60,22 +68,23 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) goto end; } - if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { - ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); - goto end; - } x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; cert = d2i_X509_bio(in, &x); } else if (type == SSL_FILETYPE_PEM) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + goto end; + j = ERR_R_PEM_LIB; - cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata); + cert = PEM_read_bio_X509(in, &x, sc->default_passwd_callback, + sc->default_passwd_callback_userdata); } else { ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); goto end; @@ -100,7 +109,7 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } @@ -115,11 +124,11 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) return ret; } -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey, SSL_CTX *ctx) { size_t i; - if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { + if (ssl_cert_lookup_by_pkey(pkey, &i, ctx) == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } @@ -138,12 +147,16 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; if (pkey == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - ret = ssl_set_pkey(ssl->cert, pkey); + ret = ssl_set_pkey(sc->cert, pkey, SSL_CONNECTION_GET_CTX(sc)); return ret; } @@ -164,10 +177,15 @@ int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) goto end; } if (type == SSL_FILETYPE_PEM) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + goto end; + j = ERR_R_PEM_LIB; pkey = PEM_read_bio_PrivateKey_ex(in, NULL, - ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata, + sc->default_passwd_callback, + sc->default_passwd_callback_userdata, ssl->ctx->libctx, ssl->ctx->propq); } else if (type == SSL_FILETYPE_ASN1) { @@ -221,10 +239,10 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) ERR_raise(ERR_LIB_SSL, rv); return 0; } - return ssl_set_cert(ctx->cert, x); + return ssl_set_cert(ctx->cert, x, ctx); } -static int ssl_set_cert(CERT *c, X509 *x) +static int ssl_set_cert(CERT *c, X509 *x, SSL_CTX *ctx) { EVP_PKEY *pkey; size_t i; @@ -235,7 +253,7 @@ static int ssl_set_cert(CERT *c, X509 *x) return 0; } - if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { + if (ssl_cert_lookup_by_pkey(pkey, &i, ctx) == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } @@ -249,6 +267,7 @@ static int ssl_set_cert(CERT *c, X509 *x) /* * The return code from EVP_PKEY_copy_parameters is deliberately * ignored. Some EVP_PKEY types cannot do this. + * coverity[check_return] */ EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); ERR_clear_error(); @@ -291,13 +310,10 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto end; } - if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { - ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); - goto end; - } + x = X509_new_ex(ctx->libctx, ctx->propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { @@ -307,6 +323,9 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) j = ERR_R_PEM_LIB; cert = PEM_read_bio_X509(in, &x, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); + } else { + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; } if (cert == NULL) { ERR_raise(ERR_LIB_SSL, j); @@ -327,7 +346,7 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) x = X509_new_ex(ctx->libctx, ctx->propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } @@ -348,7 +367,7 @@ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - return ssl_set_pkey(ctx->cert, pkey); + return ssl_set_pkey(ctx->cert, pkey, ctx); } int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) @@ -434,8 +453,13 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) passwd_callback = ctx->default_passwd_callback; passwd_callback_userdata = ctx->default_passwd_callback_userdata; } else { - passwd_callback = ssl->default_passwd_callback; - passwd_callback_userdata = ssl->default_passwd_callback_userdata; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return 0; + + passwd_callback = sc->default_passwd_callback; + passwd_callback_userdata = sc->default_passwd_callback_userdata; } in = BIO_new(BIO_s_file()); @@ -451,7 +475,7 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) x = X509_new_ex(real_ctx->libctx, real_ctx->propq); if (x == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); goto end; } if (PEM_read_bio_X509_AUX(in, &x, passwd_callback, @@ -490,7 +514,7 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) while (1) { ca = X509_new_ex(real_ctx->libctx, real_ctx->propq); if (ca == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); goto end; } if (PEM_read_bio_X509(in, &ca, passwd_callback, @@ -570,7 +594,7 @@ static int serverinfo_find_extension(const unsigned char *serverinfo, if (type == extension_type) { *extension_data = PACKET_data(&data); - *extension_length = PACKET_remaining(&data);; + *extension_length = PACKET_remaining(&data); return 1; /* Success */ } } @@ -608,13 +632,19 @@ static int serverinfoex_srv_add_cb(SSL *s, unsigned int ext_type, { const unsigned char *serverinfo = NULL; size_t serverinfo_length = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return -1; + } /* We only support extensions for the first Certificate */ if ((context & SSL_EXT_TLS1_3_CERTIFICATE) != 0 && chainidx > 0) return 0; /* Is there serverinfo data for the chosen server cert? */ - if ((ssl_get_server_cert_serverinfo(s, &serverinfo, + if ((ssl_get_server_cert_serverinfo(sc, &serverinfo, &serverinfo_length)) != 0) { /* Find the relevant extension from the serverinfo */ int retval = serverinfo_find_extension(serverinfo, serverinfo_length, @@ -752,10 +782,8 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, int ret; sinfo = OPENSSL_malloc(sinfo_length); - if (sinfo == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (sinfo == NULL) return 0; - } extension_append(SSL_SERVERINFOV1, serverinfo, serverinfo_length, sinfo); @@ -776,10 +804,8 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, } new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, serverinfo_length); - if (new_serverinfo == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (new_serverinfo == NULL) return 0; - } ctx->cert->key->serverinfo = new_serverinfo; memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); ctx->cert->key->serverinfo_length = serverinfo_length; @@ -812,8 +838,6 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) long extension_length = 0; char *name = NULL; char *header = NULL; - static const char namePrefix1[] = "SERVERINFO FOR "; - static const char namePrefix2[] = "SERVERINFOV2 FOR "; unsigned int name_len; int ret = 0; BIO *bin = NULL; @@ -851,18 +875,18 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) } /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ name_len = strlen(name); - if (name_len < sizeof(namePrefix1) - 1) { + if (name_len < sizeof(NAME_PREFIX1) - 1) { ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT); goto end; } - if (strncmp(name, namePrefix1, sizeof(namePrefix1) - 1) == 0) { + if (HAS_PREFIX(name, NAME_PREFIX1)) { version = SSL_SERVERINFOV1; } else { - if (name_len < sizeof(namePrefix2) - 1) { + if (name_len < sizeof(NAME_PREFIX2) - 1) { ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT); goto end; } - if (strncmp(name, namePrefix2, sizeof(namePrefix2) - 1) != 0) { + if (!HAS_PREFIX(name, NAME_PREFIX2)) { ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX); goto end; } @@ -891,10 +915,8 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) /* Append the decoded extension to the serverinfo buffer */ append_length = extension_append_length(version, extension_length); tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length); - if (tmp == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (tmp == NULL) goto end; - } serverinfo = tmp; extension_append(version, extension, extension_length, serverinfo + serverinfo_length); @@ -927,18 +949,24 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr size_t i; int j; int rv; - CERT *c = ssl != NULL ? ssl->cert : ctx->cert; + CERT *c; STACK_OF(X509) *dup_chain = NULL; EVP_PKEY *pubkey = NULL; + SSL_CONNECTION *sc = NULL; + + if (ctx == NULL && + (sc = SSL_CONNECTION_FROM_SSL(ssl)) == NULL) + return 0; + c = sc != NULL ? sc->cert : ctx->cert; /* Do all security checks before anything else */ - rv = ssl_security_cert(ssl, ctx, x509, 0, 1); + rv = ssl_security_cert(sc, ctx, x509, 0, 1); if (rv != 1) { ERR_raise(ERR_LIB_SSL, rv); goto out; } for (j = 0; j < sk_X509_num(chain); j++) { - rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); + rv = ssl_security_cert(sc, ctx, sk_X509_value(chain, j), 0, 0); if (rv != 1) { ERR_raise(ERR_LIB_SSL, rv); goto out; @@ -978,7 +1006,7 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr goto out; } } - if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) { + if (ssl_cert_lookup_by_pkey(pubkey, &i, ctx) == NULL) { ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); goto out; } @@ -994,12 +1022,12 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr if (chain != NULL) { dup_chain = X509_chain_up_ref(chain); if (dup_chain == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto out; } } - sk_X509_pop_free(c->pkeys[i].chain, X509_free); + OSSL_STACK_OF_X509_free(c->pkeys[i].chain); c->pkeys[i].chain = dup_chain; X509_free(c->pkeys[i].x509); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index bf84e79225..3dcc4d81e5 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -26,56 +26,27 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); DEFINE_STACK_OF(SSL_SESSION) -__owur static int sess_timedout(time_t t, SSL_SESSION *ss) +__owur static ossl_inline int sess_timedout(OSSL_TIME t, SSL_SESSION *ss) { - /* if timeout overflowed, it can never timeout! */ - if (ss->timeout_ovf) - return 0; - return t > ss->calc_timeout; + return ossl_time_compare(t, ss->calc_timeout) > 0; } /* * Returns -1/0/+1 as other XXXcmp-type functions - * Takes overflow of calculated timeout into consideration + * Takes calculated timeout into consideration */ -__owur static int timeoutcmp(SSL_SESSION *a, SSL_SESSION *b) +__owur static ossl_inline int timeoutcmp(SSL_SESSION *a, SSL_SESSION *b) { - /* if only one overflowed, then it is greater */ - if (a->timeout_ovf && !b->timeout_ovf) - return 1; - if (!a->timeout_ovf && b->timeout_ovf) - return -1; - /* No overflow, or both overflowed, so straight compare is safe */ - if (a->calc_timeout < b->calc_timeout) - return -1; - if (a->calc_timeout > b->calc_timeout) - return 1; - return 0; + return ossl_time_compare(a->calc_timeout, b->calc_timeout); } /* - * Calculates effective timeout, saving overflow state + * Calculates effective timeout * Locking must be done by the caller of this function */ void ssl_session_calculate_timeout(SSL_SESSION *ss) { -#ifndef __DJGPP__ /* time_t is unsigned on djgpp */ - /* Force positive timeout */ - if (ss->timeout < 0) - ss->timeout = 0; -#endif - ss->calc_timeout = ss->time + ss->timeout; - /* - * |timeout| is always zero or positive, so the check for - * overflow only needs to consider if |time| is positive - */ - ss->timeout_ovf = ss->time > 0 && ss->calc_timeout < ss->time; - /* - * N.B. Realistic overflow can only occur in our lifetimes on a - * 32-bit machine with signed time_t, in January 2038. - * However, There are no controls to limit the |timeout| - * value, except to keep it positive. - */ + ss->calc_timeout = ossl_time_add(ss->time, ss->timeout); } /* @@ -90,13 +61,19 @@ void ssl_session_calculate_timeout(SSL_SESSION *ss) SSL_SESSION *SSL_get_session(const SSL *ssl) /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ { - return ssl->session; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL) + return NULL; + + return sc->session; } SSL_SESSION *SSL_get1_session(SSL *ssl) /* variant of SSL_get_session: caller really gets something */ { SSL_SESSION *sess; + /* * Need to lock this all up rather than just use CRYPTO_add so that * somebody doesn't free ssl->session between when we check it's non-null @@ -104,8 +81,8 @@ SSL_SESSION *SSL_get1_session(SSL *ssl) */ if (!CRYPTO_THREAD_read_lock(ssl->lock)) return NULL; - sess = ssl->session; - if (sess) + sess = SSL_get_session(ssl); + if (sess != NULL) SSL_SESSION_up_ref(sess); CRYPTO_THREAD_unlock(ssl->lock); return sess; @@ -129,25 +106,21 @@ SSL_SESSION *SSL_SESSION_new(void) return NULL; ss = OPENSSL_zalloc(sizeof(*ss)); - if (ss == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ss == NULL) return NULL; - } ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ - ss->references = 1; - ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ - ss->time = time(NULL); + /* 5 minute timeout by default */ + ss->timeout = ossl_seconds2time(60 * 5 + 4); + ss->time = ossl_time_now(); ssl_session_calculate_timeout(ss); - ss->lock = CRYPTO_THREAD_lock_new(); - if (ss->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (!CRYPTO_NEW_REF(&ss->references, 1)) { OPENSSL_free(ss); return NULL; } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data)) { - CRYPTO_THREAD_lock_free(ss->lock); + CRYPTO_FREE_REF(&ss->references); OPENSSL_free(ss); return NULL; } @@ -168,9 +141,8 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) SSL_SESSION *dest; dest = OPENSSL_malloc(sizeof(*dest)); - if (dest == NULL) { - goto err; - } + if (dest == NULL) + return NULL; memcpy(dest, src, sizeof(*dest)); /* @@ -189,6 +161,7 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) #endif dest->peer_chain = NULL; dest->peer = NULL; + dest->peer_rpk = NULL; dest->ticket_appdata = NULL; memset(&dest->ex_data, 0, sizeof(dest->ex_data)); @@ -197,54 +170,61 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) dest->next = NULL; dest->owner = NULL; - dest->references = 1; - - dest->lock = CRYPTO_THREAD_lock_new(); - if (dest->lock == NULL) { + if (!CRYPTO_NEW_REF(&dest->references, 1)) { OPENSSL_free(dest); - dest = NULL; - goto err; + return NULL; } - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; + } if (src->peer != NULL) { - if (!X509_up_ref(src->peer)) + if (!X509_up_ref(src->peer)) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; + } dest->peer = src->peer; } if (src->peer_chain != NULL) { dest->peer_chain = X509_chain_up_ref(src->peer_chain); - if (dest->peer_chain == NULL) + if (dest->peer_chain == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); + goto err; + } + } + + if (src->peer_rpk != NULL) { + if (!EVP_PKEY_up_ref(src->peer_rpk)) goto err; + dest->peer_rpk = src->peer_rpk; } + #ifndef OPENSSL_NO_PSK if (src->psk_identity_hint) { dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint); - if (dest->psk_identity_hint == NULL) { + if (dest->psk_identity_hint == NULL) goto err; - } } if (src->psk_identity) { dest->psk_identity = OPENSSL_strdup(src->psk_identity); - if (dest->psk_identity == NULL) { + if (dest->psk_identity == NULL) goto err; - } } #endif if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, &dest->ex_data, &src->ex_data)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); goto err; } if (src->ext.hostname) { dest->ext.hostname = OPENSSL_strdup(src->ext.hostname); - if (dest->ext.hostname == NULL) { + if (dest->ext.hostname == NULL) goto err; - } } if (ticket != 0 && src->ext.tick != NULL) { @@ -267,9 +247,8 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) #ifndef OPENSSL_NO_SRP if (src->srp_username) { dest->srp_username = OPENSSL_strdup(src->srp_username); - if (dest->srp_username == NULL) { + if (dest->srp_username == NULL) goto err; - } } #endif @@ -282,7 +261,6 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) return dest; err: - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); SSL_SESSION_free(dest); return NULL; } @@ -322,10 +300,15 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int retry = 0; - do + do { if (RAND_bytes_ex(ssl->ctx->libctx, id, *id_len, 0) <= 0) return 0; - while (SSL_has_matching_session_id(ssl, id, *id_len) && +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (retry > 0) { + id[0]++; + } +#endif + } while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; if (retry < MAX_SESS_ID_ATTEMPTS) return 1; @@ -341,10 +324,11 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id, return 0; } -int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) +int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss) { unsigned int tmp; GEN_SESSION_CB cb = def_generate_session_id; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); switch (s->version) { case SSL3_VERSION: @@ -383,10 +367,10 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) } /* Choose which callback will set the session ID */ - if (!CRYPTO_THREAD_read_lock(s->lock)) + if (!CRYPTO_THREAD_read_lock(SSL_CONNECTION_GET_SSL(s)->lock)) return 0; if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) { - CRYPTO_THREAD_unlock(s->lock); + CRYPTO_THREAD_unlock(ssl->lock); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); return 0; @@ -396,11 +380,11 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) else if (s->session_ctx->generate_session_id) cb = s->session_ctx->generate_session_id; CRYPTO_THREAD_unlock(s->session_ctx->lock); - CRYPTO_THREAD_unlock(s->lock); + CRYPTO_THREAD_unlock(ssl->lock); /* Choose a session ID */ memset(ss->session_id, 0, ss->session_id_length); tmp = (int)ss->session_id_length; - if (!cb(s, ss->session_id, &tmp)) { + if (!cb(ssl, ss->session_id, &tmp)) { /* The callback failed */ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); @@ -418,7 +402,7 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) } ss->session_id_length = tmp; /* Finally, check for a conflict */ - if (SSL_has_matching_session_id(s, ss->session_id, + if (SSL_has_matching_session_id(ssl, ss->session_id, (unsigned int)ss->session_id_length)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CONFLICT); return 0; @@ -427,20 +411,20 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) return 1; } -int ssl_get_new_session(SSL *s, int session) +int ssl_get_new_session(SSL_CONNECTION *s, int session) { /* This gets used by clients and servers. */ SSL_SESSION *ss = NULL; if ((ss = SSL_SESSION_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); return 0; } /* If the context has a default timeout, use it */ - if (s->session_ctx->session_timeout == 0) - ss->timeout = SSL_get_default_timeout(s); + if (ossl_time_is_zero(s->session_ctx->session_timeout)) + ss->timeout = SSL_CONNECTION_GET_SSL(s)->method->get_timeout(); else ss->timeout = s->session_ctx->session_timeout; ssl_session_calculate_timeout(ss); @@ -449,7 +433,7 @@ int ssl_get_new_session(SSL *s, int session) s->session = NULL; if (session) { - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * We generate the session id while constructing the * NewSessionTicket in TLSv1.3. @@ -483,7 +467,8 @@ int ssl_get_new_session(SSL *s, int session) return 1; } -SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, +SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s, + const unsigned char *sess_id, size_t sess_id_len) { SSL_SESSION *ret = NULL; @@ -514,7 +499,8 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, if (ret == NULL && s->session_ctx->get_session_cb != NULL) { int copy = 1; - ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); + ret = s->session_ctx->get_session_cb(SSL_CONNECTION_GET_SSL(s), + sess_id, sess_id_len, ©); if (ret != NULL) { ssl_tsan_counter(s->session_ctx, @@ -566,7 +552,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, * - Both for new and resumed sessions, s->ext.ticket_expected is set to 1 * if the server should issue a new session ticket (to 0 otherwise). */ -int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) +int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) { /* This is used only by servers. */ @@ -575,7 +561,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) int try_session_cache = 0; SSL_TICKET_STATUS r; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * By default we will send a new ticket. This can be overridden in the * ticket processing. @@ -648,7 +634,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) goto err; } - if (sess_timedout(time(NULL), ret)) { + if (sess_timedout(ossl_time_now(), ret)) { ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_timeout); if (try_session_cache) { /* session was from the cache, so remove it */ @@ -670,7 +656,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) goto err; } - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { /* We already did this for TLS1.3 */ SSL_SESSION_free(s->session); s->session = ret; @@ -684,7 +670,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) if (ret != NULL) { SSL_SESSION_free(ret); /* In TLSv1.3 s->session was already set to ret, so we NULL it out */ - if (SSL_IS_TLS13(s)) + if (SSL_CONNECTION_IS_TLS13(s)) s->session = NULL; if (!try_session_cache) { @@ -751,7 +737,7 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) /* Adjust last used time, and add back into the cache at the appropriate spot */ if (ctx->session_cache_mode & SSL_SESS_CACHE_UPDATE_TIME) { - c->time = time(NULL); + c->time = ossl_time_now(); ssl_session_calculate_timeout(c); } @@ -828,7 +814,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) if (ss == NULL) return; - CRYPTO_DOWN_REF(&ss->references, &i, ss->lock); + CRYPTO_DOWN_REF(&ss->references, &i); REF_PRINT_COUNT("SSL_SESSION", ss); if (i > 0) return; @@ -839,7 +825,8 @@ void SSL_SESSION_free(SSL_SESSION *ss) OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key)); OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id)); X509_free(ss->peer); - sk_X509_pop_free(ss->peer_chain, X509_free); + EVP_PKEY_free(ss->peer_rpk); + OSSL_STACK_OF_X509_free(ss->peer_chain); OPENSSL_free(ss->ext.hostname); OPENSSL_free(ss->ext.tick); #ifndef OPENSSL_NO_PSK @@ -851,7 +838,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) #endif OPENSSL_free(ss->ext.alpn_selected); OPENSSL_free(ss->ticket_appdata); - CRYPTO_THREAD_lock_free(ss->lock); + CRYPTO_FREE_REF(&ss->references); OPENSSL_clear_free(ss, sizeof(*ss)); } @@ -859,7 +846,7 @@ int SSL_SESSION_up_ref(SSL_SESSION *ss) { int i; - if (CRYPTO_UP_REF(&ss->references, &i, ss->lock) <= 0) + if (CRYPTO_UP_REF(&ss->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL_SESSION", ss); @@ -869,18 +856,23 @@ int SSL_SESSION_up_ref(SSL_SESSION *ss) int SSL_set_session(SSL *s, SSL_SESSION *session) { - ssl_clear_bad_session(s); - if (s->ctx->method != s->method) { - if (!SSL_set_ssl_method(s, s->ctx->method)) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + ssl_clear_bad_session(sc); + if (s->defltmeth != s->method) { + if (!SSL_set_ssl_method(s, s->defltmeth)) return 0; } if (session != NULL) { SSL_SESSION_up_ref(session); - s->verify_result = session->verify_result; + sc->verify_result = session->verify_result; } - SSL_SESSION_free(s->session); - s->session = session; + SSL_SESSION_free(sc->session); + sc->session = session; return 1; } @@ -900,7 +892,7 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) { - time_t new_timeout = (time_t)t; + OSSL_TIME new_timeout = ossl_seconds2time(t); if (s == NULL || t < 0) return 0; @@ -922,19 +914,19 @@ long SSL_SESSION_get_timeout(const SSL_SESSION *s) { if (s == NULL) return 0; - return (long)s->timeout; + return (long)ossl_time_to_time_t(s->timeout); } long SSL_SESSION_get_time(const SSL_SESSION *s) { if (s == NULL) return 0; - return (long)s->time; + return (long)ossl_time_to_time_t(s->time); } long SSL_SESSION_set_time(SSL_SESSION *s, long t) { - time_t new_time = (time_t)t; + OSSL_TIME new_time = ossl_time_from_time_t((time_t)t); if (s == NULL) return 0; @@ -1053,6 +1045,11 @@ X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) return s->peer; } +EVP_PKEY *SSL_SESSION_get0_peer_rpk(SSL_SESSION *s) +{ + return s->peer_rpk; +} + int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len) { @@ -1080,10 +1077,11 @@ int SSL_SESSION_is_resumable(const SSL_SESSION *s) long SSL_CTX_set_timeout(SSL_CTX *s, long t) { long l; + if (s == NULL) return 0; - l = s->session_timeout; - s->session_timeout = t; + l = (long)ossl_time2seconds(s->session_timeout); + s->session_timeout = ossl_seconds2time(t); return l; } @@ -1091,49 +1089,58 @@ long SSL_CTX_get_timeout(const SSL_CTX *s) { if (s == NULL) return 0; - return s->session_timeout; + return (long)ossl_time2seconds(s->session_timeout); } int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg) { - if (s == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) return 0; - s->ext.session_secret_cb = tls_session_secret_cb; - s->ext.session_secret_cb_arg = arg; + + sc->ext.session_secret_cb = tls_session_secret_cb; + sc->ext.session_secret_cb_arg = arg; return 1; } int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, void *arg) { - if (s == NULL) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) return 0; - s->ext.session_ticket_cb = cb; - s->ext.session_ticket_cb_arg = arg; + + sc->ext.session_ticket_cb = cb; + sc->ext.session_ticket_cb_arg = arg; return 1; } int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) { - if (s->version >= TLS1_VERSION) { - OPENSSL_free(s->ext.session_ticket); - s->ext.session_ticket = NULL; - s->ext.session_ticket = + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->version >= TLS1_VERSION) { + OPENSSL_free(sc->ext.session_ticket); + sc->ext.session_ticket = NULL; + sc->ext.session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); - if (s->ext.session_ticket == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (sc->ext.session_ticket == NULL) return 0; - } if (ext_data != NULL) { - s->ext.session_ticket->length = ext_len; - s->ext.session_ticket->data = s->ext.session_ticket + 1; - memcpy(s->ext.session_ticket->data, ext_data, ext_len); + sc->ext.session_ticket->length = ext_len; + sc->ext.session_ticket->data = sc->ext.session_ticket + 1; + memcpy(sc->ext.session_ticket->data, ext_data, ext_len); } else { - s->ext.session_ticket->length = 0; - s->ext.session_ticket->data = NULL; + sc->ext.session_ticket->length = 0; + sc->ext.session_ticket->data = NULL; } return 1; @@ -1147,6 +1154,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) STACK_OF(SSL_SESSION) *sk; SSL_SESSION *current; unsigned long i; + const OSSL_TIME timeout = ossl_time_from_time_t(t); if (!CRYPTO_THREAD_write_lock(s->lock)) return; @@ -1164,7 +1172,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) */ while (s->session_cache_tail != NULL) { current = s->session_cache_tail; - if (t == 0 || sess_timedout((time_t)t, current)) { + if (t == 0 || sess_timedout(timeout, current)) { lh_SSL_SESSION_delete(s->sessions, current); SSL_SESSION_list_remove(s, current); current->not_resumable = 1; @@ -1190,11 +1198,12 @@ void SSL_CTX_flush_sessions(SSL_CTX *s, long t) sk_SSL_SESSION_pop_free(sk, SSL_SESSION_free); } -int ssl_clear_bad_session(SSL *s) +int ssl_clear_bad_session(SSL_CONNECTION *s) { if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && - !(SSL_in_init(s) || SSL_in_before(s))) { + !(SSL_in_init(SSL_CONNECTION_GET_SSL(s)) + || SSL_in_before(SSL_CONNECTION_GET_SSL(s)))) { SSL_CTX_remove_session(s->session_ctx, s->session); return 1; } else @@ -1303,7 +1312,7 @@ void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, } void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, - SSL_SESSION *(*cb) (struct ssl_st *ssl, + SSL_SESSION *(*cb) (SSL *ssl, const unsigned char *data, int len, int *copy)) { diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index f2316f7c98..8b93ccd4ac 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -13,7 +13,9 @@ const char *SSL_state_string_long(const SSL *s) { - if (ossl_statem_in_error(s)) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL || ossl_statem_in_error(sc)) return "error"; switch (SSL_get_state(s)) { @@ -35,6 +37,8 @@ const char *SSL_state_string_long(const SSL *s) return "SSLv3/TLS read server hello"; case TLS_ST_CR_CERT: return "SSLv3/TLS read server certificate"; + case TLS_ST_CR_COMP_CERT: + return "TLSv1.3 read server compressed certificate"; case TLS_ST_CR_KEY_EXCH: return "SSLv3/TLS read server key exchange"; case TLS_ST_CR_CERT_REQ: @@ -45,6 +49,8 @@ const char *SSL_state_string_long(const SSL *s) return "SSLv3/TLS read server done"; case TLS_ST_CW_CERT: return "SSLv3/TLS write client certificate"; + case TLS_ST_CW_COMP_CERT: + return "TLSv1.3 write client compressed certificate"; case TLS_ST_CW_KEY_EXCH: return "SSLv3/TLS write client key exchange"; case TLS_ST_CW_CERT_VRFY: @@ -69,6 +75,8 @@ const char *SSL_state_string_long(const SSL *s) return "SSLv3/TLS write server hello"; case TLS_ST_SW_CERT: return "SSLv3/TLS write certificate"; + case TLS_ST_SW_COMP_CERT: + return "TLSv1.3 write server compressed certificate"; case TLS_ST_SW_KEY_EXCH: return "SSLv3/TLS write key exchange"; case TLS_ST_SW_CERT_REQ: @@ -79,6 +87,8 @@ const char *SSL_state_string_long(const SSL *s) return "SSLv3/TLS write server done"; case TLS_ST_SR_CERT: return "SSLv3/TLS read client certificate"; + case TLS_ST_SR_COMP_CERT: + return "TLSv1.3 read client compressed certificate"; case TLS_ST_SR_KEY_EXCH: return "SSLv3/TLS read client key exchange"; case TLS_ST_SR_CERT_VRFY: @@ -120,7 +130,9 @@ const char *SSL_state_string_long(const SSL *s) const char *SSL_state_string(const SSL *s) { - if (ossl_statem_in_error(s)) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL || ossl_statem_in_error(sc)) return "SSLERR"; switch (SSL_get_state(s)) { @@ -146,6 +158,8 @@ const char *SSL_state_string(const SSL *s) return "TRSH"; case TLS_ST_CR_CERT: return "TRSC"; + case TLS_ST_CR_COMP_CERT: + return "TRSCC"; case TLS_ST_CR_KEY_EXCH: return "TRSKE"; case TLS_ST_CR_CERT_REQ: @@ -154,6 +168,8 @@ const char *SSL_state_string(const SSL *s) return "TRSD"; case TLS_ST_CW_CERT: return "TWCC"; + case TLS_ST_CW_COMP_CERT: + return "TWCCC"; case TLS_ST_CW_KEY_EXCH: return "TWCKE"; case TLS_ST_CW_CERT_VRFY: @@ -178,6 +194,8 @@ const char *SSL_state_string(const SSL *s) return "TWSH"; case TLS_ST_SW_CERT: return "TWSC"; + case TLS_ST_SW_COMP_CERT: + return "TWSCC"; case TLS_ST_SW_KEY_EXCH: return "TWSKE"; case TLS_ST_SW_CERT_REQ: @@ -186,6 +204,8 @@ const char *SSL_state_string(const SSL *s) return "TWSD"; case TLS_ST_SR_CERT: return "TRCC"; + case TLS_ST_SR_COMP_CERT: + return "TRCCC"; case TLS_ST_SR_KEY_EXCH: return "TRCKE"; case TLS_ST_SR_CERT_VRFY: diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c index 2be08e37fa..9e9c2e10ec 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -128,12 +128,14 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) } } #endif - if (x->time != 0L) { - if (BIO_printf(bp, "\n Start Time: %lld", (long long)x->time) <= 0) + if (!ossl_time_is_zero(x->time)) { + if (BIO_printf(bp, "\n Start Time: %lld", + (long long)ossl_time_to_time_t(x->time)) <= 0) goto err; } - if (x->timeout != 0L) { - if (BIO_printf(bp, "\n Timeout : %lld (sec)", (long long)x->timeout) <= 0) + if (!ossl_time_is_zero(x->timeout)) { + if (BIO_printf(bp, "\n Timeout : %lld (sec)", + (long long)ossl_time2seconds(x->timeout)) <= 0) goto err; } if (BIO_puts(bp, "\n") <= 0) diff --git a/ssl/ssl_utst.c b/ssl/ssl_utst.c index 690db6d497..91be7398ca 100644 --- a/ssl/ssl_utst.c +++ b/ssl/ssl_utst.c @@ -13,7 +13,6 @@ static const struct openssl_ssl_test_functions ssl_test_functions = { ssl_init_wbio_buffer, - ssl3_setup_buffers, }; const struct openssl_ssl_test_functions *SSL_test_functions(void) diff --git a/ssl/sslerr.h b/ssl/sslerr.h index 5c5b760e38..f28230f087 100644 --- a/ssl/sslerr.h +++ b/ssl/sslerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index e182b5abac..0a64ca2246 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -18,46 +18,59 @@ #include "../ssl_local.h" #include "statem_local.h" -static int final_renegotiate(SSL *s, unsigned int context, int sent); -static int init_server_name(SSL *s, unsigned int context); -static int final_server_name(SSL *s, unsigned int context, int sent); -static int final_ec_pt_formats(SSL *s, unsigned int context, int sent); -static int init_session_ticket(SSL *s, unsigned int context); +static int final_renegotiate(SSL_CONNECTION *s, unsigned int context, int sent); +static int init_server_name(SSL_CONNECTION *s, unsigned int context); +static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent); +static int final_ec_pt_formats(SSL_CONNECTION *s, unsigned int context, + int sent); +static int init_session_ticket(SSL_CONNECTION *s, unsigned int context); #ifndef OPENSSL_NO_OCSP -static int init_status_request(SSL *s, unsigned int context); +static int init_status_request(SSL_CONNECTION *s, unsigned int context); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -static int init_npn(SSL *s, unsigned int context); +static int init_npn(SSL_CONNECTION *s, unsigned int context); #endif -static int init_alpn(SSL *s, unsigned int context); -static int final_alpn(SSL *s, unsigned int context, int sent); -static int init_sig_algs_cert(SSL *s, unsigned int context); -static int init_sig_algs(SSL *s, unsigned int context); -static int init_certificate_authorities(SSL *s, unsigned int context); -static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, +static int init_alpn(SSL_CONNECTION *s, unsigned int context); +static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent); +static int init_sig_algs_cert(SSL_CONNECTION *s, unsigned int context); +static int init_sig_algs(SSL_CONNECTION *s, unsigned int context); +static int init_server_cert_type(SSL_CONNECTION *sc, unsigned int context); +static int init_client_cert_type(SSL_CONNECTION *sc, unsigned int context); +static int init_certificate_authorities(SSL_CONNECTION *s, + unsigned int context); +static EXT_RETURN tls_construct_certificate_authorities(SSL_CONNECTION *s, + WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, +static int tls_parse_certificate_authorities(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRP -static int init_srp(SSL *s, unsigned int context); +static int init_srp(SSL_CONNECTION *s, unsigned int context); #endif -static int init_ec_point_formats(SSL *s, unsigned int context); -static int init_etm(SSL *s, unsigned int context); -static int init_ems(SSL *s, unsigned int context); -static int final_ems(SSL *s, unsigned int context, int sent); -static int init_psk_kex_modes(SSL *s, unsigned int context); -static int final_key_share(SSL *s, unsigned int context, int sent); +static int init_ec_point_formats(SSL_CONNECTION *s, unsigned int context); +static int init_etm(SSL_CONNECTION *s, unsigned int context); +static int init_ems(SSL_CONNECTION *s, unsigned int context); +static int final_ems(SSL_CONNECTION *s, unsigned int context, int sent); +static int init_psk_kex_modes(SSL_CONNECTION *s, unsigned int context); +static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent); #ifndef OPENSSL_NO_SRTP -static int init_srtp(SSL *s, unsigned int context); +static int init_srtp(SSL_CONNECTION *s, unsigned int context); #endif -static int final_sig_algs(SSL *s, unsigned int context, int sent); -static int final_early_data(SSL *s, unsigned int context, int sent); -static int final_maxfragmentlen(SSL *s, unsigned int context, int sent); -static int init_post_handshake_auth(SSL *s, unsigned int context); -static int final_psk(SSL *s, unsigned int context, int sent); +static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent); +static int final_early_data(SSL_CONNECTION *s, unsigned int context, int sent); +static int final_maxfragmentlen(SSL_CONNECTION *s, unsigned int context, + int sent); +static int init_post_handshake_auth(SSL_CONNECTION *s, unsigned int context); +static int final_psk(SSL_CONNECTION *s, unsigned int context, int sent); +static int tls_init_compress_certificate(SSL_CONNECTION *sc, unsigned int context); +static EXT_RETURN tls_construct_compress_certificate(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +static int tls_parse_compress_certificate(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); /* Structure to define a built-in extension */ typedef struct extensions_definition_st { @@ -72,25 +85,27 @@ typedef struct extensions_definition_st { * Initialise extension before parsing. Always called for relevant contexts * even if extension not present */ - int (*init)(SSL *s, unsigned int context); + int (*init)(SSL_CONNECTION *s, unsigned int context); /* Parse extension sent from client to server */ - int (*parse_ctos)(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); + int (*parse_ctos)(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); /* Parse extension send from server to client */ - int (*parse_stoc)(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); + int (*parse_stoc)(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); /* Construct extension sent from server to client */ - EXT_RETURN (*construct_stoc)(SSL *s, WPACKET *pkt, unsigned int context, + EXT_RETURN (*construct_stoc)(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); /* Construct extension sent from client to server */ - EXT_RETURN (*construct_ctos)(SSL *s, WPACKET *pkt, unsigned int context, + EXT_RETURN (*construct_ctos)(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); /* * Finalise extension after parsing. Always called where an extensions was * initialised even if the extension was not present. |sent| is set to 1 if * the extension was seen, or 0 otherwise. */ - int (*final)(SSL *s, unsigned int context, int sent); + int (*final)(SSL_CONNECTION *s, unsigned int context, int sent); } EXTENSION_DEFINITION; /* @@ -296,6 +311,24 @@ static const EXTENSION_DEFINITION ext_defs[] = { NULL, tls_construct_ctos_post_handshake_auth, NULL, }, + { + TLSEXT_TYPE_client_cert_type, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS + | SSL_EXT_TLS1_2_SERVER_HELLO, + init_client_cert_type, + tls_parse_ctos_client_cert_type, tls_parse_stoc_client_cert_type, + tls_construct_stoc_client_cert_type, tls_construct_ctos_client_cert_type, + NULL + }, + { + TLSEXT_TYPE_server_cert_type, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS + | SSL_EXT_TLS1_2_SERVER_HELLO, + init_server_cert_type, + tls_parse_ctos_server_cert_type, tls_parse_stoc_server_cert_type, + tls_construct_stoc_server_cert_type, tls_construct_ctos_server_cert_type, + NULL + }, { TLSEXT_TYPE_signature_algorithms, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST, @@ -352,6 +385,15 @@ static const EXTENSION_DEFINITION ext_defs[] = { | SSL_EXT_TLS1_2_AND_BELOW_ONLY, NULL, NULL, NULL, tls_construct_stoc_cryptopro_bug, NULL, NULL }, + { + TLSEXT_TYPE_compress_certificate, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST + | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + tls_init_compress_certificate, + tls_parse_compress_certificate, tls_parse_compress_certificate, + tls_construct_compress_certificate, tls_construct_compress_certificate, + NULL + }, { TLSEXT_TYPE_early_data, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS @@ -399,13 +441,14 @@ unsigned int ossl_get_extension_type(size_t idx) } /* Check whether an extension's context matches the current context */ -static int validate_context(SSL *s, unsigned int extctx, unsigned int thisctx) +static int validate_context(SSL_CONNECTION *s, unsigned int extctx, + unsigned int thisctx) { /* Check we're allowed to use this extension in this context */ if ((thisctx & extctx) == 0) return 0; - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if ((extctx & SSL_EXT_TLS_ONLY) != 0) return 0; } else if ((extctx & SSL_EXT_DTLS_ONLY) != 0) { @@ -415,7 +458,8 @@ static int validate_context(SSL *s, unsigned int extctx, unsigned int thisctx) return 1; } -int tls_validate_all_contexts(SSL *s, unsigned int thisctx, RAW_EXTENSION *exts) +int tls_validate_all_contexts(SSL_CONNECTION *s, unsigned int thisctx, + RAW_EXTENSION *exts) { size_t i, num_exts, builtin_num = OSSL_NELEM(ext_defs), offset; RAW_EXTENSION *thisext; @@ -459,9 +503,9 @@ int tls_validate_all_contexts(SSL *s, unsigned int thisctx, RAW_EXTENSION *exts) * indicate the extension is not allowed. If returning 1 then |*found| is set to * the definition for the extension we found. */ -static int verify_extension(SSL *s, unsigned int context, unsigned int type, - custom_ext_methods *meths, RAW_EXTENSION *rawexlist, - RAW_EXTENSION **found) +static int verify_extension(SSL_CONNECTION *s, unsigned int context, + unsigned int type, custom_ext_methods *meths, + RAW_EXTENSION *rawexlist, RAW_EXTENSION **found) { size_t i; size_t builtin_num = OSSL_NELEM(ext_defs); @@ -507,7 +551,8 @@ static int verify_extension(SSL *s, unsigned int context, unsigned int type, * the extension is relevant for the current context |thisctx| or not. Returns * 1 if the extension is relevant for this context, and 0 otherwise */ -int extension_is_relevant(SSL *s, unsigned int extctx, unsigned int thisctx) +int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, + unsigned int thisctx) { int is_tls13; @@ -518,9 +563,9 @@ int extension_is_relevant(SSL *s, unsigned int extctx, unsigned int thisctx) if ((thisctx & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) is_tls13 = 1; else - is_tls13 = SSL_IS_TLS13(s); + is_tls13 = SSL_CONNECTION_IS_TLS13(s); - if ((SSL_IS_DTLS(s) + if ((SSL_CONNECTION_IS_DTLS(s) && (extctx & SSL_EXT_TLS_IMPLEMENTATION_ONLY) != 0) || (s->version == SSL3_VERSION && (extctx & SSL_EXT_SSL3_ALLOWED) == 0) @@ -557,7 +602,8 @@ int extension_is_relevant(SSL *s, unsigned int extctx, unsigned int thisctx) * found, or an internal error occurred. We only check duplicates for * extensions that we know about. We ignore others. */ -int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, +int tls_collect_extensions(SSL_CONNECTION *s, PACKET *packet, + unsigned int context, RAW_EXTENSION **res, size_t *len, int init) { PACKET extensions = *packet; @@ -579,7 +625,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, num_exts = OSSL_NELEM(ext_defs) + (exts != NULL ? exts->meths_count : 0); raw_extensions = OPENSSL_zalloc(num_exts * sizeof(*raw_extensions)); if (raw_extensions == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } @@ -645,8 +691,8 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, thisex->type = type; thisex->received_order = i++; if (s->ext.debug_cb) - s->ext.debug_cb(s, !s->server, thisex->type, - PACKET_data(&thisex->data), + s->ext.debug_cb(SSL_CONNECTION_GET_SSL(s), !s->server, + thisex->type, PACKET_data(&thisex->data), PACKET_remaining(&thisex->data), s->ext.debug_arg); } @@ -688,11 +734,11 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, * Certificate. Returns 1 on success or 0 on failure. If an extension is not * present this counted as success. */ -int tls_parse_extension(SSL *s, TLSEXT_INDEX idx, int context, +int tls_parse_extension(SSL_CONNECTION *s, TLSEXT_INDEX idx, int context, RAW_EXTENSION *exts, X509 *x, size_t chainidx) { RAW_EXTENSION *currext = &exts[idx]; - int (*parser)(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + int (*parser)(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) = NULL; /* Skip if the extension is not present */ @@ -738,7 +784,8 @@ int tls_parse_extension(SSL *s, TLSEXT_INDEX idx, int context, * working on a Certificate message then we also pass the Certificate |x| and * its position in the |chainidx|, with 0 being the first certificate. */ -int tls_parse_all_extensions(SSL *s, int context, RAW_EXTENSION *exts, X509 *x, +int tls_parse_all_extensions(SSL_CONNECTION *s, int context, + RAW_EXTENSION *exts, X509 *x, size_t chainidx, int fin) { size_t i, numexts = OSSL_NELEM(ext_defs); @@ -773,8 +820,8 @@ int tls_parse_all_extensions(SSL *s, int context, RAW_EXTENSION *exts, X509 *x, return 1; } -int should_add_extension(SSL *s, unsigned int extctx, unsigned int thisctx, - int max_version) +int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, + unsigned int thisctx, int max_version) { /* Skip if not relevant for our context */ if ((extctx & thisctx) == 0) @@ -784,7 +831,7 @@ int should_add_extension(SSL *s, unsigned int extctx, unsigned int thisctx, if (!extension_is_relevant(s, extctx, thisctx) || ((extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) != 0 - && (SSL_IS_DTLS(s) || max_version < TLS1_3_VERSION))) + && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION))) return 0; return 1; @@ -798,12 +845,14 @@ int should_add_extension(SSL *s, unsigned int extctx, unsigned int thisctx, * 0 being the first in the chain). Returns 1 on success or 0 on failure. On a * failure construction stops at the first extension to fail to construct. */ -int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, +int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { size_t i; int min_version, max_version = 0, reason; const EXTENSION_DEFINITION *thisexd; + int for_comp = (context & SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION) != 0; if (!WPACKET_start_sub_packet_u16(pkt) /* @@ -814,15 +863,17 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, || ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0 && !WPACKET_set_flags(pkt, - WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))) { + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if ((context & SSL_EXT_CLIENT_HELLO) != 0) { reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); return 0; } } @@ -838,7 +889,8 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, } for (i = 0, thisexd = ext_defs; i < OSSL_NELEM(ext_defs); i++, thisexd++) { - EXT_RETURN (*construct)(SSL *s, WPACKET *pkt, unsigned int context, + EXT_RETURN (*construct)(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); EXT_RETURN ret; @@ -865,7 +917,8 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -879,7 +932,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, * otherwise. These functions return 1 on success or 0 on failure. */ -static int final_renegotiate(SSL *s, unsigned int context, int sent) +static int final_renegotiate(SSL_CONNECTION *s, unsigned int context, int sent) { if (!s->server) { /* @@ -919,7 +972,7 @@ static ossl_inline void ssl_tsan_decr(const SSL_CTX *ctx, } } -static int init_server_name(SSL *s, unsigned int context) +static int init_server_name(SSL_CONNECTION *s, unsigned int context) { if (s->server) { s->servername_done = 0; @@ -931,22 +984,24 @@ static int init_server_name(SSL *s, unsigned int context) return 1; } -static int final_server_name(SSL *s, unsigned int context, int sent) +static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent) { int ret = SSL_TLSEXT_ERR_NOACK; int altmp = SSL_AD_UNRECOGNIZED_NAME; - int was_ticket = (SSL_get_options(s) & SSL_OP_NO_TICKET) == 0; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + int was_ticket = (SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0; - if (!ossl_assert(s->ctx != NULL) || !ossl_assert(s->session_ctx != NULL)) { + if (!ossl_assert(sctx != NULL) || !ossl_assert(s->session_ctx != NULL)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (s->ctx->ext.servername_cb != NULL) - ret = s->ctx->ext.servername_cb(s, &altmp, - s->ctx->ext.servername_arg); + if (sctx->ext.servername_cb != NULL) + ret = sctx->ext.servername_cb(ssl, &altmp, + sctx->ext.servername_arg); else if (s->session_ctx->ext.servername_cb != NULL) - ret = s->session_ctx->ext.servername_cb(s, &altmp, + ret = s->session_ctx->ext.servername_cb(ssl, &altmp, s->session_ctx->ext.servername_arg); /* @@ -974,9 +1029,9 @@ static int final_server_name(SSL *s, unsigned int context, int sent) * context, to avoid the confusing situation of having sess_accept_good * exceed sess_accept (zero) for the new context. */ - if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx + if (SSL_IS_FIRST_HANDSHAKE(s) && sctx != s->session_ctx && s->hello_retry_request == SSL_HRR_NONE) { - ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept); + ssl_tsan_counter(sctx, &sctx->stats.sess_accept); ssl_tsan_decr(s->session_ctx, &s->session_ctx->stats.sess_accept); } @@ -986,10 +1041,10 @@ static int final_server_name(SSL *s, unsigned int context, int sent) * Also, if this is not a resumption, create a new session ID */ if (ret == SSL_TLSEXT_ERR_OK && s->ext.ticket_expected - && was_ticket && (SSL_get_options(s) & SSL_OP_NO_TICKET) != 0) { + && was_ticket && (SSL_get_options(ssl) & SSL_OP_NO_TICKET) != 0) { s->ext.ticket_expected = 0; if (!s->hit) { - SSL_SESSION* ss = SSL_get_session(s); + SSL_SESSION* ss = SSL_get_session(ssl); if (ss != NULL) { OPENSSL_free(ss->ext.tick); @@ -1015,7 +1070,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent) case SSL_TLSEXT_ERR_ALERT_WARNING: /* TLSv1.3 doesn't have warning alerts so we suppress this */ - if (!SSL_IS_TLS13(s)) + if (!SSL_CONNECTION_IS_TLS13(s)) ssl3_send_alert(s, SSL3_AL_WARNING, altmp); s->servername_done = 0; return 1; @@ -1029,7 +1084,8 @@ static int final_server_name(SSL *s, unsigned int context, int sent) } } -static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) +static int final_ec_pt_formats(SSL_CONNECTION *s, unsigned int context, + int sent) { unsigned long alg_k, alg_a; @@ -1067,7 +1123,7 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) return 1; } -static int init_session_ticket(SSL *s, unsigned int context) +static int init_session_ticket(SSL_CONNECTION *s, unsigned int context) { if (!s->server) s->ext.ticket_expected = 0; @@ -1076,7 +1132,7 @@ static int init_session_ticket(SSL *s, unsigned int context) } #ifndef OPENSSL_NO_OCSP -static int init_status_request(SSL *s, unsigned int context) +static int init_status_request(SSL_CONNECTION *s, unsigned int context) { if (s->server) { s->ext.status_type = TLSEXT_STATUSTYPE_nothing; @@ -1095,7 +1151,7 @@ static int init_status_request(SSL *s, unsigned int context) #endif #ifndef OPENSSL_NO_NEXTPROTONEG -static int init_npn(SSL *s, unsigned int context) +static int init_npn(SSL_CONNECTION *s, unsigned int context) { s->s3.npn_seen = 0; @@ -1103,7 +1159,7 @@ static int init_npn(SSL *s, unsigned int context) } #endif -static int init_alpn(SSL *s, unsigned int context) +static int init_alpn(SSL_CONNECTION *s, unsigned int context) { OPENSSL_free(s->s3.alpn_selected); s->s3.alpn_selected = NULL; @@ -1116,12 +1172,12 @@ static int init_alpn(SSL *s, unsigned int context) return 1; } -static int final_alpn(SSL *s, unsigned int context, int sent) +static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent) { if (!s->server && !sent && s->session->ext.alpn_selected != NULL) s->ext.early_data_ok = 0; - if (!s->server || !SSL_IS_TLS13(s)) + if (!s->server || !SSL_CONNECTION_IS_TLS13(s)) return 1; /* @@ -1136,7 +1192,7 @@ static int final_alpn(SSL *s, unsigned int context, int sent) return tls_handle_alpn(s); } -static int init_sig_algs(SSL *s, unsigned int context) +static int init_sig_algs(SSL_CONNECTION *s, unsigned int context) { /* Clear any signature algorithms extension received */ OPENSSL_free(s->s3.tmp.peer_sigalgs); @@ -1146,7 +1202,8 @@ static int init_sig_algs(SSL *s, unsigned int context) return 1; } -static int init_sig_algs_cert(SSL *s, ossl_unused unsigned int context) +static int init_sig_algs_cert(SSL_CONNECTION *s, + ossl_unused unsigned int context) { /* Clear any signature algorithms extension received */ OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); @@ -1157,7 +1214,7 @@ static int init_sig_algs_cert(SSL *s, ossl_unused unsigned int context) } #ifndef OPENSSL_NO_SRP -static int init_srp(SSL *s, unsigned int context) +static int init_srp(SSL_CONNECTION *s, unsigned int context) { OPENSSL_free(s->srp_ctx.login); s->srp_ctx.login = NULL; @@ -1166,7 +1223,7 @@ static int init_srp(SSL *s, unsigned int context) } #endif -static int init_ec_point_formats(SSL *s, unsigned int context) +static int init_ec_point_formats(SSL_CONNECTION *s, unsigned int context) { OPENSSL_free(s->ext.peer_ecpointformats); s->ext.peer_ecpointformats = NULL; @@ -1175,14 +1232,14 @@ static int init_ec_point_formats(SSL *s, unsigned int context) return 1; } -static int init_etm(SSL *s, unsigned int context) +static int init_etm(SSL_CONNECTION *s, unsigned int context) { s->ext.use_etm = 0; return 1; } -static int init_ems(SSL *s, unsigned int context) +static int init_ems(SSL_CONNECTION *s, unsigned int context) { if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) { s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; @@ -1192,7 +1249,7 @@ static int init_ems(SSL *s, unsigned int context) return 1; } -static int final_ems(SSL *s, unsigned int context, int sent) +static int final_ems(SSL_CONNECTION *s, unsigned int context, int sent) { /* * Check extended master secret extension is not dropped on @@ -1218,14 +1275,15 @@ static int final_ems(SSL *s, unsigned int context, int sent) return 1; } -static int init_certificate_authorities(SSL *s, unsigned int context) +static int init_certificate_authorities(SSL_CONNECTION *s, unsigned int context) { sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); s->s3.tmp.peer_ca_names = NULL; return 1; } -static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, +static EXT_RETURN tls_construct_certificate_authorities(SSL_CONNECTION *s, + WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1254,7 +1312,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, +static int tls_parse_certificate_authorities(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1268,7 +1326,7 @@ static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, } #ifndef OPENSSL_NO_SRTP -static int init_srtp(SSL *s, unsigned int context) +static int init_srtp(SSL_CONNECTION *s, unsigned int context) { if (s->server) s->srtp_profile = NULL; @@ -1277,9 +1335,9 @@ static int init_srtp(SSL *s, unsigned int context) } #endif -static int final_sig_algs(SSL *s, unsigned int context, int sent) +static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) { - if (!sent && SSL_IS_TLS13(s) && !s->hit) { + if (!sent && SSL_CONNECTION_IS_TLS13(s) && !s->hit) { SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_SIGALGS_EXTENSION); return 0; @@ -1288,10 +1346,10 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent) return 1; } -static int final_key_share(SSL *s, unsigned int context, int sent) +static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) { #if !defined(OPENSSL_NO_TLS1_3) - if (!SSL_IS_TLS13(s)) + if (!SSL_CONNECTION_IS_TLS13(s)) return 1; /* Nothing to do for key_share in an HRR */ @@ -1452,13 +1510,14 @@ static int final_key_share(SSL *s, unsigned int context, int sent) return 1; } -static int init_psk_kex_modes(SSL *s, unsigned int context) +static int init_psk_kex_modes(SSL_CONNECTION *s, unsigned int context) { s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_NONE; return 1; } -int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, +int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, + const unsigned char *msgstart, size_t binderoffset, const unsigned char *binderin, unsigned char *binderout, SSL_SESSION *sess, int sign, int external) @@ -1477,6 +1536,7 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, int hashsizei = EVP_MD_get_size(md); int ret = -1; int usepskfored = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Ensure cast to size_t is safe */ if (!ossl_assert(hashsizei >= 0)) { @@ -1596,8 +1656,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, goto err; } - mackey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, finishedkey, + mackey = EVP_PKEY_new_raw_private_key_ex(sctx->libctx, "HMAC", + sctx->propq, finishedkey, hashsize); if (mackey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -1608,8 +1668,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, binderout = tmpbinder; bindersize = hashsize; - if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_get0_name(md), s->ctx->libctx, - s->ctx->propq, mackey, NULL) <= 0 + if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_get0_name(md), sctx->libctx, + sctx->propq, mackey, NULL) <= 0 || EVP_DigestSignUpdate(mctx, hash, hashsize) <= 0 || EVP_DigestSignFinal(mctx, binderout, &bindersize) <= 0 || bindersize != hashsize) { @@ -1635,7 +1695,7 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, return ret; } -static int final_early_data(SSL *s, unsigned int context, int sent) +static int final_early_data(SSL_CONNECTION *s, unsigned int context, int sent) { if (!sent) return 1; @@ -1662,7 +1722,7 @@ static int final_early_data(SSL *s, unsigned int context, int sent) || !s->ext.early_data_ok || s->hello_retry_request != SSL_HRR_NONE || (s->allow_early_data_cb != NULL - && !s->allow_early_data_cb(s, + && !s->allow_early_data_cb(SSL_CONNECTION_GET_SSL(s), s->allow_early_data_cb_data))) { s->ext.early_data = SSL_EARLY_DATA_REJECTED; } else { @@ -1678,7 +1738,8 @@ static int final_early_data(SSL *s, unsigned int context, int sent) return 1; } -static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) +static int final_maxfragmentlen(SSL_CONNECTION *s, unsigned int context, + int sent) { /* * Session resumption on server-side with MFL extension active @@ -1690,19 +1751,18 @@ static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) return 0; } - /* Current SSL buffer is lower than requested MFL */ - if (s->session && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) - && s->max_send_fragment < GET_MAX_FRAGMENT_LENGTH(s->session)) - /* trigger a larger buffer reallocation */ - if (!ssl3_setup_buffers(s)) { - /* SSLfatal() already called */ - return 0; - } + if (s->session && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) { + s->rlayer.rrlmethod->set_max_frag_len(s->rlayer.rrl, + GET_MAX_FRAGMENT_LENGTH(s->session)); + s->rlayer.wrlmethod->set_max_frag_len(s->rlayer.wrl, + ssl_get_max_send_fragment(s)); + } return 1; } -static int init_post_handshake_auth(SSL *s, ossl_unused unsigned int context) +static int init_post_handshake_auth(SSL_CONNECTION *s, + ossl_unused unsigned int context) { s->post_handshake_auth = SSL_PHA_NONE; @@ -1713,7 +1773,7 @@ static int init_post_handshake_auth(SSL *s, ossl_unused unsigned int context) * If clients offer "pre_shared_key" without a "psk_key_exchange_modes" * extension, servers MUST abort the handshake. */ -static int final_psk(SSL *s, unsigned int context, int sent) +static int final_psk(SSL_CONNECTION *s, unsigned int context, int sent) { if (s->server && sent && s->clienthello != NULL && !s->clienthello->pre_proc_exts[TLSEXT_IDX_psk_kex_modes].present) { @@ -1724,3 +1784,150 @@ static int final_psk(SSL *s, unsigned int context, int sent) return 1; } + +static int tls_init_compress_certificate(SSL_CONNECTION *sc, unsigned int context) +{ + memset(sc->ext.compress_certificate_from_peer, 0, + sizeof(sc->ext.compress_certificate_from_peer)); + return 1; +} + +/* The order these are put into the packet imply a preference order: [brotli, zlib, zstd] */ +static EXT_RETURN tls_construct_compress_certificate(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ +#ifndef OPENSSL_NO_COMP_ALG + int i; + + if (!ossl_comp_has_alg(0)) + return EXT_RETURN_NOT_SENT; + + /* Server: Don't attempt to compress a non-X509 (i.e. an RPK) */ + if (sc->server && sc->ext.server_cert_type != TLSEXT_cert_type_x509) { + sc->cert_comp_prefs[0] = TLSEXT_comp_cert_none; + return EXT_RETURN_NOT_SENT; + } + + /* Client: If we sent a client cert-type extension, don't indicate compression */ + if (!sc->server && sc->ext.client_cert_type_ctos) { + sc->cert_comp_prefs[0] = TLSEXT_comp_cert_none; + return EXT_RETURN_NOT_SENT; + } + + /* Do not indicate we support receiving compressed certificates */ + if ((sc->options & SSL_OP_NO_RX_CERTIFICATE_COMPRESSION) != 0) + return EXT_RETURN_NOT_SENT; + + if (sc->cert_comp_prefs[0] == TLSEXT_comp_cert_none) + return EXT_RETURN_NOT_SENT; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_compress_certificate) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_start_sub_packet_u8(pkt)) + goto err; + + for (i = 0; sc->cert_comp_prefs[i] != TLSEXT_comp_cert_none; i++) { + if (!WPACKET_put_bytes_u16(pkt, sc->cert_comp_prefs[i])) + goto err; + } + if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) + goto err; + + sc->ext.compress_certificate_sent = 1; + return EXT_RETURN_SENT; + err: + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; +#else + return EXT_RETURN_NOT_SENT; +#endif +} + +#ifndef OPENSSL_NO_COMP_ALG +static int tls_comp_in_pref(SSL_CONNECTION *sc, int alg) +{ + int i; + + /* ossl_comp_has_alg() considers 0 as "any" */ + if (alg == 0) + return 0; + /* Make sure algorithm is enabled */ + if (!ossl_comp_has_alg(alg)) + return 0; + /* If no preferences are set, it's ok */ + if (sc->cert_comp_prefs[0] == TLSEXT_comp_cert_none) + return 1; + /* Find the algorithm */ + for (i = 0; i < TLSEXT_comp_cert_limit; i++) + if (sc->cert_comp_prefs[i] == alg) + return 1; + return 0; +} +#endif + +int tls_parse_compress_certificate(SSL_CONNECTION *sc, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) +{ +#ifndef OPENSSL_NO_COMP_ALG + PACKET supported_comp_algs; + unsigned int comp; + int already_set[TLSEXT_comp_cert_limit]; + int j = 0; + + /* If no algorithms are available, ignore the extension */ + if (!ossl_comp_has_alg(0)) + return 1; + + /* Don't attempt to compress a non-X509 (i.e. an RPK) */ + if (sc->server && sc->ext.server_cert_type != TLSEXT_cert_type_x509) + return 1; + if (!sc->server && sc->ext.client_cert_type != TLSEXT_cert_type_x509) + return 1; + + /* Ignore the extension and don't send compressed certificates */ + if ((sc->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) + return 1; + + if (!PACKET_as_length_prefixed_1(pkt, &supported_comp_algs) + || PACKET_remaining(&supported_comp_algs) == 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + + memset(already_set, 0, sizeof(already_set)); + /* + * The preference array has real values, so take a look at each + * value coming in, and make sure it's in our preference list + * The array is 0 (i.e. "none") terminated + * The preference list only contains supported algorithms + */ + while (PACKET_get_net_2(&supported_comp_algs, &comp)) { + if (tls_comp_in_pref(sc, comp) && !already_set[comp]) { + sc->ext.compress_certificate_from_peer[j++] = comp; + already_set[comp] = 1; + } + } +#endif + return 1; +} + +static int init_server_cert_type(SSL_CONNECTION *sc, unsigned int context) +{ + /* Only reset when parsing client hello */ + if (sc->server) { + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.server_cert_type = TLSEXT_cert_type_x509; + } + return 1; +} + +static int init_client_cert_type(SSL_CONNECTION *sc, unsigned int context) +{ + /* Only reset when parsing client hello */ + if (sc->server) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.client_cert_type = TLSEXT_cert_type_x509; + } + return 1; +} diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 842be0722b..381a6c9d7b 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,7 +12,7 @@ #include "internal/cryptlib.h" #include "statem_local.h" -EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_renegotiate(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -32,7 +32,7 @@ EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_server_name(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -58,7 +58,7 @@ EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, } /* Push a Max Fragment Len extension into ClientHello */ -EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -83,7 +83,8 @@ EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, } #ifndef OPENSSL_NO_SRP -EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_srp(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { /* Add SRP username if there is one */ @@ -108,19 +109,20 @@ EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, } #endif -static int use_ecc(SSL *s, int min_version, int max_version) +static int use_ecc(SSL_CONNECTION *s, int min_version, int max_version) { int i, end, ret = 0; unsigned long alg_k, alg_a; STACK_OF(SSL_CIPHER) *cipher_stack = NULL; const uint16_t *pgroups = NULL; size_t num_groups, j; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* See if we support any ECC ciphersuites */ if (s->version == SSL3_VERSION) return 0; - cipher_stack = SSL_get1_supported_ciphers(s); + cipher_stack = SSL_get1_supported_ciphers(ssl); end = sk_SSL_CIPHER_num(cipher_stack); for (i = 0; i < end; i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); @@ -151,7 +153,7 @@ static int use_ecc(SSL *s, int min_version, int max_version) return 0; } -EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -182,7 +184,7 @@ EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -201,7 +203,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, * if we don't have EC support then we don't send this extension. */ if (!use_ecc(s, min_version, max_version) - && (SSL_IS_DTLS(s) || max_version < TLS1_3_VERSION)) + && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION)) return EXT_RETURN_NOT_SENT; /* @@ -251,7 +253,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -292,7 +294,7 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_sig_algs(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -319,7 +321,7 @@ EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, } #ifndef OPENSSL_NO_OCSP -EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_status_request(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -384,10 +386,12 @@ EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, #endif #ifndef OPENSSL_NO_NEXTPROTONEG -EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_npn(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { - if (s->ctx->ext.npn_select_cb == NULL || !SSL_IS_FIRST_HANDSHAKE(s)) + if (SSL_CONNECTION_GET_CTX(s)->ext.npn_select_cb == NULL + || !SSL_IS_FIRST_HANDSHAKE(s)) return EXT_RETURN_NOT_SENT; /* @@ -404,7 +408,8 @@ EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, } #endif -EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_alpn(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { s->s3.alpn_sent = 0; @@ -428,11 +433,12 @@ EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, #ifndef OPENSSL_NO_SRTP -EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_use_srtp(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(ssl); int i, end; if (clnt == NULL) @@ -469,7 +475,8 @@ EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, } #endif -EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_etm(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) @@ -485,7 +492,8 @@ EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, } #ifndef OPENSSL_NO_CT -EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_sct(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (s->ct_validation_callback == NULL) @@ -505,7 +513,8 @@ EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, } #endif -EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_ems(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) @@ -520,7 +529,7 @@ EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -563,7 +572,7 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, /* * Construct a psk_kex_modes extension. */ -EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -590,7 +599,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, } #ifndef OPENSSL_NO_TLS1_3 -static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) +static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int curve_id) { unsigned char *encoded_point = NULL; EVP_PKEY *key_share_key = NULL; @@ -646,7 +655,7 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) } #endif -EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -675,7 +684,6 @@ EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, curve_id = s->s3.group_id; } else { for (i = 0; i < num_groups; i++) { - if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; @@ -708,7 +716,8 @@ EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, #endif } -EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_cookie(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { EXT_RETURN ret = EXT_RETURN_FAIL; @@ -736,7 +745,7 @@ EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, return ret; } -EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -748,12 +757,13 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, SSL_SESSION *psksess = NULL; SSL_SESSION *edsess = NULL; const EVP_MD *handmd = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->hello_retry_request == SSL_HRR_PENDING) handmd = ssl_handshake_md(s); if (s->psk_use_session_cb != NULL - && (!s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess) + && (!s->psk_use_session_cb(ssl, handmd, &id, &idlen, &psksess) || (psksess != NULL && psksess->ssl_version != TLS1_3_VERSION))) { SSL_SESSION_free(psksess); @@ -767,7 +777,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, size_t psklen = 0; memset(identity, 0, sizeof(identity)); - psklen = s->psk_client_callback(s, NULL, identity, sizeof(identity) - 1, + psklen = s->psk_client_callback(ssl, NULL, + identity, sizeof(identity) - 1, psk, sizeof(psk)); if (psklen > PSK_MAX_PSK_LEN) { @@ -788,7 +799,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, * We found a PSK using an old style callback. We don't know * the digest so we default to SHA256 as per the TLSv1.3 spec */ - cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); + cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); if (cipher == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; @@ -905,7 +916,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, */ #define PSK_PRE_BINDER_OVERHEAD (2 + 2 + 2 + 2 + 4 + 2 + 1) -EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -933,7 +944,8 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, if (s->session->ssl_version == TLS1_3_VERSION && s->session->ext.ticklen != 0 && s->session->cipher != NULL) { - const EVP_MD *md = ssl_md(s->ctx, s->session->cipher->algorithm2); + const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), + s->session->cipher->algorithm2); if (md != NULL) { /* @@ -974,7 +986,8 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, /* * Construct the pre_shared_key extension */ -EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 @@ -983,6 +996,8 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL; const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL; int dores = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + OSSL_TIME t; s->ext.tick_identity = 0; @@ -1009,7 +1024,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - mdres = ssl_md(s->ctx, s->session->cipher->algorithm2); + mdres = ssl_md(sctx, s->session->cipher->algorithm2); if (mdres == NULL) { /* * Don't recognize this cipher so we can't use the session. @@ -1034,7 +1049,8 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, * this in multiple places in the code, so portability shouldn't be an * issue. */ - agesec = (uint32_t)(time(NULL) - s->session->time); + t = ossl_time_subtract(ossl_time_now(), s->session->time); + agesec = (uint32_t)ossl_time2seconds(t); /* * We calculate the age in seconds but the server may work in ms. Due to * rounding errors we could overestimate the age by up to 1s. It is @@ -1081,7 +1097,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_NOT_SENT; if (s->psksession != NULL) { - mdpsk = ssl_md(s->ctx, s->psksession->cipher->algorithm2); + mdpsk = ssl_md(sctx, s->psksession->cipher->algorithm2); if (mdpsk == NULL) { /* * Don't recognize this cipher so we can't use the session. @@ -1171,7 +1187,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, #endif } -EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL_CONNECTION *s, WPACKET *pkt, ossl_unused unsigned int context, ossl_unused X509 *x, ossl_unused size_t chainidx) @@ -1200,7 +1216,8 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, /* * Parse the server's renegotiation binding and abort if it's not right */ -int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_renegotiate(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { size_t expected_len = s->s3.previous_client_finished_len @@ -1254,7 +1271,8 @@ int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, } /* Parse the server's max fragment len extension packet */ -int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_maxfragmentlen(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int value; @@ -1292,7 +1310,8 @@ int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_server_name(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (s->ext.hostname == NULL) { @@ -1320,7 +1339,8 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { size_t ecpointformats_len; @@ -1359,13 +1379,16 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_session_ticket(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + if (s->ext.session_ticket_cb != NULL && - !s->ext.session_ticket_cb(s, PACKET_data(pkt), - PACKET_remaining(pkt), - s->ext.session_ticket_cb_arg)) { + !s->ext.session_ticket_cb(ssl, PACKET_data(pkt), + PACKET_remaining(pkt), + s->ext.session_ticket_cb_arg)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; } @@ -1385,7 +1408,8 @@ int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, } #ifndef OPENSSL_NO_OCSP -int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST) { @@ -1401,12 +1425,12 @@ int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } - if (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { + if (!SSL_CONNECTION_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* We only know how to handle this if it's for the first Certificate in * the chain. We ignore any other responses. */ @@ -1426,8 +1450,8 @@ int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, #ifndef OPENSSL_NO_CT -int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_sct(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST) { /* We ignore this if the server sends it in a CertificateRequest */ @@ -1451,7 +1475,7 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->ext.scts = OPENSSL_malloc(size); if (s->ext.scts == NULL) { s->ext.scts_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } if (!PACKET_copy_bytes(pkt, s->ext.scts, size)) { @@ -1494,7 +1518,7 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * elements of zero length are allowed and the set of elements must exactly * fill the length of the block. Returns 1 on success or 0 on failure. */ -static int ssl_next_proto_validate(SSL *s, PACKET *pkt) +static int ssl_next_proto_validate(SSL_CONNECTION *s, PACKET *pkt) { PACKET tmp_protocol; @@ -1509,19 +1533,20 @@ static int ssl_next_proto_validate(SSL *s, PACKET *pkt) return 1; } -int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_npn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { unsigned char *selected; unsigned char selected_len; PACKET tmppkt; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Check if we are in a renegotiation. If so ignore this extension */ if (!SSL_IS_FIRST_HANDSHAKE(s)) return 1; /* We must have requested it. */ - if (s->ctx->ext.npn_select_cb == NULL) { + if (sctx->ext.npn_select_cb == NULL) { SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } @@ -1532,10 +1557,10 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* SSLfatal() already called */ return 0; } - if (s->ctx->ext.npn_select_cb(s, &selected, &selected_len, - PACKET_data(pkt), - PACKET_remaining(pkt), - s->ctx->ext.npn_select_cb_arg) != + if (sctx->ext.npn_select_cb(SSL_CONNECTION_GET_SSL(s), + &selected, &selected_len, + PACKET_data(pkt), PACKET_remaining(pkt), + sctx->ext.npn_select_cb_arg) != SSL_TLSEXT_ERR_OK) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; @@ -1561,8 +1586,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #endif -int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_alpn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { size_t len; @@ -1626,8 +1651,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #ifndef OPENSSL_NO_SRTP -int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_use_srtp(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int id, ct, mki; int i; @@ -1650,7 +1675,7 @@ int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } /* Throw an error if the server gave us an unsolicited extension */ - clnt = SSL_get_srtp_profiles(s); + clnt = SSL_get_srtp_profiles(SSL_CONNECTION_GET_SSL(s)); if (clnt == NULL) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_SRTP_PROFILES); return 0; @@ -1675,8 +1700,8 @@ int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #endif -int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_etm(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { /* Ignore if inappropriate ciphersuite */ if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) @@ -1691,8 +1716,8 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_ems(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) return 1; @@ -1703,7 +1728,8 @@ int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int version; @@ -1730,11 +1756,16 @@ int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context, /* We just set it here. We validate it in ssl_choose_client_version */ s->version = version; + if (!ssl_set_record_protocol_version(s, version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } return 1; } -int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, +int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 @@ -1815,7 +1846,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSL_SESSION *new_sess; if ((new_sess = ssl_session_dup(s->session, 0)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); return 0; } SSL_SESSION_free(s->session); @@ -1823,7 +1854,8 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->session->kex_group = group_id; } - if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) { + if ((ginf = tls1_group_id_lookup(SSL_CONNECTION_GET_CTX(s), + group_id)) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } @@ -1872,8 +1904,8 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_stoc_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { PACKET cookie; @@ -1887,7 +1919,8 @@ int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_early_data(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) { @@ -1901,6 +1934,22 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, s->session->ext.max_early_data = max_early_data; + if (SSL_IS_QUIC_HANDSHAKE(s) && max_early_data != 0xffffffff) { + /* + * QUIC allows missing max_early_data, or a max_early_data value + * of 0xffffffff. Missing max_early_data is stored in the session + * as 0. This is indistinguishable in OpenSSL from a present + * max_early_data value that was 0. In order that later checks for + * invalid max_early_data correctly treat as an error the case where + * max_early_data is present and it is 0, we store any invalid + * value in the same (non-zero) way. Otherwise we would have to + * introduce a new flag just for this. + */ + s->session->ext.max_early_data = 1; + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_MAX_EARLY_DATA); + return 0; + } + return 1; } @@ -1925,7 +1974,8 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, +int tls_parse_stoc_psk(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 @@ -1981,3 +2031,107 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } + +EXT_RETURN tls_construct_ctos_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + if (sc->client_cert_type == NULL) + return EXT_RETURN_NOT_SENT; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_client_cert_type) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, sc->client_cert_type, sc->client_cert_type_len) + || !WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_GOOD; + return EXT_RETURN_SENT; +} + +int tls_parse_stoc_client_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + unsigned int type; + + if (PACKET_remaining(pkt) != 1) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + if (!PACKET_get_1(pkt, &type)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* We did not send/ask for this */ + if (!ossl_assert(sc->ext.client_cert_type_ctos == OSSL_CERT_TYPE_CTOS_GOOD)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* We don't have this enabled */ + if (sc->client_cert_type == NULL) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* Given back a value we didn't configure */ + if (memchr(sc->client_cert_type, type, sc->client_cert_type_len) == NULL) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_VALUE); + return 0; + } + sc->ext.client_cert_type = type; + return 1; +} + +EXT_RETURN tls_construct_ctos_server_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + if (sc->server_cert_type == NULL) + return EXT_RETURN_NOT_SENT; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_cert_type) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, sc->server_cert_type, sc->server_cert_type_len) + || !WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_GOOD; + return EXT_RETURN_SENT; +} + +int tls_parse_stoc_server_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + unsigned int type; + + if (PACKET_remaining(pkt) != 1) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + if (!PACKET_get_1(pkt, &type)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* We did not send/ask for this */ + if (!ossl_assert(sc->ext.server_cert_type_ctos == OSSL_CERT_TYPE_CTOS_GOOD)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* We don't have this enabled */ + if (sc->server_cert_type == NULL) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* Given back a value we didn't configure */ + if (memchr(sc->server_cert_type, type, sc->server_cert_type_len) == NULL) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_VALUE); + return 0; + } + sc->ext.server_cert_type = type; + return 1; +} diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c index 401a4c5c76..fd840e8918 100644 --- a/ssl/statem/extensions_cust.c +++ b/ssl/statem/extensions_cust.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -110,11 +110,12 @@ void custom_ext_init(custom_ext_methods *exts) } /* Pass received custom extension data to the application for parsing. */ -int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, +int custom_ext_parse(SSL_CONNECTION *s, unsigned int context, + unsigned int ext_type, const unsigned char *ext_data, size_t ext_size, X509 *x, size_t chainidx) { - int al; + int al = 0; custom_ext_methods *exts = &s->cert->custext; custom_ext_method *meth; ENDPOINT role = ENDPOINT_BOTH; @@ -154,11 +155,11 @@ int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, meth->ext_flags |= SSL_EXT_FLAG_RECEIVED; /* If no parse function set return success */ - if (!meth->parse_cb) + if (meth->parse_cb == NULL) return 1; - if (meth->parse_cb(s, ext_type, context, ext_data, ext_size, x, chainidx, - &al, meth->parse_arg) <= 0) { + if (meth->parse_cb(SSL_CONNECTION_GET_SSL(s), ext_type, context, ext_data, + ext_size, x, chainidx, &al, meth->parse_arg) <= 0) { SSLfatal(s, al, SSL_R_BAD_EXTENSION); return 0; } @@ -170,13 +171,14 @@ int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, * Request custom extension data from the application and add to the return * buffer. */ -int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, - int maxversion) +int custom_ext_add(SSL_CONNECTION *s, int context, WPACKET *pkt, X509 *x, + size_t chainidx, int maxversion) { custom_ext_methods *exts = &s->cert->custext; custom_ext_method *meth; size_t i; int al; + int for_comp = (context & SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION) != 0; for (i = 0; i < exts->meths_count; i++) { const unsigned char *out = NULL; @@ -191,6 +193,7 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, | SSL_EXT_TLS1_3_SERVER_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS | SSL_EXT_TLS1_3_CERTIFICATE + | SSL_EXT_TLS1_3_RAW_PUBLIC_KEY | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST)) != 0) { /* Only send extensions present in ClientHello/CertificateRequest */ if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED)) @@ -204,12 +207,14 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, continue; if (meth->add_cb != NULL) { - int cb_retval = meth->add_cb(s, meth->ext_type, context, &out, + int cb_retval = meth->add_cb(SSL_CONNECTION_GET_SSL(s), + meth->ext_type, context, &out, &outlen, x, chainidx, &al, meth->add_arg); if (cb_retval < 0) { - SSLfatal(s, al, SSL_R_CALLBACK_FAILED); + if (!for_comp) + SSLfatal(s, al, SSL_R_CALLBACK_FAILED); return 0; /* error */ } if (cb_retval == 0) @@ -220,7 +225,11 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, || !WPACKET_start_sub_packet_u16(pkt) || (outlen > 0 && !WPACKET_memcpy(pkt, out, outlen)) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (meth->free_cb != NULL) + meth->free_cb(SSL_CONNECTION_GET_SSL(s), meth->ext_type, context, + out, meth->add_arg); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if ((context & SSL_EXT_CLIENT_HELLO) != 0) { @@ -228,7 +237,11 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, * We can't send duplicates: code logic should prevent this. */ if (!ossl_assert((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (meth->free_cb != NULL) + meth->free_cb(SSL_CONNECTION_GET_SSL(s), meth->ext_type, + context, out, meth->add_arg); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* @@ -239,7 +252,8 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, meth->ext_flags |= SSL_EXT_FLAG_SENT; } if (meth->free_cb != NULL) - meth->free_cb(s, meth->ext_type, context, out, meth->add_arg); + meth->free_cb(SSL_CONNECTION_GET_SSL(s), meth->ext_type, context, + out, meth->add_arg); } return 1; } @@ -328,6 +342,8 @@ void custom_exts_free(custom_ext_methods *exts) OPENSSL_free(meth->parse_arg); } OPENSSL_free(exts->meths); + exts->meths = NULL; + exts->meths_count = 0; } /* Return true if a client custom extension exists, false otherwise */ @@ -337,16 +353,15 @@ int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type) NULL) != NULL; } -static int add_custom_ext_intern(SSL_CTX *ctx, ENDPOINT role, - unsigned int ext_type, - unsigned int context, - SSL_custom_ext_add_cb_ex add_cb, - SSL_custom_ext_free_cb_ex free_cb, - void *add_arg, - SSL_custom_ext_parse_cb_ex parse_cb, - void *parse_arg) +int ossl_tls_add_custom_ext_intern(SSL_CTX *ctx, custom_ext_methods *exts, + ENDPOINT role, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg) { - custom_ext_methods *exts = &ctx->cert->custext; custom_ext_method *meth, *tmp; /* @@ -356,6 +371,9 @@ static int add_custom_ext_intern(SSL_CTX *ctx, ENDPOINT role, if (add_cb == NULL && free_cb != NULL) return 0; + if (exts == NULL) + exts = &ctx->cert->custext; + #ifndef OPENSSL_NO_CT /* * We don't want applications registering callbacks for SCT extensions @@ -364,6 +382,7 @@ static int add_custom_ext_intern(SSL_CTX *ctx, ENDPOINT role, */ if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp && (context & SSL_EXT_CLIENT_HELLO) != 0 + && ctx != NULL && SSL_CTX_ct_is_enabled(ctx)) return 0; #endif @@ -428,13 +447,13 @@ static int add_old_custom_ext(SSL_CTX *ctx, ENDPOINT role, parse_cb_wrap->parse_arg = parse_arg; parse_cb_wrap->parse_cb = parse_cb; - ret = add_custom_ext_intern(ctx, role, ext_type, - context, - custom_ext_add_old_cb_wrap, - custom_ext_free_old_cb_wrap, - add_cb_wrap, - custom_ext_parse_old_cb_wrap, - parse_cb_wrap); + ret = ossl_tls_add_custom_ext_intern(ctx, NULL, role, ext_type, + context, + custom_ext_add_old_cb_wrap, + custom_ext_free_old_cb_wrap, + add_cb_wrap, + custom_ext_parse_old_cb_wrap, + parse_cb_wrap); if (!ret) { OPENSSL_free(add_cb_wrap); @@ -480,8 +499,9 @@ int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type, void *add_arg, SSL_custom_ext_parse_cb_ex parse_cb, void *parse_arg) { - return add_custom_ext_intern(ctx, ENDPOINT_BOTH, ext_type, context, add_cb, - free_cb, add_arg, parse_cb, parse_arg); + return ossl_tls_add_custom_ext_intern(ctx, NULL, ENDPOINT_BOTH, ext_type, + context, add_cb, free_cb, add_arg, + parse_cb, parse_arg); } int SSL_extension_supported(unsigned int ext_type) @@ -522,6 +542,9 @@ int SSL_extension_supported(unsigned int ext_type) case TLSEXT_TYPE_certificate_authorities: case TLSEXT_TYPE_psk: case TLSEXT_TYPE_post_handshake_auth: + case TLSEXT_TYPE_compress_certificate: + case TLSEXT_TYPE_client_cert_type: + case TLSEXT_TYPE_server_cert_type: return 1; default: return 0; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 498ff6bb5e..64ccb3ed6d 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -38,11 +38,13 @@ /* * Parse the client's renegotiation binding and abort if it's not right */ -int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_renegotiate(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int ilen; const unsigned char *data; + int ok; /* Parse the length byte */ if (!PACKET_get_1(pkt, &ilen) @@ -57,8 +59,16 @@ int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, return 0; } - if (memcmp(data, s->s3.previous_client_finished, - s->s3.previous_client_finished_len)) { + ok = memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (ok) { + if ((data[0] ^ s->s3.previous_client_finished[0]) != 0xFF) { + ok = 0; + } + } +#endif + if (ok) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH); return 0; } @@ -91,8 +101,8 @@ int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, * extension. * - On session reconnect, the servername extension may be absent. */ -int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) +int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int servname_type; PACKET sni, hostname; @@ -126,7 +136,7 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3 * we always use the SNI value from the handshake. */ - if (!s->hit || SSL_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; @@ -163,7 +173,8 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_ctos_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_maxfragmentlen(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { unsigned int value; @@ -200,8 +211,8 @@ int tls_parse_ctos_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, } #ifndef OPENSSL_NO_SRP -int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_srp(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { PACKET srp_I; @@ -220,7 +231,8 @@ int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #endif -int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { PACKET ec_point_format_list; @@ -243,13 +255,14 @@ int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_session_ticket(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (s->ext.session_ticket_cb && - !s->ext.session_ticket_cb(s, PACKET_data(pkt), - PACKET_remaining(pkt), - s->ext.session_ticket_cb_arg)) { + !s->ext.session_ticket_cb(SSL_CONNECTION_GET_SSL(s), + PACKET_data(pkt), PACKET_remaining(pkt), + s->ext.session_ticket_cb_arg)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -257,7 +270,7 @@ int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, +int tls_parse_ctos_sig_algs_cert(SSL_CONNECTION *s, PACKET *pkt, ossl_unused unsigned int context, ossl_unused X509 *x, ossl_unused size_t chainidx) @@ -278,8 +291,8 @@ int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, return 1; } -int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_sig_algs(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { PACKET supported_sig_algs; @@ -298,7 +311,8 @@ int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #ifndef OPENSSL_NO_OCSP -int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_status_request(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { PACKET responder_id_list, exts; @@ -337,7 +351,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, if (PACKET_remaining(&responder_id_list) > 0) { s->ext.ocsp.ids = sk_OCSP_RESPID_new_null(); if (s->ext.ocsp.ids == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } } else { @@ -402,8 +416,8 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_parse_ctos_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_npn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { /* * We shouldn't accept this extension on a @@ -420,8 +434,8 @@ int tls_parse_ctos_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * Save the ALPN extension in a ClientHello.|pkt| holds the contents of the ALPN * extension, not including type and length. Returns: 1 on success, 0 on error. */ -int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_alpn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { PACKET protocol_list, save_protocol_list, protocol; @@ -457,16 +471,17 @@ int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #ifndef OPENSSL_NO_SRTP -int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_use_srtp(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; unsigned int ct, mki_len, id; int i, srtp_pref; PACKET subpkt; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* Ignore this if we have no SRTP profiles */ - if (SSL_get_srtp_profiles(s) == NULL) + if (SSL_get_srtp_profiles(ssl) == NULL) return 1; /* Pull off the length of the cipher suite list and check it is even */ @@ -477,7 +492,7 @@ int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - srvr = SSL_get_srtp_profiles(s); + srvr = SSL_get_srtp_profiles(ssl); s->srtp_profile = NULL; /* Search all profiles for a match initially */ srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); @@ -524,8 +539,8 @@ int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #endif -int tls_parse_ctos_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_etm(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) s->ext.use_etm = 1; @@ -537,7 +552,8 @@ int tls_parse_ctos_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * Process a psk_kex_modes extension received in the ClientHello. |pkt| contains * the raw PACKET data for the extension. Returns 1 on success or 0 on failure. */ -int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 @@ -566,8 +582,8 @@ int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context, * Process a key_share extension received in the ClientHello. |pkt| contains * the raw PACKET data for the extension. Returns 1 on success or 0 on failure. */ -int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 unsigned int group_id; @@ -660,16 +676,16 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, continue; } + s->s3.group_id = group_id; + /* Cache the selected group ID in the SSL_SESSION */ + s->session->kex_group = group_id; + if ((s->s3.peer_tmp = ssl_generate_param_group(s, group_id)) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } - s->s3.group_id = group_id; - /* Cache the selected group ID in the SSL_SESSION */ - s->session->kex_group = group_id; - if (tls13_set_encoded_pub_key(s->s3.peer_tmp, PACKET_data(&encoded_pt), PACKET_remaining(&encoded_pt)) <= 0) { @@ -684,8 +700,8 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 unsigned int format, version, key_share, group_id; @@ -698,9 +714,11 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned char hrr[MAX_HRR_SIZE]; size_t rawlen, hmaclen, hrrlen, ciphlen; uint64_t tm, now; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Ignore any cookie if we're not set up to verify it */ - if (s->ctx->verify_stateless_cookie_cb == NULL + if (sctx->verify_stateless_cookie_cb == NULL || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return 1; @@ -721,20 +739,20 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Verify the HMAC of the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, + pkey = EVP_PKEY_new_raw_private_key_ex(sctx->libctx, "HMAC", + sctx->propq, s->session_ctx->ext.cookie_hmac_key, sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } hmaclen = SHA256_DIGEST_LENGTH; - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, - s->ctx->propq, pkey, NULL) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", sctx->libctx, + sctx->propq, pkey, NULL) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, data, rawlen - SHA256_DIGEST_LENGTH) <= 0 || hmaclen != SHA256_DIGEST_LENGTH) { @@ -814,8 +832,9 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } /* Verify the app cookie */ - if (s->ctx->verify_stateless_cookie_cb(s, PACKET_data(&appcookie), - PACKET_remaining(&appcookie)) == 0) { + if (sctx->verify_stateless_cookie_cb(ssl, + PACKET_data(&appcookie), + PACKET_remaining(&appcookie)) == 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); return 0; } @@ -835,8 +854,8 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE) || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id, s->tmp_session_id_len) - || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, &hrrpkt, - &ciphlen) + || !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, &hrrpkt, + &ciphlen) || !WPACKET_put_bytes_u8(&hrrpkt, 0) || !WPACKET_start_sub_packet_u16(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); @@ -891,7 +910,8 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { PACKET supported_groups_list; @@ -904,7 +924,7 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, return 0; } - if (!s->hit || SSL_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { OPENSSL_free(s->ext.peer_supportedgroups); s->ext.peer_supportedgroups = NULL; s->ext.peer_supportedgroups_len = 0; @@ -919,8 +939,8 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, return 1; } -int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_ems(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { /* The extension must always be empty */ if (PACKET_remaining(pkt) != 0) { @@ -937,7 +957,7 @@ int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } -int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_early_data(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { if (PACKET_remaining(pkt) != 0) { @@ -953,7 +973,7 @@ int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, return 1; } -static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL *s, PACKET *tick, +static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL_CONNECTION *s, PACKET *tick, SSL_SESSION **sess) { SSL_SESSION *tmpsess = NULL; @@ -981,14 +1001,16 @@ static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL *s, PACKET *tick, return SSL_TICKET_SUCCESS; } -int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) +int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) { PACKET identities, binders, binder; size_t binderoffset, hashsize; SSL_SESSION *sess = NULL; unsigned int id, i, ext = 0; const EVP_MD *md = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* * If we have no PSK kex mode that we recognise then we can't resume so @@ -1017,14 +1039,14 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, idlen = PACKET_remaining(&identity); if (s->psk_find_session_cb != NULL - && !s->psk_find_session_cb(s, PACKET_data(&identity), idlen, + && !s->psk_find_session_cb(ssl, PACKET_data(&identity), idlen, &sess)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_EXTENSION); return 0; } #ifndef OPENSSL_NO_PSK - if(sess == NULL + if (sess == NULL && s->psk_server_callback != NULL && idlen <= PSK_MAX_IDENTITY_LEN) { char *pskid = NULL; @@ -1035,7 +1057,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - pskdatalen = s->psk_server_callback(s, pskid, pskdata, + pskdatalen = s->psk_server_callback(ssl, pskid, pskdata, sizeof(pskdata)); OPENSSL_free(pskid); if (pskdatalen > PSK_MAX_PSK_LEN) { @@ -1049,7 +1071,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * We found a PSK using an old style callback. We don't know * the digest so we default to SHA256 as per the TLSv1.3 spec */ - cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); + cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); if (cipher == NULL) { OPENSSL_cleanse(pskdata, pskdatalen); SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -1094,7 +1116,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->ext.early_data_ok = 1; s->ext.ticket_expected = 1; } else { - uint32_t ticket_age = 0, agesec, agems; + OSSL_TIME t, age, expire; int ret; /* @@ -1133,24 +1155,26 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, continue; } - ticket_age = (uint32_t)ticket_agel; - agesec = (uint32_t)(time(NULL) - sess->time); - agems = agesec * (uint32_t)1000; - ticket_age -= sess->ext.tick_age_add; + age = ossl_time_subtract(ossl_ms2time(ticket_agel), + ossl_ms2time(sess->ext.tick_age_add)); + t = ossl_time_subtract(ossl_time_now(), sess->time); /* - * For simplicity we do our age calculations in seconds. If the - * client does it in ms then it could appear that their ticket age - * is longer than ours (our ticket age calculation should always be - * slightly longer than the client's due to the network latency). - * Therefore we add 1000ms to our age calculation to adjust for - * rounding errors. + * Although internally we use OSS_TIME which has ns granularity, + * when SSL_SESSION structures are serialised/deserialised we use + * second granularity for the sess->time field. Therefore it could + * appear that the client's ticket age is longer than ours (our + * ticket age calculation should always be slightly longer than the + * client's due to the network latency). Therefore we add 1000ms to + * our age calculation to adjust for rounding errors. */ + expire = ossl_time_add(t, ossl_ms2time(1000)); + if (id == 0 - && sess->timeout >= (time_t)agesec - && agems / (uint32_t)1000 == agesec - && ticket_age <= agems + 1000 - && ticket_age + TICKET_AGE_ALLOWANCE >= agems + 1000) { + && ossl_time_compare(sess->timeout, t) >= 0 + && ossl_time_compare(age, expire) <= 0 + && ossl_time_compare(ossl_time_add(age, TICKET_AGE_ALLOWANCE), + expire) >= 0) { /* * Ticket age is within tolerance and not expired. We allow it * for early data @@ -1159,13 +1183,13 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } - md = ssl_md(s->ctx, sess->cipher->algorithm2); + md = ssl_md(sctx, sess->cipher->algorithm2); if (md == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (!EVP_MD_is_a(md, - EVP_MD_get0_name(ssl_md(s->ctx, + EVP_MD_get0_name(ssl_md(sctx, s->s3.tmp.new_cipher->algorithm2)))) { /* The ciphersuite is not compatible with this session. */ SSL_SESSION_free(sess); @@ -1216,7 +1240,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } -int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, +int tls_parse_ctos_post_handshake_auth(SSL_CONNECTION *s, PACKET *pkt, ossl_unused unsigned int context, ossl_unused X509 *x, ossl_unused size_t chainidx) @@ -1235,7 +1259,7 @@ int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, /* * Add the server's renegotiation binding */ -EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_renegotiate(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1259,7 +1283,7 @@ EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1270,7 +1294,7 @@ EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming. * We just use the servername from the initial handshake. */ - if (s->hit && !SSL_IS_TLS13(s)) + if (s->hit && !SSL_CONNECTION_IS_TLS13(s)) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -1283,7 +1307,7 @@ EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, } /* Add/include the server's max fragment len extension into ServerHello */ -EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1305,7 +1329,7 @@ EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1331,7 +1355,7 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1351,7 +1375,7 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, } /* Copy group ID if supported */ - version = SSL_version(s); + version = SSL_version(SSL_CONNECTION_GET_SSL(s)); for (i = 0; i < numgroups; i++) { uint16_t group = groups[i]; @@ -1391,7 +1415,7 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1410,7 +1434,7 @@ EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, } #ifndef OPENSSL_NO_OCSP -EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1421,7 +1445,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, if (!s->ext.status_expected) return EXT_RETURN_NOT_SENT; - if (SSL_IS_TLS13(s) && chainidx != 0) + if (SSL_CONNECTION_IS_TLS13(s) && chainidx != 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) @@ -1435,7 +1459,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, * send back an empty extension, with the certificate status appearing as a * separate message */ - if (SSL_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) { + if (SSL_CONNECTION_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } @@ -1449,7 +1473,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, #endif #ifndef OPENSSL_NO_NEXTPROTONEG -EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_next_proto_neg(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1457,13 +1481,14 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, unsigned int npalen; int ret; int npn_seen = s->s3.npn_seen; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); s->s3.npn_seen = 0; - if (!npn_seen || s->ctx->ext.npn_advertised_cb == NULL) + if (!npn_seen || sctx->ext.npn_advertised_cb == NULL) return EXT_RETURN_NOT_SENT; - ret = s->ctx->ext.npn_advertised_cb(s, &npa, &npalen, - s->ctx->ext.npn_advertised_cb_arg); + ret = sctx->ext.npn_advertised_cb(SSL_CONNECTION_GET_SSL(s), &npa, &npalen, + sctx->ext.npn_advertised_cb_arg); if (ret == SSL_TLSEXT_ERR_OK) { if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg) || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) { @@ -1477,7 +1502,7 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, } #endif -EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_alpn(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { if (s->s3.alpn_selected == NULL) @@ -1499,7 +1524,7 @@ EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, } #ifndef OPENSSL_NO_SRTP -EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_use_srtp(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1520,7 +1545,8 @@ EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, } #endif -EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_etm(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (!s->ext.use_etm) @@ -1549,7 +1575,8 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_ems(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) @@ -1564,11 +1591,11 @@ EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (!ossl_assert(SSL_IS_TLS13(s))) { + if (!ossl_assert(SSL_CONNECTION_IS_TLS13(s))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1584,7 +1611,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1633,7 +1660,8 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if ((ginf = tls1_group_id_lookup(s->ctx, s->s3.group_id)) == NULL) { + if ((ginf = tls1_group_id_lookup(SSL_CONNECTION_GET_CTX(s), + s->s3.group_id)) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1642,7 +1670,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, /* Regular KEX */ skey = ssl_generate_pkey(s, ckey); if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); return EXT_RETURN_FAIL; } @@ -1716,7 +1744,8 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, #endif } -EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 @@ -1726,11 +1755,13 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, EVP_MD_CTX *hctx; EVP_PKEY *pkey; int ret = EXT_RETURN_FAIL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; - if (s->ctx->gen_stateless_cookie_cb == NULL) { + if (sctx->gen_stateless_cookie_cb == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_COOKIE_CALLBACK_SET); return EXT_RETURN_FAIL; } @@ -1743,8 +1774,8 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) - || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, - &ciphlen) + || !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, + &ciphlen) /* Is there a key_share extension present in this HRR? */ || !WPACKET_put_bytes_u8(pkt, s->s3.peer_tmp == NULL) || !WPACKET_put_bytes_u64(pkt, time(NULL)) @@ -1775,7 +1806,8 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, } /* Generate the application cookie */ - if (s->ctx->gen_stateless_cookie_cb(s, appcookie1, &appcookielen) == 0) { + if (sctx->gen_stateless_cookie_cb(ssl, appcookie1, + &appcookielen) == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); return EXT_RETURN_FAIL; } @@ -1798,17 +1830,17 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, /* HMAC the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, + pkey = EVP_PKEY_new_raw_private_key_ex(sctx->libctx, "HMAC", + sctx->propq, s->session_ctx->ext.cookie_hmac_key, sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, - s->ctx->propq, pkey, NULL) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", sctx->libctx, + sctx->propq, pkey, NULL) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, cookie, totcookielen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -1840,7 +1872,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, #endif } -EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1855,7 +1887,8 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, if (((s->s3.tmp.new_cipher->id & 0xFFFF) != 0x80 && (s->s3.tmp.new_cipher->id & 0xFFFF) != 0x81) - || (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0) + || (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) + & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) { @@ -1866,7 +1899,7 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_early_data(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1898,7 +1931,8 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_psk(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx) { if (!s->hit) @@ -1914,3 +1948,164 @@ EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_SENT; } + +EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + if (sc->ext.client_cert_type_ctos == OSSL_CERT_TYPE_CTOS_ERROR + && (send_certificate_request(sc) + || sc->post_handshake_auth == SSL_PHA_EXT_RECEIVED)) { + /* Did not receive an acceptable cert type - and doing client auth */ + SSLfatal(sc, SSL_AD_UNSUPPORTED_CERTIFICATE, SSL_R_BAD_EXTENSION); + return EXT_RETURN_FAIL; + } + + if (sc->ext.client_cert_type == TLSEXT_cert_type_x509) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + return EXT_RETURN_NOT_SENT; + } + + /* + * Note: only supposed to send this if we are going to do a cert request, + * but TLSv1.3 could do a PHA request if the client supports it + */ + if ((!send_certificate_request(sc) && sc->post_handshake_auth != SSL_PHA_EXT_RECEIVED) + || sc->ext.client_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD + || sc->client_cert_type == NULL) { + /* if we don't send it, reset to TLSEXT_cert_type_x509 */ + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.client_cert_type = TLSEXT_cert_type_x509; + return EXT_RETURN_NOT_SENT; + } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_client_cert_type) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u8(pkt, sc->ext.client_cert_type) + || !WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + return EXT_RETURN_SENT; +} + +/* One of |pref|, |other| is configured and the values are sanitized */ +static int reconcile_cert_type(const unsigned char *pref, size_t pref_len, + const unsigned char *other, size_t other_len, + uint8_t *chosen_cert_type) +{ + size_t i; + + for (i = 0; i < pref_len; i++) { + if (memchr(other, pref[i], other_len) != NULL) { + *chosen_cert_type = pref[i]; + return OSSL_CERT_TYPE_CTOS_GOOD; + } + } + return OSSL_CERT_TYPE_CTOS_ERROR; +} + +int tls_parse_ctos_client_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + PACKET supported_cert_types; + const unsigned char *data; + size_t len; + + /* Ignore the extension */ + if (sc->client_cert_type == NULL) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.client_cert_type = TLSEXT_cert_type_x509; + return 1; + } + + if (!PACKET_as_length_prefixed_1(pkt, &supported_cert_types)) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_ERROR; + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + if ((len = PACKET_remaining(&supported_cert_types)) == 0) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_ERROR; + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + if (!PACKET_get_bytes(&supported_cert_types, &data, len)) { + sc->ext.client_cert_type_ctos = OSSL_CERT_TYPE_CTOS_ERROR; + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* client_cert_type: client (peer) has priority */ + sc->ext.client_cert_type_ctos = reconcile_cert_type(data, len, + sc->client_cert_type, sc->client_cert_type_len, + &sc->ext.client_cert_type); + + /* Ignore the error until sending - so we can check cert auth*/ + return 1; +} + +EXT_RETURN tls_construct_stoc_server_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + if (sc->ext.server_cert_type == TLSEXT_cert_type_x509) { + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + return EXT_RETURN_NOT_SENT; + } + if (sc->ext.server_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD + || sc->server_cert_type == NULL) { + /* if we don't send it, reset to TLSEXT_cert_type_x509 */ + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.server_cert_type = TLSEXT_cert_type_x509; + return EXT_RETURN_NOT_SENT; + } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_cert_type) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u8(pkt, sc->ext.server_cert_type) + || !WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + return EXT_RETURN_SENT; +} + +int tls_parse_ctos_server_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx) +{ + PACKET supported_cert_types; + const unsigned char *data; + size_t len; + + /* Ignore the extension */ + if (sc->server_cert_type == NULL) { + sc->ext.server_cert_type_ctos = OSSL_CERT_TYPE_CTOS_NONE; + sc->ext.server_cert_type = TLSEXT_cert_type_x509; + return 1; + } + + if (!PACKET_as_length_prefixed_1(pkt, &supported_cert_types)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + + if ((len = PACKET_remaining(&supported_cert_types)) == 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + if (!PACKET_get_bytes(&supported_cert_types, &data, len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + /* server_cert_type: server (this) has priority */ + sc->ext.server_cert_type_ctos = reconcile_cert_type(sc->server_cert_type, sc->server_cert_type_len, + data, len, + &sc->ext.server_cert_type); + if (sc->ext.server_cert_type_ctos == OSSL_CERT_TYPE_CTOS_GOOD) + return 1; + + /* Did not receive an acceptable cert type */ + SSLfatal(sc, SSL_AD_UNSUPPORTED_CERTIFICATE, SSL_R_BAD_EXTENSION); + return 0; +} diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 553546d93a..921d7cfb1e 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -62,29 +62,49 @@ typedef enum { SUB_STATE_END_HANDSHAKE } SUB_STATE_RETURN; -static int state_machine(SSL *s, int server); -static void init_read_state_machine(SSL *s); -static SUB_STATE_RETURN read_state_machine(SSL *s); -static void init_write_state_machine(SSL *s); -static SUB_STATE_RETURN write_state_machine(SSL *s); +static int state_machine(SSL_CONNECTION *s, int server); +static void init_read_state_machine(SSL_CONNECTION *s); +static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s); +static void init_write_state_machine(SSL_CONNECTION *s); +static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s); OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) { - return ssl->statem.hand_state; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(ssl); + + if (sc == NULL) + return TLS_ST_BEFORE; + + return sc->statem.hand_state; } int SSL_in_init(const SSL *s) { - return s->statem.in_init; + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return sc->statem.in_init; } int SSL_is_init_finished(const SSL *s) { - return !(s->statem.in_init) && (s->statem.hand_state == TLS_ST_OK); + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + return !(sc->statem.in_init) && (sc->statem.hand_state == TLS_ST_OK); } int SSL_in_before(const SSL *s) { + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + /* * Historically being "in before" meant before anything had happened. In the * current code though we remain in the "before" state for a while after we @@ -92,39 +112,43 @@ int SSL_in_before(const SSL *s) * first message to arrive). There "in before" is taken to mean "in before" * and not started any handshake process yet. */ - return (s->statem.hand_state == TLS_ST_BEFORE) - && (s->statem.state == MSG_FLOW_UNINITED); + return (sc->statem.hand_state == TLS_ST_BEFORE) + && (sc->statem.state == MSG_FLOW_UNINITED); +} + +OSSL_HANDSHAKE_STATE ossl_statem_get_state(SSL_CONNECTION *s) +{ + return s != NULL ? s->statem.hand_state : TLS_ST_BEFORE; } /* * Clear the state machine state and reset back to MSG_FLOW_UNINITED */ -void ossl_statem_clear(SSL *s) +void ossl_statem_clear(SSL_CONNECTION *s) { s->statem.state = MSG_FLOW_UNINITED; s->statem.hand_state = TLS_ST_BEFORE; - s->statem.in_init = 1; + ossl_statem_set_in_init(s, 1); s->statem.no_cert_verify = 0; } /* * Set the state machine up ready for a renegotiation handshake */ -void ossl_statem_set_renegotiate(SSL *s) +void ossl_statem_set_renegotiate(SSL_CONNECTION *s) { - s->statem.in_init = 1; + ossl_statem_set_in_init(s, 1); s->statem.request_state = TLS_ST_SW_HELLO_REQ; } -void ossl_statem_send_fatal(SSL *s, int al) +void ossl_statem_send_fatal(SSL_CONNECTION *s, int al) { /* We shouldn't call SSLfatal() twice. Once is enough */ if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR) return; - s->statem.in_init = 1; + ossl_statem_set_in_init(s, 1); s->statem.state = MSG_FLOW_ERROR; - if (al != SSL_AD_NO_ALERT - && s->statem.enc_write_state != ENC_WRITE_STATE_INVALID) + if (al != SSL_AD_NO_ALERT) ssl3_send_alert(s, SSL3_AL_FATAL, al); } @@ -134,7 +158,8 @@ void ossl_statem_send_fatal(SSL *s, int al) * into an error state and sends an alert if appropriate. * This is a permanent error for the current connection. */ -void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...) +void ossl_statem_fatal(SSL_CONNECTION *s, int al, int reason, + const char *fmt, ...) { va_list args; @@ -164,7 +189,7 @@ void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...) * 1: Yes * 0: No */ -int ossl_statem_in_error(const SSL *s) +int ossl_statem_in_error(const SSL_CONNECTION *s) { if (s->statem.state == MSG_FLOW_ERROR) return 1; @@ -172,17 +197,19 @@ int ossl_statem_in_error(const SSL *s) return 0; } -void ossl_statem_set_in_init(SSL *s, int init) +void ossl_statem_set_in_init(SSL_CONNECTION *s, int init) { s->statem.in_init = init; + if (s->rlayer.rrlmethod != NULL && s->rlayer.rrlmethod->set_in_init != NULL) + s->rlayer.rrlmethod->set_in_init(s->rlayer.rrl, init); } -int ossl_statem_get_in_handshake(SSL *s) +int ossl_statem_get_in_handshake(SSL_CONNECTION *s) { return s->statem.in_handshake; } -void ossl_statem_set_in_handshake(SSL *s, int inhand) +void ossl_statem_set_in_handshake(SSL_CONNECTION *s, int inhand) { if (inhand) s->statem.in_handshake++; @@ -191,7 +218,7 @@ void ossl_statem_set_in_handshake(SSL *s, int inhand) } /* Are we in a sensible state to skip over unreadable early data? */ -int ossl_statem_skip_early_data(SSL *s) +int ossl_statem_skip_early_data(SSL_CONNECTION *s) { if (s->ext.early_data != SSL_EARLY_DATA_REJECTED) return 0; @@ -212,7 +239,7 @@ int ossl_statem_skip_early_data(SSL *s) * attempting to read data (SSL_read*()), or -1 if we are in SSL_do_handshake() * or similar. */ -void ossl_statem_check_finish_init(SSL *s, int sending) +void ossl_statem_check_finish_init(SSL_CONNECTION *s, int sending) { if (sending == -1) { if (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END @@ -246,10 +273,10 @@ void ossl_statem_check_finish_init(SSL *s, int sending) } } -void ossl_statem_set_hello_verify_done(SSL *s) +void ossl_statem_set_hello_verify_done(SSL_CONNECTION *s) { s->statem.state = MSG_FLOW_UNINITED; - s->statem.in_init = 1; + ossl_statem_set_in_init(s, 1); /* * This will get reset (briefly) back to TLS_ST_BEFORE when we enter * state_machine() because |state| is MSG_FLOW_UNINITED, but until then any @@ -262,22 +289,34 @@ void ossl_statem_set_hello_verify_done(SSL *s) int ossl_statem_connect(SSL *s) { - return state_machine(s, 0); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + + return state_machine(sc, 0); } int ossl_statem_accept(SSL *s) { - return state_machine(s, 1); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + + return state_machine(sc, 1); } typedef void (*info_cb) (const SSL *, int, int); -static info_cb get_callback(SSL *s) +static info_cb get_callback(SSL_CONNECTION *s) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + if (s->info_callback != NULL) return s->info_callback; - else if (s->ctx->info_callback != NULL) - return s->ctx->info_callback; + else if (sctx->info_callback != NULL) + return sctx->info_callback; return NULL; } @@ -310,13 +349,14 @@ static info_cb get_callback(SSL *s) * 1: Success * <=0: NBIO or error */ -static int state_machine(SSL *s, int server) +static int state_machine(SSL_CONNECTION *s, int server) { BUF_MEM *buf = NULL; void (*cb) (const SSL *ssl, int type, int val) = NULL; OSSL_STATEM *st = &s->statem; int ret = -1; int ssret; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (st->state == MSG_FLOW_ERROR) { /* Shouldn't have been called if we're already in the error state */ @@ -329,21 +369,21 @@ static int state_machine(SSL *s, int server) cb = get_callback(s); st->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) { + if (!SSL_in_init(ssl) || SSL_in_before(ssl)) { /* * If we are stateless then we already called SSL_clear() - don't do * it again and clear the STATELESS flag itself. */ - if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s)) + if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(ssl)) return -1; } #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) { + if (SSL_CONNECTION_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { /* * Notify SCTP BIO socket to enter handshake mode and prevent stream * identifier other than 0. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, st->in_handshake, NULL); } #endif @@ -358,8 +398,8 @@ static int state_machine(SSL *s, int server) s->server = server; if (cb != NULL) { - if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_IS_TLS13(s)) - cb(s, SSL_CB_HANDSHAKE_START, 1); + if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_CONNECTION_IS_TLS13(s)) + cb(ssl, SSL_CB_HANDSHAKE_START, 1); } /* @@ -368,7 +408,7 @@ static int state_machine(SSL *s, int server) * doomed to failure. */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && (server || (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00))) { SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); @@ -399,10 +439,6 @@ static int state_machine(SSL *s, int server) buf = NULL; } - if (!ssl3_setup_buffers(s)) { - SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); - goto end; - } s->init_num = 0; /* @@ -415,14 +451,14 @@ static int state_machine(SSL *s, int server) * SCTP */ #ifndef OPENSSL_NO_SCTP - if (!SSL_IS_DTLS(s) || !BIO_dgram_is_sctp(SSL_get_wbio(s))) + if (!SSL_CONNECTION_IS_DTLS(s) || !BIO_dgram_is_sctp(SSL_get_wbio(ssl))) #endif if (!ssl_init_wbio_buffer(s)) { SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } - if ((SSL_in_before(s)) + if ((SSL_in_before(ssl)) || s->renegotiate) { if (!tls_setup_handshake(s)) { /* SSLfatal() already called */ @@ -472,12 +508,12 @@ static int state_machine(SSL *s, int server) st->in_handshake--; #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) { + if (SSL_CONNECTION_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { /* * Notify SCTP BIO socket to leave handshake mode and allow stream * identifier other than 0. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, st->in_handshake, NULL); } #endif @@ -485,9 +521,9 @@ static int state_machine(SSL *s, int server) BUF_MEM_free(buf); if (cb != NULL) { if (server) - cb(s, SSL_CB_ACCEPT_EXIT, ret); + cb(ssl, SSL_CB_ACCEPT_EXIT, ret); else - cb(s, SSL_CB_CONNECT_EXIT, ret); + cb(ssl, SSL_CB_CONNECT_EXIT, ret); } return ret; } @@ -495,14 +531,14 @@ static int state_machine(SSL *s, int server) /* * Initialise the MSG_FLOW_READING sub-state machine */ -static void init_read_state_machine(SSL *s) +static void init_read_state_machine(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; st->read_state = READ_STATE_HEADER; } -static int grow_init_buf(SSL *s, size_t size) { +static int grow_init_buf(SSL_CONNECTION *s, size_t size) { size_t msg_offset = (char *)s->init_msg - s->init_buf->data; @@ -543,17 +579,18 @@ static int grow_init_buf(SSL *s, size_t size) { * control returns to the calling application. When this function is recalled we * will resume in the same state where we left off. */ -static SUB_STATE_RETURN read_state_machine(SSL *s) +static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; int ret, mt; size_t len = 0; - int (*transition) (SSL *s, int mt); + int (*transition) (SSL_CONNECTION *s, int mt); PACKET pkt; - MSG_PROCESS_RETURN(*process_message) (SSL *s, PACKET *pkt); - WORK_STATE(*post_process_message) (SSL *s, WORK_STATE wst); - size_t (*max_message_size) (SSL *s); + MSG_PROCESS_RETURN(*process_message) (SSL_CONNECTION *s, PACKET *pkt); + WORK_STATE(*post_process_message) (SSL_CONNECTION *s, WORK_STATE wst); + size_t (*max_message_size) (SSL_CONNECTION *s); void (*cb) (const SSL *ssl, int type, int val) = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); cb = get_callback(s); @@ -578,7 +615,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) switch (st->read_state) { case READ_STATE_HEADER: /* Get the state the peer wants to move to */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* * In DTLS we get the whole message in one go - header and body */ @@ -595,9 +632,9 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) if (cb != NULL) { /* Notify callback of an impending state change */ if (s->server) - cb(s, SSL_CB_ACCEPT_LOOP, 1); + cb(ssl, SSL_CB_ACCEPT_LOOP, 1); else - cb(s, SSL_CB_CONNECT_LOOP, 1); + cb(ssl, SSL_CB_CONNECT_LOOP, 1); } /* * Validate that we are allowed to move to the new state and move @@ -613,7 +650,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) } /* dtls_get_message already did this */ - if (!SSL_IS_DTLS(s) + if (!SSL_CONNECTION_IS_DTLS(s) && s->s3.tmp.message_size > 0 && !grow_init_buf(s, s->s3.tmp.message_size + SSL3_HM_HEADER_LENGTH)) { @@ -625,7 +662,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* Fall through */ case READ_STATE_BODY: - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* * Actually we already have the body, but we give DTLS the * opportunity to do any further processing. @@ -655,7 +692,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) return SUB_STATE_ERROR; case MSG_PROCESS_FINISHED_READING: - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { dtls1_stop_timer(s); } return SUB_STATE_FINISHED; @@ -687,7 +724,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) break; case WORK_FINISHED_STOP: - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { dtls1_stop_timer(s); } return SUB_STATE_FINISHED; @@ -705,13 +742,13 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* * Send a previously constructed message to the peer. */ -static int statem_do_write(SSL *s) +static int statem_do_write(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; if (st->hand_state == TLS_ST_CW_CHANGE || st->hand_state == TLS_ST_SW_CHANGE) { - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); else return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); @@ -723,7 +760,7 @@ static int statem_do_write(SSL *s) /* * Initialise the MSG_FLOW_WRITING sub-state machine */ -static void init_write_state_machine(SSL *s) +static void init_write_state_machine(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -761,20 +798,22 @@ static void init_write_state_machine(SSL *s) * message has been completed. As for WRITE_STATE_PRE_WORK this could also * result in an NBIO event. */ -static SUB_STATE_RETURN write_state_machine(SSL *s) +static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; int ret; - WRITE_TRAN(*transition) (SSL *s); - WORK_STATE(*pre_work) (SSL *s, WORK_STATE wst); - WORK_STATE(*post_work) (SSL *s, WORK_STATE wst); - int (*get_construct_message_f) (SSL *s, WPACKET *pkt, - int (**confunc) (SSL *s, WPACKET *pkt), + WRITE_TRAN(*transition) (SSL_CONNECTION *s); + WORK_STATE(*pre_work) (SSL_CONNECTION *s, WORK_STATE wst); + WORK_STATE(*post_work) (SSL_CONNECTION *s, WORK_STATE wst); + int (*get_construct_message_f) (SSL_CONNECTION *s, + CON_FUNC_RETURN (**confunc) (SSL_CONNECTION *s, + WPACKET *pkt), int *mt); void (*cb) (const SSL *ssl, int type, int val) = NULL; - int (*confunc) (SSL *s, WPACKET *pkt); + CON_FUNC_RETURN (*confunc) (SSL_CONNECTION *s, WPACKET *pkt); int mt; WPACKET pkt; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); cb = get_callback(s); @@ -796,9 +835,9 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) if (cb != NULL) { /* Notify callback of an impending state change */ if (s->server) - cb(s, SSL_CB_ACCEPT_LOOP, 1); + cb(ssl, SSL_CB_ACCEPT_LOOP, 1); else - cb(s, SSL_CB_CONNECT_LOOP, 1); + cb(ssl, SSL_CB_CONNECT_LOOP, 1); } switch (transition(s)) { case WRITE_TRAN_CONTINUE: @@ -833,7 +872,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) case WORK_FINISHED_STOP: return SUB_STATE_END_HANDSHAKE; } - if (!get_construct_message_f(s, &pkt, &confunc, &mt)) { + if (!get_construct_message_f(s, &confunc, &mt)) { /* SSLfatal() already called */ return SUB_STATE_ERROR; } @@ -850,14 +889,14 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) return SUB_STATE_ERROR; } if (confunc != NULL) { - int tmpret; + CON_FUNC_RETURN tmpret; tmpret = confunc(s, &pkt); - if (tmpret <= 0) { + if (tmpret == CON_FUNC_ERROR) { WPACKET_cleanup(&pkt); check_fatal(s); return SUB_STATE_ERROR; - } else if (tmpret == 2) { + } else if (tmpret == CON_FUNC_DONT_SEND) { /* * The construction function decided not to construct the * message after all and continue. Skip sending. @@ -878,7 +917,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) /* Fall through */ case WRITE_STATE_SEND: - if (SSL_IS_DTLS(s) && st->use_timer) { + if (SSL_CONNECTION_IS_DTLS(s) && st->use_timer) { dtls1_start_timer(s); } ret = statem_do_write(s); @@ -918,7 +957,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) /* * Flush the write BIO */ -int statem_flush(SSL *s) +int statem_flush(SSL_CONNECTION *s) { s->rwstate = SSL_WRITING; if (BIO_flush(s->wbio) <= 0) { @@ -937,7 +976,7 @@ int statem_flush(SSL *s) * 1: Yes (application data allowed) * 0: No (application data not allowed) */ -int ossl_statem_app_data_allowed(SSL *s) +int ossl_statem_app_data_allowed(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -971,7 +1010,7 @@ int ossl_statem_app_data_allowed(SSL *s) * This function returns 1 if TLS exporter is ready to export keying * material, or 0 if otherwise. */ -int ossl_statem_export_allowed(SSL *s) +int ossl_statem_export_allowed(SSL_CONNECTION *s) { return s->s3.previous_server_finished_len != 0 && s->statem.hand_state != TLS_ST_SW_FINISHED; @@ -981,7 +1020,7 @@ int ossl_statem_export_allowed(SSL *s) * Return 1 if early TLS exporter is ready to export keying material, * or 0 if otherwise. */ -int ossl_statem_export_early_allowed(SSL *s) +int ossl_statem_export_early_allowed(SSL_CONNECTION *s) { /* * The early exporter secret is only present on the server if we diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 3cd1ee2d3d..cbf5a57beb 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -28,14 +28,21 @@ #include #include "internal/cryptlib.h" -static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); -static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); +static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s, + PACKET *pkt); +static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL_CONNECTION *s, + PACKET *pkt); -static ossl_inline int cert_req_allowed(SSL *s); -static int key_exchange_expected(SSL *s); -static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, +static ossl_inline int cert_req_allowed(SSL_CONNECTION *s); +static int key_exchange_expected(SSL_CONNECTION *s); +static int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt); +static ossl_inline int received_server_cert(SSL_CONNECTION *sc) +{ + return sc->session->peer_rpk != NULL || sc->session->peer != NULL; +} + /* * Is a CertificateRequest message allowed at the moment or not? * @@ -43,7 +50,7 @@ static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, * 1: Yes * 0: No */ -static ossl_inline int cert_req_allowed(SSL *s) +static ossl_inline int cert_req_allowed(SSL_CONNECTION *s) { /* TLS does not like anon-DH with client cert */ if ((s->version > SSL3_VERSION @@ -61,7 +68,7 @@ static ossl_inline int cert_req_allowed(SSL *s) * 1: Yes * 0: No */ -static int key_exchange_expected(SSL *s) +static int key_exchange_expected(SSL_CONNECTION *s) { long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; @@ -86,7 +93,7 @@ static int key_exchange_expected(SSL *s) * Return values are 1 for success (transition allowed) and 0 on error * (transition not allowed) */ -static int ossl_statem_client13_read_transition(SSL *s, int mt) +static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; @@ -133,6 +140,13 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_CERT; return 1; } +#ifndef OPENSSL_NO_COMP_ALG + if (mt == SSL3_MT_COMPRESSED_CERTIFICATE + && s->ext.compress_certificate_sent) { + st->hand_state = TLS_ST_CR_COMP_CERT; + return 1; + } +#endif } break; @@ -141,9 +155,17 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_CERT; return 1; } +#ifndef OPENSSL_NO_COMP_ALG + if (mt == SSL3_MT_COMPRESSED_CERTIFICATE + && s->ext.compress_certificate_sent) { + st->hand_state = TLS_ST_CR_COMP_CERT; + return 1; + } +#endif break; case TLS_ST_CR_CERT: + case TLS_ST_CR_COMP_CERT: if (mt == SSL3_MT_CERTIFICATE_VERIFY) { st->hand_state = TLS_ST_CR_CERT_VRFY; return 1; @@ -162,7 +184,7 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_CR_SESSION_TICKET; return 1; } - if (mt == SSL3_MT_KEY_UPDATE) { + if (mt == SSL3_MT_KEY_UPDATE && !SSL_IS_QUIC_HANDSHAKE(s)) { st->hand_state = TLS_ST_CR_KEY_UPDATE; return 1; } @@ -171,7 +193,8 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) /* Restore digest for PHA before adding message.*/ # error Internal DTLS version error #endif - if (!SSL_IS_DTLS(s) && s->post_handshake_auth == SSL_PHA_EXT_SENT) { + if (!SSL_CONNECTION_IS_DTLS(s) + && s->post_handshake_auth == SSL_PHA_EXT_SENT) { s->post_handshake_auth = SSL_PHA_REQUESTED; /* * In TLS, this is called before the message is added to the @@ -203,7 +226,7 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) * Return values are 1 for success (transition allowed) and 0 on error * (transition not allowed) */ -int ossl_statem_client_read_transition(SSL *s, int mt) +int ossl_statem_client_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; int ske_expected; @@ -212,7 +235,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) * Note that after writing the first ClientHello we don't know what version * we are going to negotiate yet, so we don't take this branch until later. */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (!ossl_statem_client13_read_transition(s, mt)) goto err; return 1; @@ -228,7 +251,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) return 1; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (mt == DTLS1_MT_HELLO_VERIFY_REQUEST) { st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST; return 1; @@ -260,7 +283,8 @@ int ossl_statem_client_read_transition(SSL *s, int mt) return 1; } } else { - if (SSL_IS_DTLS(s) && mt == DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (SSL_CONNECTION_IS_DTLS(s) + && mt == DTLS1_MT_HELLO_VERIFY_REQUEST) { st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST; return 1; } else if (s->version >= TLS1_VERSION @@ -305,6 +329,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) break; case TLS_ST_CR_CERT: + case TLS_ST_CR_COMP_CERT: /* * The CertificateStatus message is optional even if * |ext.status_expected| is set @@ -381,7 +406,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) err: /* No valid transition found */ - if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + if (SSL_CONNECTION_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) { BIO *rbio; /* @@ -390,7 +415,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) */ s->init_num = 0; s->rwstate = SSL_READING; - rbio = SSL_get_rbio(s); + rbio = SSL_get_rbio(SSL_CONNECTION_GET_SSL(s)); BIO_clear_retry_flags(rbio); BIO_set_retry_read(rbio); return 0; @@ -399,12 +424,19 @@ int ossl_statem_client_read_transition(SSL *s, int mt) return 0; } +static int do_compressed_cert(SSL_CONNECTION *sc) +{ + /* If we negotiated RPK, we won't try to compress it */ + return sc->ext.client_cert_type == TLSEXT_cert_type_x509 + && sc->ext.compress_certificate_from_peer[0] != TLSEXT_comp_cert_none; +} + /* * ossl_statem_client13_write_transition() works out what handshake state to * move to next when the TLSv1.3 client is writing messages to be sent to the * server. */ -static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) +static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -421,7 +453,10 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) case TLS_ST_CR_CERT_REQ: if (s->post_handshake_auth == SSL_PHA_REQUESTED) { - st->hand_state = TLS_ST_CW_CERT; + if (do_compressed_cert(s)) + st->hand_state = TLS_ST_CW_COMP_CERT; + else + st->hand_state = TLS_ST_CW_CERT; return WRITE_TRAN_CONTINUE; } /* @@ -443,9 +478,14 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) else if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 && s->hello_retry_request == SSL_HRR_NONE) st->hand_state = TLS_ST_CW_CHANGE; + else if (s->s3.tmp.cert_req == 0) + st->hand_state = TLS_ST_CW_FINISHED; + else if (do_compressed_cert(s)) + st->hand_state = TLS_ST_CW_COMP_CERT; else - st->hand_state = (s->s3.tmp.cert_req != 0) ? TLS_ST_CW_CERT - : TLS_ST_CW_FINISHED; + st->hand_state = TLS_ST_CW_CERT; + + s->ts_msg_read = ossl_time_now(); return WRITE_TRAN_CONTINUE; case TLS_ST_PENDING_EARLY_DATA_END: @@ -457,10 +497,15 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) case TLS_ST_CW_END_OF_EARLY_DATA: case TLS_ST_CW_CHANGE: - st->hand_state = (s->s3.tmp.cert_req != 0) ? TLS_ST_CW_CERT - : TLS_ST_CW_FINISHED; + if (s->s3.tmp.cert_req == 0) + st->hand_state = TLS_ST_CW_FINISHED; + else if (do_compressed_cert(s)) + st->hand_state = TLS_ST_CW_COMP_CERT; + else + st->hand_state = TLS_ST_CW_CERT; return WRITE_TRAN_CONTINUE; + case TLS_ST_CW_COMP_CERT: case TLS_ST_CW_CERT: /* If a non-empty Certificate we also send CertificateVerify */ st->hand_state = (s->s3.tmp.cert_req == 1) ? TLS_ST_CW_CERT_VRFY @@ -493,7 +538,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) * ossl_statem_client_write_transition() works out what handshake state to * move to next when the client is writing messages to be sent to the server. */ -WRITE_TRAN ossl_statem_client_write_transition(SSL *s) +WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -502,7 +547,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * version we are going to negotiate yet, so we don't take this branch until * later */ - if (SSL_IS_TLS13(s)) + if (SSL_CONNECTION_IS_TLS13(s)) return ossl_statem_client13_write_transition(s); switch (st->hand_state) { @@ -541,6 +586,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * No transition at the end of writing because we don't know what * we will be sent */ + s->ts_msg_write = ossl_time_now(); return WRITE_TRAN_FINISHED; case TLS_ST_CR_SRVR_HELLO: @@ -557,6 +603,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_EARLY_DATA: + s->ts_msg_write = ossl_time_now(); return WRITE_TRAN_FINISHED; case DTLS_ST_CR_HELLO_VERIFY_REQUEST: @@ -564,6 +611,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_CR_SRVR_DONE: + s->ts_msg_read = ossl_time_now(); if (s->s3.tmp.cert_req) st->hand_state = TLS_ST_CW_CERT; else @@ -608,7 +656,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) #if defined(OPENSSL_NO_NEXTPROTONEG) st->hand_state = TLS_ST_CW_FINISHED; #else - if (!SSL_IS_DTLS(s) && s->s3.npn_seen) + if (!SSL_CONNECTION_IS_DTLS(s) && s->s3.npn_seen) st->hand_state = TLS_ST_CW_NEXT_PROTO; else st->hand_state = TLS_ST_CW_FINISHED; @@ -644,7 +692,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * If we can renegotiate now then do so, otherwise wait for a more * convenient time. */ - if (ssl3_renegotiate_check(s, 1)) { + if (ssl3_renegotiate_check(SSL_CONNECTION_GET_SSL(s), 1)) { if (!tls_setup_handshake(s)) { /* SSLfatal() already called */ return WRITE_TRAN_ERROR; @@ -661,7 +709,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * Perform any pre work that needs to be done prior to sending a message from * the client to the server. */ -WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -672,17 +720,34 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) case TLS_ST_CW_CLNT_HELLO: s->shutdown = 0; - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* every DTLS ClientHello resets Finished MAC */ if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ return WORK_ERROR; } + } else if (s->ext.early_data == SSL_EARLY_DATA_REJECTED) { + /* + * This must be a second ClientHello after an HRR following an + * earlier rejected attempt to send early data. Since we were + * previously encrypting the early data we now need to reset the + * write record layer in order to write in plaintext again. + */ + if (!ssl_set_new_record_layer(s, + TLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_WRITE, + OSSL_RECORD_PROTECTION_LEVEL_NONE, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NULL, 0, NID_undef, NULL, NULL, + NULL)) { + /* SSLfatal already called */ + return WORK_ERROR; + } } break; case TLS_ST_CW_CHANGE: - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (s->hit) { /* * We're into the last flight so we don't retransmit these @@ -691,7 +756,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) st->use_timer = 0; } #ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + if (BIO_dgram_is_sctp(SSL_get_wbio(SSL_CONNECTION_GET_SSL(s)))) { /* Calls SSLfatal() as required */ return dtls_wait_for_dry(s); } @@ -725,9 +790,10 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst) * Perform any work that needs to be done after sending a message from the * client to the server. */ -WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); s->init_num = 0; @@ -756,21 +822,12 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) return WORK_MORE_A; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* Treat the next message as the first packet */ s->first_packet = 1; } break; - case TLS_ST_CW_END_OF_EARLY_DATA: - /* - * We set the enc_write_ctx back to NULL because we may end up writing - * in cleartext again if we get a HelloRetryRequest from the server. - */ - EVP_CIPHER_CTX_free(s->enc_write_ctx); - s->enc_write_ctx = NULL; - break; - case TLS_ST_CW_KEY_EXCH: if (tls_client_key_exchange_post_work(s) == 0) { /* SSLfatal() already called */ @@ -779,7 +836,8 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) break; case TLS_ST_CW_CHANGE: - if (SSL_IS_TLS13(s) || s->hello_retry_request == SSL_HRR_PENDING) + if (SSL_CONNECTION_IS_TLS13(s) + || s->hello_retry_request == SSL_HRR_PENDING) break; if (s->early_data_state == SSL_EARLY_DATA_CONNECTING && s->max_early_data > 0) { @@ -802,54 +860,54 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) else s->session->compress_meth = s->s3.tmp.new_compression->id; #endif - if (!s->method->ssl3_enc->setup_key_block(s)) { + if (!ssl->method->ssl3_enc->setup_key_block(s)) { /* SSLfatal() already called */ return WORK_ERROR; } - if (!s->method->ssl3_enc->change_cipher_state(s, + if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { /* SSLfatal() already called */ return WORK_ERROR; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { #ifndef OPENSSL_NO_SCTP if (s->hit) { /* * Change to new shared key of SCTP-Auth, will be ignored if * no SCTP used. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); } #endif - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + dtls1_increment_epoch(s, SSL3_CC_WRITE); } break; case TLS_ST_CW_FINISHED: #ifndef OPENSSL_NO_SCTP - if (wst == WORK_MORE_A && SSL_IS_DTLS(s) && s->hit == 0) { + if (wst == WORK_MORE_A && SSL_CONNECTION_IS_DTLS(s) && s->hit == 0) { /* * Change to new shared key of SCTP-Auth, will be ignored if * no SCTP used. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); } #endif if (statem_flush(s) != 1) return WORK_MORE_B; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (!tls13_save_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return WORK_ERROR; } if (s->post_handshake_auth != SSL_PHA_REQUESTED) { - if (!s->method->ssl3_enc->change_cipher_state(s, + if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { /* SSLfatal() already called */ return WORK_ERROR; @@ -879,7 +937,7 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) * 1: Success * 0: Error */ -int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, +int ossl_statem_client_construct_message(SSL_CONNECTION *s, confunc_f *confunc, int *mt) { OSSL_STATEM *st = &s->statem; @@ -891,7 +949,7 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, return 0; case TLS_ST_CW_CHANGE: - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) *confunc = dtls_construct_change_cipher_spec; else *confunc = tls_construct_change_cipher_spec; @@ -918,6 +976,13 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, *mt = SSL3_MT_CERTIFICATE; break; +#ifndef OPENSSL_NO_COMP_ALG + case TLS_ST_CW_COMP_CERT: + *confunc = tls_construct_client_compressed_certificate; + *mt = SSL3_MT_COMPRESSED_CERTIFICATE; + break; +#endif + case TLS_ST_CW_KEY_EXCH: *confunc = tls_construct_client_key_exchange; *mt = SSL3_MT_CLIENT_KEY_EXCHANGE; @@ -952,7 +1017,7 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, * Returns the maximum allowed length for the current message that we are * reading. Excludes the message header. */ -size_t ossl_statem_client_max_message_size(SSL *s) +size_t ossl_statem_client_max_message_size(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -967,11 +1032,12 @@ size_t ossl_statem_client_max_message_size(SSL *s) case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return HELLO_VERIFY_REQUEST_MAX_LENGTH; + case TLS_ST_CR_COMP_CERT: case TLS_ST_CR_CERT: return s->max_cert_list; case TLS_ST_CR_CERT_VRFY: - return SSL3_RT_MAX_PLAIN_LENGTH; + return CERTIFICATE_VERIFY_MAX_LENGTH; case TLS_ST_CR_CERT_STATUS: return SSL3_RT_MAX_PLAIN_LENGTH; @@ -996,8 +1062,8 @@ size_t ossl_statem_client_max_message_size(SSL *s) return CCS_MAX_LENGTH; case TLS_ST_CR_SESSION_TICKET: - return (SSL_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13 - : SESSION_TICKET_MAX_LENGTH_TLS12; + return (SSL_CONNECTION_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13 + : SESSION_TICKET_MAX_LENGTH_TLS12; case TLS_ST_CR_FINISHED: return FINISHED_MAX_LENGTH; @@ -1013,7 +1079,8 @@ size_t ossl_statem_client_max_message_size(SSL *s) /* * Process a message that the client has received from the server. */ -MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL_CONNECTION *s, + PACKET *pkt) { OSSL_STATEM *st = &s->statem; @@ -1032,6 +1099,11 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) case TLS_ST_CR_CERT: return tls_process_server_certificate(s, pkt); +#ifndef OPENSSL_NO_COMP_ALG + case TLS_ST_CR_COMP_CERT: + return tls_process_server_compressed_certificate(s, pkt); +#endif + case TLS_ST_CR_CERT_VRFY: return tls_process_cert_verify(s, pkt); @@ -1071,7 +1143,8 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) * Perform any further processing required following the receipt of a message * from the server */ -WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_client_post_process_message(SSL_CONNECTION *s, + WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -1082,6 +1155,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) return WORK_ERROR; case TLS_ST_CR_CERT: + case TLS_ST_CR_COMP_CERT: return tls_post_process_server_certificate(s, wst); case TLS_ST_CR_CERT_VRFY: @@ -1090,7 +1164,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) } } -int tls_construct_client_hello(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pkt) { unsigned char *p; size_t sess_id_len; @@ -1100,12 +1174,13 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) #endif SSL_SESSION *sess = s->session; unsigned char *session_id; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Work out what SSL/TLS/DTLS version to use */ protverr = ssl_set_client_hello_version(s); if (protverr != 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, protverr); - return 0; + return CON_FUNC_ERROR; } if (sess == NULL @@ -1114,7 +1189,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) if (s->hello_retry_request == SSL_HRR_NONE && !ssl_get_new_session(s, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } } /* else use the pre-loaded session */ @@ -1125,7 +1200,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) * for DTLS if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { size_t idx; i = 1; for (idx = 0; idx < sizeof(s->s3.client_random); idx++) { @@ -1141,7 +1216,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3.client_random), DOWNGRADE_NONE) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /*- @@ -1180,7 +1255,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) if (!WPACKET_put_bytes_u16(pkt, s->client_version) || !WPACKET_memcpy(pkt, s->s3.client_random, SSL3_RANDOM_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* Session ID */ @@ -1192,10 +1267,10 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) s->tmp_session_id_len = sess_id_len; session_id = s->tmp_session_id; if (s->hello_retry_request == SSL_HRR_NONE - && RAND_bytes_ex(s->ctx->libctx, s->tmp_session_id, + && RAND_bytes_ex(sctx->libctx, s->tmp_session_id, sess_id_len, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } else { sess_id_len = 0; @@ -1213,49 +1288,51 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) sess_id_len)) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* cookie stuff for DTLS */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (s->d1->cookie_len > sizeof(s->d1->cookie) || !WPACKET_sub_memcpy_u8(pkt, s->d1->cookie, s->d1->cookie_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } /* Ciphers supported */ if (!WPACKET_start_sub_packet_u16(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } - if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), pkt)) { + if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(SSL_CONNECTION_GET_SSL(s)), + pkt)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } if (!WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* COMPRESSION */ if (!WPACKET_start_sub_packet_u8(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s) - && s->ctx->comp_methods - && (SSL_IS_DTLS(s) || s->s3.tmp.max_ver < TLS1_3_VERSION)) { - int compnum = sk_SSL_COMP_num(s->ctx->comp_methods); + && sctx->comp_methods + && (SSL_CONNECTION_IS_DTLS(s) + || s->s3.tmp.max_ver < TLS1_3_VERSION)) { + int compnum = sk_SSL_COMP_num(sctx->comp_methods); for (i = 0; i < compnum; i++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + comp = sk_SSL_COMP_value(sctx->comp_methods, i); if (!WPACKET_put_bytes_u8(pkt, comp->id)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } } @@ -1263,19 +1340,19 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) /* Add the NULL method */ if (!WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* TLS extensions */ if (!tls_construct_extensions(s, pkt, SSL_EXT_CLIENT_HELLO, NULL, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } -MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt) { size_t cookie_len; PACKET cookiepkt; @@ -1301,11 +1378,13 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt) return MSG_PROCESS_FINISHED_READING; } -static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) +static int set_client_ciphersuite(SSL_CONNECTION *s, + const unsigned char *cipherchars) { STACK_OF(SSL_CIPHER) *sk; const SSL_CIPHER *c; int i; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); c = ssl_get_cipher_by_char(s, cipherchars, 0); if (c == NULL) { @@ -1330,7 +1409,7 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) return 0; } - if (SSL_IS_TLS13(s) && s->s3.tmp.new_cipher != NULL + if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.new_cipher != NULL && s->s3.tmp.new_cipher->id != c->id) { /* ServerHello selected a different ciphersuite to that in the HRR */ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED); @@ -1345,15 +1424,15 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) if (s->session->cipher != NULL) s->session->cipher_id = s->session->cipher->id; if (s->hit && (s->session->cipher_id != c->id)) { - if (SSL_IS_TLS13(s)) { - const EVP_MD *md = ssl_md(s->ctx, c->algorithm2); + if (SSL_CONNECTION_IS_TLS13(s)) { + const EVP_MD *md = ssl_md(sctx, c->algorithm2); /* * In TLSv1.3 it is valid for the server to select a different * ciphersuite as long as the hash is the same. */ if (md == NULL - || md != ssl_md(s->ctx, s->session->cipher->algorithm2)) { + || md != ssl_md(sctx, s->session->cipher->algorithm2)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED); return 0; @@ -1373,7 +1452,7 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) return 1; } -MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) { PACKET session_id, extpkt; size_t session_id_len; @@ -1383,6 +1462,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) unsigned int sversion; unsigned int context; RAW_EXTENSION *extensions = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); #ifndef OPENSSL_NO_COMP SSL_COMP *comp; #endif @@ -1402,6 +1482,11 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto err; } s->hello_retry_request = SSL_HRR_PENDING; + /* Tell the record layer that we know we're going to get TLSv1.3 */ + if (!ssl_set_record_protocol_version(s, s->version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } hrr = 1; if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -1460,7 +1545,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) } } - if (SSL_IS_TLS13(s) || hrr) { + if (SSL_CONNECTION_IS_TLS13(s) || hrr) { if (compression != 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_COMPRESSION_ALGORITHM); @@ -1488,8 +1573,8 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * Now we have chosen the version we need to check again that the extensions * are appropriate for this version. */ - context = SSL_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO - : SSL_EXT_TLS1_2_SERVER_HELLO; + context = SSL_CONNECTION_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO + : SSL_EXT_TLS1_2_SERVER_HELLO; if (!tls_validate_all_contexts(s, context, extensions)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); goto err; @@ -1497,7 +1582,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) s->hit = 0; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * In TLSv1.3 a ServerHello message signals a key change so the end of * the message must be on a record boundary. @@ -1536,8 +1621,9 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * backwards compat reasons */ int master_key_length; + master_key_length = sizeof(s->session->master_key); - if (s->ext.session_secret_cb(s, s->session->master_key, + if (s->ext.session_secret_cb(ssl, s->session->master_key, &master_key_length, NULL, &pref_cipher, s->ext.session_secret_cb_arg) @@ -1589,7 +1675,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * echo of what we originally sent in the ClientHello and should not be * used for resumption. */ - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { s->session->session_id_length = session_id_len; /* session_id_len could be 0 */ if (session_id_len > 0) @@ -1642,7 +1728,8 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COMPRESSION_DISABLED); goto err; } else { - comp = ssl3_comp_find(s->ctx->comp_methods, compression); + comp = ssl3_comp_find(SSL_CONNECTION_GET_CTX(s)->comp_methods, + compression); } if (compression != 0 && comp == NULL) { @@ -1660,7 +1747,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) } #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && s->hit) { + if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -1677,7 +1764,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG) labellen += 1; - if (SSL_export_keying_material(s, sctpauthkey, + if (SSL_export_keying_material(ssl, sctpauthkey, sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { @@ -1685,7 +1772,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) goto err; } - BIO_ctrl(SSL_get_wbio(s), + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); } @@ -1695,12 +1782,29 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * In TLSv1.3 we have some post-processing to change cipher state, otherwise * we're done with this message */ - if (SSL_IS_TLS13(s) - && (!s->method->ssl3_enc->setup_key_block(s) - || !s->method->ssl3_enc->change_cipher_state(s, - SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ))) { - /* SSLfatal() already called */ - goto err; + if (SSL_CONNECTION_IS_TLS13(s)) { + if (!ssl->method->ssl3_enc->setup_key_block(s) + || !ssl->method->ssl3_enc->change_cipher_state(s, + SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ)) { + /* SSLfatal() already called */ + goto err; + } + /* + * If we're not doing early-data and we're not going to send a dummy CCS + * (i.e. no middlebox compat mode) then we can change the write keys + * immediately. Otherwise we have to defer this until after all possible + * early data is written. We could just always defer until the last + * moment except QUIC needs it done at the same time as the read keys + * are changed. Since QUIC doesn't do TLS early data or need middlebox + * compat this doesn't cause a problem. + */ + if (s->early_data_state == SSL_EARLY_DATA_NONE + && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0 + && !ssl->method->ssl3_enc->change_cipher_state(s, + SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { + /* SSLfatal() already called */ + goto err; + } } OPENSSL_free(extensions); @@ -1710,17 +1814,27 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, +static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s, PACKET *extpkt) { RAW_EXTENSION *extensions = NULL; /* - * If we were sending early_data then the enc_write_ctx is now invalid and - * should not be used. + * If we were sending early_data then any alerts should not be sent using + * the old wrlmethod. */ - EVP_CIPHER_CTX_free(s->enc_write_ctx); - s->enc_write_ctx = NULL; + if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING + && !ssl_set_new_record_layer(s, + TLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_WRITE, + OSSL_RECORD_PROTECTION_LEVEL_NONE, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NULL, 0, NID_undef, NULL, NULL, NULL)) { + /* SSLfatal already called */ + goto err; + } + /* We are definitely going to be using TLSv1.3 */ + s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, TLS1_3_VERSION); if (!tls_collect_extensions(s, extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, &extensions, NULL, 1) @@ -1769,21 +1883,106 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, return MSG_PROCESS_ERROR; } +MSG_PROCESS_RETURN tls_process_server_rpk(SSL_CONNECTION *sc, PACKET *pkt) +{ + EVP_PKEY *peer_rpk; + + if (!tls_process_rpk(sc, pkt, &peer_rpk)) { + /* SSLfatal() already called */ + return MSG_PROCESS_ERROR; + } + + if (peer_rpk == NULL) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_CERTIFICATE); + return MSG_PROCESS_ERROR; + } + + EVP_PKEY_free(sc->session->peer_rpk); + sc->session->peer_rpk = peer_rpk; + + return MSG_PROCESS_CONTINUE_PROCESSING; +} + +static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc, + WORK_STATE wst) +{ + size_t certidx; + const SSL_CERT_LOOKUP *clu; + + if (sc->session->peer_rpk == NULL) { + SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, + SSL_R_INVALID_RAW_PUBLIC_KEY); + return WORK_ERROR; + } + + if (sc->rwstate == SSL_RETRY_VERIFY) + sc->rwstate = SSL_NOTHING; + if (ssl_verify_rpk(sc, sc->session->peer_rpk) > 0 + && sc->rwstate == SSL_RETRY_VERIFY) + return WORK_MORE_A; + + if ((clu = ssl_cert_lookup_by_pkey(sc->session->peer_rpk, &certidx, + SSL_CONNECTION_GET_CTX(sc))) == NULL) { + SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return WORK_ERROR; + } + + /* + * Check certificate type is consistent with ciphersuite. For TLS 1.3 + * skip check since TLS 1.3 ciphersuites can be used with any certificate + * type. + */ + if (!SSL_CONNECTION_IS_TLS13(sc)) { + if ((clu->amask & sc->s3.tmp.new_cipher->algorithm_auth) == 0) { + SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_RPK_TYPE); + return WORK_ERROR; + } + } + + /* Ensure there is no peer/peer_chain */ + X509_free(sc->session->peer); + sc->session->peer = NULL; + sk_X509_pop_free(sc->session->peer_chain, X509_free); + sc->session->peer_chain = NULL; + sc->session->verify_result = sc->verify_result; + + /* Save the current hash state for when we receive the CertificateVerify */ + if (SSL_CONNECTION_IS_TLS13(sc) + && !ssl_handshake_hash(sc, sc->cert_verify_hash, + sizeof(sc->cert_verify_hash), + &sc->cert_verify_hash_len)) { + /* SSLfatal() already called */ + return WORK_ERROR; + } + + return WORK_FINISHED_CONTINUE; +} + /* prepare server cert verification by setting s->session->peer_chain from pkt */ -MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s, + PACKET *pkt) { unsigned long cert_list_len, cert_len; X509 *x = NULL; const unsigned char *certstart, *certbytes; size_t chainidx; unsigned int context = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + + if (s->ext.server_cert_type == TLSEXT_cert_type_rpk) + return tls_process_server_rpk(s, pkt); + if (s->ext.server_cert_type != TLSEXT_cert_type_x509) { + SSLfatal(s, SSL_AD_UNSUPPORTED_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto err; + } if ((s->session->peer_chain = sk_X509_new_null()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } - if ((SSL_IS_TLS13(s) && !PACKET_get_1(pkt, &context)) + if ((SSL_CONNECTION_IS_TLS13(s) && !PACKET_get_1(pkt, &context)) || context != 0 || !PACKET_get_net_3(pkt, &cert_list_len) || PACKET_remaining(pkt) != cert_list_len @@ -1799,10 +1998,9 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = X509_new_ex(s->ctx->libctx, s->ctx->propq); + x = X509_new_ex(sctx->libctx, sctx->propq); if (x == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_MALLOC_FAILURE); - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_ASN1_LIB); goto err; } if (d2i_X509(&x, (const unsigned char **)&certbytes, @@ -1816,7 +2014,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) goto err; } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { RAW_EXTENSION *rawexts = NULL; PACKET extensions; @@ -1838,7 +2036,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) } if (!sk_X509_push(s->session->peer_chain, x)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } x = NULL; @@ -1847,7 +2045,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) err: X509_free(x); - sk_X509_pop_free(s->session->peer_chain, X509_free); + OSSL_STACK_OF_X509_free(s->session->peer_chain); s->session->peer_chain = NULL; return MSG_PROCESS_ERROR; } @@ -1857,7 +2055,8 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) * On success set s->session->peer and s->session->verify_result. * Else the peer certificate verification callback may request retry. */ -WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) +WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s, + WORK_STATE wst) { X509 *x; EVP_PKEY *pkey = NULL; @@ -1865,6 +2064,9 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) size_t certidx; int i; + if (s->ext.server_cert_type == TLSEXT_cert_type_rpk) + return tls_post_process_server_rpk(s, wst); + if (s->rwstate == SSL_RETRY_VERIFY) s->rwstate = SSL_NOTHING; i = ssl_verify_cert_chain(s, s->session->peer_chain); @@ -1906,7 +2108,8 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) return WORK_ERROR; } - if ((clu = ssl_cert_lookup_by_pkey(pkey, &certidx)) == NULL) { + if ((clu = ssl_cert_lookup_by_pkey(pkey, &certidx, + SSL_CONNECTION_GET_CTX(s))) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return WORK_ERROR; } @@ -1915,7 +2118,7 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) * skip check since TLS 1.3 ciphersuites can be used with any certificate * type. */ - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { if ((clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CERTIFICATE_TYPE); return WORK_ERROR; @@ -1926,9 +2129,12 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) X509_up_ref(x); s->session->peer = x; s->session->verify_result = s->verify_result; + /* Ensure there is no RPK */ + EVP_PKEY_free(s->session->peer_rpk); + s->session->peer_rpk = NULL; /* Save the current hash state for when we receive the CertificateVerify */ - if (SSL_IS_TLS13(s) + if (SSL_CONNECTION_IS_TLS13(s) && !ssl_handshake_hash(s, s->cert_verify_hash, sizeof(s->cert_verify_hash), &s->cert_verify_hash_len)) { @@ -1938,7 +2144,22 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; } -static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) +#ifndef OPENSSL_NO_COMP_ALG +MSG_PROCESS_RETURN tls_process_server_compressed_certificate(SSL_CONNECTION *sc, PACKET *pkt) +{ + MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; + PACKET tmppkt; + BUF_MEM *buf = BUF_MEM_new(); + + if (tls13_process_compressed_certificate(sc, pkt, &tmppkt, buf) != MSG_PROCESS_ERROR) + ret = tls_process_server_certificate(sc, &tmppkt); + + BUF_MEM_free(buf); + return ret; +} +#endif + +static int tls_process_ske_psk_preamble(SSL_CONNECTION *s, PACKET *pkt) { #ifndef OPENSSL_NO_PSK PACKET psk_identity_hint; @@ -1977,7 +2198,7 @@ static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) #endif } -static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) +static int tls_process_ske_srp(SSL_CONNECTION *s, PACKET *pkt, EVP_PKEY **pkey) { #ifndef OPENSSL_NO_SRP PACKET prime, generator, salt, server_pub; @@ -2013,7 +2234,7 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) /* We must check if there is a certificate */ if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) - *pkey = X509_get0_pubkey(s->session->peer); + *pkey = tls_get_peer_pkey(s); return 1; #else @@ -2022,7 +2243,7 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) #endif } -static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) +static int tls_process_ske_dhe(SSL_CONNECTION *s, PACKET *pkt, EVP_PKEY **pkey) { PACKET prime, generator, pub_key; EVP_PKEY *peer_tmp = NULL; @@ -2030,6 +2251,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) EVP_PKEY_CTX *pctx = NULL; OSSL_PARAM *params = NULL; OSSL_PARAM_BLD *tmpl = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); int ret = 0; if (!PACKET_get_length_prefixed_2(pkt, &prime) @@ -2060,7 +2282,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) goto err; } - pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, "DH", sctx->propq); if (pctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -2072,7 +2294,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) } EVP_PKEY_CTX_free(pctx); - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, peer_tmp, sctx->propq); if (pctx == NULL /* * EVP_PKEY_param_check() will verify that the DH params are using @@ -2101,7 +2323,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) * public keys. We should have a less ad-hoc way of doing this */ if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) - *pkey = X509_get0_pubkey(s->session->peer); + *pkey = tls_get_peer_pkey(s); /* else anonymous DH, so no certificate or pkey. */ ret = 1; @@ -2118,7 +2340,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return ret; } -static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) +static int tls_process_ske_ecdhe(SSL_CONNECTION *s, PACKET *pkt, EVP_PKEY **pkey) { PACKET encoded_pt; unsigned int curve_type, curve_id; @@ -2166,9 +2388,9 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) * and ECDSA. */ if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aECDSA) - *pkey = X509_get0_pubkey(s->session->peer); + *pkey = tls_get_peer_pkey(s); else if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aRSA) - *pkey = X509_get0_pubkey(s->session->peer); + *pkey = tls_get_peer_pkey(s); /* else anonymous ECDH, so no certificate or pkey. */ /* Cache the agreed upon group in the SSL_SESSION */ @@ -2176,13 +2398,14 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return 1; } -MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_key_exchange(SSL_CONNECTION *s, PACKET *pkt) { long alg_k; EVP_PKEY *pkey = NULL; EVP_MD_CTX *md_ctx = NULL; EVP_PKEY_CTX *pctx = NULL; PACKET save_param_start, signature; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); alg_k = s->s3.tmp.new_cipher->algorithm_mkey; @@ -2256,7 +2479,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } - if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { + if (!tls1_lookup_md(sctx, s->s3.tmp.peer_sigalg, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); goto err; @@ -2273,13 +2496,13 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (EVP_DigestVerifyInit_ex(md_ctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; @@ -2332,15 +2555,20 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s, + PACKET *pkt) { - size_t i; - /* Clear certificate validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) - s->s3.tmp.valid_flags[i] = 0; + if (s->s3.tmp.valid_flags != NULL) + memset(s->s3.tmp.valid_flags, 0, s->ssl_pkey_num * sizeof(uint32_t)); + else + s->s3.tmp.valid_flags = OPENSSL_zalloc(s->ssl_pkey_num * sizeof(uint32_t)); + + /* Give up for good if allocation didn't work */ + if (s->s3.tmp.valid_flags == NULL) + return 0; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { PACKET reqctx, extensions; RAW_EXTENSION *rawexts = NULL; @@ -2417,7 +2645,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } if (!tls1_process_sigalgs(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); return MSG_PROCESS_ERROR; } } @@ -2445,13 +2673,15 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) * SSL_get1_peer_certificate() returns something sensible in * client_cert_cb. */ - if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED) + if (SSL_CONNECTION_IS_TLS13(s) + && s->post_handshake_auth != SSL_PHA_REQUESTED) return MSG_PROCESS_CONTINUE_READING; return MSG_PROCESS_CONTINUE_PROCESSING; } -MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, + PACKET *pkt) { unsigned int ticklen; unsigned long ticket_lifetime_hint, age_add = 0; @@ -2459,16 +2689,18 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) RAW_EXTENSION *exts = NULL; PACKET nonce; EVP_MD *sha256 = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); PACKET_null_init(&nonce); if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint) - || (SSL_IS_TLS13(s) + || (SSL_CONNECTION_IS_TLS13(s) && (!PACKET_get_net_4(pkt, &age_add) || !PACKET_get_length_prefixed_1(pkt, &nonce))) || !PACKET_get_net_2(pkt, &ticklen) - || (SSL_IS_TLS13(s) ? (ticklen == 0 || PACKET_remaining(pkt) < ticklen) - : PACKET_remaining(pkt) != ticklen)) { + || (SSL_CONNECTION_IS_TLS13(s) ? (ticklen == 0 + || PACKET_remaining(pkt) < ticklen) + : PACKET_remaining(pkt) != ticklen)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -2489,7 +2721,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * post-handshake and the session may have already gone into the session * cache. */ - if (SSL_IS_TLS13(s) || s->session->session_id_length > 0) { + if (SSL_CONNECTION_IS_TLS13(s) || s->session->session_id_length > 0) { SSL_SESSION *new_sess; /* @@ -2497,12 +2729,12 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * one */ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); goto err; } if ((s->session_ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) != 0 - && !SSL_IS_TLS13(s)) { + && !SSL_CONNECTION_IS_TLS13(s)) { /* * In TLSv1.2 and below the arrival of a new tickets signals that * any old ticket we were using is now out of date, so we remove the @@ -2515,7 +2747,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session = new_sess; } - s->session->time = time(NULL); + s->session->time = ossl_time_now(); ssl_session_calculate_timeout(s->session); OPENSSL_free(s->session->ext.tick); @@ -2524,7 +2756,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session->ext.tick = OPENSSL_malloc(ticklen); if (s->session->ext.tick == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } if (!PACKET_copy_bytes(pkt, s->session->ext.tick, ticklen)) { @@ -2536,7 +2768,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session->ext.tick_age_add = age_add; s->session->ext.ticklen = ticklen; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { PACKET extpkt; if (!PACKET_as_length_prefixed_2(pkt, &extpkt) @@ -2567,7 +2799,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * elsewhere in OpenSSL. The session ID is set to the SHA256 hash of the * ticket. */ - sha256 = EVP_MD_fetch(s->ctx->libctx, "SHA2-256", s->ctx->propq); + sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq); if (sha256 == NULL) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); @@ -2589,7 +2821,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session->not_resumable = 0; /* This is a standalone message in TLSv1.3, so there is no more to read */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { const EVP_MD *md = ssl_handshake_md(s); int hashleni = EVP_MD_get_size(md); size_t hashlen; @@ -2630,7 +2862,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * In TLSv1.3 this is called from the extensions code, otherwise it is used to * parse a separate message. Returns 1 on success or 0 on failure */ -int tls_process_cert_status_body(SSL *s, PACKET *pkt) +int tls_process_cert_status_body(SSL_CONNECTION *s, PACKET *pkt) { size_t resplen; unsigned int type; @@ -2648,7 +2880,7 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt) s->ext.ocsp.resp = OPENSSL_malloc(resplen); if (s->ext.ocsp.resp == NULL) { s->ext.ocsp.resp_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } s->ext.ocsp.resp_len = resplen; @@ -2661,7 +2893,7 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt) } -MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_cert_status(SSL_CONNECTION *s, PACKET *pkt) { if (!tls_process_cert_status_body(s, pkt)) { /* SSLfatal() already called */ @@ -2677,8 +2909,10 @@ MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) * In <=TLS1.2 this is after the ServerDone message. Returns 1 on success or 0 * on failure. */ -int tls_process_initial_server_flight(SSL *s) +int tls_process_initial_server_flight(SSL_CONNECTION *s) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + /* * at this point we check that we have the required stuff from * the server @@ -2694,8 +2928,9 @@ int tls_process_initial_server_flight(SSL *s) * message, or NULL and -1 otherwise */ if (s->ext.status_type != TLSEXT_STATUSTYPE_nothing - && s->ctx->ext.status_cb != NULL) { - int ret = s->ctx->ext.status_cb(s, s->ctx->ext.status_arg); + && sctx->ext.status_cb != NULL) { + int ret = sctx->ext.status_cb(SSL_CONNECTION_GET_SSL(s), + sctx->ext.status_arg); if (ret == 0) { SSLfatal(s, SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE, @@ -2721,7 +2956,7 @@ int tls_process_initial_server_flight(SSL *s) return 1; } -MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_server_done(SSL_CONNECTION *s, PACKET *pkt) { if (PACKET_remaining(pkt) > 0) { /* should contain no data */ @@ -2745,7 +2980,7 @@ MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) return MSG_PROCESS_FINISHED_READING; } -static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) +static int tls_construct_cke_psk_preamble(SSL_CONNECTION *s, WPACKET *pkt) { #ifndef OPENSSL_NO_PSK int ret = 0; @@ -2768,7 +3003,8 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) memset(identity, 0, sizeof(identity)); - psklen = s->psk_client_callback(s, s->session->psk_identity_hint, + psklen = s->psk_client_callback(SSL_CONNECTION_GET_SSL(s), + s->session->psk_identity_hint, identity, sizeof(identity) - 1, psk, sizeof(psk)); @@ -2790,7 +3026,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) tmppsk = OPENSSL_memdup(psk, psklen); tmpidentity = OPENSSL_strdup(identity); if (tmppsk == NULL || tmpidentity == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } @@ -2822,7 +3058,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) #endif } -static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) +static int tls_construct_cke_rsa(SSL_CONNECTION *s, WPACKET *pkt) { unsigned char *encdata = NULL; EVP_PKEY *pkey = NULL; @@ -2830,8 +3066,9 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) size_t enclen; unsigned char *pms = NULL; size_t pmslen = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - if (s->session->peer == NULL) { + if (!received_server_cert(s)) { /* * We should always have a server certificate with SSL_kRSA. */ @@ -2839,7 +3076,11 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) return 0; } - pkey = X509_get0_pubkey(s->session->peer); + if ((pkey = tls_get_peer_pkey(s)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + if (!EVP_PKEY_is_a(pkey, "RSA")) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; @@ -2848,14 +3089,14 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) pmslen = SSL_MAX_MASTER_KEY_LENGTH; pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } pms[0] = s->client_version >> 8; pms[1] = s->client_version & 0xff; - if (RAND_bytes_ex(s->ctx->libctx, pms + 2, pmslen - 2, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if (RAND_bytes_ex(sctx->libctx, pms + 2, pmslen - 2, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_RAND_LIB); goto err; } @@ -2865,7 +3106,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) goto err; } - pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pkey, s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pkey, sctx->propq); if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); @@ -2902,7 +3143,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) return 0; } -static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) +static int tls_construct_cke_dhe(SSL_CONNECTION *s, WPACKET *pkt) { EVP_PKEY *ckey = NULL, *skey = NULL; unsigned char *keybytes = NULL; @@ -2965,7 +3206,7 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) return ret; } -static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) +static int tls_construct_cke_ecdhe(SSL_CONNECTION *s, WPACKET *pkt) { unsigned char *encodedPoint = NULL; size_t encoded_pt_len = 0; @@ -2980,7 +3221,7 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) ckey = ssl_generate_pkey(s, skey); if (ckey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); goto err; } @@ -3009,12 +3250,12 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) return ret; } -static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) +static int tls_construct_cke_gost(SSL_CONNECTION *s, WPACKET *pkt) { #ifndef OPENSSL_NO_GOST /* GOST key exchange message creation */ EVP_PKEY_CTX *pkey_ctx = NULL; - X509 *peer_cert; + EVP_PKEY *pkey = NULL; size_t msglen; unsigned int md_len; unsigned char shared_ukm[32], tmp[256]; @@ -3022,6 +3263,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) int dgst_nid = NID_id_GostR3411_94; unsigned char *pms = NULL; size_t pmslen = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if ((s->s3.tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0) dgst_nid = NID_id_GostR3411_2012_256; @@ -3029,18 +3271,17 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) /* * Get server certificate PKEY and create ctx from it */ - peer_cert = s->session->peer; - if (peer_cert == NULL) { + if ((pkey = tls_get_peer_pkey(s)) == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); return 0; } - pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, - X509_get0_pubkey(peer_cert), - s->ctx->propq); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, + pkey, + sctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } /* @@ -3053,14 +3294,14 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) pmslen = 32; pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 /* Generate session key */ - || RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { + || RAND_bytes_ex(sctx->libctx, pms, pmslen, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; }; @@ -3120,7 +3361,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) } #ifndef OPENSSL_NO_GOST -int ossl_gost18_cke_cipher_nid(const SSL *s) +int ossl_gost18_cke_cipher_nid(const SSL_CONNECTION *s) { if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) return NID_magma_ctr; @@ -3130,11 +3371,13 @@ int ossl_gost18_cke_cipher_nid(const SSL *s) return NID_undef; } -int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf) +int ossl_gost_ukm(const SSL_CONNECTION *s, unsigned char *dgst_buf) { - EVP_MD_CTX * hash = NULL; + EVP_MD_CTX *hash = NULL; unsigned int md_len; - const EVP_MD *md = ssl_evp_md_fetch(s->ctx->libctx, NID_id_GostR3411_2012_256, s->ctx->propq); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const EVP_MD *md = ssl_evp_md_fetch(sctx->libctx, NID_id_GostR3411_2012_256, + sctx->propq); if (md == NULL) return 0; @@ -3155,18 +3398,19 @@ int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf) } #endif -static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) +static int tls_construct_cke_gost18(SSL_CONNECTION *s, WPACKET *pkt) { #ifndef OPENSSL_NO_GOST /* GOST 2018 key exchange message creation */ unsigned char rnd_dgst[32]; unsigned char *encdata = NULL; EVP_PKEY_CTX *pkey_ctx = NULL; - X509 *peer_cert; + EVP_PKEY *pkey; unsigned char *pms = NULL; size_t pmslen = 0; size_t msglen; int cipher_nid = ossl_gost18_cke_cipher_nid(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (cipher_nid == NID_undef) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -3182,32 +3426,31 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) pmslen = 32; pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } - if (RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { + if (RAND_bytes_ex(sctx->libctx, pms, pmslen, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* Get server certificate PKEY and create ctx from it */ - peer_cert = s->session->peer; - if (peer_cert == NULL) { + if ((pkey = tls_get_peer_pkey(s)) == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); goto err; } - pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, - X509_get0_pubkey(peer_cert), - s->ctx->propq); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, + pkey, + sctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) { + if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; }; @@ -3252,7 +3495,7 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) #endif } -static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) +static int tls_construct_cke_srp(SSL_CONNECTION *s, WPACKET *pkt) { #ifndef OPENSSL_NO_SRP unsigned char *abytes = NULL; @@ -3268,7 +3511,7 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) OPENSSL_free(s->session->srp_username); s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login); if (s->session->srp_username == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } @@ -3279,7 +3522,8 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) #endif } -int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_client_key_exchange(SSL_CONNECTION *s, + WPACKET *pkt) { unsigned long alg_k; @@ -3316,7 +3560,7 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) goto err; } - return 1; + return CON_FUNC_SUCCESS; err: OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); s->s3.tmp.pms = NULL; @@ -3326,10 +3570,10 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) s->s3.tmp.psk = NULL; s->s3.tmp.psklen = 0; #endif - return 0; + return CON_FUNC_ERROR; } -int tls_client_key_exchange_post_work(SSL *s) +int tls_client_key_exchange_post_work(SSL_CONNECTION *s) { unsigned char *pms = NULL; size_t pmslen = 0; @@ -3349,7 +3593,7 @@ int tls_client_key_exchange_post_work(SSL *s) #endif if (pms == NULL && !(s->s3.tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_PASSED_INVALID_ARGUMENT); goto err; } if (!ssl_generate_master_secret(s, pms, pmslen, 1)) { @@ -3363,10 +3607,11 @@ int tls_client_key_exchange_post_work(SSL *s) pmslen = 0; #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* * Add new shared key for SCTP-Auth, will be ignored if no SCTP @@ -3380,14 +3625,14 @@ int tls_client_key_exchange_post_work(SSL *s) if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG) labellen += 1; - if (SSL_export_keying_material(s, sctpauthkey, + if (SSL_export_keying_material(ssl, sctpauthkey, sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); } #endif @@ -3405,7 +3650,7 @@ int tls_client_key_exchange_post_work(SSL *s) * cert exists, if we have a suitable digest for TLS 1.2 if static DH client * certificates can be used and optionally checks suitability for Suite B. */ -static int ssl3_check_client_certificate(SSL *s) +static int ssl3_check_client_certificate(SSL_CONNECTION *s) { /* If no suitable signature algorithm can't use certificate */ if (!tls_choose_sigalg(s, 0) || s->s3.tmp.sigalg == NULL) @@ -3420,16 +3665,17 @@ static int ssl3_check_client_certificate(SSL *s) return 1; } -WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) +WORK_STATE tls_prepare_client_certificate(SSL_CONNECTION *s, WORK_STATE wst) { X509 *x509 = NULL; EVP_PKEY *pkey = NULL; int i; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (wst == WORK_MORE_A) { /* Let cert callback update client certificates if required */ if (s->cert->cert_cb) { - i = s->cert->cert_cb(s, s->cert->cert_cb_arg); + i = s->cert->cert_cb(ssl, s->cert->cert_cb_arg); if (i < 0) { s->rwstate = SSL_X509_LOOKUP; return WORK_MORE_A; @@ -3464,7 +3710,8 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) } s->rwstate = SSL_NOTHING; if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) + if (!SSL_use_certificate(ssl, x509) + || !SSL_use_PrivateKey(ssl, pkey)) i = 0; } else if (i == 1) { i = 0; @@ -3482,6 +3729,7 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; } else { s->s3.tmp.cert_req = 2; + s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ return WORK_ERROR; @@ -3489,6 +3737,10 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) } } + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) + s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; + if (s->post_handshake_auth == SSL_PHA_REQUESTED) return WORK_FINISHED_STOP; return WORK_FINISHED_CONTINUE; @@ -3499,47 +3751,173 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) return WORK_ERROR; } -int tls_construct_client_certificate(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s, + WPACKET *pkt) { - if (SSL_IS_TLS13(s)) { + CERT_PKEY *cpk = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + if (SSL_CONNECTION_IS_TLS13(s)) { if (s->pha_context == NULL) { /* no context available, add 0-length context */ if (!WPACKET_put_bytes_u8(pkt, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } else if (!WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } - if (!ssl3_output_cert_chain(s, pkt, - (s->s3.tmp.cert_req == 2) ? NULL - : s->cert->key)) { - /* SSLfatal() already called */ - return 0; + if (s->s3.tmp.cert_req != 2) + cpk = s->cert->key; + switch (s->ext.client_cert_type) { + case TLSEXT_cert_type_rpk: + if (!tls_output_rpk(s, pkt, cpk)) { + /* SSLfatal() already called */ + return CON_FUNC_ERROR; + } + break; + case TLSEXT_cert_type_x509: + if (!ssl3_output_cert_chain(s, pkt, cpk, 0)) { + /* SSLfatal() already called */ + return CON_FUNC_ERROR; + } + break; + default: + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return CON_FUNC_ERROR; } - if (SSL_IS_TLS13(s) + /* + * If we attempted to write early data or we're in middlebox compat mode + * then we deferred changing the handshake write keys to the last possible + * moment. We need to do it now. + */ + if (SSL_CONNECTION_IS_TLS13(s) && SSL_IS_FIRST_HANDSHAKE(s) - && (!s->method->ssl3_enc->change_cipher_state(s, + && (s->early_data_state != SSL_EARLY_DATA_NONE + || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + && (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) { /* * This is a fatal error, which leaves enc_write_ctx in an inconsistent * state and thus ssl3_send_alert may crash. */ SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_CANNOT_CHANGE_CIPHER); - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; +} + +#ifndef OPENSSL_NO_COMP_ALG +CON_FUNC_RETURN tls_construct_client_compressed_certificate(SSL_CONNECTION *sc, + WPACKET *pkt) +{ + SSL *ssl = SSL_CONNECTION_GET_SSL(sc); + WPACKET tmppkt; + BUF_MEM *buf = NULL; + size_t length; + size_t max_length; + COMP_METHOD *method; + COMP_CTX *comp = NULL; + int comp_len; + int ret = 0; + int alg = sc->ext.compress_certificate_from_peer[0]; + + /* Note that sc->s3.tmp.cert_req == 2 is checked in write transition */ + + if ((buf = BUF_MEM_new()) == NULL || !WPACKET_init(&tmppkt, buf)) + goto err; + + /* Use the |tmppkt| for the to-be-compressed data */ + if (sc->pha_context == NULL) { + /* no context available, add 0-length context */ + if (!WPACKET_put_bytes_u8(&tmppkt, 0)) + goto err; + } else if (!WPACKET_sub_memcpy_u8(&tmppkt, sc->pha_context, sc->pha_context_len)) + goto err; + + if (!ssl3_output_cert_chain(sc, &tmppkt, sc->cert->key, 0)) { + /* SSLfatal() already called */ + goto out; + } + + /* continue with the real |pkt| */ + if (!WPACKET_put_bytes_u16(pkt, alg) + || !WPACKET_get_total_written(&tmppkt, &length) + || !WPACKET_put_bytes_u24(pkt, length)) + goto err; + + switch (alg) { + case TLSEXT_comp_cert_zlib: + method = COMP_zlib_oneshot(); + break; + case TLSEXT_comp_cert_brotli: + method = COMP_brotli_oneshot(); + break; + case TLSEXT_comp_cert_zstd: + method = COMP_zstd_oneshot(); + break; + default: + goto err; + } + max_length = ossl_calculate_comp_expansion(alg, length); + + if ((comp = COMP_CTX_new(method)) == NULL + || !WPACKET_start_sub_packet_u24(pkt) + || !WPACKET_reserve_bytes(pkt, max_length, NULL)) + goto err; + + comp_len = COMP_compress_block(comp, WPACKET_get_curr(pkt), max_length, + (unsigned char *)buf->data, length); + if (comp_len <= 0) + goto err; + + if (!WPACKET_allocate_bytes(pkt, comp_len, NULL) + || !WPACKET_close(pkt)) + goto err; + + /* + * If we attempted to write early data or we're in middlebox compat mode + * then we deferred changing the handshake write keys to the last possible + * moment. We need to do it now. + */ + if (SSL_IS_FIRST_HANDSHAKE(sc) + && (sc->early_data_state != SSL_EARLY_DATA_NONE + || (sc->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + && (!ssl->method->ssl3_enc->change_cipher_state(sc, + SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) { + /* + * This is a fatal error, which leaves sc->enc_write_ctx in an + * inconsistent state and thus ssl3_send_alert may crash. + */ + SSLfatal(sc, SSL_AD_NO_ALERT, SSL_R_CANNOT_CHANGE_CIPHER); + goto out; + } + ret = 1; + goto out; + + err: + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + out: + if (buf != NULL) { + /* If |buf| is NULL, then |tmppkt| could not have been initialized */ + WPACKET_cleanup(&tmppkt); + } + BUF_MEM_free(buf); + COMP_CTX_free(comp); + return ret; } +#endif -int ssl3_check_cert_and_algorithm(SSL *s) +int ssl3_check_cert_and_algorithm(SSL_CONNECTION *s) { const SSL_CERT_LOOKUP *clu; size_t idx; long alg_k, alg_a; + EVP_PKEY *pkey; alg_k = s->s3.tmp.new_cipher->algorithm_mkey; alg_a = s->s3.tmp.new_cipher->algorithm_auth; @@ -3549,7 +3927,8 @@ int ssl3_check_cert_and_algorithm(SSL *s) return 1; /* This is the passed certificate */ - clu = ssl_cert_lookup_by_pkey(X509_get0_pubkey(s->session->peer), &idx); + pkey = tls_get_peer_pkey(s); + clu = ssl_cert_lookup_by_pkey(pkey, &idx, SSL_CONNECTION_GET_CTX(s)); /* Check certificate is recognised and suitable for cipher */ if (clu == NULL || (alg_a & clu->amask) == 0) { @@ -3557,13 +3936,6 @@ int ssl3_check_cert_and_algorithm(SSL *s) return 0; } - if (clu->amask & SSL_aECDSA) { - if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s)) - return 1; - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_ECC_CERT); - return 0; - } - if (alg_k & (SSL_kRSA | SSL_kRSAPSK) && idx != SSL_PKEY_RSA) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_MISSING_RSA_ENCRYPTING_CERT); @@ -3575,11 +3947,22 @@ int ssl3_check_cert_and_algorithm(SSL *s) return 0; } + /* Early out to skip the checks below */ + if (s->session->peer_rpk != NULL) + return 1; + + if (clu->amask & SSL_aECDSA) { + if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s)) + return 1; + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_ECC_CERT); + return 0; + } + return 1; } #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_next_proto(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_next_proto(SSL_CONNECTION *s, WPACKET *pkt) { size_t len, padding_len; unsigned char *padding = NULL; @@ -3590,17 +3973,19 @@ int tls_construct_next_proto(SSL *s, WPACKET *pkt) if (!WPACKET_sub_memcpy_u8(pkt, s->ext.npn, len) || !WPACKET_sub_allocate_bytes_u8(pkt, padding_len, &padding)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } memset(padding, 0, padding_len); - return 1; + return CON_FUNC_SUCCESS; } #endif -MSG_PROCESS_RETURN tls_process_hello_req(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_hello_req(SSL_CONNECTION *s, PACKET *pkt) { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + if (PACKET_remaining(pkt) > 0) { /* should contain no data */ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -3619,15 +4004,16 @@ MSG_PROCESS_RETURN tls_process_hello_req(SSL *s, PACKET *pkt) * HelloRequest it will do a full handshake. Either behaviour is reasonable * but doing one for TLS and another for DTLS is odd. */ - if (SSL_IS_DTLS(s)) - SSL_renegotiate(s); + if (SSL_CONNECTION_IS_DTLS(s)) + SSL_renegotiate(ssl); else - SSL_renegotiate_abbreviated(s); + SSL_renegotiate_abbreviated(ssl); return MSG_PROCESS_FINISHED_READING; } -static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt) +static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL_CONNECTION *s, + PACKET *pkt) { PACKET extensions; RAW_EXTENSION *rawexts = NULL; @@ -3655,26 +4041,32 @@ static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) +int ssl_do_client_cert_cb(SSL_CONNECTION *s, X509 **px509, EVP_PKEY **ppkey) { int i = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + #ifndef OPENSSL_NO_ENGINE - if (s->ctx->client_cert_engine) { + if (sctx->client_cert_engine) { i = tls_engine_load_ssl_client_cert(s, px509, ppkey); if (i != 0) return i; } #endif - if (s->ctx->client_cert_cb) - i = s->ctx->client_cert_cb(s, px509, ppkey); + if (sctx->client_cert_cb) + i = sctx->client_cert_cb(SSL_CONNECTION_GET_SSL(s), px509, ppkey); return i; } -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) +int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, + WPACKET *pkt) { int i; size_t totlen = 0, len, maxlen, maxverok = 0; - int empty_reneg_info_scsv = !s->renegotiate; + int empty_reneg_info_scsv = !s->renegotiate + && (SSL_CONNECTION_IS_DTLS(s) + || s->min_proto_version < TLS1_3_VERSION); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* Set disabled masks for this session */ if (!ssl_set_client_disabled(s)) { @@ -3696,7 +4088,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) * chop number of supported ciphers to keep it well below this if we * use TLS v1.2 */ - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (TLS1_get_version(ssl) >= TLS1_2_VERSION) maxlen = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; else #endif @@ -3716,14 +4108,14 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) continue; - if (!s->method->put_cipher_by_char(c, pkt, &len)) { + if (!ssl->method->put_cipher_by_char(c, pkt, &len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* Sanity check that the maximum version we offer has ciphers enabled */ if (!maxverok) { - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (DTLS_VERSION_GE(c->max_dtls, s->s3.tmp.max_ver) && DTLS_VERSION_LE(c->min_dtls, s->s3.tmp.max_ver)) maxverok = 1; @@ -3753,7 +4145,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) static SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) { + if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -3762,7 +4154,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) static SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) { + if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -3772,14 +4164,14 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) return 1; } -int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_end_of_early_data(SSL_CONNECTION *s, WPACKET *pkt) { if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + return CON_FUNC_ERROR; } s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING; - return 1; + return CON_FUNC_SUCCESS; } diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 788d0eff65..c674ddfb54 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include @@ -43,15 +44,17 @@ static unsigned char bitmask_start_values[] = static unsigned char bitmask_end_values[] = { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; -static void dtls1_fix_message_header(SSL *s, size_t frag_off, +static void dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, size_t frag_len); -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); -static void dtls1_set_message_header_int(SSL *s, unsigned char mt, +static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, + unsigned char *p); +static void dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, size_t len, unsigned short seq_num, size_t frag_off, size_t frag_len); -static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len); +static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, + size_t *len); static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) { @@ -59,14 +62,11 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) unsigned char *buf = NULL; unsigned char *bitmask = NULL; - if ((frag = OPENSSL_malloc(sizeof(*frag))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((frag = OPENSSL_zalloc(sizeof(*frag))) == NULL) return NULL; - } if (frag_len) { if ((buf = OPENSSL_malloc(frag_len)) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(frag); return NULL; } @@ -79,7 +79,6 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) if (reassembly) { bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len)); if (bitmask == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(buf); OPENSSL_free(frag); return NULL; @@ -95,11 +94,7 @@ void dtls1_hm_fragment_free(hm_fragment *frag) { if (!frag) return; - if (frag->msg_header.is_ccs) { - EVP_CIPHER_CTX_free(frag->msg_header. - saved_retransmit_state.enc_write_ctx); - EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash); - } + OPENSSL_free(frag->fragment); OPENSSL_free(frag->reassembly); OPENSSL_free(frag); @@ -109,13 +104,14 @@ void dtls1_hm_fragment_free(hm_fragment *frag) * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or * SSL3_RT_CHANGE_CIPHER_SPEC) */ -int dtls1_do_write(SSL *s, int type) +int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) { int ret; size_t written; size_t curr_mtu; int retry = 1; - size_t len, frag_off, mac_size, blocksize, used_len; + size_t len, frag_off, overhead, used_len; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (!dtls1_query_mtu(s)) return -1; @@ -130,21 +126,7 @@ int dtls1_do_write(SSL *s, int type) return -1; } - if (s->write_hash) { - if (s->enc_write_ctx - && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) & - EVP_CIPH_FLAG_AEAD_CIPHER) != 0) - mac_size = 0; - else - mac_size = EVP_MD_CTX_get_size(s->write_hash); - } else - mac_size = 0; - - if (s->enc_write_ctx && - (EVP_CIPHER_CTX_get_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) - blocksize = 2 * EVP_CIPHER_CTX_get_block_size(s->enc_write_ctx); - else - blocksize = 0; + overhead = s->rlayer.wrlmethod->get_max_record_overhead(s->rlayer.wrl); frag_off = 0; s->rwstate = SSL_NOTHING; @@ -185,8 +167,7 @@ int dtls1_do_write(SSL *s, int type) } } - used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH - + mac_size + blocksize; + used_len = BIO_wpending(s->wbio) + overhead; if (s->d1->mtu > used_len) curr_mtu = s->d1->mtu - used_len; else @@ -201,9 +182,8 @@ int dtls1_do_write(SSL *s, int type) s->rwstate = SSL_WRITING; return ret; } - used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; - if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { - curr_mtu = s->d1->mtu - used_len; + if (s->d1->mtu > overhead + DTLS1_HM_HEADER_LENGTH) { + curr_mtu = s->d1->mtu - overhead; } else { /* Shouldn't happen */ return -1; @@ -248,9 +228,9 @@ int dtls1_do_write(SSL *s, int type) * retransmit anything. continue as if everything is fine and * wait for an alert to handle the retransmit */ - if (retry && BIO_ctrl(SSL_get_wbio(s), + if (retry && BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + if (!(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { if (!dtls1_query_mtu(s)) return -1; /* Have one more go */ @@ -269,6 +249,16 @@ int dtls1_do_write(SSL *s, int type) if (!ossl_assert(len == written)) return -1; + /* + * We should not exceed the MTU size. If compression is in use + * then the max record overhead calculation is unreliable so we do + * not check in that case. We use assert rather than ossl_assert + * because in a production build, if this assert were ever to fail, + * then the best thing to do is probably carry on regardless. + */ + assert(s->s3.tmp.new_compression != NULL + || BIO_wpending(s->wbio) <= (int)s->d1->mtu); + if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { /* * should not be done for 'Hello Request's, but in that case @@ -303,7 +293,7 @@ int dtls1_do_write(SSL *s, int type) if (written == s->init_num) { if (s->msg_callback) s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, + (size_t)(s->init_off + s->init_num), ssl, s->msg_callback_arg); s->init_off = 0; /* done writing this message */ @@ -328,7 +318,7 @@ int dtls1_do_write(SSL *s, int type) return 0; } -int dtls_get_message(SSL *s, int *mt) +int dtls_get_message(SSL_CONNECTION *s, int *mt) { struct hm_header_st *msg_hdr; unsigned char *p; @@ -356,7 +346,8 @@ int dtls_get_message(SSL *s, int *mt) if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { if (s->msg_callback) { s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - p, 1, s, s->msg_callback_arg); + p, 1, SSL_CONNECTION_GET_SSL(s), + s->msg_callback_arg); } /* * This isn't a real handshake message so skip the processing below. @@ -387,7 +378,7 @@ int dtls_get_message(SSL *s, int *mt) * DTLS to do any further processing it wants at the same point that TLS would * be asked for the message body. */ -int dtls_get_message_body(SSL *s, size_t *len) +int dtls_get_message_body(SSL_CONNECTION *s, size_t *len) { unsigned char *msg = (unsigned char *)s->init_buf->data; size_t msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; @@ -416,7 +407,7 @@ int dtls_get_message_body(SSL *s, size_t *len) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, s->init_num + DTLS1_HM_HEADER_LENGTH, - s, s->msg_callback_arg); + SSL_CONNECTION_GET_SSL(s), s->msg_callback_arg); end: *len = s->init_num; @@ -428,7 +419,7 @@ int dtls_get_message_body(SSL *s, size_t *len) * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but * may be greater if the maximum certificate list size requires it. */ -static size_t dtls1_max_handshake_message_len(const SSL *s) +static size_t dtls1_max_handshake_message_len(const SSL_CONNECTION *s) { size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; if (max_len < s->max_cert_list) @@ -436,7 +427,8 @@ static size_t dtls1_max_handshake_message_len(const SSL *s) return max_len; } -static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) +static int dtls1_preprocess_fragment(SSL_CONNECTION *s, + struct hm_header_st *msg_hdr) { size_t frag_off, frag_len, msg_len; @@ -482,7 +474,7 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) * Returns 1 if there is a buffered fragment available, 0 if not, or -1 on a * fatal error. */ -static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) +static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) { /*- * (0) check whether the desired fragment is available @@ -596,8 +588,8 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) } } -static int -dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) +static int dtls1_reassemble_fragment(SSL_CONNECTION *s, + const struct hm_header_st *msg_hdr) { hm_fragment *frag = NULL; pitem *item = NULL; @@ -605,6 +597,7 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) unsigned char seq64be[8]; size_t frag_len = msg_hdr->frag_len; size_t readbytes; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) @@ -645,11 +638,11 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) unsigned char devnull[256]; while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0, &readbytes); if (i <= 0) goto err; frag_len -= readbytes; @@ -658,9 +651,9 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) } /* read the body of the fragment (header has already been read */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - frag->fragment + msg_hdr->frag_off, - frag_len, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + frag->fragment + msg_hdr->frag_off, + frag_len, 0, &readbytes); if (i <= 0 || readbytes != frag_len) i = -1; if (i <= 0) @@ -705,8 +698,8 @@ dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) return -1; } -static int -dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) +static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, + const struct hm_header_st *msg_hdr) { int i = -1; hm_fragment *frag = NULL; @@ -714,6 +707,7 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) unsigned char seq64be[8]; size_t frag_len = msg_hdr->frag_len; size_t readbytes; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) goto err; @@ -742,11 +736,11 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) unsigned char devnull[256]; while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0, &readbytes); if (i <= 0) goto err; frag_len -= readbytes; @@ -769,9 +763,9 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) /* * read the body of the fragment (header has already been read */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - frag->fragment, frag_len, 0, - &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + frag->fragment, frag_len, 0, + &readbytes); if (i<=0 || readbytes != frag_len) i = -1; if (i <= 0) @@ -803,13 +797,16 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) return 0; } -static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) +static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, + size_t *len) { unsigned char wire[DTLS1_HM_HEADER_LENGTH]; size_t mlen, frag_off, frag_len; - int i, ret, recvd_type; + int i, ret; + uint8_t recvd_type; struct hm_header_st msg_hdr; size_t readbytes; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); int chretran = 0; *errtype = 0; @@ -828,8 +825,8 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) } /* read handshake message header */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, wire, - DTLS1_HM_HEADER_LENGTH, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, wire, + DTLS1_HM_HEADER_LENGTH, 0, &readbytes); if (i <= 0) { /* nbio, or an error */ s->rwstate = SSL_READING; *len = 0; @@ -868,7 +865,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) * We must have at least frag_len bytes left in the record to be read. * Fragments must not span records. */ - if (frag_len > RECORD_LAYER_get_rrec_length(&s->rlayer)) { + if (frag_len > s->rlayer.tlsrecs[s->rlayer.curr_rec].length) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); goto f_err; } @@ -913,7 +910,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - wire, DTLS1_HM_HEADER_LENGTH, s, + wire, DTLS1_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); s->init_num = 0; @@ -934,8 +931,8 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) unsigned char *p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - &p[frag_off], frag_len, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + &p[frag_off], frag_len, 0, &readbytes); /* * This shouldn't ever fail due to NBIO because we already checked @@ -987,25 +984,23 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) /*- * for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->rlayer.read_sequence zero - * ssl->s3.read_mac_secret re-init * ssl->session->read_sym_enc assign * ssl->session->read_compression assign * ssl->session->read_hash assign */ -int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN dtls_construct_change_cipher_spec(SSL_CONNECTION *s, + WPACKET *pkt) { if (s->version == DTLS1_BAD_VER) { s->d1->next_handshake_write_seq++; if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } - return 1; + return CON_FUNC_SUCCESS; } #ifndef OPENSSL_NO_SCTP @@ -1013,13 +1008,14 @@ int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) * Wait for a dry event. Should only be called at a point in the handshake * where we are not expecting any data from the peer except an alert. */ -WORK_STATE dtls_wait_for_dry(SSL *s) +WORK_STATE dtls_wait_for_dry(SSL_CONNECTION *s) { int ret, errtype; size_t len; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* read app data until dry event */ - ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(ssl)); if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; @@ -1040,16 +1036,18 @@ WORK_STATE dtls_wait_for_dry(SSL *s) s->s3.in_read_app_data = 2; s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); + BIO_clear_retry_flags(SSL_get_rbio(ssl)); + BIO_set_retry_read(SSL_get_rbio(ssl)); return WORK_MORE_A; } return WORK_FINISHED_CONTINUE; } #endif -int dtls1_read_failed(SSL *s, int code) +int dtls1_read_failed(SSL_CONNECTION *s, int code) { + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + if (code > 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; @@ -1063,9 +1061,9 @@ int dtls1_read_failed(SSL *s, int code) return code; } /* done, no need to send a retransmit */ - if (!SSL_in_init(s)) + if (!SSL_in_init(ssl)) { - BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + BIO_set_flags(SSL_get_rbio(ssl), BIO_FLAGS_READ); return code; } @@ -1087,7 +1085,7 @@ int dtls1_get_queue_priority(unsigned short seq, int is_ccs) return seq * 2 - is_ccs; } -int dtls1_retransmit_buffered_messages(SSL *s) +int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s) { pqueue *sent = s->d1->sent_messages; piterator iter; @@ -1109,7 +1107,7 @@ int dtls1_retransmit_buffered_messages(SSL *s) return 1; } -int dtls1_buffer_message(SSL *s, int is_ccs) +int dtls1_buffer_message(SSL_CONNECTION *s, int is_ccs) { pitem *item; hm_fragment *frag; @@ -1153,12 +1151,9 @@ int dtls1_buffer_message(SSL *s, int is_ccs) frag->msg_header.is_ccs = is_ccs; /* save current state */ - frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; - frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; - frag->msg_header.saved_retransmit_state.compress = s->compress; - frag->msg_header.saved_retransmit_state.session = s->session; - frag->msg_header.saved_retransmit_state.epoch = - DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer); + frag->msg_header.saved_retransmit_state.wrlmethod = s->rlayer.wrlmethod; + frag->msg_header.saved_retransmit_state.wrl = s->rlayer.wrl; + memset(seq64be, 0, sizeof(seq64be)); seq64be[6] = @@ -1180,7 +1175,7 @@ int dtls1_buffer_message(SSL *s, int is_ccs) return 1; } -int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found) +int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) { int ret; /* XDTLS: for now assuming that read/writes are blocking */ @@ -1220,32 +1215,27 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found) frag->msg_header.frag_len); /* save current state */ - saved_state.enc_write_ctx = s->enc_write_ctx; - saved_state.write_hash = s->write_hash; - saved_state.compress = s->compress; - saved_state.session = s->session; - saved_state.epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer); + saved_state.wrlmethod = s->rlayer.wrlmethod; + saved_state.wrl = s->rlayer.wrl; s->d1->retransmitting = 1; /* restore state in which the message was originally sent */ - s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; - s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; - s->compress = frag->msg_header.saved_retransmit_state.compress; - s->session = frag->msg_header.saved_retransmit_state.session; - DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, - frag->msg_header. - saved_retransmit_state.epoch); + s->rlayer.wrlmethod = frag->msg_header.saved_retransmit_state.wrlmethod; + s->rlayer.wrl = frag->msg_header.saved_retransmit_state.wrl; + + /* + * The old wrl may be still pointing at an old BIO. Update it to what we're + * using now. + */ + s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio); ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); /* restore current state */ - s->enc_write_ctx = saved_state.enc_write_ctx; - s->write_hash = saved_state.write_hash; - s->compress = saved_state.compress; - s->session = saved_state.session; - DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, saved_state.epoch); + s->rlayer.wrlmethod = saved_state.wrlmethod; + s->rlayer.wrl = saved_state.wrl; s->d1->retransmitting = 0; @@ -1253,7 +1243,7 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found) return ret; } -void dtls1_set_message_header(SSL *s, +void dtls1_set_message_header(SSL_CONNECTION *s, unsigned char mt, size_t len, size_t frag_off, size_t frag_len) { @@ -1268,7 +1258,7 @@ void dtls1_set_message_header(SSL *s, /* don't actually do the writing, wait till the MTU has been retrieved */ static void -dtls1_set_message_header_int(SSL *s, unsigned char mt, +dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, size_t len, unsigned short seq_num, size_t frag_off, size_t frag_len) { @@ -1282,7 +1272,7 @@ dtls1_set_message_header_int(SSL *s, unsigned char mt, } static void -dtls1_fix_message_header(SSL *s, size_t frag_off, size_t frag_len) +dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, size_t frag_len) { struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; @@ -1290,7 +1280,8 @@ dtls1_fix_message_header(SSL *s, size_t frag_off, size_t frag_len) msg_hdr->frag_len = frag_len; } -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) +static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, + unsigned char *p) { struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; @@ -1304,7 +1295,8 @@ static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) return p; } -void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) +void dtls1_get_message_header(const unsigned char *data, struct + hm_header_st *msg_hdr) { memset(msg_hdr, 0, sizeof(*msg_hdr)); msg_hdr->type = *(data++); @@ -1315,7 +1307,7 @@ void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) n2l3(data, msg_hdr->frag_len); } -int dtls1_set_handshake_header(SSL *s, WPACKET *pkt, int htype) +int dtls1_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype) { unsigned char *header; @@ -1339,7 +1331,7 @@ int dtls1_set_handshake_header(SSL *s, WPACKET *pkt, int htype) return 1; } -int dtls1_close_construct_packet(SSL *s, WPACKET *pkt, int htype) +int dtls1_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) { size_t msglen; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 25055df15c..5693a1269d 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * Map error codes to TLS/SSL alart types. @@ -36,16 +37,60 @@ const unsigned char hrrrandom[] = { 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c }; +int ossl_statem_set_mutator(SSL *s, + ossl_statem_mutate_handshake_cb mutate_handshake_cb, + ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb, + void *mutatearg) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + sc->statem.mutate_handshake_cb = mutate_handshake_cb; + sc->statem.mutatearg = mutatearg; + sc->statem.finish_mutate_handshake_cb = finish_mutate_handshake_cb; + + return 1; +} + /* * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or * SSL3_RT_CHANGE_CIPHER_SPEC) */ -int ssl3_do_write(SSL *s, int type) +int ssl3_do_write(SSL_CONNECTION *s, uint8_t type) { int ret; size_t written = 0; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + /* + * If we're running the test suite then we may need to mutate the message + * we've been asked to write. Does not happen in normal operation. + */ + if (s->statem.mutate_handshake_cb != NULL + && !s->statem.write_in_progress + && type == SSL3_RT_HANDSHAKE + && s->init_num >= SSL3_HM_HEADER_LENGTH) { + unsigned char *msg; + size_t msglen; + + if (!s->statem.mutate_handshake_cb((unsigned char *)s->init_buf->data, + s->init_num, + &msg, &msglen, + s->statem.mutatearg)) + return -1; + if (msglen < SSL3_HM_HEADER_LENGTH + || !BUF_MEM_grow(s->init_buf, msglen)) + return -1; + memcpy(s->init_buf->data, msg, msglen); + s->init_num = msglen; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + s->statem.finish_mutate_handshake_cb(s->statem.mutatearg); + s->statem.write_in_progress = 1; + } - ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + ret = ssl3_write_bytes(ssl, type, &s->init_buf->data[s->init_off], s->init_num, &written); if (ret <= 0) return -1; @@ -55,7 +100,8 @@ int ssl3_do_write(SSL *s, int type) * ignore the result anyway * TLS1.3 KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_IS_TLS13(s) || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET && s->statem.hand_state != TLS_ST_CW_KEY_UPDATE && s->statem.hand_state != TLS_ST_SW_KEY_UPDATE)) if (!ssl3_finish_mac(s, @@ -63,9 +109,10 @@ int ssl3_do_write(SSL *s, int type) written)) return -1; if (written == s->init_num) { + s->statem.write_in_progress = 0; if (s->msg_callback) s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, + (size_t)(s->init_off + s->init_num), ssl, s->msg_callback_arg); return 1; } @@ -74,7 +121,7 @@ int ssl3_do_write(SSL *s, int type) return 0; } -int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) +int tls_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) { size_t msglen; @@ -88,9 +135,11 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) return 1; } -int tls_setup_handshake(SSL *s) +int tls_setup_handshake(SSL_CONNECTION *s) { int ver_min, ver_max, ok; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ @@ -106,11 +155,11 @@ int tls_setup_handshake(SSL *s) } /* Sanity check that we have MD5-SHA1 if we need it */ - if (s->ctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { + if (sctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { int md5sha1_needed = 0; /* We don't have MD5-SHA1 - do we need it? */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (DTLS_VERSION_LE(ver_max, DTLS1_VERSION)) md5sha1_needed = 1; } else { @@ -129,12 +178,12 @@ int tls_setup_handshake(SSL *s) ok = 1; /* Don't allow TLSv1.1 or below to be negotiated */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (DTLS_VERSION_LT(ver_min, DTLS1_2_VERSION)) - ok = SSL_set_min_proto_version(s, DTLS1_2_VERSION); + ok = SSL_set_min_proto_version(ssl, DTLS1_2_VERSION); } else { if (ver_min < TLS1_2_VERSION) - ok = SSL_set_min_proto_version(s, TLS1_2_VERSION); + ok = SSL_set_min_proto_version(ssl, TLS1_2_VERSION); } if (!ok) { /* Shouldn't happen */ @@ -145,7 +194,7 @@ int tls_setup_handshake(SSL *s) ok = 0; if (s->server) { - STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s); + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl); int i; /* @@ -156,7 +205,7 @@ int tls_setup_handshake(SSL *s) for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (DTLS_VERSION_GE(ver_max, c->min_dtls) && DTLS_VERSION_LE(ver_max, c->max_dtls)) ok = 1; @@ -178,7 +227,7 @@ int tls_setup_handshake(SSL *s) ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_accept); } else { /* N.B. s->ctx may not equal s->session_ctx */ - ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept_renegotiate); + ssl_tsan_counter(sctx, &sctx->stats.sess_accept_renegotiate); s->s3.tmp.cert_request = 0; } @@ -195,7 +244,7 @@ int tls_setup_handshake(SSL *s) s->s3.tmp.cert_req = 0; - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) s->statem.use_timer = 1; } @@ -209,7 +258,7 @@ int tls_setup_handshake(SSL *s) #define TLS13_TBS_START_SIZE 64 #define TLS13_TBS_PREAMBLE_SIZE (TLS13_TBS_START_SIZE + 33 + 1) -static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, +static int get_cert_verify_tbs_data(SSL_CONNECTION *s, unsigned char *tls13tbs, void **hdata, size_t *hdatalen) { /* ASCII: "TLS 1.3, server CertificateVerify", in hex for EBCDIC compatibility */ @@ -219,7 +268,7 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, static const char clientcontext[] = "\x54\x4c\x53\x20\x31\x2e\x33\x2c\x20\x63\x6c\x69" "\x65\x6e\x74\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x56\x65\x72\x69\x66\x79"; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { size_t hashlen; /* Set the first 64 bytes of to-be-signed data to octet 32 */ @@ -264,7 +313,7 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, return 1; } -int tls_construct_cert_verify(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_cert_verify(SSL_CONNECTION *s, WPACKET *pkt) { EVP_PKEY *pkey = NULL; const EVP_MD *md = NULL; @@ -275,6 +324,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) unsigned char *sig = NULL; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (lu == NULL || s->s3.tmp.cert == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -282,14 +332,14 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) } pkey = s->s3.tmp.cert->privatekey; - if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) { + if (pkey == NULL || !tls1_lookup_md(sctx, lu, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -306,7 +356,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) if (EVP_DigestSignInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; @@ -381,14 +431,14 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) OPENSSL_free(sig); EVP_MD_CTX_free(mctx); - return 1; + return CON_FUNC_SUCCESS; err: OPENSSL_free(sig); EVP_MD_CTX_free(mctx); - return 0; + return CON_FUNC_ERROR; } -MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) { EVP_PKEY *pkey = NULL; const unsigned char *data; @@ -398,27 +448,26 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; int j; unsigned int len; - X509 *peer; const EVP_MD *md = NULL; size_t hdatalen = 0; void *hdata; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; EVP_MD_CTX *mctx = EVP_MD_CTX_new(); EVP_PKEY_CTX *pctx = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - peer = s->session->peer; - pkey = X509_get0_pubkey(peer); + pkey = tls_get_peer_pkey(s); if (pkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) { + if (ssl_cert_lookup_by_pkey(pkey, NULL, sctx) == NULL) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); goto err; @@ -441,7 +490,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) goto err; } - if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { + if (!tls1_lookup_md(sctx, s->s3.tmp.peer_sigalg, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -485,7 +534,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (EVP_DigestVerifyInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; @@ -496,10 +545,8 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (pktype == NID_id_GostR3410_2001 || pktype == NID_id_GostR3410_2012_256 || pktype == NID_id_GostR3410_2012_512) { - if ((gost_data = OPENSSL_malloc(len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if ((gost_data = OPENSSL_malloc(len)) == NULL) goto err; - } BUF_reverse(gost_data, data, len); data = gost_data; } @@ -528,6 +575,11 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) } } else { j = EVP_DigestVerify(mctx, data, len, hdata, hdatalen); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Ignore bad signatures when fuzzing */ + if (SSL_IS_QUIC_HANDSHAKE(s)) + j = 1; +#endif if (j <= 0) { SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_BAD_SIGNATURE); goto err; @@ -542,7 +594,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) * want to make sure that SSL_get1_peer_certificate() will return the actual * server certificate from the client_cert_cb callback. */ - if (!s->server && SSL_IS_TLS13(s) && s->s3.tmp.cert_req == 1) + if (!s->server && SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.cert_req == 1) ret = MSG_PROCESS_CONTINUE_PROCESSING; else ret = MSG_PROCESS_CONTINUE_READING; @@ -556,61 +608,66 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) return ret; } -int tls_construct_finished(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt) { size_t finish_md_len; const char *sender; size_t slen; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* This is a real handshake so make sure we clean it up at the end */ if (!s->server && s->post_handshake_auth != SSL_PHA_REQUESTED) s->statem.cleanuphand = 1; /* - * We only change the keys if we didn't already do this when we sent the - * client certificate + * If we attempted to write early data or we're in middlebox compat mode + * then we deferred changing the handshake write keys to the last possible + * moment. If we didn't already do this when we sent the client certificate + * then we need to do it now. */ - if (SSL_IS_TLS13(s) + if (SSL_CONNECTION_IS_TLS13(s) && !s->server + && (s->early_data_state != SSL_EARLY_DATA_NONE + || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) && s->s3.tmp.cert_req == 0 - && (!s->method->ssl3_enc->change_cipher_state(s, + && (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {; /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } if (s->server) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; + sender = ssl->method->ssl3_enc->server_finished_label; + slen = ssl->method->ssl3_enc->server_finished_label_len; } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; + sender = ssl->method->ssl3_enc->client_finished_label; + slen = ssl->method->ssl3_enc->client_finished_label_len; } - finish_md_len = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3.tmp.finish_md); + finish_md_len = ssl->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3.tmp.finish_md); if (finish_md_len == 0) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } s->s3.tmp.finish_md_len = finish_md_len; if (!WPACKET_memcpy(pkt, s->s3.tmp.finish_md, finish_md_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* * Log the master secret, if logging is enabled. We don't log it for * TLSv1.3: there's a different key schedule for that. */ - if (!SSL_IS_TLS13(s) && !ssl_log_secret(s, MASTER_SECRET_LABEL, - s->session->master_key, - s->session->master_key_length)) { + if (!SSL_CONNECTION_IS_TLS13(s) + && !ssl_log_secret(s, MASTER_SECRET_LABEL, s->session->master_key, + s->session->master_key_length)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } /* @@ -618,7 +675,7 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) */ if (!ossl_assert(finish_md_len <= EVP_MAX_MD_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } if (!s->server) { memcpy(s->s3.previous_client_finished, s->s3.tmp.finish_md, @@ -630,21 +687,21 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) s->s3.previous_server_finished_len = finish_md_len; } - return 1; + return CON_FUNC_SUCCESS; } -int tls_construct_key_update(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_key_update(SSL_CONNECTION *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, s->key_update)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } s->key_update = SSL_KEY_UPDATE_NONE; - return 1; + return CON_FUNC_SUCCESS; } -MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_key_update(SSL_CONNECTION *s, PACKET *pkt) { unsigned int updatetype; @@ -693,22 +750,23 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen * to far. */ -int ssl3_take_mac(SSL *s) +int ssl3_take_mac(SSL_CONNECTION *s) { const char *sender; size_t slen; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (!s->server) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; + sender = ssl->method->ssl3_enc->server_finished_label; + slen = ssl->method->ssl3_enc->server_finished_label_len; } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; + sender = ssl->method->ssl3_enc->client_finished_label; + slen = ssl->method->ssl3_enc->client_finished_label_len; } s->s3.tmp.peer_finish_md_len = - s->method->ssl3_enc->final_finish_mac(s, sender, slen, - s->s3.tmp.peer_finish_md); + ssl->method->ssl3_enc->final_finish_mac(s, sender, slen, + s->s3.tmp.peer_finish_md); if (s->s3.tmp.peer_finish_md_len == 0) { /* SSLfatal() already called */ @@ -718,7 +776,8 @@ int ssl3_take_mac(SSL *s) return 1; } -MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL_CONNECTION *s, + PACKET *pkt) { size_t remain; @@ -728,7 +787,7 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) * been consumed by ssl_get_message() so there should be no bytes left, * unless we're using DTLS1_BAD_VER, which has an extra 2 bytes */ - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if ((s->version == DTLS1_BAD_VER && remain != DTLS1_CCS_HEADER_LENGTH + 1) || (s->version != DTLS1_BAD_VER @@ -755,8 +814,8 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } - if (SSL_IS_DTLS(s)) { - dtls1_reset_seq_numbers(s, SSL3_CC_READ); + if (SSL_CONNECTION_IS_DTLS(s)) { + dtls1_increment_epoch(s, SSL3_CC_READ); if (s->version == DTLS1_BAD_VER) s->d1->handshake_read_seq++; @@ -767,29 +826,35 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no * SCTP is used */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); + BIO_ctrl(SSL_get_wbio(SSL_CONNECTION_GET_SSL(s)), + BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); #endif } return MSG_PROCESS_CONTINUE_READING; } -MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt) { size_t md_len; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + int was_first = SSL_IS_FIRST_HANDSHAKE(s); + int ok; /* This is a real handshake so make sure we clean it up at the end */ if (s->server) { /* * To get this far we must have read encrypted data from the client. We - * no longer tolerate unencrypted alerts. This value is ignored if less - * than TLSv1.3 + * no longer tolerate unencrypted alerts. This is ignored if less than + * TLSv1.3 */ - s->statem.enc_read_state = ENC_READ_STATE_VALID; + if (s->rlayer.rrlmethod->set_plain_alerts != NULL) + s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0); if (s->post_handshake_auth != SSL_PHA_REQUESTED) s->statem.cleanuphand = 1; - if (SSL_IS_TLS13(s) && !tls13_save_handshake_digest_for_pha(s)) { + if (SSL_CONNECTION_IS_TLS13(s) + && !tls13_save_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } @@ -799,13 +864,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * In TLSv1.3 a Finished message signals a key change so the end of the * message must be on a record boundary. */ - if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { + if (SSL_CONNECTION_IS_TLS13(s) + && RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } /* If this occurs, we have missed a message */ - if (!SSL_IS_TLS13(s) && !s->s3.change_cipher_spec) { + if (!SSL_CONNECTION_IS_TLS13(s) && !s->s3.change_cipher_spec) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS); return MSG_PROCESS_ERROR; } @@ -818,8 +884,16 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } - if (CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md, - md_len) != 0) { + ok = CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md, + md_len); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (ok != 0) { + if ((PACKET_data(pkt)[0] ^ s->s3.tmp.peer_finish_md[0]) != 0xFF) { + ok = 0; + } + } +#endif + if (ok != 0) { SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DIGEST_CHECK_FAILED); return MSG_PROCESS_ERROR; } @@ -845,24 +919,24 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * In TLS1.3 we also have to change cipher state and do any final processing * of the initial server flight (if we are a client) */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (s->server) { if (s->post_handshake_auth != SSL_PHA_REQUESTED && - !s->method->ssl3_enc->change_cipher_state(s, - SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) { + !ssl->method->ssl3_enc->change_cipher_state(s, + SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } } else { /* TLS 1.3 gets the secret size from the handshake md */ size_t dummy; - if (!s->method->ssl3_enc->generate_master_secret(s, + if (!ssl->method->ssl3_enc->generate_master_secret(s, s->master_secret, s->handshake_secret, 0, &dummy)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } - if (!s->method->ssl3_enc->change_cipher_state(s, + if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; @@ -874,39 +948,50 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) } } + if (was_first + && !SSL_IS_FIRST_HANDSHAKE(s) + && s->rlayer.rrlmethod->set_first_handshake != NULL) + s->rlayer.rrlmethod->set_first_handshake(s->rlayer.rrl, 0); + return MSG_PROCESS_FINISHED_READING; } -int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_change_cipher_spec(SSL_CONNECTION *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } /* Add a certificate to the WPACKET */ -static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) +static int ssl_add_cert_to_wpacket(SSL_CONNECTION *s, WPACKET *pkt, + X509 *x, int chain, int for_comp) { int len; unsigned char *outbytes; + int context = SSL_EXT_TLS1_3_CERTIFICATE; + + if (for_comp) + context |= SSL_EXT_TLS1_3_CERTIFICATE_COMPRESSION; len = i2d_X509(x, NULL); if (len < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return 0; } if (!WPACKET_sub_allocate_bytes_u24(pkt, len, &outbytes) || i2d_X509(x, &outbytes) != len) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (SSL_IS_TLS13(s) - && !tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_CERTIFICATE, x, - chain)) { + if ((SSL_CONNECTION_IS_TLS13(s) || for_comp) + && !tls_construct_extensions(s, pkt, context, x, chain)) { /* SSLfatal() already called */ return 0; } @@ -915,13 +1000,14 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) } /* Add certificate chain to provided WPACKET */ -static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) +static int ssl_add_cert_chain(SSL_CONNECTION *s, WPACKET *pkt, CERT_PKEY *cpk, int for_comp) { int i, chain_count; X509 *x; STACK_OF(X509) *extra_certs; STACK_OF(X509) *chain = NULL; X509_STORE *chain_store; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (cpk == NULL || cpk->x509 == NULL) return 1; @@ -934,26 +1020,28 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) if (cpk->chain != NULL) extra_certs = cpk->chain; else - extra_certs = s->ctx->extra_certs; + extra_certs = sctx->extra_certs; if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) chain_store = NULL; else if (s->cert->chain_store) chain_store = s->cert->chain_store; else - chain_store = s->ctx->cert_store; + chain_store = sctx->cert_store; if (chain_store != NULL) { - X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, - s->ctx->propq); + X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(sctx->libctx, + sctx->propq); if (xs_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); return 0; } if (!X509_STORE_CTX_init(xs_ctx, chain_store, x, NULL)) { X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); return 0; } /* @@ -975,14 +1063,15 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) ERR_raise(ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK); #endif X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } chain_count = sk_X509_num(chain); for (i = 0; i < chain_count; i++) { x = sk_X509_value(chain, i); - if (!ssl_add_cert_to_wpacket(s, pkt, x, i)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, i, for_comp)) { /* SSLfatal() already called */ X509_STORE_CTX_free(xs_ctx); return 0; @@ -992,16 +1081,17 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) } else { i = ssl_security_cert_chain(s, extra_certs, x, 0); if (i != 1) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } - if (!ssl_add_cert_to_wpacket(s, pkt, x, 0)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, 0, for_comp)) { /* SSLfatal() already called */ return 0; } for (i = 0; i < sk_X509_num(extra_certs); i++) { x = sk_X509_value(extra_certs, i); - if (!ssl_add_cert_to_wpacket(s, pkt, x, i + 1)) { + if (!ssl_add_cert_to_wpacket(s, pkt, x, i + 1, for_comp)) { /* SSLfatal() already called */ return 0; } @@ -1010,18 +1100,306 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) return 1; } -unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) +EVP_PKEY* tls_get_peer_pkey(const SSL_CONNECTION *sc) +{ + if (sc->session->peer_rpk != NULL) + return sc->session->peer_rpk; + if (sc->session->peer != NULL) + return X509_get0_pubkey(sc->session->peer); + return NULL; +} + +int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) +{ + EVP_PKEY *pkey = NULL; + int ret = 0; + RAW_EXTENSION *rawexts = NULL; + PACKET extensions; + PACKET context; + unsigned long cert_len = 0, spki_len = 0; + const unsigned char *spki, *spkistart; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(sc); + + /*- + * ---------------------------- + * TLS 1.3 Certificate message: + * ---------------------------- + * https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2 + * + * enum { + * X509(0), + * RawPublicKey(2), + * (255) + * } CertificateType; + * + * struct { + * select (certificate_type) { + * case RawPublicKey: + * // From RFC 7250 ASN.1_subjectPublicKeyInfo + * opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; + * + * case X509: + * opaque cert_data<1..2^24-1>; + * }; + * Extension extensions<0..2^16-1>; + * } CertificateEntry; + * + * struct { + * opaque certificate_request_context<0..2^8-1>; + * CertificateEntry certificate_list<0..2^24-1>; + * } Certificate; + * + * The client MUST send a Certificate message if and only if the server + * has requested client authentication via a CertificateRequest message + * (Section 4.3.2). If the server requests client authentication but no + * suitable certificate is available, the client MUST send a Certificate + * message containing no certificates (i.e., with the "certificate_list" + * field having length 0). + * + * ---------------------------- + * TLS 1.2 Certificate message: + * ---------------------------- + * https://datatracker.ietf.org/doc/html/rfc7250#section-3 + * + * opaque ASN.1Cert<1..2^24-1>; + * + * struct { + * select(certificate_type){ + * + * // certificate type defined in this document. + * case RawPublicKey: + * opaque ASN.1_subjectPublicKeyInfo<1..2^24-1>; + * + * // X.509 certificate defined in RFC 5246 + * case X.509: + * ASN.1Cert certificate_list<0..2^24-1>; + * + * // Additional certificate type based on + * // "TLS Certificate Types" subregistry + * }; + * } Certificate; + * + * ------------- + * Consequently: + * ------------- + * After the (TLS 1.3 only) context octet string (1 byte length + data) the + * Certificate message has a 3-byte length that is zero in the client to + * server message when the client has no RPK to send. In that case, there + * are no (TLS 1.3 only) per-certificate extensions either, because the + * [CertificateEntry] list is empty. + * + * In the server to client direction, or when the client had an RPK to send, + * the TLS 1.3 message just prepends the length of the RPK+extensions, + * while TLS <= 1.2 sends just the RPK (octet-string). + * + * The context must be zero-length in the server to client direction, and + * must match the value recorded in the certificate request in the client + * to server direction. + */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (!PACKET_get_length_prefixed_1(pkt, &context)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + if (sc->server) { + if (sc->pha_context == NULL) { + if (PACKET_remaining(&context) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } else { + if (!PACKET_equal(&context, sc->pha_context, sc->pha_context_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } + } else { + if (PACKET_remaining(&context) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); + goto err; + } + } + } + + if (!PACKET_get_net_3(pkt, &cert_len) + || PACKET_remaining(pkt) != cert_len) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + + /* + * The list length may be zero when there is no RPK. In the case of TLS + * 1.2 this is actually the RPK length, which cannot be zero as specified, + * but that breaks the ability of the client to decline client auth. We + * overload the 0 RPK length to mean "no RPK". This interpretation is + * also used some other (reference?) implementations, but is not supported + * by the verbatim RFC7250 text. + */ + if (cert_len == 0) + return 1; + + if (SSL_CONNECTION_IS_TLS13(sc)) { + /* + * With TLS 1.3, a non-empty explicit-length RPK octet-string followed + * by a possibly empty extension block. + */ + if (!PACKET_get_net_3(pkt, &spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (spki_len == 0) { + /* empty RPK */ + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_EMPTY_RAW_PUBLIC_KEY); + goto err; + } + } else { + spki_len = cert_len; + } + + if (!PACKET_get_bytes(pkt, &spki, spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + spkistart = spki; + if ((pkey = d2i_PUBKEY_ex(NULL, &spki, spki_len, sctx->libctx, sctx->propq)) == NULL + || spki != (spkistart + spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (EVP_PKEY_missing_parameters(pkey)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto err; + } + + /* Process the Extensions block */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (PACKET_remaining(pkt) != (cert_len - 3 - spki_len)) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); + goto err; + } + if (!PACKET_as_length_prefixed_2(pkt, &extensions) + || PACKET_remaining(pkt) != 0) { + SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); + goto err; + } + if (!tls_collect_extensions(sc, &extensions, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + &rawexts, NULL, 1)) { + /* SSLfatal already called */ + goto err; + } + /* chain index is always zero and fin always 1 for RPK */ + if (!tls_parse_all_extensions(sc, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + rawexts, NULL, 0, 1)) { + /* SSLfatal already called */ + goto err; + } + } + ret = 1; + if (peer_rpk != NULL) { + *peer_rpk = pkey; + pkey = NULL; + } + + err: + OPENSSL_free(rawexts); + EVP_PKEY_free(pkey); + return ret; +} + +unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk) +{ + int pdata_len = 0; + unsigned char *pdata = NULL; + X509_PUBKEY *xpk = NULL; + unsigned long ret = 0; + X509 *x509 = NULL; + + if (cpk != NULL && cpk->x509 != NULL) { + x509 = cpk->x509; + /* Get the RPK from the certificate */ + xpk = X509_get_X509_PUBKEY(cpk->x509); + if (xpk == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + pdata_len = i2d_X509_PUBKEY(xpk, &pdata); + } else if (cpk != NULL && cpk->privatekey != NULL) { + /* Get the RPK from the private key */ + pdata_len = i2d_PUBKEY(cpk->privatekey, &pdata); + } else { + /* The server RPK is not optional */ + if (sc->server) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + /* The client can send a zero length certificate list */ + if (!WPACKET_sub_memcpy_u24(pkt, pdata, pdata_len)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + return 1; + } + + if (pdata_len <= 0) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * TLSv1.2 is _just_ the raw public key + * TLSv1.3 includes extensions, so there's a length wrapper + */ + if (SSL_CONNECTION_IS_TLS13(sc)) { + if (!WPACKET_start_sub_packet_u24(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (!WPACKET_sub_memcpy_u24(pkt, pdata, pdata_len)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (SSL_CONNECTION_IS_TLS13(sc)) { + /* + * Only send extensions relevant to raw public keys. Until such + * extensions are defined, this will be an empty set of extensions. + * |x509| may be NULL, which raw public-key extensions need to handle. + */ + if (!tls_construct_extensions(sc, pkt, SSL_EXT_TLS1_3_RAW_PUBLIC_KEY, + x509, 0)) { + /* SSLfatal() already called */ + goto err; + } + if (!WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + ret = 1; + err: + OPENSSL_free(pdata); + return ret; +} + +unsigned long ssl3_output_cert_chain(SSL_CONNECTION *s, WPACKET *pkt, + CERT_PKEY *cpk, int for_comp) { if (!WPACKET_start_sub_packet_u24(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (!ssl_add_cert_chain(s, pkt, cpk)) + if (!ssl_add_cert_chain(s, pkt, cpk, for_comp)) return 0; if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!for_comp) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1033,14 +1411,16 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) * in NBIO events. If |clearbufs| is set then init_buf and the wbio buffer is * freed up as well. */ -WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, +WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, int clearbufs, int stop) { void (*cb) (const SSL *ssl, int type, int val) = NULL; int cleanuphand = s->statem.cleanuphand; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (clearbufs) { - if (!SSL_IS_DTLS(s) + if (!SSL_CONNECTION_IS_DTLS(s) #ifndef OPENSSL_NO_SCTP /* * RFC6083: SCTP provides a reliable and in-sequence transport service for DTLS @@ -1048,7 +1428,7 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, * MUST NOT be used. * Hence the init_buf can be cleared when DTLS over SCTP as transport is used. */ - || BIO_dgram_is_sctp(SSL_get_wbio(s)) + || BIO_dgram_is_sctp(SSL_get_wbio(ssl)) #endif ) { /* @@ -1066,7 +1446,7 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, s->init_num = 0; } - if (SSL_IS_TLS13(s) && !s->server + if (SSL_CONNECTION_IS_TLS13(s) && !s->server && s->post_handshake_auth == SSL_PHA_REQUESTED) s->post_handshake_auth = SSL_PHA_EXT_SENT; @@ -1088,14 +1468,14 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, * In TLSv1.3 we update the cache as part of constructing the * NewSessionTicket */ - if (!SSL_IS_TLS13(s)) + if (!SSL_CONNECTION_IS_TLS13(s)) ssl_update_cache(s, SSL_SESS_CACHE_SERVER); /* N.B. s->ctx may not equal s->session_ctx */ - ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept_good); + ssl_tsan_counter(sctx, &sctx->stats.sess_accept_good); s->handshake_func = ossl_statem_accept; } else { - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * We encourage applications to only use TLSv1.3 tickets once, * so we remove this one from the cache. @@ -1119,7 +1499,7 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, &s->session_ctx->stats.sess_connect_good); } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* done with handshaking */ s->d1->handshake_read_seq = 0; s->d1->handshake_write_seq = 0; @@ -1130,17 +1510,17 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, if (s->info_callback != NULL) cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; + else if (sctx->info_callback != NULL) + cb = sctx->info_callback; /* The callback may expect us to not be in init at handshake done */ ossl_statem_set_in_init(s, 0); if (cb != NULL) { if (cleanuphand - || !SSL_IS_TLS13(s) + || !SSL_CONNECTION_IS_TLS13(s) || SSL_IS_FIRST_HANDSHAKE(s)) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } if (!stop) { @@ -1152,21 +1532,23 @@ WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, return WORK_FINISHED_STOP; } -int tls_get_message_header(SSL *s, int *mt) +int tls_get_message_header(SSL_CONNECTION *s, int *mt) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ - int skip_message, i, recvd_type; + int skip_message, i; + uint8_t recvd_type; unsigned char *p; size_t l, readbytes; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); p = (unsigned char *)s->init_buf->data; do { while (s->init_num < SSL3_HM_HEADER_LENGTH) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, - &p[s->init_num], - SSL3_HM_HEADER_LENGTH - s->init_num, - 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, &recvd_type, + &p[s->init_num], + SSL3_HM_HEADER_LENGTH - s->init_num, + 0, &readbytes); if (i <= 0) { s->rwstate = SSL_READING; return 0; @@ -1221,7 +1603,7 @@ int tls_get_message_header(SSL *s, int *mt) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, SSL3_HM_HEADER_LENGTH, s, + p, SSL3_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); } } while (skip_message); @@ -1238,8 +1620,7 @@ int tls_get_message_header(SSL *s, int *mt) * Total message size is the remaining record bytes to read * plus the SSL3_HM_HEADER_LENGTH bytes that we already read */ - l = RECORD_LAYER_get_rrec_length(&s->rlayer) - + SSL3_HM_HEADER_LENGTH; + l = s->rlayer.tlsrecs[0].length + SSL3_HM_HEADER_LENGTH; s->s3.tmp.message_size = l; s->init_msg = s->init_buf->data; @@ -1261,11 +1642,12 @@ int tls_get_message_header(SSL *s, int *mt) return 1; } -int tls_get_message_body(SSL *s, size_t *len) +int tls_get_message_body(SSL_CONNECTION *s, size_t *len) { size_t n, readbytes; unsigned char *p; int i; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { /* We've already read everything in */ @@ -1276,8 +1658,8 @@ int tls_get_message_body(SSL *s, size_t *len) p = s->init_msg; n = s->s3.tmp.message_size - s->init_num; while (n > 0) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, - &p[s->init_num], n, 0, &readbytes); + i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, + &p[s->init_num], n, 0, &readbytes); if (i <= 0) { s->rwstate = SSL_READING; *len = 0; @@ -1307,7 +1689,7 @@ int tls_get_message_body(SSL *s, size_t *len) } if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, - (size_t)s->init_num, s, s->msg_callback_arg); + (size_t)s->init_num, ssl, s->msg_callback_arg); } else { /* * We defer feeding in the HRR until later. We'll do it as part of @@ -1317,8 +1699,9 @@ int tls_get_message_body(SSL *s, size_t *len) */ #define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) /* KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_IS_TLS13(s) || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET - && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE || memcmp(hrrrandom, @@ -1334,7 +1717,7 @@ int tls_get_message_body(SSL *s, size_t *len) } if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ssl, s->msg_callback_arg); } @@ -1398,16 +1781,16 @@ int ssl_x509err2alert(int x509err) return tp->alert; } -int ssl_allow_compression(SSL *s) +int ssl_allow_compression(SSL_CONNECTION *s) { if (s->options & SSL_OP_NO_COMPRESSION) return 0; return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL); } -static int version_cmp(const SSL *s, int a, int b) +static int version_cmp(const SSL_CONNECTION *s, int a, int b) { - int dtls = SSL_IS_DTLS(s); + int dtls = SSL_CONNECTION_IS_DTLS(s); if (a == b) return 0; @@ -1485,7 +1868,7 @@ static const version_info dtls_version_table[] = { * * Returns 0 on success, or an SSL error reason on failure. */ -static int ssl_method_error(const SSL *s, const SSL_METHOD *method) +static int ssl_method_error(const SSL_CONNECTION *s, const SSL_METHOD *method) { int version = method->version; @@ -1511,19 +1894,20 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method) * certificate type, or has PSK or a certificate callback configured, or has * a servername callback configure. Otherwise returns 0. */ -static int is_tls13_capable(const SSL *s) +static int is_tls13_capable(const SSL_CONNECTION *s) { - int i; + size_t i; int curve; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - if (!ossl_assert(s->ctx != NULL) || !ossl_assert(s->session_ctx != NULL)) + if (!ossl_assert(sctx != NULL) || !ossl_assert(s->session_ctx != NULL)) return 0; /* * A servername callback can change the available certs, so if a servername * cb is set then we just assume TLSv1.3 will be ok */ - if (s->ctx->ext.servername_cb != NULL + if (sctx->ext.servername_cb != NULL || s->session_ctx->ext.servername_cb != NULL) return 1; @@ -1535,7 +1919,8 @@ static int is_tls13_capable(const SSL *s) if (s->psk_find_session_cb != NULL || s->cert->cert_cb != NULL) return 1; - for (i = 0; i < SSL_PKEY_NUM; i++) { + /* All provider-based sig algs are required to support at least TLS1.3 */ + for (i = 0; i < s->ssl_pkey_num; i++) { /* Skip over certs disallowed for TLSv1.3 */ switch (i) { case SSL_PKEY_DSA_SIGN: @@ -1572,12 +1957,13 @@ static int is_tls13_capable(const SSL *s) * * Returns 1 when supported, otherwise 0 */ -int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) +int ssl_version_supported(const SSL_CONNECTION *s, int version, + const SSL_METHOD **meth) { const version_info *vent; const version_info *table; - switch (s->method->version) { + switch (SSL_CONNECTION_GET_SSL(s)->method->version) { default: /* Version should match method version for non-ANY method */ return version_cmp(s, version, s->version) == 0; @@ -1615,26 +2001,27 @@ int ssl_version_supported(const SSL *s, int version, const SSL_METHOD **meth) * * Returns 1 when using the highest enabled version, 0 otherwise. */ -int ssl_check_version_downgrade(SSL *s) +int ssl_check_version_downgrade(SSL_CONNECTION *s) { const version_info *vent; const version_info *table; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* * Check that the current protocol is the highest enabled version - * (according to s->ctx->method, as version negotiation may have changed + * (according to ssl->defltmethod, as version negotiation may have changed * s->method). */ - if (s->version == s->ctx->method->version) + if (s->version == ssl->defltmeth->version) return 1; /* * Apparently we're using a version-flexible SSL_METHOD (not at its * highest protocol version). */ - if (s->ctx->method->version == TLS_method()->version) + if (ssl->defltmeth->version == TLS_method()->version) table = tls_version_table; - else if (s->ctx->method->version == DTLS_method()->version) + else if (ssl->defltmeth->version == DTLS_method()->version) table = dtls_version_table; else { /* Unexpected state; fail closed. */ @@ -1672,8 +2059,10 @@ int ssl_set_version_bound(int method_version, int version, int *bound) valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION_INTERNAL; valid_dtls = - DTLS_VERSION_LE(version, DTLS_MAX_VERSION_INTERNAL) && - DTLS_VERSION_GE(version, DTLS1_BAD_VER); + /* We support client side pre-standardisation version of DTLS */ + (version == DTLS1_BAD_VER) + || (DTLS_VERSION_LE(version, DTLS_MAX_VERSION_INTERNAL) + && DTLS_VERSION_GE(version, DTLS1_VERSION)); if (!valid_tls && !valid_dtls) return 0; @@ -1709,12 +2098,12 @@ int ssl_set_version_bound(int method_version, int version, int *bound) return 1; } -static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) +static void check_for_downgrade(SSL_CONNECTION *s, int vers, DOWNGRADE *dgrd) { if (vers == TLS1_2_VERSION && ssl_version_supported(s, TLS1_3_VERSION, NULL)) { *dgrd = DOWNGRADE_TO_1_2; - } else if (!SSL_IS_DTLS(s) + } else if (!SSL_CONNECTION_IS_DTLS(s) && vers < TLS1_2_VERSION /* * We need to ensure that a server that disables TLSv1.2 @@ -1739,7 +2128,8 @@ static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) * * Returns 0 on success or an SSL error reason number on failure. */ -int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) +int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, + DOWNGRADE *dgrd) { /*- * With version-flexible methods we have an initial state with: @@ -1750,7 +2140,8 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * So we detect version-flexible methods via the method version, not the * handle version. */ - int server_version = s->method->version; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + int server_version = ssl->method->version; int client_version = hello->legacy_version; const version_info *vent; const version_info *table; @@ -1761,7 +2152,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) switch (server_version) { default: - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { if (version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; *dgrd = DOWNGRADE_NONE; @@ -1793,7 +2184,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) if (!suppversions->present && s->hello_retry_request != SSL_HRR_NONE) return SSL_R_UNSUPPORTED_PROTOCOL; - if (suppversions->present && !SSL_IS_DTLS(s)) { + if (suppversions->present && !SSL_CONNECTION_IS_DTLS(s)) { unsigned int candidate_vers = 0; unsigned int best_vers = 0; const SSL_METHOD *best_method = NULL; @@ -1841,7 +2232,10 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) } check_for_downgrade(s, best_vers, dgrd); s->version = best_vers; - s->method = best_method; + ssl->method = best_method; + if (!ssl_set_record_protocol_version(s, best_vers)) + return ERR_R_INTERNAL_ERROR; + return 0; } return SSL_R_UNSUPPORTED_PROTOCOL; @@ -1868,7 +2262,10 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) if (ssl_method_error(s, method) == 0) { check_for_downgrade(s, vent->version, dgrd); s->version = vent->version; - s->method = method; + ssl->method = method; + if (!ssl_set_record_protocol_version(s, s->version)) + return ERR_R_INTERNAL_ERROR; + return 0; } disabled = 1; @@ -1887,11 +2284,13 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * * Returns 1 on success or 0 on error. */ -int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) +int ssl_choose_client_version(SSL_CONNECTION *s, int version, + RAW_EXTENSION *extensions) { const version_info *vent; const version_info *table; int ret, ver_min, ver_max, real_max, origv; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); origv = s->version; s->version = version; @@ -1912,9 +2311,9 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) return 0; } - switch (s->method->version) { + switch (ssl->method->version) { default: - if (s->version != s->method->version) { + if (s->version != ssl->method->version) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION); return 0; @@ -1926,6 +2325,10 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) * versions they don't want. If not, then easy to fix, just return * ssl_method_error(s, s->method) */ + if (!ssl_set_record_protocol_version(s, s->version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } return 1; case TLS_ANY_VERSION: table = tls_version_table; @@ -1941,13 +2344,13 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) SSLfatal(s, SSL_AD_PROTOCOL_VERSION, ret); return 0; } - if (SSL_IS_DTLS(s) ? DTLS_VERSION_LT(s->version, ver_min) - : s->version < ver_min) { + if (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_LT(s->version, ver_min) + : s->version < ver_min) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; - } else if (SSL_IS_DTLS(s) ? DTLS_VERSION_GT(s->version, ver_max) - : s->version > ver_max) { + } else if (SSL_CONNECTION_IS_DTLS(s) ? DTLS_VERSION_GT(s->version, ver_max) + : s->version > ver_max) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; @@ -1967,7 +2370,7 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) SSL_R_INAPPROPRIATE_FALLBACK); return 0; } - } else if (!SSL_IS_DTLS(s) + } else if (!SSL_CONNECTION_IS_DTLS(s) && s->version < TLS1_2_VERSION && real_max > s->version) { if (memcmp(tls11downgrade, @@ -1985,7 +2388,11 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) if (vent->cmeth == NULL || s->version != vent->version) continue; - s->method = vent->cmeth(); + ssl->method = vent->cmeth(); + if (!ssl_set_record_protocol_version(s, s->version)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } return 1; } @@ -2016,17 +2423,17 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) * Returns 0 on success or an SSL error reason number on failure. On failure * min_version and max_version will also be set to 0. */ -int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, - int *real_max) +int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, + int *max_version, int *real_max) { int version, tmp_real_max; int hole; - const SSL_METHOD *single = NULL; const SSL_METHOD *method; const version_info *table; const version_info *vent; + const SSL *ssl = SSL_CONNECTION_GET_SSL(s); - switch (s->method->version) { + switch (ssl->method->version) { default: /* * If this SSL handle is not from a version flexible method we don't @@ -2062,13 +2469,12 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, * the valid protocol entries) and we don't have a selected version yet. * * Whenever "hole == 1", and we hit an enabled method, its version becomes - * the selected version, and the method becomes a candidate "single" - * method. We're no longer in a hole, so "hole" becomes 0. + * the selected version. We're no longer in a hole, so "hole" becomes 0. * - * If "hole == 0" and we hit an enabled method, then "single" is cleared, - * as we support a contiguous range of at least two methods. If we hit - * a disabled method, then hole becomes true again, but nothing else - * changes yet, because all the remaining methods may be disabled too. + * If "hole == 0" and we hit an enabled method, we support a contiguous + * range of at least two methods. If we hit a disabled method, + * then hole becomes true again, but nothing else changes yet, + * because all the remaining methods may be disabled too. * If we again hit an enabled method after the new hole, it becomes * selected, as we start from scratch. */ @@ -2095,12 +2501,11 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, if (ssl_method_error(s, method) != 0) { hole = 1; } else if (!hole) { - single = NULL; *min_version = method->version; } else { if (real_max != NULL && tmp_real_max != 0) *real_max = tmp_real_max; - version = (single = method)->version; + version = method->version; *min_version = version; hole = 0; } @@ -2123,7 +2528,7 @@ int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version, * * Returns 0 on success or an SSL error reason number on failure. */ -int ssl_set_client_hello_version(SSL *s) +int ssl_set_client_hello_version(SSL_CONNECTION *s) { int ver_min, ver_max, ret; @@ -2141,9 +2546,22 @@ int ssl_set_client_hello_version(SSL *s) s->version = ver_max; - /* TLS1.3 always uses TLS1.2 in the legacy_version field */ - if (!SSL_IS_DTLS(s) && ver_max > TLS1_2_VERSION) + if (SSL_CONNECTION_IS_DTLS(s)) { + if (ver_max == DTLS1_BAD_VER) { + /* + * Even though this is technically before version negotiation, + * because we have asked for DTLS1_BAD_VER we will never negotiate + * anything else, and this has impacts on the record layer for when + * we read the ServerHello. So we need to tell the record layer + * about this immediately. + */ + if (!ssl_set_record_protocol_version(s, ver_max)) + return 0; + } + } else if (ver_max > TLS1_2_VERSION) { + /* TLS1.3 always uses TLS1.2 in the legacy_version field */ ver_max = TLS1_2_VERSION; + } s->client_version = ver_max; return 0; @@ -2155,7 +2573,7 @@ int ssl_set_client_hello_version(SSL *s) * used. Returns 1 if the group is in the list (and allowed if |checkallow| is * 1) or 0 otherwise. */ -int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, +int check_in_list(SSL_CONNECTION *s, uint16_t group_id, const uint16_t *groups, size_t num_groups, int checkallow) { size_t i; @@ -2177,7 +2595,8 @@ int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, } /* Replace ClientHello1 in the transcript hash with a synthetic message */ -int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, +int create_synthetic_message_hash(SSL_CONNECTION *s, + const unsigned char *hashval, size_t hashlen, const unsigned char *hrr, size_t hrrlen) { @@ -2235,14 +2654,14 @@ static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) return X509_NAME_cmp(*a, *b); } -int parse_ca_names(SSL *s, PACKET *pkt) +int parse_ca_names(SSL_CONNECTION *s, PACKET *pkt) { STACK_OF(X509_NAME) *ca_sk = sk_X509_NAME_new(ca_dn_cmp); X509_NAME *xn = NULL; PACKET cadns; if (ca_sk == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } /* get the CA RDNs */ @@ -2272,7 +2691,7 @@ int parse_ca_names(SSL *s, PACKET *pkt) } if (!sk_X509_NAME_push(ca_sk, xn)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } xn = NULL; @@ -2289,23 +2708,25 @@ int parse_ca_names(SSL *s, PACKET *pkt) return 0; } -const STACK_OF(X509_NAME) *get_ca_names(SSL *s) +const STACK_OF(X509_NAME) *get_ca_names(SSL_CONNECTION *s) { - const STACK_OF(X509_NAME) *ca_sk = NULL;; + const STACK_OF(X509_NAME) *ca_sk = NULL; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (s->server) { - ca_sk = SSL_get_client_CA_list(s); + ca_sk = SSL_get_client_CA_list(ssl); if (ca_sk != NULL && sk_X509_NAME_num(ca_sk) == 0) ca_sk = NULL; } if (ca_sk == NULL) - ca_sk = SSL_get0_CA_list(s); + ca_sk = SSL_get0_CA_list(ssl); return ca_sk; } -int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) +int construct_ca_names(SSL_CONNECTION *s, const STACK_OF(X509_NAME) *ca_sk, + WPACKET *pkt) { /* Start sub-packet for client CA list */ if (!WPACKET_start_sub_packet_u16(pkt)) { @@ -2341,14 +2762,14 @@ int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) } /* Create a buffer containing data to be signed for server key exchange */ -size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, +size_t construct_key_exchange_tbs(SSL_CONNECTION *s, unsigned char **ptbs, const void *param, size_t paramlen) { size_t tbslen = 2 * SSL3_RANDOM_SIZE + paramlen; unsigned char *tbs = OPENSSL_malloc(tbslen); if (tbs == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } memcpy(tbs, s->s3.client_random, SSL3_RANDOM_SIZE); @@ -2364,7 +2785,7 @@ size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, * Saves the current handshake digest for Post-Handshake Auth, * Done after ClientFinished is processed, done exactly once */ -int tls13_save_handshake_digest_for_pha(SSL *s) +int tls13_save_handshake_digest_for_pha(SSL_CONNECTION *s) { if (s->pha_dgst == NULL) { if (!ssl3_digest_cached_records(s, 1)) @@ -2391,7 +2812,7 @@ int tls13_save_handshake_digest_for_pha(SSL *s) * Restores the Post-Handshake Auth handshake digest * Done just before sending/processing the Cert Request */ -int tls13_restore_handshake_digest_for_pha(SSL *s) +int tls13_restore_handshake_digest_for_pha(SSL_CONNECTION *s) { if (s->pha_dgst == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -2404,3 +2825,76 @@ int tls13_restore_handshake_digest_for_pha(SSL *s) } return 1; } + +#ifndef OPENSSL_NO_COMP_ALG +MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc, + PACKET *pkt, + PACKET *tmppkt, + BUF_MEM *buf) +{ + MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; + int comp_alg; + COMP_METHOD *method = NULL; + COMP_CTX *comp = NULL; + size_t expected_length; + size_t comp_length; + int i; + int found = 0; + + if (buf == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!PACKET_get_net_2(pkt, (unsigned int*)&comp_alg)) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto err; + } + /* If we have a prefs list, make sure the algorithm is in it */ + if (sc->cert_comp_prefs[0] != TLSEXT_comp_cert_none) { + for (i = 0; sc->cert_comp_prefs[i] != TLSEXT_comp_cert_none; i++) { + if (sc->cert_comp_prefs[i] == comp_alg) { + found = 1; + break; + } + } + if (!found) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + } + if (!ossl_comp_has_alg(comp_alg)) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + switch (comp_alg) { + case TLSEXT_comp_cert_zlib: + method = COMP_zlib_oneshot(); + break; + case TLSEXT_comp_cert_brotli: + method = COMP_brotli_oneshot(); + break; + case TLSEXT_comp_cert_zstd: + method = COMP_zstd_oneshot(); + break; + default: + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_COMPRESSION_ALGORITHM); + goto err; + } + + if ((comp = COMP_CTX_new(method)) == NULL + || !PACKET_get_net_3_len(pkt, &expected_length) + || !PACKET_get_net_3_len(pkt, &comp_length) + || PACKET_remaining(pkt) != comp_length + || !BUF_MEM_grow(buf, expected_length) + || !PACKET_buf_init(tmppkt, (unsigned char *)buf->data, expected_length) + || COMP_expand_block(comp, (unsigned char *)buf->data, expected_length, + (unsigned char*)PACKET_data(pkt), comp_length) != (int)expected_length) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_BAD_DECOMPRESSION); + goto err; + } + ret = MSG_PROCESS_CONTINUE_PROCESSING; + err: + COMP_CTX_free(comp); + return ret; +} +#endif diff --git a/ssl/statem/statem_local.h b/ssl/statem/statem_local.h index ad4d93b1e2..04114b1e27 100644 --- a/ssl/statem/statem_local.h +++ b/ssl/statem/statem_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,6 +31,9 @@ /* Max ServerHello size permitted by RFC 8446 */ #define SERVER_HELLO_MAX_LENGTH 65607 +/* Max CertificateVerify size permitted by RFC 8446 */ +#define CERTIFICATE_VERIFY_MAX_LENGTH 65539 + /* Max should actually be 36 but we are generous */ #define FINISHED_MAX_LENGTH 64 @@ -59,116 +62,187 @@ typedef enum { MSG_PROCESS_CONTINUE_READING } MSG_PROCESS_RETURN; -typedef int (*confunc_f) (SSL *s, WPACKET *pkt); +typedef CON_FUNC_RETURN (*confunc_f) (SSL_CONNECTION *s, WPACKET *pkt); -int ssl3_take_mac(SSL *s); -int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, +int ssl3_take_mac(SSL_CONNECTION *s); +int check_in_list(SSL_CONNECTION *s, uint16_t group_id, const uint16_t *groups, size_t num_groups, int checkallow); -int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, +int create_synthetic_message_hash(SSL_CONNECTION *s, + const unsigned char *hashval, size_t hashlen, const unsigned char *hrr, size_t hrrlen); -int parse_ca_names(SSL *s, PACKET *pkt); -const STACK_OF(X509_NAME) *get_ca_names(SSL *s); -int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt); -size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, +int parse_ca_names(SSL_CONNECTION *s, PACKET *pkt); +const STACK_OF(X509_NAME) *get_ca_names(SSL_CONNECTION *s); +int construct_ca_names(SSL_CONNECTION *s, const STACK_OF(X509_NAME) *ca_sk, + WPACKET *pkt); +size_t construct_key_exchange_tbs(SSL_CONNECTION *s, unsigned char **ptbs, const void *param, size_t paramlen); /* * TLS/DTLS client state machine functions */ -int ossl_statem_client_read_transition(SSL *s, int mt); -WRITE_TRAN ossl_statem_client_write_transition(SSL *s); -WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst); -WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst); -int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, +int ossl_statem_client_read_transition(SSL_CONNECTION *s, int mt); +WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s); +WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst); +WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst); +int ossl_statem_client_construct_message(SSL_CONNECTION *s, confunc_f *confunc, int *mt); -size_t ossl_statem_client_max_message_size(SSL *s); -MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt); -WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst); +size_t ossl_statem_client_max_message_size(SSL_CONNECTION *s); +MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL_CONNECTION *s, + PACKET *pkt); +WORK_STATE ossl_statem_client_post_process_message(SSL_CONNECTION *s, + WORK_STATE wst); /* * TLS/DTLS server state machine functions */ -int ossl_statem_server_read_transition(SSL *s, int mt); -WRITE_TRAN ossl_statem_server_write_transition(SSL *s); -WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst); -WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst); -int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, +int ossl_statem_server_read_transition(SSL_CONNECTION *s, int mt); +WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s); +WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst); +WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst); +int ossl_statem_server_construct_message(SSL_CONNECTION *s, confunc_f *confunc,int *mt); -size_t ossl_statem_server_max_message_size(SSL *s); -MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt); -WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst); +size_t ossl_statem_server_max_message_size(SSL_CONNECTION *s); +MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL_CONNECTION *s, + PACKET *pkt); +WORK_STATE ossl_statem_server_post_process_message(SSL_CONNECTION *s, + WORK_STATE wst); /* Functions for getting new message data */ -__owur int tls_get_message_header(SSL *s, int *mt); -__owur int tls_get_message_body(SSL *s, size_t *len); -__owur int dtls_get_message(SSL *s, int *mt); -__owur int dtls_get_message_body(SSL *s, size_t *len); +__owur int tls_get_message_header(SSL_CONNECTION *s, int *mt); +__owur int tls_get_message_body(SSL_CONNECTION *s, size_t *len); +__owur int dtls_get_message(SSL_CONNECTION *s, int *mt); +__owur int dtls_get_message_body(SSL_CONNECTION *s, size_t *len); /* Message construction and processing functions */ -__owur int tls_process_initial_server_flight(SSL *s); -__owur MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt); -__owur int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt); -__owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt); - -__owur int tls_construct_finished(SSL *s, WPACKET *pkt); -__owur int tls_construct_key_update(SSL *s, WPACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt); -__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, - int stop); -__owur WORK_STATE dtls_wait_for_dry(SSL *s); +__owur int tls_process_initial_server_flight(SSL_CONNECTION *s); +__owur MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL_CONNECTION *s, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_change_cipher_spec(SSL_CONNECTION *s, + WPACKET *pkt); +__owur CON_FUNC_RETURN dtls_construct_change_cipher_spec(SSL_CONNECTION *s, + WPACKET *pkt); + +__owur CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_key_update(SSL_CONNECTION *s, WPACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_key_update(SSL_CONNECTION *s, + PACKET *pkt); +__owur WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, WORK_STATE wst, + int clearbufs, int stop); +__owur WORK_STATE dtls_wait_for_dry(SSL_CONNECTION *s); + +#ifndef OPENSSL_NO_COMP_ALG +__owur MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc, + PACKET *pkt, + PACKET *tmppkt, + BUF_MEM *buf); +#endif /* some client-only functions */ -__owur int tls_construct_client_hello(SSL *s, WPACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt); -__owur int tls_process_cert_status_body(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt); -__owur int tls_construct_cert_verify(SSL *s, WPACKET *pkt); -__owur WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst); -__owur int tls_construct_client_certificate(SSL *s, WPACKET *pkt); -__owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); -__owur int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt); -__owur int tls_client_key_exchange_post_work(SSL *s); -__owur int tls_construct_cert_status_body(SSL *s, WPACKET *pkt); -__owur int tls_construct_cert_status(SSL *s, WPACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt); -__owur WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst); -__owur int ssl3_check_cert_and_algorithm(SSL *s); +__owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, + WPACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, + PACKET *pkt); +__owur int tls_process_cert_status_body(SSL_CONNECTION *s, PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_cert_status(SSL_CONNECTION *s, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_server_done(SSL_CONNECTION *s, + PACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_cert_verify(SSL_CONNECTION *s, + WPACKET *pkt); +__owur WORK_STATE tls_prepare_client_certificate(SSL_CONNECTION *s, + WORK_STATE wst); +__owur CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s, + WPACKET *pkt); +#ifndef OPENSSL_NO_COMP_ALG +__owur CON_FUNC_RETURN tls_construct_client_compressed_certificate(SSL_CONNECTION *sc, + WPACKET *pkt); +#endif +__owur int ssl_do_client_cert_cb(SSL_CONNECTION *s, X509 **px509, + EVP_PKEY **ppkey); +__owur CON_FUNC_RETURN tls_construct_client_key_exchange(SSL_CONNECTION *s, + WPACKET *pkt); +__owur int tls_client_key_exchange_post_work(SSL_CONNECTION *s); +__owur int tls_construct_cert_status_body(SSL_CONNECTION *s, WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_cert_status(SSL_CONNECTION *s, + WPACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_key_exchange(SSL_CONNECTION *s, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_server_rpk(SSL_CONNECTION *sc, + PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, + PACKET *pkt); +__owur unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, + CERT_PKEY *cpk); +__owur int tls_process_rpk(SSL_CONNECTION *s, PACKET *pkt, EVP_PKEY **peer_rpk); +__owur MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s, + PACKET *pkt); +__owur WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s, + WORK_STATE wst); +#ifndef OPENSSL_NO_COMP_ALG +__owur MSG_PROCESS_RETURN tls_process_server_compressed_certificate(SSL_CONNECTION *sc, + PACKET *pkt); +#endif +__owur int ssl3_check_cert_and_algorithm(SSL_CONNECTION *s); #ifndef OPENSSL_NO_NEXTPROTONEG -__owur int tls_construct_next_proto(SSL *s, WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_next_proto(SSL_CONNECTION *s, WPACKET *pkt); #endif -__owur MSG_PROCESS_RETURN tls_process_hello_req(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt); -__owur int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_hello_req(SSL_CONNECTION *s, PACKET *pkt); +__owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_end_of_early_data(SSL_CONNECTION *s, + WPACKET *pkt); /* some server-only functions */ -__owur MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt); -__owur WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst); -__owur int tls_construct_server_hello(SSL *s, WPACKET *pkt); -__owur int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt); -__owur int tls_construct_server_certificate(SSL *s, WPACKET *pkt); -__owur int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt); -__owur int tls_construct_certificate_request(SSL *s, WPACKET *pkt); -__owur int tls_construct_server_done(SSL *s, WPACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt); -__owur MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt); -__owur WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst); -__owur MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, + PACKET *pkt); +__owur WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, + WORK_STATE wst); +__owur CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, + WPACKET *pkt); +__owur CON_FUNC_RETURN dtls_construct_hello_verify_request(SSL_CONNECTION *s, + WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_server_certificate(SSL_CONNECTION *s, + WPACKET *pkt); +#ifndef OPENSSL_NO_COMP_ALG +__owur CON_FUNC_RETURN tls_construct_server_compressed_certificate(SSL_CONNECTION *sc, + WPACKET *pkt); +#endif +__owur CON_FUNC_RETURN tls_construct_server_key_exchange(SSL_CONNECTION *s, + WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_certificate_request(SSL_CONNECTION *s, + WPACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_server_done(SSL_CONNECTION *s, + WPACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, + PACKET *pkt); +#ifndef OPENSSL_NO_COMP_ALG +__owur MSG_PROCESS_RETURN tls_process_client_compressed_certificate(SSL_CONNECTION *sc, + PACKET *pkt); +#endif +__owur MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL_CONNECTION *s, + PACKET *pkt); +__owur WORK_STATE tls_post_process_client_key_exchange(SSL_CONNECTION *s, + WORK_STATE wst); +__owur MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, + PACKET *pkt); #ifndef OPENSSL_NO_NEXTPROTONEG -__owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); +__owur MSG_PROCESS_RETURN tls_process_next_proto(SSL_CONNECTION *s, + PACKET *pkt); #endif -__owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); -MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); +__owur CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, + WPACKET *pkt); +MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL_CONNECTION *s, + PACKET *pkt); #ifndef OPENSSL_NO_GOST /* These functions are used in GOST18 CKE, both for client and server */ -int ossl_gost18_cke_cipher_nid(const SSL *s); -int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf); +int ossl_gost18_cke_cipher_nid(const SSL_CONNECTION *s); +int ossl_gost_ukm(const SSL_CONNECTION *s, unsigned char *dgst_buf); #endif /* Extension processing */ @@ -179,252 +253,320 @@ typedef enum ext_return_en { EXT_RETURN_NOT_SENT } EXT_RETURN; -__owur int tls_validate_all_contexts(SSL *s, unsigned int thisctx, +__owur int tls_validate_all_contexts(SSL_CONNECTION *s, unsigned int thisctx, RAW_EXTENSION *exts); -__owur int extension_is_relevant(SSL *s, unsigned int extctx, +__owur int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx); -__owur int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, +__owur int tls_collect_extensions(SSL_CONNECTION *s, PACKET *packet, + unsigned int context, RAW_EXTENSION **res, size_t *len, int init); -__owur int tls_parse_extension(SSL *s, TLSEXT_INDEX idx, int context, +__owur int tls_parse_extension(SSL_CONNECTION *s, TLSEXT_INDEX idx, int context, RAW_EXTENSION *exts, X509 *x, size_t chainidx); -__owur int tls_parse_all_extensions(SSL *s, int context, RAW_EXTENSION *exts, +__owur int tls_parse_all_extensions(SSL_CONNECTION *s, int context, + RAW_EXTENSION *exts, X509 *x, size_t chainidx, int fin); -__owur int should_add_extension(SSL *s, unsigned int extctx, +__owur int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx, int max_version); -__owur int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, +__owur int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -__owur int tls_psk_do_binder(SSL *s, const EVP_MD *md, +__owur int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *msgstart, size_t binderoffset, const unsigned char *binderin, unsigned char *binderout, SSL_SESSION *sess, int sign, int external); /* Server Extension processing */ -int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_renegotiate(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_maxfragmentlen(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRP -int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_ctos_srp(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #endif -int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_early_data(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidxl); -int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_session_ticket(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_sig_algs_cert(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_ctos_sig_algs(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_OCSP -int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_status_request(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_parse_ctos_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_ctos_npn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #endif -int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_ctos_alpn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRTP -int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_ctos_use_srtp(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif -int tls_parse_ctos_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_ctos_etm(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); +int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_ems(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_post_handshake_auth(SSL *, PACKET *pkt, unsigned int context, +int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_post_handshake_auth(SSL_CONNECTION *, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_renegotiate(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_early_data(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_OCSP -EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_next_proto_neg(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #endif -EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_alpn(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRTP -EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); +EXT_RETURN tls_construct_stoc_use_srtp(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); #endif -EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_etm(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_ems(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); /* * Not in public headers as this is not an official extension. Only used when * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set. */ #define TLSEXT_TYPE_cryptopro_bug 0xfde8 -EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_psk(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); /* Client Extension processing */ -EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_renegotiate(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +EXT_RETURN tls_construct_ctos_server_name(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRP -EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +EXT_RETURN tls_construct_ctos_srp(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx); #endif -EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_sig_algs(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_OCSP -EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_status_request(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_npn(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif -EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_alpn(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRTP -EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_use_srtp(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif -EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_etm(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_CT -EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_sct(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif -EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_ems(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_cookie(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, +EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL_CONNECTION *s, WPACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_renegotiate(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_server_name(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_early_data(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_maxfragmentlen(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_session_ticket(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_OCSP -int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif #ifndef OPENSSL_NO_CT -int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_stoc_sct(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_stoc_npn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #endif -int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_stoc_alpn(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); #ifndef OPENSSL_NO_SRTP -int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_stoc_use_srtp(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); #endif -int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context, +int tls_parse_stoc_etm(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_stoc_ems(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); +int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, X509 *x, size_t chainidx); +int tls_parse_stoc_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_stoc_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); + +int tls_handle_alpn(SSL_CONNECTION *s); -int tls_handle_alpn(SSL *s); +int tls13_save_handshake_digest_for_pha(SSL_CONNECTION *s); +int tls13_restore_handshake_digest_for_pha(SSL_CONNECTION *s); -int tls13_save_handshake_digest_for_pha(SSL *s); -int tls13_restore_handshake_digest_for_pha(SSL *s); +__owur EVP_PKEY* tls_get_peer_pkey(const SSL_CONNECTION *sc); +/* RFC7250 */ +EXT_RETURN tls_construct_ctos_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_client_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_stoc_client_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +EXT_RETURN tls_construct_ctos_server_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +EXT_RETURN tls_construct_stoc_server_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_ctos_server_cert_type(SSL_CONNECTION *sc, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); +int tls_parse_stoc_server_cert_type(SSL_CONNECTION *s, PACKET *pkt, + unsigned int context, + X509 *x, size_t chainidx); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 5d59d53563..853af8c0aa 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -26,6 +26,7 @@ #include #include #include +#include #define TICKET_NONCE_SIZE 8 @@ -43,7 +44,13 @@ ASN1_SEQUENCE(GOST_KX_MESSAGE) = { IMPLEMENT_ASN1_FUNCTIONS(GOST_KX_MESSAGE) -static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt); +static CON_FUNC_RETURN tls_construct_encrypted_extensions(SSL_CONNECTION *s, + WPACKET *pkt); + +static ossl_inline int received_client_cert(const SSL_CONNECTION *sc) +{ + return sc->session->peer_rpk != NULL || sc->session->peer != NULL; +} /* * ossl_statem_server13_read_transition() encapsulates the logic for the allowed @@ -54,7 +61,7 @@ static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt); * Return values are 1 for success (transition allowed) and 0 on error * (transition not allowed) */ -static int ossl_statem_server13_read_transition(SSL *s, int mt) +static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; @@ -90,6 +97,13 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_SR_CERT; return 1; } +#ifndef OPENSSL_NO_COMP_ALG + if (mt == SSL3_MT_COMPRESSED_CERTIFICATE + && s->ext.compress_certificate_sent) { + st->hand_state = TLS_ST_SR_COMP_CERT; + return 1; + } +#endif } else { if (mt == SSL3_MT_FINISHED) { st->hand_state = TLS_ST_SR_FINISHED; @@ -98,8 +112,9 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) } break; + case TLS_ST_SR_COMP_CERT: case TLS_ST_SR_CERT: - if (s->session->peer == NULL) { + if (!received_client_cert(s)) { if (mt == SSL3_MT_FINISHED) { st->hand_state = TLS_ST_SR_FINISHED; return 1; @@ -127,13 +142,21 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) if (s->early_data_state == SSL_EARLY_DATA_READING) break; - if (mt == SSL3_MT_CERTIFICATE - && s->post_handshake_auth == SSL_PHA_REQUESTED) { - st->hand_state = TLS_ST_SR_CERT; - return 1; + if (s->post_handshake_auth == SSL_PHA_REQUESTED) { + if (mt == SSL3_MT_CERTIFICATE) { + st->hand_state = TLS_ST_SR_CERT; + return 1; + } +#ifndef OPENSSL_NO_COMP_ALG + if (mt == SSL3_MT_COMPRESSED_CERTIFICATE + && s->ext.compress_certificate_sent) { + st->hand_state = TLS_ST_SR_COMP_CERT; + return 1; + } +#endif } - if (mt == SSL3_MT_KEY_UPDATE) { + if (mt == SSL3_MT_KEY_UPDATE && !SSL_IS_QUIC_HANDSHAKE(s)) { st->hand_state = TLS_ST_SR_KEY_UPDATE; return 1; } @@ -153,11 +176,11 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) * Return values are 1 for success (transition allowed) and 0 on error * (transition not allowed) */ -int ossl_statem_server_read_transition(SSL *s, int mt) +int ossl_statem_server_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (!ossl_statem_server13_read_transition(s, mt)) goto err; return 1; @@ -232,7 +255,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) * the case of static DH). In that case |st->no_cert_verify| should be * set. */ - if (s->session->peer == NULL || st->no_cert_verify) { + if (!received_client_cert(s) || st->no_cert_verify) { if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) { /* * For the ECDH ciphersuites when the client sends its ECDH @@ -295,7 +318,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) err: /* No valid transition found */ - if (SSL_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + if (SSL_CONNECTION_IS_DTLS(s) && mt == SSL3_MT_CHANGE_CIPHER_SPEC) { BIO *rbio; /* @@ -304,7 +327,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) */ s->init_num = 0; s->rwstate = SSL_READING; - rbio = SSL_get_rbio(s); + rbio = SSL_get_rbio(SSL_CONNECTION_GET_SSL(s)); BIO_clear_retry_flags(rbio); BIO_set_retry_read(rbio); return 0; @@ -320,7 +343,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) * 1: Yes * 0: No */ -static int send_server_key_exchange(SSL *s) +static int send_server_key_exchange(SSL_CONNECTION *s) { unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; @@ -355,6 +378,27 @@ static int send_server_key_exchange(SSL *s) return 0; } +/* + * Used to determine if we should send a CompressedCertificate message + * + * Returns the algorithm to use, TLSEXT_comp_cert_none means no compression + */ +static int get_compressed_certificate_alg(SSL_CONNECTION *sc) +{ +#ifndef OPENSSL_NO_COMP_ALG + int *alg = sc->ext.compress_certificate_from_peer; + + if (sc->s3.tmp.cert == NULL) + return TLSEXT_comp_cert_none; + + for (; *alg != TLSEXT_comp_cert_none; alg++) { + if (sc->s3.tmp.cert->comp_cert[*alg] != NULL) + return *alg; + } +#endif + return TLSEXT_comp_cert_none; +} + /* * Should we send a CertificateRequest message? * @@ -362,7 +406,7 @@ static int send_server_key_exchange(SSL *s) * 1: Yes * 0: No */ -int send_certificate_request(SSL *s) +int send_certificate_request(SSL_CONNECTION *s) { if ( /* don't request cert unless asked for it: */ @@ -371,7 +415,8 @@ int send_certificate_request(SSL *s) * don't request if post-handshake-only unless doing * post-handshake in TLSv1.3: */ - && (!SSL_IS_TLS13(s) || !(s->verify_mode & SSL_VERIFY_POST_HANDSHAKE) + && (!SSL_CONNECTION_IS_TLS13(s) + || !(s->verify_mode & SSL_VERIFY_POST_HANDSHAKE) || s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) /* * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert @@ -404,12 +449,19 @@ int send_certificate_request(SSL *s) return 0; } +static int do_compressed_cert(SSL_CONNECTION *sc) +{ + /* If we negotiated RPK, we won't attempt to compress it */ + return sc->ext.server_cert_type == TLSEXT_cert_type_x509 + && get_compressed_certificate_alg(sc) != TLSEXT_comp_cert_none; +} + /* * ossl_statem_server13_write_transition() works out what handshake state to * move to next when a TLSv1.3 server is writing messages to be sent to the * client. */ -static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) +static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -466,6 +518,8 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) st->hand_state = TLS_ST_SW_FINISHED; else if (send_certificate_request(s)) st->hand_state = TLS_ST_SW_CERT_REQ; + else if (do_compressed_cert(s)) + st->hand_state = TLS_ST_SW_COMP_CERT; else st->hand_state = TLS_ST_SW_CERT; @@ -475,11 +529,14 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) { s->post_handshake_auth = SSL_PHA_REQUESTED; st->hand_state = TLS_ST_OK; + } else if (do_compressed_cert(s)) { + st->hand_state = TLS_ST_SW_COMP_CERT; } else { st->hand_state = TLS_ST_SW_CERT; } return WRITE_TRAN_CONTINUE; + case TLS_ST_SW_COMP_CERT: case TLS_ST_SW_CERT: st->hand_state = TLS_ST_SW_CERT_VRFY; return WRITE_TRAN_CONTINUE; @@ -490,12 +547,14 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) case TLS_ST_SW_FINISHED: st->hand_state = TLS_ST_EARLY_DATA; + s->ts_msg_write = ossl_time_now(); return WRITE_TRAN_CONTINUE; case TLS_ST_EARLY_DATA: return WRITE_TRAN_FINISHED; case TLS_ST_SR_FINISHED: + s->ts_msg_read = ossl_time_now(); /* * Technically we have finished the handshake at this point, but we're * going to remain "in_init" for now and write out any session tickets @@ -541,7 +600,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) * ossl_statem_server_write_transition() works out what handshake state to move * to next when the server is writing messages to be sent to the client. */ -WRITE_TRAN ossl_statem_server_write_transition(SSL *s) +WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -550,7 +609,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) * to negotiate yet, so we don't take this branch until later */ - if (SSL_IS_TLS13(s)) + if (SSL_CONNECTION_IS_TLS13(s)) return ossl_statem_server13_write_transition(s); switch (st->hand_state) { @@ -582,8 +641,8 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_SR_CLNT_HELLO: - if (SSL_IS_DTLS(s) && !s->d1->cookie_verified - && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) { + if (SSL_CONNECTION_IS_DTLS(s) && !s->d1->cookie_verified + && (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE)) { st->hand_state = DTLS_ST_SW_HELLO_VERIFY_REQUEST; } else if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) { /* We must have rejected the renegotiation */ @@ -645,9 +704,11 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_SW_SRVR_DONE: + s->ts_msg_write = ossl_time_now(); return WRITE_TRAN_FINISHED; case TLS_ST_SR_FINISHED: + s->ts_msg_read = ossl_time_now(); if (s->hit) { st->hand_state = TLS_ST_OK; return WRITE_TRAN_CONTINUE; @@ -679,9 +740,10 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) * Perform any pre work that needs to be done prior to sending a message from * the server to the client. */ -WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); switch (st->hand_state) { default: @@ -690,13 +752,13 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) case TLS_ST_SW_HELLO_REQ: s->shutdown = 0; - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) dtls1_clear_sent_buffer(s); break; case DTLS_ST_SW_HELLO_VERIFY_REQUEST: s->shutdown = 0; - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { dtls1_clear_sent_buffer(s); /* We don't buffer this message so don't use the timer */ st->use_timer = 0; @@ -704,7 +766,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) break; case TLS_ST_SW_SRVR_HELLO: - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* * Messages we write from now on should be buffered and * retransmitted if necessary, so we need to use the timer now @@ -715,7 +777,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) case TLS_ST_SW_SRVR_DONE: #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) { + if (SSL_CONNECTION_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { /* Calls SSLfatal() as required */ return dtls_wait_for_dry(s); } @@ -723,7 +785,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; case TLS_ST_SW_SESSION_TICKET: - if (SSL_IS_TLS13(s) && s->sent_tickets == 0 + if (SSL_CONNECTION_IS_TLS13(s) && s->sent_tickets == 0 && s->ext.extra_tickets_expected == 0) { /* * Actually this is the end of the handshake, but we're going @@ -734,7 +796,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) */ return tls_finish_handshake(s, wst, 0, 0); } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* * We're into the last flight. We don't retransmit the last flight * unless we need to, so we don't use the timer @@ -744,7 +806,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) break; case TLS_ST_SW_CHANGE: - if (SSL_IS_TLS13(s)) + if (SSL_CONNECTION_IS_TLS13(s)) break; /* Writes to s->session are only safe for initial handshakes */ if (s->session->cipher == NULL) { @@ -753,11 +815,11 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } - if (!s->method->ssl3_enc->setup_key_block(s)) { + if (!ssl->method->ssl3_enc->setup_key_block(s)) { /* SSLfatal() already called */ return WORK_ERROR; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* * We're into the last flight. We don't retransmit the last flight * unless we need to, so we don't use the timer. This might have @@ -806,9 +868,10 @@ static ossl_inline int conn_is_closed(void) * Perform any work that needs to be done after sending a message from the * server to the client. */ -WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); s->init_num = 0; @@ -842,14 +905,15 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) break; case TLS_ST_SW_SRVR_HELLO: - if (SSL_IS_TLS13(s) && s->hello_retry_request == SSL_HRR_PENDING) { + if (SSL_CONNECTION_IS_TLS13(s) + && s->hello_retry_request == SSL_HRR_PENDING) { if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0 && statem_flush(s) != 1) return WORK_MORE_A; break; } #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && s->hit) { + if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -866,7 +930,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG) labellen += 1; - if (SSL_export_keying_material(s, sctpauthkey, + if (SSL_export_keying_material(ssl, sctpauthkey, sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { @@ -874,11 +938,11 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) return WORK_ERROR; } - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); } #endif - if (!SSL_IS_TLS13(s) + if (!SSL_CONNECTION_IS_TLS13(s) || ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 && s->hello_retry_request != SSL_HRR_COMPLETE)) break; @@ -891,16 +955,16 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) break; } - if (SSL_IS_TLS13(s)) { - if (!s->method->ssl3_enc->setup_key_block(s) - || !s->method->ssl3_enc->change_cipher_state(s, + if (SSL_CONNECTION_IS_TLS13(s)) { + if (!ssl->method->ssl3_enc->setup_key_block(s) + || !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE)) { /* SSLfatal() already called */ return WORK_ERROR; } if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED - && !s->method->ssl3_enc->change_cipher_state(s, + && !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE |SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return WORK_ERROR; @@ -910,29 +974,29 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) * is an unencrypted alert, an encrypted alert, or an encrypted * handshake message. We temporarily tolerate unencrypted alerts. */ - s->statem.enc_read_state = ENC_READ_STATE_ALLOW_PLAIN_ALERTS; + if (s->rlayer.rrlmethod->set_plain_alerts != NULL) + s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 1); break; } #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && !s->hit) { + if (SSL_CONNECTION_IS_DTLS(s) && !s->hit) { /* * Change to new shared key of SCTP-Auth, will be ignored if * no SCTP used. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); } #endif - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_SERVER_WRITE)) - { + if (!ssl->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) { /* SSLfatal() already called */ return WORK_ERROR; } - if (SSL_IS_DTLS(s)) - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + if (SSL_CONNECTION_IS_DTLS(s)) + dtls1_increment_epoch(s, SSL3_CC_WRITE); break; case TLS_ST_SW_SRVR_DONE: @@ -944,22 +1008,22 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) if (statem_flush(s) != 1) return WORK_MORE_A; #ifndef OPENSSL_NO_SCTP - if (SSL_IS_DTLS(s) && s->hit) { + if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { /* * Change to new shared key of SCTP-Auth, will be ignored if * no SCTP used. */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); } #endif - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* TLS 1.3 gets the secret size from the handshake md */ size_t dummy; - if (!s->method->ssl3_enc->generate_master_secret(s, + if (!ssl->method->ssl3_enc->generate_master_secret(s, s->master_secret, s->handshake_secret, 0, &dummy) - || !s->method->ssl3_enc->change_cipher_state(s, + || !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_WRITE)) /* SSLfatal() already called */ return WORK_ERROR; @@ -970,6 +1034,18 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) { if (statem_flush(s) != 1) return WORK_MORE_A; + } else { + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) + s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; + } + break; + + case TLS_ST_SW_ENCRYPTED_EXTENSIONS: + if (!s->hit && !send_certificate_request(s)) { + if (!SSL_CONNECTION_IS_TLS13(s) + || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) + s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; } break; @@ -984,8 +1060,8 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) case TLS_ST_SW_SESSION_TICKET: clear_sys_error(); - if (SSL_IS_TLS13(s) && statem_flush(s) != 1) { - if (SSL_get_error(s, 0) == SSL_ERROR_SYSCALL + if (SSL_CONNECTION_IS_TLS13(s) && statem_flush(s) != 1) { + if (SSL_get_error(ssl, 0) == SSL_ERROR_SYSCALL && conn_is_closed()) { /* * We ignore connection closed errors in TLSv1.3 when sending a @@ -1014,7 +1090,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) * 1: Success * 0: Error */ -int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, +int ossl_statem_server_construct_message(SSL_CONNECTION *s, confunc_f *confunc, int *mt) { OSSL_STATEM *st = &s->statem; @@ -1026,7 +1102,7 @@ int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, return 0; case TLS_ST_SW_CHANGE: - if (SSL_IS_DTLS(s)) + if (SSL_CONNECTION_IS_DTLS(s)) *confunc = dtls_construct_change_cipher_spec; else *confunc = tls_construct_change_cipher_spec; @@ -1054,6 +1130,13 @@ int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, *mt = SSL3_MT_CERTIFICATE; break; +#ifndef OPENSSL_NO_COMP_ALG + case TLS_ST_SW_COMP_CERT: + *confunc = tls_construct_server_compressed_certificate; + *mt = SSL3_MT_COMPRESSED_CERTIFICATE; + break; +#endif + case TLS_ST_SW_CERT_VRFY: *confunc = tls_construct_cert_verify; *mt = SSL3_MT_CERTIFICATE_VERIFY; @@ -1133,7 +1216,7 @@ int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, * Returns the maximum allowed length for the current message that we are * reading. Excludes the message header. */ -size_t ossl_statem_server_max_message_size(SSL *s) +size_t ossl_statem_server_max_message_size(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; @@ -1148,6 +1231,7 @@ size_t ossl_statem_server_max_message_size(SSL *s) case TLS_ST_SR_END_OF_EARLY_DATA: return END_OF_EARLY_DATA_MAX_LENGTH; + case TLS_ST_SR_COMP_CERT: case TLS_ST_SR_CERT: return s->max_cert_list; @@ -1155,7 +1239,7 @@ size_t ossl_statem_server_max_message_size(SSL *s) return CLIENT_KEY_EXCH_MAX_LENGTH; case TLS_ST_SR_CERT_VRFY: - return SSL3_RT_MAX_PLAIN_LENGTH; + return CERTIFICATE_VERIFY_MAX_LENGTH; #ifndef OPENSSL_NO_NEXTPROTONEG case TLS_ST_SR_NEXT_PROTO: @@ -1176,7 +1260,8 @@ size_t ossl_statem_server_max_message_size(SSL *s) /* * Process a message that the server has received from the client. */ -MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL_CONNECTION *s, + PACKET *pkt) { OSSL_STATEM *st = &s->statem; @@ -1195,6 +1280,11 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt) case TLS_ST_SR_CERT: return tls_process_client_certificate(s, pkt); +#ifndef OPENSSL_NO_COMP_ALG + case TLS_ST_SR_COMP_CERT: + return tls_process_client_compressed_certificate(s, pkt); +#endif + case TLS_ST_SR_KEY_EXCH: return tls_process_client_key_exchange(s, pkt); @@ -1222,7 +1312,8 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt) * Perform any further processing required following the receipt of a message * from the client */ -WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) +WORK_STATE ossl_statem_server_post_process_message(SSL_CONNECTION *s, + WORK_STATE wst) { OSSL_STATEM *st = &s->statem; @@ -1242,7 +1333,7 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) #ifndef OPENSSL_NO_SRP /* Returns 1 on success, 0 for retryable error, -1 for fatal error */ -static int ssl_check_srp_ext_ClientHello(SSL *s) +static int ssl_check_srp_ext_ClientHello(SSL_CONNECTION *s) { int ret; int al = SSL_AD_UNRECOGNIZED_NAME; @@ -1285,25 +1376,28 @@ int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, return 1; } -int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN dtls_construct_hello_verify_request(SSL_CONNECTION *s, + WPACKET *pkt) { unsigned int cookie_leni; - if (s->ctx->app_gen_cookie_cb == NULL || - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &cookie_leni) == 0 || - cookie_leni > DTLS1_COOKIE_LENGTH) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + + if (sctx->app_gen_cookie_cb == NULL + || sctx->app_gen_cookie_cb(SSL_CONNECTION_GET_SSL(s), s->d1->cookie, + &cookie_leni) == 0 + || cookie_leni > DTLS1_COOKIE_LENGTH) { SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); - return 0; + return CON_FUNC_ERROR; } s->d1->cookie_len = cookie_leni; if (!dtls_raw_hello_verify_request(pkt, s->d1->cookie, - s->d1->cookie_len)) { + s->d1->cookie_len)) { SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } /*- @@ -1320,7 +1414,8 @@ int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt) * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from * 10.8..10.8.3 (which don't work). */ -static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello) +static void ssl_check_for_safari(SSL_CONNECTION *s, + const CLIENTHELLO_MSG *hello) { static const unsigned char kSafariExtensionsBlock[] = { 0x00, 0x0a, /* elliptic_curves extension */ @@ -1361,8 +1456,9 @@ static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello) if (type != TLSEXT_TYPE_server_name) return; - ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ? - sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength; + ext_len = TLS1_get_client_version( + SSL_CONNECTION_GET_SSL(s)) >= TLS1_2_VERSION ? + sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength; s->s3.is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock, ext_len); @@ -1372,7 +1468,7 @@ static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello) ((options & SSL_OP_NO_RENEGOTIATION) == 0 \ && (options & SSL_OP_ALLOW_CLIENT_RENEGOTIATION) != 0) -MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) { /* |cookie| will only be initialized for DTLS. */ PACKET session_id, compression, extensions, cookie; @@ -1381,7 +1477,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) /* Check if this is actually an unexpected renegotiation ClientHello */ if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) { - if (!ossl_assert(!SSL_IS_TLS13(s))) { + if (!ossl_assert(!SSL_CONNECTION_IS_TLS13(s))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1511,7 +1607,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) goto err; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; @@ -1527,7 +1623,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) * just return since we do not want to allocate any memory yet. * So check cookie length... */ - if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + if (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) { if (clienthello->dtls_cookie_len == 0) { OPENSSL_free(clienthello); return MSG_PROCESS_FINISHED_READING; @@ -1584,7 +1680,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -static int tls_early_post_process_client_hello(SSL *s) +static int tls_early_post_process_client_hello(SSL_CONNECTION *s) { unsigned int j; int i, al = SSL_AD_INTERNAL_ERROR; @@ -1599,12 +1695,14 @@ static int tls_early_post_process_client_hello(SSL *s) STACK_OF(SSL_CIPHER) *scsvs = NULL; CLIENTHELLO_MSG *clienthello = s->clienthello; DOWNGRADE dgrd = DOWNGRADE_NONE; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + SSL *ssl = SSL_CONNECTION_GET_SSL(s); /* Finished parsing the ClientHello, now we can start processing it */ /* Give the ClientHello callback a crack at things */ - if (s->ctx->client_hello_cb != NULL) { + if (sctx->client_hello_cb != NULL) { /* A failure in the ClientHello callback terminates the connection. */ - switch (s->ctx->client_hello_cb(s, &al, s->ctx->client_hello_cb_arg)) { + switch (sctx->client_hello_cb(ssl, &al, sctx->client_hello_cb_arg)) { case SSL_CLIENT_HELLO_SUCCESS: break; case SSL_CLIENT_HELLO_RETRY: @@ -1640,9 +1738,9 @@ static int tls_early_post_process_client_hello(SSL *s) * Do SSL/TLS version negotiation if applicable. For DTLS we just check * versions are potentially compatible. Version negotiation comes later. */ - if (!SSL_IS_DTLS(s)) { + if (!SSL_CONNECTION_IS_DTLS(s)) { protverr = ssl_choose_server_version(s, clienthello, &dgrd); - } else if (s->method->version != DTLS_ANY_VERSION && + } else if (ssl->method->version != DTLS_ANY_VERSION && DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) { protverr = SSL_R_VERSION_TOO_LOW; } else { @@ -1659,16 +1757,17 @@ static int tls_early_post_process_client_hello(SSL *s) } /* TLSv1.3 specifies that a ClientHello must end on a record boundary */ - if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { + if (SSL_CONNECTION_IS_TLS13(s) + && RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); goto err; } - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { /* Empty cookie was already handled above by returning early. */ - if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { - if (s->ctx->app_verify_cookie_cb != NULL) { - if (s->ctx->app_verify_cookie_cb(s, clienthello->dtls_cookie, + if (SSL_get_options(ssl) & SSL_OP_COOKIE_EXCHANGE) { + if (sctx->app_verify_cookie_cb != NULL) { + if (sctx->app_verify_cookie_cb(ssl, clienthello->dtls_cookie, clienthello->dtls_cookie_len) == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_COOKIE_MISMATCH); @@ -1684,7 +1783,7 @@ static int tls_early_post_process_client_hello(SSL *s) } s->d1->cookie_verified = 1; } - if (s->method->version == DTLS_ANY_VERSION) { + if (ssl->method->version == DTLS_ANY_VERSION) { protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr != 0) { s->version = s->client_version; @@ -1698,8 +1797,8 @@ static int tls_early_post_process_client_hello(SSL *s) if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites, clienthello->isv2) || - !bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, &scsvs, - clienthello->isv2, 1)) { + !ossl_bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, + &scsvs, clienthello->isv2, 1)) { /* SSLfatal() already called */ goto err; } @@ -1707,7 +1806,7 @@ static int tls_early_post_process_client_hello(SSL *s) s->s3.send_connection_binding = 0; /* Check what signalling cipher-suite values were received. */ if (scsvs != NULL) { - for(i = 0; i < sk_SSL_CIPHER_num(scsvs); i++) { + for (i = 0; i < sk_SSL_CIPHER_num(scsvs); i++) { c = sk_SSL_CIPHER_value(scsvs, i); if (SSL_CIPHER_get_id(c) == SSL3_CK_SCSV) { if (s->renegotiate) { @@ -1734,9 +1833,9 @@ static int tls_early_post_process_client_hello(SSL *s) } /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { const SSL_CIPHER *cipher = - ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s)); + ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(ssl)); if (cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_CIPHER); @@ -1803,7 +1902,7 @@ static int tls_early_post_process_client_hello(SSL *s) } } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { memcpy(s->tmp_session_id, s->clienthello->session_id, s->clienthello->session_id_len); s->tmp_session_id_len = s->clienthello->session_id_len; @@ -1813,7 +1912,7 @@ static int tls_early_post_process_client_hello(SSL *s) * If it is a hit, check that the cipher is in the list. In TLSv1.3 we check * ciphersuite compatibility with the session as part of resumption. */ - if (!SSL_IS_TLS13(s) && s->hit) { + if (!SSL_CONNECTION_IS_TLS13(s) && s->hit) { j = 0; id = s->session->cipher->id; @@ -1882,9 +1981,9 @@ static int tls_early_post_process_client_hello(SSL *s) if (!s->hit && s->version >= TLS1_VERSION - && !SSL_IS_TLS13(s) - && !SSL_IS_DTLS(s) - && s->ext.session_secret_cb) { + && !SSL_CONNECTION_IS_TLS13(s) + && !SSL_CONNECTION_IS_DTLS(s) + && s->ext.session_secret_cb != NULL) { const SSL_CIPHER *pref_cipher = NULL; /* * s->session->master_key_length is a size_t, but this is an int for @@ -1893,7 +1992,7 @@ static int tls_early_post_process_client_hello(SSL *s) int master_key_length; master_key_length = sizeof(s->session->master_key); - if (s->ext.session_secret_cb(s, s->session->master_key, + if (s->ext.session_secret_cb(ssl, s->session->master_key, &master_key_length, ciphers, &pref_cipher, s->ext.session_secret_cb_arg) @@ -1908,7 +2007,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* check if some cipher was preferred by call back */ if (pref_cipher == NULL) pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, - SSL_get_ciphers(s)); + SSL_get_ciphers(ssl)); if (pref_cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_CIPHER); goto err; @@ -1928,7 +2027,7 @@ static int tls_early_post_process_client_hello(SSL *s) * algorithms from the client, starting at q. */ s->s3.tmp.new_compression = NULL; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * We already checked above that the NULL compression method appears in * the list. Now we check there aren't any others (which is illegal in @@ -1953,8 +2052,8 @@ static int tls_early_post_process_client_hello(SSL *s) goto err; } /* Look for resumed compression method */ - for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + for (m = 0; m < sk_SSL_COMP_num(sctx->comp_methods); m++) { + comp = sk_SSL_COMP_value(sctx->comp_methods, m); if (comp_id == comp->id) { s->s3.tmp.new_compression = comp; break; @@ -1977,14 +2076,14 @@ static int tls_early_post_process_client_hello(SSL *s) } } else if (s->hit) { comp = NULL; - } else if (ssl_allow_compression(s) && s->ctx->comp_methods) { + } else if (ssl_allow_compression(s) && sctx->comp_methods) { /* See if we have a match */ int m, nn, v, done = 0; unsigned int o; - nn = sk_SSL_COMP_num(s->ctx->comp_methods); + nn = sk_SSL_COMP_num(sctx->comp_methods); for (m = 0; m < nn; m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + comp = sk_SSL_COMP_value(sctx->comp_methods, m); v = comp->id; for (o = 0; o < clienthello->compressions_len; o++) { if (v == clienthello->compressions[o]) { @@ -2015,7 +2114,7 @@ static int tls_early_post_process_client_hello(SSL *s) * Given s->peer_ciphers and SSL_get_ciphers, we must pick a cipher */ - if (!s->hit || SSL_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { sk_SSL_CIPHER_free(s->peer_ciphers); s->peer_ciphers = ciphers; if (ciphers == NULL) { @@ -2057,8 +2156,10 @@ static int tls_early_post_process_client_hello(SSL *s) * Call the status request callback if needed. Upon success, returns 1. * Upon failure, returns 0. */ -static int tls_handle_status_request(SSL *s) +static int tls_handle_status_request(SSL_CONNECTION *s) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + s->ext.status_expected = 0; /* @@ -2067,8 +2168,8 @@ static int tls_handle_status_request(SSL *s) * and must be called after the cipher has been chosen because this may * influence which certificate is sent */ - if (s->ext.status_type != TLSEXT_STATUSTYPE_nothing && s->ctx != NULL - && s->ctx->ext.status_cb != NULL) { + if (s->ext.status_type != TLSEXT_STATUSTYPE_nothing && sctx != NULL + && sctx->ext.status_cb != NULL) { int ret; /* If no certificate can't return certificate status */ @@ -2078,7 +2179,8 @@ static int tls_handle_status_request(SSL *s) * et al can pick it up. */ s->cert->key = s->s3.tmp.cert; - ret = s->ctx->ext.status_cb(s, s->ctx->ext.status_arg); + ret = sctx->ext.status_cb(SSL_CONNECTION_GET_SSL(s), + sctx->ext.status_arg); switch (ret) { /* We don't want to send a status request response */ case SSL_TLSEXT_ERR_NOACK: @@ -2105,16 +2207,18 @@ static int tls_handle_status_request(SSL *s) * Call the alpn_select callback if needed. Upon success, returns 1. * Upon failure, returns 0. */ -int tls_handle_alpn(SSL *s) +int tls_handle_alpn(SSL_CONNECTION *s) { const unsigned char *selected = NULL; unsigned char selected_len = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - if (s->ctx->ext.alpn_select_cb != NULL && s->s3.alpn_proposed != NULL) { - int r = s->ctx->ext.alpn_select_cb(s, &selected, &selected_len, - s->s3.alpn_proposed, - (unsigned int)s->s3.alpn_proposed_len, - s->ctx->ext.alpn_select_cb_arg); + if (sctx->ext.alpn_select_cb != NULL && s->s3.alpn_proposed != NULL) { + int r = sctx->ext.alpn_select_cb(SSL_CONNECTION_GET_SSL(s), + &selected, &selected_len, + s->s3.alpn_proposed, + (unsigned int)s->s3.alpn_proposed_len, + sctx->ext.alpn_select_cb_arg); if (r == SSL_TLSEXT_ERR_OK) { OPENSSL_free(s->s3.alpn_selected); @@ -2181,9 +2285,10 @@ int tls_handle_alpn(SSL *s) return 1; } -WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) +WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst) { const SSL_CIPHER *cipher; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (wst == WORK_MORE_A) { int rv = tls_early_post_process_client_hello(s); @@ -2196,10 +2301,10 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) wst = WORK_MORE_B; } if (wst == WORK_MORE_B) { - if (!s->hit || SSL_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { /* Let cert callback update server certificates if required */ if (!s->hit && s->cert->cert_cb != NULL) { - int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + int rv = s->cert->cert_cb(ssl, s->cert->cert_cb_arg); if (rv == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CERT_CB_ERROR); goto err; @@ -2212,9 +2317,10 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) } /* In TLSv1.3 we selected the ciphersuite before resumption */ - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { cipher = - ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(s)); + ssl3_choose_cipher(s, s->peer_ciphers, + SSL_get_ciphers(ssl)); if (cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, @@ -2231,7 +2337,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) /* check whether we should disable session resumption */ if (s->not_resumable_session_cb != NULL) s->session->not_resumable = - s->not_resumable_session_cb(s, + s->not_resumable_session_cb(ssl, ((s->s3.tmp.new_cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) != 0)); if (s->session->not_resumable) @@ -2247,7 +2353,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) * we now have the following setup. * client_random * cipher_list - our preferred list of ciphers - * ciphers - the clients preferred list of ciphers + * ciphers - the client's preferred list of ciphers * compression - basically ignored right now * ssl version is set - sslv3 * s->session - The ssl session has been setup. @@ -2269,7 +2375,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) * we already did this because cipher negotiation happens earlier, and * we must handle ALPN before we decide whether to accept early_data. */ - if (!SSL_IS_TLS13(s) && !tls_handle_alpn(s)) { + if (!SSL_CONNECTION_IS_TLS13(s) && !tls_handle_alpn(s)) { /* SSLfatal() already called */ goto err; } @@ -2298,13 +2404,14 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) return WORK_ERROR; } -int tls_construct_server_hello(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) { int compm; size_t sl, len; int version; unsigned char *session_id; - int usetls13 = SSL_IS_TLS13(s) || s->hello_retry_request == SSL_HRR_PENDING; + int usetls13 = SSL_CONNECTION_IS_TLS13(s) + || s->hello_retry_request == SSL_HRR_PENDING; version = usetls13 ? TLS1_2_VERSION : s->version; if (!WPACKET_put_bytes_u16(pkt, version) @@ -2317,7 +2424,7 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) ? hrrrandom : s->s3.server_random, SSL3_RANDOM_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /*- @@ -2339,7 +2446,7 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) * to send back. */ if (s->session->not_resumable || - (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + (!(SSL_CONNECTION_GET_CTX(s)->session_cache_mode & SSL_SESS_CACHE_SERVER) && !s->hit)) s->session->session_id_length = 0; @@ -2353,7 +2460,7 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) if (sl > sizeof(s->session->session_id)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* set up the compression method */ @@ -2367,21 +2474,22 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) #endif if (!WPACKET_sub_memcpy_u8(pkt, session_id, sl) - || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &len) + || !SSL_CONNECTION_GET_SSL(s)->method->put_cipher_by_char(s->s3.tmp.new_cipher, + pkt, &len) || !WPACKET_put_bytes_u8(pkt, compm)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } if (!tls_construct_extensions(s, pkt, s->hello_retry_request == SSL_HRR_PENDING ? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - : (SSL_IS_TLS13(s) + : (SSL_CONNECTION_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO : SSL_EXT_TLS1_2_SERVER_HELLO), NULL, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } if (s->hello_retry_request == SSL_HRR_PENDING) { @@ -2396,29 +2504,30 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) */ if (!create_synthetic_message_hash(s, NULL, 0, NULL, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } } else if (!(s->verify_mode & SSL_VERIFY_PEER) && !ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */; - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } -int tls_construct_server_done(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_server_done(SSL_CONNECTION *s, WPACKET *pkt) { if (!s->s3.tmp.cert_request) { if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } } - return 1; + return CON_FUNC_SUCCESS; } -int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_server_key_exchange(SSL_CONNECTION *s, + WPACKET *pkt) { EVP_PKEY *pkdh = NULL; unsigned char *encodedPoint = NULL; @@ -2431,7 +2540,9 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); EVP_PKEY_CTX *pctx = NULL; size_t paramlen, paramoffset; - int freer = 0, ret = 0; + int freer = 0; + CON_FUNC_RETURN ret = CON_FUNC_ERROR; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (!WPACKET_get_total_written(pkt, ¶moffset)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -2439,7 +2550,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) } if (md_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -2467,7 +2578,8 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) } #if !defined(OPENSSL_NO_DEPRECATED_3_0) if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) { - pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(s, 0, 1024)); + pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(SSL_CONNECTION_GET_SSL(s), + 0, 1024)); if (pkdh == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -2661,7 +2773,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) unsigned char *sigbytes1, *sigbytes2, *tbs; size_t siglen = 0, tbslen; - if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) { + if (pkey == NULL || !tls1_lookup_md(sctx, lu, &md)) { /* Should never happen */ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -2679,7 +2791,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) if (EVP_DigestSignInit_ex(md_ctx, &pctx, md == NULL ? NULL : EVP_MD_get0_name(md), - s->ctx->libctx, s->ctx->propq, pkey, + sctx->libctx, sctx->propq, pkey, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -2711,7 +2823,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) OPENSSL_free(tbs); } - ret = 1; + ret = CON_FUNC_SUCCESS; err: EVP_PKEY_free(pkdh); OPENSSL_free(encodedPoint); @@ -2725,9 +2837,10 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) return ret; } -int tls_construct_certificate_request(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_certificate_request(SSL_CONNECTION *s, + WPACKET *pkt) { - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* Send random context when doing post-handshake auth */ if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) { OPENSSL_free(s->pha_context); @@ -2735,24 +2848,24 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL) { s->pha_context_len = 0; SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } - if (RAND_bytes_ex(s->ctx->libctx, s->pha_context, - s->pha_context_len, 0) <= 0 + if (RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, + s->pha_context, s->pha_context_len, 0) <= 0 || !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* reset the handshake hash back to just after the ClientFinished */ if (!tls13_restore_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } } else { if (!WPACKET_put_bytes_u8(pkt, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } @@ -2760,7 +2873,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) SSL_EXT_TLS1_3_CERTIFICATE_REQUEST, NULL, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } goto done; } @@ -2769,7 +2882,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) if (!WPACKET_start_sub_packet_u8(pkt) || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } if (SSL_USE_SIGALGS(s)) { @@ -2781,22 +2894,22 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) || !tls12_copy_sigalgs(s, pkt, psigs, nl) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } } if (!construct_ca_names(s, get_ca_names(s), pkt)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } done: s->certreqs_sent++; s->s3.tmp.cert_request = 1; - return 1; + return CON_FUNC_SUCCESS; } -static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) +static int tls_process_cke_psk_preamble(SSL_CONNECTION *s, PACKET *pkt) { #ifndef OPENSSL_NO_PSK unsigned char psk[PSK_MAX_PSK_LEN]; @@ -2821,7 +2934,8 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) return 0; } - psklen = s->psk_server_callback(s, s->session->psk_identity, + psklen = s->psk_server_callback(SSL_CONNECTION_GET_SSL(s), + s->session->psk_identity, psk, sizeof(psk)); if (psklen > PSK_MAX_PSK_LEN) { @@ -2841,7 +2955,7 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) if (s->s3.tmp.psk == NULL) { s->s3.tmp.psklen = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } @@ -2855,7 +2969,7 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) #endif } -static int tls_process_cke_rsa(SSL *s, PACKET *pkt) +static int tls_process_cke_rsa(SSL_CONNECTION *s, PACKET *pkt) { size_t outlen; PACKET enc_premaster; @@ -2864,6 +2978,7 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) int ret = 0; EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM params[3], *p = params; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); rsa = s->cert->pkeys[SSL_PKEY_RSA].privatekey; if (rsa == NULL) { @@ -2885,13 +3000,13 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) outlen = SSL_MAX_MASTER_KEY_LENGTH; rsa_decrypt = OPENSSL_malloc(outlen); if (rsa_decrypt == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } - ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, rsa, s->ctx->propq); + ctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, rsa, sctx->propq); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -2939,8 +3054,7 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) } /* Also cleanses rsa_decrypt (on success or failure) */ - if (!ssl_generate_master_secret(s, rsa_decrypt, - SSL_MAX_MASTER_KEY_LENGTH, 0)) { + if (!ssl_generate_master_secret(s, rsa_decrypt, outlen, 0)) { /* SSLfatal() already called */ goto err; } @@ -2952,7 +3066,7 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) return ret; } -static int tls_process_cke_dhe(SSL *s, PACKET *pkt) +static int tls_process_cke_dhe(SSL_CONNECTION *s, PACKET *pkt) { EVP_PKEY *skey = NULL; unsigned int i; @@ -3003,7 +3117,7 @@ static int tls_process_cke_dhe(SSL *s, PACKET *pkt) return ret; } -static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) +static int tls_process_cke_ecdhe(SSL_CONNECTION *s, PACKET *pkt) { EVP_PKEY *skey = s->s3.tmp.pkey; EVP_PKEY *ckey = NULL; @@ -3059,7 +3173,7 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) return ret; } -static int tls_process_cke_srp(SSL *s, PACKET *pkt) +static int tls_process_cke_srp(SSL_CONNECTION *s, PACKET *pkt) { #ifndef OPENSSL_NO_SRP unsigned int i; @@ -3081,7 +3195,7 @@ static int tls_process_cke_srp(SSL *s, PACKET *pkt) OPENSSL_free(s->session->srp_username); s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login); if (s->session->srp_username == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; } @@ -3098,18 +3212,19 @@ static int tls_process_cke_srp(SSL *s, PACKET *pkt) #endif } -static int tls_process_cke_gost(SSL *s, PACKET *pkt) +static int tls_process_cke_gost(SSL_CONNECTION *s, PACKET *pkt) { #ifndef OPENSSL_NO_GOST EVP_PKEY_CTX *pkey_ctx; EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; unsigned char premaster_secret[32]; const unsigned char *start; - size_t outlen = 32, inlen; + size_t outlen = sizeof(premaster_secret), inlen; unsigned long alg_a; GOST_KX_MESSAGE *pKX = NULL; const unsigned char *ptr; int ret = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Get our certificate private key */ alg_a = s->s3.tmp.new_cipher->algorithm_auth; @@ -3128,9 +3243,9 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; } - pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pk, sctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); return 0; } if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { @@ -3143,7 +3258,7 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) * EVP_PKEY_derive_set_peer, because it is completely valid to use a * client certificate for authorization only. */ - client_pub_pkey = X509_get0_pubkey(s->session->peer); + client_pub_pkey = tls_get_peer_pkey(s); if (client_pub_pkey) { if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) ERR_clear_error(); @@ -3179,8 +3294,7 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) goto err; } /* Generate master secret */ - if (!ssl_generate_master_secret(s, premaster_secret, - sizeof(premaster_secret), 0)) { + if (!ssl_generate_master_secret(s, premaster_secret, outlen, 0)) { /* SSLfatal() already called */ goto err; } @@ -3201,7 +3315,7 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) #endif } -static int tls_process_cke_gost18(SSL *s, PACKET *pkt) +static int tls_process_cke_gost18(SSL_CONNECTION *s, PACKET *pkt) { #ifndef OPENSSL_NO_GOST unsigned char rnd_dgst[32]; @@ -3209,9 +3323,10 @@ static int tls_process_cke_gost18(SSL *s, PACKET *pkt) EVP_PKEY *pk = NULL; unsigned char premaster_secret[32]; const unsigned char *start = NULL; - size_t outlen = 32, inlen = 0; + size_t outlen = sizeof(premaster_secret), inlen = 0; int ret = 0; int cipher_nid = ossl_gost18_cke_cipher_nid(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (cipher_nid == NID_undef) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -3232,9 +3347,9 @@ static int tls_process_cke_gost18(SSL *s, PACKET *pkt) goto err; } - pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pk, sctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { @@ -3262,8 +3377,7 @@ static int tls_process_cke_gost18(SSL *s, PACKET *pkt) goto err; } /* Generate master secret */ - if (!ssl_generate_master_secret(s, premaster_secret, - sizeof(premaster_secret), 0)) { + if (!ssl_generate_master_secret(s, premaster_secret, outlen, 0)) { /* SSLfatal() already called */ goto err; } @@ -3279,7 +3393,8 @@ static int tls_process_cke_gost18(SSL *s, PACKET *pkt) #endif } -MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL_CONNECTION *s, + PACKET *pkt) { unsigned long alg_k; @@ -3347,11 +3462,12 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) +WORK_STATE tls_post_process_client_key_exchange(SSL_CONNECTION *s, + WORK_STATE wst) { #ifndef OPENSSL_NO_SCTP if (wst == WORK_MORE_A) { - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -3367,7 +3483,8 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG) labellen += 1; - if (SSL_export_keying_material(s, sctpauthkey, + if (SSL_export_keying_material(SSL_CONNECTION_GET_SSL(s), + sctpauthkey, sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { @@ -3375,13 +3492,13 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) return WORK_ERROR; } - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + BIO_ctrl(s->wbio, BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, sizeof(sctpauthkey), sctpauthkey); } } #endif - if (s->statem.no_cert_verify || !s->session->peer) { + if (s->statem.no_cert_verify || !received_client_cert(s)) { /* * No certificate verify or no peer certificate so we no longer need * the handshake_buffer @@ -3409,7 +3526,93 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; } -MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt) +{ + MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; + SSL_SESSION *new_sess = NULL; + EVP_PKEY *peer_rpk = NULL; + + if (!tls_process_rpk(sc, pkt, &peer_rpk)) { + /* SSLfatal already called */ + goto err; + } + + if (peer_rpk == NULL) { + if ((sc->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) + && (sc->verify_mode & SSL_VERIFY_PEER)) { + SSLfatal(sc, SSL_AD_CERTIFICATE_REQUIRED, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + goto err; + } + } else { + if (ssl_verify_rpk(sc, peer_rpk) <= 0) { + SSLfatal(sc, ssl_x509err2alert(sc->verify_result), + SSL_R_CERTIFICATE_VERIFY_FAILED); + goto err; + } + } + + /* + * Sessions must be immutable once they go into the session cache. Otherwise + * we can get multi-thread problems. Therefore we don't "update" sessions, + * we replace them with a duplicate. Here, we need to do this every time + * a new RPK (or certificate) is received via post-handshake authentication, + * as the session may have already gone into the session cache. + */ + + if (sc->post_handshake_auth == SSL_PHA_REQUESTED) { + if ((new_sess = ssl_session_dup(sc->session, 0)) == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + SSL_SESSION_free(sc->session); + sc->session = new_sess; + } + + /* Ensure there is no peer/peer_chain */ + X509_free(sc->session->peer); + sc->session->peer = NULL; + sk_X509_pop_free(sc->session->peer_chain, X509_free); + sc->session->peer_chain = NULL; + /* Save RPK */ + EVP_PKEY_free(sc->session->peer_rpk); + sc->session->peer_rpk = peer_rpk; + peer_rpk = NULL; + + sc->session->verify_result = sc->verify_result; + + /* + * Freeze the handshake buffer. For cert_verify_hash, + sizeof(sc->cert_verify_hash), + &sc->cert_verify_hash_len)) { + /* SSLfatal() already called */; + goto err; + } + + /* resend session tickets */ + sc->sent_tickets = 0; + } + + ret = MSG_PROCESS_CONTINUE_READING; + + err: + EVP_PKEY_free(peer_rpk); + return ret; +} + +MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, + PACKET *pkt) { int i; MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; @@ -3420,23 +3623,35 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) PACKET spkt, context; size_t chainidx; SSL_SESSION *new_sess = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* * To get this far we must have read encrypted data from the client. We no - * longer tolerate unencrypted alerts. This value is ignored if less than - * TLSv1.3 + * longer tolerate unencrypted alerts. This is ignored if less than TLSv1.3 */ - s->statem.enc_read_state = ENC_READ_STATE_VALID; + if (s->rlayer.rrlmethod->set_plain_alerts != NULL) + s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0); + + if (s->ext.client_cert_type == TLSEXT_cert_type_rpk) + return tls_process_client_rpk(s, pkt); + + if (s->ext.client_cert_type != TLSEXT_cert_type_x509) { + SSLfatal(s, SSL_AD_UNSUPPORTED_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto err; + } if ((sk = sk_X509_new_null()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } - if (SSL_IS_TLS13(s) && (!PACKET_get_length_prefixed_1(pkt, &context) - || (s->pha_context == NULL && PACKET_remaining(&context) != 0) - || (s->pha_context != NULL && - !PACKET_equal(&context, s->pha_context, s->pha_context_len)))) { + if (SSL_CONNECTION_IS_TLS13(s) + && (!PACKET_get_length_prefixed_1(pkt, &context) + || (s->pha_context == NULL && PACKET_remaining(&context) != 0) + || (s->pha_context != NULL + && !PACKET_equal(&context, s->pha_context, + s->pha_context_len)))) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); goto err; } @@ -3455,9 +3670,9 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = X509_new_ex(s->ctx->libctx, s->ctx->propq); + x = X509_new_ex(sctx->libctx, sctx->propq); if (x == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_X509_LIB); goto err; } if (d2i_X509(&x, (const unsigned char **)&certbytes, l) == NULL) { @@ -3470,7 +3685,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) goto err; } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { RAW_EXTENSION *rawexts = NULL; PACKET extensions; @@ -3491,7 +3706,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } if (!sk_X509_push(sk, x)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } x = NULL; @@ -3542,7 +3757,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) if (s->post_handshake_auth == SSL_PHA_REQUESTED) { if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); goto err; } @@ -3554,15 +3769,18 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) s->session->peer = sk_X509_shift(sk); s->session->verify_result = s->verify_result; - sk_X509_pop_free(s->session->peer_chain, X509_free); + OSSL_STACK_OF_X509_free(s->session->peer_chain); s->session->peer_chain = sk; sk = NULL; + /* Ensure there is no RPK */ + EVP_PKEY_free(s->session->peer_rpk); + s->session->peer_rpk = NULL; /* * Freeze the handshake buffer. For cert_verify_hash, sizeof(s->cert_verify_hash), &s->cert_verify_hash_len)) { @@ -3589,39 +3807,93 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) err: X509_free(x); - sk_X509_pop_free(sk, X509_free); + OSSL_STACK_OF_X509_free(sk); + return ret; +} + +#ifndef OPENSSL_NO_COMP_ALG +MSG_PROCESS_RETURN tls_process_client_compressed_certificate(SSL_CONNECTION *sc, PACKET *pkt) +{ + MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; + PACKET tmppkt; + BUF_MEM *buf = BUF_MEM_new(); + + if (tls13_process_compressed_certificate(sc, pkt, &tmppkt, buf) != MSG_PROCESS_ERROR) + ret = tls_process_client_certificate(sc, &tmppkt); + + BUF_MEM_free(buf); return ret; } +#endif -int tls_construct_server_certificate(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_server_certificate(SSL_CONNECTION *s, WPACKET *pkt) { CERT_PKEY *cpk = s->s3.tmp.cert; if (cpk == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + return CON_FUNC_ERROR; } /* * In TLSv1.3 the certificate chain is always preceded by a 0 length context * for the server Certificate message */ - if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) { + if (SSL_CONNECTION_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return CON_FUNC_ERROR; + } + switch (s->ext.server_cert_type) { + case TLSEXT_cert_type_rpk: + if (!tls_output_rpk(s, pkt, cpk)) { + /* SSLfatal() already called */ + return 0; + } + break; + case TLSEXT_cert_type_x509: + if (!ssl3_output_cert_chain(s, pkt, cpk, 0)) { + /* SSLfatal() already called */ + return 0; + } + break; + default: SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (!ssl3_output_cert_chain(s, pkt, cpk)) { - /* SSLfatal() already called */ + + return CON_FUNC_SUCCESS; +} + +#ifndef OPENSSL_NO_COMP_ALG +CON_FUNC_RETURN tls_construct_server_compressed_certificate(SSL_CONNECTION *sc, WPACKET *pkt) +{ + int alg = get_compressed_certificate_alg(sc); + OSSL_COMP_CERT *cc = sc->s3.tmp.cert->comp_cert[alg]; + + if (!ossl_assert(cc != NULL)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } + /* + * Server can't compress on-demand + * Use pre-compressed certificate + */ + if (!WPACKET_put_bytes_u16(pkt, alg) + || !WPACKET_put_bytes_u24(pkt, cc->orig_len) + || !WPACKET_start_sub_packet_u24(pkt) + || !WPACKET_memcpy(pkt, cc->data, cc->len) + || !WPACKET_close(pkt)) + return 0; + sc->s3.tmp.cert->cert_comp_used++; return 1; } +#endif -static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, - unsigned char *tick_nonce) +static int create_ticket_prequel(SSL_CONNECTION *s, WPACKET *pkt, + uint32_t age_add, unsigned char *tick_nonce) { - uint32_t timeout = (uint32_t)s->session->timeout; + uint32_t timeout = (uint32_t)ossl_time2seconds(s->session->timeout); /* * Ticket lifetime hint: @@ -3632,8 +3904,9 @@ static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, */ #define ONE_WEEK_SEC (7 * 24 * 60 * 60) - if (SSL_IS_TLS13(s)) { - if (s->session->timeout > ONE_WEEK_SEC) + if (SSL_CONNECTION_IS_TLS13(s)) { + if (ossl_time_compare(s->session->timeout, + ossl_seconds2time(ONE_WEEK_SEC)) > 0) timeout = ONE_WEEK_SEC; } else if (s->hit) timeout = 0; @@ -3643,7 +3916,7 @@ static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, return 0; } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (!WPACKET_put_bytes_u32(pkt, age_add) || !WPACKET_sub_memcpy_u8(pkt, tick_nonce, TICKET_NONCE_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -3660,12 +3933,10 @@ static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, return 1; } -/* - * Returns 1 on success, 0 to abort construction of the ticket (non-fatal), or - * -1 on fatal error - */ -static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, - unsigned char *tick_nonce) +static CON_FUNC_RETURN construct_stateless_ticket(SSL_CONNECTION *s, + WPACKET *pkt, + uint32_t age_add, + unsigned char *tick_nonce) { unsigned char *senc = NULL; EVP_CIPHER_CTX *ctx = NULL; @@ -3678,8 +3949,11 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, SSL_CTX *tctx = s->session_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[TLSEXT_KEYNAME_LENGTH]; - int iv_len, ok = -1; + int iv_len; + CON_FUNC_RETURN ok = CON_FUNC_ERROR; size_t macoffset, macendoffset; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* get session encoding length */ slen_full = i2d_SSL_SESSION(s->session, NULL); @@ -3693,14 +3967,18 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, } senc = OPENSSL_malloc(slen_full); if (senc == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } hctx = ssl_hmac_new(tctx); - if (ctx == NULL || hctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + if (hctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); goto err; } @@ -3714,7 +3992,8 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, * create a fresh copy (not shared with other threads) to clean up */ const_p = senc; - sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); + sess = d2i_SSL_SESSION_ex(NULL, &const_p, slen_full, sctx->libctx, + sctx->propq); if (sess == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -3748,13 +4027,13 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, int ret = 0; if (tctx->ext.ticket_key_evp_cb != NULL) - ret = tctx->ext.ticket_key_evp_cb(s, key_name, iv, ctx, + ret = tctx->ext.ticket_key_evp_cb(ssl, key_name, iv, ctx, ssl_hmac_get0_EVP_MAC_CTX(hctx), 1); #ifndef OPENSSL_NO_DEPRECATED_3_0 else if (tctx->ext.ticket_key_cb != NULL) /* if 0 is returned, write an empty ticket */ - ret = tctx->ext.ticket_key_cb(s, key_name, iv, ctx, + ret = tctx->ext.ticket_key_cb(ssl, key_name, iv, ctx, ssl_hmac_get0_HMAC_CTX(hctx), 1); #endif @@ -3764,8 +4043,8 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, * length ticket is not allowed so we abort construction of the * ticket */ - if (SSL_IS_TLS13(s)) { - ok = 0; + if (SSL_CONNECTION_IS_TLS13(s)) { + ok = CON_FUNC_DONT_SEND; goto err; } /* Put timeout and length */ @@ -3777,7 +4056,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); ssl_hmac_free(hctx); - return 1; + return CON_FUNC_SUCCESS; } if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); @@ -3789,8 +4068,8 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, goto err; } } else { - EVP_CIPHER *cipher = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC", - s->ctx->propq); + EVP_CIPHER *cipher = EVP_CIPHER_fetch(sctx->libctx, "AES-256-CBC", + sctx->propq); if (cipher == NULL) { /* Error is already recorded */ @@ -3800,7 +4079,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, iv_len = EVP_CIPHER_get_iv_length(cipher); if (iv_len < 0 - || RAND_bytes_ex(s->ctx->libctx, iv, iv_len, 0) <= 0 + || RAND_bytes_ex(sctx->libctx, iv, iv_len, 0) <= 0 || !EVP_EncryptInit_ex(ctx, cipher, NULL, tctx->ext.secure->tick_aes_key, iv) || !ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key, @@ -3854,7 +4133,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, goto err; } - ok = 1; + ok = CON_FUNC_SUCCESS; err: OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); @@ -3862,7 +4141,8 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, return ok; } -static int construct_stateful_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, +static int construct_stateful_ticket(SSL_CONNECTION *s, WPACKET *pkt, + uint32_t age_add, unsigned char *tick_nonce) { if (!create_ticket_prequel(s, pkt, age_add, tick_nonce)) { @@ -3880,7 +4160,7 @@ static int construct_stateful_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, return 1; } -static void tls_update_ticket_counts(SSL *s) +static void tls_update_ticket_counts(SSL_CONNECTION *s) { /* * Increment both |sent_tickets| and |next_ticket_nonce|. |sent_tickets| @@ -3894,7 +4174,7 @@ static void tls_update_ticket_counts(SSL *s) s->ext.extra_tickets_expected--; } -int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt) { SSL_CTX *tctx = s->session_ctx; unsigned char tick_nonce[TICKET_NONCE_SIZE]; @@ -3902,11 +4182,11 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) unsigned char age_add_c[sizeof(uint32_t)]; uint32_t age_add; } age_add_u; - int ret = 0; + CON_FUNC_RETURN ret = CON_FUNC_ERROR; age_add_u.age_add = 0; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { size_t i, hashlen; uint64_t nonce; static const unsigned char nonce_label[] = "resumption"; @@ -3941,8 +4221,8 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - if (RAND_bytes_ex(s->ctx->libctx, age_add_u.age_add_c, - sizeof(age_add_u), 0) <= 0) { + if (RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, + age_add_u.age_add_c, sizeof(age_add_u), 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3966,7 +4246,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } s->session->master_key_length = hashlen; - s->session->time = time(NULL); + s->session->time = ossl_time_now(); ssl_session_calculate_timeout(s->session); if (s->s3.alpn_selected != NULL) { OPENSSL_free(s->session->ext.alpn_selected); @@ -3974,7 +4254,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) OPENSSL_memdup(s->s3.alpn_selected, s->s3.alpn_selected_len); if (s->session->ext.alpn_selected == NULL) { s->session->ext.alpn_selected_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } s->session->ext.alpn_selected_len = s->s3.alpn_selected_len; @@ -3983,7 +4263,8 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } if (tctx->generate_ticket_cb != NULL && - tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0) { + tctx->generate_ticket_cb(SSL_CONNECTION_GET_SSL(s), + tctx->ticket_cb_data) == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3992,7 +4273,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) * SSL_OP_NO_TICKET is set - we are caching tickets anyway so there * is no point in using full stateless tickets. */ - if (SSL_IS_TLS13(s) + if (SSL_CONNECTION_IS_TLS13(s) && ((s->options & SSL_OP_NO_TICKET) != 0 || (s->max_early_data > 0 && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))) { @@ -4001,13 +4282,14 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) goto err; } } else { - int tmpret; + CON_FUNC_RETURN tmpret; tmpret = construct_stateless_ticket(s, pkt, age_add_u.age_add, tick_nonce); - if (tmpret != 1) { - if (tmpret == 0) { - ret = 2; /* Non-fatal. Abort construction but continue */ + if (tmpret != CON_FUNC_SUCCESS) { + if (tmpret == CON_FUNC_DONT_SEND) { + /* Non-fatal. Abort construction but continue */ + ret = CON_FUNC_DONT_SEND; /* We count this as a success so update the counts anwyay */ tls_update_ticket_counts(s); } @@ -4016,7 +4298,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } } - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { if (!tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_NEW_SESSION_TICKET, NULL, 0)) { @@ -4027,7 +4309,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) ssl_update_cache(s, SSL_SESS_CACHE_SERVER); } - ret = 1; + ret = CON_FUNC_SUCCESS; err: return ret; } @@ -4036,7 +4318,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) * In TLSv1.3 this is called from the extensions code, otherwise it is used to * create a separate message. Returns 1 on success or 0 on failure. */ -int tls_construct_cert_status_body(SSL *s, WPACKET *pkt) +int tls_construct_cert_status_body(SSL_CONNECTION *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, s->ext.status_type) || !WPACKET_sub_memcpy_u24(pkt, s->ext.ocsp.resp, @@ -4048,14 +4330,14 @@ int tls_construct_cert_status_body(SSL *s, WPACKET *pkt) return 1; } -int tls_construct_cert_status(SSL *s, WPACKET *pkt) +CON_FUNC_RETURN tls_construct_cert_status(SSL_CONNECTION *s, WPACKET *pkt) { if (!tls_construct_cert_status_body(s, pkt)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } #ifndef OPENSSL_NO_NEXTPROTONEG @@ -4063,7 +4345,7 @@ int tls_construct_cert_status(SSL *s, WPACKET *pkt) * tls_process_next_proto reads a Next Protocol Negotiation handshake message. * It sets the next_proto member in s if found */ -MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_next_proto(SSL_CONNECTION *s, PACKET *pkt) { PACKET next_proto, padding; size_t next_proto_len; @@ -4094,18 +4376,19 @@ MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) } #endif -static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt) +static CON_FUNC_RETURN tls_construct_encrypted_extensions(SSL_CONNECTION *s, + WPACKET *pkt) { if (!tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, NULL, 0)) { /* SSLfatal() already called */ - return 0; + return CON_FUNC_ERROR; } - return 1; + return CON_FUNC_SUCCESS; } -MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt) +MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL_CONNECTION *s, PACKET *pkt) { if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -4128,7 +4411,7 @@ MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt) } s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; - if (!s->method->ssl3_enc->change_cipher_state(s, + if (!SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 91238e6457..673a53ad36 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -22,7 +22,7 @@ #include /* seed1 through seed5 are concatenated */ -static int tls1_PRF(SSL *s, +static int tls1_PRF(SSL_CONNECTION *s, const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len, const void *seed3, size_t seed3_len, @@ -45,7 +45,9 @@ static int tls1_PRF(SSL *s, ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } - kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_PRF, s->ctx->propq); + kdf = EVP_KDF_fetch(SSL_CONNECTION_GET_CTX(s)->libctx, + OSSL_KDF_NAME_TLS1_PRF, + SSL_CONNECTION_GET_CTX(s)->propq); if (kdf == NULL) goto err; kctx = EVP_KDF_CTX_new(kdf); @@ -83,7 +85,8 @@ static int tls1_PRF(SSL *s, return 0; } -static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) +static int tls1_generate_key_block(SSL_CONNECTION *s, unsigned char *km, + size_t num) { int ret; @@ -98,43 +101,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) return ret; } -#ifndef OPENSSL_NO_KTLS - /* - * Count the number of records that were not processed yet from record boundary. - * - * This function assumes that there are only fully formed records read in the - * record layer. If read_ahead is enabled, then this might be false and this - * function will fail. - */ -# ifndef OPENSSL_NO_KTLS_RX -static int count_unprocessed_records(SSL *s) -{ - SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); - PACKET pkt, subpkt; - int count = 0; - - if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) - return -1; - - while (PACKET_remaining(&pkt) > 0) { - /* Skip record type and version */ - if (!PACKET_forward(&pkt, 3)) - return -1; - - /* Read until next record */ - if (!PACKET_get_length_prefixed_2(&pkt, &subpkt)) - return -1; - - count += 1; - } - - return count; -} -# endif -#endif - - -int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx, +int tls_provider_set_tls_params(SSL_CONNECTION *s, EVP_CIPHER_CTX *ctx, const EVP_CIPHER *ciph, const EVP_MD *md) { @@ -183,32 +150,23 @@ static int tls_iv_length_within_key_block(const EVP_CIPHER *c) return EVP_CIPHER_get_iv_length(c); } -int tls1_change_cipher_state(SSL *s, int which) +int tls1_change_cipher_state(SSL_CONNECTION *s, int which) { unsigned char *p, *mac_secret; - unsigned char *ms, *key, *iv; - EVP_CIPHER_CTX *dd; + unsigned char *key, *iv; const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - const SSL_COMP *comp; -#endif + const SSL_COMP *comp = NULL; const EVP_MD *m; int mac_type; - size_t *mac_secret_size; - EVP_MD_CTX *mac_ctx; - EVP_PKEY *mac_key; + size_t mac_secret_size; size_t n, i, j, k, cl; - int reuse_dd = 0; -#ifndef OPENSSL_NO_KTLS - ktls_crypto_info_t crypto_info; - unsigned char *rec_seq; - void *rl_sequence; -# ifndef OPENSSL_NO_KTLS_RX - int count_unprocessed; - int bit; -# endif - BIO *bio; -#endif + int iivlen; + /* + * Taglen is only relevant for CCM ciphersuites. Other ciphersuites + * ignore this value so we can default it to 0. + */ + size_t taglen = 0; + int direction; c = s->s3.tmp.new_sym_enc; m = s->s3.tmp.new_hash; @@ -217,128 +175,20 @@ int tls1_change_cipher_state(SSL *s, int which) comp = s->s3.tmp.new_compression; #endif - if (which & SSL3_CC_READ) { - if (s->ext.use_etm) - s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; - else - s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; - - if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; - - if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) - s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; - else - s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; - - if (s->enc_read_ctx != NULL) { - reuse_dd = 1; - } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } else { - /* - * make sure it's initialised in case we exit later with an error - */ - EVP_CIPHER_CTX_reset(s->enc_read_ctx); - } - dd = s->enc_read_ctx; - mac_ctx = ssl_replace_hash(&s->read_hash, NULL); - if (mac_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifndef OPENSSL_NO_COMP - COMP_CTX_free(s->expand); - s->expand = NULL; - if (comp != NULL) { - s->expand = COMP_CTX_new(comp->method); - if (s->expand == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err; - } - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - RECORD_LAYER_reset_read_sequence(&s->rlayer); - mac_secret = &(s->s3.read_mac_secret[0]); - mac_secret_size = &(s->s3.read_mac_secret_size); - } else { - s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; - if (s->ext.use_etm) - s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; - else - s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; - - if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; - - if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) - s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; - else - s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; - if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { - reuse_dd = 1; - } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - dd = s->enc_write_ctx; - if (SSL_IS_DTLS(s)) { - mac_ctx = EVP_MD_CTX_new(); - if (mac_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - s->write_hash = mac_ctx; - } else { - mac_ctx = ssl_replace_hash(&s->write_hash, NULL); - if (mac_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - } -#ifndef OPENSSL_NO_COMP - COMP_CTX_free(s->compress); - s->compress = NULL; - if (comp != NULL) { - s->compress = COMP_CTX_new(comp->method); - if (s->compress == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err; - } - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - RECORD_LAYER_reset_write_sequence(&s->rlayer); - mac_secret = &(s->s3.write_mac_secret[0]); - mac_secret_size = &(s->s3.write_mac_secret_size); - } - - if (reuse_dd) - EVP_CIPHER_CTX_reset(dd); - p = s->s3.tmp.key_block; - i = *mac_secret_size = s->s3.tmp.new_mac_secret_size; + i = mac_secret_size = s->s3.tmp.new_mac_secret_size; cl = EVP_CIPHER_get_key_length(c); j = cl; - k = tls_iv_length_within_key_block(c); + iivlen = tls_iv_length_within_key_block(c); + if (iivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + k = iivlen; if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); + mac_secret = &(p[0]); n = i + i; key = &(p[n]); n += j + j; @@ -346,7 +196,7 @@ int tls1_change_cipher_state(SSL *s, int which) n += k + k; } else { n = i; - ms = &(p[n]); + mac_secret = &(p[n]); n += i + j; key = &(p[n]); n += j + k; @@ -359,155 +209,72 @@ int tls1_change_cipher_state(SSL *s, int which) goto err; } - memcpy(mac_secret, ms, i); - - if (!(EVP_CIPHER_get_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - if (mac_type == EVP_PKEY_HMAC) { - mac_key = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, mac_secret, - *mac_secret_size); - } else { - /* - * If its not HMAC then the only other types of MAC we support are - * the GOST MACs, so we need to use the old style way of creating - * a MAC key. - */ - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, - (int)*mac_secret_size); - } - if (mac_key == NULL - || EVP_DigestSignInit_ex(mac_ctx, NULL, EVP_MD_get0_name(m), - s->ctx->libctx, s->ctx->propq, mac_key, - NULL) <= 0) { - EVP_PKEY_free(mac_key); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - EVP_PKEY_free(mac_key); - } - - OSSL_TRACE_BEGIN(TLS) { - BIO_printf(trc_out, "which = %04X, mac key:\n", which); - BIO_dump_indent(trc_out, ms, i, 4); - } OSSL_TRACE_END(TLS); - - if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) { - if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) - || EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, (int)k, - iv) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { - int taglen; - if (s->s3.tmp. - new_cipher->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) + switch (EVP_CIPHER_get_mode(c)) { + case EVP_CIPH_GCM_MODE: + taglen = EVP_GCM_TLS_TAG_LEN; + break; + case EVP_CIPH_CCM_MODE: + if ((s->s3.tmp.new_cipher->algorithm_enc + & (SSL_AES128CCM8 | SSL_AES256CCM8)) != 0) taglen = EVP_CCM8_TLS_TAG_LEN; else taglen = EVP_CCM_TLS_TAG_LEN; - if (!EVP_CipherInit_ex(dd, c, NULL, NULL, NULL, (which & SSL3_CC_WRITE)) - || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) <= 0) - || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) - || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_CCM_SET_IV_FIXED, (int)k, iv) <= 0) - || !EVP_CipherInit_ex(dd, NULL, NULL, key, NULL, -1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; + break; + default: + if (EVP_CIPHER_is_a(c, "CHACHA20-POLY1305")) { + taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; + } else { + /* MAC secret size corresponds to the MAC output size */ + taglen = s->s3.tmp.new_mac_secret_size; } + break; } - /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if ((EVP_CIPHER_get_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) - && *mac_secret_size - && EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, - (int)*mac_secret_size, mac_secret) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - if (EVP_CIPHER_get0_provider(c) != NULL - && !tls_provider_set_tls_params(s, dd, c, m)) { - /* SSLfatal already called */ - goto err; - } - -#ifndef OPENSSL_NO_KTLS - if (s->compress || (s->options & SSL_OP_ENABLE_KTLS) == 0) - goto skip_ktls; - - /* ktls supports only the maximum fragment size */ - if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) - goto skip_ktls; - - /* check that cipher is supported */ - if (!ktls_check_supported_cipher(s, c, dd)) - goto skip_ktls; - if (which & SSL3_CC_WRITE) - bio = s->wbio; - else - bio = s->rbio; + if (which & SSL3_CC_READ) { + if (s->ext.use_etm) + s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; + else + s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; - if (!ossl_assert(bio != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; - /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ - if (which & SSL3_CC_WRITE) { - if (BIO_flush(bio) <= 0) - goto skip_ktls; - } + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; - /* ktls doesn't support renegotiation */ - if ((BIO_get_ktls_send(s->wbio) && (which & SSL3_CC_WRITE)) || - (BIO_get_ktls_recv(s->rbio) && (which & SSL3_CC_READ))) { - SSLfatal(s, SSL_AD_NO_RENEGOTIATION, ERR_R_INTERNAL_ERROR); - goto err; - } + direction = OSSL_RECORD_DIRECTION_READ; + } else { + if (s->ext.use_etm) + s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; + else + s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; - if (which & SSL3_CC_WRITE) - rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); - else - rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; - if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, - iv, key, ms, *mac_secret_size)) - goto skip_ktls; + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; - if (which & SSL3_CC_READ) { -# ifndef OPENSSL_NO_KTLS_RX - count_unprocessed = count_unprocessed_records(s); - if (count_unprocessed < 0) - goto skip_ktls; - - /* increment the crypto_info record sequence */ - while (count_unprocessed) { - for (bit = 7; bit >= 0; bit--) { /* increment */ - ++rec_seq[bit]; - if (rec_seq[bit] != 0) - break; - } - count_unprocessed--; - } -# else - goto skip_ktls; -# endif + direction = OSSL_RECORD_DIRECTION_WRITE; } - /* ktls works with user provided buffers directly */ - if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { - if (which & SSL3_CC_WRITE) - ssl3_release_write_buffer(s); - SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); + if (!ssl_set_new_record_layer(s, s->version, direction, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + NULL, 0, key, cl, iv, (size_t)k, mac_secret, + mac_secret_size, c, taglen, mac_type, + m, comp, NULL)) { + /* SSLfatal already called */ + goto err; } - skip_ktls: -#endif /* OPENSSL_NO_KTLS */ - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; - OSSL_TRACE_BEGIN(TLS) { BIO_printf(trc_out, "which = %04X, key:\n", which); BIO_dump_indent(trc_out, key, EVP_CIPHER_get_key_length(c), 4); @@ -520,7 +287,7 @@ int tls1_change_cipher_state(SSL *s, int which) return 0; } -int tls1_setup_key_block(SSL *s) +int tls1_setup_key_block(SSL_CONNECTION *s) { unsigned char *p; const EVP_CIPHER *c; @@ -529,12 +296,14 @@ int tls1_setup_key_block(SSL *s) int mac_type = NID_undef; size_t num, mac_secret_size = 0; int ret = 0; + int ivlen; if (s->s3.tmp.key_block_length != 0) return 1; - if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, &mac_type, - &mac_secret_size, &comp, s->ext.use_etm)) { + if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, + &mac_type, &mac_secret_size, &comp, + s->ext.use_etm)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; @@ -546,14 +315,18 @@ int tls1_setup_key_block(SSL *s) s->s3.tmp.new_hash = hash; s->s3.tmp.new_mac_pkey_type = mac_type; s->s3.tmp.new_mac_secret_size = mac_secret_size; - num = mac_secret_size + EVP_CIPHER_get_key_length(c) - + tls_iv_length_within_key_block(c); + ivlen = tls_iv_length_within_key_block(c); + if (ivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + num = mac_secret_size + EVP_CIPHER_get_key_length(c) + ivlen; num *= 2; ssl3_cleanup_key_block(s); if ((p = OPENSSL_malloc(num)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } @@ -582,30 +355,13 @@ int tls1_setup_key_block(SSL *s) BIO_dump_indent(trc_out, p, num, 4); } OSSL_TRACE_END(TLS); - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) - && s->method->version <= TLS1_VERSION) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3.need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3.need_empty_fragments = 0; - - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3.need_empty_fragments = 0; - } - } - ret = 1; err: return ret; } -size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, - unsigned char *out) +size_t tls1_final_finish_mac(SSL_CONNECTION *s, const char *str, + size_t slen, unsigned char *out) { size_t hashlen; unsigned char hash[EVP_MAX_MD_SIZE]; @@ -634,8 +390,9 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, return finished_size; } -int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, - size_t len, size_t *secret_size) +int tls1_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, + unsigned char *p, size_t len, + size_t *secret_size) { if (s->session->flags & SSL_SESS_FLAG_EXTMS) { unsigned char hash[EVP_MAX_MD_SIZE * 2]; @@ -697,14 +454,14 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, return 1; } -int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, +int tls1_export_keying_material(SSL_CONNECTION *s, unsigned char *out, + size_t olen, const char *label, size_t llen, const unsigned char *context, size_t contextlen, int use_context) { unsigned char *val = NULL; size_t vallen = 0, currentvalpos; - int rv; + int rv = 0; /* * construct PRF arguments we construct the PRF argument ourself rather @@ -718,7 +475,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, val = OPENSSL_malloc(vallen); if (val == NULL) - goto err2; + goto ret; currentvalpos = 0; memcpy(val + currentvalpos, (unsigned char *)label, llen); currentvalpos += llen; @@ -770,11 +527,6 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, goto ret; err1: ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); - rv = 0; - goto ret; - err2: - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); - rv = 0; ret: OPENSSL_clear_free(val, vallen); return rv; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 8be00a4f34..631e1fdef9 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -23,16 +23,14 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "internal/tlsgroups.h" -#include "internal/cryptlib.h" #include "ssl_local.h" +#include "quic/quic_local.h" #include -static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey); -static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu); +static const SIGALG_LOOKUP *find_sig_alg(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pkey); +static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, const SIGALG_LOOKUP *lu); SSL3_ENC_METHOD const TLSv1_enc_data = { - tls1_enc, - tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, tls1_change_cipher_state, @@ -48,8 +46,6 @@ SSL3_ENC_METHOD const TLSv1_enc_data = { }; SSL3_ENC_METHOD const TLSv1_1_enc_data = { - tls1_enc, - tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, tls1_change_cipher_state, @@ -65,8 +61,6 @@ SSL3_ENC_METHOD const TLSv1_1_enc_data = { }; SSL3_ENC_METHOD const TLSv1_2_enc_data = { - tls1_enc, - tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, tls1_change_cipher_state, @@ -83,8 +77,6 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = { }; SSL3_ENC_METHOD const TLSv1_3_enc_data = { - tls13_enc, - tls1_mac, tls13_setup_key_block, tls13_generate_master_secret, tls13_change_cipher_state, @@ -99,13 +91,13 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = { ssl3_handshake_write }; -long tls1_default_timeout(void) +OSSL_TIME tls1_default_timeout(void) { /* * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for * http, the cache would over fill */ - return (60 * 60 * 2); + return ossl_seconds2time(60 * 60 * 2); } int tls1_new(SSL *s) @@ -120,19 +112,29 @@ int tls1_new(SSL *s) void tls1_free(SSL *s) { - OPENSSL_free(s->ext.session_ticket); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return; + + OPENSSL_free(sc->ext.session_ticket); ssl3_free(s); } int tls1_clear(SSL *s) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + if (!ssl3_clear(s)) return 0; if (s->method->version == TLS_ANY_VERSION) - s->version = TLS_MAX_VERSION_INTERNAL; + sc->version = TLS_MAX_VERSION_INTERNAL; else - s->version = s->method->version; + sc->version = s->method->version; return 1; } @@ -172,13 +174,16 @@ static struct { {NID_brainpoolP512r1, OSSL_TLS_GROUP_ID_brainpoolP512r1}, {EVP_PKEY_X25519, OSSL_TLS_GROUP_ID_x25519}, {EVP_PKEY_X448, OSSL_TLS_GROUP_ID_x448}, - {NID_id_tc26_gost_3410_2012_256_paramSetA, 0x0022}, - {NID_id_tc26_gost_3410_2012_256_paramSetB, 0x0023}, - {NID_id_tc26_gost_3410_2012_256_paramSetC, 0x0024}, - {NID_id_tc26_gost_3410_2012_256_paramSetD, 0x0025}, - {NID_id_tc26_gost_3410_2012_512_paramSetA, 0x0026}, - {NID_id_tc26_gost_3410_2012_512_paramSetB, 0x0027}, - {NID_id_tc26_gost_3410_2012_512_paramSetC, 0x0028}, + {NID_brainpoolP256r1tls13, OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13}, + {NID_brainpoolP384r1tls13, OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13}, + {NID_brainpoolP512r1tls13, OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13}, + {NID_id_tc26_gost_3410_2012_256_paramSetA, OSSL_TLS_GROUP_ID_gc256A}, + {NID_id_tc26_gost_3410_2012_256_paramSetB, OSSL_TLS_GROUP_ID_gc256B}, + {NID_id_tc26_gost_3410_2012_256_paramSetC, OSSL_TLS_GROUP_ID_gc256C}, + {NID_id_tc26_gost_3410_2012_256_paramSetD, OSSL_TLS_GROUP_ID_gc256D}, + {NID_id_tc26_gost_3410_2012_512_paramSetA, OSSL_TLS_GROUP_ID_gc512A}, + {NID_id_tc26_gost_3410_2012_512_paramSetB, OSSL_TLS_GROUP_ID_gc512B}, + {NID_id_tc26_gost_3410_2012_512_paramSetC, OSSL_TLS_GROUP_ID_gc512C}, {NID_ffdhe2048, OSSL_TLS_GROUP_ID_ffdhe2048}, {NID_ffdhe3072, OSSL_TLS_GROUP_ID_ffdhe3072}, {NID_ffdhe4096, OSSL_TLS_GROUP_ID_ffdhe4096}, @@ -194,31 +199,31 @@ static const unsigned char ecformats_default[] = { /* The default curves */ static const uint16_t supported_groups_default[] = { - 29, /* X25519 (29) */ - 23, /* secp256r1 (23) */ - 30, /* X448 (30) */ - 25, /* secp521r1 (25) */ - 24, /* secp384r1 (24) */ - 34, /* GC256A (34) */ - 35, /* GC256B (35) */ - 36, /* GC256C (36) */ - 37, /* GC256D (37) */ - 38, /* GC512A (38) */ - 39, /* GC512B (39) */ - 40, /* GC512C (40) */ - 0x100, /* ffdhe2048 (0x100) */ - 0x101, /* ffdhe3072 (0x101) */ - 0x102, /* ffdhe4096 (0x102) */ - 0x103, /* ffdhe6144 (0x103) */ - 0x104, /* ffdhe8192 (0x104) */ + OSSL_TLS_GROUP_ID_x25519, /* X25519 (29) */ + OSSL_TLS_GROUP_ID_secp256r1, /* secp256r1 (23) */ + OSSL_TLS_GROUP_ID_x448, /* X448 (30) */ + OSSL_TLS_GROUP_ID_secp521r1, /* secp521r1 (25) */ + OSSL_TLS_GROUP_ID_secp384r1, /* secp384r1 (24) */ + OSSL_TLS_GROUP_ID_gc256A, /* GC256A (34) */ + OSSL_TLS_GROUP_ID_gc256B, /* GC256B (35) */ + OSSL_TLS_GROUP_ID_gc256C, /* GC256C (36) */ + OSSL_TLS_GROUP_ID_gc256D, /* GC256D (37) */ + OSSL_TLS_GROUP_ID_gc512A, /* GC512A (38) */ + OSSL_TLS_GROUP_ID_gc512B, /* GC512B (39) */ + OSSL_TLS_GROUP_ID_gc512C, /* GC512C (40) */ + OSSL_TLS_GROUP_ID_ffdhe2048, /* ffdhe2048 (0x100) */ + OSSL_TLS_GROUP_ID_ffdhe3072, /* ffdhe3072 (0x101) */ + OSSL_TLS_GROUP_ID_ffdhe4096, /* ffdhe4096 (0x102) */ + OSSL_TLS_GROUP_ID_ffdhe6144, /* ffdhe6144 (0x103) */ + OSSL_TLS_GROUP_ID_ffdhe8192, /* ffdhe8192 (0x104) */ }; static const uint16_t suiteb_curves[] = { - TLSEXT_curve_P_256, - TLSEXT_curve_P_384 + OSSL_TLS_GROUP_ID_secp256r1, + OSSL_TLS_GROUP_ID_secp384r1, }; -struct provider_group_data_st { +struct provider_ctx_data_st { SSL_CTX *ctx; OSSL_PROVIDER *provider; }; @@ -227,7 +232,7 @@ struct provider_group_data_st { static OSSL_CALLBACK add_provider_groups; static int add_provider_groups(const OSSL_PARAM params[], void *data) { - struct provider_group_data_st *pgd = data; + struct provider_ctx_data_st *pgd = data; SSL_CTX *ctx = pgd->ctx; OSSL_PROVIDER *provider = pgd->provider; const OSSL_PARAM *p; @@ -248,10 +253,8 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) (ctx->group_list_max_len + TLS_GROUP_LIST_MALLOC_BLOCK_SIZE) * sizeof(TLS_GROUP_INFO)); - if (tmp == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (tmp == NULL) return 0; - } ctx->group_list = tmp; memset(tmp + ctx->group_list_max_len, 0, @@ -267,10 +270,8 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) goto err; } ginf->tlsname = OPENSSL_strdup(p->data); - if (ginf->tlsname == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ginf->tlsname == NULL) goto err; - } p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL); if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { @@ -278,10 +279,8 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) goto err; } ginf->realname = OPENSSL_strdup(p->data); - if (ginf->realname == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ginf->realname == NULL) goto err; - } p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID); if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) { @@ -296,10 +295,8 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) goto err; } ginf->algorithm = OPENSSL_strdup(p->data); - if (ginf->algorithm == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ginf->algorithm == NULL) goto err; - } p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS); if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) { @@ -379,7 +376,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) static int discover_provider_groups(OSSL_PROVIDER *provider, void *vctx) { - struct provider_group_data_st pgd; + struct provider_ctx_data_st pgd; pgd.ctx = vctx; pgd.provider = provider; @@ -410,10 +407,8 @@ int ssl_load_groups(SSL_CTX *ctx) ctx->ext.supported_groups_default = OPENSSL_malloc(sizeof(uint16_t) * num_deflt_grps); - if (ctx->ext.supported_groups_default == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if (ctx->ext.supported_groups_default == NULL) return 0; - } memcpy(ctx->ext.supported_groups_default, tmp_supp_groups, @@ -423,6 +418,319 @@ int ssl_load_groups(SSL_CTX *ctx) return 1; } +#define TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE 10 +static OSSL_CALLBACK add_provider_sigalgs; +static int add_provider_sigalgs(const OSSL_PARAM params[], void *data) +{ + struct provider_ctx_data_st *pgd = data; + SSL_CTX *ctx = pgd->ctx; + OSSL_PROVIDER *provider = pgd->provider; + const OSSL_PARAM *p; + TLS_SIGALG_INFO *sinf = NULL; + EVP_KEYMGMT *keymgmt; + const char *keytype; + unsigned int code_point = 0; + int ret = 0; + + if (ctx->sigalg_list_max_len == ctx->sigalg_list_len) { + TLS_SIGALG_INFO *tmp = NULL; + + if (ctx->sigalg_list_max_len == 0) + tmp = OPENSSL_malloc(sizeof(TLS_SIGALG_INFO) + * TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE); + else + tmp = OPENSSL_realloc(ctx->sigalg_list, + (ctx->sigalg_list_max_len + + TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE) + * sizeof(TLS_SIGALG_INFO)); + if (tmp == NULL) + return 0; + ctx->sigalg_list = tmp; + memset(tmp + ctx->sigalg_list_max_len, 0, + sizeof(TLS_SIGALG_INFO) * TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE); + ctx->sigalg_list_max_len += TLS_SIGALG_LIST_MALLOC_BLOCK_SIZE; + } + + sinf = &ctx->sigalg_list[ctx->sigalg_list_len]; + + /* First, mandatory parameters */ + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_NAME); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + OPENSSL_free(sinf->sigalg_name); + sinf->sigalg_name = OPENSSL_strdup(p->data); + if (sinf->sigalg_name == NULL) + goto err; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + OPENSSL_free(sinf->name); + sinf->name = OPENSSL_strdup(p->data); + if (sinf->name == NULL) + goto err; + + p = OSSL_PARAM_locate_const(params, + OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT); + if (p == NULL + || !OSSL_PARAM_get_uint(p, &code_point) + || code_point > UINT16_MAX) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + sinf->code_point = (uint16_t)code_point; + + p = OSSL_PARAM_locate_const(params, + OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS); + if (p == NULL || !OSSL_PARAM_get_uint(p, &sinf->secbits)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + /* Now, optional parameters */ + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_OID); + if (p == NULL) { + sinf->sigalg_oid = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->sigalg_oid); + sinf->sigalg_oid = OPENSSL_strdup(p->data); + if (sinf->sigalg_oid == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME); + if (p == NULL) { + sinf->sig_name = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->sig_name); + sinf->sig_name = OPENSSL_strdup(p->data); + if (sinf->sig_name == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_SIG_OID); + if (p == NULL) { + sinf->sig_oid = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->sig_oid); + sinf->sig_oid = OPENSSL_strdup(p->data); + if (sinf->sig_oid == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME); + if (p == NULL) { + sinf->hash_name = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->hash_name); + sinf->hash_name = OPENSSL_strdup(p->data); + if (sinf->hash_name == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_HASH_OID); + if (p == NULL) { + sinf->hash_oid = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->hash_oid); + sinf->hash_oid = OPENSSL_strdup(p->data); + if (sinf->hash_oid == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE); + if (p == NULL) { + sinf->keytype = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->keytype); + sinf->keytype = OPENSSL_strdup(p->data); + if (sinf->keytype == NULL) + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID); + if (p == NULL) { + sinf->keytype_oid = NULL; + } else if (p->data_type != OSSL_PARAM_UTF8_STRING) { + goto err; + } else { + OPENSSL_free(sinf->keytype_oid); + sinf->keytype_oid = OPENSSL_strdup(p->data); + if (sinf->keytype_oid == NULL) + goto err; + } + + /* The remaining parameters below are mandatory again */ + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->mintls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + if ((sinf->mintls != 0) && (sinf->mintls != -1) && + ((sinf->mintls < TLS1_3_VERSION))) { + /* ignore this sigalg as this OpenSSL doesn't know how to handle it */ + ret = 1; + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &sinf->maxtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + if ((sinf->maxtls != 0) && (sinf->maxtls != -1) && + ((sinf->maxtls < sinf->mintls))) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + if ((sinf->maxtls != 0) && (sinf->maxtls != -1) && + ((sinf->maxtls < TLS1_3_VERSION))) { + /* ignore this sigalg as this OpenSSL doesn't know how to handle it */ + ret = 1; + goto err; + } + + /* + * Now check that the algorithm is actually usable for our property query + * string. Regardless of the result we still return success because we have + * successfully processed this signature, even though we may decide not to + * use it. + */ + ret = 1; + ERR_set_mark(); + keytype = (sinf->keytype != NULL + ? sinf->keytype + : (sinf->sig_name != NULL + ? sinf->sig_name + : sinf->sigalg_name)); + keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, keytype, ctx->propq); + if (keymgmt != NULL) { + /* + * We have successfully fetched the algorithm - however if the provider + * doesn't match this one then we ignore it. + * + * Note: We're cheating a little here. Technically if the same algorithm + * is available from more than one provider then it is undefined which + * implementation you will get back. Theoretically this could be + * different every time...we assume here that you'll always get the + * same one back if you repeat the exact same fetch. Is this a reasonable + * assumption to make (in which case perhaps we should document this + * behaviour)? + */ + if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) { + /* + * We have a match - so we could use this signature; + * Check proper object registration first, though. + * Don't care about return value as this may have been + * done within providers or previous calls to + * add_provider_sigalgs. + */ + OBJ_create(sinf->sigalg_oid, sinf->sigalg_name, NULL); + /* sanity check: Without successful registration don't use alg */ + if ((OBJ_txt2nid(sinf->sigalg_name) == NID_undef) || + (OBJ_nid2obj(OBJ_txt2nid(sinf->sigalg_name)) == NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + if (sinf->sig_name != NULL) + OBJ_create(sinf->sig_oid, sinf->sig_name, NULL); + if (sinf->keytype != NULL) + OBJ_create(sinf->keytype_oid, sinf->keytype, NULL); + if (sinf->hash_name != NULL) + OBJ_create(sinf->hash_oid, sinf->hash_name, NULL); + OBJ_add_sigid(OBJ_txt2nid(sinf->sigalg_name), + (sinf->hash_name != NULL + ? OBJ_txt2nid(sinf->hash_name) + : NID_undef), + OBJ_txt2nid(keytype)); + ctx->sigalg_list_len++; + sinf = NULL; + } + EVP_KEYMGMT_free(keymgmt); + } + ERR_pop_to_mark(); + err: + if (sinf != NULL) { + OPENSSL_free(sinf->name); + sinf->name = NULL; + OPENSSL_free(sinf->sigalg_name); + sinf->sigalg_name = NULL; + OPENSSL_free(sinf->sigalg_oid); + sinf->sigalg_oid = NULL; + OPENSSL_free(sinf->sig_name); + sinf->sig_name = NULL; + OPENSSL_free(sinf->sig_oid); + sinf->sig_oid = NULL; + OPENSSL_free(sinf->hash_name); + sinf->hash_name = NULL; + OPENSSL_free(sinf->hash_oid); + sinf->hash_oid = NULL; + OPENSSL_free(sinf->keytype); + sinf->keytype = NULL; + OPENSSL_free(sinf->keytype_oid); + sinf->keytype_oid = NULL; + } + return ret; +} + +static int discover_provider_sigalgs(OSSL_PROVIDER *provider, void *vctx) +{ + struct provider_ctx_data_st pgd; + + pgd.ctx = vctx; + pgd.provider = provider; + OSSL_PROVIDER_get_capabilities(provider, "TLS-SIGALG", + add_provider_sigalgs, &pgd); + /* + * Always OK, even if provider doesn't support the capability: + * Reconsider testing retval when legacy sigalgs are also loaded this way. + */ + return 1; +} + +int ssl_load_sigalgs(SSL_CTX *ctx) +{ + size_t i; + SSL_CERT_LOOKUP lu; + + if (!OSSL_PROVIDER_do_all(ctx->libctx, discover_provider_sigalgs, ctx)) + return 0; + + /* now populate ctx->ssl_cert_info */ + if (ctx->sigalg_list_len > 0) { + ctx->ssl_cert_info = OPENSSL_zalloc(sizeof(lu) * ctx->sigalg_list_len); + if (ctx->ssl_cert_info == NULL) + return 0; + for(i = 0; i < ctx->sigalg_list_len; i++) { + ctx->ssl_cert_info[i].nid = OBJ_txt2nid(ctx->sigalg_list[i].sigalg_name); + ctx->ssl_cert_info[i].amask = SSL_aANY; + } + } + + /* + * For now, leave it at this: legacy sigalgs stay in their own + * data structures until "legacy cleanup" occurs. + */ + + return 1; +} + static uint16_t tls1_group_name2id(SSL_CTX *ctx, const char *name) { size_t i; @@ -448,6 +756,16 @@ const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id) return NULL; } +const char *tls1_group_id2name(SSL_CTX *ctx, uint16_t group_id) +{ + const TLS_GROUP_INFO *tls_group_info = tls1_group_id_lookup(ctx, group_id); + + if (tls_group_info == NULL) + return NULL; + + return tls_group_info->tlsname; +} + int tls1_group_id2nid(uint16_t group_id, int include_unknown) { size_t i; @@ -490,9 +808,11 @@ uint16_t tls1_nid2group_id(int nid) * Set *pgroups to the supported groups list and *pgroupslen to * the number of groups supported. */ -void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, +void tls1_get_supported_groups(SSL_CONNECTION *s, const uint16_t **pgroups, size_t *pgroupslen) { + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + /* For Suite B mode only include P-256, P-384 */ switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: @@ -512,8 +832,8 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, default: if (s->ext.supportedgroups == NULL) { - *pgroups = s->ctx->ext.supported_groups_default; - *pgroupslen = s->ctx->ext.supported_groups_default_len; + *pgroups = sctx->ext.supported_groups_default; + *pgroupslen = sctx->ext.supported_groups_default_len; } else { *pgroups = s->ext.supportedgroups; *pgroupslen = s->ext.supportedgroups_len; @@ -522,10 +842,12 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, } } -int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion, +int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, + int minversion, int maxversion, int isec, int *okfortls13) { - const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group_id); + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(SSL_CONNECTION_GET_CTX(s), + group_id); int ret; if (okfortls13 != NULL) @@ -534,7 +856,7 @@ int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion, if (ginfo == NULL) return 0; - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (ginfo->mindtls < 0 || ginfo->maxdtls < 0) return 0; if (ginfo->maxdtls == 0) @@ -565,9 +887,10 @@ int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion, } /* See if group is allowed by security callback */ -int tls_group_allowed(SSL *s, uint16_t group, int op) +int tls_group_allowed(SSL_CONNECTION *s, uint16_t group, int op) { - const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group); + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(SSL_CONNECTION_GET_CTX(s), + group); unsigned char gtmp[2]; if (ginfo == NULL) @@ -596,12 +919,12 @@ static int tls1_in_list(uint16_t id, const uint16_t *list, size_t listlen) * For nmatch == -2, return the id of the group to use for * a tmp key, or 0 if there is no match. */ -uint16_t tls1_shared_group(SSL *s, int nmatch) +uint16_t tls1_shared_group(SSL_CONNECTION *s, int nmatch) { const uint16_t *pref, *supp; size_t num_pref, num_supp, i; int k; - SSL_CTX *ctx = s->ctx; + SSL_CTX *ctx = SSL_CONNECTION_GET_CTX(s); /* Can't do anything on client side */ if (s->server == 0) @@ -615,9 +938,9 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return TLSEXT_curve_P_256; + return OSSL_TLS_GROUP_ID_secp256r1; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return TLSEXT_curve_P_384; + return OSSL_TLS_GROUP_ID_secp384r1; /* Should never happen */ return 0; } @@ -646,7 +969,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) inf = tls1_group_id_lookup(ctx, id); if (!ossl_assert(inf != NULL)) return 0; - if (SSL_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s)) { if (inf->maxdtls == -1) continue; if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls)) @@ -688,10 +1011,8 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return 0; } - if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) return 0; - } for (i = 0; i < ngroups; i++) { unsigned long idmask; uint16_t id; @@ -796,7 +1117,8 @@ int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, } /* Check a group id matches preferences */ -int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) +int tls1_check_group_id(SSL_CONNECTION *s, uint16_t group_id, + int check_own_groups) { const uint16_t *groups; size_t groups_len; @@ -809,10 +1131,10 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { - if (group_id != TLSEXT_curve_P_256) + if (group_id != OSSL_TLS_GROUP_ID_secp256r1) return 0; } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { - if (group_id != TLSEXT_curve_P_384) + if (group_id != OSSL_TLS_GROUP_ID_secp384r1) return 0; } else { /* Should never happen */ @@ -848,7 +1170,7 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return tls1_in_list(group_id, groups, groups_len); } -void tls1_get_formatlist(SSL *s, const unsigned char **pformats, +void tls1_get_formatlist(SSL_CONNECTION *s, const unsigned char **pformats, size_t *num_formats) { /* @@ -868,7 +1190,7 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, } /* Check a key is compatible with compression extension */ -static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) +static int tls1_check_pkey_comp(SSL_CONNECTION *s, EVP_PKEY *pkey) { unsigned char comp_id; size_t i; @@ -885,7 +1207,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) return 0; if (point_conv == POINT_CONVERSION_UNCOMPRESSED) { comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } else if (SSL_IS_TLS13(s)) { + } else if (SSL_CONNECTION_IS_TLS13(s)) { /* * ec_point_formats extension is not used in TLSv1.3 so we ignore * this check. @@ -929,7 +1251,7 @@ static uint16_t tls1_get_group_id(EVP_PKEY *pkey) * Check cert parameters compatible with extensions: currently just checks EC * certificates have compatible curves and compression. */ -static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) +static int tls1_check_cert_param(SSL_CONNECTION *s, X509 *x, int check_ee_md) { uint16_t group_id; EVP_PKEY *pkey; @@ -958,15 +1280,15 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) size_t i; /* Check to see we have necessary signing algorithm */ - if (group_id == TLSEXT_curve_P_256) + if (group_id == OSSL_TLS_GROUP_ID_secp256r1) check_md = NID_ecdsa_with_SHA256; - else if (group_id == TLSEXT_curve_P_384) + else if (group_id == OSSL_TLS_GROUP_ID_secp384r1) check_md = NID_ecdsa_with_SHA384; else return 0; /* Should never happen */ for (i = 0; i < s->shared_sigalgslen; i++) { if (check_md == s->shared_sigalgs[i]->sigandhash) - return 1;; + return 1; } return 0; } @@ -983,7 +1305,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) * * Returns 0 when the cipher can't be used or 1 when it can. */ -int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) +int tls1_check_ec_tmp_key(SSL_CONNECTION *s, unsigned long cid) { /* If not Suite B just need a shared group */ if (!tls1_suiteb(s)) @@ -993,9 +1315,9 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) * curves permitted. */ if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return tls1_check_group_id(s, TLSEXT_curve_P_256, 1); + return tls1_check_group_id(s, OSSL_TLS_GROUP_ID_secp256r1, 1); if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return tls1_check_group_id(s, TLSEXT_curve_P_384, 1); + return tls1_check_group_id(s, OSSL_TLS_GROUP_ID_secp384r1, 1); return 0; } @@ -1007,6 +1329,9 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_ecdsa_secp521r1_sha512, TLSEXT_SIGALG_ed25519, TLSEXT_SIGALG_ed448, + TLSEXT_SIGALG_ecdsa_brainpoolP256r1_sha256, + TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384, + TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512, TLSEXT_SIGALG_rsa_pss_pss_sha256, TLSEXT_SIGALG_rsa_pss_pss_sha384, @@ -1069,6 +1394,15 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { {NULL, TLSEXT_SIGALG_ecdsa_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA1, NID_undef, 1}, + {"ecdsa_brainpoolP256r1_sha256", TLSEXT_SIGALG_ecdsa_brainpoolP256r1_sha256, + NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA256, NID_brainpoolP256r1, 1}, + {"ecdsa_brainpoolP384r1_sha384", TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384, + NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA384, NID_brainpoolP384r1, 1}, + {"ecdsa_brainpoolP512r1_sha512", TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512, + NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, + NID_ecdsa_with_SHA512, NID_brainpoolP512r1, 1}, {"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, NID_undef, NID_undef, 1}, @@ -1164,24 +1498,36 @@ static const uint16_t tls_default_sigalg[] = { 0, /* SSL_PKEY_ED448 */ }; -int ssl_setup_sig_algs(SSL_CTX *ctx) +int ssl_setup_sigalgs(SSL_CTX *ctx) { - size_t i; + size_t i, cache_idx, sigalgs_len; const SIGALG_LOOKUP *lu; - SIGALG_LOOKUP *cache - = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl)); + SIGALG_LOOKUP *cache = NULL; + uint16_t *tls12_sigalgs_list = NULL; EVP_PKEY *tmpkey = EVP_PKEY_new(); int ret = 0; + if (ctx == NULL) + goto err; + + sigalgs_len = OSSL_NELEM(sigalg_lookup_tbl) + ctx->sigalg_list_len; + + cache = OPENSSL_malloc(sizeof(const SIGALG_LOOKUP) * sigalgs_len); if (cache == NULL || tmpkey == NULL) goto err; + tls12_sigalgs_list = OPENSSL_malloc(sizeof(uint16_t) * sigalgs_len); + if (tls12_sigalgs_list == NULL) + goto err; + ERR_set_mark(); + /* First fill cache and tls12_sigalgs list from legacy algorithm list */ for (i = 0, lu = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) { EVP_PKEY_CTX *pctx; cache[i] = *lu; + tls12_sigalgs_list[i] = tls12_sigalgs[i]; /* * Check hash is available. @@ -1207,26 +1553,48 @@ int ssl_setup_sig_algs(SSL_CTX *ctx) cache[i].enabled = 0; EVP_PKEY_CTX_free(pctx); } + + /* Now complete cache and tls12_sigalgs list with provider sig information */ + cache_idx = OSSL_NELEM(sigalg_lookup_tbl); + for (i = 0; i < ctx->sigalg_list_len; i++) { + TLS_SIGALG_INFO si = ctx->sigalg_list[i]; + cache[cache_idx].name = si.name; + cache[cache_idx].sigalg = si.code_point; + tls12_sigalgs_list[cache_idx] = si.code_point; + cache[cache_idx].hash = si.hash_name?OBJ_txt2nid(si.hash_name):NID_undef; + cache[cache_idx].hash_idx = ssl_get_md_idx(cache[cache_idx].hash); + cache[cache_idx].sig = OBJ_txt2nid(si.sigalg_name); + cache[cache_idx].sig_idx = i + SSL_PKEY_NUM; + cache[cache_idx].sigandhash = OBJ_txt2nid(si.sigalg_name); + cache[cache_idx].curve = NID_undef; + /* all provided sigalgs are enabled by load */ + cache[cache_idx].enabled = 1; + cache_idx++; + } ERR_pop_to_mark(); ctx->sigalg_lookup_cache = cache; + ctx->tls12_sigalgs = tls12_sigalgs_list; + ctx->tls12_sigalgs_len = sigalgs_len; cache = NULL; + tls12_sigalgs_list = NULL; ret = 1; err: OPENSSL_free(cache); + OPENSSL_free(tls12_sigalgs_list); EVP_PKEY_free(tmpkey); return ret; } /* Lookup TLS signature algorithm */ -static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg) +static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL_CONNECTION *s, + uint16_t sigalg) { size_t i; const SIGALG_LOOKUP *lu; - for (i = 0, lu = s->ctx->sigalg_lookup_cache; - /* cache should have the same number of elements as sigalg_lookup_tbl */ - i < OSSL_NELEM(sigalg_lookup_tbl); + for (i = 0, lu = SSL_CONNECTION_GET_CTX(s)->sigalg_lookup_cache; + i < SSL_CONNECTION_GET_CTX(s)->tls12_sigalgs_len; lu++, i++) { if (lu->sigalg == sigalg) { if (!lu->enabled) @@ -1240,6 +1608,7 @@ static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg) int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd) { const EVP_MD *md; + if (lu == NULL) return 0; /* lu->hash == NID_undef means no associated digest */ @@ -1284,15 +1653,17 @@ static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const EVP_PKEY *pkey, * certificate type from |s| will be used. * Returns the signature algorithm to use, or NULL on error. */ -static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) +static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL_CONNECTION *s, + int idx) { if (idx == -1) { if (s->server) { size_t i; /* Work out index corresponding to ciphersuite */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(i); + for (i = 0; i < s->ssl_pkey_num; i++) { + const SSL_CERT_LOOKUP *clu + = ssl_cert_lookup_by_idx(i, SSL_CONNECTION_GET_CTX(s)); if (clu == NULL) continue; @@ -1337,12 +1708,13 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) } if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg)) return NULL; + if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) { const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]); if (lu == NULL) return NULL; - if (!tls1_lookup_md(s->ctx, lu, NULL)) + if (!tls1_lookup_md(SSL_CONNECTION_GET_CTX(s), lu, NULL)) return NULL; if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) return NULL; @@ -1353,12 +1725,12 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) return &legacy_rsa_sigalg; } /* Set peer sigalg based key type */ -int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey) +int tls1_set_peer_legacy_sigalg(SSL_CONNECTION *s, const EVP_PKEY *pkey) { size_t idx; const SIGALG_LOOKUP *lu; - if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL) + if (ssl_cert_lookup_by_pkey(pkey, &idx, SSL_CONNECTION_GET_CTX(s)) == NULL) return 0; lu = tls1_get_legacy_sigalg(s, idx); if (lu == NULL) @@ -1367,7 +1739,7 @@ int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey) return 1; } -size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) +size_t tls12_get_psigalgs(SSL_CONNECTION *s, int sent, const uint16_t **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other @@ -1398,8 +1770,8 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) *psigs = s->cert->conf_sigalgs; return s->cert->conf_sigalgslen; } else { - *psigs = tls12_sigalgs; - return OSSL_NELEM(tls12_sigalgs); + *psigs = SSL_CONNECTION_GET_CTX(s)->tls12_sigalgs; + return SSL_CONNECTION_GET_CTX(s)->tls12_sigalgs_len; } } @@ -1407,7 +1779,7 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) * Called by servers only. Checks that we have a sig alg that supports the * specified EC curve. */ -int tls_check_sigalg_curve(const SSL *s, int curve) +int tls_check_sigalg_curve(const SSL_CONNECTION *s, int curve) { const uint16_t *sigs; size_t siglen, i; @@ -1416,8 +1788,8 @@ int tls_check_sigalg_curve(const SSL *s, int curve) sigs = s->cert->conf_sigalgs; siglen = s->cert->conf_sigalgslen; } else { - sigs = tls12_sigalgs; - siglen = OSSL_NELEM(tls12_sigalgs); + sigs = SSL_CONNECTION_GET_CTX(s)->tls12_sigalgs; + siglen = SSL_CONNECTION_GET_CTX(s)->tls12_sigalgs_len; } for (i = 0; i < siglen; i++) { @@ -1474,6 +1846,14 @@ static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) else if (lu->sigalg == TLSEXT_SIGALG_ed448) secbits = 224; } + /* + * For provider-based sigalgs we have secbits information available + * in the (provider-loaded) sigalg_list structure + */ + if ((secbits == 0) && (lu->sig_idx >= SSL_PKEY_NUM) + && ((lu->sig_idx - SSL_PKEY_NUM) < (int)ctx->sigalg_list_len)) { + secbits = ctx->sigalg_list[lu->sig_idx - SSL_PKEY_NUM].secbits; + } return secbits; } @@ -1482,7 +1862,7 @@ static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) * algorithms and if so set relevant digest and signature scheme in * s. */ -int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) +int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey) { const uint16_t *sent_sigs; const EVP_MD *md = NULL; @@ -1493,10 +1873,8 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) int secbits = 0; pkeyid = EVP_PKEY_get_id(pkey); - /* Should never happen */ - if (pkeyid == -1) - return -1; - if (SSL_IS_TLS13(s)) { + + if (SSL_CONNECTION_IS_TLS13(s)) { /* Disallow DSA for TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); @@ -1507,19 +1885,30 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) pkeyid = EVP_PKEY_RSA_PSS; } lu = tls1_lookup_sigalg(s, sig); + /* if this sigalg is loaded, set so far unknown pkeyid to its sig NID */ + if ((pkeyid == EVP_PKEY_KEYMGMT) && (lu != NULL)) + pkeyid = lu->sig; + + /* Should never happen */ + if (pkeyid == -1) + return -1; + /* * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type * is consistent with signature: RSA keys can be used for RSA-PSS */ if (lu == NULL - || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) + || (SSL_CONNECTION_IS_TLS13(s) + && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) || (pkeyid != lu->sig && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Check the sigalg is consistent with the key OID */ - if (!ssl_cert_lookup_by_nid(EVP_PKEY_get_id(pkey), &cidx) + if (!ssl_cert_lookup_by_nid( + (pkeyid == EVP_PKEY_RSA_PSS) ? EVP_PKEY_get_id(pkey) : pkeyid, + &cidx, SSL_CONNECTION_GET_CTX(s)) || lu->sig_idx != (int)cidx) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; @@ -1535,7 +1924,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) } /* For TLS 1.3 or Suite B check curve matches signature algorithm */ - if (SSL_IS_TLS13(s) || tls1_suiteb(s)) { + if (SSL_CONNECTION_IS_TLS13(s) || tls1_suiteb(s)) { int curve = ssl_get_EC_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { @@ -1543,7 +1932,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) return 0; } } - if (!SSL_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_TLS13(s)) { /* Check curve matches extensions */ if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); @@ -1576,7 +1965,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - if (!tls1_lookup_md(s->ctx, lu, &md)) { + if (!tls1_lookup_md(SSL_CONNECTION_GET_CTX(s), lu, &md)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST); return 0; } @@ -1586,7 +1975,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) */ sigalgstr[0] = (sig >> 8) & 0xff; sigalgstr[1] = sig & 0xff; - secbits = sigalg_security_bits(s->ctx, lu); + secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu); if (secbits == 0 || !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits, md != NULL ? EVP_MD_get_type(md) : NID_undef, @@ -1601,17 +1990,27 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3.tmp.peer_sigalg == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->s3.tmp.peer_sigalg == NULL) return 0; - *pnid = s->s3.tmp.peer_sigalg->sig; + *pnid = sc->s3.tmp.peer_sigalg->sig; return 1; } int SSL_get_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3.tmp.sigalg == NULL) + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); + + if (sc == NULL) return 0; - *pnid = s->s3.tmp.sigalg->sig; + + if (sc->s3.tmp.sigalg == NULL) + return 0; + *pnid = sc->s3.tmp.sigalg->sig; return 1; } @@ -1625,7 +2024,7 @@ int SSL_get_signature_type_nid(const SSL *s, int *pnid) * * Call ssl_cipher_disabled() to check that it's enabled or not. */ -int ssl_set_client_disabled(SSL *s) +int ssl_set_client_disabled(SSL_CONNECTION *s) { s->s3.tmp.mask_a = 0; s->s3.tmp.mask_k = 0; @@ -1658,14 +2057,27 @@ int ssl_set_client_disabled(SSL *s) * * Returns 1 when it's disabled, 0 when enabled. */ -int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) +int ssl_cipher_disabled(const SSL_CONNECTION *s, const SSL_CIPHER *c, + int op, int ecdhe) { if (c->algorithm_mkey & s->s3.tmp.mask_k || c->algorithm_auth & s->s3.tmp.mask_a) return 1; if (s->s3.tmp.max_ver == 0) return 1; - if (!SSL_IS_DTLS(s)) { + + if (SSL_IS_QUIC_HANDSHAKE(s)) + /* For QUIC, only allow these ciphersuites. */ + switch (SSL_CIPHER_get_id(c)) { + case TLS1_3_CK_AES_128_GCM_SHA256: + case TLS1_3_CK_AES_256_GCM_SHA384: + case TLS1_3_CK_CHACHA20_POLY1305_SHA256: + break; + default: + return 1; + } + + if (!SSL_CONNECTION_IS_DTLS(s)) { int min_tls = c->min_tls; /* @@ -1679,21 +2091,22 @@ int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver)) return 1; } - if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver) - || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver))) + if (SSL_CONNECTION_IS_DTLS(s) + && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver) + || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver))) return 1; return !ssl_security(s, op, c->strength_bits, 0, (void *)c); } -int tls_use_ticket(SSL *s) +int tls_use_ticket(SSL_CONNECTION *s) { if ((s->options & SSL_OP_NO_TICKET)) return 0; return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL); } -int tls1_set_server_sigalgs(SSL *s) +int tls1_set_server_sigalgs(SSL_CONNECTION *s) { size_t i; @@ -1701,9 +2114,14 @@ int tls1_set_server_sigalgs(SSL *s) OPENSSL_free(s->shared_sigalgs); s->shared_sigalgs = NULL; s->shared_sigalgslen = 0; + /* Clear certificate validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) - s->s3.tmp.valid_flags[i] = 0; + if (s->s3.tmp.valid_flags) + memset(s->s3.tmp.valid_flags, 0, s->ssl_pkey_num * sizeof(uint32_t)); + else + s->s3.tmp.valid_flags = OPENSSL_zalloc(s->ssl_pkey_num * sizeof(uint32_t)); + if (s->s3.tmp.valid_flags == NULL) + return 0; /* * If peer sent no signature algorithms check to see if we support * the default algorithm for each certificate type @@ -1713,7 +2131,7 @@ int tls1_set_server_sigalgs(SSL *s) const uint16_t *sent_sigs; size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); - for (i = 0; i < SSL_PKEY_NUM; i++) { + for (i = 0; i < s->ssl_pkey_num; i++) { const SIGALG_LOOKUP *lu = tls1_get_legacy_sigalg(s, i); size_t j; @@ -1750,7 +2168,8 @@ int tls1_set_server_sigalgs(SSL *s) * ret: (output) on return, if a ticket was decrypted, then this is set to * point to the resulting session. */ -SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, +SSL_TICKET_STATUS tls_get_ticket_from_client(SSL_CONNECTION *s, + CLIENTHELLO_MSG *hello, SSL_SESSION **ret) { size_t size; @@ -1800,8 +2219,10 @@ SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * psess: (output) on return, if a ticket was decrypted, then this is set to * point to the resulting session. */ -SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, - size_t eticklen, const unsigned char *sess_id, +SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s, + const unsigned char *etick, + size_t eticklen, + const unsigned char *sess_id, size_t sesslen, SSL_SESSION **psess) { SSL_SESSION *sess = NULL; @@ -1814,6 +2235,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, SSL_HMAC *hctx = NULL; EVP_CIPHER_CTX *ctx = NULL; SSL_CTX *tctx = s->session_ctx; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (eticklen == 0) { /* @@ -1823,7 +2245,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, ret = SSL_TICKET_EMPTY; goto end; } - if (!SSL_IS_TLS13(s) && s->ext.session_secret_cb) { + if (!SSL_CONNECTION_IS_TLS13(s) && s->ext.session_secret_cb) { /* * Indicate that the ticket couldn't be decrypted rather than * generating the session from ticket now, trigger @@ -1861,7 +2283,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, int rv = 0; if (tctx->ext.ticket_key_evp_cb != NULL) - rv = tctx->ext.ticket_key_evp_cb(s, nctick, + rv = tctx->ext.ticket_key_evp_cb(SSL_CONNECTION_GET_SSL(s), nctick, nctick + TLSEXT_KEYNAME_LENGTH, ctx, ssl_hmac_get0_EVP_MAC_CTX(hctx), @@ -1869,7 +2291,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, #ifndef OPENSSL_NO_DEPRECATED_3_0 else if (tctx->ext.ticket_key_cb != NULL) /* if 0 is returned, write an empty ticket */ - rv = tctx->ext.ticket_key_cb(s, nctick, + rv = tctx->ext.ticket_key_cb(SSL_CONNECTION_GET_SSL(s), nctick, nctick + TLSEXT_KEYNAME_LENGTH, ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0); #endif @@ -1893,8 +2315,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, goto end; } - aes256cbc = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC", - s->ctx->propq); + aes256cbc = EVP_CIPHER_fetch(sctx->libctx, "AES-256-CBC", + sctx->propq); if (aes256cbc == NULL || ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key, sizeof(tctx->ext.secure->tick_hmac_key), @@ -1907,7 +2329,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, goto end; } EVP_CIPHER_free(aes256cbc); - if (SSL_IS_TLS13(s)) + if (SSL_CONNECTION_IS_TLS13(s)) renew_ticket = 1; } /* @@ -1962,7 +2384,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, slen += declen; p = sdec; - sess = d2i_SSL_SESSION(NULL, &p, slen); + sess = d2i_SSL_SESSION_ex(NULL, &p, slen, sctx->libctx, sctx->propq); slen -= p - sdec; OPENSSL_free(sdec); if (sess) { @@ -2014,7 +2436,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (keyname_len > TLSEXT_KEYNAME_LENGTH) keyname_len = TLSEXT_KEYNAME_LENGTH; - retcb = s->session_ctx->decrypt_ticket_cb(s, sess, etick, keyname_len, + retcb = s->session_ctx->decrypt_ticket_cb(SSL_CONNECTION_GET_SSL(s), + sess, etick, keyname_len, ret, s->session_ctx->ticket_cb_data); switch (retcb) { @@ -2052,7 +2475,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } } - if (s->ext.session_secret_cb == NULL || SSL_IS_TLS13(s)) { + if (s->ext.session_secret_cb == NULL || SSL_CONNECTION_IS_TLS13(s)) { switch (ret) { case SSL_TICKET_NO_DECRYPT: case SSL_TICKET_SUCCESS_RENEW: @@ -2067,7 +2490,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Check to see if a signature algorithm is allowed */ -static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) +static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, + const SIGALG_LOOKUP *lu) { unsigned char sigalgstr[2]; int secbits; @@ -2075,30 +2499,31 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) if (lu == NULL || !lu->enabled) return 0; /* DSA is not allowed in TLS 1.3 */ - if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA) + if (SSL_CONNECTION_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA) return 0; /* * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3 * spec */ - if (!s->server && !SSL_IS_DTLS(s) && s->s3.tmp.min_ver >= TLS1_3_VERSION + if (!s->server && !SSL_CONNECTION_IS_DTLS(s) + && s->s3.tmp.min_ver >= TLS1_3_VERSION && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX || lu->hash_idx == SSL_MD_MD5_IDX || lu->hash_idx == SSL_MD_SHA224_IDX)) return 0; /* See if public key algorithm allowed */ - if (ssl_cert_is_disabled(s->ctx, lu->sig_idx)) + if (ssl_cert_is_disabled(SSL_CONNECTION_GET_CTX(s), lu->sig_idx)) return 0; if (lu->sig == NID_id_GostR3410_2012_256 || lu->sig == NID_id_GostR3410_2012_512 || lu->sig == NID_id_GostR3410_2001) { /* We never allow GOST sig algs on the server with TLSv1.3 */ - if (s->server && SSL_IS_TLS13(s)) + if (s->server && SSL_CONNECTION_IS_TLS13(s)) return 0; if (!s->server - && s->method->version == TLS_ANY_VERSION + && SSL_CONNECTION_GET_SSL(s)->method->version == TLS_ANY_VERSION && s->s3.tmp.max_ver >= TLS1_3_VERSION) { int i, num; STACK_OF(SSL_CIPHER) *sk; @@ -2112,7 +2537,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) if (s->s3.tmp.min_ver >= TLS1_3_VERSION) return 0; - sk = SSL_get_ciphers(s); + sk = SSL_get_ciphers(SSL_CONNECTION_GET_SSL(s)); num = sk != NULL ? sk_SSL_CIPHER_num(sk) : 0; for (i = 0; i < num; i++) { const SSL_CIPHER *c; @@ -2131,7 +2556,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) } /* Finally see if security callback allows it */ - secbits = sigalg_security_bits(s->ctx, lu); + secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; sigalgstr[1] = lu->sigalg & 0xff; return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr); @@ -2143,7 +2568,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) * disabled. */ -void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) +void ssl_set_sig_mask(uint32_t *pmask_a, SSL_CONNECTION *s, int op) { const uint16_t *sigalgs; size_t i, sigalgslen; @@ -2160,7 +2585,8 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) if (lu == NULL) continue; - clu = ssl_cert_lookup_by_idx(lu->sig_idx); + clu = ssl_cert_lookup_by_idx(lu->sig_idx, + SSL_CONNECTION_GET_CTX(s)); if (clu == NULL) continue; @@ -2172,7 +2598,7 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) *pmask_a |= disabled_mask; } -int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, +int tls12_copy_sigalgs(SSL_CONNECTION *s, WPACKET *pkt, const uint16_t *psig, size_t psiglen) { size_t i; @@ -2190,7 +2616,7 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, * If TLS 1.3 must have at least one valid TLS 1.3 message * signing algorithm: i.e. neither RSA nor SHA1/SHA224 */ - if (rv == 0 && (!SSL_IS_TLS13(s) + if (rv == 0 && (!SSL_CONNECTION_IS_TLS13(s) || (lu->sig != EVP_PKEY_RSA && lu->hash != NID_sha1 && lu->hash != NID_sha224))) @@ -2202,7 +2628,8 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, } /* Given preference and allowed sigalgs set shared sigalgs */ -static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig, +static size_t tls12_shared_sigalgs(SSL_CONNECTION *s, + const SIGALG_LOOKUP **shsig, const uint16_t *pref, size_t preflen, const uint16_t *allow, size_t allowlen) { @@ -2228,7 +2655,7 @@ static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig, } /* Set shared signature algorithms for SSL structures */ -static int tls1_set_shared_sigalgs(SSL *s) +static int tls1_set_shared_sigalgs(SSL_CONNECTION *s) { const uint16_t *pref, *allow, *conf; size_t preflen, allowlen, conflen; @@ -2262,10 +2689,8 @@ static int tls1_set_shared_sigalgs(SSL *s) } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { - if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) return 0; - } nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); } else { salgs = NULL; @@ -2289,10 +2714,8 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) size >>= 1; - if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) return 0; - } for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++) buf[i] = stmp; @@ -2308,7 +2731,7 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) return 1; } -int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) +int tls1_save_sigalgs(SSL_CONNECTION *s, PACKET *pkt, int cert) { /* Extension ignored for inappropriate versions */ if (!SSL_USE_SIGALGS(s)) @@ -2328,7 +2751,7 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) /* Set preferred digest for each key type */ -int tls1_process_sigalgs(SSL *s) +int tls1_process_sigalgs(SSL_CONNECTION *s) { size_t i; uint32_t *pvalid = s->s3.tmp.valid_flags; @@ -2336,7 +2759,7 @@ int tls1_process_sigalgs(SSL *s) if (!tls1_set_shared_sigalgs(s)) return 0; - for (i = 0; i < SSL_PKEY_NUM; i++) + for (i = 0; i < s->ssl_pkey_num; i++) pvalid[i] = 0; for (i = 0; i < s->shared_sigalgslen; i++) { @@ -2344,10 +2767,11 @@ int tls1_process_sigalgs(SSL *s) int idx = sigptr->sig_idx; /* Ignore PKCS1 based sig algs in TLSv1.3 */ - if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) + if (SSL_CONNECTION_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) continue; /* If not disabled indicate we can explicitly sign */ - if (pvalid[idx] == 0 && !ssl_cert_is_disabled(s->ctx, idx)) + if (pvalid[idx] == 0 + && !ssl_cert_is_disabled(SSL_CONNECTION_GET_CTX(s), idx)) pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; } return 1; @@ -2357,8 +2781,16 @@ int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash, unsigned char *rsig, unsigned char *rhash) { - uint16_t *psig = s->s3.tmp.peer_sigalgs; - size_t numsigalgs = s->s3.tmp.peer_sigalgslen; + uint16_t *psig; + size_t numsigalgs; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + psig = sc->s3.tmp.peer_sigalgs; + numsigalgs = sc->s3.tmp.peer_sigalgslen; + if (psig == NULL || numsigalgs > INT_MAX) return 0; if (idx >= 0) { @@ -2371,7 +2803,7 @@ int SSL_get_sigalgs(SSL *s, int idx, *rhash = (unsigned char)((*psig >> 8) & 0xff); if (rsig != NULL) *rsig = (unsigned char)(*psig & 0xff); - lu = tls1_lookup_sigalg(s, *psig); + lu = tls1_lookup_sigalg(sc, *psig); if (psign != NULL) *psign = lu != NULL ? lu->sig : NID_undef; if (phash != NULL) @@ -2387,12 +2819,17 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, unsigned char *rsig, unsigned char *rhash) { const SIGALG_LOOKUP *shsigalgs; - if (s->shared_sigalgs == NULL + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + if (sc->shared_sigalgs == NULL || idx < 0 - || idx >= (int)s->shared_sigalgslen - || s->shared_sigalgslen > INT_MAX) + || idx >= (int)sc->shared_sigalgslen + || sc->shared_sigalgslen > INT_MAX) return 0; - shsigalgs = s->shared_sigalgs[idx]; + shsigalgs = sc->shared_sigalgs[idx]; if (phash != NULL) *phash = shsigalgs->hash; if (psign != NULL) @@ -2403,7 +2840,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, *rsig = (unsigned char)(shsigalgs->sigalg & 0xff); if (rhash != NULL) *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff); - return (int)s->shared_sigalgslen; + return (int)sc->shared_sigalgslen; } /* Maximum possible number of unique entries in sigalgs array */ @@ -2519,10 +2956,8 @@ int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, { uint16_t *sigalgs; - if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) return 0; - } memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs)); if (client) { @@ -2545,10 +2980,8 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) if (salglen & 1) return 0; - if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) return 0; - } for (i = 0, sptr = sigalgs; i < salglen; i += 2) { size_t j; const SIGALG_LOOKUP *curr; @@ -2584,19 +3017,20 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) return 0; } -static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) +static int tls1_check_sig_alg(SSL_CONNECTION *s, X509 *x, int default_nid) { int sig_nid, use_pc_sigalgs = 0; size_t i; const SIGALG_LOOKUP *sigalg; size_t sigalgslen; + if (default_nid == -1) return 1; sig_nid = X509_get_signature_nid(x); if (default_nid) return sig_nid == default_nid ? 1 : 0; - if (SSL_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { + if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { /* * If we're in TLSv1.3 then we only get here if we're checking the * chain. If the peer has specified peer_cert_sigalgs then we use them @@ -2646,8 +3080,8 @@ static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx) +int tls1_check_chain(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pk, + STACK_OF(X509) *chain, int idx) { int i; int rv = 0; @@ -2656,9 +3090,16 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, CERT *c = s->cert; uint32_t *pvalid; unsigned int suiteb_flags = tls1_suiteb(s); - /* idx == -1 means checking server chains */ + + /* + * Meaning of idx: + * idx == -1 means SSL_check_chain() invocation + * idx == -2 means checking client certificate chains + * idx >= 0 means checking SSL_PKEY index + * + * For RPK, where there may be no cert, we ignore -1 + */ if (idx != -1) { - /* idx == -2 means checking client certificate chains */ if (idx == -2) { cpk = c->key; idx = (int)(cpk - c->pkeys); @@ -2669,16 +3110,23 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, pk = cpk->privatekey; chain = cpk->chain; strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT; + if (tls12_rpk_and_privkey(s, idx)) { + if (EVP_PKEY_is_a(pk, "EC") && !tls1_check_pkey_comp(s, pk)) + return 0; + *pvalid = rv = CERT_PKEY_RPK; + return rv; + } /* If no cert or key, forget it */ - if (!x || !pk) + if (x == NULL || pk == NULL) goto end; } else { size_t certidx; - if (!x || !pk) + if (x == NULL || pk == NULL) return 0; - if (ssl_cert_lookup_by_pkey(pk, &certidx) == NULL) + if (ssl_cert_lookup_by_pkey(pk, &certidx, + SSL_CONNECTION_GET_CTX(s)) == NULL) return 0; idx = certidx; pvalid = s->s3.tmp.valid_flags + idx; @@ -2705,9 +3153,11 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, * Check all signature algorithms are consistent with signature * algorithms extension if TLS 1.2 or later and strict mode. */ - if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { + if (TLS1_get_version(SSL_CONNECTION_GET_SSL(s)) >= TLS1_2_VERSION + && strict_mode) { int default_nid; int rsign = 0; + if (s->s3.tmp.peer_cert_sigalgs != NULL || s->s3.tmp.peer_sigalgs != NULL) { default_nid = 0; @@ -2770,7 +3220,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, } } /* Check signature algorithm of each cert in chain */ - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { /* * We only get here if the application has called SSL_check_chain(), * so check_flags is always set. @@ -2871,7 +3321,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, end: - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (TLS1_get_version(SSL_CONNECTION_GET_SSL(s)) >= TLS1_2_VERSION) rv |= *pvalid & (CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN); else rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; @@ -2893,7 +3343,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, } /* Set validity of certificates in an SSL structure */ -void tls1_set_cert_validity(SSL *s) +void tls1_set_cert_validity(SSL_CONNECTION *s) { tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_PSS_SIGN); @@ -2909,10 +3359,15 @@ void tls1_set_cert_validity(SSL *s) /* User level utility function to check a chain is suitable */ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) { - return tls1_check_chain(s, x, pk, chain, -1); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return tls1_check_chain(sc, x, pk, chain, -1); } -EVP_PKEY *ssl_get_auto_dh(SSL *s) +EVP_PKEY *ssl_get_auto_dh(SSL_CONNECTION *s) { EVP_PKEY *dhp = NULL; BIGNUM *p; @@ -2920,6 +3375,7 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s) EVP_PKEY_CTX *pctx = NULL; OSSL_PARAM_BLD *tmpl = NULL; OSSL_PARAM *params = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (s->cert->dh_tmp_auto != 2) { if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { @@ -2935,7 +3391,8 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s) } /* Do not pick a prime that is too weak for the current security level */ - sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL); + sec_level_bits = ssl_get_security_level_bits(SSL_CONNECTION_GET_SSL(s), + NULL, NULL); if (dh_secbits < sec_level_bits) dh_secbits = sec_level_bits; @@ -2952,7 +3409,7 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s) if (p == NULL) goto err; - pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, "DH", sctx->propq); if (pctx == NULL || EVP_PKEY_fromdata_init(pctx) != 1) goto err; @@ -2976,10 +3433,12 @@ EVP_PKEY *ssl_get_auto_dh(SSL *s) return dhp; } -static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) +static int ssl_security_cert_key(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x, + int op) { int secbits = -1; EVP_PKEY *pkey = X509_get0_pubkey(x); + if (pkey) { /* * If no parameters this will return -1 and fail using the default @@ -2989,16 +3448,18 @@ static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) */ secbits = EVP_PKEY_get_security_bits(pkey); } - if (s) + if (s != NULL) return ssl_security(s, op, secbits, 0, x); else return ssl_ctx_security(ctx, op, secbits, 0, x); } -static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op) +static int ssl_security_cert_sig(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x, + int op) { /* Lookup signature algorithm digest */ int secbits, nid, pknid; + /* Don't check signature if self signed */ if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0) return 1; @@ -3007,13 +3468,14 @@ static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op) /* If digest NID not defined use signature NID */ if (nid == NID_undef) nid = pknid; - if (s) + if (s != NULL) return ssl_security(s, op, secbits, nid, x); else return ssl_ctx_security(ctx, op, secbits, nid, x); } -int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee) +int ssl_security_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x, int vfy, + int is_ee) { if (vfy) vfy = SSL_SECOP_PEER; @@ -3035,9 +3497,11 @@ int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee) * one to the peer. Return values: 1 if ok otherwise error code to use */ -int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) +int ssl_security_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk, + X509 *x, int vfy) { int rv, start_idx, i; + if (x == NULL) { x = sk_X509_value(sk, 0); if (x == NULL) @@ -3064,10 +3528,12 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) * with the signature algorithm "lu" and return index of certificate. */ -static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) +static int tls12_get_cert_sigalg_idx(const SSL_CONNECTION *s, + const SIGALG_LOOKUP *lu) { int sig_idx = lu->sig_idx; - const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx); + const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx, + SSL_CONNECTION_GET_CTX(s)); /* If not recognised or not supported by cipher mask it is not suitable */ if (clu == NULL @@ -3076,6 +3542,10 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) && (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0)) return -1; + /* If doing RPK, the CERT_PKEY won't be "valid" */ + if (tls12_rpk_and_privkey(s, sig_idx)) + return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_RPK ? sig_idx : -1; + return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; } @@ -3085,13 +3555,14 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) * the key. * Returns true if the cert is usable and false otherwise. */ -static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, - EVP_PKEY *pkey) +static int check_cert_usable(SSL_CONNECTION *s, const SIGALG_LOOKUP *sig, + X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu; int mdnid, pknid, supported; size_t i; const char *mdname = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* * If the given EVP_PKEY cannot support signing with this digest, @@ -3099,9 +3570,9 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, */ if (sig->hash != NID_undef) mdname = OBJ_nid2sn(sig->hash); - supported = EVP_PKEY_digestsign_supports_digest(pkey, s->ctx->libctx, + supported = EVP_PKEY_digestsign_supports_digest(pkey, sctx->libctx, mdname, - s->ctx->propq); + sctx->propq); if (supported <= 0) return 0; @@ -3143,7 +3614,7 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, * the signature_algorithm_cert restrictions sent by the peer (if any). * Returns false if no usable certificate is found. */ -static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx) +static int has_usable_cert(SSL_CONNECTION *s, const SIGALG_LOOKUP *sig, int idx) { /* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */ if (idx == -1) @@ -3159,12 +3630,12 @@ static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx) * Returns true if the supplied cert |x| and key |pkey| is usable with the * specified signature scheme |sig|, or false otherwise. */ -static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, +static int is_cert_usable(SSL_CONNECTION *s, const SIGALG_LOOKUP *sig, X509 *x, EVP_PKEY *pkey) { size_t idx; - if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL) + if (ssl_cert_lookup_by_pkey(pkey, &idx, SSL_CONNECTION_GET_CTX(s)) == NULL) return 0; /* Check the key is consistent with the sig alg */ @@ -3179,12 +3650,14 @@ static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, * |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our * available certs/keys to find one that works. */ -static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) +static const SIGALG_LOOKUP *find_sig_alg(SSL_CONNECTION *s, X509 *x, + EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu = NULL; size_t i; int curve = -1; EVP_PKEY *tmppkey; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* Look for a shared sigalgs matching possible certificates */ for (i = 0; i < s->shared_sigalgslen; i++) { @@ -3197,7 +3670,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) || lu->sig == EVP_PKEY_RSA) continue; /* Check that we have a cert, and signature_algorithms_cert */ - if (!tls1_lookup_md(s->ctx, lu, NULL)) + if (!tls1_lookup_md(sctx, lu, NULL)) continue; if ((pkey == NULL && !has_usable_cert(s, lu, -1)) || (pkey != NULL && !is_cert_usable(s, lu, x, pkey))) @@ -3213,7 +3686,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) continue; } else if (lu->sig == EVP_PKEY_RSA_PSS) { /* validate that key is large enough for the signature algorithm */ - if (!rsa_pss_check_min_key_size(s->ctx, tmppkey, lu)) + if (!rsa_pss_check_min_key_size(sctx, tmppkey, lu)) continue; } break; @@ -3236,7 +3709,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) * a fatal error: we will either try another certificate or not present one * to the server. In this case no error is set. */ -int tls_choose_sigalg(SSL *s, int fatalerrs) +int tls_choose_sigalg(SSL_CONNECTION *s, int fatalerrs) { const SIGALG_LOOKUP *lu = NULL; int sig_idx = -1; @@ -3244,7 +3717,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) s->s3.tmp.cert = NULL; s->s3.tmp.sigalg = NULL; - if (SSL_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_TLS13(s)) { lu = find_sig_alg(s, NULL, NULL); if (lu == NULL) { if (!fatalerrs) @@ -3264,6 +3737,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) size_t i; if (s->s3.tmp.peer_sigalgs != NULL) { int curve = -1; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* For Suite B need to match signature algorithm to curve */ if (tls1_suiteb(s)) @@ -3294,7 +3768,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) /* validate that key is large enough for the signature algorithm */ EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey; - if (!rsa_pss_check_min_key_size(s->ctx, pkey, lu)) + if (!rsa_pss_check_min_key_size(sctx, pkey, lu)) continue; } if (curve == -1 || lu->curve == curve) @@ -3306,7 +3780,9 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) * in supported_algorithms extension, so when we have GOST-based ciphersuite, * we have to assume GOST support. */ - if (i == s->shared_sigalgslen && s->s3.tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) { + if (i == s->shared_sigalgslen + && (s->s3.tmp.new_cipher->algorithm_auth + & (SSL_aGOST01 | SSL_aGOST12)) != 0) { if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; @@ -3388,13 +3864,19 @@ int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode) int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc == NULL + || (IS_QUIC(ssl) && mode != TLSEXT_max_fragment_length_DISABLED)) + return 0; + if (mode != TLSEXT_max_fragment_length_DISABLED && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) { ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } - ssl->ext.max_fragment_len_mode = mode; + sc->ext.max_fragment_len_mode = mode; return 1; } diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index c1f3d9107a..b05012f74f 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -98,6 +98,7 @@ static const ssl_trace_tbl ssl_handshake_tbl[] = { {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"}, {SSL3_MT_SUPPLEMENTAL_DATA, "SupplementalData"}, {SSL3_MT_KEY_UPDATE, "KeyUpdate"}, + {SSL3_MT_COMPRESSED_CERTIFICATE, "CompressedCertificate"}, # ifndef OPENSSL_NO_NEXTPROTONEG {SSL3_MT_NEXT_PROTO, "NextProto"}, # endif @@ -476,9 +477,12 @@ static const ssl_trace_tbl ssl_exts_tbl[] = { {TLSEXT_TYPE_application_layer_protocol_negotiation, "application_layer_protocol_negotiation"}, {TLSEXT_TYPE_signed_certificate_timestamp, "signed_certificate_timestamps"}, + {TLSEXT_TYPE_client_cert_type, "client_cert_type"}, + {TLSEXT_TYPE_server_cert_type, "server_cert_type"}, {TLSEXT_TYPE_padding, "padding"}, {TLSEXT_TYPE_encrypt_then_mac, "encrypt_then_mac"}, {TLSEXT_TYPE_extended_master_secret, "extended_master_secret"}, + {TLSEXT_TYPE_compress_certificate, "compress_certificate"}, {TLSEXT_TYPE_session_ticket, "session_ticket"}, {TLSEXT_TYPE_psk, "psk"}, {TLSEXT_TYPE_early_data, "early_data"}, @@ -526,6 +530,9 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { {28, "brainpoolP512r1"}, {29, "ecdh_x25519"}, {30, "ecdh_x448"}, + {31, "brainpoolP256r1tls13"}, + {32, "brainpoolP384r1tls13"}, + {33, "brainpoolP512r1tls13"}, {34, "GC256A"}, {35, "GC256B"}, {36, "GC256C"}, @@ -585,6 +592,9 @@ static const ssl_trace_tbl ssl_sigalg_tbl[] = { {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, "gost2012_256"}, {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, "gost2012_512"}, {TLSEXT_SIGALG_gostr34102001_gostr3411, "gost2001_gost94"}, + {TLSEXT_SIGALG_ecdsa_brainpoolP256r1_sha256, "ecdsa_brainpoolP256r1_sha256"}, + {TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384, "ecdsa_brainpoolP384r1_sha384"}, + {TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512, "ecdsa_brainpoolP512r1_sha512"}, }; static const ssl_trace_tbl ssl_ctype_tbl[] = { @@ -612,6 +622,25 @@ static const ssl_trace_tbl ssl_key_update_tbl[] = { {SSL_KEY_UPDATE_REQUESTED, "update_requested"} }; +static const ssl_trace_tbl ssl_comp_cert_tbl[] = { + {TLSEXT_comp_cert_none, "none"}, + {TLSEXT_comp_cert_zlib, "zlib"}, + {TLSEXT_comp_cert_brotli, "brotli"}, + {TLSEXT_comp_cert_zstd, "zstd"} +}; + +/* + * "pgp" and "1609dot2" are defined in RFC7250, + * although OpenSSL doesn't support them, it can + * at least report them in traces + */ +static const ssl_trace_tbl ssl_cert_type_tbl[] = { + {TLSEXT_cert_type_x509, "x509"}, + {TLSEXT_cert_type_pgp, "pgp"}, + {TLSEXT_cert_type_rpk, "rpk"}, + {TLSEXT_cert_type_1609dot2, "1609dot2"} +}; + static void ssl_print_hex(BIO *bio, int indent, const char *name, const unsigned char *msg, size_t msglen) { @@ -686,12 +715,12 @@ static int ssl_print_random(BIO *bio, int indent, return 1; } -static int ssl_print_signature(BIO *bio, int indent, const SSL *ssl, +static int ssl_print_signature(BIO *bio, int indent, const SSL_CONNECTION *sc, const unsigned char **pmsg, size_t *pmsglen) { if (*pmsglen < 2) return 0; - if (SSL_USE_SIGALGS(ssl)) { + if (SSL_USE_SIGALGS(sc)) { const unsigned char *p = *pmsg; unsigned int sigalg = (p[0] << 8) | p[1]; @@ -716,6 +745,14 @@ static int ssl_print_extension(BIO *bio, int indent, int server, BIO_printf(bio, "extension_type=%s(%d), length=%d\n", ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen); switch (extype) { + case TLSEXT_TYPE_compress_certificate: + if (extlen < 1) + return 0; + xlen = ext[0]; + if (extlen != xlen + 1) + return 0; + return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 2, ssl_comp_cert_tbl); + case TLSEXT_TYPE_max_fragment_length: if (extlen < 1) return 0; @@ -887,6 +924,20 @@ static int ssl_print_extension(BIO *bio, int indent, int server, BIO_printf(bio, "max_early_data=%u\n", (unsigned int)max_early_data); break; + case TLSEXT_TYPE_server_cert_type: + case TLSEXT_TYPE_client_cert_type: + if (server) { + if (extlen != 1) + return 0; + return ssl_trace_list(bio, indent + 2, ext, 1, 1, ssl_cert_type_tbl); + } + if (extlen < 1) + return 0; + xlen = ext[0]; + if (extlen != xlen + 1) + return 0; + return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 1, ssl_cert_type_tbl); + default: BIO_dump_indent(bio, (const char *)ext, extlen, indent + 2); } @@ -946,7 +997,7 @@ static int ssl_print_extensions(BIO *bio, int indent, int server, return 1; } -static int ssl_print_client_hello(BIO *bio, const SSL *ssl, int indent, +static int ssl_print_client_hello(BIO *bio, const SSL_CONNECTION *sc, int indent, const unsigned char *msg, size_t msglen) { size_t len; @@ -958,7 +1009,7 @@ static int ssl_print_client_hello(BIO *bio, const SSL *ssl, int indent, return 0; if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) return 0; - if (SSL_IS_DTLS(ssl)) { + if (SSL_CONNECTION_IS_DTLS(sc)) { if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) return 0; } @@ -1049,9 +1100,9 @@ static int ssl_print_server_hello(BIO *bio, int indent, return 1; } -static int ssl_get_keyex(const char **pname, const SSL *ssl) +static int ssl_get_keyex(const char **pname, const SSL_CONNECTION *sc) { - unsigned long alg_k = ssl->s3.tmp.new_cipher->algorithm_mkey; + unsigned long alg_k = sc->s3.tmp.new_cipher->algorithm_mkey; if (alg_k & SSL_kRSA) { *pname = "rsa"; @@ -1097,11 +1148,11 @@ static int ssl_get_keyex(const char **pname, const SSL *ssl) return 0; } -static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, +static int ssl_print_client_keyex(BIO *bio, int indent, const SSL_CONNECTION *sc, const unsigned char *msg, size_t msglen) { const char *algname; - int id = ssl_get_keyex(&algname, ssl); + int id = ssl_get_keyex(&algname, sc); BIO_indent(bio, indent, 80); BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); @@ -1114,7 +1165,7 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, case SSL_kRSA: case SSL_kRSAPSK: - if (TLS1_get_version(ssl) == SSL3_VERSION) { + if (TLS1_get_version(SSL_CONNECTION_GET_SSL(sc)) == SSL3_VERSION) { ssl_print_hex(bio, indent + 2, "EncryptedPreMasterSecret", msg, msglen); } else { @@ -1149,11 +1200,11 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, return !msglen; } -static int ssl_print_server_keyex(BIO *bio, int indent, const SSL *ssl, +static int ssl_print_server_keyex(BIO *bio, int indent, const SSL_CONNECTION *sc, const unsigned char *msg, size_t msglen) { const char *algname; - int id = ssl_get_keyex(&algname, ssl); + int id = ssl_get_keyex(&algname, sc); BIO_indent(bio, indent, 80); BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); @@ -1213,17 +1264,18 @@ static int ssl_print_server_keyex(BIO *bio, int indent, const SSL *ssl, break; } if (!(id & SSL_PSK)) - ssl_print_signature(bio, indent, ssl, &msg, &msglen); + ssl_print_signature(bio, indent, sc, &msg, &msglen); return !msglen; } -static int ssl_print_certificate(BIO *bio, int indent, +static int ssl_print_certificate(BIO *bio, const SSL_CONNECTION *sc, int indent, const unsigned char **pmsg, size_t *pmsglen) { size_t msglen = *pmsglen; size_t clen; X509 *x; const unsigned char *p = *pmsg, *q; + SSL_CTX *ctx = SSL_CONNECTION_GET_CTX(sc); if (msglen < 3) return 0; @@ -1233,8 +1285,12 @@ static int ssl_print_certificate(BIO *bio, int indent, q = p + 3; BIO_indent(bio, indent, 80); BIO_printf(bio, "ASN.1Cert, length=%d", (int)clen); - x = d2i_X509(NULL, &q, clen); - if (!x) + x = X509_new_ex(ctx->libctx, ctx->propq); + if (x != NULL && d2i_X509(&x, &q, clen) == NULL) { + X509_free(x); + x = NULL; + } + if (x == NULL) BIO_puts(bio, "\n"); else { BIO_puts(bio, "\n------details-----\n"); @@ -1252,13 +1308,43 @@ static int ssl_print_certificate(BIO *bio, int indent, return 1; } -static int ssl_print_certificates(BIO *bio, const SSL *ssl, int server, +static int ssl_print_raw_public_key(BIO *bio, const SSL *ssl, int server, + int indent, const unsigned char **pmsg, + size_t *pmsglen) +{ + EVP_PKEY *pkey; + size_t clen; + const unsigned char *msg = *pmsg; + size_t msglen = *pmsglen; + + if (msglen < 3) + return 0; + clen = (msg[0] << 16) | (msg[1] << 8) | msg[2]; + if (msglen < clen + 3) + return 0; + + msg += 3; + + BIO_indent(bio, indent, 80); + BIO_printf(bio, "raw_public_key, length=%d\n", (int)clen); + + pkey = d2i_PUBKEY_ex(NULL, &msg, clen, ssl->ctx->libctx, ssl->ctx->propq); + if (pkey == NULL) + return 0; + EVP_PKEY_print_public(bio, pkey, indent + 2, NULL); + EVP_PKEY_free(pkey); + *pmsg += clen + 3; + *pmsglen -= clen + 3; + return 1; +} + +static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server, int indent, const unsigned char *msg, size_t msglen) { size_t clen; - if (SSL_IS_TLS13(ssl) + if (SSL_CONNECTION_IS_TLS13(sc) && !ssl_print_hexbuf(bio, indent, "context", 1, &msg, &msglen)) return 0; @@ -1268,12 +1354,22 @@ static int ssl_print_certificates(BIO *bio, const SSL *ssl, int server, if (msglen != clen + 3) return 0; msg += 3; + if ((server && sc->ext.server_cert_type == TLSEXT_cert_type_rpk) + || (!server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk)) { + if (!ssl_print_raw_public_key(bio, &sc->ssl, server, indent, &msg, &clen)) + return 0; + if (SSL_CONNECTION_IS_TLS13(sc) + && !ssl_print_extensions(bio, indent + 2, server, + SSL3_MT_CERTIFICATE, &msg, &clen)) + return 0; + return 1; + } BIO_indent(bio, indent, 80); BIO_printf(bio, "certificate_list, length=%d\n", (int)clen); while (clen > 0) { - if (!ssl_print_certificate(bio, indent + 2, &msg, &clen)) + if (!ssl_print_certificate(bio, sc, indent + 2, &msg, &clen)) return 0; - if (SSL_IS_TLS13(ssl) + if (SSL_CONNECTION_IS_TLS13(sc) && !ssl_print_extensions(bio, indent + 2, server, SSL3_MT_CERTIFICATE, &msg, &clen)) return 0; @@ -1282,13 +1378,84 @@ static int ssl_print_certificates(BIO *bio, const SSL *ssl, int server, return 1; } -static int ssl_print_cert_request(BIO *bio, int indent, const SSL *ssl, +static int ssl_print_compressed_certificates(BIO *bio, const SSL_CONNECTION *sc, + int server, int indent, + const unsigned char *msg, + size_t msglen) +{ + size_t uclen; + size_t clen; + unsigned int alg; + int ret = 1; +#ifndef OPENSSL_NO_COMP_ALG + COMP_METHOD *method; + COMP_CTX *comp = NULL; + unsigned char* ucdata = NULL; +#endif + + if (msglen < 8) + return 0; + + alg = (msg[0] << 8) | msg[1]; + uclen = (msg[2] << 16) | (msg[3] << 8) | msg[4]; + clen = (msg[5] << 16) | (msg[6] << 8) | msg[7]; + if (msglen != clen + 8) + return 0; + + msg += 8; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "Compression type=%s (0x%04x)\n", ssl_trace_str(alg, ssl_comp_cert_tbl), alg); + BIO_indent(bio, indent, 80); + BIO_printf(bio, "Uncompressed length=%d\n", (int)uclen); + BIO_indent(bio, indent, 80); + if (clen > 0) + BIO_printf(bio, "Compressed length=%d, Ratio=%f:1\n", (int)clen, (float)uclen / (float)clen); + else + BIO_printf(bio, "Compressed length=%d, Ratio=unknown\n", (int)clen); + + BIO_dump_indent(bio, (const char *)msg, clen, indent); + +#ifndef OPENSSL_NO_COMP_ALG + if (!ossl_comp_has_alg(alg)) + return 0; + + /* Check against certificate maximum size (coverity) */ + if (uclen == 0 || uclen > 0xFFFFFF || (ucdata = OPENSSL_malloc(uclen)) == NULL) + return 0; + + switch (alg) { + case TLSEXT_comp_cert_zlib: + method = COMP_zlib(); + break; + case TLSEXT_comp_cert_brotli: + method = COMP_brotli_oneshot(); + break; + case TLSEXT_comp_cert_zstd: + method = COMP_zstd_oneshot(); + break; + default: + goto err; + } + + if ((comp = COMP_CTX_new(method)) == NULL + || COMP_expand_block(comp, ucdata, uclen, (unsigned char*)msg, clen) != (int)uclen) + goto err; + + ret = ssl_print_certificates(bio, sc, server, indent, ucdata, uclen); + err: + COMP_CTX_free(comp); + OPENSSL_free(ucdata); +#endif + return ret; +} + +static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc, const unsigned char *msg, size_t msglen) { size_t xlen; unsigned int sigalg; - if (SSL_IS_TLS13(ssl)) { + if (SSL_CONNECTION_IS_TLS13(sc)) { if (!ssl_print_hexbuf(bio, indent, "request_context", 1, &msg, &msglen)) return 0; if (!ssl_print_extensions(bio, indent, 1, @@ -1309,7 +1476,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL *ssl, msg += xlen; msglen -= xlen + 1; } - if (SSL_USE_SIGALGS(ssl)) { + if (SSL_USE_SIGALGS(sc)) { if (msglen < 2) return 0; xlen = (msg[0] << 8) | msg[1]; @@ -1363,7 +1530,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL *ssl, xlen -= dlen + 2; msg += dlen; } - if (SSL_IS_TLS13(ssl)) { + if (SSL_CONNECTION_IS_TLS13(sc)) { if (!ssl_print_hexbuf(bio, indent, "request_extensions", 2, &msg, &msglen)) return 0; @@ -1371,7 +1538,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL *ssl, return msglen == 0; } -static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, +static int ssl_print_ticket(BIO *bio, int indent, const SSL_CONNECTION *sc, const unsigned char *msg, size_t msglen) { unsigned int tick_life; @@ -1391,7 +1558,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, msg += 4; BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life); - if (SSL_IS_TLS13(ssl)) { + if (SSL_CONNECTION_IS_TLS13(sc)) { unsigned int ticket_age_add; if (msglen < 4) @@ -1411,7 +1578,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, } if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen)) return 0; - if (SSL_IS_TLS13(ssl) + if (SSL_CONNECTION_IS_TLS13(sc) && !ssl_print_extensions(bio, indent + 2, 0, SSL3_MT_NEWSESSION_TICKET, &msg, &msglen)) return 0; @@ -1420,7 +1587,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, return 1; } -static int ssl_print_handshake(BIO *bio, const SSL *ssl, int server, +static int ssl_print_handshake(BIO *bio, const SSL_CONNECTION *sc, int server, const unsigned char *msg, size_t msglen, int indent) { @@ -1436,7 +1603,7 @@ static int ssl_print_handshake(BIO *bio, const SSL *ssl, int server, ssl_trace_str(htype, ssl_handshake_tbl), (int)hlen); msg += 4; msglen -= 4; - if (SSL_IS_DTLS(ssl)) { + if (SSL_CONNECTION_IS_DTLS(sc)) { if (msglen < 8) return 0; BIO_indent(bio, indent, 80); @@ -1452,7 +1619,7 @@ static int ssl_print_handshake(BIO *bio, const SSL *ssl, int server, return 0; switch (htype) { case SSL3_MT_CLIENT_HELLO: - if (!ssl_print_client_hello(bio, ssl, indent + 2, msg, msglen)) + if (!ssl_print_client_hello(bio, sc, indent + 2, msg, msglen)) return 0; break; @@ -1467,27 +1634,32 @@ static int ssl_print_handshake(BIO *bio, const SSL *ssl, int server, break; case SSL3_MT_SERVER_KEY_EXCHANGE: - if (!ssl_print_server_keyex(bio, indent + 2, ssl, msg, msglen)) + if (!ssl_print_server_keyex(bio, indent + 2, sc, msg, msglen)) return 0; break; case SSL3_MT_CLIENT_KEY_EXCHANGE: - if (!ssl_print_client_keyex(bio, indent + 2, ssl, msg, msglen)) + if (!ssl_print_client_keyex(bio, indent + 2, sc, msg, msglen)) return 0; break; case SSL3_MT_CERTIFICATE: - if (!ssl_print_certificates(bio, ssl, server, indent + 2, msg, msglen)) + if (!ssl_print_certificates(bio, sc, server, indent + 2, msg, msglen)) + return 0; + break; + + case SSL3_MT_COMPRESSED_CERTIFICATE: + if (!ssl_print_compressed_certificates(bio, sc, server, indent + 2, msg, msglen)) return 0; break; case SSL3_MT_CERTIFICATE_VERIFY: - if (!ssl_print_signature(bio, indent + 2, ssl, &msg, &msglen)) + if (!ssl_print_signature(bio, indent + 2, sc, &msg, &msglen)) return 0; break; case SSL3_MT_CERTIFICATE_REQUEST: - if (!ssl_print_cert_request(bio, indent + 2, ssl, msg, msglen)) + if (!ssl_print_cert_request(bio, indent + 2, sc, msg, msglen)) return 0; break; @@ -1501,7 +1673,7 @@ static int ssl_print_handshake(BIO *bio, const SSL *ssl, int server, break; case SSL3_MT_NEWSESSION_TICKET: - if (!ssl_print_ticket(bio, indent + 2, ssl, msg, msglen)) + if (!ssl_print_ticket(bio, indent + 2, sc, msg, msglen)) return 0; break; @@ -1534,6 +1706,23 @@ void SSL_trace(int write_p, int version, int content_type, { const unsigned char *msg = buf; BIO *bio = arg; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); +#ifndef OPENSSL_NO_QUIC + QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(ssl); + + if (qc != NULL) { + if (ossl_quic_trace(write_p, version, content_type, buf, msglen, ssl, + arg)) + return; + /* + * Otherwise ossl_quic_trace didn't handle this content_type so we + * fallback to standard TLS handling + */ + } +#endif + + if (sc == NULL) + return; switch (content_type) { case SSL3_RT_HEADER: @@ -1541,7 +1730,7 @@ void SSL_trace(int write_p, int version, int content_type, int hvers; /* avoid overlapping with length at the end of buffer */ - if (msglen < (size_t)(SSL_IS_DTLS(ssl) ? + if (msglen < (size_t)(SSL_CONNECTION_IS_DTLS(sc) ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH)) { BIO_puts(bio, write_p ? "Sent" : "Received"); ssl_print_hex(bio, 0, " too short message", msg, msglen); @@ -1549,9 +1738,9 @@ void SSL_trace(int write_p, int version, int content_type, } hvers = msg[1] << 8 | msg[2]; BIO_puts(bio, write_p ? "Sent" : "Received"); - BIO_printf(bio, " Record\nHeader:\n Version = %s (0x%x)\n", + BIO_printf(bio, " TLS Record\nHeader:\n Version = %s (0x%x)\n", ssl_trace_str(hvers, ssl_version_tbl), hvers); - if (SSL_IS_DTLS(ssl)) { + if (SSL_CONNECTION_IS_DTLS(sc)) { BIO_printf(bio, " epoch=%d, sequence_number=%04x%04x%04x\n", (msg[3] << 8 | msg[4]), @@ -1571,7 +1760,7 @@ void SSL_trace(int write_p, int version, int content_type, break; case SSL3_RT_HANDSHAKE: - if (!ssl_print_handshake(bio, ssl, ssl->server ? write_p : !write_p, + if (!ssl_print_handshake(bio, sc, sc->server ? write_p : !write_p, msg, msglen, 4)) BIO_printf(bio, "Message length parse error!\n"); break; diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 9ae2126e3c..772a6fc173 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,14 +27,16 @@ static const unsigned char label_prefix[] = "\x74\x6C\x73\x31\x33\x20"; * secret |outlen| bytes long and store it in the location pointed to be |out|. * The |data| value may be zero length. Any errors will be treated as fatal if * |fatal| is set. Returns 1 on success 0 on failure. + * If |raise_error| is set, ERR_raise is called on failure. */ -int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, - const unsigned char *label, size_t labellen, - const unsigned char *data, size_t datalen, - unsigned char *out, size_t outlen, int fatal) +int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EVP_MD *md, + const unsigned char *secret, + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen, int raise_error) { - EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, - s->ctx->propq); + EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_TLS1_3_KDF, propq); EVP_KDF_CTX *kctx; OSSL_PARAM params[7], *p = params; int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; @@ -48,24 +50,20 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, return 0; if (labellen > TLS13_MAX_LABEL_LEN) { - if (fatal) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - } else { + if (raise_error) /* * Probably we have been called from SSL_export_keying_material(), * or SSL_export_keying_material_early(). */ ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); - } + EVP_KDF_CTX_free(kctx); return 0; } if ((ret = EVP_MD_get_size(md)) <= 0) { EVP_KDF_CTX_free(kctx); - if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - else + if (raise_error) ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } @@ -91,20 +89,37 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, EVP_KDF_CTX_free(kctx); if (ret != 0) { - if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - else + if (raise_error) ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); } return ret == 0; } +int tls13_hkdf_expand(SSL_CONNECTION *s, const EVP_MD *md, + const unsigned char *secret, + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen, int fatal) +{ + int ret; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + + ret = tls13_hkdf_expand_ex(sctx->libctx, sctx->propq, md, + secret, label, labellen, data, datalen, + out, outlen, !fatal); + if (ret == 0 && fatal) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + + return ret; +} + /* * Given a |secret| generate a |key| of length |keylen| bytes. Returns 1 on * success 0 on failure. */ -int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret, +int tls13_derive_key(SSL_CONNECTION *s, const EVP_MD *md, + const unsigned char *secret, unsigned char *key, size_t keylen) { /* ASCII: "key", in hex for EBCDIC compatibility */ @@ -118,7 +133,8 @@ int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret, * Given a |secret| generate an |iv| of length |ivlen| bytes. Returns 1 on * success 0 on failure. */ -int tls13_derive_iv(SSL *s, const EVP_MD *md, const unsigned char *secret, +int tls13_derive_iv(SSL_CONNECTION *s, const EVP_MD *md, + const unsigned char *secret, unsigned char *iv, size_t ivlen) { /* ASCII: "iv", in hex for EBCDIC compatibility */ @@ -128,7 +144,7 @@ int tls13_derive_iv(SSL *s, const EVP_MD *md, const unsigned char *secret, NULL, 0, iv, ivlen, 1); } -int tls13_derive_finishedkey(SSL *s, const EVP_MD *md, +int tls13_derive_finishedkey(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *secret, unsigned char *fin, size_t finlen) { @@ -144,7 +160,7 @@ int tls13_derive_finishedkey(SSL *s, const EVP_MD *md, * length |insecretlen|, generate a new secret and store it in the location * pointed to by |outsecret|. Returns 1 on success 0 on failure. */ -int tls13_generate_secret(SSL *s, const EVP_MD *md, +int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *prevsecret, const unsigned char *insecret, size_t insecretlen, @@ -160,8 +176,9 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, const char *mdname = EVP_MD_get0_name(md); /* ASCII: "derived", in hex for EBCDIC compatibility */ static const char derived_secret_label[] = "\x64\x65\x72\x69\x76\x65\x64"; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, s->ctx->propq); + kdf = EVP_KDF_fetch(sctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, sctx->propq); kctx = EVP_KDF_CTX_new(kdf); EVP_KDF_free(kdf); if (kctx == NULL) { @@ -210,8 +227,9 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, * handshake secret. This requires the early secret to already have been * generated. Returns 1 on success 0 on failure. */ -int tls13_generate_handshake_secret(SSL *s, const unsigned char *insecret, - size_t insecretlen) +int tls13_generate_handshake_secret(SSL_CONNECTION *s, + const unsigned char *insecret, + size_t insecretlen) { /* Calls SSLfatal() if required */ return tls13_generate_secret(s, ssl_handshake_md(s), s->early_secret, @@ -224,7 +242,7 @@ int tls13_generate_handshake_secret(SSL *s, const unsigned char *insecret, * secret and store its length in |*secret_size|. Returns 1 on success 0 on * failure. */ -int tls13_generate_master_secret(SSL *s, unsigned char *out, +int tls13_generate_master_secret(SSL_CONNECTION *s, unsigned char *out, unsigned char *prev, size_t prevlen, size_t *secret_size) { @@ -239,7 +257,7 @@ int tls13_generate_master_secret(SSL *s, unsigned char *out, * Generates the mac for the Finished message. Returns the length of the MAC or * 0 on error. */ -size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, +size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen, unsigned char *out) { const EVP_MD *md = ssl_handshake_md(s); @@ -249,14 +267,15 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, unsigned char *key = NULL; size_t len = 0, hashlen; OSSL_PARAM params[2], *p = params; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (md == NULL) return 0; /* Safe to cast away const here since we're not "getting" any data */ - if (s->ctx->propq != NULL) + if (sctx->propq != NULL) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES, - (char *)s->ctx->propq, + (char *)sctx->propq, 0); *p = OSSL_PARAM_construct_end(); @@ -265,7 +284,7 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, goto err; } - if (str == s->method->ssl3_enc->server_finished_label) { + if (str == SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->server_finished_label) { key = s->server_finished_secret; } else if (SSL_IS_FIRST_HANDSHAKE(s)) { key = s->client_finished_secret; @@ -277,7 +296,7 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, key = finsecret; } - if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname, + if (!EVP_Q_mac(sctx->libctx, "HMAC", sctx->propq, mdname, params, key, hashlen, hash, hashlen, /* outsize as per sizeof(peer_finish_md) */ out, EVP_MAX_MD_SIZE * 2, &len)) { @@ -294,14 +313,14 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, * There isn't really a key block in TLSv1.3, but we still need this function * for initialising the cipher and hash. Returns 1 on success or 0 on failure. */ -int tls13_setup_key_block(SSL *s) +int tls13_setup_key_block(SSL_CONNECTION *s) { const EVP_CIPHER *c; const EVP_MD *hash; s->session->cipher = s->s3.tmp.new_cipher; - if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, NULL, - 0)) { + if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, + NULL, NULL, NULL, 0)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; @@ -315,18 +334,19 @@ int tls13_setup_key_block(SSL *s) return 1; } -static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, +static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, const EVP_CIPHER *ciph, const unsigned char *insecret, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, - unsigned char *key, unsigned char *iv, - EVP_CIPHER_CTX *ciph_ctx) + unsigned char *key, size_t *keylen, + unsigned char *iv, size_t *ivlen, + size_t *taglen) { - size_t ivlen, keylen, taglen; int hashleni = EVP_MD_get_size(md); size_t hashlen; + int mode; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashleni >= 0)) { @@ -341,11 +361,13 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, return 0; } - keylen = EVP_CIPHER_get_key_length(ciph); - if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) { + *keylen = EVP_CIPHER_get_key_length(ciph); + + mode = EVP_CIPHER_get_mode(ciph); + if (mode == EVP_CIPH_CCM_MODE) { uint32_t algenc; - ivlen = EVP_CCM_TLS_IV_LEN; + *ivlen = EVP_CCM_TLS_IV_LEN; if (s->s3.tmp.new_cipher != NULL) { algenc = s->s3.tmp.new_cipher->algorithm_enc; } else if (s->session->cipher != NULL) { @@ -359,33 +381,36 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, return 0; } if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) - taglen = EVP_CCM8_TLS_TAG_LEN; + *taglen = EVP_CCM8_TLS_TAG_LEN; else - taglen = EVP_CCM_TLS_TAG_LEN; + *taglen = EVP_CCM_TLS_TAG_LEN; } else { - ivlen = EVP_CIPHER_get_iv_length(ciph); - taglen = 0; - } + int iivlen; - if (!tls13_derive_key(s, md, secret, key, keylen) - || !tls13_derive_iv(s, md, secret, iv, ivlen)) { - /* SSLfatal() already called */ - return 0; + if (mode == EVP_CIPH_GCM_MODE) { + *taglen = EVP_GCM_TLS_TAG_LEN; + } else { + /* CHACHA20P-POLY1305 */ + *taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; + } + iivlen = EVP_CIPHER_get_iv_length(ciph); + if (iivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + *ivlen = iivlen; } - if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0 - || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0 - || (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, - taglen, NULL) <= 0) - || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + if (!tls13_derive_key(s, md, secret, key, *keylen) + || !tls13_derive_iv(s, md, secret, iv, *ivlen)) { + /* SSLfatal() already called */ return 0; } return 1; } -int tls13_change_cipher_state(SSL *s, int which) +int tls13_change_cipher_state(SSL_CONNECTION *s, int which) { /* ASCII: "c e traffic", in hex for EBCDIC compatibility */ static const unsigned char client_early_traffic[] = "\x63\x20\x65\x20\x74\x72\x61\x66\x66\x69\x63"; @@ -403,7 +428,7 @@ int tls13_change_cipher_state(SSL *s, int which) static const unsigned char resumption_master_secret[] = "\x72\x65\x73\x20\x6D\x61\x73\x74\x65\x72"; /* ASCII: "e exp master", in hex for EBCDIC compatibility */ static const unsigned char early_exporter_master_secret[] = "\x65\x20\x65\x78\x70\x20\x6D\x61\x73\x74\x65\x72"; - unsigned char *iv; + unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; @@ -411,48 +436,17 @@ int tls13_change_cipher_state(SSL *s, int which) unsigned char *insecret; unsigned char *finsecret = NULL; const char *log_label = NULL; - EVP_CIPHER_CTX *ciph_ctx; size_t finsecretlen = 0; const unsigned char *label; size_t labellen, hashlen = 0; int ret = 0; const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; -#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) - ktls_crypto_info_t crypto_info; - BIO *bio; -#endif - - if (which & SSL3_CC_READ) { - if (s->enc_read_ctx != NULL) { - EVP_CIPHER_CTX_reset(s->enc_read_ctx); - } else { - s->enc_read_ctx = EVP_CIPHER_CTX_new(); - if (s->enc_read_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - } - ciph_ctx = s->enc_read_ctx; - iv = s->read_iv; - - RECORD_LAYER_reset_read_sequence(&s->rlayer); - } else { - s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; - if (s->enc_write_ctx != NULL) { - EVP_CIPHER_CTX_reset(s->enc_write_ctx); - } else { - s->enc_write_ctx = EVP_CIPHER_CTX_new(); - if (s->enc_write_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - } - ciph_ctx = s->enc_write_ctx; - iv = s->write_iv; - - RECORD_LAYER_reset_write_sequence(&s->rlayer); - } + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + size_t keylen, ivlen, taglen; + int level; + int direction = (which & SSL3_CC_READ) != 0 ? OSSL_RECORD_DIRECTION_READ + : OSSL_RECORD_DIRECTION_WRITE; if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE)) || ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) { @@ -502,7 +496,7 @@ int tls13_change_cipher_state(SSL *s, int which) */ mdctx = EVP_MD_CTX_new(); if (mdctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -510,14 +504,14 @@ int tls13_change_cipher_state(SSL *s, int which) * This ups the ref count on cipher so we better make sure we free * it again */ - if (!ssl_cipher_get_evp_cipher(s->ctx, sslcipher, &cipher)) { + if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); EVP_MD_CTX_free(mdctx); goto err; } - md = ssl_md(s->ctx, sslcipher->algorithm2); + md = ssl_md(sctx, sslcipher->algorithm2); if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL) || !EVP_DigestUpdate(mdctx, hdata, handlen) || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) { @@ -626,12 +620,12 @@ int tls13_change_cipher_state(SSL *s, int which) } /* check whether cipher is known */ - if(!ossl_assert(cipher != NULL)) + if (!ossl_assert(cipher != NULL)) goto err; - if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, + if (!derive_secret_key_and_iv(s, md, cipher, insecret, hash, label, labellen, secret, key, - iv, ciph_ctx)) { + &keylen, iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } @@ -668,52 +662,28 @@ int tls13_change_cipher_state(SSL *s, int which) goto err; } - if (!s->server && label == client_early_traffic) - s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; - else - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; -#ifndef OPENSSL_NO_KTLS -# if defined(OPENSSL_KTLS_TLS13) - if (!(which & SSL3_CC_WRITE) - || !(which & SSL3_CC_APPLICATION) - || (s->options & SSL_OP_ENABLE_KTLS) == 0) - goto skip_ktls; - - /* ktls supports only the maximum fragment size */ - if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) - goto skip_ktls; - - /* ktls does not support record padding */ - if (s->record_padding_cb != NULL) - goto skip_ktls; - - /* check that cipher is supported */ - if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) - goto skip_ktls; - - bio = s->wbio; + if ((which & SSL3_CC_WRITE) != 0) { + if (!s->server && label == client_early_traffic) + s->rlayer.wrlmethod->set_plain_alerts(s->rlayer.wrl, 1); + else + s->rlayer.wrlmethod->set_plain_alerts(s->rlayer.wrl, 0); + } - if (!ossl_assert(bio != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + level = (which & SSL3_CC_EARLY) != 0 + ? OSSL_RECORD_PROTECTION_LEVEL_EARLY + : ((which &SSL3_CC_HANDSHAKE) != 0 + ? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE + : OSSL_RECORD_PROTECTION_LEVEL_APPLICATION); + + if (!ssl_set_new_record_layer(s, s->version, + direction, + level, secret, hashlen, key, keylen, iv, + ivlen, NULL, 0, cipher, taglen, NID_undef, + NULL, NULL, md)) { + /* SSLfatal already called */ goto err; } - /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ - if (BIO_flush(bio) <= 0) - goto skip_ktls; - - /* configure kernel crypto structure */ - if (!ktls_configure_crypto(s, cipher, ciph_ctx, - RECORD_LAYER_get_write_sequence(&s->rlayer), - &crypto_info, NULL, iv, key, NULL, 0)) - goto skip_ktls; - - /* ktls works with user provided buffers directly */ - if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) - ssl3_release_write_buffer(s); -skip_ktls: -# endif -#endif ret = 1; err: if ((which & SSL3_CC_EARLY) != 0) { @@ -725,18 +695,21 @@ int tls13_change_cipher_state(SSL *s, int which) return ret; } -int tls13_update_key(SSL *s, int sending) +int tls13_update_key(SSL_CONNECTION *s, int sending) { /* ASCII: "traffic upd", in hex for EBCDIC compatibility */ static const unsigned char application_traffic[] = "\x74\x72\x61\x66\x66\x69\x63\x20\x75\x70\x64"; const EVP_MD *md = ssl_handshake_md(s); size_t hashlen; unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char *insecret, *iv; + unsigned char *insecret; unsigned char secret[EVP_MAX_MD_SIZE]; char *log_label; - EVP_CIPHER_CTX *ciph_ctx; + size_t keylen, ivlen, taglen; int ret = 0, l; + int direction = sending ? OSSL_RECORD_DIRECTION_WRITE + : OSSL_RECORD_DIRECTION_READ; + unsigned char iv[EVP_MAX_IV_LENGTH]; if ((l = EVP_MD_get_size(md)) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -749,36 +722,33 @@ int tls13_update_key(SSL *s, int sending) else insecret = s->client_app_traffic_secret; - if (sending) { - s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; - iv = s->write_iv; - ciph_ctx = s->enc_write_ctx; - RECORD_LAYER_reset_write_sequence(&s->rlayer); - } else { - iv = s->read_iv; - ciph_ctx = s->enc_read_ctx; - RECORD_LAYER_reset_read_sequence(&s->rlayer); - } - - if (!derive_secret_key_and_iv(s, sending, md, + if (!derive_secret_key_and_iv(s, md, s->s3.tmp.new_sym_enc, insecret, NULL, application_traffic, sizeof(application_traffic) - 1, secret, key, - iv, ciph_ctx)) { + &keylen, iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } memcpy(insecret, secret, hashlen); + if (!ssl_set_new_record_layer(s, s->version, + direction, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + insecret, hashlen, key, keylen, iv, ivlen, NULL, 0, + s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL, + NULL, md)) { + /* SSLfatal already called */ + goto err; + } + /* Call Key log on successful traffic secret update */ log_label = s->server == sending ? SERVER_APPLICATION_N_LABEL : CLIENT_APPLICATION_N_LABEL; if (!ssl_log_secret(s, log_label, secret, hashlen)) { /* SSLfatal() already called */ goto err; } - - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ret = 1; err: OPENSSL_cleanse(key, sizeof(key)); @@ -795,7 +765,8 @@ int tls13_alert_code(int code) return tls1_alert_code(code); } -int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen, +int tls13_export_keying_material(SSL_CONNECTION *s, + unsigned char *out, size_t olen, const char *label, size_t llen, const unsigned char *context, size_t contextlen, int use_context) @@ -834,7 +805,8 @@ int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen, return ret; } -int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, +int tls13_export_keying_material_early(SSL_CONNECTION *s, + unsigned char *out, size_t olen, const char *label, size_t llen, const unsigned char *context, size_t contextlen) @@ -858,7 +830,7 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, else sslcipher = SSL_SESSION_get0_cipher(s->session); - md = ssl_md(s->ctx, sslcipher->algorithm2); + md = ssl_md(SSL_CONNECTION_GET_CTX(s), sslcipher->algorithm2); /* * Calculate the hash value and store it in |data|. The reason why diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c index 1761ba1d8e..85ed9f25f9 100644 --- a/ssl/tls_depr.c +++ b/ssl/tls_depr.c @@ -64,10 +64,14 @@ const EVP_MD *tls_get_digest_from_engine(int nid) } #ifndef OPENSSL_NO_ENGINE -int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey) +int tls_engine_load_ssl_client_cert(SSL_CONNECTION *s, X509 **px509, + EVP_PKEY **ppkey) { - return ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, - SSL_get_client_CA_list(s), + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + return ENGINE_load_ssl_client_cert(SSL_CONNECTION_GET_CTX(s)->client_cert_engine, + ssl, + SSL_get_client_CA_list(ssl), px509, ppkey, NULL, NULL, NULL); } #endif diff --git a/ssl/tls_srp.c b/ssl/tls_srp.c index 872d1b66f8..80c70bbaa2 100644 --- a/ssl/tls_srp.c +++ b/ssl/tls_srp.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -57,7 +57,7 @@ int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx) * The public API SSL_SRP_CTX_free() is deprecated so we use * ssl_srp_ctx_free_intern() internally. */ -int ssl_srp_ctx_free_intern(SSL *s) +int ssl_srp_ctx_free_intern(SSL_CONNECTION *s) { if (s == NULL) return 0; @@ -78,18 +78,21 @@ int ssl_srp_ctx_free_intern(SSL *s) int SSL_SRP_CTX_free(SSL *s) { - return ssl_srp_ctx_free_intern(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + /* the call works with NULL sc */ + return ssl_srp_ctx_free_intern(sc); } /* * The public API SSL_SRP_CTX_init() is deprecated so we use * ssl_srp_ctx_init_intern() internally. */ -int ssl_srp_ctx_init_intern(SSL *s) +int ssl_srp_ctx_init_intern(SSL_CONNECTION *s) { SSL_CTX *ctx; - if ((s == NULL) || ((ctx = s->ctx) == NULL)) + if (s == NULL || (ctx = SSL_CONNECTION_GET_CTX(s)) == NULL) return 0; memset(&s->srp_ctx, 0, sizeof(s->srp_ctx)); @@ -156,7 +159,10 @@ int ssl_srp_ctx_init_intern(SSL *s) int SSL_SRP_CTX_init(SSL *s) { - return ssl_srp_ctx_init_intern(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + /* the call works with NULL sc */ + return ssl_srp_ctx_init_intern(sc); } /* @@ -184,15 +190,17 @@ int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx) * The public API SSL_srp_server_param_with_username() is deprecated so we use * ssl_srp_server_param_with_username_intern() internally. */ -int ssl_srp_server_param_with_username_intern(SSL *s, int *ad) +int ssl_srp_server_param_with_username_intern(SSL_CONNECTION *s, int *ad) { unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; int al; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && ((al = - s->srp_ctx.TLS_ext_srp_username_callback(s, ad, + s->srp_ctx.TLS_ext_srp_username_callback(SSL_CONNECTION_GET_SSL(s), + ad, s->srp_ctx.SRP_cb_arg)) != SSL_ERROR_NONE)) return al; @@ -203,7 +211,8 @@ int ssl_srp_server_param_with_username_intern(SSL *s, int *ad) (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) return SSL3_AL_FATAL; - if (RAND_priv_bytes_ex(s->ctx->libctx, b, sizeof(b), 0) <= 0) + if (RAND_priv_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, b, sizeof(b), + 0) <= 0) return SSL3_AL_FATAL; s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); OPENSSL_cleanse(b, sizeof(b)); @@ -212,13 +221,18 @@ int ssl_srp_server_param_with_username_intern(SSL *s, int *ad) return ((s->srp_ctx.B = SRP_Calc_B_ex(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, - s->srp_ctx.v, s->ctx->libctx, s->ctx->propq)) != + s->srp_ctx.v, sctx->libctx, sctx->propq)) != NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; } int SSL_srp_server_param_with_username(SSL *s, int *ad) { - return ssl_srp_server_param_with_username_intern(s, ad); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return SSL3_AL_FATAL; + + return ssl_srp_server_param_with_username_intern(sc, ad); } /* @@ -228,17 +242,23 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad) int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp) { - SRP_gN *GN = SRP_get_default_gN(grp); + SRP_gN *GN; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + + GN = SRP_get_default_gN(grp); if (GN == NULL) return -1; - s->srp_ctx.N = BN_dup(GN->N); - s->srp_ctx.g = BN_dup(GN->g); - BN_clear_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; - BN_clear_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; - if (!SRP_create_verifier_BN_ex(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, - s->srp_ctx.N, s->srp_ctx.g, s->ctx->libctx, + sc->srp_ctx.N = BN_dup(GN->N); + sc->srp_ctx.g = BN_dup(GN->g); + BN_clear_free(sc->srp_ctx.v); + sc->srp_ctx.v = NULL; + BN_clear_free(sc->srp_ctx.s); + sc->srp_ctx.s = NULL; + if (!SRP_create_verifier_BN_ex(user, pass, &sc->srp_ctx.s, &sc->srp_ctx.v, + sc->srp_ctx.N, sc->srp_ctx.g, s->ctx->libctx, s->ctx->propq)) return -1; @@ -248,66 +268,72 @@ int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, BIGNUM *sa, BIGNUM *v, char *info) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return -1; + if (N != NULL) { - if (s->srp_ctx.N != NULL) { - if (!BN_copy(s->srp_ctx.N, N)) { - BN_free(s->srp_ctx.N); - s->srp_ctx.N = NULL; + if (sc->srp_ctx.N != NULL) { + if (!BN_copy(sc->srp_ctx.N, N)) { + BN_free(sc->srp_ctx.N); + sc->srp_ctx.N = NULL; } } else - s->srp_ctx.N = BN_dup(N); + sc->srp_ctx.N = BN_dup(N); } if (g != NULL) { - if (s->srp_ctx.g != NULL) { - if (!BN_copy(s->srp_ctx.g, g)) { - BN_free(s->srp_ctx.g); - s->srp_ctx.g = NULL; + if (sc->srp_ctx.g != NULL) { + if (!BN_copy(sc->srp_ctx.g, g)) { + BN_free(sc->srp_ctx.g); + sc->srp_ctx.g = NULL; } } else - s->srp_ctx.g = BN_dup(g); + sc->srp_ctx.g = BN_dup(g); } if (sa != NULL) { - if (s->srp_ctx.s != NULL) { - if (!BN_copy(s->srp_ctx.s, sa)) { - BN_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; + if (sc->srp_ctx.s != NULL) { + if (!BN_copy(sc->srp_ctx.s, sa)) { + BN_free(sc->srp_ctx.s); + sc->srp_ctx.s = NULL; } } else - s->srp_ctx.s = BN_dup(sa); + sc->srp_ctx.s = BN_dup(sa); } if (v != NULL) { - if (s->srp_ctx.v != NULL) { - if (!BN_copy(s->srp_ctx.v, v)) { - BN_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; + if (sc->srp_ctx.v != NULL) { + if (!BN_copy(sc->srp_ctx.v, v)) { + BN_free(sc->srp_ctx.v); + sc->srp_ctx.v = NULL; } } else - s->srp_ctx.v = BN_dup(v); + sc->srp_ctx.v = BN_dup(v); } if (info != NULL) { - if (s->srp_ctx.info) - OPENSSL_free(s->srp_ctx.info); - if ((s->srp_ctx.info = OPENSSL_strdup(info)) == NULL) + if (sc->srp_ctx.info) + OPENSSL_free(sc->srp_ctx.info); + if ((sc->srp_ctx.info = OPENSSL_strdup(info)) == NULL) return -1; } - if (!(s->srp_ctx.N) || - !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) + if (!(sc->srp_ctx.N) || + !(sc->srp_ctx.g) || !(sc->srp_ctx.s) || !(sc->srp_ctx.v)) return -1; return 1; } -int srp_generate_server_master_secret(SSL *s) +int srp_generate_server_master_secret(SSL_CONNECTION *s) { BIGNUM *K = NULL, *u = NULL; int ret = 0, tmp_len = 0; unsigned char *tmp = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) goto err; if ((u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, - s->ctx->libctx, s->ctx->propq)) == NULL) + sctx->libctx, sctx->propq)) == NULL) goto err; if ((K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)) == NULL) @@ -315,7 +341,7 @@ int srp_generate_server_master_secret(SSL *s) tmp_len = BN_num_bytes(K); if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } BN_bn2bin(K, tmp); @@ -328,44 +354,45 @@ int srp_generate_server_master_secret(SSL *s) } /* client side */ -int srp_generate_client_master_secret(SSL *s) +int srp_generate_client_master_secret(SSL_CONNECTION *s) { BIGNUM *x = NULL, *u = NULL, *K = NULL; int ret = 0, tmp_len = 0; char *passwd = NULL; unsigned char *tmp = NULL; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* * Checks if b % n == 0 */ if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0 || (u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, - s->ctx->libctx, s->ctx->propq)) + sctx->libctx, sctx->propq)) == NULL || s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if ((passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, - s->srp_ctx.SRP_cb_arg)) + if ((passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(SSL_CONNECTION_GET_SSL(s), + s->srp_ctx.SRP_cb_arg)) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); goto err; } if ((x = SRP_Calc_x_ex(s->srp_ctx.s, s->srp_ctx.login, passwd, - s->ctx->libctx, s->ctx->propq)) == NULL + sctx->libctx, sctx->propq)) == NULL || (K = SRP_Calc_client_key_ex(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u, - s->ctx->libctx, - s->ctx->propq)) == NULL) { + sctx->libctx, + sctx->propq)) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } tmp_len = BN_num_bytes(K); if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; } BN_bn2bin(K, tmp); @@ -380,7 +407,7 @@ int srp_generate_client_master_secret(SSL *s) return ret; } -int srp_verify_server_param(SSL *s) +int srp_verify_server_param(SSL_CONNECTION *s) { SRP_CTX *srp = &s->srp_ctx; /* @@ -399,7 +426,8 @@ int srp_verify_server_param(SSL *s) } if (srp->SRP_verify_param_callback) { - if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { + if (srp->SRP_verify_param_callback(SSL_CONNECTION_GET_SSL(s), + srp->SRP_cb_arg) <= 0) { SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_CALLBACK_FAILED); return 0; } @@ -416,11 +444,12 @@ int srp_verify_server_param(SSL *s) * The public API SRP_Calc_A_param() is deprecated so we use * ssl_srp_calc_a_param_intern() internally. */ -int ssl_srp_calc_a_param_intern(SSL *s) +int ssl_srp_calc_a_param_intern(SSL_CONNECTION *s) { unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; - if (RAND_priv_bytes_ex(s->ctx->libctx, rnd, sizeof(rnd), 0) <= 0) + if (RAND_priv_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, + rnd, sizeof(rnd), 0) <= 0) return 0; s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); OPENSSL_cleanse(rnd, sizeof(rnd)); @@ -433,34 +462,59 @@ int ssl_srp_calc_a_param_intern(SSL *s) int SRP_Calc_A_param(SSL *s) { - return ssl_srp_calc_a_param_intern(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return 0; + + return ssl_srp_calc_a_param_intern(sc); } BIGNUM *SSL_get_srp_g(SSL *s) { - if (s->srp_ctx.g != NULL) - return s->srp_ctx.g; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->srp_ctx.g != NULL) + return sc->srp_ctx.g; return s->ctx->srp_ctx.g; } BIGNUM *SSL_get_srp_N(SSL *s) { - if (s->srp_ctx.N != NULL) - return s->srp_ctx.N; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->srp_ctx.N != NULL) + return sc->srp_ctx.N; return s->ctx->srp_ctx.N; } char *SSL_get_srp_username(SSL *s) { - if (s->srp_ctx.login != NULL) - return s->srp_ctx.login; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->srp_ctx.login != NULL) + return sc->srp_ctx.login; return s->ctx->srp_ctx.login; } char *SSL_get_srp_userinfo(SSL *s) { - if (s->srp_ctx.info != NULL) - return s->srp_ctx.info; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + + if (sc == NULL) + return NULL; + + if (sc->srp_ctx.info != NULL) + return sc->srp_ctx.info; return s->ctx->srp_ctx.info; }